diff --git a/README.md b/README.md index 6541734b134bcb419fe64489882058236040fe06..ab877f2d05ad5b25838c8b9d95bc45835e031a53 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,27 @@ uw-php-security is a PHP companion to [uw-spring-security](https://git.doit.wisc.edu/adi-ia/uw-spring-security) for Java. Its purpose is to ease development of PHP applications needing details about UW users provided through Shibboleth. +Like uw-spring-security, uw-php-security provides a class called `UWUserDetails` for easily accessing common UW user attributes. This model is provided to applications through a `UserDetailsService`, and uw-php-security provides implementations suitable for both local and preauth (Shibboleth) environments. + +```php +<?php + +use edu\wisc\doit\PreauthUserDetailsService; // or LocalUserDetailsService for local development +... +$userDetailsService = new PreauthUserDetailsService(); +$user = $userDetailsService->loadUser(); +if ($user == null) { + // handle error +} +... +``` + ## Developer Requirements * PHP +* [Composer](https://getcomposer.org/) +* [Phing](https://www.phing.info/) +* [PHPUnit](https://phpunit.de/) ## Building diff --git a/composer.json b/composer.json index 915a72a2117807da53ab4cef224889528d2dcce7..0b591f06e8ea33c7a7fa1f0150f5a91ef47742a9 100644 --- a/composer.json +++ b/composer.json @@ -19,5 +19,10 @@ "psr-4": { "edu\\wisc\\doit\\": "src/main/edu/wisc/doit/" } + }, + "autoload-dev": { + "psr-4": { + "edu\\wisc\\doit\\": "src/test/edu/wisc/doit" + } } } diff --git a/composer.phar b/composer.phar deleted file mode 100644 index c0d6e92adc3237fb893ffc02ae32af567b465f04..0000000000000000000000000000000000000000 Binary files a/composer.phar and /dev/null differ diff --git a/phing.phar b/phing.phar deleted file mode 100755 index 79e3435c04c01d05613381a0d8fefb7be4e52b0f..0000000000000000000000000000000000000000 Binary files a/phing.phar and /dev/null differ diff --git a/phpunit.phar b/phpunit.phar deleted file mode 100755 index 90cae7c5d74320748838c1b0a4e041096978e7a0..0000000000000000000000000000000000000000 --- a/phpunit.phar +++ /dev/null @@ -1,72809 +0,0 @@ -#!/usr/bin/env php -<?php -if (version_compare('5.6.0', PHP_VERSION, '>')) { - fwrite( - STDERR, - 'This version of PHPUnit requires PHP 5.6; using the latest version of PHP is highly recommended.' . PHP_EOL - ); - - die(1); -} - -if (__FILE__ == realpath($GLOBALS['_SERVER']['SCRIPT_NAME'])) { - $execute = true; -} else { - $execute = false; -} - -define('__PHPUNIT_PHAR__', str_replace(DIRECTORY_SEPARATOR, '/', __FILE__)); -define('__PHPUNIT_PHAR_ROOT__', 'phar://phpunit-5.4.6.phar'); - -Phar::mapPhar('phpunit-5.4.6.phar'); - -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/DeepCopy.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Exception/CloneException.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Filter/Filter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Matcher/Matcher.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php'; -require 'phar://phpunit-5.4.6.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.php'; -require 'phar://phpunit-5.4.6.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.php'; -require 'phar://phpunit-5.4.6.phar' . '/doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/doctrine-instantiator/Doctrine/Instantiator/Instantiator.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-file-iterator/Iterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-file-iterator/Facade.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-file-iterator/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Test.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/SelfDescribing.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Assert.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/TestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/ForwardCompatibility/TestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/ITester.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/AbstractTester.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Constraint/DataSetIsEqual.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Constraint/TableIsEqual.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Constraint/TableRowCount.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/IDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/AbstractDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/DataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/IDatabaseConnection.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/FilteredDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/IMetaData.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/Dblib.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/Firebird.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/InformationSchema.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/MySQL.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/Oci.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/PgSQL.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/SqlSrv.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/MetaData/Sqlite.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ITable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/AbstractTable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/ResultSetTable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/Table.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ITableIterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/TableIterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ITableMetaData.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DB/TableMetaData.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ArrayDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/CompositeDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/CsvDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/DataSetFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/DefaultDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/DefaultTableIterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/IPersistable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ISpec.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/IYamlParser.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Abstract.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Xml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Persistors/Yaml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/QueryDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/QueryTable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementTable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Csv.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/IDatabaseListConsumer.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/DbQuery.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/DbTable.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/IFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/FlatXml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Xml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/Specs/Yaml.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/TableFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/XmlDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DataSet/YamlDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/DefaultTester.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/IDatabaseOperation.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Composite.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/RowBased.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Delete.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/DeleteAll.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Insert.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Null.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Replace.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Truncate.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/Operation/Update.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/TestCaseTrait.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/TestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/Command.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/Context.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/IMediumPrinter.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/IMedium.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/IMode.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/IModeFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/InvalidModeException.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/Mediums/Text.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/ModeFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/Modes/ExportDataSet.php'; -require 'phar://phpunit-5.4.6.phar' . '/dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/TestSuite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Extensions/GroupTestSuite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Extensions/PhptTestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Extensions/PhptTestSuite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Extensions/TestDecorator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Extensions/RepeatedTest.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/TestListener.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Extensions/TicketListener.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/AssertionFailedError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/BaseTestListener.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/CodeCoverageException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/And.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ArrayHasKey.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ArraySubset.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Composite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Attribute.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Callback.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ClassHasAttribute.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ClassHasStaticAttribute.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Count.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ExceptionCode.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ExceptionMessage.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ExceptionMessageRegExp.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/FileExists.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/GreaterThan.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsAnything.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsEmpty.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsEqual.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsFalse.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsFinite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsIdentical.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsInfinite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsInstanceOf.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsJson.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsNan.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsNull.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsTrue.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/IsType.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/JsonMatches.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/LessThan.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Not.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/ObjectHasAttribute.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Or.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/PCREMatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/SameSize.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/StringContains.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/StringEndsWith.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/StringMatches.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/StringStartsWith.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/TraversableContains.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/TraversableContainsOnly.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Constraint/Xor.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/RiskyTest.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/RiskyTestError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/PHPUnit_Framework_CoveredCodeNotExecutedException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Error.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Error/Deprecated.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Error/Notice.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Error/Warning.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/ExceptionWrapper.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/ExpectationFailedException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/IncompleteTest.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/IncompleteTestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/IncompleteTestError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/InvalidCoversTargetException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/PHPUnit_Framework_MissingCoversAnnotationException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Identity.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Stub.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Match.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Generator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Verifiable.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Invokable.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/InvocationMocker.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation/Static.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Invocation/Object.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/MockBuilder.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/MockObject.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/Return.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnReference.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/OutputError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/SkippedTest.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/SkippedTestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/SkippedTestError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/SkippedTestSuiteError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/SyntheticError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/TestFailure.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/TestResult.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/TestSuite/DataProvider.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/UnintentionallyCoveredCodeError.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/Warning.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Framework/WarningTestCase.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/BaseTestRunner.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Filter/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Filter/Group.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Filter/Group/Exclude.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Filter/Group/Include.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Filter/Test.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/TestSuiteLoader.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/StandardTestSuiteLoader.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Runner/Version.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/TextUI/Command.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Printer.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/TextUI/ResultPrinter.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/TextUI/TestRunner.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Blacklist.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Configuration.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/ConfigurationGenerator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/ErrorHandler.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Fileloader.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Filesystem.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Filter.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Getopt.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/GlobalState.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/InvalidArgumentHelper.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Log/JSON.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Log/JUnit.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Log/TAP.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Log/TeamCity.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/PHP.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/PHP/Default.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/PHP/Windows.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Regex.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/String.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Test.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/TestDox/NamePrettifier.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/TestDox/ResultPrinter.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/TestDox/ResultPrinter/HTML.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/TestDox/ResultPrinter/Text.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/TestDox/ResultPrinter/XML.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/TestSuiteIterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/Type.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpunit/Util/XML.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-invoker/Invoker.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-invoker/TimeoutException.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-timer/Timer.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-token-stream/Token.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-token-stream/Token/Stream.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-token-stream/Token/Stream/CachingFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/ArgumentsWildcard.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/TokenInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/AnyValueToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/AnyValuesToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ApproximateValueToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayCountToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayEntryToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ArrayEveryEntryToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/CallbackToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ExactValueToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/IdenticalValueToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/LogicalAndToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/LogicalNotToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/ObjectStateToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/StringContainsToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Argument/Token/TypeToken.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Call/Call.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Call/CallCenter.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/Comparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Comparator/ClosureComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Comparator/Factory.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/ArrayComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/ObjectComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Comparator/ProphecyComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Doubler.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/CachedDoubler.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/KeywordPatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/MagicCallPatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/ClassPatch/TraversablePatch.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/DoubleInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassCodeGenerator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassCreator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ClassMirror.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/ArgumentNode.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/ClassNode.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/Node/MethodNode.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/Generator/ReflectionInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/LazyDouble.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Doubler/NameGenerator.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/ProphecyException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/ObjectProphecyException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Call/UnexpectedCallException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/DoublerException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassCreatorException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassMirrorException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/DoubleException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ClassNotFoundException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/InterfaceNotFoundException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotExtendableException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotFoundException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Doubler/ReturnByReferenceException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/InvalidArgumentException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/PredictionException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/AggregateException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/FailedPredictionException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prophecy/MethodProphecyException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/NoCallsException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/PhpDocumentor/ClassTagRetriever.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prediction/PredictionInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallPrediction.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallTimesPrediction.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prediction/CallbackPrediction.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prediction/NoCallsPrediction.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Promise/PromiseInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Promise/CallbackPromise.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Promise/ReturnArgumentPromise.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Promise/ReturnPromise.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Promise/ThrowPromise.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophecy/MethodProphecy.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ProphecyInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ObjectProphecy.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophecy/ProphecySubjectInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophecy/RevealerInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophecy/Revealer.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Prophet.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Util/ExportUtil.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpspec-prophecy/Prophecy/Util/StringUtil.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/CodeCoverage.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Exception/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Exception/RuntimeException.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Exception/CoveredCodeNotExecutedException.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Driver/Driver.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Driver/Xdebug.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Driver/HHVM.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Driver/PHPDBG.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Filter.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Exception/InvalidArgumentException.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Exception/MissingCoversAnnotationException.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Node/AbstractNode.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Node/Builder.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Node/Directory.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Node/File.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Node/Iterator.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Clover.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Crap4j.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Html/Renderer.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Html/Renderer/Dashboard.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Html/Renderer/Directory.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Html/Facade.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Html/Renderer/File.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/PHP.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Text.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Coverage.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Node.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Directory.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Facade.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/File.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Method.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Project.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Report.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Tests.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Totals.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Report/Xml/Unit.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Exception/UnintentionallyCoveredCodeException.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-code-coverage/Util.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-code-unit-reverse-lookup/Wizard.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/ComparisonFailure.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/DOMNodeComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/DateTimeComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/ScalarComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/NumericComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/DoubleComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/ExceptionComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/MockObjectComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/ResourceComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/SplObjectStorageComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-comparator/TypeComparator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/Chunk.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/Diff.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/Differ.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/LCS/LongestCommonSubsequence.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/Line.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-diff/Parser.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-environment/Console.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-environment/Runtime.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-exporter/Exporter.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-global-state/Blacklist.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-global-state/CodeExporter.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-global-state/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-global-state/Restorer.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-global-state/RuntimeException.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-global-state/Snapshot.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-object-enumerator/Enumerator.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-object-enumerator/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-object-enumerator/InvalidArgumentException.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-recursion-context/Context.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-recursion-context/Exception.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-recursion-context/InvalidArgumentException.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-resource-operations/ResourceOperations.php'; -require 'phar://phpunit-5.4.6.phar' . '/sebastian-version/Version.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Dumper.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Escaper.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Exception/ExceptionInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Exception/RuntimeException.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Exception/DumpException.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Exception/ParseException.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Inline.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Parser.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Unescaper.php'; -require 'phar://phpunit-5.4.6.phar' . '/symfony/yaml/Yaml.php'; -require 'phar://phpunit-5.4.6.phar' . '/php-text-template/Template.php'; -require 'phar://phpunit-5.4.6.phar' . '/webmozart-assert/Assert.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlockFactoryInterface.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlockFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Description.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/DescriptionFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Serializer.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/TagFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/StandardTagFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tag.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Factory/StaticMethod.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/BaseTag.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Author.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Covers.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Deprecated.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Example.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Factory/Strategy.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Formatter.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Formatter/PassthroughFormatter.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Generic.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Link.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Method.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Param.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Property.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/PropertyRead.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/PropertyWrite.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Return_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/See.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Since.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Source.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Throws.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Uses.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Var_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/Tags/Version.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-common/Element.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-docblock/DocBlock/ExampleFinder.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-common/File.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-common/Fqsen.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/FqsenResolver.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-common/Location.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-common/Project.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-reflection-common/ProjectFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Type.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/TypeResolver.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Array_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Boolean.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Callable_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Compound.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Context.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/ContextFactory.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Float_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Integer.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Mixed.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Null_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Object_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Resource.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Scalar.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Self_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Static_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/String_.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/This.php'; -require 'phar://phpunit-5.4.6.phar' . '/phpdocumentor-type-resolver/Types/Void_.php'; - -if ($execute) { - if (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == '--manifest') { - print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt'); - exit; - } - - PHPUnit_TextUI_Command::main(); -} - -__HALT_COMPILER(); ?> -'���Y���������phpunit-5.4.6.phar�������manifest.txt(���@bW(��M��ض���������ca.pem����@bW����by����������php-code-coverage/LICENSE���@bW��ЉxZ�������"���php-code-coverage/CodeCoverage.php�s���@bW�s�����W�������#���php-code-coverage/Driver/Driver.php���@bW������������!���php-code-coverage/Driver/HHVM.php����@bW���Ն7�������#���php-code-coverage/Driver/PHPDBG.php]���@bW]��ӔӶ������#���php-code-coverage/Driver/Xdebug.php� -���@bW� -�����������?���php-code-coverage/Exception/CoveredCodeNotExecutedException.php����@bW���/�/��������)���php-code-coverage/Exception/Exception.php~���@bW~����u�������8���php-code-coverage/Exception/InvalidArgumentException.php����@bW����N��������@���php-code-coverage/Exception/MissingCoversAnnotationException.php����@bW����fM�������0���php-code-coverage/Exception/RuntimeException.phpp���@bWp��w�C�������C���php-code-coverage/Exception/UnintentionallyCoveredCodeException.php����@bW����F�+����������php-code-coverage/Filter.php����@bW�����ʶ������'���php-code-coverage/Node/AbstractNode.php����@bW����_��������"���php-code-coverage/Node/Builder.phpb���@bWb���*�̶������$���php-code-coverage/Node/Directory.php�&���@bW�&���k����������php-code-coverage/Node/File.php�H���@bW�H���*P��������#���php-code-coverage/Node/Iterator.php����@bW���9��Q�������#���php-code-coverage/Report/Clover.php�&���@bW�&���$촶������#���php-code-coverage/Report/Crap4j.php����@bW���qro��������(���php-code-coverage/Report/Html/Facade.php����@bW����;Ƕ������*���php-code-coverage/Report/Html/Renderer.php�"���@bW�"��JN#X�������4���php-code-coverage/Report/Html/Renderer/Dashboard.phpm&���@bWm&��!mu�������4���php-code-coverage/Report/Html/Renderer/Directory.php����@bW���;$��������/���php-code-coverage/Report/Html/Renderer/File.php(I���@bW(I���Q���������F���php-code-coverage/Report/Html/Renderer/Template/coverage_bar.html.dist1���@bW1��itL�������E���php-code-coverage/Report/Html/Renderer/Template/css/bootstrap.min.css����@bW���n�8��������A���php-code-coverage/Report/Html/Renderer/Template/css/nv.d3.min.cssX%���@bWX%���0,�������=���php-code-coverage/Report/Html/Renderer/Template/css/style.css+���@bW+��Y`�g�������C���php-code-coverage/Report/Html/Renderer/Template/dashboard.html.dist����@bW�����"�������C���php-code-coverage/Report/Html/Renderer/Template/directory.html.dist!���@bW!��!_�������H���php-code-coverage/Report/Html/Renderer/Template/directory_item.html.dist5���@bW5���Z�]�������>���php-code-coverage/Report/Html/Renderer/Template/file.html.dist� -���@bW� -���(ﷶ������C���php-code-coverage/Report/Html/Renderer/Template/file_item.html.distg���@bWg��V� P�������V���php-code-coverage/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.eot�N���@bW�N��XDZ��������V���php-code-coverage/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.svg¨��@bW¨�|��ɶ������V���php-code-coverage/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.ttf\����@bW\����<��������W���php-code-coverage/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff�[���@bW�[���{��������X���php-code-coverage/Report/Html/Renderer/Template/fonts/glyphicons-halflings-regular.woff2lF���@bWlF��v��a�������C���php-code-coverage/Report/Html/Renderer/Template/js/bootstrap.min.js����@bW���::�ڶ������<���php-code-coverage/Report/Html/Renderer/Template/js/d3.min.js�P��@bW�P��h�b�������@���php-code-coverage/Report/Html/Renderer/Template/js/holder.min.js�m���@bW�m��J�sѶ������C���php-code-coverage/Report/Html/Renderer/Template/js/html5shiv.min.js[(���@bW[(��ü,�������@���php-code-coverage/Report/Html/Renderer/Template/js/jquery.min.js�{��@bW�{� ��l�������?���php-code-coverage/Report/Html/Renderer/Template/js/nv.d3.min.js�R��@bW�R�<Ms�������A���php-code-coverage/Report/Html/Renderer/Template/js/respond.min.js���@bW���{�������E���php-code-coverage/Report/Html/Renderer/Template/method_item.html.distx���@bWx��*��������� ���php-code-coverage/Report/PHP.php����@bW���DP��������!���php-code-coverage/Report/Text.php"���@bW"��l���������)���php-code-coverage/Report/Xml/Coverage.phpC���@bWC��dȶ������*���php-code-coverage/Report/Xml/Directory.phpR���@bWR��&�a�������'���php-code-coverage/Report/Xml/Facade.php����@bW���&*��������%���php-code-coverage/Report/Xml/File.php����@bW���e�5j�������'���php-code-coverage/Report/Xml/Method.phpW���@bWW��� \�������%���php-code-coverage/Report/Xml/Node.php����@bW���;�#P�������(���php-code-coverage/Report/Xml/Project.php���@bW��ă�J�������'���php-code-coverage/Report/Xml/Report.php����@bW���@�wS�������&���php-code-coverage/Report/Xml/Tests.php����@bW������Z�������'���php-code-coverage/Report/Xml/Totals.php����@bW���酮��������%���php-code-coverage/Report/Xml/Unit.php -���@bW -��-5�^����������php-code-coverage/Util.php����@bW���������������php-file-iterator/LICENSE���@bW����s�����������php-file-iterator/Facade.php����@bW�����0�����������php-file-iterator/Factory.php� ���@bW� ���y������������php-file-iterator/Iterator.phpa���@bWa���������������php-text-template/LICENSE���@bW��S�:�����������php-text-template/Template.php����@bW����w4�����������php-timer/LICENSE���@bW��ǨAE����������php-timer/Timer.phpE ���@bWE ����6����������php-token-stream/LICENSE���@bW���-& ����������php-token-stream/Token.php:b���@bW:b���#0!�������!���php-token-stream/Token/Stream.php�@���@bW�@����ܜ�������0���php-token-stream/Token/Stream/CachingFactory.php���@bW��_����������phpunit-mock-objects/LICENSE���@bW��C>��������>���phpunit-mock-objects/Framework/MockObject/Builder/Identity.php����@bW���w[�������F���phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php����@bW������϶������;���phpunit-mock-objects/Framework/MockObject/Builder/Match.php���@bW��jZ��������E���phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php����@bW���$����������?���phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php���@bW����AF�������E���phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php���@bW��w2�������:���phpunit-mock-objects/Framework/MockObject/Builder/Stub.phpX���@bWX��ѕ�������N���phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.php����@bW�����).�������A���phpunit-mock-objects/Framework/MockObject/Exception/Exception.php����@bW���]�T�������H���phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.php����@bW���Y�n4�������7���phpunit-mock-objects/Framework/MockObject/Generator.php�����@bW�����'���������H���phpunit-mock-objects/Framework/MockObject/Generator/deprecation.tpl.dist;����@bW;���O5�s�������I���phpunit-mock-objects/Framework/MockObject/Generator/mocked_class.tpl.dist����@bW����z�Q�������P���phpunit-mock-objects/Framework/MockObject/Generator/mocked_class_method.tpl.dist�����@bW�����4������I���phpunit-mock-objects/Framework/MockObject/Generator/mocked_clone.tpl.dist�����@bW�����aT�������J���phpunit-mock-objects/Framework/MockObject/Generator/mocked_method.tpl.dist����@bW��������������Q���phpunit-mock-objects/Framework/MockObject/Generator/mocked_static_method.tpl.dist�����@bW����Ϫ^b�������K���phpunit-mock-objects/Framework/MockObject/Generator/proxied_method.tpl.dist����@bW�������������H���phpunit-mock-objects/Framework/MockObject/Generator/trait_class.tpl.dist7����@bW7����[$~�������K���phpunit-mock-objects/Framework/MockObject/Generator/unmocked_clone.tpl.dist�����@bW����8W}ض������G���phpunit-mock-objects/Framework/MockObject/Generator/wsdl_class.tpl.dist�����@bW����w&S�������H���phpunit-mock-objects/Framework/MockObject/Generator/wsdl_method.tpl.dist<����@bW<�����i��������8���phpunit-mock-objects/Framework/MockObject/Invocation.php����@bW���9T���������?���phpunit-mock-objects/Framework/MockObject/Invocation/Object.php����@bW���8����������?���phpunit-mock-objects/Framework/MockObject/Invocation/Static.phpf���@bWf����%�������>���phpunit-mock-objects/Framework/MockObject/InvocationMocker.php����@bW���`8��������7���phpunit-mock-objects/Framework/MockObject/Invokable.php����@bW��������������5���phpunit-mock-objects/Framework/MockObject/Matcher.phpi!���@bWi!��7ZRж������E���phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.php����@bW����Ds$�������C���phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.phpI���@bWI��U��@�������K���phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php����@bW���o"ī�������@���phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php���@bW��@⸩�������D���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php ���@bW ��7y�{�������I���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.php����@bW���0�8�������H���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php����@bW���E�@G�������H���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.php����@bW���̈́-�������B���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php����@bW���q��������E���phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.phpb���@bWb��i����������@���phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php-���@bW-���=R�������@���phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php���@bW��� }(�������I���phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.phpi���@bWi������������9���phpunit-mock-objects/Framework/MockObject/MockBuilder.phpI#���@bWI#��y��������8���phpunit-mock-objects/Framework/MockObject/MockObject.php����@bW�������������2���phpunit-mock-objects/Framework/MockObject/Stub.php����@bW�������������C���phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php����@bW���2 � �������<���phpunit-mock-objects/Framework/MockObject/Stub/Exception.php&���@bW&��_, -�������D���phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php����@bW�����v�������9���phpunit-mock-objects/Framework/MockObject/Stub/Return.php����@bW���L�f+�������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.php����@bW���9)�`�������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php����@bW���g��`�������B���phpunit-mock-objects/Framework/MockObject/Stub/ReturnReference.php;���@bW;��l���������=���phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php����@bW���fk�k�������A���phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php|���@bW|��uB �������8���phpunit-mock-objects/Framework/MockObject/Verifiable.php����@bW����'L�������*���sebastian-code-unit-reverse-lookup/LICENSE���@bW��<�P��������-���sebastian-code-unit-reverse-lookup/Wizard.phpe���@bWe���������������sebastian-comparator/LICENSE ���@bW ���:�������(���sebastian-comparator/ArrayComparator.php����@bW���v�x�������#���sebastian-comparator/Comparator.phpP���@bWP��!P�=�������*���sebastian-comparator/ComparisonFailure.php����@bW��� �V�������*���sebastian-comparator/DOMNodeComparator.php� ���@bW� ����>%�������+���sebastian-comparator/DateTimeComparator.php����@bW�����������)���sebastian-comparator/DoubleComparator.php7���@bW7��S�tٶ������,���sebastian-comparator/ExceptionComparator.php����@bW����kf�������� ���sebastian-comparator/Factory.phpd���@bWd��ه1�������-���sebastian-comparator/MockObjectComparator.php����@bW������O�������*���sebastian-comparator/NumericComparator.php~ -���@bW~ -���7��������)���sebastian-comparator/ObjectComparator.php����@bW������w�������+���sebastian-comparator/ResourceComparator.php����@bW���&�w�������)���sebastian-comparator/ScalarComparator.php>���@bW>����B(�������3���sebastian-comparator/SplObjectStorageComparator.php� -���@bW� -���M�Q�������'���sebastian-comparator/TypeComparator.php����@bW����Q����������sebastian-diff/LICENSE���@bW��vEvö���������sebastian-diff/Chunk.php����@bW���-*�����������sebastian-diff/Diff.php����@bW���˾�����������sebastian-diff/Differ.php����@bW�����`�������/���sebastian-diff/LCS/LongestCommonSubsequence.phpl���@bWl���l�1�������L���sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php� ���@bW� ���_�������J���sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php����@bW���f#5/����������sebastian-diff/Line.php����@bW����:;����������sebastian-diff/Parser.php'���@bW'���Z�K����������sebastian-environment/LICENSE -���@bW -�����߶������!���sebastian-environment/Console.php����@bW����?."�������!���sebastian-environment/Runtime.phpH���@bWH��8������������sebastian-exporter/LICENSE���@bW��A�e)����������sebastian-exporter/Exporter.php["���@bW["���T��������#���sebastian-recursion-context/LICENSE���@bW������������'���sebastian-recursion-context/Context.php����@bW����qP��������)���sebastian-recursion-context/Exception.phpJ���@bWJ������������8���sebastian-recursion-context/InvalidArgumentException.php����@bW���mH�������%���sebastian-resource-operations/LICENSE ���@bW ��I���������4���sebastian-resource-operations/ResourceOperations.php�U���@bW�U���hն���������sebastian-global-state/LICENSE -���@bW -���`�������$���sebastian-global-state/Blacklist.php[���@bW[��:��������'���sebastian-global-state/CodeExporter.php����@bW���`�(C�������$���sebastian-global-state/Exception.php?���@bW?����������#���sebastian-global-state/Restorer.php����@bW���ӓ;\�������+���sebastian-global-state/RuntimeException.phpq���@bWq���~]!�������#���sebastian-global-state/Snapshot.php�%���@bW�%��ÖSݶ���������object-enumerator/LICENSE���@bW���Y�u�������*���sebastian-object-enumerator/Enumerator.php����@bW����=��������)���sebastian-object-enumerator/Exception.php6���@bW6��n$*a�������8���sebastian-object-enumerator/InvalidArgumentException.phpx���@bWx����'�����������sebastian-version/LICENSE���@bW��n����������sebastian-version/Version.php����@bW���N\Ƕ���������doctrine-instantiator/LICENSE$���@bW$�� -͂�������L���doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php����@bW����.�ö������R���doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.php����@bW���h�7I�������R���doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.php� -���@bW� -��"�� �������<���doctrine-instantiator/Doctrine/Instantiator/Instantiator.php� ���@bW� ���&�������E���doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php~���@bW~�����:����������symfony/LICENSE)���@bW)��������������symfony/yaml/Dumper.php����@bW����쇶���������symfony/yaml/Escaper.php ���@bW ��+�oö������(���symfony/yaml/Exception/DumpException.php����@bW�����������-���symfony/yaml/Exception/ExceptionInterface.php����@bW����^KA�������)���symfony/yaml/Exception/ParseException.php] ���@bW] ��A��������+���symfony/yaml/Exception/RuntimeException.php����@bW����_q�����������symfony/yaml/Inline.phpka���@bWka��=�^����������symfony/yaml/Parser.php�~���@bW�~��D���������symfony/yaml/Unescaper.phpU���@bWU���őU����������symfony/yaml/Yaml.php����@bW�����;ٶ������-���dbunit/Extensions/Database/AbstractTester.php���@bW��C�Y�������8���dbunit/Extensions/Database/Constraint/DataSetIsEqual.php����@bW���M���������6���dbunit/Extensions/Database/Constraint/TableIsEqual.php���@bW��7� -�������7���dbunit/Extensions/Database/Constraint/TableRowCount.php����@bW���I�XӶ������)���dbunit/Extensions/Database/DB/DataSet.phpC���@bWC��ԍ�������;���dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php}���@bW}�������������1���dbunit/Extensions/Database/DB/FilteredDataSet.phpF���@bWF�� (�e�������5���dbunit/Extensions/Database/DB/IDatabaseConnection.php���@bW���dʶ������+���dbunit/Extensions/Database/DB/IMetaData.php3���@bW3��@G���������*���dbunit/Extensions/Database/DB/MetaData.php����@bW����Pp�������0���dbunit/Extensions/Database/DB/MetaData/Dblib.php� -���@bW� -��#j*-�������3���dbunit/Extensions/Database/DB/MetaData/Firebird.php����@bW����]Y�������<���dbunit/Extensions/Database/DB/MetaData/InformationSchema.phpA���@bWA��4�C"�������0���dbunit/Extensions/Database/DB/MetaData/MySQL.php����@bW�������������.���dbunit/Extensions/Database/DB/MetaData/Oci.phpI���@bWI��UWK��������0���dbunit/Extensions/Database/DB/MetaData/PgSQL.php����@bW���A�.��������1���dbunit/Extensions/Database/DB/MetaData/SqlSrv.php� ���@bW� ��y�D�������1���dbunit/Extensions/Database/DB/MetaData/Sqlite.php -���@bW -������������0���dbunit/Extensions/Database/DB/ResultSetTable.php����@bW����O&�������'���dbunit/Extensions/Database/DB/Table.php����@bW���8k8o�������/���dbunit/Extensions/Database/DB/TableIterator.php} -���@bW} -��0W�6�������/���dbunit/Extensions/Database/DB/TableMetaData.php���@bW���;Е�������6���dbunit/Extensions/Database/DataSet/AbstractDataSet.php���@bW���^��������4���dbunit/Extensions/Database/DataSet/AbstractTable.phpS���@bWS��Xl�ٶ������<���dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php����@bW���;�c��������9���dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php����@bW����F!�������3���dbunit/Extensions/Database/DataSet/ArrayDataSet.phpo���@bWo����||�������7���dbunit/Extensions/Database/DataSet/CompositeDataSet.php5 -���@bW5 -����4O�������1���dbunit/Extensions/Database/DataSet/CsvDataSet.php����@bW���l���������4���dbunit/Extensions/Database/DataSet/DataSetFilter.phpG���@bWG��1�������5���dbunit/Extensions/Database/DataSet/DefaultDataSet.php����@bW�����w��������3���dbunit/Extensions/Database/DataSet/DefaultTable.phpt���@bWt����϶������;���dbunit/Extensions/Database/DataSet/DefaultTableIterator.php� ���@bW� ��4��������;���dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php����@bW���.�F�������5���dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php@���@bW@���耀�������/���dbunit/Extensions/Database/DataSet/IDataSet.php���@bW���Z߶������3���dbunit/Extensions/Database/DataSet/IPersistable.php����@bW��������������,���dbunit/Extensions/Database/DataSet/ISpec.php����@bW���݂������-���dbunit/Extensions/Database/DataSet/ITable.php���@bW��ȃN��������5���dbunit/Extensions/Database/DataSet/ITableIterator.php���@bW���!-�������5���dbunit/Extensions/Database/DataSet/ITableMetaData.php1���@bW1��,�+;�������2���dbunit/Extensions/Database/DataSet/IYamlParser.php���@bW��@ۈ[�������6���dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php���@bW��Ʊ�¶������:���dbunit/Extensions/Database/DataSet/Persistors/Abstract.php -���@bW -��D:�������9���dbunit/Extensions/Database/DataSet/Persistors/Factory.php���@bW���(��������9���dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php����@bW���T�Z,�������:���dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php� ���@bW� ���O�Ӷ������5���dbunit/Extensions/Database/DataSet/Persistors/Xml.php5���@bW5����.��������6���dbunit/Extensions/Database/DataSet/Persistors/Yaml.php����@bW���*�勇������3���dbunit/Extensions/Database/DataSet/QueryDataSet.php� ���@bW� ��'�7u�������1���dbunit/Extensions/Database/DataSet/QueryTable.phpV���@bWV��lN���������9���dbunit/Extensions/Database/DataSet/ReplacementDataSet.php� -���@bW� -����O�������7���dbunit/Extensions/Database/DataSet/ReplacementTable.phph���@bWh��/��w�������?���dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php� ���@bW� ����Ns�������0���dbunit/Extensions/Database/DataSet/Specs/Csv.php� -���@bW� -��:�d=�������4���dbunit/Extensions/Database/DataSet/Specs/DbQuery.php����@bW�����Ķ������4���dbunit/Extensions/Database/DataSet/Specs/DbTable.php����@bW�����v�������4���dbunit/Extensions/Database/DataSet/Specs/Factory.php����@bW���A�̶������4���dbunit/Extensions/Database/DataSet/Specs/FlatXml.php����@bW����߆�������5���dbunit/Extensions/Database/DataSet/Specs/IFactory.phpl���@bWl���+�������0���dbunit/Extensions/Database/DataSet/Specs/Xml.php����@bW����TZ�������1���dbunit/Extensions/Database/DataSet/Specs/Yaml.php����@bW���{;>�������8���dbunit/Extensions/Database/DataSet/SymfonyYamlParser.phpO���@bWO���PW��������2���dbunit/Extensions/Database/DataSet/TableFilter.php� ���@bW� ��)Ŷ������:���dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php9 ���@bW9 ��52P�������1���dbunit/Extensions/Database/DataSet/XmlDataSet.phpt���@bWt�����D�������2���dbunit/Extensions/Database/DataSet/YamlDataSet.php|���@bW|��I�K�������,���dbunit/Extensions/Database/DefaultTester.php����@bW����X`��������(���dbunit/Extensions/Database/Exception.php���@bW��m�-`�������4���dbunit/Extensions/Database/IDatabaseListConsumer.php;���@bW;��4o�������&���dbunit/Extensions/Database/ITester.php����@bW�����#��������2���dbunit/Extensions/Database/Operation/Composite.php����@bW�����M�������/���dbunit/Extensions/Database/Operation/Delete.php���@bW���Z>0�������2���dbunit/Extensions/Database/Operation/DeleteAll.php����@bW����}^ �������2���dbunit/Extensions/Database/Operation/Exception.php/���@bW/���J��������0���dbunit/Extensions/Database/Operation/Factory.php���@bW��p{U��������;���dbunit/Extensions/Database/Operation/IDatabaseOperation.php����@bW���"��������/���dbunit/Extensions/Database/Operation/Insert.php����@bW��� td�������-���dbunit/Extensions/Database/Operation/Null.php����@bW�����0Ӷ������0���dbunit/Extensions/Database/Operation/Replace.php`���@bW`���d綶������1���dbunit/Extensions/Database/Operation/RowBased.php+���@bW+���c�X�������1���dbunit/Extensions/Database/Operation/Truncate.php� ���@bW� ���;�i�������/���dbunit/Extensions/Database/Operation/Update.php����@bW���W":˶������'���dbunit/Extensions/Database/TestCase.php���@bW����[i�������,���dbunit/Extensions/Database/TestCaseTrait.php6!���@bW6!��X#�K�������)���dbunit/Extensions/Database/UI/Command.phpI���@bWI���T��������)���dbunit/Extensions/Database/UI/Context.php���@bW���G�������)���dbunit/Extensions/Database/UI/IMedium.phpP���@bWP����Ԛ�������0���dbunit/Extensions/Database/UI/IMediumPrinter.php����@bW����}�0�������'���dbunit/Extensions/Database/UI/IMode.php����@bW�����d�������.���dbunit/Extensions/Database/UI/IModeFactory.php -���@bW -�������������6���dbunit/Extensions/Database/UI/InvalidModeException.php���@bW���*,�������.���dbunit/Extensions/Database/UI/Mediums/Text.php� ���@bW� ��o4�a�������-���dbunit/Extensions/Database/UI/ModeFactory.php= -���@bW= -���t�=�������5���dbunit/Extensions/Database/UI/Modes/ExportDataSet.php����@bW����X�q�������?���dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php� -���@bW� -���:Y�����������php-invoker/Invoker.php����@bW���w�������� ���php-invoker/TimeoutException.phpp���@bWp��~���������'���phpdocumentor-reflection-common/LICENSE9���@bW9��*2Ȑ�������+���phpdocumentor-reflection-common/Element.php1���@bW1���iUҶ������(���phpdocumentor-reflection-common/File.php7���@bW7���3"�������)���phpdocumentor-reflection-common/Fqsen.php����@bW���C���������,���phpdocumentor-reflection-common/Location.phpH���@bWH��?-��������+���phpdocumentor-reflection-common/Project.php���@bW��/H� �������2���phpdocumentor-reflection-common/ProjectFactory.php���@bW��Q�"ܶ������)���phpdocumentor-reflection-docblock/LICENSE8���@bW8����ʶ������.���phpdocumentor-reflection-docblock/DocBlock.php����@bW����/呶������:���phpdocumentor-reflection-docblock/DocBlock/Description.php� ���@bW� ������������A���phpdocumentor-reflection-docblock/DocBlock/DescriptionFactory.php0���@bW0���MD�������<���phpdocumentor-reflection-docblock/DocBlock/ExampleFinder.php����@bW�����+�������9���phpdocumentor-reflection-docblock/DocBlock/Serializer.php7���@bW7���@]D�������A���phpdocumentor-reflection-docblock/DocBlock/StandardTagFactory.phpx-���@bWx-���,K�������2���phpdocumentor-reflection-docblock/DocBlock/Tag.phpu���@bWu���������9���phpdocumentor-reflection-docblock/DocBlock/TagFactory.php���@bW��P;Ͷ������:���phpdocumentor-reflection-docblock/DocBlock/Tags/Author.php� ���@bW� ���tc�������;���phpdocumentor-reflection-docblock/DocBlock/Tags/BaseTag.php����@bW���X� -c�������:���phpdocumentor-reflection-docblock/DocBlock/Tags/Covers.phpJ���@bWJ���XL�������>���phpdocumentor-reflection-docblock/DocBlock/Tags/Deprecated.php -���@bW -��B�w$�������;���phpdocumentor-reflection-docblock/DocBlock/Tags/Example.phpQ���@bWQ����������H���phpdocumentor-reflection-docblock/DocBlock/Tags/Factory/StaticMethod.php����@bW����2i��������D���phpdocumentor-reflection-docblock/DocBlock/Tags/Factory/Strategy.php����@bW�����R�������=���phpdocumentor-reflection-docblock/DocBlock/Tags/Formatter.php����@bW���Dy7�������R���phpdocumentor-reflection-docblock/DocBlock/Tags/Formatter/PassthroughFormatter.php%���@bW%��I`��������;���phpdocumentor-reflection-docblock/DocBlock/Tags/Generic.phpX -���@bWX -��D� �������8���phpdocumentor-reflection-docblock/DocBlock/Tags/Link.phpN���@bWN��V���������:���phpdocumentor-reflection-docblock/DocBlock/Tags/Method.phpd���@bWd��iY&�������9���phpdocumentor-reflection-docblock/DocBlock/Tags/Param.php{���@bW{���v�O�������<���phpdocumentor-reflection-docblock/DocBlock/Tags/Property.php����@bW���T��̶������@���phpdocumentor-reflection-docblock/DocBlock/Tags/PropertyRead.php����@bW����ѝݶ������A���phpdocumentor-reflection-docblock/DocBlock/Tags/PropertyWrite.php����@bW������������;���phpdocumentor-reflection-docblock/DocBlock/Tags/Return_.php����@bW����R�������7���phpdocumentor-reflection-docblock/DocBlock/Tags/See.phpd���@bWd����O�������9���phpdocumentor-reflection-docblock/DocBlock/Tags/Since.php� ���@bW� ���P�������:���phpdocumentor-reflection-docblock/DocBlock/Tags/Source.phpm���@bWm���d%�������:���phpdocumentor-reflection-docblock/DocBlock/Tags/Throws.php����@bW����Ȉض������8���phpdocumentor-reflection-docblock/DocBlock/Tags/Uses.phpP���@bWP��T,��������8���phpdocumentor-reflection-docblock/DocBlock/Tags/Var_.php����@bW����L&�������;���phpdocumentor-reflection-docblock/DocBlock/Tags/Version.php� ���@bW� ��d�8�������5���phpdocumentor-reflection-docblock/DocBlockFactory.php�$���@bW�$��Jl�2�������>���phpdocumentor-reflection-docblock/DocBlockFactoryInterface.php!���@bW!����}�������#���phpdocumentor-type-resolver/LICENSE8���@bW8����ʶ������-���phpdocumentor-type-resolver/FqsenResolver.php����@bW���]Y��������$���phpdocumentor-type-resolver/Type.php����@bW�����[L�������,���phpdocumentor-type-resolver/TypeResolver.php�"���@bW�"��W.�������,���phpdocumentor-type-resolver/Types/Array_.phpN���@bWN��]ɤv�������-���phpdocumentor-type-resolver/Types/Boolean.php����@bW����f��������/���phpdocumentor-type-resolver/Types/Callable_.php����@bW���4ɿ�������.���phpdocumentor-type-resolver/Types/Compound.php ���@bW ��kd4b�������-���phpdocumentor-type-resolver/Types/Context.php]���@bW]���X�������4���phpdocumentor-type-resolver/Types/ContextFactory.php����@bW�����;�������,���phpdocumentor-type-resolver/Types/Float_.php����@bW����w,�������-���phpdocumentor-type-resolver/Types/Integer.php����@bW���"s��������+���phpdocumentor-type-resolver/Types/Mixed.php����@bW�����Z�������+���phpdocumentor-type-resolver/Types/Null_.php����@bW���@�%��������-���phpdocumentor-type-resolver/Types/Object_.phpk���@bWk�����������.���phpdocumentor-type-resolver/Types/Resource.php����@bW�����/�������,���phpdocumentor-type-resolver/Types/Scalar.php���@bW��U����������+���phpdocumentor-type-resolver/Types/Self_.php���@bW����9'�������-���phpdocumentor-type-resolver/Types/Static_.phpU���@bWU���ޟ�������-���phpdocumentor-type-resolver/Types/String_.php����@bW������������*���phpdocumentor-type-resolver/Types/This.php����@bW����h²�������+���phpdocumentor-type-resolver/Types/Void_.phpW���@bWW����ֶ���������phpspec-prophecy/LICENSE}���@bW}����6�������&���phpspec-prophecy/Prophecy/Argument.php����@bW���AT�������8���phpspec-prophecy/Prophecy/Argument/ArgumentsWildcard.php4 ���@bW4 ��A;K2�������:���phpspec-prophecy/Prophecy/Argument/Token/AnyValueToken.php����@bW���F�h�������;���phpspec-prophecy/Prophecy/Argument/Token/AnyValuesToken.php����@bW����bN/�������B���phpspec-prophecy/Prophecy/Argument/Token/ApproximateValueToken.php����@bW���#I��������<���phpspec-prophecy/Prophecy/Argument/Token/ArrayCountToken.php����@bW����4�̶������<���phpspec-prophecy/Prophecy/Argument/Token/ArrayEntryToken.php����@bW����J�:�������A���phpspec-prophecy/Prophecy/Argument/Token/ArrayEveryEntryToken.php����@bW���pb���������:���phpspec-prophecy/Prophecy/Argument/Token/CallbackToken.php,���@bW,��cR�̶������<���phpspec-prophecy/Prophecy/Argument/Token/ExactValueToken.php����@bW�����3��������@���phpspec-prophecy/Prophecy/Argument/Token/IdenticalValueToken.php����@bW��������������<���phpspec-prophecy/Prophecy/Argument/Token/LogicalAndToken.php����@bW��� N�v�������<���phpspec-prophecy/Prophecy/Argument/Token/LogicalNotToken.php���@bW����r�������=���phpspec-prophecy/Prophecy/Argument/Token/ObjectStateToken.php9 -���@bW9 -��_�Jg�������@���phpspec-prophecy/Prophecy/Argument/Token/StringContainsToken.php����@bW������>�������;���phpspec-prophecy/Prophecy/Argument/Token/TokenInterface.php����@bW���ٰ���������6���phpspec-prophecy/Prophecy/Argument/Token/TypeToken.php����@bW����n�\�������'���phpspec-prophecy/Prophecy/Call/Call.php� ���@bW� ��{:�%�������-���phpspec-prophecy/Prophecy/Call/CallCenter.php����@bW����|��������:���phpspec-prophecy/Prophecy/Comparator/ClosureComparator.phpK���@bWK��)RQ�������0���phpspec-prophecy/Prophecy/Comparator/Factory.php����@bW���ֈi��������;���phpspec-prophecy/Prophecy/Comparator/ProphecyComparator.phps���@bWs����hǶ������3���phpspec-prophecy/Prophecy/Doubler/CachedDoubler.php����@bW���̇g�������D���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ClassPatchInterface.phpl���@bWl��)�5:�������H���phpspec-prophecy/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php����@bW���:0`�������C���phpspec-prophecy/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php����@bW���x��^�������=���phpspec-prophecy/Prophecy/Doubler/ClassPatch/KeywordPatch.php����@bW����/@ȶ������?���phpspec-prophecy/Prophecy/Doubler/ClassPatch/MagicCallPatch.php����@bW�����|��������E���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php� -���@bW� -���n�i�������P���phpspec-prophecy/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.phpp���@bWp��x����������A���phpspec-prophecy/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.phpQ -���@bWQ -����[��������A���phpspec-prophecy/Prophecy/Doubler/ClassPatch/TraversablePatch.php ���@bW ����jN�������5���phpspec-prophecy/Prophecy/Doubler/DoubleInterface.php����@bW���8d�j�������-���phpspec-prophecy/Prophecy/Doubler/Doubler.php����@bW���8]�^�������B���phpspec-prophecy/Prophecy/Doubler/Generator/ClassCodeGenerator.php7 ���@bW7 ���О��������<���phpspec-prophecy/Prophecy/Doubler/Generator/ClassCreator.php����@bW����?Br�������;���phpspec-prophecy/Prophecy/Doubler/Generator/ClassMirror.php����@bW���Օ�c�������A���phpspec-prophecy/Prophecy/Doubler/Generator/Node/ArgumentNode.php����@bW����>�X�������>���phpspec-prophecy/Prophecy/Doubler/Generator/Node/ClassNode.phpI���@bWI���)Uݶ������?���phpspec-prophecy/Prophecy/Doubler/Generator/Node/MethodNode.php����@bW���'�������C���phpspec-prophecy/Prophecy/Doubler/Generator/ReflectionInterface.php����@bW�������������0���phpspec-prophecy/Prophecy/Doubler/LazyDouble.phpF ���@bWF ����l��������3���phpspec-prophecy/Prophecy/Doubler/NameGenerator.php����@bW�����7�������D���phpspec-prophecy/Prophecy/Exception/Call/UnexpectedCallException.php����@bW������������E���phpspec-prophecy/Prophecy/Exception/Doubler/ClassCreatorException.php����@bW���77/%�������D���phpspec-prophecy/Prophecy/Exception/Doubler/ClassMirrorException.php����@bW���ۉ?�������F���phpspec-prophecy/Prophecy/Exception/Doubler/ClassNotFoundException.php����@bW���h+������?���phpspec-prophecy/Prophecy/Exception/Doubler/DoubleException.php����@bW���z�F��������@���phpspec-prophecy/Prophecy/Exception/Doubler/DoublerException.php����@bW����Z^�������J���phpspec-prophecy/Prophecy/Exception/Doubler/InterfaceNotFoundException.php����@bW��������������L���phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotExtendableException.phpD���@bWD���p��������G���phpspec-prophecy/Prophecy/Exception/Doubler/MethodNotFoundException.php����@bW���i�h�������J���phpspec-prophecy/Prophecy/Exception/Doubler/ReturnByReferenceException.php����@bW������������1���phpspec-prophecy/Prophecy/Exception/Exception.php+���@bW+������������@���phpspec-prophecy/Prophecy/Exception/InvalidArgumentException.php����@bW����g��������E���phpspec-prophecy/Prophecy/Exception/Prediction/AggregateException.php����@bW���?D<ζ������L���phpspec-prophecy/Prophecy/Exception/Prediction/FailedPredictionException.phpJ���@bWJ��~��D�������C���phpspec-prophecy/Prophecy/Exception/Prediction/NoCallsException.php����@bW����l<��������F���phpspec-prophecy/Prophecy/Exception/Prediction/PredictionException.php����@bW���2T�Ѷ������P���phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php���@bW��� ƶ������K���phpspec-prophecy/Prophecy/Exception/Prediction/UnexpectedCallsException.php,���@bW,�����a�������H���phpspec-prophecy/Prophecy/Exception/Prophecy/MethodProphecyException.php)���@bW)��F��4�������H���phpspec-prophecy/Prophecy/Exception/Prophecy/ObjectProphecyException.php���@bW���:�F�������B���phpspec-prophecy/Prophecy/Exception/Prophecy/ProphecyException.php����@bW�����$϶������I���phpspec-prophecy/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.phpx���@bWx��rЬ�������=���phpspec-prophecy/Prophecy/PhpDocumentor/ClassTagRetriever.phpD���@bWD��d9�϶������C���phpspec-prophecy/Prophecy/PhpDocumentor/LegacyClassTagRetriever.phpo���@bWo��u9��������G���phpspec-prophecy/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php����@bW����;��������7���phpspec-prophecy/Prophecy/Prediction/CallPrediction.phpQ ���@bWQ ��I��������<���phpspec-prophecy/Prophecy/Prediction/CallTimesPrediction.php����@bW���X���������;���phpspec-prophecy/Prophecy/Prediction/CallbackPrediction.php����@bW���Vb{ζ������:���phpspec-prophecy/Prophecy/Prediction/NoCallsPrediction.php����@bW���L9%�������<���phpspec-prophecy/Prophecy/Prediction/PredictionInterface.php����@bW���`IE�������5���phpspec-prophecy/Prophecy/Promise/CallbackPromise.php����@bW���[���������6���phpspec-prophecy/Prophecy/Promise/PromiseInterface.phpK���@bWK������������;���phpspec-prophecy/Prophecy/Promise/ReturnArgumentPromise.php'���@bW'���(���������3���phpspec-prophecy/Prophecy/Promise/ReturnPromise.php���@bW���؏�������2���phpspec-prophecy/Prophecy/Promise/ThrowPromise.php` -���@bW` -��+��,�������5���phpspec-prophecy/Prophecy/Prophecy/MethodProphecy.php�,���@bW�,���?�������5���phpspec-prophecy/Prophecy/Prophecy/ObjectProphecy.php����@bW����5D�������8���phpspec-prophecy/Prophecy/Prophecy/ProphecyInterface.php,���@bW,���W�������?���phpspec-prophecy/Prophecy/Prophecy/ProphecySubjectInterface.php����@bW���i��������/���phpspec-prophecy/Prophecy/Prophecy/Revealer.php����@bW���j�ɸ�������8���phpspec-prophecy/Prophecy/Prophecy/RevealerInterface.phpH���@bWH���gZ��������%���phpspec-prophecy/Prophecy/Prophet.php���@bW���vq��������-���phpspec-prophecy/Prophecy/Util/ExportUtil.php2���@bW2���W��������-���phpspec-prophecy/Prophecy/Util/StringUtil.php� ���@bW� ��%�����������myclabs-deep-copy/LICENSE5���@bW5��ʭ˄�������'���myclabs-deep-copy/DeepCopy/DeepCopy.php+���@bW+���Q ��������7���myclabs-deep-copy/DeepCopy/Exception/CloneException.php`����@bW`���.ڝ��������G���myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php����@bW����xkж������L���myclabs-deep-copy/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.phpe���@bWe��+�ֶ������,���myclabs-deep-copy/DeepCopy/Filter/Filter.phpS���@bWS��ks�k�������0���myclabs-deep-copy/DeepCopy/Filter/KeepFilter.php�����@bW�����ߝ��������3���myclabs-deep-copy/DeepCopy/Filter/ReplaceFilter.php���@bW��̎|��������3���myclabs-deep-copy/DeepCopy/Filter/SetNullFilter.php����@bW����M䧶������.���myclabs-deep-copy/DeepCopy/Matcher/Matcher.php�����@bW����(�(��������6���myclabs-deep-copy/DeepCopy/Matcher/PropertyMatcher.php����@bW���u�օ�������:���myclabs-deep-copy/DeepCopy/Matcher/PropertyNameMatcher.php����@bW���y㻞�������:���myclabs-deep-copy/DeepCopy/Matcher/PropertyTypeMatcher.php����@bW���o����������:���myclabs-deep-copy/DeepCopy/Reflection/ReflectionHelper.php���@bW��&ԋ�������7���myclabs-deep-copy/DeepCopy/TypeFilter/ReplaceFilter.php����@bW����;If�������;���myclabs-deep-copy/DeepCopy/TypeFilter/ShallowCopyFilter.php�����@bW����ت���������4���myclabs-deep-copy/DeepCopy/TypeFilter/TypeFilter.php�����@bW����9�4�������6���myclabs-deep-copy/DeepCopy/TypeMatcher/TypeMatcher.php����@bW���ʨ������������webmozart-assert/LICENSE<���@bW<��t�}�����������webmozart-assert/Assert.php�l���@bW�l����=����������phpunit/Exception.phps���@bWs��y:�۶������%���phpunit/Extensions/GroupTestSuite.php����@bW���0����������#���phpunit/Extensions/PhptTestCase.php�.���@bW�.������������$���phpunit/Extensions/PhptTestSuite.php���@bW�� ��ܶ������#���phpunit/Extensions/RepeatedTest.php����@bW�������������$���phpunit/Extensions/TestDecorator.php@ ���@bW@ ����9�������%���phpunit/Extensions/TicketListener.php"���@bW"��]N�������)���phpunit/ForwardCompatibility/TestCase.phpZ���@bWZ���9�����������phpunit/Framework/Assert.php�[��@bW�[�H��1�������&���phpunit/Framework/Assert/Functions.php�����@bW�����i���������*���phpunit/Framework/AssertionFailedError.php{���@bW{��+���������&���phpunit/Framework/BaseTestListener.php����@bW���_03�������+���phpunit/Framework/CodeCoverageException.phpq���@bWq��E���������� ���phpunit/Framework/Constraint.php9���@bW9��z}��������$���phpunit/Framework/Constraint/And.php+���@bW+��\����������,���phpunit/Framework/Constraint/ArrayHasKey.php����@bW���V���������,���phpunit/Framework/Constraint/ArraySubset.phpI���@bWI���c��������*���phpunit/Framework/Constraint/Attribute.php� ���@bW� ��l���������)���phpunit/Framework/Constraint/Callback.php3���@bW3������������2���phpunit/Framework/Constraint/ClassHasAttribute.php����@bW����b�������8���phpunit/Framework/Constraint/ClassHasStaticAttribute.php����@bW�����-��������*���phpunit/Framework/Constraint/Composite.php����@bW����4~)�������&���phpunit/Framework/Constraint/Count.php� ���@bW� ��u���������*���phpunit/Framework/Constraint/Exception.php����@bW����+��������.���phpunit/Framework/Constraint/ExceptionCode.php[���@bW[�����������1���phpunit/Framework/Constraint/ExceptionMessage.phpC���@bWC�������������7���phpunit/Framework/Constraint/ExceptionMessageRegExp.php`���@bW`����0}�������+���phpunit/Framework/Constraint/FileExists.php����@bW���+�2�������,���phpunit/Framework/Constraint/GreaterThan.php����@bW����O�R�������+���phpunit/Framework/Constraint/IsAnything.phpo���@bWo��*�KT�������(���phpunit/Framework/Constraint/IsEmpty.php&���@bW&�����v�������(���phpunit/Framework/Constraint/IsEqual.php!���@bW!�� (Q�������(���phpunit/Framework/Constraint/IsFalse.phpu���@bWu��ֻ� �������)���phpunit/Framework/Constraint/IsFinite.php~���@bW~��@h�.�������,���phpunit/Framework/Constraint/IsIdentical.php����@bW���Fy�;�������+���phpunit/Framework/Constraint/IsInfinite.php����@bW�������������-���phpunit/Framework/Constraint/IsInstanceOf.php����@bW�����`Ѷ������'���phpunit/Framework/Constraint/IsJson.php5���@bW5��C7�F�������&���phpunit/Framework/Constraint/IsNan.phpr���@bWr����}��������'���phpunit/Framework/Constraint/IsNull.phpq���@bWq���^�`�������'���phpunit/Framework/Constraint/IsTrue.phpq���@bWq��*%���������'���phpunit/Framework/Constraint/IsType.phpo ���@bWo ��F&�{�������,���phpunit/Framework/Constraint/JsonMatches.php ���@bW ����Ҷ������A���phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php����@bW���d��������)���phpunit/Framework/Constraint/LessThan.php����@bW���4�w϶������$���phpunit/Framework/Constraint/Not.php����@bW���+�,�������3���phpunit/Framework/Constraint/ObjectHasAttribute.php����@bW�����/�������#���phpunit/Framework/Constraint/Or.php[���@bW[��N?�G�������*���phpunit/Framework/Constraint/PCREMatch.php����@bW��������������)���phpunit/Framework/Constraint/SameSize.phpS���@bWS��/#�S�������/���phpunit/Framework/Constraint/StringContains.php2���@bW2���]�.�������/���phpunit/Framework/Constraint/StringEndsWith.php����@bW���v�>g�������.���phpunit/Framework/Constraint/StringMatches.php ���@bW ���;R-�������1���phpunit/Framework/Constraint/StringStartsWith.php����@bW�����[�������4���phpunit/Framework/Constraint/TraversableContains.php� ���@bW� ��:Z5������8���phpunit/Framework/Constraint/TraversableContainsOnly.php� ���@bW� ��g|s�������$���phpunit/Framework/Constraint/Xor.php����@bW����{����������phpunit/Framework/Error.php$���@bW$��X%yW�������&���phpunit/Framework/Error/Deprecated.phpF���@bWF����V�������"���phpunit/Framework/Error/Notice.php0���@bW0���I���������#���phpunit/Framework/Error/Warning.php3���@bW3��mO������������phpunit/Framework/Exception.php ���@bW ���~b��������&���phpunit/Framework/ExceptionWrapper.php����@bW������������0���phpunit/Framework/ExpectationFailedException.php����@bW���_S�;�������$���phpunit/Framework/IncompleteTest.php����@bW����J�������(���phpunit/Framework/IncompleteTestCase.php5���@bW5��.�S��������)���phpunit/Framework/IncompleteTestError.php���@bW��Ht��������2���phpunit/Framework/InvalidCoversTargetException.php����@bW���%M��������!���phpunit/Framework/OutputError.php����@bW���j�̶������G���phpunit/Framework/PHPUnit_Framework_CoveredCodeNotExecutedException.php���@bW���ϡǶ������H���phpunit/Framework/PHPUnit_Framework_MissingCoversAnnotationException.php���@bW����ö���������phpunit/Framework/RiskyTest.php����@bW����\�������$���phpunit/Framework/RiskyTestError.php���@bW��?�v�������$���phpunit/Framework/SelfDescribing.php���@bW��:�|�������!���phpunit/Framework/SkippedTest.php����@bW����_ $�������%���phpunit/Framework/SkippedTestCase.php����@bW���`�u�������&���phpunit/Framework/SkippedTestError.php ���@bW ���T�������+���phpunit/Framework/SkippedTestSuiteError.php���@bW����7<�������$���phpunit/Framework/SyntheticError.php ���@bW ���K����������phpunit/Framework/Test.php����@bW�����%����������phpunit/Framework/TestCase.php3��@bW3�E����������!���phpunit/Framework/TestFailure.php����@bW���ai�ʶ������"���phpunit/Framework/TestListener.php]���@bW]������������ ���phpunit/Framework/TestResult.php)����@bW)������j����������phpunit/Framework/TestSuite.php�s���@bW�s��Cۖ��������,���phpunit/Framework/TestSuite/DataProvider.php����@bW����<Us�������5���phpunit/Framework/UnintentionallyCoveredCodeError.php���@bW���摢����������phpunit/Framework/Warning.phpp���@bWp��t�d�������%���phpunit/Framework/WarningTestCase.php����@bW���rJ@ö������!���phpunit/Runner/BaseTestRunner.php{���@bW{��DJ�{����������phpunit/Runner/Exception.phpt���@bWt���d���������!���phpunit/Runner/Filter/Factory.php����@bW����ἕ����������phpunit/Runner/Filter/Group.php����@bW���km1��������'���phpunit/Runner/Filter/Group/Exclude.php����@bW�����PF�������'���phpunit/Runner/Filter/Group/Include.php����@bW���Ve����������phpunit/Runner/Filter/Test.php���@bW��a���������*���phpunit/Runner/StandardTestSuiteLoader.php� ���@bW� ����� �������"���phpunit/Runner/TestSuiteLoader.php����@bW���������������phpunit/Runner/Version.php����@bW����/7�����������phpunit/TextUI/Command.phph����@bWh����4Զ������ ���phpunit/TextUI/ResultPrinter.phphI���@bWhI��|銶���������phpunit/TextUI/TestRunner.php����@bW���ݬ�{����������phpunit/Util/Blacklist.php� ���@bW� ���YW����������phpunit/Util/Configuration.phpX����@bWX�����K�������'���phpunit/Util/ConfigurationGenerator.php|���@bW|���0������������phpunit/Util/ErrorHandler.php} ���@bW} ��*��z����������phpunit/Util/Fileloader.php����@bW������>����������phpunit/Util/Filesystem.php����@bW�����{����������phpunit/Util/Filter.php����@bW���i�����������phpunit/Util/Getopt.php����@bW����������������phpunit/Util/GlobalState.php%���@bW%���ޫ�������&���phpunit/Util/InvalidArgumentHelper.phpS���@bWS��(Qϩ����������phpunit/Util/Log/JSON.phpa���@bWa���L�x����������phpunit/Util/Log/JUnit.php�3���@bW�3����蒶���������phpunit/Util/Log/TAP.php����@bW������?����������phpunit/Util/Log/TeamCity.php�+���@bW�+��H�uֶ���������phpunit/Util/PHP.phpi)���@bWi)����U:����������phpunit/Util/PHP/Default.phpa���@bWa��r��?�������1���phpunit/Util/PHP/Template/TestCaseMethod.tpl.dist� -���@bW� -���S������������phpunit/Util/PHP/Windows.php$���@bW$��5�1I����������phpunit/Util/PHP/eval-stdin.php6����@bW6�����G����������phpunit/Util/Printer.phpl���@bWl��4[�����������phpunit/Util/Regex.php����@bW����P�d����������phpunit/Util/String.php���@bW�����d����������phpunit/Util/Test.php�����@bW������"��������'���phpunit/Util/TestDox/NamePrettifier.phpt���@bWt����������&���phpunit/Util/TestDox/ResultPrinter.php�&���@bW�&���X�,�������+���phpunit/Util/TestDox/ResultPrinter/HTML.php-���@bW-���&�������+���phpunit/Util/TestDox/ResultPrinter/Text.phpw���@bWw�� ;���������*���phpunit/Util/TestDox/ResultPrinter/XML.php����@bW�����i�������"���phpunit/Util/TestSuiteIterator.php����@bW����⍘����������phpunit/Util/Type.php3���@bW3����N����������phpunit/Util/XML.php����@bW���a�¶������phpunit/phpunit: 5.4.6 -doctrine/instantiator: 1.0.5 -myclabs/deep-copy: 1.5.1 -phpdocumentor/reflection-common: 1.0 -phpdocumentor/reflection-docblock: 3.1.0 -phpdocumentor/type-resolver: 0.2 -phpspec/prophecy: v1.6.1 -phpunit/dbunit: 2.0.2 -phpunit/php-code-coverage: 4.0.0 -phpunit/php-file-iterator: 1.4.1 -phpunit/php-invoker: 1.1.4 -phpunit/php-text-template: 1.2.1 -phpunit/php-timer: 1.0.8 -phpunit/php-token-stream: 1.4.8 -phpunit/phpunit-mock-objects: 3.2.3 -sebastian/code-unit-reverse-lookup: 1.0.0 -sebastian/comparator: 1.2.0 -sebastian/diff: 1.4.1 -sebastian/environment: 1.3.7 -sebastian/exporter: 1.2.1 -sebastian/global-state: 1.1.1 -sebastian/object-enumerator: 1.0.0 -sebastian/recursion-context: 1.0.2 -sebastian/resource-operations: 1.0.0 -sebastian/version: 2.0.0 -symfony/yaml: v3.1.1 -webmozart/assert: 1.0.2 ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- -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. -<?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->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'); - } - } -} -<?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(); -} -<?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(); - } -} -<?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; - } -} -<?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]; - } -} -<?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 -{ -} -<?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 -{ -} -<?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 - ) - ); - } -} -<?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 -{ -} -<?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 -{ -} -<?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; - } -} -<?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; - } -} -<?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(); -} -<?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); - } -} -<?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; - } -} -<?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 $numTestedTraits = 0; - - /** - * @var int - */ - private $numTestedClasses = 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() - { - return count($this->classes); - } - - /** - * Returns the number of tested classes. - * - * @return int - */ - public function getNumTestedClasses() - { - return $this->numTestedClasses; - } - - /** - * Returns the number of traits. - * - * @return int - */ - public function getNumTraits() - { - return count($this->traits); - } - - /** - * 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; - } else { - $trait['coverage'] = 100; - } - - if ($trait['coverage'] == 100) { - $this->numTestedClasses++; - } - - $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; - } else { - $class['coverage'] = 100; - } - - if ($class['coverage'] == 100) { - $this->numTestedClasses++; - } - - $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'], - ]; - } -} -<?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; - } -} -<?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; - } -} -<?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); - } -} -<?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; - -/** - * 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 - ) - ); - } -} -<?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.0', 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 = ' / '; - - 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 = 'success'; - $classesNumber = '0' . $numSeparator . '0'; - $classesBar = $this->getCoverageBar(100); - } - - if ($data['numMethods'] > 0) { - $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']); - - $methodsNumber = $data['numTestedMethods'] . $numSeparator . - $data['numMethods']; - - $methodsBar = $this->getCoverageBar( - $data['testedMethodsPercent'] - ); - } else { - $methodsLevel = 'success'; - $methodsNumber = '0' . $numSeparator . '0'; - $methodsBar = $this->getCoverageBar(100); - $data['testedMethodsPercentAsString'] = '100.00%'; - } - - if ($data['numExecutableLines'] > 0) { - $linesLevel = $this->getColorLevel($data['linesExecutedPercent']); - - $linesNumber = $data['numExecutedLines'] . $numSeparator . - $data['numExecutableLines']; - - $linesBar = $this->getCoverageBar( - $data['linesExecutedPercent'] - ); - } else { - $linesLevel = 'success'; - $linesNumber = '0' . $numSeparator . '0'; - $linesBar = $this->getCoverageBar(100); - $data['linesExecutedPercentAsString'] = '100.00%'; - } - - $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; - } -} -<?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() - ); - } -} -<?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 - ); - } -} -<?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++; - } - } - - $buffer .= $this->renderItemTemplate( - $template, - [ - 'name' => $name, - 'numClasses' => 1, - 'numTestedClasses' => $numTestedMethods == $numMethods ? 1 : 0, - 'numMethods' => $numMethods, - 'numTestedMethods' => $numTestedMethods, - '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( - $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, - ' ' - ); - } - } - - 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", ' '], - [' ', ' '], - 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; - } -} - <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> -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 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:thin dotted;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:thin dotted;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:thin dotted;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 */.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}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; -} -<!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(key, y, e, 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(key, y, e, 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> -<!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> </td> - <td colspan="9"><div align="center"><strong>Code Coverage</strong></div></td> - </tr> - <tr> - <td> </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> - <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> - -<!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> </td> - <td colspan="10"><div align="center"><strong>Code Coverage</strong></div></td> - </tr> - <tr> - <td> </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> - <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> - -�N��AM���������������������LP����������������������',������������������(�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s����R�e�g�u�l�a�r���x�V�e�r�s�i�o�n� �1�.�0�0�9�;�P�S� �0�0�1�.�0�0�9�;�h�o�t�c�o�n�v� �1�.�0�.�7�0�;�m�a�k�e�o�t�f�.�l�i�b�2�.�5�.�5�8�3�2�9���8�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s� �R�e�g�u�l�a�r�����BSGP��������������������M�M�F�����٣(uʌ<0D�B/X �N���CC�^�rmR2sk��PJ"5+�gl�W*i�W�/E�4#�ԣU�~�f��UD�Ĺ�����J�1�/!��/���s�7��k���(���hN��8o��d$yq��1���9�@-��HG���S"�Fj�ؠ6C3��&�����W51����B��a��QaR�U/��{*������=�@d��h$�1�Tۗnc+c��A��� �Zɀ�@Q�c�a���l��2>�K��m�' ��C�HMĬfB�X�,�Y��p�e�� -U��*Ҕz� -m���iO1nE�.��� hx!aC -XT�V������R��%�|I�H���P�5"�b�N��=���r�/_�R����_�%҄�uz��Ҙ�5�2ġ��P�)������F�7S�q�F�{n�ia���@D�s�;�}9⬥?ź���R{�Tk�;ǜ�U\N�Z��Q-�^�s�7�f0���S3A� _n��`W7Pp����i���!�g�/�_p���Z�-=�ץ~WZ#/�4 KF�`� ��z��0�| D�ѵ����&däI����Ï�;�M�{'�om��m�I!wi9|H:�ۧ�������{�~���q���O�����,� �L]&�J0��9/�9&�Y�蓰{;��'�3`�e�@vH�yDZ$���3���Dx28�W� Cx5xw�B`�$C$'��El�y��h��Ԁ DJ -$(p���QA�A܉A�@'�$ hp�0�V0 `��s��e�$�4$"t2=f��4�A�{Tk�0|rH������`L&��s�h�]��A<����`R�'��!���1N�;�_�t3�#� ������V��*ve�F`E O$�{)�W=p:���F`��2��2ړC����^�.�ć�����G�<<?���~z������>�.p�Ne2��ִ��+Y�s�l:��˼�ܫu5�����t�u�^8��6��ȄTmy�Q�%�u~��%~1rҘa�wߚ^��_�Z��Z�a���0!������N�`�.� uq����YB�\����ᨀ��[e�����:@��J'Eہ,�3ubj@�p������f����eW9( �����ޅ���=�l�G��7gj �S�M6����0��9�Oˑ����l��B�a�݁��<����Bՙ(VRAp�f�^���+g9�q�����M�t]�ت�p�E��r@]�@��V��kV� -u��d�^�X ���R@?E��Y2�����]#�Ǽ�4�J��K����'���d��PC|m�m�n�#��$+48u'���e&���[n[L������%{BCD�L:^!����bƙ:&����g3�-3��u�������b iLZ�ڂW�FS��Id��6.�k5P�l7�7�Uz�T:N�N���.�"����)����['�|U"A�����I���v�w���p���t�dk���9���嫫�9�n�D�mq��7I|6�Kbc�]�M���������B�A��B�Ȫ�_�J�T��q � 6@����F�����hd`G��T��:M�7'��L,�Ih��FP ��~j�������$¡ �3�hA�����-S�^�چ����-%qe���~��Qq���ln"i��&����Qe?FlK�"�As�(�3Y;"�L���e�t�'�Rz<MW!��S�3$rZ:��b�-^DŽ/�$Q��q�JB'Wd�GAO����`.�( ���o�3�B0���ɑ�1��p(���(*�o�^�Ǫk��J`v��[���C|9�=����#��A��Q���# ���7;.]L:��ϸc���d���i��Esr�����6?�}��e�@H-��b���ƖC�1;����. �v.�ɾ$`T������ JW����%B�Z�I04����^:kU,��C�^�WVF����`�F�b��(�O��O��2<��@�X�u����g~�ɑ�W �t�&1\�1�L�:φ��"�!�P�����3/���^��ǰ�q��w`IA��D -�)�q�C�f��O�� ��0�2Y29�3N��f�p�����\��C���ah��&�6�p�`�ځz�g�B -hRf����];]�#pw_t(�pq꿏ٷ,���bdk�R��B����T?��2����2�c�F�y2��%���C�n�9����0����9E&#�l�T__�Sлg�)eh/ڷ+�#:FGot�k5Gbr;Cb˴�:���#��ɜ &����QC��w����mxlN��q����P��)�͐3f-v5K���h��0Aכ���j�nSp� ��^H��G�F��f����H� "%[ѻ��� @���p �a��α��$$��͂�*��_�\��@>M��10�{=��)���K�%�$C -���9�M����4c �Eotj��V�GD�)l�8��,�\w���!�%$��3t� TBz��Ҵ iUJ��[��xgd�Br�$�!eq���"J>�� )\�~����3�(^ �R8#>�b��H��G'7_fӫcκtD�oAA߃�(q�B<�`��`V����Ϋ��֘�*�b��u�P�4v@�+��.���Q�ԥ$V����@C0 -�R��ܐP[�z:X�H#e���s�>?�E�WO>@I�$|s��i� -ES��)0A�?�9�ab,��@K��̩o&�����Q�%�ϞLu+� -�+�H|�Ɛ?�NK�4����CnPt� 'OT��.j5�Ĵ8��v�w֜��I�&�+�`��yS��caO[#�g��Q�����d�[�K�I矗`�ČLP��� #���� �)2�7aT���i@c\ސ�����0n�C�p�ߖ運4͵��x�*���R�z�Y�b����T[\�kU�v�Hʈ�q�pI��I�ŗ)�bB X�P�N���tz� 2 I�==� ������;}�b���q��jiކ�a�#" ��>1����1�A��p1���P��O��O�ux�Q����� -Fϲ(�h݄�O'MDx�L�K$ȵ�h�& �����1���4��Si���rHJ�P�t�DM�;rM�+��� -*����ؗ5u2$�f3�K �<�P�L�r�c�I)����^�da> -%��ѳb(���@,�2f,~"�7�R;�E��;���HX�(���4�2Z��'�T�ۿ������2J+�^!#o����Y~4�-׃�GW*�!��A�0&8�f�{`����W�=�DP8�'�= �R� g�}�iP>��#���4��E�BRY��^4e�����N8��V,[B��Ĩ�D#�X��]�,���LBsNC> +��o��^x�� -�����jC�.4�Ya�_{e�A2=r���+�������9PO�A!! -�}�Y�PJe���Gn��%x��1�/}RgH��a�^3-�� �5 -�|�qS���aWK{1al`I�1���Q��f_yyCZ)�L3X�]W6@DM�T�<.��u�G�K��8�Ds��бW�r��\�7Z\����V�"I����S���d��>C���U�j���e����D �3M�tWcP����Ӊ6#3Q��nቩ��J\���7�#磱`K�� ��lV6&�T�� �~��l.���� <��BP -�*�!zRZ��eљ���ٷT�#�C�LH����W�)�D����p�YU#��51{WJ���4^�f�̼Z����y6�ӑT2�d�4H=�B�Ҋ��}�&݃��,aPçv+:2�~��*0����d�ɓ��փd ���!"A+�r��Hn���sA���ڗU ����b�H��N6�$.�l�};�@���iK� \�҂:v�QE��:,|��Q� Y0|�%�@�� ܁�qc���dqh��諹v�C�GV�����-(��m��1���q89KF��ä -"2��}Rrz�,j^��q�\�ݖ#p��+�`fl�����:k�t�5E�OaI�J�P @ps�E�j1�4;6��/aH�.��ӰT�X�p�L���L8��F�ܚi�l�1��Y؊8� %�!/��{�����霋���X���b�����N��xp���PW�����cI9g�*�����%:��L��u��CAO��%�/œ�(Y��^�?����&I'��uh[x���Q�$�zҵŽ�� ߳���(=V׀�� �m��U)��lΠΒ��i��d㦈���~f��jG���R{D�%>���@���6���1��`�!� ` ���wY�����k/a�0A��¹�ԁ��Yh�����d��x��k:f�����<���WL4�`8IYMB�Slc������-�E҂'�ڌ�:,�D�������Ʃ84�)~��2�j���Ǡi��B(L�|"a����4,�b8���ԓi 94�����jWщ��6*��T��c4g�̓��UM�b�R�E������C5��)j�ȴ ��1�6pb���ƎH���Fx������ģ�%4��Q��C�ʈ�� $9�:�M>�E��a��o��̟^��<Iw��Ygq�7s[��� -y�1ع5��a��MK�א�RB�Y���Fq}����8���*�Nt�'.Yb������Z��v�K -(�]&ɜ�(�ՙ��2�:0� ��o�ΏхPKiBH4U�X,���[��$ -0�mX��ش�� �f�5�0��VR �8�%����ާ�Dt��U��s`��-BP��z�P�s���vI�8z-�t1DiB -��"˶��YTJ ��.�?�0�7��jL��N��[2�t��Į̎�����#�6?E�������:ɞ�Y;��A&q��S�IR�)�ss -9*x��0Bj)m��H�A��hyЏh�Mm�&4Ŋ�4�����g��V�&tY����OCS0�Y��d7Mv�N�j)w��A�(��o "͢�[�� -E`�����7ez�ď����-�Q�]�6�+Bca�@^I�:�һ����=�����sS���nc��� 6 ���O�B�4����L���Gp�B�q/<�zA��C��� ��A~��x�06rih��h�I�طO�N,:o��k�����/�{H�,�zЂg�fȻz���5��F��Tr�n/�t``l���*H6jT�tG/x��@P@(��I�p �e�!��`wv,:A쑜�N� 4}09z�qC���$r���M`Y�Q����M�䕫���(|�B!�>���>�O pwj A*@����J�C[h&3���B Qb�ϩ8�:�%f~�v/�l�S����0�����0a���"<TX�@�&���Jg� 3ϕ��HF��o��I8��{��:YT��b(��P�j�<za{��wX�oa�04 �3��l��GȶN��0>�B�8(f �uGoǚ�gy���t�_�y~�͔� -�%����m��L -��!I$�X<T+�3��dq� -D�M��t��2|fEV([�]�Ndb��D3Sp'R�G�m�K��<�T��ٰ�}�5iܷ�ʹ���p����#�&jF �Z�'���2�%y9�Q#2�H]w�A�}�vf������%�����X�Ӛ��)�X_�S0�t�(���-��ⰓjHp��Ӗv��/���詵�,9�w<`�E�� -��F�agA�ٓ�Љt��)l�e -���;���$9����{�C������()��?���p���IF����������b3���l[):�drr]�?�Ֆ��?��Bd�i�D������7��hJ��: -��U%n�3aƬJ.�>t0���~�e�P�z��]�U�g Н=_�?���.j#+`li�� B���M5�� ��őG�p��7�a -�֒�%Y[UG9����@\bD��Y��{��{��ED0�� -�$��Q�+FvC�`ݨ�3��Q� ��E\��uC9���![�$�l��������6�D�o�Dg�G�*+�X!��%#�C�q�?�8ZUB)U@o��pgީ�Z�q����8��9���|uc�cAќ����W;�@�"���>P����h_���9}.6���V/�O:�3�}��ZS���{:��~�����y�k�c���O6;O�B�=�bV�. R�k� -o���^�GV=�� }�oI"+ � -]w���F��zϷ��`<����30��h���3]�Rf���859s�`K�M��8�� -X�Uq�<���\���ZO�ss�M��&j&� ��� .�%���P�BL~^����G�ˈ�3p�D���:����Z������<\�Ǡi���W̆���"(��:���z���X�~��0PG]8������RQMNT��qf�W~!�0�R%Ց�0�xvGFy/F�-��w�u�/��*�+�� \��8@�6��������c<��L�;c�[������ºnr �QS'o�Qu�T�{qҐ�_�Ϳ���Sd��A*ð:m�8Yuz2�PB� �Hh`l�k�p��LLh -cEb6eۏ�ҋ ?!��>|*=V����K�@��rx�0�G`%ryr[6�Y3�7���f*�*n��%9��df��1�1ޢځ^'��]��� R���q���.����,�����^%��l��� �e��#wW��s�56!�=��!q[������%�Ԯ]�5^:��m�5�)?�Vb|�u�7f���w�����,:�Ye�R%� -�[���� �o g�F�Az�FP������x���{���d�xí�w�8���ٔ{{L> ��d��2C��L����L�,�L��,��(�mS�������$=�|%�֝lu�& ą�83�� -N�X�x�\Vn���J[)I��w��/�鹻���|�Gź��Y����DH���*�S������p6�0�c�J2�@�W�%Ѧc�_^�$��#*:G���6���n>�D;����~�`9�hXB �U��JB_в���ˈ�%����w'�$��v|#T<68�KM�ϑ-�5U+���'�B -�ĪN����bJ��Ov'��|��+*M��k(d� }�C�˱@���q���&�aR%}� -�!�VЃ�s3w2���a�2���awH�z�/��Q0�F� �]~;��ä��� ND�P -m��K3x��ke_�� ����S�!��V&=�����v�_P��L9Y��i� -�NU��_���)���J6�9�f*��S � �1�7�F|�BR$��y,Ʊ.���&=uqs��OD��B���R�=��ɳ�e�ؽɇ�B����H���� -�2lu'�h7^#�S�)�Xi2..P�e�/@F�K��$�](�%�|�2��Y1pC��8t��I��11N//+\��p�j����d�����W�m��I=߽��Y�Zx��MЉP�8��1/JG���^U ,P�d1O��^�y�pq�l���2h��$�jv���������I��%�������]V��� -.�'[+WU8��[��D����,�-=[����O - -w����E�)�3������J&�d�قݶR¡��S�\.� �5J$I�&��o��Hȳ~� l���z>� -Ux/�H��u;�?Gt�{?��;�T���H �L�|F�8��}��{��p:�2t�͆<L�CA`���ʘ��Ç득��+' ������oR0D?A�ClI���Z1���F?j᧴���{^��E�dGI��T���&#eJ}��ɣ_m���i���A3�K["o�C�TJEߞ4�c$�jݍbY�nathY��`YG���ei����(�a�#ps�W���i-1���b��,ʎT�cm��bhv9jh��3�t�4�@z�K���Ꙇf�jĖ�\$5P��!�hR��$P� -M�њ`�����C�C^%2�]uOs��LTx���p�Y��!�UƜ{��'�����yL� +��l�J�8����)@�w�$F5t4����$�,��34aT��&���݄�Ui��+���--��,��{!/\���ς��'&�S�����0xk�Y���0I�)�'����~�� �j��#�m!�-TQ`���=�=�KR���,.is�gI&jf�-I�(��~���o��,�i���傌t&�\���`͞���ҕ,�Y��Gܑu��I(~[�!2=��������h��&I���{8~4�� -�j(*��aA�T�R�?b�0�I��K�P� -����M��^c���Yf3��-��J��c��r�;�ru��GuA�T1?Q���8D�py�y�+��c���@6!�[o���f��Zp����ɲ�`$�Q��!��O�� �4���|���qi��L^��_ǀM+�ƾQb��#7Ճ��X 5=��qQ���!�i���m~����������u�ݢ���� r(48zr�Y;�*1�yNk�$9j���ip+�q]��g�i�f������f�ԥ����>a��ѧp6���������5Y"L�D���.�r��V�����S_ ���k��]�n&�H��z�~�9�æ -�p $�4ق��'�{�&�����M\�ΰ�ч��!�q�i�� ��(.h�'�B�T���|�{I�6cL�.���빍iI�\!�;��g`1����j%C �o�3*60��E��؎�]t�.�-%0 Y�K�_nft] �*VFC�tJ���T�+�\WZ�8�����gF����^ -ޞf�� 5�I=���#6�.@�2z��;W�`�B/ęQ��g���h�jyJ����N�AX�3��,����K�6��6�ڲ�M0�T@���O{���4kj�|"�ftџ�ۄU��<-��a����5b��)�^R��8�����:��il����Ka�6@���!���]�buvΏ$ �oU��~:.�L�t���e�� ���JξP -l$S[z��~Rq39钺��9�Q��/�m"�%ʤ����7�� ��5MKL�鑧"IߏG� �XTގXL�F�ݧV j�p^�/M�g�ۻ{���w� -�*����9���O�ʈ<�"a����A���q����.M��2@m��p�^�'�wߕm��kxO8�$[�&��|Y�Zy�`2_|%r��/�J?�Q��Ṉl�3Þ��K�E$�w�vC�h��a@�U�1�M��%0?1*��$G�Z�{!|�ʿ�$��ە�-�٪Ev;��͓:���`Bl�˸�쌧�ɬ�oQ�0&�����,�F?����^�s,�c���h˕�$�E�cl0��w`�⏺�ň�@/�r^l�8cT�3���k@���J�ݔ�uP�&ʪN��d�JjT�K��i ��*u���X�{t�j~�ɡ}��i\B�Ken�ȵ|N����u���#�]@l�CZ$iP�a�㸩t04y20� s�֪�,Au�!Q��B�ϖ��^�@Vsɑ��\�Z�a�7�쾉���ш��6-T�r���U���u��~�1H�J�(<α�����bRԖ�qi����J?�e�G�� �*jVħ"���:Y);�-F�d�!�H���G~��u�x cb�6m���)&;�0��dU?�8�X~�1�2��ۼ�t��I��x�5��{(�z�� -�'���[�Ńk��ZЅ����i,��b�1̇����`��(��m�H�N���e�K����/ -[�(��#Q��Gd�u�T��^�m���%����!(�7Kg�P=�h�ϕ�kɐU+���.[�e������C������"GD�Ψ��<*<����h�)�` A�U@O]h�l�f2��!H���F#�QB��=uȾ9f�h��;"R�����K�3-�(G )�P��������T],7�ec� -� F4hH�s�73ᖟ�����`�R��T�wfͳ;6B�>Ř 9&�����܂�?����)�\����<&Ŏ��5 L�Ju�@Y���,�냲ھ�_w�0�^�17�����p�*>D�8����_)$Uź��R�!jOF��>{�����t,�-�bP�,m`D"/�z�A� ͔إ��QZG�&U]�xejx��Lwv�~��=)@�B��6�?!;53/ps@t�OZS7���ؙ��n��lx����Z?�Z��j a��{��6���L4���1�2�����Q�i��&֥l�����]o=�7�ļ of�Ж�rMEV@��H�����/��aD�٦�H����lK5)Z OE����3��IG�'г;�D'�zl(����E���$��.ٜ�-WR'\w+)�w3�꺾�� @�%R�)�.�~�9;]�.g+)�%ȝ�k���҉��^��N�W�>b1z:s��oD -K�����2w[|>9�vWMF�u�`���ax�chի�U��`*ʆe�]O�V'6����x�d?�H]_r�A��+z�d�F��H �ʋ<��Ǵ���kUsFz����aH��9-������gv�b�=��L/�E�)��.��x9j%B�)�$���A�B���� ���t b.b�AE��Z�Rb�H(���J�ya��9Wj0f��F'��X�z���$DQ�6��q��` o�� i=���{#4��FYH�@�J�3 3i~�tYТ�hkH�P�����17�����Y�D�"�p�Ħ;'�16��f�pu����>�F�oD�Qi�n�̒�-��@P#��� �h�j ނ�ŀf��C� ���7°�T5HVX�p���klĭ���]��yXr�)?ͺ�BNJ�B����#��9e��&&�_0��=��pZ��6��h��)� ̗�a b���=(p)������;�.N�,��W�^*hԺ�C��m}E�7�i���6����a�I�vͲxp�*Ac#4��������N�&�`)�ĉ��H�We��y7jl����o�Eh_n3 � �jp?�4�p2W�E'kT_� &��!ȖjVl�H�ӻ_kɚ����ʳ�aY���� s�@�[�G"��bY�L�ܫX��i� �C��q8�&�z��VaY{��#I@����2��m�!�d�[1 �A�Ƣ��nK�����eם��/>�d�m�uX:xʷ\��p�N����l�+�H+c�tSǶ��C��[��~3��e�}6� �\�,��Ʉ��|�Y�ݧ����v]�'�|����&��M�2� d���ds�x-((76��aX��m=��ӊ��Q��<$������Q���\�� -��qi�H阇���i'i��$�"�{S*V�wF��/�t<����Q`ʒZ��+�pr)�(�.j�鸫I�k5� <�ʆ�ˮ��, kO���DT��J&^7���ĪQ�����v�e -&�Z��� ^4��^s��D+`WH����b�6���� ���L��W{ZZ �@��mq��v�ɷ(D�\+�l���0*�V�߇�Vm����hƏ��/S`|�^\<-����6�2�N3��" To���lr��e��!��H2�p�A ֛������{�ȼ�/�����udU2*2�"c��"p�${��y�,饋�&\�m�&�`�|x �p��C��w#���W�9D�Ii�іC���Ks�燝S���3�,����M��;j��B�4��P�2��i���f���ɿ��bA�]a�id�������"���i!aQh�CNO������Y� -�xF$��g�9���Z`W���VB�g�����#j\˂���e�G��[�.�]��0�~X{2�D��?��"�3�B�j,�K~��b#�0�ɒL�kc�(6 � -�a�E7λ�/Վ�%�� ����� ��ġR�^J���CϏZ+71X���UO,����}#�-��e٤�4�3ł��t�8��Z7��i��<:i�?Ft�Fk�CW'��f0i<�Xdj����0�W#i����eC� -zI7��B�s���.K� *��V����d���D�lj�@��% -�܈�� �Z��s�ﮐsh̸%�^� -�����@8����?�N�8g�G�gr�X��S������ Ap���4�z*��4���,í��t4G�n������dS�>f�Q�C��WUZ{S�;N�x��}��H&��*��9�q��U1 ��a�`(M-a�G}�n�̽��0 ��p���mcn� ���ɘ�_�\��l������}� ���9�F�v�Hþk�JZ�NO �mZ���Q��Ҥ aS��f�� -)QC+2 -d���[��� ����H"t*� �c*b��ڢ��q��,����#S��#��u�'Ҭ�:4�as���CDM�F�|ɸm�_�1L]��Y��\���*�X��>t�����g���D������d@&[�)8��;<�{��8<��+VG\�H���^��a��a�e�-4��s�J�A \��hM[�\`���#�pD5Z97g;��BW�m��qTXX�%0��v����&��]E��4]�F�IJ�����&�S�_��4�R�0���D�+�me���Y �g��O��+M{�03�v�'ͅf���t����:;�ر� N��n�\ǔ^�,)1�l��aB�ZZ��[�� �� �ZS���UYh�߆��w����S�\�/�*?zQЋ�`�X4�g�r��[��CW��G�.�Y��0Q|�Rԃ�E�[w���y�)���,ш�$�NK@c/b --#Z�I �G$Ɨ���tm��H#��)X�wPZAD|�S o�f���T���H��)������>�M1�b 7���ɆS�u��q� -���jK4[s��� ���xL ���Ǣ��]5�!M!A�dƧN��><�:ǻZ(�8����)e��� ����/�W���| ��b����<�����T?%� �:@���,-���ecMP�8u�m�V�g��9H��6���}�=�5����Ab�Ď���찁�Ι�V:���_�leɹ� -��v�`�0��!$`G��A"I;$�^?�����Ke O� ���N(ս���Yy�5B��w��V�%�ju;)lF�oa����7��x���ڸ�4-��%� ��$�ֹ/zskǘ(sh>��DD�Ń�t�T�7�rur���0�Ң�`ܴh5 5�������S�}������4hrva��l�c!ZjB]������x�D���b�Tx�zYS��6_�)��o��p>�#�@P�S�*�b�S\qƋx�YfQ><"���� Y6���IE�r_7�ҰV�H�!���I�r�EL�6�!N���q"'�d��a�qMv���A�%����� �v����n<Eб�;��,�w��2pO%�r��X�H�`�uI#�/�K���;�56��LL.�MI8�q��4U�n�rɡ"s9�(��@=��}N��)?S����.�r�0L3�m7V��K HG�/�yQ���2�/Ww�F)���d)s��F�7|���vQ̴�A�Iz`�\��������䄛<>�.;��A/���2ʲ��a8D$�GWv�#̏� 9�k��'���o؟�o�@��� (]gk�+}/ (nq���K(f����Ɵи�p���2��3Y����w��pD�dG�q2$��}�KӯA�"�E&N�tg'Ne�s��!Ю�4q�o}쿝�S���,o�jr/s�T�MT�&���Qf\12�h'&ctN��'T�x7��]2� ;G� ʅ��|T�++:%/ ������1T�������ˀ�<���4������͔���˗ �,0~��!�W�O��'� ��:s�u���Ҧن��(�^ﮎ����)��7���f���ml��ҹ�1ūt��Z��h� �L0����6�X"J҂� -��4�9�� �֩B�}��ԭ`�`�����Ӓ� #�J��n����_�F� H|��$O�K��=�œi1���7��o-H�q���p[ɫ%%:��Ɉi3۠��G C��LL�4�S�:�dB�j|��pY��S�D�P>�p�v���5KLe�{t0��y�END$�*�;z�5��N��BI��gn��.N�|��n���R�aS�Z��JcH� m��X����e�k;_6�,y��b��0#�Z��A e|w���G U�1l��LD�7ÄV�q��t[�xu�E�QUL���PB�lZSh��.��1Q0U�ٱ8R�i��p;��{��H#�GON!?��t>�Q |p�k����q!�gT,��j��2��sǍ4툊t�j��nƛ/I�O�E!ˋnF��4����M&�1�����x�$�ew+v�S�� -bm]e%8��P�� -!����s��_06��)Q�2JB�����[t9���'���Ԝ,����[�f�Æג�]��B�B�@���r&B�s|�Q� ����g��OC��1��J D�<���U���μ�(o�!��h���K�H�� 0q����A�V��'p�f�y"Q -O��2�Z���q��#d"�@bQ�,���w)�P�\b`x���O�)ޢd�MC�$[Ho��Wަ�va4{�DZ`52�����5;��X��ao�K�;�6�%�R(�����хx9�8�2r�Dc��@و�����F�<�d(�AN#F�I���zmE���F=���ƚ��S��f -4�8�<'���j���-���'ǘ<�Tb�2�v�E�t��q��3qODd_��{`/�hh���`9_�1hAY|/���U�-͕���A���o(���"�$r؆T��PR;�.�-w>&LJ�iC`A�^���#���X8�t���H?�d��a�ĖTST�a�H�0@����U)����^e}Jb7%�ܔ%:��ƿ@���M�+�y�sq�����L�������Y�00Ô�G�D� >ĩ�AW���2�I�:��F ����3�2<k�}[{�*�"A�z0��:@���1�A:�����ܤh�X��C�9�8����E�����U��eu)[?�mt-5�r�~J�ݪ�V2li)�՞<�ҳ?�(D���;)��o (����XI�I$����$�)�'i(��*��_��E K��*�4C�k����wkOI�FfQ$8γ�;(0+.�9���9u�$��0��t�170��fȦ ǒ�aO�=T,�m;���n�����˸��Χ�c�<9�0�<��� _�=g �QV&��B�܀�%f�3`5�F�ݶ�~��`6d�.�2`?���]�}�O�0^�A�K�N\Q�(I {����p[Ꜫ�4�$6x�P&� :�'�7u������ ���&���R��d�'� ʹ#{*W����l��D�Q��̎.*ZE�� �c���7��|4��Ղor\�*�� -HX���'�#k?WR���mP�x�$ٓ]���� ׄFK� ~�4; [Ҋh2�A�ɉf���<P dg���)�!b#Z�?0o���[��E�hX�$�����S��ؾe���N��$����=�8Ш"^ �V�cFD��x�����RX�C�X���.:F��q,���1)b�B�1 �+�Q�)�_�OyE��� -�������nTp ��}1`�# -ףd-�֥#�O��ℚt��:5Ћ�/<b0�'m�oqI���B��FW��.�\k�c�5ߦ-v�T[͂������� ���-4�:dݗu��[ 8:P금���BT���U����Q�,F24�l�EO�?�D�k��{ �1�k6)R�̘GI��6�Yp^U��!A�@�{xg�#^/ ��E�Tz��Ēʻ@:F�'\�Q6�t,��pT!i� -N!�dG�B��^ -�$@yn��_u�U��C���K�_K62��B| -^����T�mr���LDgʿ�f�)!-�����o���ch�}��@o�[r�E] ��/i�WJ8�Ogb�ӁF�e�(/��EΠ�yO��LB��]IkTډa��bV��� -�� - 2����ց%�b���j���g��'���2�-6���D�����JZe' �oBi2��+]x;S�P���{�{Ju�m��f^L -S0�����~o�����-���S�Ec�*�vl��pOm�@��v -S��D;<U�C�Y������nA)�pxO�@�i�L���7�E`K\�J`�9�U$� p�'�Տ�����3�v +��n��%�lS�}��A��Nj0*���׳48���i%�����8��P5�c��#��T$F�?$���L~�I�QN_�MC -Tn�L�`)e|Ȑ�!d������ܑ[�s��D�\Vo��gF���G(1� ��OJB���J�FR%p���3N�P C�S����@pM����vA�f,- +�H�Ft�,����wfA�������)y���^�Ƹ}�N�+s8Z�$j�NF����i#�l���h����P!9ge]�i���h����f�v'�l��!��yn�O��]3��i��я�F� ���Pkc�\� -`���@�92� z��X��;]۩�i�%[5����p�8Q c���d��\�Lo��;jP�/���n�g���[��qB�QP;��,V�e���3�Pr�'ط�4Y��� 8��[%���c� -^�`��� ��PjL>ʠ�q����:6S����]K��"���g[�� �ϑH���B�5�VEq�LJ��X{C����B����!�P�I�q9��Llx��ʪ7�>֤��]@�!@9H�!����p�ə�$ �?��)����l�/"���́��+�@`}}:\���� 8�zQgS��+��C��}�R:��H�UF\�X��g��/��AZ%c1�wlET��wX�ZNh����yf2D� �ø�&v�L�q�4�7����z��\�iJy��J-k�N�3��� �-�s��J5��)�V0�N0�d�\ӛd0d-��E�[mf�\�Um�x���C�R<(`�ѕ��p4^!�h�Q��`���!l� ~ƙ�:J�ɠ�l�W���9˸�ZXB=��l)`j��eVJ��U���G!�s��1�?Ƽ3��Ê.�}bIa��6�ʕ �t?����SxZJ'�p -i�,�.�����R2T`5��-R -Bxr�WH�JP�e#Bb�|���-������[�����P������Eh���(5S���f�r��/]���IƊ ��d��E#��O�S�3�9ӻ]����e��ۮ�ɹ.9_�b�e��M���9b#e��(��-� 0����Ra����9����"������U,��%�~�X�܀����z�۽{'6[@�t[W%��*.d'vR {���h��!�Aed�C�E}�x=E[|�B$7J�* B-��,=k7�[_��-�I�������J5e�̶��{ ��( ��;�WMw�`����~p�A��z 8��f�))���(��@ �Īم��<���.a%N ��n�@bz��������>����%���T*?lgb�d��<�ĵ���w9Na���8;<^*%��y�:tD�ҕZ<@��0����q4����l\ ��1������`/�$IJ ғsN)�;:A;�)$ו -�Ww�y%Kr�Iv\b�V��\n�d{����6t��v���/~���*O�� -7U>�8�r�AC<�j�E�-j��牷��xs�)���D���1�Ì/��q�p**̸�$ّ�,�� ��B�ȼp��k Mhp�K�7�U��]���h&�-�$�鎻����Y��;�q��6w�z���W��˄֭A�h��D��^R���"��s5�f���w ���+�Q&�/9Ȃ���wNb�����������z{�����Y�> -]NE���c,ߞ#BF�:0��/-EȾ��׃�F\���I�{t��A�Z�C�OR�uk�i���)�ytkd�N�&�v�A���P{�����P'��>���x�Ɔ`.��%,;:Կ�:������aF�oTQ�}v#��ף���Qk��'�s������~����z5hM�Qʒ�Y>C��ʍ����i��U���NF#J0u��C���8k�! -f���v�{E�/���IKIE�>�p�yd��e -ʾ�=z�:@7�J�����|��5g8��x�3�O�������� -�3�H1��F.�y�fz��WIM����j[�.w�%�i?҆U��f|}@+[8�k7Cx��S���EOޯp�$�����Q�+��:�<�]���K�3��T-y���[N��z���;y���-HZ��Y^��.�M�*�'h8��A�.�N�2r��LB�7:Or���}�C�S˚S9�Jq#�WI}*8�D!��# g#Y�>8`� -�В��?a��2H,^���'���?���^����n�h�Oƒ��i<����Ya2�+���6a�F��a<�!��0��2�]�c:�e�K��X�X�[Ug�O�u5i�yPcV�T��5RI��A6�OԸi ��C�\�����QZ�M�D�ƃ����B!X��:���\!�^��"{�E Vax$P \$�DBBT��Ft�~��{O��� w����5a#�`��=�g��Ё�Y�2>��MG�-G�k�è��1T�b���L -�`*ـ�V�X -��*�x�e§֊�Z*c`�V�S�b���JU����*6�TK@�zqP����h���g��*ߔU�(��QU4��9L� -�cM�*��T��R!R,B�ȅE�����*C|Tz��p��F��@��4��*��������텰��ج�X�b��L�.��T2�y`���Upb����� -���T�,��%@`�����#��?@�t����GL��Ş�S�)��ÿ�z��tϲFy� �14�Lh�������f�����e�(.)pK�@\����X�e@�Tb�v�h�D��&�0-I�bD� d@�ZD1�@��D�y���ѧ�CN| 9�4��Ӛ#Ncl���;��, �`c�X���@�(��2$0�"@- ��$�B@��<$�А���8p7C����b�(�@� -PA@��F��0����t������G���OR���IJ�I�T�yS��MW52\T�oR�KV�0Ȏ����( --�$������ �!6���w��H�������G���O r~�e~/�]���V~/�P~7�Sz�K���Fv`;��`9v�# -J���B�N�,�����ӭ�'���`���'��`\LT���ApBs�)r�!� -�( -�i�`<?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=" " /> -<glyph unicode="¥" 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=" " horiz-adv-x="650" /> -<glyph unicode=" " horiz-adv-x="1300" /> -<glyph unicode=" " horiz-adv-x="650" /> -<glyph unicode=" " horiz-adv-x="1300" /> -<glyph unicode=" " horiz-adv-x="433" /> -<glyph unicode=" " horiz-adv-x="325" /> -<glyph unicode=" " horiz-adv-x="216" /> -<glyph unicode=" " horiz-adv-x="216" /> -<glyph unicode=" " horiz-adv-x="162" /> -<glyph unicode=" " horiz-adv-x="260" /> -<glyph unicode=" " horiz-adv-x="72" /> -<glyph unicode=" " horiz-adv-x="260" /> -<glyph unicode=" " horiz-adv-x="325" /> -<glyph unicode="€" 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="₽" 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="−" 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="⌛" 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="◼" horiz-adv-x="500" d="M0 0z" /> -<glyph unicode="☁" 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="⛺" 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="✉" 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="✏" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" /> -<glyph unicode="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" /> -<glyph unicode="" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" /> -<glyph unicode="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" /> -<glyph unicode="" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" /> -<glyph unicode="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" /> -<glyph unicode="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" 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="" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" /> -<glyph unicode="" 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="" 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="" 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="" 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="" 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="" 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="" 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="🔑" 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="🚪" 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> ��������pFFTMm*���������GDEFD������ OS/2g�k���8���`cmapڭ������rcvt �(������gasp��������glyf}]�o������headM/��������6hhea -D�������$hmtx�� `�����tlocao���������0maxpj��������� name�,���������post���5������ -�webf�TP���T�����������=�������v�u�����vs�������������������������������Z�����2���������������������������UKWN�@� �������{�������������� ����������,��� -��������h�����,�� -��������h�@��(� �+���� - / _ � �"#%�&&�' '�� ��)�9�I�Y�`�i�y����� ��)�9�F�I�Y�i�y����� ���!�'�9�I�Y�`������� �*���� � / _ � �"#%�&&�' '���� �0�@�P�`�b�p������� �0�@�H�P�`�p������ ���!�#�0�@�P�`���������f�b���ߵ�i�Y������!�� - ������|vpjdc]WQKED��������������������������������������������������������������������������������������������������������������������������������5��� ��� ������*���+��������������������������� ��� -����� /�� /����� _�� _����� ��� ������ ��� ������"��"�����#��#�����%���%������&��&�����&���&������' ��' �����'��'������������������ ���!���������&��� ���)���0���0���9���:���@���I���D���P���Y���N���`���`���X���b���i���Y���p���y���a�����������k�����������u������ ���}������������� ���)�������0���9�������@���F�������H���I�������P���Y�������`���i�������p���y������������������������������������������������ ��� ���������������������������!���!�������#���'�������0���9�������@���I�������P���Y�� ���`���`��������������������������� -���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(���������(��h ���.��/<���2��<���2���/<���2��<���23!%3#(@���� ��(���d�dLL�[��27>32+&/#"&/.=/&6?#"&'&546?>;'.?654676X& -�j�� - -��j� -)"& -�j�� - -��j� -)L -��j� -)"& -�j�� - -��j� -)"& -�j�� -��������LL�#��32!2#!+"&5!"&=463!46��^�����^L�����^�^�����p��@L�E��32!2+!2++"&=!"&?>;5!"&?>;&'&6;22?69� -�� -x -} -x -}��� -x -}�� -x -v�� -���L -���d����d�l -�����d����;��2#4.#"!!!!32>53#"'.'#7367#73>76��p<�#4@9+820{d���d�� 09B49@4#�bk��v$B�dp�d�>u��hi-K0!.O2d22dJtB+"0J+�ku�0�wd/5dW�%����{��L��>�G��!2+!2++"&=!"&?>;5!"&?>;4632654&#�^CjB00BjC� -x -� -� -�� -x -u�� -x -u��@--@�$?2O*$$*P2@%d�� -��d�� -���BVT@�����L����!2#!"&=46� ���������������%�A��+32!546;5467.=#"&=!54&'.467>=�2cQQc2��2cQQc2�A7 7A�A7 7A��d[�##�[����[�##�[d��d<c2<2c<��<c2<2c<d���������������1����,�A���2632#!"&5467&546�n�,,.x��x�OqUB�Awa�xy�rPEk��������d�������32!546;'&>76!'� -���Pԇ - $ -op zy���#��%**%�$ ���p�������d�L���#�7��!2"'&6&546 6'&4#!"&7622?62~ -������ - -� - -��\l -�� -l��L -��7 -����� -& -�� -�� -��� - -l������������ � ����2'7' �&� c�_"���f���n� �&\�`�t���f�jpO������������32!546;!����������22&&�����L����%6.676.67646p�'0SFO�$WOHB��XAO�$WOHB��"��7Q)mr ���*`)nq&*���� ������)���2"'#'".4>"2>4&�ȶ�NN;)��w�d��NN�r��VV���VV�N��d�y��%:MN��ȶ�[V���VV�����d�X�D���>.54>�0{xuX6Cy��>>��xC8Zvxy�DH-Sv@9y��UU��y9@vS-H������^{����62!2'%&7%&63�������������� a����o��������^{���"��62!2'%&7%&63#7'7#'�����������������J��J��N a����o����d�⋌�����������&��2##!"&=467%>="&=46X|�>& f -�� - f &>���|�.hK -� -] - -] -� -Kh.�|���� �����L���#�'�+�/�3�7�G�K�O�S�W��!2#!"&54635)"3!2654&33535!3535!35!"3!2654&35!3535!35~ - -�� -Ud��� - -& -sd�d d�d d��� - -& -��d d�d dL -�� - - -ddd -�� - -^ -dd�dddd�ddddd -�� - -^ -ddddd�dddd������LL���/�?��!2#!"&546)2#!"&546!2#!"&546)2#!"&5462��pm��p����pm��pL�p��p����p��p��� ����LL���/�?�O�_�o�����32+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=462����������������������������L�������p�������p������������L���/�?�O�_��32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462�����D�������D�������DL�����p�����p���������&�,� ��� 62"'&4?622�;��������;��������n�nBB�#�� "' "/&47 &4?62 62�������������;��������������������%�I���2"'#".4>"2>4&3232++"&=#"&=46;546�ij�MN,m��w�b��MM�o��XX���XX��� -K - -K -� -K - -K�M��b�y��l+MM��ij�MX���XX���# -K -� -K - -K -� -K -���������%�5���2"'#".4>"2>4&!2#!"&=46�ij�MN,m��w�b��MM�o��XX���XX�X^ - -�� -�M��b�y��l+MM��ij�MX���XX���� -� - -� -����������-��32+"&5465".5472>54&&dd��[���֛[ҧg|r���r|��p��>�ٸu֛[[��u�'>�7�xt�rr�tx���d�������/�?��32+"&54632+"&54632+"&54632+"&=46� - -� -�ޖ - -� -�ޖ - -� -�ޖ - -� -� -�� - -~ -�p -� - -� -�� -�> - -� -� -� - -� -���������G�O��27'#"/&/&'7'&/&54?6?'6776?6"264X!)&1-�=+P��P08�,2&+!)&1-�<,P �� P/:�-1&+x�~~�~��P09�,1&+"(&1,�=,Q��Q09�-0&* !(&0-�=,P���~�~~���d������!�%�)�-�1��!2!2!5463!546!5#!"&53333333�,); -�� -;),,;)�D);dddddddd;)d -KK -d);ddd����);;) d�D��D��D��D���������62++"&5!+"&5#"&l` -� -� -�� -� -� -j`�� -�� - -w�� - -? -��d��������3!#!"&5463#"&=X;),��R���p);�vL�p���������0���2".4>"2>4&3232+"&546��֛[[���֛[[����rr���rr�|2 -� - -� -�[���֛[[���֛;r���rr��� -�� -2 - -^ -�������������)#!3333��)�)�����������p���,�p��,�����d������/��3232"'&6;4632#!"&546;2!546&�� �� & �� �T2 - -�� - -2 -���>�p���� -�� - -^ - -�� -��������1���2".4>"2>4&3232"'&6;46��֛[[���֛[[����rr���rr�|� -� - � & � -��[���֛[[���֛;r���rr��� -���� -����������1���2".4>"2>4&%++"&5#"&762��֛[[���֛[[����rr���rr��� -� -� -� - � &�[���֛[[���֛;r���rr������� - -������������9��!2#!"&'&547>!";2;26?>;26'.�� -������� -W -� -& -� -& -� -W� -�t�W �� -��> -� - -� -���������'���2".4>"2>4&&546��֛[[���֛[[����rr���rr�����[���֛[[���֛;r���rr���]�$��������(��76#!"&?&#"2>53".4>32�� -���m�t�rr���r�[���֛[[��u�$��� -�Lr���rr�tu֛[[���֛[����������5��76#!"&?&#"#4>323#"'&5463!232>�����n�t�r�[��u��[��u���h -�n�t�r$����Kr�tu֛[��u֛[v� -h�Lr���� -�d�������/�?�O�_�o�������!2#!"&546!"3!2654&32+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=46} - -�� -��� - -R -�2 - -2 -�� - -�> -�2 - -2 -�� - -�> -�2 - -2 -�� - -�> -�2 - -2 -�� - -�> -� -�� - -~ -� -�� - -R -d -2 - -2 - -2 - -2 -� -2 - -2 - -2 - -2 -� -2 - -2 - -2 - -2 -� -2 - -2 - -2 - -2 -��������L���#��54&#!"#"3!2654&#!546;2�uS��Rvd);;)�);;)��� �SuvR�;)��);;)X);����d��LL� �7��32#462#".'.#"#"'&5>763276}2 -d�!C@1?*'),GUKx;(.9)-EgPL -��3 -0�[;P$ 9�7WW���������!�1�A���2+"&54. +"&54>32+"&546!32+"&546��ޣc -2 -����� -2 -c�*��`���c��t�� - -,�rr��� - -,tޣ���4��4���������G���9��%6'%&+"&546;2762"/"/&4?'&4?62A ��� - -�Xx"xx"xx"ww".� -� -� -^ -�x"xx"ww"xx"��������r���/��%6'%&+"&546;2%3"/.7654'&6?6A ��� - -�� -`Z HN.� -� -� -^ -d ��� g~�j��������b���1�K��3#"/.7654&'&6?6%6'%&+"&546;2%3"/.7654'&6?6��D@ - *o;7 *�� ��� - -�� -`Z HN� ��i�T "��Z�G !�� -� -� -^ -d ��� g~�j���� ������� ����!�%�-�;�?�C�G�K�O��3#!#!#3!##5!!!!#53#533!3533##5#535#5!!#53#53#53!5!�dd�pd�������dX��,�,��dd�dd�D���d��d�dd�,�D,ddd�dd�dd���,�dddX�d�,,�d��,��,�ddd���d��dddd�d���,�ddd��ddd���� ���������������#��7#3#3#3#3#3!5!#53#53#53ddd�dd����dd,������,�dd�dd,�������������Pdd[[[[[����� -��� ��� "'463&"26���0�V -C;S;;S;��V�0�� -�;;T;;������� -��� ��!�� "'463!"/ &"26���0�V -��08��D��;S;;S;��V�0�� -�V�08���;;T;;�����d�����&��!2&54&#!"3!2#!"&54?6,9K@ - -�D@ -� - -�� -��K�|@ -� -@ - -�J - -���������L�� -��!2 46� �>�>�����C������������E�U��!"3!26?6'.#"#!"&/.+";26=463!2;2654&!"3!26/.6�DN9 -� ->SV� -N -�� -N -� - -� - -� - -� -��� -& -X -&� -��l l- -�p � � -�v - -� - -� - -� -�� -� - -� -�������d�L��!�)�1��3232#!"&546;>35"264$2"&4��8]4$�);;)�);;)� '3]�d�Ͼ������V<<V<L);;;)��);;)X);E5+��ddF�����<V<<V�����5����� �#�� !526/!3!567>?!��(% -�_5,R�y:" *2��8��T���2*BBW-ޑY".BB% ��Z������d�����'�2�;��#!5>54.'52%32654.+32654&+�50;*7Xml0�);!�9uc>--���Ni*S>v�PR}^��3:R.CuN7Y3(; G)IsC3[:+ 1aJ);4��ePZ�������o����!56764.'&'5mSB� ,J��� �95(��1(aaR@ 9����������%�/��#4.+!52>5#"#!#3'3#72&�2�p"�&2���KK}}KK}� ��dd R ,��১ ���!�����%�/��#4.+!52>5#"#!5!'7!5L2&�2�p"�&2�C��১ � �vdd � ,��}KK}}KK������L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462X���� ��L��Ldd��dd��dd��dd������L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=46���D�L�����D�L��Ldd��dd��dd��dd������L���/�?��5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&�X���p��� ����L���dd��dd��dd��dd�������L���/�?��!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462L��L��L��L��Ldd��dd��dd��dd������L���/�?�O�_�o���32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ddA ����ddA ����ddA ����ddA ��Ldddd��dddd��dddd��dddd�������L���#�*�:�J��!#;2+"&=46!2#!"&=465#535!2#!"&=46!2#!"&=46�dd�dd��������,��X��Ldd��dd�}KdK�dd��dd�������L���#�*�:�J��32+"&=46#3!2#!"&=463#'7!2#!"&=46!2#!"&=462ddgdd����/�ȧ���,��X��Ldd��L��dd�dK}}�dd��dd��������������!2#!"&546 K�,,�,,���,�,�v,,�,�D,,������L�����!2#!"&5467'2"&4,X��J�*J%���pNNpNL��d����>���tNoOOo�������6�����2.'&54>"264�u�sFE�66 !^Xm)<Ds��������x�us�m�?>!fh�H�uX�yHÂ����������������2".4>"��֛[[���֛[[�Kt�rr��[���֛[[���֛�oVr���r���u����5��.54>6?6&'.'&76#&*IOWN>%3Vp}?T�|J$?LWPI�)(!1 ) H�uwsu�EG�^F&:c�YE�vsxv���!K�:%A'#" -A)Y���������l��*�/��7>%!2!"3!26=7#!"&546 7�l -l��27���);;)�);Ȼ��p���8���7c�s* -s� �;)�);;)���������������2�c������L��6��!#"3!2657#!"&546&'5&>75>^i�4�);;)�);ȹ��p���S��9dTX -.9I@F*L�6;)�);;)�g����������� � 0!;bA4� -���������L��5��!2!"3!26=7#!"&546 62"/&4?622^^<C���);;)�);ȹ��p�����e���eoL�;)�);;)E�ۥ�������3�e���eo���� -� -���;�� 62+3546&=#32"'&6;5#'&47635#"&> -�� -�� -Ȫ -���� -�� -�� -ȯ -��� -ȭ -���� -�� -�� -ȭ - -�� -������L���326'+"&546�d��0dL�J����J���������L�#��3266''+"&5462d���0�0dL�J��J����J��J��������3���''&4766��0������J�*��J�������36���&546�.��2�������d������32+"&546!32+"&546��������� �� �����dL����#!"&5463!2L�� ��� �������3���46&5&546����0d�� *� ��;�������O�#��72#"&5&5&5464646dd�1�2��N���: ��9 � �>� �=���,���L���32+"&5&54646Rdd�0�L���;��;����d���H���� #!"&762!2#!"&=46�� �� �*����9���Hdd�����uJ��� u��`���(������(&����;��(J��� ' 7(���a���#���aa��������3���2".4>#"#";;26=326=4&+54&��֛[[���֛[[�}d��d���[���֛[[���֛��d��d��������������2".4>!"3!26=4&��֛[[���֛[[�E���[���֛[[���֛�~dd�������3���2".4>"'&"2?2?64/764/��֛[[���֛[[�� xx � xx � xx � xx ��[���֛[[���֛� xx � xx � xx � xx ��������$���2".4>'&"2764/&"��֛[[���֛[[�T��w��[���֛[[���֛�1U��w�����������;�K���2".4>";7>32";2>54.#";26=4&��֛[[���֛[[�?<B2!� �(#"3D<:� - -� -�[���֛[[���֛�/O2*(8\6/H* �� -� - -� -���������>���2".4>#";26=4&#";#"3!26=4&+4&��֛[[���֛[[��� - -� - -� - -KK - -^ - -K�[���֛[[���֛V -� - -� -�� -2 -� -2 - -2 - -��������/�_��3232++"&=.'#"&=46;>7546+"&=32+546;2>7#"&=46;. � -g�� - -��g -� -g�� - -��g� -� -Df� - -�fD -� -Df� - -�f� -��g -� -g�� - -��g -� -g�� -�ͨ - -�fD -� -Df� - -�fD -� -Df��������?���2".4>"2>4&"/"/&4?'&4?62762��֛[[���֛[[����rr���rr�@||@||@||@||�[���֛[[���֛;r���rr���Z@||@||@||@||����������0���2".4>"2>4&"/&4?62762��֛[[���֛[[����rr���rr�j���jO��[���֛[[���֛;r���rr���}j���jO�����������!���2".4>"&32>54��֛[[���֛[[�Kt�rAKi���hst�r�[���֛[[���֛;r�txiKA���>r�ts������S�����6!2#!'&4' -&����F� -����� - � &�������S����� &5!"&=463!46 -����&��U & �U -#�# -�������]���� #!+"&5!"&762�� -����� - � &�����& -������]����32!2"'&63!46&�# - �U & �U -#����� -&�������]��� &5>746 -��^���$,[��~U�U & �U -#$DuMi��qF -���������+��!2/"/&4?'&6!"&546762R,^�j�^�!��^�j�^���^�j�^�P,^�j�^����I�Igg��+��#!"&546762!2/"/&4?'&6�j�^��^��,^�j�^`j�^,^�����^�j�^�����������/���2".4>#";2676&#";26=4&��֛[[���֛[[���:#6#:1� - -� -�[���֛[[���֛���.� -� - -� -�����������I�U�a�h�o��276?67632;2+"!#!54&+"&=46;2654?67>;26/.'&;26!"&5)#! �&�0 -= - -2 -�p��p -2 - -= �� -� - -3�5�3 - -��� -�X -��� - v v -!{, -2 - -�,�ԯ - -2 -0�y� - -� -�� -� - -�r -w�� -�����������+�I��6.'&&&547>7>'.>7>&67>7>7>�-Bla�b�D8=3�*U :1'Ra\�{�%&�=>8\tYR-!�q[Fak[)����ȕX1�"@&J<7_�?3J5%#/D &/q!!6ROg58<'([@1%@_U2��]�r��O��.>7'&767>.'&'.'&>77>.'&>�' -'8GB - - `�H >JS>H7 '+" NA -5M[`/Pg!;('2"&"IbY�C�e\D9$886#1%)*����J7gG: 8G\au9h�oK$�]54<<E"5cQ8 .@AU!U�hQ)�������j�F��?�Q���2".4>&"&5476&2>76&'&6?6&'&'.��{nO9:On{���{nO:9On{���FZ 2Z_���_Z2Z��# %8-#,-"F-I\b\I*I\b\I--I\b\I*I\b\I�9>|��|;7Es1$F^D10E^E$1u$/D0 "%,I�����������'�;�L��!#7.54>327377>76&'&%7.5476&6?'&'.P�[�vY,9On{�R=A �&/l�'Pj�R.Mv&6�QFZ *HLh5)k�|# %8-,-"xatzbI\b\I-y�R�U�4Zrnc�1�?1FrEs1<QA9 ��n;7p$/D0 V,I�����������(��'6#!"&%!546;2!32+"&/&6Z�8�%��% -Y -� -Y�Ch�:#6#:d*!�� GD�K - -K��������d����(���2'%/&=47&=4674L|Xk��d��d��k�X>����1) ���]@ �� @]� )1ES>�������L���'�+�/�3�7�;�?�C�G�K�O�S�W�[�_�c��3232!546;546;2!546#!"&5353353353353353533533533533535335335335335Rd2��2d��dddddddddd�|ddddddddd�|ddddddddd�2��222�p���dddddddddd�dddddddddd�dddddddddd������w���%�7��&=#!"&=46;3546'#"&=463!&=#'73546o��������X����z�#���z���*����dX����zd�M�*����z���������L���!2#!#"&546d�);;)����d);;L;)��);��,;)X);����d��L�� ��?��32!546!32!546".5!2>&54=��������(Lf���fL(, '6B6'������p��)IjV\>((>\VjI),� +'%! !%'*��������L���� 'L������'��a���'�����M���� 7 M�����aa��'���a�����Q�d_���)��!232"/&6;!%+!!"&5#"&?62����*������������*���������p�&���������0��32!2#!!2+"&=!"&=#"&/#"&468^&�d,!��02*��*�6��%�%+�*2222 -�*���������L����!53463!2!!��P�;),);�D��P�dd);;)���������L����3463!2!!���;),*:�,���P, �pX);;)�d�D��E��k����+32"/&6;#"&?62{����*����*������Y�����D�k���&=!/&4?6!546�������X`�)� �� �)� �� ���������� ���!��.#!"!"3!26=4&53353��$�`$�-�);;)�);;��ddd��-(�d;)d);;)d);�dddd������d�L��#�1���2"&54%##"+"&'=454>;%".=4>7i**d�]&/T7���"L��R�����Q� ����)2(����J��f��,�5��3232#"./.46;7>7'&6327"&)^Sz?vdj�O9t\U>/v?zS$24517F8�%M���)( -()�GM~ ��1==��������7'''7'7'7'77 �N괴�N�-��-�N괴�N�-���N�-��-�N괴�N�-��-�N괴����d���!�-�=��32!2+"&/#"&54?>335!7532+"&546�2(<H(<�,�F=-7�` 1d�d����>2�vdd�Q,�}Q,d-��!2$'�$��(d����dw}��������������L� �0�<��32#!+"&/&546;632+"&546!#35'!5X�,�<(��<(21 `�7-=|��dd_�d�d22��L!��-d,Qv�,Q(��$�'$dd��d���ԯ�}w����dO��7�G��%6!2+#!"&5467!>;26&#!*.'&?'32+"&546dkn T.TlnTj����:d%���8 - �V�Oddi�p &yL�N��(� % -H� YS(22�S���������d�O��6�F��#!"&'#"&463!'&6?6*#!32!7%32+"&546�n ����jUmlT.U nJ� -�%��&j��PddO��� �(SN�Ly& p��d(��Y���������a��L��7�G���2#!"&/&?>454&/!7%.!2#!"&=46ސNS(� ��% - �p &y�22�S��Y��(���nTj����kn T.T���8 - �V��d%��dd�������-�I��!26=4&#!""&5&/&7>3!2766=467%'^��N�Ly& p� �(���S�22(SYLdd��jTnlT.T nk������V� -�8��%d�������%���2".4>%&!"3!7%64��֛[[���֛[[������ - -�[���֛[[���֛�9� -� -� -� - � &��������%���2".4> 6=!26=4&#!54&��֛[[���֛[[�%�� - -���[���֛[[���֛�� & � -� -� -� -���������%���2".4>&";;265326��֛[[���֛[[�K� & � -� -� -� -�[���֛[[���֛�@���� - -��������%���2".4>#"#"276&+4&��֛[[���֛[[��� -� - � & � -��[���֛[[���֛� -���� -��������������2".4>%&277>7.'.'"'&65.'6.'&767>'&>7>7&72267.'4>&'?6.'.'>72>��՛\\���՛\\�d+: -=?1 ""/?9 #hu!$ 0E.(,3)( -*!A7,8 !?* - -�\���՛\\���՛ '"r"v G - .&* -r$> #1 - % * - '" $g2( % -������������67'"/&47&6�������PM<�;��+oX"O�\e��~Y�+"��n+We�����`�����#�'�7�;��!2#!"&=46#3!2#!"&=46!!!2#!"&=46!!d�);;)�);;����);;)�);;����);;)�);;��,�;)d);;)d);dd�;)d);;)d);dd�;)d);;)d);dd����d��L�����!2#!"&46!���|;�����**�D�����������d�����%��32!2!5#!463!54635#!"&=��);,);���;),;)��;)�);�;)d;)�pdd�);d);ddd�D�);;)������������+�A�W��!2"/&546)2/"/&4?'&6#!"&54676276#!"&?'&4?622,^�j�^5,^�j�^�/j�^��^��^��^�j�^�j�^,��^�j�^�&j�^,^��^��^�j������������#�;�C�K���2".4>"2>4&$2"&4$2#"'"&546?&542"&4$2"&4��ݟ__���ݠ^^���oo��oo�-- - L- 73H3)z ��- - - - �_���ݠ^^���ݟWo��oo�� -!!- -! -�$33$ 1~� - - - -����Z���[��%676&'&#"�3276'.#"&47�7>32#"&'&6767632'."�[v_"A0?! ��- Y7J3$$ ��)G"#A.,= #(wn�kV8@Fv"0D�G([kPHNg8B�*��[eb�2!��5(7>B3$$'��)M"#!7)/c#*xn�fL@9N�D�H7!$�W]�B�$&����d�X�D��D��>.54>"".#"2>767>54&�0{xuX6Cy��>>��xC8Zvxy#!?2-*!')-?"CoA23:+1! "3)@+)?j�DH-Sv@9y��UU��y9@vS-H-&65&&56&oM8J41<*.0(@ )*D*2Om��9��w���.���2&/7'/&477"/&4?��B�B8"._��{�i�BBi - �BB��B�B�BB7._���B�B^*k"5._��{�j�B�B�Fi �B�B��BB�B�B77/_������������������2#!"&54>!�"264��d:;)��);<f>X��V==V=�.2�G);;)�3-��D��=V==V���������� "/''!'&462�*$��������3�,#*���*#��������4�$*����'� ��2�@�K��#.'#5&'.'3'.54>75>4.�&ER<,� 3'@"<P7(��d�W(�WJ.BN0 2Uh:**& h)1"37�N,?iB$.,�� -<d>��MOW(kVMbO/9X6FpH*M�6&+��� 4C4%����d�f���J��2#4.#"3#>36327#".'>7>'#53&'.>761T�^�'<;%T)��-6"b �"S5268 jt&'V7 0$ݦ --$a�P�N(?",9J0* d2�>2 -"�"� -7�Gd/9+DAL!X������������32"/&6;3+##"&?62���*�����Ȗ�*,�����|�������������%��#5##!32"/&6;3353!57#5!�ddd,����*����dc������,�dd��|���d����d��d������������!�%��32"/&6;33!57#5!#5##!35���*���X������,ddd,�d,�����d��d�Pdd�d��������L�������32"/&6;3##53#5#!35���*���Xdd�dd�,�d,�����d�Pd�d���������L�������32"/&6;3#5#!35##53���*����d�,�ddd�,����d�d�����d����������������32"/&6;3#53!5!!5!!5!���*������d��,d�p�d��,������������������������32"/&6;3!5!!5!!5!#53���*��� ��d�p�d��,d��,����������������LL����!2#!"&546!"3!2654&^������p���g�);;)�);;L���p��������;)�);;)�);��������LL���+��!2#!"&546!"3!2654&&546^������p���d�);;)�);;�o��L���p��������;)�);;)�);��$����������LL���+��!2#!"&546!"3!2654&!2"/&6^������p���g�);;)�);;���$�L���p��������;)�);;)�);����������LL���+��!2#!"&546!"3!2654&#!"&?62^������p���g�);;)�);;����p�$L���p��������;)�);;)�);�����������L��5��!2#!"&=463!2654&#!"&=46&=#"&=46;546&������p�);;)�>�D����L���p��d;)�);d���&�� -��� -��������#��%2"+'&7>?!"'&76�6763 �,���� P''�� -K � � -�S#���� �nnV/���������L��5��!2#!"3!2#!"&546&=#"&=46;546^��>);;)��p����D����Ld;)�);d��������&�� -��� -���������1��!2/"/&47'&6#"3!26=7#!"&5463!��m��)�8m��);;)�);Ȼ��p����,��pm���)8m��;)�);;)���֥���������������#���2".4>"2>4&2"&4��ٝ]]���ٝ]]����qq���qq�{�rr�r�]���ٝ]]���ٝGq���qq���sr�rr�������L����#��3232"'&6;46!2!54635��� -��' �� ������gd����V�^�|��d22�������L����#�� ++"&=#"&7>!2!54635Gz -�"��'�����gd��M ��!����d22�����LK���"�� 62"'&4?62!2!54635�q����������gd�q���#�����d22�����L�� ��#�'��762'&476#"&?'7!2!54635��*M�M���К��=���gd��M�L*����Л��:��d22�������L����#�'��/'7'&6"/&4?!2!54635^WЛԛ��L*�M�����gd���КԚ��PM�*M�X��d22����������% ! �����q��3�g�q������������dL�����+!#"&546;!3#53L��D���d�dd�����p���,�������E�����/��'&"!#"&546;!3#53"/&4?6262L��_ ��Ȗ��d�dd�j�\�jO)���_ ��p���,����j�[�jO)���� ����>��'.!#"&546;!3#53"/"/&4?'&4?62762Lg�%�������d�dd�F��F)��)F��F)��)���g����p���,����F)��)F��F)��)F������������/��!"!#"&546;!3#533232"/&6;546L������d�dd�d��*�������p���,���������������������/��'&"!#"&546;!3#53++"&=#"&?62L�*���n���d�dd���d��*��p����p���,��������������L� ����!2!546#!"&5!52L�P���d�L������&��������}������-�1�;��&=!5!546#"&=46;#5376!!/&4#5;2+����p��/22�dd�����p��ddd33��*��Ȗ��d������Ȗ�*y�d�����d������Q��%6+"&5.546%2+"&5.54>323<>3234>^%�"%�� -�" - d d 1t���5gD� �>?1)�A�..@� ��^ ��^ ��d���L�3��"!5265!3!52>54&/5!"!4�"2�pK�K�p"2�K�KL8 -��88 %��v% 88 -x88 %�v�% 8�������LL��� �$�(�4��!2#5'!7!!2#!"&546!55%!5#!!'!73�wi����pdw�%,);;)��);;),��p��,���d��d��i��bb�d�;)�);;)�);d����������f�dd�������&��767>".'.7�.�wf��w3�� .1LOefx;JwF2��1v��ev�/� 5Cc;J�|sU@��������L�#�A���2/.=& &=>2#!"&=46754>���ud?, ���� 1;ft�pR&m��m&L!((" - -�""��""� '$+ �� - -2��2��2/2 !��������� ��'��!'3353353!2+!7#"&46!2!546L��������������J��L�P����������*dd*��22����d���L� ����#"!4&#"!4&!46;2�d);,;gd);,;���;)d);L;)��);��;)�D�);���);;)���������L����%�)��!2#!"&546!#3!535#!#33��|��|�D|����������,�d��ddL�|�|��|�|���D��d��dd,d��d�d��,��������L����%�)��!2#!"&546!#5##3353#33��|��|�D|����dddddd�d��ddL�|�|��|�|���D��������d��d�d��,������L����#��!2#!"&546!#3!!#3!!��|��|�D|��������,�����,L�|�|��|�|���D����d�d��d���������L������!2#!"&546!- ��|��|�D|������,���L�|�|��|�|���D������,��������L���� �)��!2#!"&546!!!#";32654&#��|��|�D|���d�D�d�&96)���)69&L�|�|��|�|���D����dVAAT,��TAAV��������L����%�)��!2#!"&546!#3!535#!##53#53��|��|�D|����������,�dd��ddL�|�|��|�|���D��d��dd,��d�d������L�����#�'��!2#!"&546!3!3##5335#53��|��|�D|����D���dXdd���d,ddL�|�|��|�|���D���p���d�����d������L����"�&��!2#!"&546!#575#5!##53#53��|��|�D|�����d��,�dd��ddL�|�|��|�|���D��p�2Ȗd��d�d���� � �����%���2".4>"2>4&!!!'57!��۞^^���۞^^����qq���qql��,��dd,�^���۞^^���۞Lq���qq�����dd�d����� � �����'�+���2".4>"2>4&#'##!35��۞^^���۞^^����qq���qql2ddd�d,���^���۞^^���۞Lq���qq����d2d2dd�ddd�������A� �6��2632+54&#!"#"&5467&54>3232"/&6;46�n�,,.x��x����PpVAb�z� -� - � & � -�Awa����sOEkd�b�� -���� -���������A��3��2632&"#"&5467&54>++"&5#"&76762�n�,+.y�xZ�� % �� OqVAb��� -� -� -� - �Awa�xc�h��sOEkd�c����� - -�����d��Lm���%5!33 33!#"!54&#���������Ԫ�����2�dd,,M������d22�����y��7��/��2#"'2!54635#"&547.546324&546X^�Y{;2 iJ7-��-7Ji/9iJ��qY�Z=gJi�22�iJX5Jit�����'�����*�B�J�b�{��"&'&7>2"3276767>/&'&"327>7>/&'&&"267"327>76&/&"327>76&/&�oOOoS���SoOOoS����=y�" $GF` Pu "Q9 �c�cc�cVQ: Pu "�GF` y�" $�o����oSWWSo++oSWW"�y `FG# �uP :Q#�cc�cc:Q#uP $`FG# "�y ����d���������"��!#5!!463!#53'353!"&5+�,����� -?,�d��Ԣd��u -� -� ����� -��������� -��� -�����d����� ����!��! 463!#5##5#7!"&=)+5�,���� -?,�>�d�Ԫ�� -| -� ��^��G -����|����d -77 -P���������������#3!#732!!34>3!!��dd�Ԣ���!,���d!s����,� �d,��+$d���$+�p�p��������LL��2�9��3232#!"&=46;54652#!"'74633!265#535�d2��2s);;)�����;)X>,>X�����L2dd2��;)��);�FD);�>XX��Ԣd���d���L��6�=��3232#!"&=46;54652#3#!"&54633!265#535�d2��2s);��!��);;)X>,>X����L2dd2��;)���$+;) );�>XX��Ԣd�������������� #!"&762#";2676&35�} ,�, }@D�:#6#:�����&77&P'�L��.�dd���� ����LL���/�?�O�_�o�����32+"&=4632+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=46�� - -� - -� - -� -�� - -� -��� - -� -�� - -� -�� - -� -��� - -� -�� - -� -�� - -� -L -� - -� -�� -� - -� - -� - -� -�� -� - -� - -� - -� - -� - -� -�� -� - -� - -� - -� - -� - -� -����������)�3��3#!2!&/&63!5#5353!2+!7#"&46!2!546�dd^>1B)(��()B1>^dd��>���J� �L�P��dO7�S33S�7Od�d�|*dd*��22����������+�5���2#4!!2!'&63!&54!2+!%5#"&46!2!5460P9�<:H)"��Z�" -)H����J��L�P;))�%&!��!&��*����*��22����������$�.���2"&432!65463!2+!7#"&46!2!546 �jj�j�."+'��'+#��� ��J��L�P�j�jj���9:LkkL:9�r*dd*��22���������,�6��2"&5477'632!65463!2+!7#"&46!2!546X/[3o�o"�o�"."+'��'+#��� ��J��L�Pk�6NooN>Q�o�� -9:LkkL:9�r*dd*��22����������"�,��!!.54>7!2+!7#"&46!2!546X,��%??M��<=Bm�J��� ��J��L�P���9fQ?HS�TT�vK�~*dd*��22��������)���2!546754!2#3#3#3#!"&546/R;.6�p6.d�6\������uS�pSuu;)N\6226\N)�G6.dddddSuuS�Su���d��LL��/�3��!2#!"&546!2#!"/!"&4?!"&=46!'���|� - -��� % X��W & ��� -�dDdL���D -2 -� % XX % � -2 -ddd���������L��#�-�7��!2#4&+"#4&+"#546!2!46+"&=!+"&=� Sud;)�);d;)�);du�);�P;�d�dLuS�);;));;)�Su�;)��,);�2222������� ���� !&4762 !2!546������ 'Y��V/��� �|��UY�Y(�n��0U�22��������!���/��.#!"3!26=326!546;546;33232!�'�p'�q*}���20�/2�������22,��2��������� ���"��!#!5463!#5!#!"&5463!#5�, -���� -w,���, -�v - -w,� �� -O,T -������ - -� -�������dG�F�V��32676'&7>++"&?+"'+"&?&/.=46;67'&6;6#";26=4&��K�jIC - - -)V=>8'"d1*�)"dT,�|-o�tE� - -� -GAk�I -! "%,=?W7|&�F@�Je5&2WO_e_ -2 - -2 -�����~� �$�4�<�R�b��%6%32!2&'&#!"&=46#";2654&'&"2647>?&/&6%?6'.'.��. ��+jCHf7�" *:��>XX�P*� �@--@-�� -?0 !3P/|)�( )f!% =��&* x�"6�2&�CX>�>X�83D�-@--@�ۂ -# �=I+E( /�/}X&+ 5!H �����d��9��Q�`�o��322#+"&=#+"&=#"&=46;#"&=46;546;23546!2>574.#!2>574.#q� -Oh ..40:*"6-@# -� -d -� -� - -KK - -� -� -d�))��k))� -m!mJ.M-(2N-;]<*K - -KK - -K -� -X -� -K - -KK -��� -"�p� -"��������)�,��!2#!"&'.546"!7.#�Vz$�R��R�(z �}VG+�0� )IU!���zV�`3�BBWwvXZ�3�Vz�&--%��,(1#������������32#!"&546+"&=ۖg�T)�>)T�H6�6�g�)TT)�g���66������������33#!"&546+"&=�`��T)�>)T�H6�6���B)TT)�g���66���������� %'5754&>?' %5%����Nd��d/��\����^^���<��ǔ�Ȗ� -(A�b��������d�� �����2"&4$2"&4$2"&4�|XX|X�|XX|X�|XX|X X|XX|XX|XX|XX|XX|��������L������2"&42"&42"&4�|XX|XX|XX|XX|XX|XLX|XX|��X|XX|��X|XX|����d�dLL���/��!2#!"&=46!2#!"&=46!2#!"&=46}� - -�J - -� - -�J - -� - -�J -L -� - -� -�p -� - -� -�p -� - -� -������������/�3��!2#!"&546!"3!2654&!2#!"&546!5^������������);;)X);;����G�������������;)��);;)X);d��,d�������d�d�L�;��!2+32+32+32#!"&46;5#"&46;5#"&46;5#"&46��222222�222222L*�*�*�**�*�*�*���,����� ����*��.62"&%#462"&%#46"&=32�W??WW??��|�|���|���|�|���|��*(�C��BB�����|�||�|��|�||�|��Ӑ����������B��76+2+"47&"+".543#"&'&676/!'.6�E* '?)�� -T��0I'*L -#3�{�,# -n�� 6F82 ��*<SC# -(#(��(#�����������%�C��#4.+!52>5#"#!#4.+3#525#"#5!�2&�2�p"�&2��D -d �2d -�� ��dd R ,� -�W 22� -���������L��� �0��5"'./#!5"&?!##!"&=463!2���E�� 1;E%= !'��y���,2 " -��# 22+.��"A2�V����dd���������G�J��!2#!"&546#"3!26=4&#"'&?!#"3!26=4&'"'&'#L��FF ��& 7 - -? -99���g���LR� 22��22$�������������#�'��!5!!2#!"&546)2#!"&546!��P�����pm��pG,Ld��|��p�d��,����������#�'��!2#!"&546!2#!"&546!!5!2��pm��pG,��P���|���p�d��,��d�������d���'�+��!235463!23##!"&=##!"&546!2�d�dd�pd�p�,�����d���� ����,������������'��3#3!2#!"&546!!2#!"&546ddd���pG,����|�d�p�d��,��p������d��L��'�+��32+!2#!"&5463!5#"&546;53!X����|^��d�,L�pd�p�d�d���,�������������'��!#3!2#!"&546!!2#!"&546�dd�v��pG,����|�d�p�d��,��p���,�0o���� #"&54632a��5���*����A�2�~��� 6'&4O�**�{�)�)�*�����2A~����!2"'&6d�)�*��*��*�����2,~o��� #!"&762{�)�)�*a�**���������(�� -��5-5!5!��L��c��� �����������������d����1��#3!35#5!34>;!5".5323!�������,�P2&d2�"d&2���dd,dd� ��dd & ,������L��%�1��#4.+!52>5#"#!#3!35#5! 2&d2�p"d&2 ,������,� ��dd & ,��dd,dd�����frJ���32 +"'&476�� -�0� -� -�)� -J�0�0 �� ��>�f�J���32+"&7 &6S� -��) - � -��0 -J �)�) �����f��Jr����"'&=46 4 �)�) ��w -� -�)� - � -�0�����f>J���� ' &=4762j� �0�0 ���) - � -��0 -� -��������=���:��#463267>"&#""'./.>'&6�|��Vd&O"(P3G*+*3M, :IG79_7&%*>7F1� �|�|���5KmCKG\JBktl$#?hI7 ��������������!2+&5#"&546!5�X����,��p�� ��ddd������L�����!2%!#4675��'=�DX�Dd d�Q,�[u�}�4�]dd����Mo�__<��������vs������vs��Q���������������������Q����������������������(������������d��������p�������������E�����������������H����E����d��{���������������������������� ��d�����������������������&��n��������d����d����d�������d���������������d�����d��������������������������d�����������5��d��������!����������������������������������u����������� -�������������������������,��d����;����������������������������������������I����������]�����������d�����������d��������Q���������E����������J����������������a���������������������d���������d�9����'�d�������������������������������������������������d�d��������d����������������� � �����d�y�'�d�d�����d�����������������d������������d��������d��d���d,�����������������d��,A�2�2�������>�f�f���������*�*�*�*������NNNNNNNNNNNNNN�"~���Fn��2b��\�r� b�b� 6 � � � -( -L -� -�0��X * ^ �h�(��T��*v� -8|�t�*�<��6`��R�.j����(h����6h��^�2��Dl���.v�b� F �!2!v!�"@"�"�##"#8#z#�#�$$0$^$�$�%4%`%�&&~&�'P'�'�(4(p(�)�)�*&*J*�+ -+z,,h,�,�--�-�.(.f.�.�//F/~/�/�0>0�0�11`1�1�2$2^2�2�3"3>3h3�44`4�4�5,5�5�6>6|6�77N7�7�88B8�8�9 -9J9�9�::l:�:�;�;�<<P<�<�=2=�>:>�>�?(?n?�?�@H@�@�AA~BB�B�CCBCvC�C�DD`D�D�EZE�FFtF�F�G6GvG�G�HH2HNHjH�H�II8I^I�I�JJ.JR������������������@�.�������������������� ���j��� ��(�|�� ������ ��L���� ��8���� ��x6�� ��6��� ����� � ���� ��$�� ��$4�� ��$X�� ���|�� ���0��� ���www.glyphicons.com�C�o�p�y�r�i�g�h�t� ��� �2�0�1�4� �b�y� �J�a�n� �K�o�v�a�r�i�k�.� �A�l�l� �r�i�g�h�t�s� �r�e�s�e�r�v�e�d�.�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s�R�e�g�u�l�a�r�1�.�0�0�9�;�U�K�W�N�;�G�L�Y�P�H�I�C�O�N�S�H�a�l�f�l�i�n�g�s�-�R�e�g�u�l�a�r�G�L�Y�P�H�I�C�O�N�S� �H�a�l�f�l�i�n�g�s� �R�e�g�u�l�a�r�V�e�r�s�i�o�n� �1�.�0�0�9�;�P�S� �0�0�1�.�0�0�9�;�h�o�t�c�o�n�v� �1�.�0�.�7�0�;�m�a�k�e�o�t�f�.�l�i�b�2�.�5�.�5�8�3�2�9�G�L�Y�P�H�I�C�O�N�S�H�a�l�f�l�i�n�g�s�-�R�e�g�u�l�a�r�J�a�n� �K�o�v�a�r�i�k�J�a�n� �K�o�v�a�r�i�k�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�w�w�w�.�g�l�y�p�h�i�c�o�n�s�.�c�o�m�W�e�b�f�o�n�t� �1�.�0�W�e�d� �O�c�t� �2�9� �0�6�:�3�6�:�0�7� �2�0�1�4�F�o�n�t� �S�q�u�i�r�r�e�l������������2������������������������ ��� - �� !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~��������������������������������������������������������������������������������������������������������������������������������� - glyph1glyph2uni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni20BDuni231Buni25FCuni2601uni26FAuni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200uniE201uniE202uniE203uniE204uniE205uniE206uniE209uniE210uniE211uniE212uniE213uniE214uniE215uniE216uniE218uniE219uniE221uniE223uniE224uniE225uniE226uniE227uniE230uniE231uniE232uniE233uniE234uniE235uniE236uniE237uniE238uniE239uniE240uniE241uniE242uniE243uniE244uniE245uniE246uniE247uniE248uniE249uniE250uniE251uniE252uniE253uniE254uniE255uniE256uniE257uniE258uniE259uniE260uniF8FFu1F511u1F6AA����TP���wOFF�����[�������\�����������������������FFTM��X������m*��GDEF��t������ D�OS/2������E���`g�k�cmap��������rڭ�cvt ����������(�gasp������������glyf�����M����}]�ohead��Q����4���6M/�hhea��Q�������$ -Dhmtx��R��O��t�� `loca��S`��'��0o���maxp��U���� ��� j��name��U��������,��post��WH��-�� -Ѻ��5webf��[x�������TP��������=�������v�u�����vs�x�c`d``�b `b`d`d�,`�H�J�x�c`f�f��������t���! -B3.a0b���� ���������?��@u"�@aF$% -��1����x��?hSA���iS�����m߽44���,q�PK� q��XE]�(2 �.�ԩ�]�� "E�D� -����i]DԡZJ���\��8�����w��w�������V"�F�pUԯ���.Χ(�g�K�4On�;�N���R{�g`'!��P�M�UHEՠJ��ʫ�*����Yq�9�c��<��U��9�!�Q�I��Y�ׅ-��KC���+ դ��U)�Q9�4�J���Yp�]Nq��9�.q��yVV -�n��)��9����[��{�����v�V��כ־���FWb++{�>��a|��*��g�Q���,K�<'����<!�ɣr�Yw֜β��y�<q9�{-]����c���]o���I���!0l6�7��͍��{j�G,�OX�^�P�d�Q����{,�M4�c�(QBX���m!�K�,��Y��Ha�2�}�̘��0B�A�)ؐF},�Q8����'A5�(�>W@�Ex̢�D���&�U�d�#����&� x�Mx�<�a�a���,l2<���M��02���6�Π^����P�$Ґ6{��,�#�ƞ�{�M�wp�B��8H���#�6�7ad�&'~�95r -3w�"�[�Et���W�:�ӭ:$"��>2��c��5*�.�l����N��/����h����]Gt��T�������(�������x�Ž |յ0>w��m#Y�e[�%Y�-YR'r���Y�j��D% �,@�B�KZjH�ڤ@b���-�R���+�n�hK�~���룼���$��;��h������^f�ܹs��n�{ι˴0��kb8Fd:�%Lה�"��1��A�Ք�A�Y��>,�ؔ����#�p�Z�4�؟��5�ma�d�e�� ?Ȝy�=����I:C�� �D���(nI��x�L�.1�!�P'�JD�t�Hj�@L4��P���h' )�b�)vH�X,f�1�c\'��cG�����u��>��1�~�t��?����!x���T_q�?qB���F���#�L%��D�ћ"��?Y�����ǯ����j??8>N�Skem���AY���Db�4 �J)��;�@�j��P$ -��'qh�8`��;a���X��6C��F�*�d�Y�c��"����������'?h�L�V㗌�,�>c�e�3eV��h� =C�������~��xC��\((qb@�4��x�K&hׁ� ��4\2�DZ6N1|-�;���j��� Yu�@��j��ѫx�����i�䊧�mK���ٍD�E�w�q3�̷.��cAw@�4t.�g����kg��r�{~��Wl~�{��lW2����}�27�6a2�\�6o�z@�$�����H�S��H� �g�����b�t�X7�0K�t��c1�,��7�B�oL��Ə�6��6[,���%�i�Z ��,�l>T�p�K��SGg�\> �#��A�#3���E��y�k��6v���������;u3�!ZI�8��M��k?�8�C��Wq{`�C*��h>H���1�_s��k��h)����oj�OO'� -!~dX�g��B(����0< kOYx�e����Ƨĭ5k��=d���ϧ> ��+�t�C�-o -Ǫ��/���_ko�ܶ���s��+f���O�z�tp�u7-�}�d���9� s���e ��\9.H4�!0��S\ ʱk2��"?ip7�\2z����lް�t=��W��\!�KyOXimU���nov����6�:��� 2��LZkA�A�^�qC�ޔ &P���aF��I�0��>�&���Q�#F�Q���l�> A�·q*�O��������Ȧ��_@27��l�,���s�����f��6�p7�ܩ?���M�����1v�A��2��]$j"��;�v�lk~va0��g�j���z����RD:�g����c�6���yw�%�g�(þ��#'��uB��#�=�_@?�>�F��Vb�0�a�!�aL4tXv���:�F��h��9��j^�xތ����z��}�Wn�}7}���j���Κ��i�H���������i���t���K�S���a�XE��E�bbBQ1���f�t�x��FȮ��-"dqA���\��~F`���6�i䁕+��Ԣ�^Ȳ�}ש�׆k&��Ĺ�����<- \�;��g1>�w�0�0�v��^x ���7l�<��y��}��S�o�9��-ۮ�6k�бl˴��n�����o�庾i[�u���~¬�o�`j����{i�\C4,"iW8�J�o�V�bp��w��C����!�;�'7�D.v���֏� n��oZ-n�����e��P��io4�~LY�/zm�w_�������g�Ͻ����R��"tޠ�&NoN��)4��M�C�G2��\j��8�d-�@>#�Ot^���5�+x��e.^�]����G�8�^� �m��(��t1 �s��bf�J���� �%�����<���4��H�����@e���8C���,�5<�(��k�c5Y�I���������A��]|�ך�l6+��=�HV�cb�KՋB�6�i4�#��_��|&�>NvQ�k#�pW�=�u�7��HɰR$ ���� �[5싙� ���g� ���%�1��9}���������&@$&�������l���=�1RI��}9��#�ς�z�??1z&��ı_a��c|P�I[��:u�;�����l��->k4���G���Y�m|Z��w� }���Hn�R=-B����~�m����.ِ� .����Mz^,���0�%���8��E��G��**|�sg|o����zO���֬0s��z���.���WN��^� ��yHk<J����{n��E��h� - -TG�~��o]��V�ṇ��zn�Аzd�,/�)j�l.��w<w ��?5*F�qH|�<f7�[�6T��d��������?�C8��S�'��N -#�0�f�2^~7��: -�m���M I��`M�:ӊH����F��9�B��:����g���Sk�oz��k���#�S�o�̨oc3�����A��'ӹm�i�k�n��Z�-�y�ZP ��=Uc�'����?&ȏ�K��Eu�l�;��><�v3t{8-�|�' -��e��a~���H94��x���A�-�@�y bT4@0�b#]D�D����lj�DSio:Ag����S��P z:�;��-�|yH"r ��{�B{\��5RLi�6�A��A���tM�]����t���a�R�K����C��!�1��C��gC�샂� +���1EG�!����Xz������ٛnz��v�@�x�������-#i^��x�*�$)���W���=�O\f���[W�����X~V�?�����`Lei�::v4��$?�=R��a#�c��]8Y��FJ�b&'{%LC�E�������Cf�]�^$��/����fߪ�M;À�;����� �����6��CX��V�����#��X~F���<� :�vC��c��yBpLv�����1��F�v#�9� -/��8VF�01��_K��?��x�>�}��#�G7�т\W�p!.@������b�wɡ+{�o����#�ԍP�QҮnī66 -cZ����D�����(. ����u�;n�M}�����?������v�t��x��F���{�+�����`� -�=��"�rPπl�D�V̶��������?���Z@�H�䰅]��[��3��5��%O���)�\^���� Z;��>�F��tf�-I�zӮ����y�u�1�u�o<�:�oa:uq����w�ykk ⋜�}0?jv��X+����}V�����G$s���� -?2�6������Y�I5c�$�Cf�b!�X�*|F���^�$�p�7�p��55���߶6[�m��jg������l>�*�� KO& - ��8�ܝ�:ǰ�o���k���K�m~�o�S�-*4�E�}P/���%�k:�e�"�1A�J�����CAX�����8= �L�Ţ>�ܱa����v{�|K.3���:\B�x���w���b�eb��<n�/�N����jN�j�OTQM������է ��g��[ -1��J�[H*�d÷���J�(�R�Y}����Ҙ�c�hC;�ay�h��&�Cq;7/SG�n���y'^���9wה[�y��F`4;��upX_#��6Qy'�xC��q/�Q�P&�N�t���4p����ԍqD�2/ع��i=����X�܆D�A�<���-��>>�1ۿv�H�?�f��58����%�6�$ɲ�'p�L^H��X�bpI�Vqn�����A�8��K�g'i�!Uz��SE��I�����5���N=��hp��V�?��(�E� ������V��r��?��7�������V�ڋ�ɿ�.��O���;������p��4��N�RZm.�O��> Mu��L'��j5����`;�Mt�AQܶM����y�V��<`�� $m)�y��ڳ�X���Da�:��݁��q�1�J�Fq�15��-�l��\��3�~X��-2pF�D�e���/�f!��2��i�:��=�h��{�%�{t�^���*�P����Bͽ]��Y�D3��jd ����*�w|��GLϽ}�ˑk7��Ç�=0��6�o�z*����zo��1~J�w0�0S��e�Pw%���#@BJB �� %��+�� �'����;�%!&��)�H�q �7f�q�H.�������!�E�ǎf��,�9՚�$9� �H{~i��� �Z��)O|��!"��D.K��Qa2� -%���2W��ɂ\�{�*��B{7�,�9.�'ew U^��W��&�$�r9���rcG�B��wl�����l�<�����ʷ�SQ�ゅ��h�! i�Ѩv���J :�Y?��#���_�m4��q[�������}�,�E��A{V�П������P|�D��g�?9M���Id?{�)���/��� /\[ ��J�ҏ����[��f4G>����Q�K��^��m�� ���O��� -7w�]����<�U3jƏ,���:��Y��q�~�0��/�m��ŵ@C��C�F�q<��y�x�h����\�0=�RgY�d�(��(_�2������a��_�{p�M�T*��0�U��T���!�if$ԟ�(W�q�RC:P�a3=b�� rK1'-�{����H�ʽH�1��'`�kϯex�$��.�h�{܆`�F�z�E�0��c5xfM���䏾}�߾S��S�����K�]N�f'�pPιS�`BmmH�v9�4ሄ^�m �D $����,�'܄ �p�Wɭ�g�dV/L�;���MZL����ꭵ�H>{�,�������Θ������쬷ΘQSo �l���sɿh���?A��2q���`��5����Z��&*�X1L5:�6����ς+����O]ue�j�����%?�ۼ&���aW?{����2[�}��W?��J�b��Ι��k�-\���b7�sI�kf&Λ�f�x~���n�O-9�V��� �~c�W"ȗy)b\)�2MrW��f�;M��U�7��'[�������-c/��.�ؾ���u�M��l�&��.��9��) G���!�!W* �60C�ф#��q�����rq�O��K�ZO�Wq�,�8́/Xp����T��ȑ�g<>�¤)��[J8�o` -;��S\�S���������%��h~��p�|J˾F~K�=E0N�Q�X�����*����8;D7�Q��1��QC�% *E�y�y}�� �UG?>�I`�>���'�6<�+�����3IV�g�Ϯ�yO����Q$WBv��H v�[�Ϗ 2�+����'�ø6N�߆<�������ɕ��� �2��S�娚9��X�1�\�┣����df>�B�~�����-��t>�W�]��p�Pr��Z[��'����+��ƌ�l�9]�8q��C��!��'�@AA�Ou�Ш� -!?M\�JMͭ�fǞ)�ߕ�=���w?A�N>�����¼}�jQ<ǏpǠ^���(��}����1�+��2��qF��4R���iHď��IT�r8���^����!gm���>������'����ڸh��E�`�s̊o����l���!�(9~�� �o���%#�)�~ƃ�j$�@�Ք�Lp�G�Oa{��߿f��é�)�z�ؔY�<����������~����^��c�����s����潺��������ݴN�RU����R�T�Y%8�����K�s3�q�d]^�QTb' ��zx�)�H���FҩP�mU�Z�jQ&�X��Ɓ�o��<0�j�YG����z�]����$8c��&�h�y�ݼ���wΞ{��9^����sf߹�m[v������ӣ!�(Z�As��ۧ��y�B�������8RiԣB�g6�{�Um��tyW!b�pǮd n�/ŷ�ʼ@v��/����%�c������x�En�:��4Y���²�,yZ-�kr���cH&��^ȩ�C�'Ȯ'^T����5�������r)(�(I��J�U��&#�! +YM.�J�EX^|����L��w@��ھ��Zsg�Y�洺���\����x�ԟ����x���y���L��Cyo���<�Q�O$)�W�6�m%݆�r݆�d����ս���{��O�b��p��AE܀ʌ�g���������i��~�A������O"mo*�!��[T�����m�dH�T1�$� - �PԐ4^��sfcA3��,��XA��P��b�ks�Y��� �yH�h�P����+b�W�=}���;�����"Z&x<SySVY��&=��4��&��1J�5u~��,ӿ�z�e��g^QB\/�Pʄ%�+p�re|Pn� �T��cZ>?���e�V"_[��Q�/�5Y���|���qI��/\��9������di��EBh$���v�������wOL� ����fp�a �,?H�gH�f2���RbL -v >�U�So���^1/,��ē�vc��Y��Gm��Ũ��~�Am��z��?�/���4��0���yj̸p�k����2��H -��eE�R�b���/"M 7�5u�l�[�drC�&Y͐�&I� -`!>p��;���J-�b���--.�V�M��4>��Fj��/�5���σ�������t5}�>C�*�<'���d��?,c�����d�Gf����2ҁ0w��6����L�h"�f�K����ζp;���ǿ϶P�d�c��1�EO���i�%����Ř(DC���W�����V�2��I)��T�i�M���F�T�z�0������U�� S��7V�� mBW6;�nYZU�zS�Tg>(�h���F"�T뽷���R]���L۶�|��Lx�[�s,'NU|����E�<�4)�R����p�*��vU#�g��*�g��jə*=�~܃��A�S��ē���AJ�Hw�3@Nur�bw���Ȁʌx�}[�`�7������Z����tPlh ���L.)NU�}���kq�'��v����FQr��{ˤ�S]�Z�L��(�@�*�Sf�^��+u�Pe_k#��.�8��ɂ%��ՠ�,���@���TK��х��� -t`�ߑ�X�AD;��b���|p�A��7�}q���2 -@Y�`�~�������iԬK��0j���Y�( ���R����~^��ҧ8�>��=�F"�˜A[��Dq�vQ�C�X�|Z��sO���<NǦ�c�PI|���։��2����ů��1��Q|��FH\[ ��T�k�$���3���X����5��ˮA��q�_��rv��7���@��v�2ˀ��i%��m�؊�f���P��^{�ovvy�fV�w4e�w� ""Zd�[��T�Cʭ"ٛ!C�ƛ���#^��� -��Z���fR�4���x��p�V�rSK\���B��]Q� -���B~#�V*�p�x ��^��(���o/`D��ס�.����E�OWTv���6�����M^~Ey�l��/�ѫ��NJ�l�Q�6M����q�":}H�ea���-EY�"��z"�ȏVKF5����8�/7 -t��D�n#D*'����^I��������Z}pITmdL%�7�@�C�:F��By%����������KS<K�Re��ī�so�k��|ȝr��^�s�u�~�����w�N�_�V�P�6;�Y�\�\�l�m����I��"����R� -2���ts�0��^~������ -��;�gELc�7�����"�����<^�����$�g$�y����s��L״���$֠�D�> \�/�f.����F;���k�P��b�d�z7ԐeͶ-6�b�y���b�aWjnh7Y�L�F�!�4��w��ssF�C�n�h��_0����>�M�Z�� ���nC������*#5/O�U�N\(3o�@�[7`�Mg8x��g�e;f\y�|f֤�ޑ��]�i5��q5q&�>�'����������353��k�Yꭑ��=W�7��+yx�I�e<�����P��h�X a��v��"���cJc�oH�O�Cu]�L5��������k����і�����]x���~�#�;!���)B58�/P�� ��H��F#0��B(��p�}�Fst��M|���l��)]tϼ&�ݖ��,㙗nt,�h[��Y4ݬ$�wQג�,��@�����k�`D��g]r����|��Y}�Vq�wRC*��9[o�����Ν�d�X6��&�=���}��߰�/*͏\�˔)���5gO�l�Ӧ���}��1:>O��YǏ�s(�p6��[��B/t爁*̠-n:�� <Ц����)����+�ް~q_}����oxt>L���V� F���G�@d�9��[<�s/����.<7���s�B���d�B'�wX�����ο���Z鵣��W���>2��?�2ȳ���8�笞��={��fg�csC����m�����r��e��#���E>���45�qo:�J���X��^io��P,x��f�:/y��n9��V�ѥS�7=����u-�\�%�K�ϦUv���,�Ⳁ����Z=�v���k���N�*+_�.�ڊ��֞�i��ڃ=w @��l�m�r��>��O���o,VԲ���ɝz&:'�4��5���!��9�pI 0@I[�PU""�s��Inv�R>�A����9t�$�3/���|k�8y�i�E �����c8��E�!Q�\ۂ}%A��f4�s*�A8���A���>D��=5uw�����j��nG �z?2�Q�/I=��f�H���4�n���]�澀�Ym�G"��2�PE�H��f�vZn�<�PiA_�q/��P�Dտ� �$$�~%Nyhr�OdM\�-��m�(��@\���#����Ƽ��N��J�O���>a+� �uJ�*(%�¢FP�J�W����������,$)���)��������}��� -B\����_������w�V�] 0��T�OCÊQ}��5����{Ho*�;;�葞�rǨ���M�c�5����4S -: ��M�����7�(kY:�����z�`�gp �J�stˉ��v'���e��G^~����i�D��1����6�dA �@'N �����֭<?�Ғ9庳b���ɩ�EÁ:��h�{��h��0��vۧ�Q~�{�"�H����GQ�kl�<�:ʛ^g�/���_i��������P������>N.��?�f� �1��b��zJ���D �V -o@7R@6�<��%IF��0�mj= �[�}N����ۊ�57��p��y��v4@<mЭ��9T��p?��R7�����0қ���Q�G�[j�������zi���b����~��/)wC?�� רa�-/�C�n���.ĕ�Hj63������p���Krh�����X��I�Ǝj� -��o��1��9 -�f�\�~�:-��ѓK��4��7BY���̆�y%�DC~e��m��@�]���%�r����s4T� ������G-�Ug��>���H�OpV�B��]�{9&�^6�|�m���_PLLI7ǒ�i����"'T }���? 4�����|��[Fǭ�tu/�_y;Z��?��H�K�0W�z��c#����)��~.r��ĥ+�B����&J���G�0��[������.Ρ�r��O�k��;VC���oX� ���KS߳�r�t�����:z�X\��xm��Jh��x���N��h�5��K�`�;ydp.Ec�4�X�D<-�ll��ip.�^��p��:� �u�/����.��Y[�rl��_�4����kz�$~Dq�]7/T_<菵�����4K�$�Ɩ�� ���&w���� ���S��7���|K�^�������7�MsMG�������h��w����㢴0]?���fja�5a�i��Ц�6C�2�no���f��=�)�d^����v� qNc�Ԏ����l=u���]?;�f��-E�~�����n�v��}5����%���������Oջ�d덿=�Z%v��� ��� n�K��u �̓*J���#1�h�u1Hr�� o��}����SZ�u=���w�;�nϗU������`�F���ȶ��En?����߫k&����l9�Y���d��gA��8NSG���D�09M�AK{ހK3݊����[_]�%W4z�ۈu9�\~����n3���~��zir���� �����X3k�`Ps�������n����=m���]�ԃJ�ks���T�9d���eYN`}��/�]U#��b�;R�����t,��l�h*���#JB+ -(��iGx\}~IֳF��v@T��u��֭��J�� -������� -�@-L����w�z�Y��g�����w�`wx-�����(d٢]����F�3_��X�cY�mQԃ��W�b�-��F���K�5�d-0b��球֨�T+�_�Z�x�c���j*`���}�|x�~�L�F�*�S*o�Mت�A�����T�1p�7�1?�Rt>��R'"�������E�y�)o�P�7����%���$r�v�� Q����eE�����+���n�zl��Vl�Frkt��'��'?R��'Z�CE�I�Ky� ga��0����^��}�pE;��Kq{��T/�?�i"%���1�ޒ�b�-�Ծqƛ�˵��+ ��8�]��rI����ڣV�{�dȪ͜�\�A���Q�vO�S��]0.���N��X9s��v�b?OE~�FPU}o�[Y�K�r�����A��̓U%���7D�w ����q�b�/�h� ��A���hPbQؓJB8�I��?�I%=�X�t�O�;�(P�h�L�d�� S �'h�ݱ�>|���T����V?�,O���"\�`�7�����.�2���>���D�� �f��m�g;��-����C�'����u�,���� z�A`-�ټ��$�xvc��k2��[x�p\c�b��l�ih�s���iv�aÛ��M,gĨl��M���z����7Jv����ˑV�RWϋN����o�4�(�-��XB^�Cl&Vn��n����n D4[k6�����N��&��}f��3Y�Qw�@$�U$(Ǫo�:-�ZG��#&���/�}�?��N}ƥ��7�A!M���h��W>���?iX�p���r��A�١�b���?uϱ�ι�-h������6;��S�B�#/���@ѿJ ��� -!%Q�)��Dq:{JI^ޑˡ�PY7UG��(������h�?Hm���ъ�vRE��H����=�N`P)Q�����G9��FM��S�MG��@2�E�$Q -�$�s�~�TkN�"�9�Ն8�c�F��^�"?+G٠ -^�*��gUlFVx���U�poC���.XCƵ��͉�q�K�[�k[���K�(l��;� �ӡ�n��%^�R�j�,$)� ����1��n.���G�:C��f��(��,���;��Ĵ��R�F�_~���^��;��ի�D��;6|/jGGSSG��G�ӎļD��zbR�/X?�������U��p14u�$`��[ߜH47�7I�~��~I�r�ߙs��#�6��+�h��e�W�6@wK�̸h6, �1C�"������=�m���e�A����=����@�z����� �s��ls�]�;kkl���r�^"s��青�>�&Մ�-[��{�JiҴ9[�ݵ�ȩ�-�]�dޢ��c��An�۹��g�}ꒇ��6hT���ɖ�?3s���^k���L�cY�1�Z��n[���bݴ�E߆��դ�w���k3�f���>���fM��D��ՠ�a��D���~}&���@��5�ugn��OȢ<��'`&bӬ��-6���;��X�"�d*�a�w���Y���v��t�L��X�ָk�U�ߩ����a���=HR_�@���+j�2��T*�£�%��/oƤ����y�� ����1��9/7� ��~�7����_���o����+��$D�үs�IH�:�r� �� �yiF:�����v�����(��d�O":��om����dM�8��;��Z9u�ʩ�HCg\�K/*���ԙ�g*�-�I�������_�E���Rq�R'�[�f�?G�U��Ao�vb A$�e�]��/�Կ��o�?|�Ԑ�Q�m�4�G���7�G�83��3+ �74�z*)�$J��pD��N�j5p�q���e�Df/���>�������%��g�W���{�U��:g,�n���l���U�\��t�'���%���E��}��͝�u��C��ꘒ�ܻߺp�}U�+^b'�����o(5g�V�B�I���OE�m>�������5y�zg��}�����A��P-�P/���ޫ����6�)�x5/t;1�p�1�L��9�Aܳ|����)�����X]m����kFE�H/�4}:�,oLM�o�6]Y�M�5���0u[��yҫ�fV�h��?���E-A�_i��j�� �. -6|��5�`#��Z-�sv�fq�ӟ����s�͚>���w����7C��{ A������]B����z,i�H'd����v�?�`E��� -�x,��m��z�`�F[��2a�v�hp�%(�̒���ʂ���5Ԧ;G�юh������\�y";|"�ٝʖ��rx�z�s�P�HCT�v�P$���ly}�iyhvM�C��r)�#�x���-�.(�t%fu���(ۅe��UU�o� -�p��qe�ˡ啗�s�y�i� X��k�`�>�X�@2P��. �2͌>�n�|��,/4����}����?A��&�J����r�+����ɐ��CV�]{���Z�0�- ��A=�� -F��$�+����%U�Z�y���ޗ��ٲR� �B��)�����wT8��(�a��R�Σ*-�����s�r5v ��!^tZ:/�K,'���F 9��=���G�<���C��u�"$�-��F��S2�(��F -0Q��+X����w�,�]=b�h[q�B�QI� ���;)"�Ō��9��2��6�r?��}l�V�=b�[���j��4�Az���K�kQ?T��[%��$�K�Q�-��l_@l/ &;���차�Dr�?P_d�E1�~�z��^I�~b����r��e�u��f��P�/�պ#�E�+�S\�G�-�R4��� �S���S��V俑;���*`�G��*5'���d�L� -���~���� ��5��F���hb`� -�ꁜ���4��[b$~�G�N�AX$����~�}[��W�}��_��z×6m��&~O�%��j/�r�&|_S����y�<��-�*Lϛ���,��JQ�z�ͤ�𫷣�����|�V|�GVW~��<mbl���������B�&���̭j���y��\r=���'�9�H�f)������ԅr� w��!;;vs��B�7Ӏ��'�k��*��ir�����b�/�K�+ԔW��R��O ����h$!`�1�[�r�����(�a\T�R�����"P�?]Y�;?��х�yKRX�W�OCz���ܩ�H�jPn��[��忊�;�͇G��q��Z.�A��.*�@/�)WQHQ���U�L�2^��$,T=Q����(J~�BI�UP�J���=�WC@�ﰉ8&�~D���W�����k�[��<�Տ}�.�"S<#A�>�z ���� -�H�����E� ���Y�n���H4�r7P?99���ߡ|O-��5�� �%�4� dz�O/4�L_Ps��T�>�LQ��D(�����J8��F��+)jCb -�Mu�2Xc8$�t�}�&<?��9lW��~�ҿ͑��n��90A�=&W=s�Կ���_V����}�?k�U(�m��utE��*� -�K%� �t���Z�p�J�� �B�W���P �A�l��(Z�L��zF���Z�}��/��40�l�V ���i%L��^V`�jp�P������5QV��V�k���zX8���^s��ţW4U*u��}�L��8�F� � �~�3��B�"I�/.��O -=7B�JA������K��Q-�|����Vw|()8��C������%ʴ��To�l�s�7*���rev�٢���6m���ǖ ���C�T��pT'ǑpL!�jRC4���}a��Sm���[��%�4a.��첹},�L���B���=�:ݍ'�b���� dm��}V����Y,�t��;���9������ �:\�I5��fDA����u�I���F�H2� @:2 �!�ԏ��j�-���@ٵ�G������`vKcw��I�lar��%l��Es� -��rDe��T��ib����@���d4�����B�DH��T�. ]��K�*��շs�\m�F�:�:��4v��X ��<�;���r�����%���6�aꇷ����ܥG����������ѧ���|��g�у����h��v�qtJ�J��K����H�^v������gp�.��?뜸�B����0�^q�8�|f�S[�t����Cx�Ҕ�������f�й -�^�FB� -�Pi��WFpR�U -�:̓�D��}���فv���������}4��z�/���F<���P莣\��U�'c?��4�sJ ���jj>�@��Qr�-��֤��U_o6���q7�P1�ˤ+���rc6�I -�\ �(*v�2��4Uc(A� ̣9�3���]�z�����;0'�=���*,e5�6��V�a,�qh�*��P@wȬ�G��/�O�j�|�FIm� #Pz�;J�wʎ}��<�����zT���t��~�`�ȱGP%;?�5(�(u��#���vՊI���#9,?G����b4K]�Qgԟ]�E[�phʯ���G���+`���Ęp�?�@�>!�}" -�ҽ��r=�C�D5� 62��ZY�����?����i��A��� -T(�EU�Ju�;"}��պ#��L�c����ӗ�V����W�O��&�CIԙ���u8*烞Q��a�Q^*z(�L�|Jӏ��^�f�p1����0�4~��C��Ux��*r�V�*�N9π�׳�P���ūs��p���_L�������3�Z"}�&�r�O�|l���~���k�C�/Wj><��S�x���M�bS������g(]�J(Z#��x�\$OC6�8-�f:{�S�ҳ蚨o�4:����)���Wb�"u�iu�h��~�d����%����B����AM -s���WH.gv�%��4���v�+����=¿ -��S�G�ϋjWHW���u>��[�B{[�u�ɶs�;la�z�i���W߭�\z���C����|��\f�����te��&��ߕ+B�k���/t�� -�CM�� /@S�>Tm -�G`v�`?�������G�(�,zb"���e���A��A�i�����7���Q���R<�"i�X��:�I܋(a�V�������;4R����]}����^���1�v�Ե�����7���=�p�|�[Jο�e�µ{)�e����#��ief0�K�J�q�"*�F#�(��GjJF�h���X�#ш������ݍk���5E�R�P�� ^p�C�eo���e��:��{6�۬��5�͝s��ƙ8�X�K6��V[��=��}V+��hͧ���J��l��ZZ�5��W����;��T��e�V-�@�H��I����D<͙[�)�����l^b�Xe��NN���"K]�@���b����?.�H�H -gzXa���ْA��}MO�e�X��H�N�r���ڟW�;�ht�gttO�yu3=���*פ���ؿ�C��FGsh9J�ͽZ�-�k��]L-�~h�ii�.�49�Qr5��I,Vݓ��^jf��_}�,���Q6?�5��NV���� -ޞˍ�YٜN��%ez��qƨ�>�Z� ��Nt��1� �a�%��=� y�hޙ�� H����J�Z��?� h�vr�k��@�m�Y`�^ins��F\�*�|L�z!/?�)(�0�� -MS4(�ȗh��{������-�'�h���o�7�cCҞ�?�6���'|ub�գ@����!�b�Ù�����f{tz��1U�A?=�@��� t%�䕉����iu��[ N��i�D���G�T@�:�p<�(�c�X���Um�2�ϱ7z��O��M^�FϴYUfwGs���#�t:�/�������~�Os�]��F����ݑ��(��(^����?L��$�Sʽ�WzT>m�'_���d�����:���5�Lh;�H7�Wgz�g�Z��Zb3�{2d5�Jj��9�c+���\vqz�Db���b��ƶ�g �"l@צ�p�QB�b���S Q�>��+d �p���%}�L!��������cdwHo�����p�x(T�p��x��p#��:dvQ q�dA�QFd�L��K�m�PR�� �pU?�l��� ��zg�-�����jP��b��G�aR���&^q���>u�8��p&�Ӯф �`�MGS������ܵao����WܛZ�aâ�ٟݰ�V5��R�s2NX �qGB ��O���K�g�����BW��)Sg\����ӡl����]z��<߲o-_��-����A��KMqӭ!�æSi�gy�����۰]K�;S��T'���kPq��e��e�7cZT{~*�7�b�\H�?�jٵl3��P ��оw�T2��j�Y;��)�l D�ueytOT���jö���U�H�����X�gɬ,��W��Ϣ^���u��![]�v�F���| -�QG�h`(�# �R�'5X�D��Q��qM�6g�c'b��u�:'�����H(�?�yյ����6�~.�e��[n ����*��U�yZs�t�9�R!G���������MM$�x�z��$]��{��L<�}���4���JZ���~�MV�Օhy� >@u���� ����+������]��2FqO8j��ѥ�WC��Qq����rw��.��䄫�ޥ\��_�������y��\O�n�)I�KGR��HŁq���I���. -d+u@ϴ�� �k��Ť}9��T�v6�*x�g�e7?��ì�}�S���-��AU����OMlJ �p��ժݧ����Yw���h�i6�\fA�Zc,�rjF�T��Mj8kO�51��T���qW�_�n��`�7�%�K����W�s�d0���:��`��OX����s$�4�?:�SI1���W-�Pr}�²���9�.��&�P��^f -�8(�W�I���`��`@5a}�z��i�V �p��PԽ+:��d\j�"=�a�j����)W��$q�{���͜�p)�V���|�7hj�������������$�L��֡�9�\���ځn[ ��k{lG���.m�m~�T���E������b�ȭ�m�` -��w�ny�P&�:P�LJ��Y������_�p�NW����zV��S׃]7��E�d�%i�癬|������E�WM���7r� ��HB���6�`UG�Z���� �9�N2l2��ɅHY��(�ŗ���iw��ݓ[��`�cZ��R;Yz=Tr�vH��9�c.�ֲ�G���6�*p��΅�'�[�:�/�ҪX����CYхM��t��-'�]�n,{@��c��Ob�����I�N�.�x�N��F9��뛝N��K��[���X�r=���W�m���ݏ�Ʀ�Y+���?s�J����g�X�u�P���%ȗV^����[��� ����W���;��W� �xv�i�/��XS3��ȼ�2���ԩZ�<F��=0V�[%�R~ˌ�x���y�s��y?�Θ(O�q_�V-��aQ�*Q1 �t$�j�D�pRR~�zǢ��p�"�]�gw���=�%GV�����rt����>��f�2���/y���?����8�M@�Q��*˄�������C�X��k���?MzT�y?���Z��Yu׳)���]͕��1�-��a��7j�~���� -.d��� -� ��'��������V��z�tXK��2k̹d?��z���z���K�.�>,��BZ��`q��'�k�H�qy����5��j>a���\C��#��H;#p����7l�4�}��IR�7���ފ0����$��=�V�������#���_.�v��s�{g><c������_����O���gx���5&�?���̠';z���a��a�:zӑ��Q�Fꉢ��^��MF�����9��&��A������Eb���ٽ\�|�3�gE}"+�>��h!���A�b�/p7����=�z����mi�%�͟�3)^O�j�<_�U��NY63dsIr���8E�j�����U�*� 33�|v���;��O��B@��,��,��\cwd}6k.�u�k�F9��'��2�6D]e��x�G�J�K.}��S��$�@t"�;2�ɩ��*�����4��1_��x�7��Q�bj�X����9����Q��;�#��{9��e�I -�-�奐br B<��9�dpz��IV����Q:l�+�s�i�#=��T��+R��(��M�DC$� -��a�̱ �ONg�j1�9������gqXk��}F�����d�����c��G�,���&��.��.^ɷwwc��>�E�_]3��U��|�t{J�f�窂u_�.�\����*���W�=��}�lN���o+^���Ṿ�� v�P�>~��s��T�jWz~_��o�gS�}-��D�Td��-T�Aa��Yf����3,PATcm�� ռ4g�}���m�E$B��w��Ū8�>��9����JW�O��/9�P�JC�XA{,�@c,tEJ��T�j��9���8Q����&� �H���P�l~K%ƞ�1��ѻ� �-�e�DzxN���Xuz���.9��}�M�c�&�:��Z5��ә8��%յս�m����om�CB�:����l��8������~��ܦ�E��j�T�����YH�Y�v�n�V^IN]]�CXkg#�sc�S��B�$�Ý=�$��k�}cG�&��/��z��}������_��v6<�7����IVGG���g*l��\RXS�T���)�E��%Y�u���~Q~>X����Ѕ��`9�W��k*�@_ՊpM�]0�*��%�a��3X팁K�M�|�{��FԔ���� -췾d7[�n��l��ͬ�D������@��m�����8����e �cż�#�gH���dd@~.�j�l�lɛ��eRcx�E��(( ��K����m¼��G�X�A7��S���@[l��.%���գnMDs�]n�_Q �5�i?z��G�T�G3��T�@e �i���,���r�� -O2<�����l+���/,��%���m�� ��ۚX�n�|�E����]����l�í������[m<�|#�z�+�5�� 7&\5S�-�{��AE��^���t�K�������M�^rq]��Fm�C%2��vJ��)W-�}OM"`�9l�+�=�%"����T�'8�zH3QҐ��ѩ�Y�P~V��ز�Ni���7����ۛ� ���?w1���x�c`d```d��?��o�A�eP��BY�t�?���;�"@.H�c�x�c`d``�� -&�]a���A���_x�}S�JA��S<�`�����������b)6���>@D��"�X\o��!�����ι{��,_��o�gg��g� ��#J�VYp>uC4�&*�<=$���g9�W@.0��q���- ������;�:pt"H�U�e���5����Vg(�[A�x�9��!��EM���ߗ�4�N�&Ӟ��wj�t���Ԟeσ�Lp�>�w���>G��pfz`�|����^�a�ż�>���)�o�o���M�g+R�m�Rq��,���RJ��1���X�T��N7t�{I�E�\�F��8�U ���mb��:f�N�&��j9�Y�x�c``Ђ�M/^0��K�ؘ���ژ�0=avc�c�a>���bĒIJ��k�.�"�/� -�I�8�8�8�q�q�pn�ǥ���5���w�)�^-�8� ||||[�5���?� �JPK�Lp����P��a)��"Z"WDmDW��c3K� �O<H|����D��4� $�IjHfHN�<"yKT���o�q�[d�d��<���u�͑�"�G����\���$�K -n -���w(9(MSڡ̧��l�\�|H�� -���J��4�G�&� �{�D��Ԟ���Q��a�Q��Fs��-5-/�m.�*��]:otet;t��i��-һ�ϧ�_��I����A��%C!��u�/�T��f�3V2�3�0�f"a�`��䒩��<�fvf5fw̥���'�_��p�h�8a�e�e�ay�J�*�j��=��wl$ll���5�}cge�cw�^�>�~��/��c�L�uNN+��9K8;9�9/p>�"�����k��676��-n�����ܷ���0�����h�8�)�i����ʋ�K�+��s�9�������������������@�.����xڭ��NA��w��h���� -/�"�T�D�#J$��r�qr|�!'�O�3��X�F�ާ�0�wY� �1�fg;73;3���x��E0C�q=���q�X�4���G�A$�x�ZB�8ڃ� D�w�!��I��a�S���X���w����.�0�?��o��N��؍�gڍ��@\�A�`��sb�� -�k`��sݡ}�,�0�Y��aD��ȵȵMyF�Mv�Yd��S����2����0~�>�/�qJ��G -i��<��#c���0�C~G�����9eeKv���в[ڷ{&V(Ө1j�1�M�Zqr�7�,gKܥ�X�����0�����QY{� -���M�Y��жz=���a�:[jEݢ� ��BZ�Z�=n��s�`�+o���̏���x�m�U�SgF���B�]���9I�$uw�-J;m���Pwwwwwwww�l�ޕ���]<3)e��7�R�^����V�V�_@��$zГ^���З~�g��`�0m�[�czf`(3233�2�3s2s3�2��������e�D�*95�4X��X�eX��X��1�4i�+�+� -����k�k����� ����[�[� ۲�3�Q�fvd;1�q�gg&����n��LdO�bo�a_�c�@�`�P�p��H��h��X��xN�DN�dNa�r�sgrgs�r�srs �r�sWrWs �r�s7r7s�r�swrws�r���������O�O�����/�/� -����o�o������� ����_�_� ����?�?��������f��,˺eݳYϬW�;�M����e����lP68�s䘉�GE{R�α����M��� 7����n��ܺ�p;ڛZ��[ݛ�Ƶ?ѵ�ֵykx�~y�j?\3V+wE������5=��QM�jzTӣ��(�v�N؉�k/셽����d/�K���d/�K���d�b�b�b�b�b�b�b�b�b�b�j�j�j�j�j�j�j�j�j�j/�������r{���^n/���+�v -;���Na��S�)���Լ�f�f�f�f�f�f�f�f�n�n�n�n�n�n�n�n�n�n�a�a�a�a�a�a�a����C���h�QN��-ܩ��������?�����C�����?�����C�����?�����C�����?�����C�����?��݇�C����}�>t�݇�C����}������C�����?�����C�����?�����C�����?�����C�����?�����v�Nj�HM�p�[q�n����?�?�?�?�?�?�?�>�>�=�<�<�<�<�<�:�:�:�:�:�:�:U�>���:�:�:�:�:�:�:�:�=�;�;�;�;�;�;�;�;�;�;�;�;�}��V��h�S�������o����TP���wOF2�����Fl������\��F �M��������������������?FFTM `��r -��$��e6$�t�0� �"�Q?webfe�5옏��@��?�� -��� �t������������,3+2q �F�YO�&>��b�m�5�Z��H$��Y���{�H jd�Չ��%��٧y"����+�@��]��e��{���v��Nc�)�n���?~?萤h����_�&i���ѝ���?�>��^K �v�-cۍ1���2K��y��,'n���(�3Ewi�B��&����T�lh�0M���҆d�Y�r�ﲬ�nti�]�yur�������VXsj����gMn�әH�W���� r2�>iT`V7��R(������+�o6�'c��B����4��ι����㿚�T ]a[Qd<3wq8,���rTI�8��0>E�?�*E�痦�#��7'�����S oc�ʷ�_�7&#*�+)����+4a�A6�c��y�٣�f(bF�����$;{ YA�1vP-tG�������"����C�f- W����ԙ�uKְK�#����*K�<�� (�������Z�`٫�[�%�YT��{%�Ɋ$���s{o����ջ�vt"p��4`��ߩ�Ϥ}o`���'ne�> -�G5s�z�_N� -�PKӦvmU�ɾ{z�����������"3`l ��W#Ԑ�^@+�,c��ko��AOpnu���z�zJ)��Υ���1�}���O=����x�R��`�J�`�q���Us/�+�k�v�1xl���jl�El�\nD���ƶ�V�����jg�{Zd�z7�5��!xm�5o�[��u��&��1ڂHBkA��qr��R�� ����(\gh��7��Ҋy�=�H�Z�UPh��$8Rg���z�gͭ�N:���1u�$܅����>R�]�����"��f7���K�^'���3�+E/��^�YU5]�NB.�ʋ��8��+�͏8��,|�{M|�A��ua|�a�����˅՝%� -lKG�P�,Nu���k�c�8mX@��d�̘?�����Y�&��{�������?�P�(�G�]������O������r-��\LF�9�,&��y�8r����3�ܟ�?p��>�~����s��������D��z�1��?\U5q=��t�zԒ�&Z�nj�%�mM�"}���tk�D�wh�-=�m��B���76����&:һ�qt"�1:���Е��u;�"K_�/Jd�c0�l��0��'^B��8VC��zg����[ ;��d� -�Y�bȃu���u;�@�*}y�|.��'C>\g=�9�V�Ő��[o�|g��^���>��d� -9���������� -*E|A���*M�[�[*mO��Q�z?P�n�?R)Y��oT&[�U*��5�S�MB�����[� -���oYDh��{��,}1<f�&6h��'��ʥU#V������E�D"T��ީ��AD9��eB�:��%O�� ����Fu�n 7?%RG4"��f�g��F꺁 a=��-��Q��y+B�,���2��օ5���xn�Ϊf*!����l�|GXQ� ރUp�� -�Eu �@����-��Do.6YZ��-&a>f?����N�N�� ]�O/^;\��J� �B�EsJr���Ě��'�g/���B%��o C��n�7��:|�y�Kt�&�$��s�|��wP���\i]�$Z@+���Հ90x]�r��%���+�RU�Em�+ܰ��;w�u��9/I��7�7զ�Q�lu\�y�W�N)�8�ܰvY�*u�m��������m( f�E���G8��j#I��R���z#q�߷� �)Y��$��Л�c_%�m-{!0-`;�公�hyV���]Hv! �ta�\K���[�1{"�j 6@�3T0%���Θ"�ԙ�ZI�G��S����.��Σp��ӬS�1e��ٓ�؛��Y��v�8d�\�B�l�S��R)�ӆ������{I�ӆ��%���>�0Ўڦ�\�'�cg�2%4�Q�D� -0͒3B�"�M�Վ&�ۊhI��ڧ�Rg�ME������ I��(���5U�D]}��b�8$���8�>��X �h�"l��j�.%�ۀHH�-I��ݸ#1�C4��Y�7����Yݖ�Vo>P�]�6�����O4�7f �~�AJdYF��.��o���y) �8l��22�e����1H�[t��@!ȅ2\�@�5�ٓ�%Z����kޒa����@�.`n�3�OF��R(���ZkLkF �HWjY I��5��*�6��e�Sbk.��5F,�.�N0�ԙ���|��V��||~N�( 4����],�Jp|~�xe��A����5��/�ڻS������v���y?���'_v|r��X���H�Q���ēB@=�X����B9�4����T��B�B�c����H�P��+��_���YH�#�$���`��F���B;��+���BPR�4̼ t�:t�"ZE�J^!X�Ǔ�q4_dTW(5�܀������I��UŇ�A�z�@U6�n.WGX����H�RK��&'swM�j�ʎ���<����3�)���`#F@F Ԣ���v�o�b$x�+��u�&�}�|�X&[٪�8F�-�E&/>�/�G�.a�z^��/���})����'�x��$O=<��z��o��A9M؝&�~�3r�3g���'�8ң\�-�MDz����k��5����A -����G9��|1-�! �87�[���,mR�u|�57� -=X���,�aJ����^t�N�4��\fЄ]AzH^7��F������&k"LU>}�>�rB�X(ۂ��T�%��J����dhK���P��K�TFaA�3HH�C[r;a���d����54����lL�kjG{��8�h~� fR@���9w�B����0�zS�����'��a7�@�@N����ƹl�bj3hN�X��F/��e�s��'��DsQ��<�k^������ZASO�id�SJ�xN4D���K�!���� !٫v��hA`�E��X�����- �P ��:���ѤC�:��W�zS�s�dO:�_����`�:t�aηБ����س���� �IY�4�# ��*��+<�q�n�o���u -U�cww��x$d���ƿ�}ρ���94�����9p�*T:�%GQ�^a������'��e��b���l-��*X�L�%*ź�.�ڊ�\�@pR$T�*K����hp���������m����-/�oS�3���E����to��}�жV�o�eJ`<�$��t����� �]g*�Z���6q���l��~�E�� -�S��/���i��T�t�k�Ǯ�W�þ�=?j��G����UUAJ����`��b�ˑ��G�Q�Aϫ���Ö����c���W���WSm���g���F��&�^��ؘԡ�6;C1:=ۈP���`�ڜ�VV���E��5"�hO�X�~���N3_5Ӂ]�z-���CW��tԥ��ӈ���e�]�\����V����c�#m[�kuޗ�_ʱ"���s�H��<}x��m0b�xH�qb�a3tf�MT���*]I� -�}�(���,M����=� �@�JA���d�����?§6PV��[ dV�v��4j��ߛ�lH\������{���M��Ș\����Y�܁��`9M�`Db�<�;a#z�<�x"�,�d�gCi�`�c��:���I��>jw��}J��z��^:V.�:��ڋ{�ͼ(ȲB���ɦ���x�<Db#"S��{��P�Hu�N�/�{r6;wU����s�PО�<��X��Y�s����Mxu��\�b���s�$��x��(��/^|^*0j~m�;#�%J��M4��p�QM�::b\C2gf��]�z�P8T� U��Qb��t��C�T�> -p�8+6g_2�lΡ6�H� ���džH�:� d�<�C��6��ؤ�/��6�E:�K��"�`kJ�<��Ƣ�=�v�7���N5��`��Jt��\j�6ͅ%˞7�*�'��U��4�:�X+ �\b���E -����af��x��}��1+p��B��0�6�����3r�A$N�~��#�d�}�פ�P7h�H7b�F��§���8� �P>�BtGN����m��x�@�j ���|{�s9�=�wR�/��oDJs5z>�;�'x��E�q^r�^=G?��9A���A�_���K%�Dɮ:uikjk�Ie���G�՝#*��)�jm��|�t��}`J�Z؈���H=4�{g߁��)�qX�MA,�H��7�1��V"��o,�Y#h���ݨS�_�;��a_ԗZ^cn4�����H�E��?���}� -ȝ�����٤=}B�WvުUe��h����G��F�����;�@2S����@�f ����n��2�#�����f�Y:]�Jy�H]��-��Gwgv'��|��0e� -�_7��Ґ�n+f�ٸ��Y<��(� -�?����y���%wm�+j�&&!�c�^�u'�b�&�h�m6¤����*2?�A�I��Ʋ5FW�ؙ[�Ɯ�B�Uz�I�E��!�m:����xh�e��Ǯn�z|]%��m�r�U�F�گ����1��};!n F�&�g����P�����;&������$$��F�).t�B�Q�3���(�C=����X���es�;�i����ي@��~�N��ΡE� �SR���h�\����Be�o��������bT��nΒju��� g@��'qQ딎nx.u6bVU&��]�;��!C_���5�*�z�ɺ�m�RQu��q�����P��Z0��}m����n��^n�Or�T������:�U�'�h��0nZ�p^R�|DF�_b\�@��m���DE�8���{o�GM�q���}��Sd �C,�i�ܚE���/��Ë[d8]��,MCI����_u�,]V��c�"��p�g@�`"y)�,;B�^e��l���2'�.(���Ę�y>�-|�h����w����;�j����Ս��iԽ���_o|!@�)ɢ���=�̌SPz����*!z})�|ƧT}�j��E�tC�Z�n���ý�*՞��4ۆ[����9�Ю�����ݓ��z`Wme�o��|j8j��5��9���@.��E�V�/�ZW@|��f_�\"${���v������/��;a�:Se�i3T�G�*����]�ơ/�h�2C32$�����1}��D��NX���t�?Fϝ�~n,Pj9.�>ף���{ -9��EN-v|3h��C�иE��� XT���;P�$�=�J�-��gݕ��igz~q�(A�<:h1�9�3�N�̽�Q����}CL��W�ߧ��~�� �b��"����|�4u}����c�y����6��2�[ ���\d�,�Ҏճb�k���D��%0T�x��{=;�Է��(�i���LS���1������3�N�h/�6?�'E^�~���P�{sZ��Z�K�ĞB{�D�t�&���z���)�Uoa�5Q�3��ȗ�r~���� -����F]�$�<��tm(�}���MB@��[�Gx��F�h8��#}��,�#��u�Laz(�Qh�4%�xm`U��չ.E��v1a��4_'/[�d�{Fx�I�59���D�<��&�8V�E�Fg���芘#�I�䟍2S����_�]QqA�n��_�Q�>bޘ4g����-�0&E#c��i8� vR/�4�r����P7��KsOW�N3ՏvE\bq��Q�5�Z�ڽVy5]�����h/ i)�����-/���k�N�ю���#e�)"P��� {�KSQ�x�����>a�&����<a,릌HEH��� ]�%,eD��U~W�l��ڛ�;c�ᘓ�`��? ��p�M �l��.�P�W7��٣�./�W�#;W�d*�:z;E2�������j��9y��A�S�S8�u����;fY8�m Kѯ��ԄԶ�͡>,�� _�g���-m�c<�n]Ч-�5�2c�����z �7d P�z������V�����OPvf�R�R���ఓ9�Z -���d������C�����`,�at�=�k?v��4#P �B���إ�/[�s.<a0e�{��&��v��a~e��8��)f��ny��f�BPL�u�Iy�H=S�2����"[��(�¼O@�z*I��@��0��#����,�����I$Q��y c�ўF �a�ߞv"��|R�ܘ 'W�F�x?�+aN�M���K�`�D�/�nf:X�I8:H �IRm]�K��6i �@U�H*N��oF���;����ᇏ"W�q��d\���Ѝ*C=#�2�6x�7�<T�� -7y��rU>-bH)ɺz� '}���w�!r�X�Z�� �.:�Vn�;�-�>�:� -6�r���U�cs�4k�VW�{����#��5ߑ0�B����`ܝ�0u��".Q����dB��0����C��r�]���#��Q9lq��N^�ֳ����h~�NU\� �16� -~����S�n�T�l��\�THҲڛ-��~�G~)$�oQ7-�C�����}q%/a���vO��|[q4�����~Bc-$N�7<V�HE�i-���R�F�GNM�{�"3���49�[�j<����Wӭ��h����l�n�� ���QҨډGcq��@w�/e q����g���<����: ���a钷��u����_P�`��b{E��I(��OWG��fEy���ABa_��;O^�DQ��'�s�������`D�#њi�:Ѵ�+�Y{�{�p�&��\�Ra�����g�Ϟ0��g��T�L�i<'�7��?���X1���C�� -a����n0o�r1��/U������o�/?�♯a��_�p�Hֱ G�촠��8�ݣ?3F�0����`%��ϑ��<� -G�]Խ�8bl͏%-,�)}%�J�:�Y��j�T�;Ыȶ5Œ>�6���w�{�V餃.&��(�o��*�n<��n9��J� -"a��Д��+��a�/�����;7zD�Zη{�t�M Mp�� iؚk�NPw�ؑͺ�H`T �$23��f�����0�z��;�����"�]��*�Y���,�Q�W�����lS���O�rW$5]K�VٻB��ܚ�I��k�|�=�&�[�������58E�R�0ދGk�sS���n��nnu���ExK��r����}�~m��`�G4u{���=]6f����ר -Bo�&< �ñc;2��P$�ǃ{mW_c��ª'B6Њ?$�^z[�C�Y�ݭ��j�N�~��ۮ0����t������6/)-�1:p$Dꥅȗ -� -,'���y�����v�� �n��F�T�с�['a�Mb�J]�%�&î�lc6&��IpF�� ��o��i������5���'r����r�(q�������z6������(5���E��ɢ՟l\�L�k�7��1�Y4^)bٗ¦8��y�Ə��� -N��=��9zT�^[T$�dk�� Q�iK%�6����q������fO|���c�8$�ji^vr�.QQR"�Y�rĊ���� ��k����r���K���<QI�"�@���R9 ��/��\&7Y}m�gҊ7��z6�-M�u=���,��N3O\�6��aDA��ޮ�Ld^r��/.�>���� -N�e��Ri�4���!3R����"�4������n�b�m�-y[X�����."��!���QK��E\N��4gՠם������aN�p� >k)9��0�B�Z��Bs -��y�r��er�)v���D��t�rv�\�v�[��>�r�Jm��� -a��̼�~u���Տ�>�rMZ���c�B<��`)\y�t|ۍ��r'<����>�����[�Î���h7����Z��8caI�!� �p⢟�̮�,�G���k�5@�����`��iw ��nО8p�v� ���*����'O -�������A[�.��r�h�T pR?+;���\*H�sLq���U��f��:ql-ć��*6!�h�+ˬ�{h���- jg�k�MM��P#��:�}���{/���V��ŶC]옙�&[�W$ګ^�#����4fWa\ ��5��躺M[6��)T�3���~������� -�:. Z����`s�i(�R��Q����|/�`� -il�^�L#����f�-��;-C;_���*�{@EMCooÂ_�����7�T��rqz�F�%ׯ|��U<Z��o�[TA=���'DPJ]�;,U9���Q���p��k�4~�����_�C�^�qE�Ů��b �SGs����Y��2N�A��u��%��SD�� �hj -�y;9$ߴIA��h�EO�����} -�g�����/+ �Ճ��5�JY� @�G��������f2����Y���/���e�߷��|v�/�"���p��~刋�T��8OK�r*���* ���4hi�@Q��3g"�j��:�$��;:���f������,d���z��Ț��Ԍ꺳��u%�ˣ}O�&���i2U�,@�k�j%u?��4�N�Km����d?5�ݓ;�0�Y���e}sZ���>EƫUs^ݜv{����fQ<Đ��VP����Tfͦ�?���m�p�P*��&���Q�G��{c�J��EPe2)�xP�0A����MɪZH�j�""�A��C+zq�mVzᖞ�U%�C��:@1���W���[y)�J@�o�b%�j�A>)N�ǀ�i�$�A���t`>�?f0g��H36p�6��D|�M����4N��� -�� 4J�Jڃ� -�j���Ƈ��\ �p�3����8������Я���6p��V?:�$�sD��N��ƹ�2�n�,��H�O\�[��ո��K�-)��W~�i�m�?���T�:���U�eY���-#dJe)����Z��5�?�$���\d�W<���,Ɇ��;�ط��5���S�ո���T�T���̄f(�PY�v=Q ~DX*���8�辩s- �˨�55� X�R�l QC��������l|��5�{�ӦT\t꼕+��e�n�۸���Ps��l�3���UO�[����Z��S3���*��,����:ÛZ����L�����S���'̵��*��*@���ı~xgno2�����- -�� �W����V�;�pZ�9�?~��$�6�<��Qr�bQ8&�se��Eb��Q,��^|B���碘�Vd�V-�(�]� .��ˎ8/qhV�nR��Q�D�*�U(*1h�1�`؝QL{��Uj`��"�o3�ܻ�V�l��: ������ jaFa��E��̞Z��g1��z���2֠�:�Au�ZIf6��2�tw+���f��D�������CL-}g��Z�0>҄�xJ����>\���Q��A�_C�i�h��bl] �6����4*�A˯ɰ�qX��7��Y�X.�-���ո�aɇ�V�h��iKg���qN�RĆN(r'�]��%٘�����@3�̀�j�Z��J�.;��nm�����,S���0x������ͻ�OF33�ҧ���<$'���G�E+��}������'1�f3����y�5�/&�Z�\RB�7dm��]�8���\���3߂�Ȫ�@��o��T�3eu^�W@�������e7l�!B�,�s���1���$����Z��&���?��dC�� �(YЦSm>�J"&pt�܈�P㇄BF���������4�G�5� t^Ć$���j-a㠍g^�ʐC����As�T=k�TS,|�r���9I��BϘЬ��'��vG�A��@��t��hQ�Nj�&��T=�xt;2]�P�|T- LÞ�����e1�ݽW�ZŚ*MrH5?��=����o��"��9�K5��=�'k�-*���A�E| � � qҔ�_?\�7%��|M6�f�+��+�S*}�W�_�]3����fmܮ��˳��m w!�����.�R#�鬪;�����q�q�71���$ݙկ_��iK�&�J�άM������em�V�5P�0>�� Q��5��W��H�Ih���&�4ҍIl�E7}�s���m[cȾ���|�d^ ���%Uv�1�D��>�.�T��7*�=t�Z�_�㟾1Х:=0pZ��6ҋ�N�t�(�u�Ɲ�; �B�]��$�k�ڌ��.�{�F�*/UZ��N�砦|oq��K�G;^�侞9N��e��xK����\�wh���~���ZpH�b���䉸���[k�8����k��.bX.Q�Xp�xYa^��"��#���B�wnb����u���m5�F��~>��8���b����N:�p4�[gv^ -B��F�Uz�)?��60��F��8����/2��C8���>�N8G��%l�%��5�FH�{4�6h���4�%�# 7������x�o��N t�\�'�Ȩ � ��E����0#��j�NãV�ӹd�?WlcW������� -ž�ֵ�u�-��}2�2���EN��}#�䵵2H^a3����r��qs�����-�S3&���f�퇣���fwl.�=W�8�,���cH�j�cT�W��נs�9�0��Z�D�M���C2�ZM�����dj��t�"8�:g�{.Ʊ��1Fb6�1�8"yԦ>�����W�9�� �V�����`�j������T��<I��MԱW'%�f&�\y�Z�dkʹ��Ry�jw��}��Ѐ��[8�ԍ����bB� �'d'm�o�'<��|E���5��:��ڋo����>��r,n��i��� <T��S���>�d�� ���qN���.g+ �S�� Q������ ��KaB����?_��Q�E ���r���j��h>��E��ӛ;�C�7���^q� -�`U�e�#-���;oJ�ċ���ԝ>)���;Jg���9R;Og����iI7�}��8K���ہq�j���eؓ�+ٗ'n�Ϸk3�����eFρ����0����V#���p�MAzb^P��V�u��~�1u��ғ�wn� ^�.II���_���vdW������[Q,���+L�b�������ćq�� 9�V}� �ΏV�w4qU�3&j�ıHYb� ����tt�T���7ρ��arBwP9?)�u��T/�a���A19��k�M -\��P��s�<�Ta����@�<?M�(��.�,'%?,�%�a~e������U�0��/zQ��(Ѹ����a���p:.6�j��dF@\V�4��{�Ri����8�ɪnu��F�M_��=���Z8�H��l�sy5k%��|(�i9"�6�}ԋ~WK�۟�hY�k�����\���l�Rm���&� �����0���b�]g����"��ހD^���ތ�j��J*)��6���-Yb�h����� -Z����=ޑ�A,��(��K#� ��Of�J:�;�I���!6Yi&�d���%m�86#���Q�����W_��A�v}?+�G��� cc*�m���g`�>��q��+��=�[5�͔����?�9�W��+^�o�^E��8s�)�f��2a���Q�x��i��& NE>"^Na�a�;f���9]NE& t^��CLz'�e�8ZR�s&6��7_��ãcyJ��1 ��@TZ�?S�D2� -�|�P���Oӌ�\d�R����7zH����9i���Q#����zr��c.�4��G�R�4��qx��<2~X�h��n��ੳ��2�auB�NC��+��k�X�0� aj5n>މ���e3�vާ���<�>��_�����uH:��XR��%~9�!4��o�Ѽ���3���8?�� �1d#������A&���{A!i6����/Xa����=W�;|���)� �g�~� ?*�悽� }��ڧ�Kt�>5|�E�������.���A��Q�6�� ���(6 - -6є�7����<9��_�C�f1��Ў�i8����, V�4$��ut������i�,.`v6r ��P ��gFB�Ɏ� -t���� C3�;�,�oÂ���x| -/K�Mp�1S_��X.f�V���#�U>Ȓ���#B��]� A��IVo��Іϵ����GTV1nr+��OX�S�%��³��f�OZ[�_�9���P�߰� {Gln�%�#��h�dw�H��=� �y�e/��W����>�,����IP,*MV���~ºK&�e�ċ��M콣=�)�qF��S���"�G��T�F��*�LX,h�[�����w�w��e�WQE�x��?��{^چE�x�h��i���ׂ��J����H��|�^�͓���e*^�Я.�u�xE����b#�;���ԝ<]z]\����w�N�ho�chq�E��=���4Q1�7���W��̓lÕ6�᧿�HE_̣��qy���YR��۫<x=�cS�Xy!=0�8Ǘ�x�����?�{}�����F_���Ǡ�z���kt�ɱ��7��ڂ|t��+a�m�<xe$��e���ɍ��<[�T����X[���������s�V�̋�ާU��*��h�S�K=Fe�sw uY�o��ٯnQ��=NE:[�(t]� k�|�@�ٿuZ\9{h���v��ܕӆ.ڡ�sa��$u+�q�w:#��?�e�T�3=��л�!�p�PL`�:����R;�gʮ�Fha�ΐ;���5Ie�+�������bt06AW40T�hJcc<&�mJcc� -���OCn�W?��N�i��o](XЄ��{�Lz���;����g��|Ǐ�>�9~l4s�Vy���`��Uߛ,������#_�u��+De�����M���~h�q�벇��#Y����z�$;�5ͯ9$�� z�>� -�*j�O������$��$O/���xR����t�f-}*�o�ɦ���|3�M;xި�U���l/.�~Xǎ�Y�4�x3&���x�";�$�KI��5�dڭ������~w[��M9O��%4��Q�}�S^��t���@���w[�Y;-������s;�b��wH-*�im��I�-�1e/�~��TNN�.�p���)H$��W��~������Ʀ��O -(��9�,� ]gM6r�+�#�%��/s�w�A�$��q�4�O> -d9}��+��$�s����?0��a,>�y��ڈs<��=�,��c_*\�D���}�2M����T8/�4�g�'ڦ���8'�}"�C�*�\9�#Y�>z$����7c[s�|"$}� ym�����zQx 5�%�o��$j�k��p)�x���-:��И|?��o��f��gFr���2�S��Z��q}q��� �o�,wy�O�g��CF1�l��'�L5T3��3���y��M�9�2"s���5uD��6��-J�U�bs�� -�O)��w�R -2�/5f�<�BQ�4k��ꐭ�G� )%�<d��ĪĞ��3�2`�a��]��S{�K%�\]�3&��p����ڸ���Cո����놶�,�� ��^�T���7�h�5�u�lD��xڷ���L'D���r�6�vշfc\�����gA������@�?������� ��GF��VA�l,���:����i#~NU��DV~7��k�K`!�P��MX��R��$#�Tiih���om�<.8Um�<��3���ES�4ܫ���V9��'��bv�{���?�VV���3��;�U'֬���1R�V�{B����i��4CRh��r6~�Ӗ�J��P�͎��M�7G���-,NLo��<���ѣz����2H&|$����<{ �ڜ�K�_����mmS�)>r�ϛf@=��BF���CB�������&'�F}@�&����y�ub�����C?'�����S�49+�Ó�C����Iî���+���f/R�U� ��C�Fu:C*�}�T:��}{��ݽⲷ�u������e[!��>�?����ڸ�"�M -8gz��0\Hk��Z�:�h��~�@�+�#�N���fj��y���io�!�B� ������R'�5>�`��[!��T�`mC��I�ѝ�}�n -�>W��!M}U�av��4��3)!�kcȂ��m�?�� ��d�w��v�!ה;Xϡۨ}�8�vt���"Ӽ#k�vX�J��[�l��[ZݙMÀ���XC3l�[ �Ta�Vj����ʻ���Ѭ"œ��t:�(�����<�cZ�ve��Q���T���qH�i{��銀Q埓'��Ö��i��P��■������mK�A�I�����BF� -�=�����Tᅽ��(��&TS�?/�A:ַ��ОV�(��@w�Fa^�]����o]*��99�R�i��_�������2vM���`P���f��{QY���H#V7v�7�Ұ�q>@��~uɘ׆Ax��/��x��B��3�Ġ��t���y�b0��nG`��E�D�ٍ�A��:�P�wI�7��nW��2ED<hD�&Z��� Π7�3�&���)LD�4;�7��Ѵ?$���k@�"��"L&~���1ʺf�14�ʱ|���7Os��}��L1;��?�{1$���w)��1}��0�~7��#E5��`�q&o �ow����_��鴊��8Q1��G�����Ɋ���08��h��W�e��+��\��ԉ�R�����U?w��e���O���Sx�AU�̞3�| =WA����R� -P�tO%Q"1Yה!so%%�^�z�_hn,�{?���"L�5�_D6���+����Sb�<���gfJ���0�b�_��x�-��;�H�����W�:G�M�i�Ee�Iu��vJ]~m����QHLKk��hb�A>}.(h��"���U]�9I�h_�V�@��GZ0C -�pb �:�L3��tN*�N�2��!�3�� Ca��yn.���ɋW�`̳�}�QB�C���i ��8*��{57���O#aT��B����U�o�i�0� �_����^ -ChrU}~r�L 1�z�>..�=%G���G����o ����E�u�P�Psؘ��8����P��u&;��*���|i&��Pb�ț���h�;�[��|y*c�V�h�Ҽ�(��~�_A�qU2����GIQ�3`�^�v�=�@��K'��Ї��Z#4sJ=��:sY�� sڥb�yj��S_E܃"����@�~���>�86��#�y����[��c�S�Ŭ�����#�SJ�GZ��yvv��S�я扝p�waT�����/, -9'Jkv%%.�~o�[�� 衧���R�Bj��S�Ȁ*$'�腁�pçS�u��+�9\��_f+����8�u\,����t���p�э�kخJ0h�(]N�Q�v�W����7��8��6:��ݣ����Wc��Y_i>����"��R�����(�e]�6���RA%U�6&�F]��7@̳k3X h�?��K�����Q�2�Bk�[<o�-[ �s~��0��]T���2���h���J�q�K�v���(32J���//W��,����z��d$2�cA�kP��� ��K�+��Ec�����[Q�������i��EdV��xR8��B�5���a=:��KQ�����\��@�V�^;Kr� �M{����{#��C�w}{^,��$0Rc�\o��Q�Ѽ�ץP��$��Y�vp�>?.���.K��KAb��6���5��k�e�+]�F<H�e"�;{wN�yx/���&f檄/XZ[��7���c%�ŀ5�d�Y_�y"Ыߞ�2\37� -�k\�띲|FO ���68���������������nK�zR"�������?/7�32�:а�>��e�WH�U��0O�ק�5���� ����e3H��co�>l]0�2��c����H�9�{Z {sO��!�A,�7�?ŷ3�w俎A -�Fj���8�B�&8U$G��������$�Y5���F�L�5n����1��>q�2��.�6�e�� -� �����+��@/���k�b{��(��7�i=��{l͍�݂���濦��8��1g�(���%��h/�Ef�M�ҍ�t��5��̼vg�o� �~ਜ਼WKi父U��أݖ�w�RS�E�F��T��%� `=���|*=1��*�����S�X�����^���w)l���fQ�H���(YS��SˌK���1����W]�f����7ך�^&�p�@T'.��%3����� ��������5�zaTf6��A5�L��X̡��|�L�-��η��T�g{A)�F��."h���j��A;.��~����o�%���G#�}&]�c�`C�hH9xnN��Y �l�c��\+v\E���Ƨ1�D9K�X�)2b.��N���W����Qש$�/��|6tð��32ԛ��7�����2���иyu�0e��)�N�uh'd������~xY������>��#b�"k3�������:�9���v��$ПC�:�)H��> զ�z��;e�d\jmf��O�a%�9���cK�x��ۥ�!k�%H��Dn��{Y�"�{n_�} -�)9�= _/��Z�(��>l����Y���V��gQ#�߭:Q���bw����$�zw��ٮ�#���U�?|���G���h�z�{�o�$w��Ϝ���)|Vh��?�� ZV�7�%��G�o/�׆���E�"�KӲ����l�p76��-z !�l�4n>��$\��zV?sz�qej�Q���]m���^�=^� ����!���l��HB4sLi9}�2�^��K�5�OB�)��O ��v^~����݀x��rm\K�&G^�5�C��L�}&F�����B]K��n3��|�sGjy�k�O���b�sܽ�aW?R6�����J���fh��2 ��lBS�\=�j��V��*��Y��^�����˺^E)��*�\��� -��r�r(a�@��6nԌ�?�}�dL�����g�Ivq�Nc��a��Ʈk���mL��c�A!��hd���V����wc=��憖����s_�:��җ��sL���g>���1�*4-%�&��0Ub�)Eܬ��*b���51���� �+�+;��<����`!q�f��M�*�,[/GK+{����,>C�L���R%%c�����~��'EG��A��G��=�h�䟔��8:ID�N)�W̻�AF)ucw'qh�Xè�L@a��~�6�Pc2L�"�A�2b��U ��&�����9�A#�QLO�:�E�9k�����f�KF�b93t�L$c�ˬp�Lz���5�d�p����۰>$`�.��~X�=����?��N�Ͱ/���L�P���No0�����p���� �b8AR4�r� J��j�}��� Ӳ��0��4ˋ�����q��uۏ���AFP'H�fX�DIVTM7L�v\��(N�,/ʪnڮ�i^�m?��~����� ����Q�U� Ӳ��0��4ˋ�����q��uۏ�����b$��tV&g�ϖ��r>�<�y��?������f�{�紷�������%����~�Z��a�zW�������2��sv��������eW����������@DDDD$""""bffff�}�X �O�0�cDDDDD���Z�6W�08B��I��������������.H��W������ -�߈��9���u�*��R*J^}��:M��$I�$I�F������yџ�����_W���<G<���/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 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]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(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){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(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.6",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);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.6",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)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},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);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).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.6",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"));return a>this.$items.length-1||0>a?void 0: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(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0: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.6",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.6",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.6",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){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.6",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);return 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()?void 0:(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.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(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=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},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})};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.6",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.6",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.6",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.6",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 c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},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);!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}();/*! - -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(/\&(\#[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); -/** -* @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)); -/*! jQuery v1.12.3 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"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){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.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||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;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(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[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;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=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=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(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 oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.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),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(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(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),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){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(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("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.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?J(k,a)-J(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?J(k,a)-J(k,b):0;if(e===f)return ka(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?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$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 fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.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},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.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=fa.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=fa.selectors={cacheLength:50,createPseudo:ha,match:W,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(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===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]||fa.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]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.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(ba,ca).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("(^|"+L+")"+a+"("+L+"|$)"))&&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=fa.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(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},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()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(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:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).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:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!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 Y.test(a.nodeName)},input:function(a){return X.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:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?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]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.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=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[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?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(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 ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(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?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(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}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(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]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.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 n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.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){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.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=!0,c||j.disable(),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},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; -}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.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=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.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 n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.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=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.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 Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;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},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="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";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(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)sa(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=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(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=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(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&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=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},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.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+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(b,c,e){var f=!0,g="width"===c?b.offsetWidth:b.offsetHeight,h=Ra(b),i=l.boxSizing&&"border-box"===n.css(b,"boxSizing",!1,h);if(d.msFullscreenElement&&a.top!==a&&b.getClientRects().length&&(g=Math.round(100*b.getBoundingClientRect()[c])),0>=g||null==g){if(g=Sa(b,c,h),(0>g||null==g)&&(g=b.style[c]),Oa.test(g))return g;f=i&&(l.boxSizingReliable()||g===b.style[c]),g=parseFloat(g)||0}return g+eb(b,c,e||(i?"border":"content"),f,h)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(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":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){ -return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.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):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.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=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.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 qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.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;d>c;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(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.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)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(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=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.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||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.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;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.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,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.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=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.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=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"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):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.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 Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(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}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,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":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.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 n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.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?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.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)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0; -})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.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)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n}); -/* 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"}();/*! 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='­<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); <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> - -<?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; - } - } -} -<?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; - } -} -<?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; - } -} -<?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 -{ -} -<?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 as $node) { - if ($node instanceof DirectoryNode) { - $this->processDirectory($node, $dirObject); - continue; - } - - if ($node instanceof FileNode) { - $this->processFile($node, $dirObject); - continue; - } - - throw new RuntimeException( - 'Unknown node type for XML report' - ); - } - } - - 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() - ); - } -} -<?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); - } -} -<?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); - } -} -<?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); - } -} -<?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(); - } -} -<?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); - } -} -<?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 - ]; - - 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']]); - } -} -<?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) - ); - } -} -<?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); - } -} -<?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; - } - } -} -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. -<?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; - } -} -<?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, $locals); - } else { - $_paths[] = $path; - } - } - - return $_paths; - } -} -<?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 $subString - * @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; - } -} -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. -<?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 - ) - ) - ); - } - } -} - -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. -<?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. - * - * @since Class available since Release 1.0.0 - */ -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); -} -PHP_TokenStream - -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. -<?php -/* - * This file is part of the PHP_TokenStream 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 PHP token. - * - * @author Sebastian Bergmann <sebastian@phpunit.de> - * @copyright Sebastian Bergmann <sebastian@phpunit.de> - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/php-token-stream/tree - * @since Class available since Release 1.0.0 - */ -abstract class PHP_Token -{ - /** - * @var string - */ - protected $text; - - /** - * @var integer - */ - protected $line; - - /** - * @var PHP_Token_Stream - */ - protected $tokenStream; - - /** - * @var integer - */ - protected $id; - - /** - * Constructor. - * - * @param string $text - * @param integer $line - * @param PHP_Token_Stream $tokenStream - * @param integer $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 integer - */ - public function getLine() - { - return $this->line; - } -} - -abstract class PHP_TokenWithScope extends PHP_Token -{ - /** - * @var integer - */ - 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 integer - */ - 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 integer - */ - 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 = array(); - $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 integer - */ - protected $ccn; - - /** - * @var string - */ - protected $name; - - /** - * @var string - */ - protected $signature; - - /** - * @return array - */ - public function getArguments() - { - if ($this->arguments !== null) { - return $this->arguments; - } - - $this->arguments = array(); - $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(); - - for ($i = $this->id + 1; $i < count($tokens); $i++) { - if ($tokens[$i] instanceof PHP_Token_STRING) { - $this->name = (string)$tokens[$i]; - break; - } elseif ($tokens[$i] instanceof PHP_Token_AMPERSAND && - $tokens[$i+1] instanceof PHP_Token_STRING) { - $this->name = (string)$tokens[$i+1]; - break; - } elseif ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) { - $this->name = 'anonymous function'; - break; - } - } - - if ($this->name != 'anonymous function') { - 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 integer - */ - 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->getName() == 'anonymous function') { - $this->signature = 'anonymous function'; - $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; - } -} - -class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility -{ - /** - * @var array - */ - protected $interfaces; - - /** - * @return string - */ - public function getName() - { - return (string)$this->tokenStream[$this->id + 2]; - } - - /** - * @return boolean - */ - 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 = array( - '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 = join($join, $parts); - } - - return $result; - } - - /** - * @return boolean|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 boolean - */ - 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|boolean - */ - 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 -{ - /** - * @return string - */ - public function getName() - { - $next = $this->tokenStream[$this->id + 1]; - - if ($next instanceof PHP_Token_WHITESPACE) { - $next = $this->tokenStream[$this->id + 2]; - } - - if ($next instanceof PHP_Token_STRING) { - return (string) $next; - } - - if ($next instanceof PHP_Token_OPEN_CURLY || - $next instanceof PHP_Token_EXTENDS || - $next instanceof PHP_Token_IMPLEMENTS) { - return 'anonymous class'; - } - } -} - -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_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_SHAPE 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 {} -<?php -/* - * This file is part of the PHP_TokenStream 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 stream of PHP tokens. - * - * @author Sebastian Bergmann <sebastian@phpunit.de> - * @copyright Sebastian Bergmann <sebastian@phpunit.de> - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/php-token-stream/tree - * @since Class available since Release 1.0.0 - */ -class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator -{ - /** - * @var array - */ - protected static $customTokens = array( - '(' => '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 = array(); - - /** - * @var integer - */ - protected $position = 0; - - /** - * @var array - */ - protected $linesOfCode = array('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 = array(); - - /** - * 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 = array(); - } - - /** - * @return string - */ - public function __toString() - { - $buffer = ''; - - foreach ($this as $token) { - $buffer .= $token; - } - - return $buffer; - } - - /** - * @return string - * @since Method available since Release 1.1.0 - */ - 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) - { - $line = 1; - $tokens = token_get_all($sourceCode); - $numTokens = count($tokens); - - $lastNonWhitespaceTokenWasDoubleColon = false; - - for ($i = 0; $i < $numTokens; ++$i) { - $token = $tokens[$i]; - unset($tokens[$i]); - - if (is_array($token)) { - $name = substr(token_name($token[0]), 2); - $text = $token[1]; - - if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') { - $name = 'CLASS_NAME_CONSTANT'; - } - - $tokenClass = 'PHP_Token_' . $name; - } else { - $text = $token; - $tokenClass = self::$customTokens[$token]; - } - - $this->tokens[] = new $tokenClass($text, $line, $this, $i); - $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; - } - } - - $this->linesOfCode['loc'] = substr_count($sourceCode, "\n"); - $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] - - $this->linesOfCode['cloc']; - } - - /** - * @return integer - */ - 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 - * @since Method available since Release 1.1.0 - */ - 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 - * @since Method available since Release 1.1.0 - */ - public function getIncludes($categorize = false, $category = null) - { - if ($this->includes === null) { - $this->includes = array( - 'require_once' => array(), - 'require' => array(), - 'include_once' => array(), - 'include' => array() - ); - - 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 - * @since Method available since Release 1.2.0 - */ - public function getFunctionForLine($line) - { - $this->parse(); - - if (isset($this->lineToFunctionMap[$line])) { - return $this->lineToFunctionMap[$line]; - } - } - - protected function parse() - { - $this->interfaces = array(); - $this->classes = array(); - $this->traits = array(); - $this->functions = array(); - $class = array(); - $classEndLine = array(); - $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] = array( - 'methods' => array(), - '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 = array( - 'methods' => array(), - '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(); - - if ($class[count($class)-1] != 'anonymous class') { - $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 = array( - '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) && $class[count($class)-1] != 'anonymous 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 boolean - */ - public function valid() - { - return isset($this->tokens[$this->position]); - } - - /** - * @return integer - */ - public function key() - { - return $this->position; - } - - /** - * @return PHP_Token - */ - public function current() - { - return $this->tokens[$this->position]; - } - - /** - */ - public function next() - { - $this->position++; - } - - /** - * @param integer $offset - * @return boolean - */ - public function offsetExists($offset) - { - return isset($this->tokens[$offset]); - } - - /** - * @param integer $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 integer $offset - * @param mixed $value - */ - public function offsetSet($offset, $value) - { - $this->tokens[$offset] = $value; - } - - /** - * @param integer $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 integer $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 integer $startLine - * @param integer $endLine - */ - private function addFunctionToMap($name, $startLine, $endLine) - { - for ($line = $startLine; $line <= $endLine; $line++) { - $this->lineToFunctionMap[$line] = $name; - } - } -} -<?php -/* - * This file is part of the PHP_TokenStream 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 caching factory for token stream objects. - * - * @author Sebastian Bergmann <sebastian@phpunit.de> - * @copyright Sebastian Bergmann <sebastian@phpunit.de> - * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License - * @link http://github.com/sebastianbergmann/php-token-stream/tree - * @since Class available since Release 1.0.0 - */ -class PHP_Token_Stream_CachingFactory -{ - /** - * @var array - */ - protected static $cache = array(); - - /** - * @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 = array(); - } - } -} -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. -<?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); -} -<?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; - } -} -<?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); -} -<?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); -} -<?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); -} -<?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(); -} -<?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); -} -<?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 -{ -} -<?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 -{ -} -<?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 -{ -} -<?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 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 = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . - DIRECTORY_SEPARATOR; - $classTemplate = new Text_Template( - $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 = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR; - $classTemplate = new Text_Template($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 = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . DIRECTORY_SEPARATOR; - $methodTemplate = new Text_Template($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 = new Text_Template($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) - { - $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . - DIRECTORY_SEPARATOR; - $classTemplate = new Text_Template( - $templateDir . 'mocked_class.tpl' - ); - - $additionalInterfaces = []; - $cloneTemplate = ''; - $isClass = false; - $isInterface = false; - - $mockClassName = $this->generateClassName( - $type, - $mockClassName, - 'Mock_' - ); - - 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 - ) - ); - } - - $additionalInterfaces[] = $_type; - - foreach ($this->getClassMethods($_type) as $method) { - if (in_array($method, $methods)) { - throw new PHPUnit_Framework_MockObject_RuntimeException( - sprintf( - 'Duplicate method "%s" not allowed.', - $method - ) - ); - } - - $methods[] = $method; - } - } - } - - 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 = new Text_Template( - $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 = new Text_Template( - $templateDir . 'unmocked_clone.tpl' - ); - } else { - $cloneTemplate = new Text_Template( - $templateDir . 'mocked_clone.tpl' - ); - } - } - } else { - $cloneTemplate = new Text_Template( - $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 - ); - } - } - } 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 = new Text_Template( - $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(microtime()), 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 - ); - } - - /** - * @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 - * - * @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) - { - if ($static) { - $templateFile = 'mocked_static_method.tpl'; - } 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 = new Text_Template($templateDir . 'deprecation.tpl'); - - $deprecationTemplate->setVar( - [ - 'deprecation' => var_export($deprecation, true), - ] - ); - - $deprecation = $deprecationTemplate->render(); - } - - $template = new Text_Template($templateDir . $templateFile); - - $template->setVar( - [ - 'arguments_decl' => $arguments_decl, - 'arguments_call' => $arguments_call, - 'return_delim' => $return_type ? ': ' : '', - '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; - } - } - - $default = ''; - $reference = ''; - $typeDeclaration = ''; - - if (!$forCall) { - if ($this->hasType($parameter) && (string) $parameter->getType() !== 'self') { - $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[] = $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 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; - } -} - - @trigger_error({deprecation}, E_USER_DEPRECATED); -{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} - - 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 __clone() - { - $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker(); - } - - {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; - } - - {modifier} function {reference}{method_name}({arguments_decl}){return_delim}{return_type} - { - throw new PHPUnit_Framework_MockObject_BadMethodCallException; - } - - {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); - } -{prologue}class {class_name} -{ - use {trait_name}; -} - public function __clone() - { - $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker(); - parent::__clone(); - } -{namespace}class {class_name} extends \SoapClient -{ - public function __construct($wsdl, array $options) - { - parent::__construct('{wsdl}', $options); - } -{methods}} - - public function {method_name}({arguments}) - { - } -<?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(); -} -<?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; - } -} -<?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; - - /** - * @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; - $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 ''; - case 'float': return 0.0; - case 'int': return 0; - case 'bool': return false; - case 'array': return []; - - case 'callable': - case 'Closure': - return function () {}; - - case 'Traversable': - case 'Generator': - $generator = function () { yield; }; - - return $generator(); - - default: - $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; - } - } -} -<?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(); - } - } -} -<?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); -} -<?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; - } -} -<?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() - { - } -} -<?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; - } -} -<?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() - ) - ); - } - } -} -<?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); -} -<?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 - ) - ); - } - } -} -<?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).' - ); - } - } -} -<?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.' - ); - } - } -} -<?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).' - ); - } - } -} -<?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 - ) - ); - } - } -} -<?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; - } -} -<?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); - } -} -<?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; - } -} -<?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() - { - } -} -<?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; - } -} -<?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(); -} -<?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); -} -<?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) - ); - } -} -<?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) - ); - } -} -<?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); -} -<?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) - ); - } -} -<?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); - } -} -<?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'; - } - } -} -<?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; - } -} -<?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'; - } -} -<?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'; - } -} -<?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(); -} -code-unit-reverse-lookup - -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. -<?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; - } - } -} -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. -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @param array $processed - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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)); - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - abstract public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false); -} -<?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(); - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false) - { - $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; - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false) - { - $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 - */ - protected function dateTimeToString($datetime) - { - $string = $datetime->format(\DateTime::ISO8601); - - return $string ? $string : 'Invalid DateTimeInterface object'; - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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); - } -} -<?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; - } -} -<?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]); - } - } - } -} -<?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; - } -}<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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) - ) - ); - } - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @param array $processed - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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); - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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) - ); - } - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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) - ) - ); - } - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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.' - ); - } - } - } -} -<?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 The first value to compare - * @param mixed $actual The second value to compare - * @param float $delta The allowed numerical distance between two values to - * consider them equal - * @param bool $canonicalize If set to TRUE, arrays are sorted before - * comparison - * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is - * ignored when comparing string values - * @throws ComparisonFailure Thrown when the comparison - * fails. Contains information about the - * specific errors that lead to the failure. - */ - 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 - -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. -<?php -/* - * This file is part of the Diff 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\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; - } -} -<?php -/* - * This file is part of the Diff 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\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; - } -} -<?php -/* - * This file is part of the Diff 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\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 - */ - 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) - { - if (!is_array($from) && !is_string($from)) { - $from = (string) $from; - } - - if (!is_array($to) && !is_string($to)) { - $to = (string) $to; - } - - $buffer = $this->header; - $diff = $this->diffToArray($from, $to, $lcs); - - $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; - } - - $start = isset($old[0]) ? $old[0] : 0; - $end = count($diff); - - if ($tmp = array_search($end, $old)) { - $end = $tmp; - } - - $newChunk = true; - - for ($i = $start; $i < $end; $i++) { - if (isset($old[$i])) { - $buffer .= "\n"; - $newChunk = true; - $i = $old[$i]; - } - - if ($newChunk) { - if ($this->showNonDiffLines === true) { - $buffer .= "@@ @@\n"; - } - $newChunk = false; - } - - if ($diff[$i][1] === 1 /* ADDED */) { - $buffer .= '+' . $diff[$i][0] . "\n"; - } elseif ($diff[$i][1] === 2 /* REMOVED */) { - $buffer .= '-' . $diff[$i][0] . "\n"; - } elseif ($this->showNonDiffLines === true) { - $buffer .= ' ' . $diff[$i][0] . "\n"; - } - } - - return $buffer; - } - - /** - * Returns the diff between two arrays or strings as array. - * - * Each array element contains two elements: - * - [0] => string $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) - { - preg_match_all('(\r\n|\r|\n)', $from, $fromMatches); - preg_match_all('(\r\n|\r|\n)', $to, $toMatches); - - if (is_string($from)) { - $from = preg_split('(\r\n|\r|\n)', $from); - } - - if (is_string($to)) { - $to = preg_split('(\r\n|\r|\n)', $to); - } - - $start = array(); - $end = array(); - $fromLength = count($from); - $toLength = count($to); - $length = min($fromLength, $toLength); - - for ($i = 0; $i < $length; ++$i) { - if ($from[$i] === $to[$i]) { - $start[] = $from[$i]; - unset($from[$i], $to[$i]); - } else { - break; - } - } - - $length -= $i; - - for ($i = 1; $i < $length; ++$i) { - if ($from[$fromLength - $i] === $to[$toLength - $i]) { - array_unshift($end, $from[$fromLength - $i]); - unset($from[$fromLength - $i], $to[$toLength - $i]); - } else { - break; - } - } - - if ($lcs === null) { - $lcs = $this->selectLcsImplementation($from, $to); - } - - $common = $lcs->calculate(array_values($from), array_values($to)); - $diff = array(); - - if (isset($fromMatches[0]) && $toMatches[0] && - count($fromMatches[0]) === count($toMatches[0]) && - $fromMatches[0] !== $toMatches[0]) { - $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; - } - - /** - * @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 - */ - private function calculateEstimatedFootprint(array $from, array $to) - { - $itemSize = PHP_INT_SIZE == 4 ? 76 : 144; - - return $itemSize * pow(min(count($from), count($to)), 2); - } -} -<?php -/* - * This file is part of the Diff 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\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); -} -<?php -/* - * This file is part of the Diff 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\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(); - } elseif ($cFrom == 1) { - if (in_array($from[0], $to)) { - return array($from[0]); - } else { - return array(); - } - } else { - $i = intval($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; - } -} -<?php -/* - * This file is part of the Diff 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\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); - } -} -<?php -/* - * This file is part of the Diff 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\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; - } -} -<?php -/* - * This file is part of the Diff 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\Diff; - -/** - * Unified diff parser. - */ -class Parser -{ - /** - * @param string $string - * - * @return Diff[] - */ - public function parse($string) - { - $lines = preg_split('(\r\n|\r|\n)', $string); - $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 (count($collected) && ($diff !== null)) { - $this->parseFileDiff($diff, $collected); - $diffs[] = $diff; - } - - return $diffs; - } - - /** - * @param Diff $diff - * @param array $lines - */ - private function parseFileDiff(Diff $diff, array $lines) - { - $chunks = array(); - - 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 (isset($chunk)) { - $chunk->setLines($diffLines); - } - } - } - - $diff->setChunks($chunks); - } -} -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. -<?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', - array( - 1 => array('pipe', 'w'), - 2 => array('pipe', 'w') - ), - $pipes, - null, - null, - array('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); - } -} -<?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')) { - 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 = array( - 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'); - } -} -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. -<?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; - } - - $context->add($data); - - foreach ($data 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. This method guarantees - * thought that the result contains now newlines. - * - * 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 (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\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; - } - - $key = $processed->add($value); - $values = ''; - - if (count($value) > 0) { - foreach ($value 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); - } -} -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. -<?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); - } - - else if (is_object($value)) { - return $this->addObject($value); - } - - throw new InvalidArgumentException( - 'Only arrays and objects are supported' - ); - } - - /** - * Checks if the given value exists within the context. - * - * @param array|object $value The value to check. - * @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); - } - - else if (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; - } - - $this->arrays[] = &$array; - - return count($this->arrays) - 1; - } - - /** - * @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) - { - $keys = array_keys($this->arrays, $array, true); - $hash = '_Key_' . microtime(true); - - foreach ($keys as $key) { - $this->arrays[$key][$hash] = $hash; - - if (isset($array[$hash]) && $array[$hash] === $hash) { - unset($this->arrays[$key][$hash]); - - return $key; - } - - unset($this->arrays[$key][$hash]); - } - - return false; - } - - /** - * @param object $value - * @return string|false - */ - private function containsObject($value) - { - if ($this->objects->contains($value)) { - return spl_object_hash($value); - } - - return false; - } -} -<?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 -{ -} -<?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 -{ -} -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. -<?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', - ]; - } -} -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. -<?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; - } -} -<?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; - } -} -<?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 -{ -} -<?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]); - } - } - } - } -} -<?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 -{ -} -<?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; - } -} -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. -<?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; - } - - $processed->add($variable); - - if (is_array($variable)) { - foreach ($variable 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); - - $value = $attribute->getValue($variable); - - if (!is_array($value) && !is_object($value)) { - continue; - } - - $objects = array_merge( - $objects, - $this->enumerate($value, $processed) - ); - } - } - - return $objects; - } -} -<?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 -{ -} -<?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 -{ -} -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. -<?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; - } -} -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. -<?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 -{ -} -<?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 -{ - /** - * @param string $className - * - * @return self - */ - public static function fromNonExistingClass($className) - { - 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)); - } - - /** - * @param ReflectionClass $reflectionClass - * - * @return self - */ - public static function fromAbstractClass(ReflectionClass $reflectionClass) - { - return new self(sprintf( - 'The provided class "%s" is abstract, and can not be instantiated', - $reflectionClass->getName() - )); - } -} -<?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 -{ - /** - * @param ReflectionClass $reflectionClass - * @param Exception $exception - * - * @return self - */ - public static function fromSerializationTriggeredException(ReflectionClass $reflectionClass, Exception $exception) - { - return new self( - sprintf( - 'An exception was raised while trying to instantiate an instance of "%s" via un-serialization', - $reflectionClass->getName() - ), - 0, - $exception - ); - } - - /** - * @param ReflectionClass $reflectionClass - * @param string $errorString - * @param int $errorCode - * @param string $errorFile - * @param int $errorLine - * - * @return UnexpectedValueException - */ - public static function fromUncleanUnSerialization( - ReflectionClass $reflectionClass, - $errorString, - $errorCode, - $errorFile, - $errorLine - ) { - 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) - ); - } -} -<?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 Closure; -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 \Closure[] of {@see \Closure} instances used to instantiate specific classes - */ - private static $cachedInstantiators = array(); - - /** - * @var object[] of objects that can directly be cloned - */ - private static $cachedCloneables = array(); - - /** - * {@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 - * - * @param string $className - * - * @return object - */ - private function buildAndCacheFromFactory($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 {@see \Closure} capable of instantiating the given $className without - * invoking its constructor. - * - * @param string $className - * - * @return Closure - */ - private function buildFactory($className) - { - $reflectionClass = $this->getReflectionClass($className); - - if ($this->isInstantiableViaReflection($reflectionClass)) { - return function () use ($reflectionClass) { - return $reflectionClass->newInstanceWithoutConstructor(); - }; - } - - $serializedString = sprintf( - '%s:%d:"%s":0:{}', - $this->getSerializationFormat($reflectionClass), - strlen($className), - $className - ); - - $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString); - - return function () use ($serializedString) { - return unserialize($serializedString); - }; - } - - /** - * @param string $className - * - * @return ReflectionClass - * - * @throws InvalidArgumentException - */ - private function getReflectionClass($className) - { - 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) - { - set_error_handler(function ($code, $message, $file, $line) use ($reflectionClass, & $error) { - $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) - { - try { - unserialize($serializedString); - } catch (Exception $exception) { - restore_error_handler(); - - throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception); - } - } - - /** - * @param ReflectionClass $reflectionClass - * - * @return bool - */ - private function isInstantiableViaReflection(ReflectionClass $reflectionClass) - { - if (\PHP_VERSION_ID >= 50600) { - return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal()); - } - - return \PHP_VERSION_ID >= 50400 && ! $this->hasInternalAncestors($reflectionClass); - } - - /** - * Verifies whether the given class is to be considered internal - * - * @param ReflectionClass $reflectionClass - * - * @return bool - */ - private function hasInternalAncestors(ReflectionClass $reflectionClass) - { - do { - if ($reflectionClass->isInternal()) { - return true; - } - } while ($reflectionClass = $reflectionClass->getParentClass()); - - return false; - } - - /** - * Verifies if the given PHP version implements the `Serializable` interface serialization - * with an incompatible serialization format. If that's the case, use serialization marker - * "C" instead of "O". - * - * @link http://news.php.net/php.internals/74654 - * - * @param ReflectionClass $reflectionClass - * - * @return string the serialization format marker, either self::SERIALIZATION_FORMAT_USE_UNSERIALIZER - * or self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER - */ - private function getSerializationFormat(ReflectionClass $reflectionClass) - { - if ($this->isPhpVersionWithBrokenSerializationFormat() - && $reflectionClass->implementsInterface('Serializable') - ) { - return self::SERIALIZATION_FORMAT_USE_UNSERIALIZER; - } - - return self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER; - } - - /** - * Checks whether the current PHP runtime uses an incompatible serialization format - * - * @return bool - */ - private function isPhpVersionWithBrokenSerializationFormat() - { - return PHP_VERSION_ID === 50429 || PHP_VERSION_ID === 50513; - } - - /** - * Checks if a class is cloneable - * - * @param ReflectionClass $reflection - * - * @return bool - */ - private function isSafeToClone(ReflectionClass $reflection) - { - if (method_exists($reflection, 'isCloneable') && ! $reflection->isCloneable()) { - return false; - } - - // not cloneable if it implements `__clone`, as we want to avoid calling it - return ! $reflection->hasMethod('__clone'); - } -} -<?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); -} -Copyright (c) 2004-2016 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. -<?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> - */ -class Dumper -{ - /** - * The amount of spaces to use for indentation of nested nodes. - * - * @var int - */ - protected $indentation; - - /** - * @param int $indentation - */ - public function __construct($indentation = 4) - { - if ($indentation < 1) { - throw new \InvalidArgumentException('The indentation must be greater than zero.'); - } - - $this->indentation = $indentation; - } - - /** - * Sets the indentation. - * - * @param int $num The amount of spaces to use for indentation of nested nodes. - */ - public function setIndentation($num) - { - @trigger_error('The '.__METHOD__.' method is deprecated since version 3.1 and will be removed in 4.0. Pass the indentation to the constructor instead.', E_USER_DEPRECATED); - - $this->indentation = (int) $num; - } - - /** - * 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, $inline = 0, $indent = 0, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 5) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(4)) { - $flags |= Yaml::DUMP_OBJECT; - } - } - - $output = ''; - $prefix = $indent ? str_repeat(' ', $indent) : ''; - - if ($inline <= 0 || !is_array($input) || empty($input)) { - $output .= $prefix.Inline::dump($input, $flags); - } else { - $isAHash = 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")) { - $output .= sprintf("%s%s%s |\n", $prefix, $isAHash ? Inline::dump($key, $flags).':' : '-', ''); - - foreach (preg_split('/\n|\r\n/', $value) as $row) { - $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row); - } - - continue; - } - - $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value); - - $output .= sprintf('%s%s%s%s', - $prefix, - $isAHash ? Inline::dump($key, $flags).':' : '-', - $willBeInlined ? ' ' : "\n", - $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) - ).($willBeInlined ? "\n" : ''); - } - } - - return $output; - } -} -<?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($value) - { - return 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($value) - { - 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($value) - { - // 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 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($value) - { - return sprintf("'%s'", str_replace('\'', '\'\'', $value)); - } -} -<?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 -{ -} -<?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 -{ -} -<?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; - - /** - * Constructor. - * - * @param string $message The error message - * @param int $parsedLine The line where the error occurred - * @param int $snippet The snippet of code near the problem - * @param string $parsedFile The file name where the error occurred - * @param \Exception $previous The previous exception - */ - public function __construct($message, $parsedLine = -1, $snippet = null, $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 .= '.'; - } - } -} -<?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 -{ -} -<?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\Exception\DumpException; - -/** - * Inline implements a YAML parser/dumper for the YAML inline syntax. - * - * @author Fabien Potencier <fabien@symfony.com> - * - * @internal - */ -class Inline -{ - const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')'; - - private static $exceptionOnInvalidType = false; - private static $objectSupport = false; - private static $objectForMap = false; - - /** - * Converts a YAML string to a PHP array. - * - * @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 array A PHP array representing the YAML string - * - * @throws ParseException - */ - public static function parse($value, $flags = 0, $references = array()) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3 && !is_array($references)) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - - if ($references) { - $flags |= Yaml::PARSE_OBJECT; - } - - if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(3)) { - $flags |= Yaml::PARSE_OBJECT_FOR_MAP; - } - } - - if (func_num_args() >= 5) { - $references = func_get_arg(4); - } else { - $references = array(); - } - } - - 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); - - $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; - switch ($value[0]) { - 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, array('"', "'"), $i, true, $references); - } - - // some comments are allowed at the end - if (preg_replace('/\s+#.*$/A', '', substr($value, $i))) { - throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i))); - } - - 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 array - * - * @throws DumpException When trying to dump PHP resource - */ - public static function dump($value, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(2)) { - $flags |= Yaml::DUMP_OBJECT; - } - } - - 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 (Yaml::DUMP_OBJECT & $flags) { - return '!php/object:'.serialize($value); - } - - if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { - return self::dumpArray((array) $value, $flags); - } - - 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 preg_match(self::getHexRegex(), $value): - case preg_match(self::getTimestampRegex(), $value): - return Escaper::escapeWithSingleQuotes($value); - default: - return $value; - } - } - - /** - * Check if given array is hash or just normal indexed array. - * - * @internal - * - * @param array $value The PHP array to check - * - * @return bool true if value is hash array, false otherwise - */ - public static function isHash(array $value) - { - $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($value, $flags) - { - // array - if ($value && !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 scalar to a YAML string. - * - * @param string $scalar - * @param int $flags - * @param string $delimiters - * @param array $stringDelimiters - * @param int &$i - * @param bool $evaluate - * @param array $references - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - * - * @internal - */ - public static function parseScalar($scalar, $flags = 0, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true, $references = array()) - { - if (in_array($scalar[$i], $stringDelimiters)) { - // quoted scalar - $output = self::parseQuotedScalar($scalar, $i); - - if (null !== $delimiters) { - $tmp = ltrim(substr($scalar, $i), ' '); - if (!in_array($tmp[0], $delimiters)) { - throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i))); - } - } - } else { - // "normal" string - if (!$delimiters) { - $output = substr($scalar, $i); - $i += strlen($output); - - // remove comments - if (preg_match('/[ \t]+#/', $output, $match, PREG_OFFSET_CAPTURE)) { - $output = substr($output, 0, $match[0][1]); - } - } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { - $output = $match[1]; - $i += strlen($output); - } else { - throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar)); - } - - // 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])) { - throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0])); - } - - if ($output && '%' === $output[0]) { - @trigger_error('Not quoting a scalar starting with the "%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', E_USER_DEPRECATED); - } - - if ($evaluate) { - $output = self::evaluateScalar($output, $flags, $references); - } - } - - return $output; - } - - /** - * Parses a quoted scalar to YAML. - * - * @param string $scalar - * @param int &$i - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseQuotedScalar($scalar, &$i) - { - if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { - throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i))); - } - - $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 sequence to a YAML string. - * - * @param string $sequence - * @param int $flags - * @param int &$i - * @param array $references - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseSequence($sequence, $flags, &$i = 0, $references = array()) - { - $output = array(); - $len = strlen($sequence); - ++$i; - - // [foo, bar, ...] - while ($i < $len) { - switch ($sequence[$i]) { - case '[': - // nested sequence - $output[] = self::parseSequence($sequence, $flags, $i, $references); - break; - case '{': - // nested mapping - $output[] = self::parseMapping($sequence, $flags, $i, $references); - break; - case ']': - return $output; - case ',': - case ' ': - break; - default: - $isQuoted = in_array($sequence[$i], array('"', "'")); - $value = self::parseScalar($sequence, $flags, array(',', ']'), array('"', "'"), $i, true, $references); - - // the value can be an array if a reference has been resolved to an array var - if (!is_array($value) && !$isQuoted && false !== strpos($value, ': ')) { - // embedded mapping? - try { - $pos = 0; - $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references); - } catch (\InvalidArgumentException $e) { - // no, it's not - } - } - - $output[] = $value; - - --$i; - } - - ++$i; - } - - throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence)); - } - - /** - * Parses a mapping to a YAML string. - * - * @param string $mapping - * @param int $flags - * @param int &$i - * @param array $references - * - * @return string A YAML string - * - * @throws ParseException When malformed inline YAML string is parsed - */ - private static function parseMapping($mapping, $flags, &$i = 0, $references = array()) - { - $output = array(); - $len = strlen($mapping); - ++$i; - - // {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 - $key = self::parseScalar($mapping, $flags, array(':', ' '), array('"', "'"), $i, false); - - // value - $done = false; - - while ($i < $len) { - 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. - if (!isset($output[$key])) { - $output[$key] = $value; - } - $done = true; - 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. - if (!isset($output[$key])) { - $output[$key] = $value; - } - $done = true; - break; - case ':': - case ' ': - break; - default: - $value = self::parseScalar($mapping, $flags, array(',', '}'), array('"', "'"), $i, true, $references); - // Spec: Keys MUST be unique; first one wins. - // Parser cannot abort this mapping earlier, since lines - // are processed sequentially. - if (!isset($output[$key])) { - $output[$key] = $value; - } - $done = true; - --$i; - } - - ++$i; - - if ($done) { - continue 2; - } - } - } - - throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping)); - } - - /** - * Evaluates scalars and replaces magic values. - * - * @param string $scalar - * @param int $flags - * @param array $references - * - * @return string A 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($scalar, $flags, $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.'); - } - - if (!array_key_exists($value, $references)) { - throw new ParseException(sprintf('Reference "%s" does not exist.', $value)); - } - - return $references[$value]; - } - - switch (true) { - case 'null' === $scalarLower: - case '' === $scalar: - case '~' === $scalar: - return; - case 'true' === $scalarLower: - return true; - case 'false' === $scalarLower: - return false; - // Optimise for returning strings. - case $scalar[0] === '+' || $scalar[0] === '-' || $scalar[0] === '.' || $scalar[0] === '!' || is_numeric($scalar[0]): - switch (true) { - case 0 === strpos($scalar, '!str'): - return (string) substr($scalar, 5); - case 0 === strpos($scalar, '! '): - return (int) self::parseScalar(substr($scalar, 2), $flags); - case 0 === strpos($scalar, '!php/object:'): - if (self::$objectSupport) { - return unserialize(substr($scalar, 12)); - } - - if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); - } - - return; - case 0 === strpos($scalar, '!!php/object:'): - if (self::$objectSupport) { - @trigger_error('The !!php/object tag to indicate dumped PHP objects is deprecated since version 3.1 and will be removed in 4.0. Use the !php/object tag instead.', E_USER_DEPRECATED); - - return unserialize(substr($scalar, 13)); - } - - if (self::$exceptionOnInvalidType) { - throw new ParseException('Object support when parsing a YAML file has been disabled.'); - } - - return; - case 0 === strpos($scalar, '!!float '): - return (float) substr($scalar, 8); - 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 preg_match(self::getHexRegex(), $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 0 === strpos($scalar, '!!binary '): - return self::evaluateBinaryScalar(substr($scalar, 9)); - case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): - return (float) str_replace(',', '', $scalar); - case preg_match(self::getTimestampRegex(), $scalar): - if (Yaml::PARSE_DATETIME & $flags) { - 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; - } - default: - return (string) $scalar; - } - } - - /** - * @param string $scalar - * - * @return string - * - * @internal - */ - public static function evaluateBinaryScalar($scalar) - { - $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))); - } - - if (!preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) { - throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData)); - } - - return base64_decode($parsedBinaryData, true); - } - - private static function isBinaryString($value) - { - return !preg_match('//u', $value) || preg_match('/[^\x09-\x0d\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() - { - 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() - { - return '~^0x[0-9a-f]++$~i'; - } -} -<?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; - -/** - * Parser parses YAML strings to convert them to PHP arrays. - * - * @author Fabien Potencier <fabien@symfony.com> - */ -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 $offset = 0; - private $totalNumberOfLines; - private $lines = array(); - private $currentLineNb = -1; - private $currentLine = ''; - private $refs = array(); - private $skippedLineNumbers = array(); - private $locallySkippedLineNumbers = array(); - - /** - * Constructor. - * - * @param int $offset The offset of YAML document (used for line numbers in error messages) - * @param int|null $totalNumberOfLines The overall number of lines being parsed - * @param int[] $skippedLineNumbers Number of comment lines that have been skipped by the parser - */ - public function __construct($offset = 0, $totalNumberOfLines = null, array $skippedLineNumbers = array()) - { - $this->offset = $offset; - $this->totalNumberOfLines = $totalNumberOfLines; - $this->skippedLineNumbers = $skippedLineNumbers; - } - - /** - * 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($value, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(2)) { - $flags |= Yaml::PARSE_OBJECT; - } - } - - if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(3)) { - $flags |= Yaml::PARSE_OBJECT_FOR_MAP; - } - } - - if (!preg_match('//u', $value)) { - throw new ParseException('The YAML value does not appear to be valid UTF-8.'); - } - $this->currentLineNb = -1; - $this->currentLine = ''; - $value = $this->cleanup($value); - $this->lines = explode("\n", $value); - - if (null === $this->totalNumberOfLines) { - $this->totalNumberOfLines = count($this->lines); - } - - if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { - $mbEncoding = mb_internal_encoding(); - mb_internal_encoding('UTF-8'); - } - - $data = array(); - $context = null; - $allowOverwrite = false; - while ($this->moveToNextLine()) { - 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); - } - - $isRef = $mergeNode = false; - if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $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); - } - $context = 'sequence'; - - if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) { - $isRef = $matches['ref']; - $values['value'] = $matches['value']; - } - - // array - if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags); - } else { - if (isset($values['leadspaces']) - && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $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 (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $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); - } - $context = 'mapping'; - - // force correct settings - Inline::parse(null, $flags, $this->refs); - try { - $key = Inline::parseScalar($values['key']); - } catch (ParseException $e) { - $e->setParsedLine($this->getRealCurrentLineNb() + 1); - $e->setSnippet($this->currentLine); - - throw $e; - } - - // Convert float keys to strings, to avoid being converted to integers by PHP - if (is_float($key)) { - $key = (string) $key; - } - - if ('<<' === $key) { - $mergeNode = true; - $allowOverwrite = true; - if (isset($values['value']) && 0 === strpos($values['value'], '*')) { - $refName = substr($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); - } - - $refValue = $this->refs[$refName]; - - if (!is_array($refValue)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - foreach ($refValue as $key => $value) { - if (!isset($data[$key])) { - $data[$key] = $value; - } - } - } else { - if (isset($values['value']) && $values['value'] !== '') { - $value = $values['value']; - } else { - $value = $this->getNextEmbedBlock(); - } - $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags); - - if (!is_array($parsed)) { - throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - - 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 (!is_array($parsedItem)) { - throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem); - } - - foreach ($parsedItem as $key => $value) { - if (!isset($data[$key])) { - $data[$key] = $value; - } - } - } - } 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. - foreach ($parsed as $key => $value) { - if (!isset($data[$key])) { - $data[$key] = $value; - } - } - } - } - } elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) { - $isRef = $matches['ref']; - $values['value'] = $matches['value']; - } - - if ($mergeNode) { - // Merge keys - } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { - // 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])) { - $data[$key] = null; - } - } else { - $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags); - // 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 { - $value = $this->parseValue($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; - } - } - 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); - } - - // 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; - } - - if (is_array($value)) { - $first = reset($value); - if (is_string($first) && 0 === strpos($first, '*')) { - $data = array(); - foreach ($value as $alias) { - $data[] = $this->refs[substr($alias, 1)]; - } - $value = $data; - } - } - - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - return $value; - } - - 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 = 'Unable to parse.'; - } - - throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } - - if (isset($mbEncoding)) { - mb_internal_encoding($mbEncoding); - } - - 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($offset, $yaml, $flags) - { - $skippedLineNumbers = $this->skippedLineNumbers; - - foreach ($this->locallySkippedLineNumbers as $lineNumber) { - if ($lineNumber < $offset) { - continue; - } - - $skippedLineNumbers[] = $lineNumber; - } - - $parser = new self($offset, $this->totalNumberOfLines, $skippedLineNumbers); - $parser->refs = &$this->refs; - - return $parser->parse($yaml, $flags); - } - - /** - * Returns the current line number (takes the offset into account). - * - * @return int The current line number - */ - private function getRealCurrentLineNb() - { - $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() - { - return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' ')); - } - - /** - * Returns the next embed block of YAML. - * - * @param int $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($indentation = null, $inSequence = false) - { - $oldLineIndentation = $this->getCurrentLineIndentation(); - $blockScalarIndentations = array(); - - if ($this->isBlockScalarHeader()) { - $blockScalarIndentations[] = $this->getCurrentLineIndentation(); - } - - if (!$this->moveToNextLine()) { - return; - } - - if (null === $indentation) { - $newIndent = $this->getCurrentLineIndentation(); - - $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem(); - - if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } else { - $newIndent = $indentation; - } - - $data = array(); - if ($this->getCurrentLineIndentation() >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent); - } else { - $this->moveToPreviousLine(); - - return; - } - - if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) { - // the previous line contained a dash but no item content, this line is a sequence item with the same indentation - // and therefore no nested list or mapping - $this->moveToPreviousLine(); - - return; - } - - $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); - - 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 >= $this->getCurrentLineIndentation()) { - unset($blockScalarIndentations[$key]); - } - } - } - - if (empty($blockScalarIndentations) && !$this->isCurrentLineComment() && $this->isBlockScalarHeader()) { - $blockScalarIndentations[] = $this->getCurrentLineIndentation(); - } - - $previousLineIndentation = $indent; - - if ($isItUnindentedCollection && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) { - $this->moveToPreviousLine(); - break; - } - - if ($this->isCurrentLineBlank()) { - $data[] = substr($this->currentLine, $newIndent); - continue; - } - - // we ignore "comment" lines only when we are not inside a scalar block - if (empty($blockScalarIndentations) && $this->isCurrentLineComment()) { - // remember ignored comment lines (they are used later in nested - // parser calls to determine real line numbers) - // - // CAUTION: beware to not populate the global property here as it - // will otherwise influence the getRealCurrentLineNb() call here - // for consecutive comment lines and subsequent embedded blocks - $this->locallySkippedLineNumbers[] = $this->getRealCurrentLineNb(); - - continue; - } - - if ($indent >= $newIndent) { - $data[] = substr($this->currentLine, $newIndent); - } elseif (0 == $indent) { - $this->moveToPreviousLine(); - - break; - } else { - throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine); - } - } - - return implode("\n", $data); - } - - /** - * Moves the parser to the next line. - * - * @return bool - */ - private function moveToNextLine() - { - 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() - { - 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($value, $flags, $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); - } - - return $this->refs[$value]; - } - - if (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 (isset($matches['tag']) && '!!binary' === $matches['tag']) { - return Inline::evaluateBinaryScalar($data); - } - - return $data; - } - - try { - $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.'); - } - - 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($style, $chomping = '', $indentation = 0) - { - $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 (preg_match('/^ +/', $this->currentLine, $matches)) { - $indentation = strlen($matches[0]); - } - } - - if ($indentation > 0) { - $pattern = sprintf('/^ {%d}(.*)$/', $indentation); - - while ( - $notEOF && ( - $isCurrentLineBlank || - 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; $i < count($blockLines); ++$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() - { - $currentIndentation = $this->getCurrentLineIndentation(); - $EOF = !$this->moveToNextLine(); - - while (!$EOF && $this->isCurrentLineEmpty()) { - $EOF = !$this->moveToNextLine(); - } - - if ($EOF) { - return false; - } - - $ret = false; - if ($this->getCurrentLineIndentation() > $currentIndentation) { - $ret = true; - } - - $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() - { - 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() - { - 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() - { - //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() - { - 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($value) - { - $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 ($count == 1) { - // 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 ($count == 1) { - // 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() - { - $currentIndentation = $this->getCurrentLineIndentation(); - $notEOF = $this->moveToNextLine(); - - while ($notEOF && $this->isCurrentLineEmpty()) { - $notEOF = $this->moveToNextLine(); - } - - if (false === $notEOF) { - return false; - } - - $ret = false; - if ( - $this->getCurrentLineIndentation() == $currentIndentation - && - $this->isStringUnIndentedCollectionItem() - ) { - $ret = true; - } - - $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() - { - 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() - { - return (bool) preg_match('~'.self::BLOCK_SCALAR_HEADER_PATTERN.'$~', $this->currentLine); - } -} -<?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($value) - { - return str_replace('\'\'', '\'', $value); - } - - /** - * Unescapes a double quoted string. - * - * @param string $value A double quoted string. - * - * @return string The unescaped string. - */ - public function unescapeDoubleQuotedString($value) - { - $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($value) - { - 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. - * - * @param int $c The unicode code point - * - * @return string The corresponding UTF-8 character - */ - private static function utf8chr($c) - { - 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); - } -} -<?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> - */ -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; - - /** - * 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($input, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = self::PARSE_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 3) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the PARSE_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(2)) { - $flags |= self::PARSE_OBJECT; - } - } - - if (func_num_args() >= 4) { - @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since version 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(3)) { - $flags |= self::PARSE_OBJECT_FOR_MAP; - } - } - - $yaml = new Parser(); - - return $yaml->parse($input, $flags); - } - - /** - * Dumps a PHP array to a YAML string. - * - * The dump method, when supplied with an array, will do its best - * to convert the array into friendly YAML. - * - * @param array $array PHP array - * @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 array - */ - public static function dump($array, $inline = 2, $indent = 4, $flags = 0) - { - if (is_bool($flags)) { - @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since version 3.1 and will be removed in 4.0. Use the DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', E_USER_DEPRECATED); - - if ($flags) { - $flags = self::DUMP_EXCEPTION_ON_INVALID_TYPE; - } else { - $flags = 0; - } - } - - if (func_num_args() >= 5) { - @trigger_error('Passing a boolean flag to toggle object support is deprecated since version 3.1 and will be removed in 4.0. Use the DUMP_OBJECT flag instead.', E_USER_DEPRECATED); - - if (func_get_arg(4)) { - $flags |= self::DUMP_OBJECT; - } - } - - $yaml = new Dumper($indent); - - return $yaml->dump($array, $inline, 0, $flags); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Can be used as a foundation for new DatabaseTesters. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_AbstractTester implements PHPUnit_Extensions_Database_ITester -{ - /** - * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - protected $setUpOperation; - - /** - * @var PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - protected $tearDownOperation; - - /** - * @var PHPUnit_Extensions_Database_DataSet_IDataSet - */ - protected $dataSet; - - /** - * @var string - */ - protected $schema; - - /** - * Creates a new database tester. - */ - public function __construct() - { - $this->setUpOperation = PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT(); - $this->tearDownOperation = PHPUnit_Extensions_Database_Operation_Factory::NONE(); - } - - /** - * Closes the specified connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - */ - public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $connection->close(); - } - - /** - * Returns the test dataset. - * - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - public function getDataSet() - { - return $this->dataSet; - } - - /** - * TestCases must call this method inside setUp(). - */ - public function onSetUp() - { - $this->getSetUpOperation()->execute($this->getConnection(), $this->getDataSet()); - } - - /** - * TestCases must call this method inside tearDown(). - */ - public function onTearDown() - { - $this->getTearDownOperation()->execute($this->getConnection(), $this->getDataSet()); - } - - /** - * Sets the test dataset to use. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - $this->dataSet = $dataSet; - } - - /** - * Sets the schema value. - * - * @param string $schema - */ - public function setSchema($schema) - { - $this->schema = $schema; - } - - /** - * Sets the DatabaseOperation to call when starting the test. - * - * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation - */ - public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation) - { - $this->setUpOperation = $setUpOperation; - } - - /** - * Sets the DatabaseOperation to call when ending the test. - * - * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation - */ - public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation) - { - $this->tearDownOperation = $tearDownOperation; - } - - /** - * Returns the schema value - * - * @return string - */ - protected function getSchema() - { - return $this->schema; - } - - /** - * Returns the database operation that will be called when starting the test. - * - * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation - */ - protected function getSetUpOperation() - { - return $this->setUpOperation; - } - - /** - * Returns the database operation that will be called when ending the test. - * - * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation - */ - protected function getTearDownOperation() - { - return $this->tearDownOperation; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 dbunit datasets are equal. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Constraint_DataSetIsEqual extends PHPUnit_Framework_Constraint -{ - /** - * @var PHPUnit_Extensions_Database_DataSet_IDataSet - */ - protected $value; - - /** - * @var string - */ - protected $failure_reason; - - /** - * Creates a new constraint. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $value - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $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) - { - if (!$other instanceof PHPUnit_Extensions_Database_DataSet_IDataSet) { - throw new InvalidArgumentException( - 'PHPUnit_Extensions_Database_DataSet_IDataSet expected' - ); - } - - return $this->value->matches($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 $other->__toString() . ' ' . $this->toString(); - } - - /** - * Returns a string representation of the constraint. - * - * @return string - */ - public function toString() - { - return sprintf( - 'is equal to expected %s', $this->value->__toString() - ); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 dbunit tables are equal. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Constraint_TableIsEqual extends PHPUnit_Framework_Constraint -{ - /** - * @var PHPUnit_Extensions_Database_DataSet_ITable - */ - protected $value; - - /** - * @var string - */ - protected $failure_reason; - - /** - * Creates a new constraint. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $value - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $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) - { - if (!$other instanceof PHPUnit_Extensions_Database_DataSet_ITable) { - throw new InvalidArgumentException( - 'PHPUnit_Extensions_Database_DataSet_ITable expected' - ); - } - - return $this->value->matches($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 $other->__toString() . ' ' . $this->toString(); - } - - /** - * Returns a string representation of the constraint. - * - * @return string - */ - public function toString() - { - return sprintf( - 'is equal to expected %s', $this->value->__toString() - ); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 the row count in a table - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Constraint_TableRowCount extends PHPUnit_Framework_Constraint -{ - /** - * @var int - */ - protected $value; - - /** - * @var string - */ - protected $tableName; - - /** - * Creates a new constraint. - * - * @param $tableName - * @param $value - */ - public function __construct($tableName, $value) - { - parent::__construct(); - $this->tableName = $tableName; - $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) - { - return $other == $this->value; - } - - /** - * Returns a string representation of the constraint. - * - * @return string - */ - public function toString() - { - return sprintf('is equal to expected row count %d', $this->value); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 access to a database instance as a data set. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_DataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * An array of ITable objects. - * - * @var array - */ - protected $tables = []; - - /** - * The database connection this dataset is using. - * - * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - protected $databaseConnection; - - /** - * Creates a new dataset using the given database connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - */ - public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) - { - $this->databaseConnection = $databaseConnection; - } - - /** - * Creates the query necessary to pull all of the data from a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData - * @return unknown - */ - public static function buildTableSelect(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection = NULL) - { - if ($tableMetaData->getTableName() == '') { - $e = new Exception('Empty Table Name'); - echo $e->getTraceAsString(); - throw $e; - } - - $columns = $tableMetaData->getColumns(); - if ($databaseConnection) { - $columns = array_map([$databaseConnection, 'quoteSchemaObject'], $columns); - } - $columnList = implode(', ', $columns); - - if ($databaseConnection) { - $tableName = $databaseConnection->quoteSchemaObject($tableMetaData->getTableName()); - } else { - $tableName = $tableMetaData->getTableName(); - } - - $primaryKeys = $tableMetaData->getPrimaryKeys(); - if ($databaseConnection) { - $primaryKeys = array_map([$databaseConnection, 'quoteSchemaObject'], $primaryKeys); - } - if (count($primaryKeys)) { - $orderBy = 'ORDER BY ' . implode(' ASC, ', $primaryKeys) . ' ASC'; - } else { - $orderBy = ''; - } - - return "SELECT {$columnList} FROM {$tableName} {$orderBy}"; - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DB_TableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DB_TableIterator($this->getTableNames(), $this, $reverse); - } - - /** - * Returns a table object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DB_Table - */ - public function getTable($tableName) - { - if (!in_array($tableName, $this->getTableNames())) { - throw new InvalidArgumentException("$tableName is not a table in the current database."); - } - - if (empty($this->tables[$tableName])) { - $this->tables[$tableName] = new PHPUnit_Extensions_Database_DB_Table($this->getTableMetaData($tableName), $this->databaseConnection); - } - - return $this->tables[$tableName]; - } - - /** - * Returns a table meta data object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData - */ - public function getTableMetaData($tableName) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $this->databaseConnection->getMetaData()->getTableColumns($tableName), $this->databaseConnection->getMetaData()->getTablePrimaryKeys($tableName)); - } - - /** - * Returns a list of table names for the database - * - * @return Array - */ - public function getTableNames() - { - return $this->databaseConnection->getMetaData()->getTableNames(); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for communicating with a database. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection implements PHPUnit_Extensions_Database_DB_IDatabaseConnection -{ - /** - * @var PDO - */ - protected $connection; - - /** - * The metadata object used to retrieve table meta data from the database. - * - * @var PHPUnit_Extensions_Database_DB_IMetaData - */ - protected $metaData; - - /** - * Creates a new database connection - * - * @param PDO $connection - * @param string $schema - The name of the database schema you will be testing against. - */ - public function __construct(PDO $connection, $schema = '') - { - $this->connection = $connection; - $this->metaData = PHPUnit_Extensions_Database_DB_MetaData::createMetaData($connection, $schema); - $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - } - - /** - * Close this connection. - */ - public function close() - { - unset($this->connection); - } - - /** - * Returns a database metadata object that can be used to retrieve table - * meta data from the database. - * - * @return PHPUnit_Extensions_Database_DB_IMetaData - */ - public function getMetaData() - { - return $this->metaData; - } - - /** - * Returns the schema for the connection. - * - * @return string - */ - public function getSchema() - { - return $this->getMetaData()->getSchema(); - } - - /** - * Creates a dataset containing the specified table names. If no table - * names are specified then it will created a dataset over the entire - * database. - * - * @param array $tableNames - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - * @todo Implement the filtered data set. - */ - public function createDataSet(array $tableNames = NULL) - { - if (empty($tableNames)) { - return new PHPUnit_Extensions_Database_DB_DataSet($this); - } else { - return new PHPUnit_Extensions_Database_DB_FilteredDataSet($this, $tableNames); - } - } - - /** - * Creates a table with the result of the specified SQL statement. - * - * @param string $resultName - * @param string $sql - * @return PHPUnit_Extensions_Database_DB_Table - */ - public function createQueryTable($resultName, $sql) - { - return new PHPUnit_Extensions_Database_DataSet_QueryTable($resultName, $sql, $this); - } - - /** - * Returns this connection database configuration - * - * @return PHPUnit_Extensions_Database_Database_DatabaseConfig - */ - public function getConfig() - { - } - - /** - * Returns a PDO Connection - * - * @return PDO - */ - public function getConnection() - { - return $this->connection; - } - - /** - * Returns the number of rows in the given table. You can specify an - * optional where clause to return a subset of the table. - * - * @param string $tableName - * @param string $whereClause - * @return int - */ - public function getRowCount($tableName, $whereClause = NULL) - { - $query = 'SELECT COUNT(*) FROM ' . $this->quoteSchemaObject($tableName); - - if (isset($whereClause)) { - $query .= " WHERE {$whereClause}"; - } - - return (int) $this->connection->query($query)->fetchColumn(); - } - - /** - * Returns a quoted schema object. (table name, column name, etc) - * - * @param string $object - * @return string - */ - public function quoteSchemaObject($object) - { - return $this->getMetaData()->quoteSchemaObject($object); - } - - /** - * Returns the command used to truncate a table. - * - * @return string - */ - public function getTruncateCommand() - { - return $this->getMetaData()->getTruncateCommand(); - } - - /** - * Returns true if the connection allows cascading - * - * @return bool - */ - public function allowsCascading() - { - return $this->getMetaData()->allowsCascading(); - } - - /** - * Disables primary keys if connection does not allow setting them otherwise - * - * @param string $tableName - */ - public function disablePrimaryKeys($tableName) - { - $this->getMetaData()->disablePrimaryKeys($tableName); - } - - /** - * Reenables primary keys after they have been disabled - * - * @param string $tableName - */ - public function enablePrimaryKeys($tableName) - { - $this->getMetaData()->enablePrimaryKeys($tableName); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 access to a database instance as a data set. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_FilteredDataSet extends PHPUnit_Extensions_Database_DB_DataSet -{ - /** - * @var Array - */ - protected $tableNames; - - /** - * Creates a new dataset using the given database connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - */ - public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection, Array $tableNames) - { - parent::__construct($databaseConnection); - $this->tableNames = $tableNames; - } - - /** - * Returns a list of table names for the database - * - * @return Array - */ - public function getTableNames() - { - return $this->tableNames; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for communicating with a database. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DB_IDatabaseConnection -{ - /** - * Close this connection. - */ - public function close(); - - /** - * Creates a dataset containing the specified table names. If no table - * names are specified then it will created a dataset over the entire - * database. - * - * @param array $tableNames - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - public function createDataSet(Array $tableNames = NULL); - - /** - * Creates a table with the result of the specified SQL statement. - * - * @param string $resultName - * @param string $sql - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function createQueryTable($resultName, $sql); - - /** - * Returns a PDO Connection - * - * @return PDO - */ - public function getConnection(); - - /** - * Returns a database metadata object that can be used to retrieve table - * meta data from the database. - * - * @return PHPUnit_Extensions_Database_DB_IMetaData - */ - public function getMetaData(); - - /** - * Returns the number of rows in the given table. You can specify an - * optional where clause to return a subset of the table. - * - * @param string $tableName - * @param string $whereClause - * @param int - */ - public function getRowCount($tableName, $whereClause = NULL); - - /** - * Returns the schema for the connection. - * - * @return string - */ - public function getSchema(); - - /** - * Returns a quoted schema object. (table name, column name, etc) - * - * @param string $object - * @return string - */ - public function quoteSchemaObject($object); - - /** - * Returns the command used to truncate a table. - * - * @return string - */ - public function getTruncateCommand(); - - /** - * Returns true if the connection allows cascading - * - * @return bool - */ - public function allowsCascading(); - - /** - * Disables primary keys if connection does not allow setting them otherwise - * - * @param string $tableName - */ - public function disablePrimaryKeys($tableName); - - /** - * Reenables primary keys after they have been disabled - * - * @param string $tableName - */ - public function enablePrimaryKeys($tableName); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for retreiving metadata from a database. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DB_IMetaData -{ - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames(); - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName); - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName); - - /** - * Returns the name of the default schema. - * - * @return string - */ - public function getSchema(); - - /** - * Returns a quoted schema object. (table name, column name, etc) - * - * @param string $object - * @return string - */ - public function quoteSchemaObject($object); - - /** - * Returns true if the rdbms allows cascading - * - * @return bool - */ - public function allowsCascading(); - - /** - * Disables primary keys if rdbms does not allow setting them otherwise - * - * @param string $tableName - */ - public function disablePrimaryKeys($tableName); - - /** - * Reenables primary keys after they have been disabled - * - * @param string $tableName - */ - public function enablePrimaryKeys($tableName); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic constructor for all meta data classes and a factory for - * generating the appropriate meta data class. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_DB_MetaData implements PHPUnit_Extensions_Database_DB_IMetaData -{ - protected static $metaDataClassMap = [ - 'pgsql' => 'PHPUnit_Extensions_Database_DB_MetaData_PgSQL', - 'mysql' => 'PHPUnit_Extensions_Database_DB_MetaData_MySQL', - 'oci' => 'PHPUnit_Extensions_Database_DB_MetaData_Oci', - 'sqlite' => 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite', - 'sqlite2' => 'PHPUnit_Extensions_Database_DB_MetaData_Sqlite', - 'sqlsrv' => 'PHPUnit_Extensions_Database_DB_MetaData_SqlSrv', - 'firebird' => 'PHPUnit_Extensions_Database_DB_MetaData_Firebird', - 'dblib' => 'PHPUnit_Extensions_Database_DB_MetaData_Dblib' - ]; - - /** - * The PDO connection used to retreive database meta data - * - * @var PDO - */ - protected $pdo; - - /** - * The default schema name for the meta data object. - * - * @var string - */ - protected $schema; - - /** - * The character used to quote schema objects. - */ - protected $schemaObjectQuoteChar = '"'; - - /** - * The command used to perform a TRUNCATE operation. - */ - protected $truncateCommand = 'TRUNCATE'; - - /** - * Creates a new database meta data object using the given pdo connection - * and schema name. - * - * @param PDO $pdo - * @param string $schema - */ - public final function __construct(PDO $pdo, $schema = '') - { - $this->pdo = $pdo; - $this->schema = $schema; - } - - /** - * Creates a meta data object based on the driver of given $pdo object and - * $schema name. - * - * @param PDO $pdo - * @param string $schema - * @return PHPUnit_Extensions_Database_DB_MetaData - */ - public static function createMetaData(PDO $pdo, $schema = '') - { - $driverName = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - if (isset(self::$metaDataClassMap[$driverName])) { - $className = self::$metaDataClassMap[$driverName]; - - if ($className instanceof ReflectionClass) { - return $className->newInstance($pdo, $schema); - } else { - return self::registerClassWithDriver($className, $driverName)->newInstance($pdo, $schema); - } - } else { - throw new PHPUnit_Extensions_Database_Exception("Could not find a meta data driver for {$driverName} pdo driver."); - } - } - - /** - * Validates and registers the given $className with the given $pdoDriver. - * It should be noted that this function will not attempt to include / - * require the file. The $pdoDriver can be determined by the value of the - * PDO::ATTR_DRIVER_NAME attribute for a pdo object. - * - * A reflection of the $className is returned. - * - * @param string $className - * @param string $pdoDriver - * @return ReflectionClass - */ - public static function registerClassWithDriver($className, $pdoDriver) - { - if (!class_exists($className)) { - throw new PHPUnit_Extensions_Database_Exception("Specified class for {$pdoDriver} driver ({$className}) does not exist."); - } - - $reflection = new ReflectionClass($className); - if ($reflection->isSubclassOf('PHPUnit_Extensions_Database_DB_MetaData')) { - return self::$metaDataClassMap[$pdoDriver] = $reflection; - } else { - throw new PHPUnit_Extensions_Database_Exception("Specified class for {$pdoDriver} driver ({$className}) does not extend PHPUnit_Extensions_Database_DB_MetaData."); - } - } - - /** - * Returns the schema for the connection. - * - * @return string - */ - public function getSchema() - { - return $this->schema; - } - - /** - * Returns a quoted schema object. (table name, column name, etc) - * - * @param string $object - * @return string - */ - public function quoteSchemaObject($object) - { - $parts = explode('.', $object); - $quotedParts = []; - - foreach ($parts as $part) { - $quotedParts[] = $this->schemaObjectQuoteChar . - str_replace($this->schemaObjectQuoteChar, $this->schemaObjectQuoteChar . $this->schemaObjectQuoteChar, $part) . - $this->schemaObjectQuoteChar; - } - - return implode('.', $quotedParts); - } - - /** - * Seperates the schema and the table from a fully qualified table name. - * - * Returns an associative array containing the 'schema' and the 'table'. - * - * @param string $fullTableName - * @return array - */ - public function splitTableName($fullTableName) - { - if (($dot = strpos($fullTableName, '.')) !== FALSE) { - return [ - 'schema' => substr($fullTableName, 0, $dot), - 'table' => substr($fullTableName, $dot + 1) - ]; - } else { - return [ - 'schema' => NULL, - 'table' => $fullTableName - ]; - } - } - - /** - * Returns the command for the database to truncate a table. - * - * @return string - */ - public function getTruncateCommand() - { - return $this->truncateCommand; - } - - /** - * Returns true if the rdbms allows cascading - * - * @return bool - */ - public function allowsCascading() - { - return FALSE; - } - - /** - * Disables primary keys if the rdbms does not allow setting them otherwise - * - * @param string $tableName - */ - public function disablePrimaryKeys($tableName) - { - return; - } - - /** - * Reenables primary keys after they have been disabled - * - * @param string $tableName - */ - public function enablePrimaryKeys($tableName) - { - return; - } -} -<?php -/** - * Provides functionality to retrieve meta data from an Dblib (SQL Server) database. - */ -class PHPUnit_Extensions_Database_DB_MetaData_Dblib extends PHPUnit_Extensions_Database_DB_MetaData -{ - /** - * No character used to quote schema objects. - * @var string - */ - protected $schemaObjectQuoteChar = ''; - - /** - * The command used to perform a TRUNCATE operation. - * @var string - */ - protected $truncateCommand = 'TRUNCATE TABLE'; - - /** - * @var array - */ - protected $columns = []; - - /** - * @var array - */ - protected $keys = []; - - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $tableNames = []; - - $query = 'SELECT name - FROM sys.tables - ORDER BY name'; - - $result = $this->pdo->query($query); - - while ($tableName = $result->fetchColumn(0)) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - if (!isset($this->columns[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->columns[$tableName]; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - if (!isset($this->keys[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->keys[$tableName]; - } - - /** - * Loads column info from a sql server database. - * - * @param string $tableName - */ - protected function loadColumnInfo($tableName) - { - $query = "SELECT name - FROM sys.columns - WHERE object_id = OBJECT_ID('" . $tableName . "') - ORDER BY column_id"; - - $result = $this->pdo->query($query); - - while ($columnName = $result->fetchColumn(0)) { - $this->columns[$tableName][] = $columnName; - } - - $keyQuery = "SELECT COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName - FROM sys.indexes AS i INNER JOIN - sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID - AND i.index_id = ic.index_id - WHERE i.is_primary_key = 1 AND OBJECT_NAME(ic.OBJECT_ID) = '" . $tableName . "'"; - - $result = $this->pdo->query($keyQuery); - - while ($columnName = $result->fetchColumn(0)) { - $this->keys[$tableName][] = $columnName; - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from a Firebird database. - * - * @version Release: 1.1.2 - * @since - */ -class PHPUnit_Extensions_Database_DB_MetaData_Firebird extends PHPUnit_Extensions_Database_DB_MetaData -{ - /** - * The command used to perform a TRUNCATE operation. - * @var string - */ - protected $truncateCommand = 'DELETE FROM'; - - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $query = " - SELECT DISTINCT - TABLE_NAME - FROM INFORMATION_SCHEMA.TABLES - WHERE - TABLE_TYPE='BASE TABLE' AND - TABLE_SCHEMA = ? - ORDER BY TABLE_NAME - "; - - $query = " - select - RDB$RELATION_NAME as TABLE_NAME - from RDB$RELATIONS - where - ((RDB$RELATION_TYPE = 0) or - (RDB$RELATION_TYPE is null)) and - (RDB$SYSTEM_FLAG = 0) - order by (RDB$RELATION_NAME) - "; - - $statement = $this->pdo->prepare($query); - $statement->execute([$this->getSchema()]); - - $tableNames = []; - while ($tableName = $statement->fetchColumn(0)) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - if (!isset($this->columns[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->columns[$tableName]; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - if (!isset($this->keys[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->keys[$tableName]; - } - - /** - * Loads column info from a database table. - * - * @param string $tableName - */ - protected function loadColumnInfo($tableName) - { - $this->columns[$tableName] = []; - $this->keys[$tableName] = []; - - $columnQuery = ' - SELECT DISTINCT - COLUMN_NAME, ORDINAL_POSITION - FROM INFORMATION_SCHEMA.COLUMNS - WHERE - TABLE_NAME = ? AND - TABLE_SCHEMA = ? - ORDER BY ORDINAL_POSITION - '; - - $columnQuery = " - select - rf.RDB\$FIELD_NAME as COLUMN_NAME, - rf.RDB\$FIELD_POSITION as ORDINAL_POSITION - from RDB\$RELATION_FIELDS as rf - where - upper(RDB\$RELATION_NAME) = upper(?) - order by - ORDINAL_POSITION - - "; - - $columnStatement = $this->pdo->prepare($columnQuery); - $columnStatement->execute([$tableName]); - - while ($columName = $columnStatement->fetchColumn(0)) { - $this->columns[$tableName][] = $columName; - } - - $keyQuery = " - SELECT - KCU.COLUMN_NAME, - KCU.ORDINAL_POSITION - FROM - INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU - LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC - ON TC.TABLE_NAME = KCU.TABLE_NAME - WHERE - TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND - TC.TABLE_NAME = ? AND - TC.TABLE_SCHEMA = ? - ORDER BY - KCU.ORDINAL_POSITION ASC - "; - - $keyQuery = " - select - idseg.rdb\$field_name as COLUMN_NAME, - idseg.rdb\$field_position as ORDINAL_POSITION, - rc.rdb\$relation_name as tablename, - rc.rdb\$constraint_name as pk_name - from - RDB\$RELATION_CONSTRAINTS AS rc - left join - rdb\$index_segments as idseg on - (rc.rdb\$index_name = idseg.rdb\$index_name) - where - rc.RDB\$CONSTRAINT_TYPE = 'PRIMARY KEY' - and upper(rc.RDB\$RELATION_NAME) = upper(?) - order by - rc.rdb\$constraint_name, idseg.rdb\$field_position - "; - - $keyStatement = $this->pdo->prepare($keyQuery); - $keyStatement->execute([$tableName]); - - while ($columName = $keyStatement->fetchColumn(0)) { - $this->keys[$tableName][] = $columName; - } - } - - /** - * Returns the schema for the connection. - * - * @return string - */ - public function getSchema() - { - if (empty($this->schema)) { - return 'public'; - } else { - return $this->schema; - } - } - - /** - * Returns true if the rdbms allows cascading - * - * @return bool - */ - public function allowsCascading() - { - return false; - } - - /** - * Returns a quoted schema object. (table name, column name, etc) - * - * @param string $object - * @return string - */ - public function quoteSchemaObject($object) { - return $object; //firebird does not allow object quoting - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from a database with information_schema support. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_MetaData_InformationSchema extends PHPUnit_Extensions_Database_DB_MetaData -{ - protected $columns = []; - - protected $keys = []; - - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $query = " - SELECT DISTINCT - TABLE_NAME - FROM INFORMATION_SCHEMA.TABLES - WHERE - TABLE_TYPE='BASE TABLE' AND - TABLE_SCHEMA = ? - ORDER BY TABLE_NAME - "; - - $statement = $this->pdo->prepare($query); - $statement->execute([$this->getSchema()]); - - $tableNames = []; - while ($tableName = $statement->fetchColumn(0)) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - if (!isset($this->columns[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->columns[$tableName]; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - if (!isset($this->keys[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->keys[$tableName]; - } - - /** - * Loads column info from a sqlite database. - * - * @param string $tableName - */ - protected function loadColumnInfo($tableName) - { - $this->columns[$tableName] = []; - $this->keys[$tableName] = []; - - $columnQuery = ' - SELECT DISTINCT - COLUMN_NAME - FROM INFORMATION_SCHEMA.COLUMNS - WHERE - TABLE_NAME = ? AND - TABLE_SCHEMA = ? - ORDER BY ORDINAL_POSITION - '; - - $columnStatement = $this->pdo->prepare($columnQuery); - $columnStatement->execute([$tableName, $this->getSchema()]); - - while ($columName = $columnStatement->fetchColumn(0)) { - $this->columns[$tableName][] = $columName; - } - - $keyQuery = " - SELECT - KCU.COLUMN_NAME - FROM - INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC, - INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU - WHERE - TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND - TC.TABLE_NAME = KCU.TABLE_NAME AND - TC.TABLE_SCHEMA = KCU.TABLE_SCHEMA AND - TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND - TC.TABLE_NAME = ? AND - TC.TABLE_SCHEMA = ? - ORDER BY - KCU.ORDINAL_POSITION ASC - "; - - $keyStatement = $this->pdo->prepare($keyQuery); - $keyStatement->execute([$tableName, $this->getSchema()]); - - while ($columName = $keyStatement->fetchColumn(0)) { - $this->keys[$tableName][] = $columName; - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from a MySQL database. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_MetaData_MySQL extends PHPUnit_Extensions_Database_DB_MetaData -{ - protected $schemaObjectQuoteChar = '`'; - - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $query = 'SHOW TABLES'; - $statement = $this->pdo->prepare($query); - $statement->execute(); - - $tableNames = []; - while (($tableName = $statement->fetchColumn(0))) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - $query = 'SHOW COLUMNS FROM ' . $this->quoteSchemaObject($tableName); - $statement = $this->pdo->prepare($query); - $statement->execute(); - - $columnNames = []; - while (($columnName = $statement->fetchColumn(0))) { - $columnNames[] = $columnName; - } - - return $columnNames; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - $query = 'SHOW INDEX FROM ' . $this->quoteSchemaObject($tableName); - $statement = $this->pdo->prepare($query); - $statement->execute(); - $statement->setFetchMode(PDO::FETCH_ASSOC); - - $columnNames = []; - while (($column = $statement->fetch())) { - if ($column['Key_name'] == 'PRIMARY') { - $columnNames[] = $column['Column_name']; - } - } - - return $columnNames; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from an Oracle database. - * - * @since Class available since Release 3.2.3 - */ -class PHPUnit_Extensions_Database_DB_MetaData_Oci extends PHPUnit_Extensions_Database_DB_MetaData -{ - /** - * No character used to quote schema objects. - * @var string - */ - protected $schemaObjectQuoteChar = ''; - - /** - * The command used to perform a TRUNCATE operation. - * @var string - */ - protected $truncateCommand = 'TRUNCATE TABLE'; - - /** - * @var array - */ - protected $columns = []; - - /** - * @var array - */ - protected $keys = []; - - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $tableNames = []; - - $query = "SELECT table_name - FROM cat - WHERE table_type='TABLE' - ORDER BY table_name"; - - $result = $this->pdo->query($query); - - while ($tableName = $result->fetchColumn(0)) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - if (!isset($this->columns[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->columns[$tableName]; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - if (!isset($this->keys[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->keys[$tableName]; - } - - /** - * Loads column info from a oracle database. - * - * @param string $tableName - */ - protected function loadColumnInfo($tableName) - { - $ownerQuery = ''; - $conOwnerQuery = ''; - $tableParts = $this->splitTableName($tableName); - - $this->columns[$tableName] = []; - $this->keys[$tableName] = []; - - if (!empty($tableParts['schema'])) - { - $ownerQuery = " AND OWNER = '{$tableParts['schema']}'"; - $conOwnerQuery = " AND a.owner = '{$tableParts['schema']}'"; - } - - $query = "SELECT DISTINCT COLUMN_NAME - FROM USER_TAB_COLUMNS - WHERE TABLE_NAME='" . $tableParts['table'] . "' - $ownerQuery - ORDER BY COLUMN_NAME"; - - $result = $this->pdo->query($query); - - while ($columnName = $result->fetchColumn(0)) { - $this->columns[$tableName][] = $columnName; - } - - $keyQuery = "SELECT b.column_name - FROM user_constraints a, user_cons_columns b - WHERE a.constraint_type='P' - AND a.constraint_name=b.constraint_name - $conOwnerQuery - AND a.table_name = '" . $tableParts['table'] . "' "; - - $result = $this->pdo->query($keyQuery); - - while ($columnName = $result->fetchColumn(0)) { - $this->keys[$tableName][] = $columnName; - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from a PostgreSQL database. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_MetaData_PgSQL extends PHPUnit_Extensions_Database_DB_MetaData -{ - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $query = " - SELECT DISTINCT - TABLE_NAME - FROM INFORMATION_SCHEMA.TABLES - WHERE - TABLE_TYPE='BASE TABLE' AND - TABLE_SCHEMA = ? - ORDER BY TABLE_NAME - "; - - $statement = $this->pdo->prepare($query); - $statement->execute([$this->getSchema()]); - - $tableNames = []; - while ($tableName = $statement->fetchColumn(0)) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - if (!isset($this->columns[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->columns[$tableName]; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - if (!isset($this->keys[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->keys[$tableName]; - } - - /** - * Loads column info from a database table. - * - * @param string $tableName - */ - protected function loadColumnInfo($tableName) - { - $this->columns[$tableName] = []; - $this->keys[$tableName] = []; - - $columnQuery = ' - SELECT DISTINCT - COLUMN_NAME, ORDINAL_POSITION - FROM INFORMATION_SCHEMA.COLUMNS - WHERE - TABLE_NAME = ? AND - TABLE_SCHEMA = ? - ORDER BY ORDINAL_POSITION - '; - - $columnStatement = $this->pdo->prepare($columnQuery); - $columnStatement->execute([$tableName, $this->getSchema()]); - - while ($columName = $columnStatement->fetchColumn(0)) { - $this->columns[$tableName][] = $columName; - } - - $keyQuery = " - SELECT - KCU.COLUMN_NAME, - KCU.ORDINAL_POSITION - FROM - INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU - LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC - ON TC.TABLE_NAME = KCU.TABLE_NAME AND - TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME - WHERE - TC.CONSTRAINT_TYPE = 'PRIMARY KEY' AND - TC.TABLE_NAME = ? AND - TC.TABLE_SCHEMA = ? - ORDER BY - KCU.ORDINAL_POSITION ASC - "; - - $keyStatement = $this->pdo->prepare($keyQuery); - $keyStatement->execute([$tableName, $this->getSchema()]); - - while ($columName = $keyStatement->fetchColumn(0)) { - $this->keys[$tableName][] = $columName; - } - } - - /** - * Returns the schema for the connection. - * - * @return string - */ - public function getSchema() - { - if (empty($this->schema)) { - return 'public'; - } else { - return $this->schema; - } - } - - /** - * Returns true if the rdbms allows cascading - * - * @return bool - */ - public function allowsCascading() - { - return TRUE; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from a Microsoft SQL Server database. - * - * @since Class available since Release 1.1.0 - */ -class PHPUnit_Extensions_Database_DB_MetaData_SqlSrv extends PHPUnit_Extensions_Database_DB_MetaData -{ - /** - * No character used to quote schema objects. - * @var string - */ - protected $schemaObjectQuoteChar = ''; - - /** - * The command used to perform a TRUNCATE operation. - * @var string - */ - protected $truncateCommand = 'TRUNCATE TABLE'; - - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $query = "SELECT name - FROM sysobjects - WHERE type='U'"; - - $statement = $this->pdo->prepare($query); - $statement->execute(); - - $tableNames = []; - while (($tableName = $statement->fetchColumn(0))) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - $query = "SELECT c.name - FROM syscolumns c - LEFT JOIN sysobjects o ON c.id = o.id - WHERE o.name = '$tableName'"; - - $statement = $this->pdo->prepare($query); - $statement->execute(); - - $columnNames = []; - while (($columnName = $statement->fetchColumn(0))) { - $columnNames[] = $columnName; - } - - return $columnNames; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - $query = "EXEC sp_statistics '$tableName'"; - $statement = $this->pdo->prepare($query); - $statement->execute(); - $statement->setFetchMode(PDO::FETCH_ASSOC); - - $columnNames = []; - while (($column = $statement->fetch())) { - if ($column['TYPE'] == 1) { - $columnNames[] = $column['COLUMN_NAME']; - } - } - - return $columnNames; - } - - /** - * Allow overwriting identities for the given table. - * - * @param string $tableName - */ - public function disablePrimaryKeys($tableName) - { - try { - $query = "SET IDENTITY_INSERT $tableName ON"; - $this->pdo->exec($query); - } - catch (PDOException $e) { - // ignore the error here - can happen if primary key is not an identity - } - } - - /** - * Reenable auto creation of identities for the given table. - * - * @param string $tableName - */ - public function enablePrimaryKeys($tableName) - { - try { - $query = "SET IDENTITY_INSERT $tableName OFF"; - $this->pdo->exec($query); - } - catch (PDOException $e) { - // ignore the error here - can happen if primary key is not an identity - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 functionality to retrieve meta data from an Sqlite database. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_MetaData_Sqlite extends PHPUnit_Extensions_Database_DB_MetaData -{ - protected $columns = []; - - protected $keys = []; - - protected $truncateCommand = 'DELETE FROM'; - /** - * Returns an array containing the names of all the tables in the database. - * - * @return array - */ - public function getTableNames() - { - $query = " - SELECT name - FROM sqlite_master - WHERE - type='table' AND - name <> 'sqlite_sequence' - ORDER BY name - "; - - $result = $this->pdo->query($query); - - $tableNames = []; - - while ($tableName = $result->fetchColumn(0)) { - $tableNames[] = $tableName; - } - - return $tableNames; - } - - /** - * Returns an array containing the names of all the columns in the - * $tableName table, - * - * @param string $tableName - * @return array - */ - public function getTableColumns($tableName) - { - if (!isset($this->columns[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->columns[$tableName]; - } - - /** - * Returns an array containing the names of all the primary key columns in - * the $tableName table. - * - * @param string $tableName - * @return array - */ - public function getTablePrimaryKeys($tableName) - { - if (!isset($this->keys[$tableName])) { - $this->loadColumnInfo($tableName); - } - - return $this->keys[$tableName]; - } - - /** - * Loads column info from a sqlite database. - * - * @param string $tableName - */ - protected function loadColumnInfo($tableName) - { - $query = "PRAGMA table_info('{$tableName}')"; - $statement = $this->pdo->query($query); - - /* @var $statement PDOStatement */ - $this->columns[$tableName] = []; - $this->keys[$tableName] = []; - - while ($columnData = $statement->fetch(PDO::FETCH_NUM)) { - $this->columns[$tableName][] = $columnData[1]; - - if ($columnData[5] == 1) { - $this->keys[$tableName][] = $columnData[1]; - } - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 the functionality to represent a database result set as a DBUnit - * table. - * - * @deprecated The PHPUnit_Extension_Database_DataSet_QueryTable should be used instead - * @see PHPUnit_Extension_Database_DataSet_QueryTable - * @see PHPUnit_Extension_Database_DataSet_QueryDataSet - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_ResultSetTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable -{ - /** - * Creates a new result set table. - * - * @param string $tableName - * @param PDOStatement $pdoStatement - */ - public function __construct($tableName, PDOStatement $pdoStatement) - { - $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC); - - if (count($this->data)) { - $columns = array_keys($this->data[0]); - } else { - $columns = []; - } - - $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns)); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 the functionality to represent a database table. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_Table extends PHPUnit_Extensions_Database_DataSet_AbstractTable -{ - /** - * Creates a new database table object. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) - { - $this->setTableMetaData($tableMetaData); - - $pdoStatement = $databaseConnection->getConnection()->prepare(PHPUnit_Extensions_Database_DB_DataSet::buildTableSelect($tableMetaData, $databaseConnection)); - $pdoStatement->execute(); - $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 iterative access to tables from a database instance. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_TableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator -{ - /** - * An array of tablenames. - * - * @var Array - */ - protected $tableNames; - - /** - * If this property is true then the tables will be iterated in reverse - * order. - * - * @var bool - */ - protected $reverse; - - /** - * The database dataset that this iterator iterates over. - * - * @var PHPUnit_Extensions_Database_DB_DataSet - */ - protected $dataSet; - - public function __construct($tableNames, PHPUnit_Extensions_Database_DB_DataSet $dataSet, $reverse = FALSE) - { - $this->tableNames = $tableNames; - $this->dataSet = $dataSet; - $this->reverse = $reverse; - - $this->rewind(); - } - - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function getTable() - { - return $this->current(); - } - - /** - * Returns the current table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData() - { - return $this->current()->getTableMetaData(); - } - - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function current() - { - $tableName = current($this->tableNames); - - return $this->dataSet->getTable($tableName); - } - - /** - * Returns the name of the current table. - * - * @return string - */ - public function key() - { - return $this->current()->getTableMetaData()->getTableName(); - } - - /** - * advances to the next element. - */ - public function next() - { - if ($this->reverse) { - prev($this->tableNames); - } else { - next($this->tableNames); - } - } - - /** - * Rewinds to the first element - */ - public function rewind() - { - if ($this->reverse) { - end($this->tableNames); - } else { - reset($this->tableNames); - } - } - - /** - * Returns true if the current index is valid - * - * @return bool - */ - public function valid() - { - return (current($this->tableNames) !== FALSE); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * This class loads a table metadata object with database metadata. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DB_TableMetaData extends PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData -{ - public function __construct($tableName, PHPUnit_Extensions_Database_DB_IMetaData $databaseMetaData) - { - $this->tableName = $tableName; - $this->columns = $databaseMetaData->getTableColumns($tableName); - $this->primaryKeys = $databaseMetaData->getTablePrimaryKeys($tableName); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Implements the basic functionality of data sets. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_DataSet_AbstractDataSet implements PHPUnit_Extensions_Database_DataSet_IDataSet -{ - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected abstract function createIterator($reverse = FALSE); - - /** - * Returns an array of table names contained in the dataset. - * - * @return array - */ - public function getTableNames() - { - $tableNames = []; - - foreach ($this->getIterator() as $table) { - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - $tableNames[] = $table->getTableMetaData()->getTableName(); - } - - return $tableNames; - } - - /** - * Returns a table meta data object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData($tableName) - { - return $this->getTable($tableName)->getTableMetaData(); - } - - /** - * Returns a table object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function getTable($tableName) - { - foreach ($this->getIterator() as $table) { - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - if ($table->getTableMetaData()->getTableName() == $tableName) { - return $table; - } - } - } - - /** - * Returns an iterator for all table objects in the given dataset. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - public function getIterator() - { - return $this->createIterator(); - } - - /** - * Returns a reverse iterator for all table objects in the given dataset. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - public function getReverseIterator() - { - return $this->createIterator(TRUE); - } - - /** - * Asserts that the given data set matches this data set. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other) - { - $thisTableNames = $this->getTableNames(); - $otherTableNames = $other->getTableNames(); - - sort($thisTableNames); - sort($otherTableNames); - - if ($thisTableNames != $otherTableNames) { - return FALSE; - } - - foreach ($thisTableNames as $tableName) { - $table = $this->getTable($tableName); - - if (!$table->matches($other->getTable($tableName))) { - return FALSE; - } - } - - return TRUE; - } - - public function __toString() - { - $iterator = $this->getIterator(); - - $dataSetString = ''; - foreach ($iterator as $table) { - $dataSetString .= $table->__toString(); - } - - return $dataSetString; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic functionality for dbunit tables - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_AbstractTable implements PHPUnit_Extensions_Database_DataSet_ITable -{ - /** - * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - protected $tableMetaData; - - /** - * A 2-dimensional array containing the data for this table. - * - * @var array - */ - protected $data; - - /** - * @var PHPUnit_Extensions_Database_DataSet_ITable|null - */ - private $other; - - /** - * Sets the metadata for this table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData - * @deprecated - */ - protected function setTableMetaData(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData) - { - $this->tableMetaData = $tableMetaData; - } - - /** - * Returns the table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData() - { - return $this->tableMetaData; - } - - /** - * Returns the number of rows in this table. - * - * @return int - */ - public function getRowCount() - { - return count($this->data); - } - - /** - * Returns the value for the given column on the given row. - * - * @param int $row - * @param int $column - * @todo reorganize this function to throw the exception first. - */ - public function getValue($row, $column) - { - if (isset($this->data[$row][$column])) { - $value = $this->data[$row][$column]; - - return ($value instanceof SimpleXMLElement) ? (string) $value : $value; - } else { - if (!in_array($column, $this->getTableMetaData()->getColumns()) || $this->getRowCount() <= $row) { - throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}"); - } else { - return NULL; - } - } - } - - /** - * Returns the an associative array keyed by columns for the given row. - * - * @param int $row - * @return array - */ - public function getRow($row) - { - if (isset($this->data[$row])) { - return $this->data[$row]; - } else { - if ($this->getRowCount() <= $row) { - throw new InvalidArgumentException("The given row ({$row}) does not exist in table {$this->getTableMetaData()->getTableName()}"); - } else { - return NULL; - } - } - } - - /** - * Asserts that the given table matches this table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other) - { - $thisMetaData = $this->getTableMetaData(); - $otherMetaData = $other->getTableMetaData(); - - if (!$thisMetaData->matches($otherMetaData) || - $this->getRowCount() != $other->getRowCount()) { - return FALSE; - } - - $columns = $thisMetaData->getColumns(); - $rowCount = $this->getRowCount(); - - for ($i = 0; $i < $rowCount; $i++) { - foreach ($columns as $columnName) { - $thisValue = $this->getValue($i, $columnName); - $otherValue = $other->getValue($i, $columnName); - if (is_numeric($thisValue) && is_numeric($otherValue)) { - if ($thisValue != $otherValue) { - $this->other = $other; - - return FALSE; - } - } elseif ($thisValue !== $otherValue) { - $this->other = $other; - - return FALSE; - } - } - } - - return TRUE; - } - - /** - * Checks if a given row is in the table - * - * @param array $row - * - * @return bool - */ - public function assertContainsRow(array $row) - { - return in_array($row, $this->data); - } - - public function __toString() - { - $columns = $this->getTableMetaData()->getColumns(); - $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n"; - $lineLength = strlen($lineSeperator) - 1; - - $tableString = $lineSeperator; - $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n"; - $tableString .= $lineSeperator; - $tableString .= $this->rowToString($columns); - $tableString .= $lineSeperator; - - $rowCount = $this->getRowCount(); - - for ($i = 0; $i < $rowCount; $i++) { - $values = []; - - foreach ($columns as $columnName) { - if ($this->other) { - try { - if ($this->getValue($i, $columnName) != $this->other->getValue($i, $columnName)) { - $values[] = sprintf( - '%s != actual %s', - var_export($this->getValue($i, $columnName), TRUE), - var_export($this->other->getValue($i, $columnName), TRUE) - ); - } else { - $values[] = $this->getValue($i, $columnName); - } - } catch (\InvalidArgumentException $ex) { - $values[] = $this->getValue($i, $columnName) . ': no row'; - } - } else { - $values[] = $this->getValue($i, $columnName); - } - } - - $tableString .= $this->rowToString($values) . $lineSeperator; - } - - return ($this->other ? '(table diff enabled)' : '') . "\n" . $tableString . "\n"; - } - - protected function rowToString(Array $row) - { - $rowString = ''; - - foreach ($row as $value) { - if (is_null($value)) { - $value = 'NULL'; - } - - $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' '; - } - - return $rowString . "|\n"; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 basic functionality for table meta data. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData implements PHPUnit_Extensions_Database_DataSet_ITableMetaData -{ - /** - * The names of all columns in the table. - * - * @var Array - */ - protected $columns; - - /** - * The names of all the primary keys in the table. - * - * @var Array - */ - protected $primaryKeys; - - /** - * @var string - */ - protected $tableName; - - /** - * Returns the names of the columns in the table. - * - * @return array - */ - public function getColumns() - { - return $this->columns; - } - - /** - * Returns the names of the primary key columns in the table. - * - * @return array - */ - public function getPrimaryKeys() - { - return $this->primaryKeys; - } - - /** - * Returns the name of the table. - * - * @return string - */ - public function getTableName() - { - return $this->tableName; - } - - /** - * Asserts that the given tableMetaData matches this tableMetaData. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other) - { - if ($this->getTableName() != $other->getTableName() || - $this->getColumns() != $other->getColumns()) { - return FALSE; - } - - return TRUE; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default implementation of a data set. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * @var array - */ - protected $tables; - - /** - * @var SimpleXmlElement - */ - protected $xmlFileContents; - - /** - * Creates a new dataset using the given tables. - * - * @param array $tables - */ - public function __construct($xmlFile) - { - if (!is_file($xmlFile)) { - throw new InvalidArgumentException( - "Could not find xml file: {$xmlFile}" - ); - } - - $libxmlErrorReporting = libxml_use_internal_errors(TRUE); - $this->xmlFileContents = simplexml_load_file($xmlFile, 'SimpleXMLElement', LIBXML_COMPACT | LIBXML_PARSEHUGE); - - if (!$this->xmlFileContents) { - $message = ''; - - foreach (libxml_get_errors() as $error) { - $message .= print_r($error, true); - } - - throw new RuntimeException($message); - } - - libxml_clear_errors(); - libxml_use_internal_errors($libxmlErrorReporting); - - $tableColumns = []; - $tableValues = []; - - $this->getTableInfo($tableColumns, $tableValues); - $this->createTables($tableColumns, $tableValues); - } - - /** - * Reads the simple xml object and creates the appropriate tables and meta - * data for this dataset. - */ - protected abstract function getTableInfo(Array &$tableColumns, Array &$tableValues); - - protected function createTables(Array &$tableColumns, Array &$tableValues) - { - foreach ($tableValues as $tableName => $values) { - $table = $this->getOrCreateTable($tableName, $tableColumns[$tableName]); - foreach ($values as $value) { - $table->addRow($value); - } - } - } - - /** - * Returns the table with the matching name. If the table does not exist - * an empty one is created. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - protected function getOrCreateTable($tableName, $tableColumns) - { - if (empty($this->tables[$tableName])) { - $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $tableColumns); - $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable($tableMetaData); - } - - return $this->tables[$tableName]; - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Implements the basic functionality of data sets using a PHP array. - * - * @since Class available since Release 1.3.2 - */ -class PHPUnit_Extensions_Database_DataSet_ArrayDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * @var array - */ - protected $tables = []; - - /** - * Constructor to build a new ArrayDataSet with the given array. - * The array parameter is an associative array of tables where the key is - * the table name and the value an array of rows. Each row is an associative - * array by itself with keys representing the field names and the values the - * actual data. - * For example: - * array( - * "addressbook" => array( - * array("id" => 1, "name" => "...", "address" => "..."), - * array("id" => 2, "name" => "...", "address" => "...") - * ) - * ) - * - * @param array $data - */ - public function __construct(array $data) - { - foreach ($data AS $tableName => $rows) { - $columns = []; - if (isset($rows[0])) { - $columns = array_keys($rows[0]); - } - - $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns); - $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData); - - foreach ($rows AS $row) { - $table->addRow($row); - } - $this->tables[$tableName] = $table; - } - } - - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); - } - - public function getTable($tableName) - { - if (!isset($this->tables[$tableName])) { - throw new InvalidArgumentException("$tableName is not a table in the current database."); - } - - return $this->tables[$tableName]; - } -} -?><?php -/* - * This file is part of DBUnit. - * - * (c) 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 Composite Datasets - * - * Allows for creating datasets from multiple sources (csv, query, xml, etc.) - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_CompositeDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - protected $motherDataSet; - - /** - * Creates a new Composite dataset - * - * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet - * - * @param string $delimiter - * @param string $enclosure - * @param string $escape - */ - public function __construct(Array $dataSets = []) - { - $this->motherDataset = new PHPUnit_Extensions_Database_DataSet_DefaultDataSet(); - - foreach ($dataSets as $dataSet) - { - $this->addDataSet($dataSet); - } - } - - /** - * Adds a new data set to the composite. - * - * The dataset may not define tables that already exist in the composite. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function addDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - foreach ($dataSet->getTableNames() as $tableName) - { - if (!in_array($tableName, $this->getTableNames())) { - $this->motherDataset->addTable($dataSet->getTable($tableName)); - } else { - $other = $dataSet->getTable($tableName); - $table = $this->getTable($tableName); - - if (!$table->getTableMetaData()->matches($other->getTableMetaData())) - { - throw new InvalidArgumentException("There is already a table named $tableName with different table definition"); - } - - $table->addTableRows($dataSet->getTable($tableName)); - } - } - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - if ($reverse) { - return $this->motherDataset->getReverseIterator(); - } else { - return $this->motherDataset->getIterator(); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 CsvDataSets. - * - * You can incrementally add CSV files as tables to your datasets - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_CsvDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * @var array - */ - protected $tables = []; - - /** - * @var string - */ - protected $delimiter = ','; - - /** - * @var string - */ - protected $enclosure = '"'; - - /** - * @var string - */ - protected $escape = '"'; - - /** - * Creates a new CSV dataset - * - * You can pass in the parameters for how csv files will be read. - * - * @param string $delimiter - * @param string $enclosure - * @param string $escape - */ - public function __construct($delimiter = ',', $enclosure = '"', $escape = '"') - { - $this->delimiter = $delimiter; - $this->enclosure = $enclosure; - $this->escape = $escape; - } - - /** - * Adds a table to the dataset - * - * The table will be given the passed name. $csvFile should be a path to - * a valid csv file (based on the arguments passed to the constructor.) - * - * @param string $tableName - * @param string $csvFile - */ - public function addTable($tableName, $csvFile) - { - if (!is_file($csvFile)) { - throw new InvalidArgumentException("Could not find csv file: {$csvFile}"); - } - - if (!is_readable($csvFile)) { - throw new InvalidArgumentException("Could not read csv file: {$csvFile}"); - } - - $fh = fopen($csvFile, 'r'); - $columns = $this->getCsvRow($fh); - - if ($columns === FALSE) - { - throw new InvalidArgumentException("Could not determine the headers from the given file {$csvFile}"); - } - - $metaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($tableName, $columns); - $table = new PHPUnit_Extensions_Database_DataSet_DefaultTable($metaData); - - while (($row = $this->getCsvRow($fh)) !== FALSE) - { - $table->addRow(array_combine($columns, $row)); - } - - $this->tables[$tableName] = $table; - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); - } - - /** - * Returns a row from the csv file in an indexed array. - * - * @param resource $fh - * @return array - */ - protected function getCsvRow($fh) - { - if (version_compare(PHP_VERSION, '5.3.0', '>')) { - return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure, $this->escape); - } else { - return fgetcsv($fh, NULL, $this->delimiter, $this->enclosure); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 dataset decorator that allows filtering out tables and table columns from - * results. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_DataSetFilter extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * The dataset being decorated. - * @var PHPUnit_Extensions_Database_DataSet_IDataSet - */ - protected $originalDataSet; - - /** - * The tables to exclude from the data set. - * @var Array - */ - protected $excludeTables = []; - - /** - * The tables to exclude from the data set. - * @var Array - */ - protected $includeTables = []; - - /** - * The columns to exclude from the data set. - * @var Array - */ - protected $excludeColumns = []; - - /** - * The columns to exclude from the data set. - * @var Array - */ - protected $includeColumns = []; - - /** - * Creates a new filtered data set. - * - * The $exclude tables should be an associative array using table names as - * the key and an array of column names to exclude for the value. If you - * would like to exclude a full table set the value of the table's entry - * to the special string '*'. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet - * @param Array $excludeTables @deprecated use set* methods instead. - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $originalDataSet, array $excludeTables = []) - { - $this->originalDataSet = $originalDataSet; - - $tables = []; - foreach ($excludeTables as $tableName => $values) { - if (is_array($values)) { - $this->setExcludeColumnsForTable($tableName, $values); - } elseif ($values == '*') { - $tables[] = $tableName; - } else { - $this->setExcludeColumnsForTable($tableName, (array) $values); - } - } - - $this->addExcludeTables($tables); - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - $original_tables = $this->originalDataSet->getIterator($reverse); - $new_tables = []; - - foreach ($original_tables as $table) { - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - $tableName = $table->getTableMetaData()->getTableName(); - - if ((!in_array($tableName, $this->includeTables) && !empty($this->includeTables)) || - in_array($tableName, $this->excludeTables) - ) { - continue; - } elseif (!empty($this->excludeColumns[$tableName]) || !empty($this->includeColumns[$tableName])) { - $new_table = new PHPUnit_Extensions_Database_DataSet_TableFilter($table); - - if (!empty($this->includeColumns[$tableName])) { - $new_table->addIncludeColumns($this->includeColumns[$tableName]); - } - - if (!empty($this->excludeColumns[$tableName])) { - $new_table->addExcludeColumns($this->excludeColumns[$tableName]); - } - - $new_tables[] = $new_table; - } else { - $new_tables[] = $table; - } - } - - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($new_tables); - } - - /** - * Adds tables to be included in the data set. - * @param array $tables - */ - public function addIncludeTables(Array $tables) - { - $this->includeTables = array_unique(array_merge($this->includeTables, $tables)); - } - - /** - * Adds tables to be included in the data set. - * @param array $tables - */ - public function addExcludeTables(Array $tables) - { - $this->excludeTables = array_unique(array_merge($this->excludeTables, $tables)); - } - - /** - * Adds columns to include in the data set for the given table. - * @param string $table - * @param Array $columns - */ - public function setIncludeColumnsForTable($table, Array $columns) - { - $this->includeColumns[$table] = $columns; - } - - /** - * Adds columns to include in the data set for the given table. - * @param string $table - * @param Array $columns - */ - public function setExcludeColumnsForTable($table, Array $columns) - { - $this->excludeColumns[$table] = $columns; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default implementation of a data set. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_DefaultDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * An array of ITable objects. - * - * @var array - */ - protected $tables; - - /** - * Creates a new dataset using the given tables. - * - * @param array $tables - */ - public function __construct(Array $tables = []) - { - $this->tables = $tables; - } - - /** - * Adds a table to the dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - public function addTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - $this->tables[] = $table; - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default table functionality. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_DefaultTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable -{ - /** - * Creates a new table object using the given $tableMetaData - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $tableMetaData) - { - $this->setTableMetaData($tableMetaData); - $this->data = []; - } - - /** - * Adds a row to the table with optional values. - * - * @param array $values - */ - public function addRow($values = []) - { - $this->data[] = array_replace( - array_fill_keys($this->getTableMetaData()->getColumns(), NULL), - $values - ); - } - - /** - * Adds the rows in the passed table to the current table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - public function addTableRows(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - $tableColumns = $this->getTableMetaData()->getColumns(); - $rowCount = $table->getRowCount(); - - for ($i = 0; $i < $rowCount; $i++) { - $newRow = []; - foreach ($tableColumns as $columnName) { - $newRow[$columnName] = $table->getValue($i, $columnName); - } - $this->addRow($newRow); - } - } - - /** - * Sets the specified column of the specied row to the specified value. - * - * @param int $row - * @param string $column - * @param mixed $value - */ - public function setValue($row, $column, $value) - { - if (isset($this->data[$row])) { - $this->data[$row][$column] = $value; - } else { - throw new InvalidArgumentException('The row given does not exist.'); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default table iterator - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_DefaultTableIterator implements PHPUnit_Extensions_Database_DataSet_ITableIterator -{ - /** - * An array of tables in the iterator. - * - * @var Array - */ - protected $tables; - - /** - * If this property is true then the tables will be iterated in reverse - * order. - * - * @var bool - */ - protected $reverse; - - /** - * Creates a new default table iterator object. - * - * @param array $tables - * @param bool $reverse - */ - public function __construct(Array $tables, $reverse = FALSE) - { - $this->tables = $tables; - $this->reverse = $reverse; - - $this->rewind(); - } - - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function getTable() - { - return $this->current(); - } - - /** - * Returns the current table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData() - { - return $this->current()->getTableMetaData(); - } - - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function current() - { - return current($this->tables); - } - - /** - * Returns the name of the current table. - * - * @return string - */ - public function key() - { - return $this->current()->getTableMetaData()->getTableName(); - } - - /** - * advances to the next element. - */ - public function next() - { - if ($this->reverse) { - prev($this->tables); - } else { - next($this->tables); - } - } - - /** - * Rewinds to the first element - */ - public function rewind() - { - if ($this->reverse) { - end($this->tables); - } else { - reset($this->tables); - } - } - - /** - * Returns true if the current index is valid - * - * @return bool - */ - public function valid() - { - return ($this->current() !== FALSE); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default implementation of table meta data - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData -{ - /** - * Creates a new default table meta data object. - * - * @param string $tableName - * @param array $columns - * @param array $primaryKeys - */ - public function __construct($tableName, Array $columns, Array $primaryKeys = []) - { - $this->tableName = $tableName; - $this->columns = $columns; - $this->primaryKeys = []; - - foreach ($primaryKeys as $columnName) { - if (!in_array($columnName, $this->columns)) { - throw new InvalidArgumentException('Primary key column passed that is not in the column list.'); - } else { - $this->primaryKeys[] = $columnName; - } - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default implementation of a data set. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet -{ - protected function getTableInfo(Array &$tableColumns, Array &$tableValues) - { - if ($this->xmlFileContents->getName() != 'dataset') { - throw new PHPUnit_Extensions_Database_Exception('The root element of a flat xml data set file must be called <dataset>'); - } - - foreach ($this->xmlFileContents->children() as $row) { - $tableName = $row->getName(); - - if (!isset($tableColumns[$tableName])) { - $tableColumns[$tableName] = []; - $tableValues[$tableName] = []; - } - - $values = []; - foreach ($row->attributes() as $name => $value) { - if (!in_array($name, $tableColumns[$tableName])) { - $tableColumns[$tableName][] = $name; - } - - $values[$name] = $value; - } - - if (count($values)) { - $tableValues[$tableName][] = $values; - } - } - } - - public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) - { - $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml(); - $pers->setFileName($filename); - - try { - $pers->write($dataset); - } catch (RuntimeException $e) { - throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.'); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for creating and reading data from data sets. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_IDataSet extends IteratorAggregate -{ - /** - * Returns an array of table names contained in the dataset. - * - * @return array - */ - public function getTableNames(); - - /** - * Returns a table meta data object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData($tableName); - - /** - * Returns a table object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function getTable($tableName); - - /** - * Returns a reverse iterator for all table objects in the given dataset. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - public function getReverseIterator(); - - /** - * Asserts that the given data set matches this data set. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_IDataSet $other); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 for persisting datasets - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_IPersistable -{ - /** - * Writes the given dataset - * - * The previous dataset will be overwritten. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 an interface for creating data sets from data set spec strings. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_ISpec -{ - /** - * Creates a data set from a data set spec string. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - public function getDataSet($dataSetSpec); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for creating and reading data from data sets. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_ITable -{ - /** - * Returns the table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData(); - - /** - * Returns the number of rows in this table. - * - * @return int - */ - public function getRowCount(); - - /** - * Returns the value for the given column on the given row. - * - * @param int $row - * @param int $column - */ - public function getValue($row, $column); - - /** - * Returns the an associative array keyed by columns for the given row. - * - * @param int $row - * @return array - */ - public function getRow($row); - - /** - * Asserts that the given table matches this table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for creating and reading data from data sets. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_ITableIterator extends Iterator -{ - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function getTable(); - - /** - * Returns the current table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData(); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface for returning table meta data. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_ITableMetaData -{ - /** - * Returns the names of the columns in the table. - * - * @return array - */ - public function getColumns(); - - /** - * Returns the names of the primary key columns in the table. - * - * @return array - */ - public function getPrimaryKeys(); - - /** - * Returns the name of the table. - * - * @return string - */ - public function getTableName(); - - /** - * Asserts that the given tableMetaData matches this tableMetaData. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_ITableMetaData $other); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 for parsing YAML files. - * - * @since Class available since Release 1.3.1 - */ -interface PHPUnit_Extensions_Database_DataSet_IYamlParser { - /** - * @param string $yamlFile - * @return array parsed YAML - */ - public function parseYaml($yamlFile); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Data set implementation for the output of mysqldump --xml. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet -{ - protected function getTableInfo(array &$tableColumns, array &$tableValues) - { - if ($this->xmlFileContents->getName() != 'mysqldump') { - throw new PHPUnit_Extensions_Database_Exception('The root element of a MySQL XML data set file must be called <mysqldump>'); - } - - foreach ($this->xmlFileContents->xpath('./database/table_data') as $tableElement) { - if (empty($tableElement['name'])) { - throw new PHPUnit_Extensions_Database_Exception('<table_data> elements must include a name attribute'); - } - - $tableName = (string) $tableElement['name']; - - if (!isset($tableColumns[$tableName])) { - $tableColumns[$tableName] = []; - } - - if (!isset($tableValues[$tableName])) { - $tableValues[$tableName] = []; - } - - foreach ($tableElement->xpath('./row') as $rowElement) { - $rowValues = []; - - foreach ($rowElement->xpath('./field') as $columnElement) { - if (empty($columnElement['name'])) { - throw new PHPUnit_Extensions_Database_Exception('<field> element name attributes cannot be empty'); - } - - $columnName = (string) $columnElement['name']; - - if (!in_array($columnName, $tableColumns[$tableName])) { - $tableColumns[$tableName][] = $columnName; - } - } - - foreach ($tableColumns[$tableName] as $columnName) { - $fields = $rowElement->xpath('./field[@name="' . $columnName . '"]'); - $column = $fields[0]; - $attr = $column->attributes('http://www.w3.org/2001/XMLSchema-instance'); - - if (isset($attr['type']) && (string) $attr['type'] === 'xs:hexBinary') { - $columnValue = pack('H*',(string) $column); - } else { - $null = isset($column['nil']) || isset($attr[0]); - $columnValue = $null ? NULL : (string) $column; - } - - $rowValues[$columnName] = $columnValue; - - } - - $tableValues[$tableName][] = $rowValues; - } - } - - foreach ($this->xmlFileContents->xpath('./database/table_structure') as $tableElement) { - if (empty($tableElement['name'])) { - throw new PHPUnit_Extensions_Database_Exception('<table_structure> elements must include a name attribute'); - } - - $tableName = (string) $tableElement['name']; - - foreach ($tableElement->xpath('./field') as $fieldElement) { - if (empty($fieldElement['Field'])) { - throw new PHPUnit_Extensions_Database_Exception('<field> elements must include a Field attribute'); - } - - $columnName = (string) $fieldElement['Field']; - - if (!in_array($columnName, $tableColumns[$tableName])) { - $tableColumns[$tableName][] = $columnName; - } - } - } - } - - public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) - { - $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml; - $pers->setFileName($filename); - - try { - $pers->write($dataset); - } - - catch (RuntimeException $e) { - throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.'); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 abstract implementation of a dataset persistor. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_DataSet_Persistors_Abstract implements PHPUnit_Extensions_Database_DataSet_IPersistable -{ - public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - $this->saveDataSet($dataset); - } - - /** - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function saveDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - $this->startDataSet($dataset); - - foreach ($dataset as $table) { - $this->saveTable($table); - } - - $this->endDataSet($dataset); - } - - /** - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function saveTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - $rowCount = $table->getRowCount(); - $this->startTable($table); - - for ($i = 0; $i < $rowCount; $i++) { - $this->row($table->getRow($i), $table); - } - - $this->endTable($table); - } - - /** - * Override to save the start of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - abstract protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset); - - /** - * Override to save the end of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - abstract protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset); - - /** - * Override to save the start of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - abstract protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table); - - /** - * Override to save the end of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - abstract protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table); - - /** - * Override to save a table row. - * - * @param array $row - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - abstract protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 the appropriate Persistor based on a given type and spec. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Persistors_Factory -{ - /** - * Returns the persistor. - * - * @param string $type - * @param string $spec - * @return PHPUnit_Extensions_Database_DataSet_IPersistable - */ - public function getPersistorBySpec($type, $spec) - { - switch (strtolower($type)) { - case 'xml': - $xmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml(); - $xmlPersistor->setFileName($spec); - - return $xmlPersistor; - - case 'flatxml': - $flatXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml(); - $flatXmlPersistor->setFileName($spec); - - return $flatXmlPersistor; - - case 'yaml': - $yamlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml(); - $yamlPersistor->setFileName($spec); - - return $yamlPersistor; - - case 'mysqlxml': - $mysqlXmlPersistor = new PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml(); - $mysqlXmlPersistor->setFileName($spec); - - return $mysqlXmlPersistor; - - default: - throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me. PERSISTOR"); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 Flat XML dataset persistor. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Persistors_FlatXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract -{ - /** - * @var string - */ - protected $filename; - - /** - * @var resource - */ - protected $fh; - - /** - * Sets the filename that this persistor will save to. - * - * @param string $filename - */ - public function setFileName($filename) - { - $this->filename = $filename; - } - - /** - * Override to save the start of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - $this->fh = fopen($this->filename, 'w'); - - if ($this->fh === FALSE) { - throw new PHPUnit_Framework_Exception( - "Could not open {$this->filename} for writing see " . __CLASS__ . '::setFileName()' - ); - } - - fwrite($this->fh, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); - fwrite($this->fh, "<dataset>\n"); - } - - /** - * Override to save the end of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - fwrite($this->fh, "</dataset>\n"); - } - - /** - * Override to save the start of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - if ($table->getRowCount() == 0) { - fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()} />\n"); - } - } - - /** - * Override to save the end of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - //do nothing - } - - /** - * Override to save a table row. - * - * @param array $row - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t<{$table->getTableMetaData()->getTableName()}\n"); - - foreach ($table->getTableMetaData()->getColumns() as $columnName) { - if (isset($row[$columnName])) { - fwrite($this->fh, "\t\t{$columnName}=\"" . htmlspecialchars($row[$columnName]) . "\"\n"); - } - } - - fwrite($this->fh, "\t/>\n"); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 MySQL XML dataset persistor. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Persistors_MysqlXml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract -{ - /** - * @var string - */ - protected $filename; - - /** - * @var string - */ - protected $database; - - /** - * @var resource - */ - protected $fh; - - /** - * Sets the filename that this persistor will save to. - * - * @param string $filename - */ - public function setFileName($filename) - { - $this->filename = $filename; - } - - /** - * Sets the name of the database. - * - * @param string $database - */ - public function setDatabase($database) - { - $this->database = $database; - } - - /** - * Override to save the start of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - $this->fh = fopen($this->filename, 'w'); - - if ($this->fh === FALSE) { - throw new PHPUnit_Framework_Exception( - "Could not open {$this->filename} for writing see " . __CLASS__ . '::setFileName()' - ); - } - - fwrite($this->fh, '<?xml version="1.0" encoding="UTF-8"?>' . "\n"); - fwrite($this->fh, '<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' . "\n"); - fwrite($this->fh, '<database name="' . $this->database . '">' . "\n"); - } - - /** - * Override to save the end of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - fwrite($this->fh, '</database>' . "\n"); - fwrite($this->fh, '</mysqldump>' . "\n"); - } - - /** - * Override to save the start of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t" . '<table_data name="' . $table->getTableMetaData()->getTableName() . '">' . "\n"); - } - - /** - * Override to save the end of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t" . '</table_data>' . "\n"); - } - - /** - * Override to save a table row. - * - * @param array $row - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t" . '<row>' . "\n"); - - foreach ($table->getTableMetaData()->getColumns() as $columnName) { - fwrite($this->fh, "\t\t" . '<field name="' . $columnName . '"'); - if (isset($row[$columnName])) { - fwrite($this->fh, '>' . htmlspecialchars($row[$columnName]) . '</field>' . "\n"); - } else { - fwrite($this->fh, ' xsi:nil="true" />' . "\n"); - } - } - - fwrite($this->fh, "\t" . '</row>' . "\n"); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 XML dataset persistor. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Persistors_Xml extends PHPUnit_Extensions_Database_DataSet_Persistors_Abstract -{ - /** - * @var string - */ - protected $filename; - - /** - * @var resource - */ - protected $fh; - - /** - * Sets the filename that this persistor will save to. - * - * @param string $filename - */ - public function setFileName($filename) - { - $this->filename = $filename; - } - - /** - * Override to save the start of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function startDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - $this->fh = fopen($this->filename, 'w'); - - if ($this->fh === FALSE) { - throw new PHPUnit_Framework_Exception( - "Could not open {$this->filename} for writing see " . __CLASS__ . '::setFileName()' - ); - } - - fwrite($this->fh, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); - fwrite($this->fh, "<dataset>\n"); - } - - /** - * Override to save the end of a dataset. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - protected function endDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - fwrite($this->fh, "</dataset>\n"); - } - - /** - * Override to save the start of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function startTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t<table name=\"{$table->getTableMetaData()->getTableName()}\">\n"); - - foreach ($table->getTableMetaData()->getColumns() as $columnName) { - fwrite($this->fh, "\t\t<column>{$columnName}</column>\n"); - } - } - - /** - * Override to save the end of a table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function endTable(PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t</table>\n"); - } - - /** - * Override to save a table row. - * - * @param array $row - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - */ - protected function row(Array $row, PHPUnit_Extensions_Database_DataSet_ITable $table) - { - fwrite($this->fh, "\t\t<row>\n"); - - foreach ($table->getTableMetaData()->getColumns() as $columnName) { - if (isset($row[$columnName])) { - fwrite($this->fh, "\t\t\t<value>" . htmlspecialchars($row[$columnName]) . "</value>\n"); - } else { - fwrite($this->fh, "\t\t\t<null />\n"); - } - } - - fwrite($this->fh, "\t\t</row>\n"); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 yaml dataset persistor - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Persistors_Yaml implements PHPUnit_Extensions_Database_DataSet_IPersistable -{ - /** - * @var string - */ - protected $filename; - - /** - * Sets the filename that this persistor will save to. - * - * @param string $filename - */ - public function setFileName($filename) - { - $this->filename = $filename; - } - - /** - * Writes the dataset to a yaml file - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - */ - public function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset) - { - $phpArr = []; - $emptyTables = []; - - foreach ($dataset as $table) { - $tableName = $table->getTableMetaData()->getTableName(); - $rowCount = $table->getRowCount(); - - if (!$rowCount) { - $emptyTables[] = $tableName; - continue; - } - - $phpArr[$tableName] = []; - - for ($i = 0; $i < $rowCount; $i++) { - $phpArr[$tableName][] = $table->getRow($i); - } - } - - $emptyTablesAsString = ''; - - if (count($emptyTables)) { - $emptyTablesAsString = implode(":\n", $emptyTables) . ":\n\n"; - } - - file_put_contents( - $this->filename, - Symfony\Component\Yaml\Yaml::dump($phpArr, 3) . $emptyTablesAsString - ); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 access to a database instance as a data set. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_QueryDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * An array of ITable objects. - * - * @var array - */ - protected $tables = []; - - /** - * The database connection this dataset is using. - * - * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - protected $databaseConnection; - - /** - * Creates a new dataset using the given database connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - */ - public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) - { - $this->databaseConnection = $databaseConnection; - } - - public function addTable($tableName, $query = NULL) - { - if ($query === NULL) { - $query = 'SELECT * FROM ' . $tableName; - } - - $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_QueryTable($tableName, $query, $this->databaseConnection); - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DB_TableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator($this->tables, $reverse); - } - - /** - * Returns a table object for the given table. - * - * @param string $tableName - * @return PHPUnit_Extensions_Database_DB_Table - */ - public function getTable($tableName) - { - if (!isset($this->tables[$tableName])) { - throw new InvalidArgumentException("$tableName is not a table in the current database."); - } - - return $this->tables[$tableName]; - } - - /** - * Returns a list of table names for the database - * - * @return Array - */ - public function getTableNames() - { - return array_keys($this->tables); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 the functionality to represent a database table. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_QueryTable extends PHPUnit_Extensions_Database_DataSet_AbstractTable -{ - /** - * @var string - */ - protected $query; - - /** - * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - protected $databaseConnection; - - /** - * @var string - */ - protected $tableName; - - /** - * Creates a new database query table object. - * - * @param string $table_name - * @param string $query - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection - */ - public function __construct($tableName, $query, PHPUnit_Extensions_Database_DB_IDatabaseConnection $databaseConnection) - { - $this->query = $query; - $this->databaseConnection = $databaseConnection; - $this->tableName = $tableName; - } - - /** - * Returns the table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData() - { - $this->createTableMetaData(); - - return parent::getTableMetaData(); - } - - /** - * Checks if a given row is in the table - * - * @param array $row - * - * @return bool - */ - public function assertContainsRow(Array $row) - { - $this->loadData(); - - return parent::assertContainsRow($row); - } - - /** - * Returns the number of rows in this table. - * - * @return int - */ - public function getRowCount() - { - $this->loadData(); - - return parent::getRowCount(); - } - - /** - * Returns the value for the given column on the given row. - * - * @param int $row - * @param int $column - */ - public function getValue($row, $column) - { - $this->loadData(); - - return parent::getValue($row, $column); - } - - /** - * Returns the an associative array keyed by columns for the given row. - * - * @param int $row - * @return array - */ - public function getRow($row) - { - $this->loadData(); - - return parent::getRow($row); - } - - /** - * Asserts that the given table matches this table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other) - { - $this->loadData(); - - return parent::matches($other); - } - - protected function loadData() - { - if ($this->data === NULL) { - $pdoStatement = $this->databaseConnection->getConnection()->query($this->query); - $this->data = $pdoStatement->fetchAll(PDO::FETCH_ASSOC); - } - } - - protected function createTableMetaData() - { - if ($this->tableMetaData === NULL) - { - $this->loadData(); - - // if some rows are in the table - $columns = []; - if (isset($this->data[0])) - // get column names from data - $columns = array_keys($this->data[0]); - else { - // if no rows found, get column names from database - $pdoStatement = $this->databaseConnection->getConnection()->prepare('SELECT column_name FROM information_schema.COLUMNS WHERE table_schema=:schema AND table_name=:table'); - $pdoStatement->execute([ - 'table' => $this->tableName, - 'schema' => $this->databaseConnection->getSchema() - ]); - - $columns = $pdoStatement->fetchAll(PDO::FETCH_COLUMN, 0); - } - // create metadata - $this->tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData($this->tableName, $columns); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Allows for replacing arbitrary values or portions of values with new data. - * - * A usage for this is replacing all values == '[NULL'] with a true NULL value - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_ReplacementDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * @var PHPUnit_Extensions_Database_DataSet_IDataSet - */ - protected $dataSet; - - /** - * @var array - */ - protected $fullReplacements; - - /** - * @var array - */ - protected $subStrReplacements; - - /** - * Creates a new replacement dataset - * - * You can pass in any data set that implements PHPUnit_Extensions_Database_DataSet_IDataSet - * - * @param string $delimiter - * @param string $enclosure - * @param string $escape - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet, Array $fullReplacements = [], Array $subStrReplacements = []) - { - $this->dataSet = $dataSet; - $this->fullReplacements = $fullReplacements; - $this->subStrReplacements = $subStrReplacements; - } - - /** - * Adds a new full replacement - * - * Full replacements will only replace values if the FULL value is a match - * - * @param string $value - * @param string $replacement - */ - public function addFullReplacement($value, $replacement) - { - $this->fullReplacements[$value] = $replacement; - } - - /** - * Adds a new substr replacement - * - * Substr replacements will replace all occurances of the substr in every column - * - * @param string $value - * @param string $replacement - */ - public function addSubStrReplacement($value, $replacement) - { - $this->subStrReplacements[$value] = $replacement; - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - $innerIterator = $reverse ? $this->dataSet->getReverseIterator() : $this->dataSet->getIterator(); - - return new PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator($innerIterator, $this->fullReplacements, $this->subStrReplacements); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Allows for replacing arbitrary strings in your data sets with other values. - * - * @since Class available since Release 1.0.0 - * @todo When setTableMetaData() is taken out of the AbstractTable this class should extend AbstractTable. - */ -class PHPUnit_Extensions_Database_DataSet_ReplacementTable implements PHPUnit_Extensions_Database_DataSet_ITable -{ - /** - * @var PHPUnit_Extensions_Database_DataSet_ITable - */ - protected $table; - - /** - * @var array - */ - protected $fullReplacements; - - /** - * @var array - */ - protected $subStrReplacements; - - /** - * Creates a new replacement table - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - * @param array $fullReplacements - * @param array $subStrReplacements - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $table, Array $fullReplacements = [], Array $subStrReplacements = []) - { - $this->table = $table; - $this->fullReplacements = $fullReplacements; - $this->subStrReplacements = $subStrReplacements; - } - - /** - * Adds a new full replacement - * - * Full replacements will only replace values if the FULL value is a match - * - * @param string $value - * @param string $replacement - */ - public function addFullReplacement($value, $replacement) - { - $this->fullReplacements[$value] = $replacement; - } - - /** - * Adds a new substr replacement - * - * Substr replacements will replace all occurances of the substr in every column - * - * @param string $value - * @param string $replacement - */ - public function addSubStrReplacement($value, $replacement) - { - $this->subStrReplacements[$value] = $replacement; - } - - /** - * Returns the table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData() - { - return $this->table->getTableMetaData(); - } - - /** - * Returns the number of rows in this table. - * - * @return int - */ - public function getRowCount() - { - return $this->table->getRowCount(); - } - - /** - * Returns the value for the given column on the given row. - * - * @param int $row - * @param int $column - */ - public function getValue($row, $column) - { - return $this->getReplacedValue($this->table->getValue($row, $column)); - } - - /** - * Returns the an associative array keyed by columns for the given row. - * - * @param int $row - * @return array - */ - public function getRow($row) - { - $row = $this->table->getRow($row); - - return array_map([$this, 'getReplacedValue'], $row); - } - - /** - * Asserts that the given table matches this table. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $other - */ - public function matches(PHPUnit_Extensions_Database_DataSet_ITable $other) - { - $thisMetaData = $this->getTableMetaData(); - $otherMetaData = $other->getTableMetaData(); - - if (!$thisMetaData->matches($otherMetaData) || - $this->getRowCount() != $other->getRowCount()) { - return FALSE; - } - - $columns = $thisMetaData->getColumns(); - $rowCount = $this->getRowCount(); - - for ($i = 0; $i < $rowCount; $i++) { - foreach ($columns as $columnName) { - $thisValue = $this->getValue($i, $columnName); - $otherValue = $other->getValue($i, $columnName); - if (is_numeric($thisValue) && is_numeric($otherValue)) { - if ($thisValue != $otherValue) { - return FALSE; - } - } elseif ($thisValue !== $otherValue) { - return FALSE; - } - } - } - - return TRUE; - } - - public function __toString() - { - $columns = $this->getTableMetaData()->getColumns(); - - $lineSeperator = str_repeat('+----------------------', count($columns)) . "+\n"; - $lineLength = strlen($lineSeperator) - 1; - - $tableString = $lineSeperator; - $tableString .= '| ' . str_pad($this->getTableMetaData()->getTableName(), $lineLength - 4, ' ', STR_PAD_RIGHT) . " |\n"; - $tableString .= $lineSeperator; - $tableString .= $this->rowToString($columns); - $tableString .= $lineSeperator; - - $rowCount = $this->getRowCount(); - - for ($i = 0; $i < $rowCount; $i++) { - $values = []; - - foreach ($columns as $columnName) { - $values[] = $this->getValue($i, $columnName); - } - - $tableString .= $this->rowToString($values); - $tableString .= $lineSeperator; - } - - return "\n" . $tableString . "\n"; - } - - protected function rowToString(Array $row) - { - $rowString = ''; - - foreach ($row as $value) { - if (is_null($value)) { - $value = 'NULL'; - } - - $rowString .= '| ' . str_pad(substr($value, 0, 20), 20, ' ', STR_PAD_BOTH) . ' '; - } - - return $rowString . "|\n"; - } - - protected function getReplacedValue($value) - { - if (is_scalar($value) && array_key_exists((string) $value, $this->fullReplacements)) { - return $this->fullReplacements[$value]; - } - - else if (count($this->subStrReplacements) && isset($value)) { - return str_replace(array_keys($this->subStrReplacements), array_values($this->subStrReplacements), $value); - } - - else { - return $value; - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default table iterator - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_ReplacementTableIterator implements OuterIterator, PHPUnit_Extensions_Database_DataSet_ITableIterator -{ - /** - * @var PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected $innerIterator; - - /** - * @var array - */ - protected $fullReplacements; - - /** - * @var array - */ - protected $subStrReplacements; - - /** - * Creates a new replacement table iterator object. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator - * @param array $fullReplacements - * @param array $subStrReplacements - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITableIterator $innerIterator, Array $fullReplacements = [], Array $subStrReplacements = []) - { - $this->innerIterator = $innerIterator; - $this->fullReplacements = $fullReplacements; - $this->subStrReplacements = $subStrReplacements; - } - - /** - * Adds a new full replacement - * - * Full replacements will only replace values if the FULL value is a match - * - * @param string $value - * @param string $replacement - */ - public function addFullReplacement($value, $replacement) - { - $this->fullReplacements[$value] = $replacement; - } - - /** - * Adds a new substr replacement - * - * Substr replacements will replace all occurances of the substr in every column - * - * @param string $value - * @param string $replacement - */ - public function addSubStrReplacement($value, $replacement) - { - $this->subStrReplacements[$value] = $replacement; - } - - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function getTable() - { - return $this->current(); - } - - /** - * Returns the current table's meta data. - * - * @return PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - public function getTableMetaData() - { - $this->current()->getTableMetaData(); - } - - /** - * Returns the current table. - * - * @return PHPUnit_Extensions_Database_DataSet_ITable - */ - public function current() - { - return new PHPUnit_Extensions_Database_DataSet_ReplacementTable($this->innerIterator->current(), $this->fullReplacements, $this->subStrReplacements); - } - - /** - * Returns the name of the current table. - * - * @return string - */ - public function key() - { - return $this->current()->getTableMetaData()->getTableName(); - } - - /** - * advances to the next element. - */ - public function next() - { - $this->innerIterator->next(); - } - - /** - * Rewinds to the first element - */ - public function rewind() - { - $this->innerIterator->rewind(); - } - - /** - * Returns true if the current index is valid - * - * @return bool - */ - public function valid() - { - return $this->innerIterator->valid(); - } - - public function getInnerIterator() - { - return $this->innerIterator; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 CsvDataSets based off of a spec string. - * - * The format of the spec string is as follows: - * - * <csv options>|table1:filename.csv,table2:filename2.csv - * - * The first portion of the spec including the pipe symbol '|' is optional. - * If the pipe option is included than it may be preceded by up to four - * characters specifying values for the following arguments in order: - * delimiter (defaults to ',',) enclosure (defaults to '"',) escape (defaults to '"',). - * - * Any additional characters in the csv options will be discarded. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_Csv implements PHPUnit_Extensions_Database_DataSet_ISpec -{ - /** - * Creates CSV Data Set from a data set spec. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet - */ - public function getDataSet($dataSetSpec) - { - $csvDataSetArgs = $this->getCsvOptions($dataSetSpec); - $csvDataSetRfl = new ReflectionClass('PHPUnit_Extensions_Database_DataSet_CsvDataSet'); - $csvDataSet = $csvDataSetRfl->newInstanceArgs($csvDataSetArgs); - - foreach ($this->getTableFileMap($dataSetSpec) as $tableName => $file) { - $csvDataSet->addTable($tableName, $file); - } - - return $csvDataSet; - } - - /** - * Returns CSV options. - * - * Returns an array containing the options that will be passed to the - * PHPUnit_Extensions_Database_DataSet_CsvDataSet constructor. The options - * are determined by the given $dataSetSpec. - * - * @param string $dataSetSpec - * @return array - */ - protected function getCsvOptions($dataSetSpec) - { - list($csvOptStr) = explode('|', $dataSetSpec, 2); - - return str_split($csvOptStr); - } - - /** - * Returns map of tables to files. - * - * Returns an associative array containing a mapping of tables (the key) - * to files (the values.) The tables and files are determined by the given - * $dataSetSpec - * - * @param string $dataSetSpec - * @return array - */ - protected function getTableFileMap($dataSetSpec) - { - $tables = []; - - foreach (explode(',', $dataSetSpec) as $csvfile) { - list($tableName, $file) = explode(':', $csvfile, 2); - $tables[$tableName] = $file; - } - - return $tables; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 DefaultDataSets based off of a spec string. - * - * This spec class requires a list of databases to be set to the object before - * it can return a list of databases. - * - * The format of the spec string is as follows: - * - * <db label>:<schema>:<table name>:<sql> - * - * The db label should be equal to one of the keys in the array of databases - * passed to setDatabases(). - * - * The schema should be the primary schema you will be running the sql query - * against. - * - * The table name should be set to what you would like the table name in the - * dataset to be. - * - * The sql is the query you want to use to generate the table columns and data. - * The column names in the table will be identical to the column aliases in the - * query. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_DbQuery implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer -{ - /** - * @var array - */ - protected $databases = []; - - /** - * Sets the database for the spec - * - * @param array $databases - */ - public function setDatabases(array $databases) - { - $this->databases = $databases; - } - - /** - * Creates a Default Data Set with a query table from a data set spec. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_DefaultDataSet - */ - public function getDataSet($dataSetSpec) - { - list($dbLabel, $schema, $table, $sql) = explode(':', $dataSetSpec, 4); - $databaseInfo = $this->databases[$dbLabel]; - - $pdoRflc = new ReflectionClass('PDO'); - $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo)); - $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema); - $table = $dbConnection->createQueryTable($table, $sql); - - return new PHPUnit_Extensions_Database_DataSet_DefaultDataSet([$table]); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 database dataset based off of a spec string. - * - * This spec class requires a list of databases to be set to the object before - * it can return a list of databases. - * - * The format of the spec string is as follows: - * - * <db label>:<schema>:<tables> - * - * The db label should be equal to one of the keys in the array of databases - * passed to setDatabases(). - * - * The schema should be the primary schema you will be choosing tables from. - * - * The tables should be a comma delimited list of all tables you would like to - * pull data from. - * - * The sql is the query you want to use to generate the table columns and data. - * The column names in the table will be identical to the column aliases in the - * query. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_DbTable implements PHPUnit_Extensions_Database_DataSet_ISpec, PHPUnit_Extensions_Database_IDatabaseListConsumer -{ - /** - * @var array - */ - protected $databases = []; - - /** - * Sets the database for the spec - * - * @param array $databases - */ - public function setDatabases(array $databases) - { - $this->databases = $databases; - } - - /** - * Creates a DB Data Set from a data set spec. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - public function getDataSet($dataSetSpec) - { - list($dbLabel, $schema, $tables) = explode(':', $dataSetSpec, 3); - $databaseInfo = $this->databases[$dbLabel]; - - $pdoRflc = new ReflectionClass('PDO'); - $pdo = $pdoRflc->newInstanceArgs(explode('|', $databaseInfo)); - $dbConnection = new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($pdo, $schema); - - return !empty($tables) ? $dbConnection->createDataSet(explode(',', $tables)) : $dbConnection->createDataSet(); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 the appropriate DataSet Spec based on a given type. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_Factory implements PHPUnit_Extensions_Database_DataSet_Specs_IFactory -{ - /** - * Returns the data set - * - * @param string $type - * @return PHPUnit_Extensions_Database_DataSet_ISpec - */ - public function getDataSetSpecByType($type) - { - switch ($type) { - case 'xml': - return new PHPUnit_Extensions_Database_DataSet_Specs_Xml(); - - case 'flatxml': - return new PHPUnit_Extensions_Database_DataSet_Specs_FlatXml(); - - case 'csv': - return new PHPUnit_Extensions_Database_DataSet_Specs_Csv(); - - case 'yaml': - return new PHPUnit_Extensions_Database_DataSet_Specs_Yaml(); - - case 'dbtable': - return new PHPUnit_Extensions_Database_DataSet_Specs_DbTable(); - - case 'dbquery': - return new PHPUnit_Extensions_Database_DataSet_Specs_DbQuery(); - - default: - throw new PHPUnit_Extensions_Database_Exception("I don't know what you want from me."); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 FlatXML dataset based off of a spec string. - * - * The format of the spec string is as follows: - * - * <filename> - * - * The filename should be the location of a flat xml file relative to the - * current working directory. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_FlatXml implements PHPUnit_Extensions_Database_DataSet_ISpec -{ - /** - * Creates Flat XML Data Set from a data set spec. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet - */ - public function getDataSet($dataSetSpec) - { - return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($dataSetSpec); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 for data set spec factories. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_DataSet_Specs_IFactory -{ - /** - * Returns the data set - * - * @param string $type - * @return PHPUnit_Extensions_Database_DataSet_ISpec - */ - public function getDataSetSpecByType($type); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 XML dataset based off of a spec string. - * - * The format of the spec string is as follows: - * - * <filename> - * - * The filename should be the location of a xml file relative to the - * current working directory. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_Xml implements PHPUnit_Extensions_Database_DataSet_ISpec -{ - /** - * Creates XML Data Set from a data set spec. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet - */ - public function getDataSet($dataSetSpec) - { - return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($dataSetSpec); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 YAML dataset based off of a spec string. - * - * The format of the spec string is as follows: - * - * <filename> - * - * The filename should be the location of a yaml file relative to the - * current working directory. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_Specs_Yaml implements PHPUnit_Extensions_Database_DataSet_ISpec -{ - /** - * Creates YAML Data Set from a data set spec. - * - * @param string $dataSetSpec - * @return PHPUnit_Extensions_Database_DataSet_YamlDataSet - */ - public function getDataSet($dataSetSpec) - { - return new PHPUnit_Extensions_Database_DataSet_YamlDataSet($dataSetSpec); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default YAML parser, using Symfony/Yaml. - * - * @since Class available since Release 1.3.1 - */ -class PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser implements PHPUnit_Extensions_Database_DataSet_IYamlParser { - public function parseYaml($yamlFile) { - return Symfony\Component\Yaml\Yaml::parse(file_get_contents($yamlFile)); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 table decorator that allows filtering out table columns from results. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_TableFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTable -{ - /** - * The table meta data being decorated. - * @var PHPUnit_Extensions_Database_DataSet_ITable - */ - protected $originalTable; - - /** - * Creates a new table filter using the original table - * - * @param $originalTable PHPUnit_Extensions_Database_DataSet_ITable - * @param $excludeColumns Array @deprecated, use the set* methods instead. - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITable $originalTable, Array $excludeColumns = []) - { - $this->originalTable = $originalTable; - $this->setTableMetaData(new PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter($originalTable->getTableMetaData())); - $this->addExcludeColumns($excludeColumns); - } - - /** - * Returns the number of rows in this table. - * - * @return int - */ - public function getRowCount() - { - return $this->originalTable->getRowCount(); - } - - /** - * Returns the value for the given column on the given row. - * - * @param int $row - * @param int $column - */ - public function getValue($row, $column) - { - if (in_array($column, $this->getTableMetaData()->getColumns())) { - return $this->originalTable->getValue($row, $column); - } else { - throw new InvalidArgumentException("The given row ({$row}) and column ({$column}) do not exist in table {$this->getTableMetaData()->getTableName()}"); - } - } - - /** - * Sets the columns to include in the table. - * @param Array $includeColumns - */ - public function addIncludeColumns(Array $includeColumns) - { - $this->tableMetaData->addIncludeColumns($includeColumns); - } - - /** - * Clears the included columns. - */ - public function clearIncludeColumns() - { - $this->tableMetaData->clearIncludeColumns(); - } - - /** - * Sets the columns to exclude from the table. - * @param Array $excludeColumns - */ - public function addExcludeColumns(Array $excludeColumns) - { - $this->tableMetaData->addExcludeColumns($excludeColumns); - } - - /** - * Clears the included columns. - */ - public function clearExcludeColumns() - { - $this->tableMetaData->clearExcludeColumns(); - } - - /** - * Checks if a given row is in the table - * - * @param array $row - * - * @return bool - */ - public function assertContainsRow(Array $row) - { - $this->loadData(); - - return parent::assertContainsRow($row); - } - - /** - * Loads data into local data table if it's not already loaded - */ - protected function loadData() - { - if ($this->data === NULL) { - $data = []; - for($row = 0;$row < $this->originalTable->getRowCount();$row++) { - $tRow = []; - foreach($this->getTableMetaData()->getColumns() as $col) { - $tRow[$col] = $this->getValue($row, $col); - } - $data[$row] = $tRow; - } - $this->data = $data; - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 TableMetaData decorator that allows filtering columns from another - * metaData object. - * - * The if a whitelist (include) filter is specified, then only those columns - * will be included. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_TableMetaDataFilter extends PHPUnit_Extensions_Database_DataSet_AbstractTableMetaData -{ - /** - * The table meta data being decorated. - * @var PHPUnit_Extensions_Database_DataSet_ITableMetaData - */ - protected $originalMetaData; - - /** - * The columns to exclude from the meta data. - * @var Array - */ - protected $excludeColumns = []; - - /** - * The columns to include from the meta data. - * @var Array - */ - protected $includeColumns = []; - - /** - * Creates a new filtered table meta data object filtering out - * $excludeColumns. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData - * @param array $excludeColumns - Deprecated. Use the set* methods instead. - */ - public function __construct(PHPUnit_Extensions_Database_DataSet_ITableMetaData $originalMetaData, Array $excludeColumns = []) - { - $this->originalMetaData = $originalMetaData; - $this->addExcludeColumns($excludeColumns); - } - - /** - * Returns the names of the columns in the table. - * - * @return array - */ - public function getColumns() - { - if (!empty($this->includeColumns)) { - return array_values(array_intersect($this->originalMetaData->getColumns(), $this->includeColumns)); - } - elseif (!empty($this->excludeColumns)) { - return array_values(array_diff($this->originalMetaData->getColumns(), $this->excludeColumns)); - } - else { - return $this->originalMetaData->getColumns(); - } - } - - /** - * Returns the names of the primary key columns in the table. - * - * @return array - */ - public function getPrimaryKeys() - { - return $this->originalMetaData->getPrimaryKeys(); - } - - /** - * Returns the name of the table. - * - * @return string - */ - public function getTableName() - { - return $this->originalMetaData->getTableName(); - } - - /** - * Sets the columns to include in the table. - * @param Array $includeColumns - */ - public function addIncludeColumns(Array $includeColumns) - { - $this->includeColumns = array_unique(array_merge($this->includeColumns, $includeColumns)); - } - - /** - * Clears the included columns. - */ - public function clearIncludeColumns() - { - $this->includeColumns = []; - } - - /** - * Sets the columns to exclude from the table. - * @param Array $excludeColumns - */ - public function addExcludeColumns(Array $excludeColumns) - { - $this->excludeColumns = array_unique(array_merge($this->excludeColumns, $excludeColumns)); - } - - /** - * Clears the excluded columns. - */ - public function clearExcludeColumns() - { - $this->excludeColumns = []; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default implementation of a data set. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_XmlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractXmlDataSet -{ - protected function getTableInfo(Array &$tableColumns, Array &$tableValues) - { - if ($this->xmlFileContents->getName() != 'dataset') { - throw new PHPUnit_Extensions_Database_Exception('The root element of an xml data set file must be called <dataset>'); - } - - foreach ($this->xmlFileContents->xpath('/dataset/table') as $tableElement) { - if (empty($tableElement['name'])) { - throw new PHPUnit_Extensions_Database_Exception('Table elements must include a name attribute specifying the table name.'); - } - - $tableName = (string) $tableElement['name']; - - if (!isset($tableColumns[$tableName])) { - $tableColumns[$tableName] = []; - } - - if (!isset($tableValues[$tableName])) { - $tableValues[$tableName] = []; - } - - $tableInstanceColumns = []; - - foreach ($tableElement->xpath('./column') as $columnElement) { - $columnName = (string) $columnElement; - if (empty($columnName)) { - throw new PHPUnit_Extensions_Database_Exception("Missing <column> elements for table $tableName. Add one or more <column> elements to the <table> element."); - } - - if (!in_array($columnName, $tableColumns[$tableName])) { - $tableColumns[$tableName][] = $columnName; - } - - $tableInstanceColumns[] = $columnName; - } - - foreach ($tableElement->xpath('./row') as $rowElement) { - $rowValues = []; - $index = 0; - $numOfTableInstanceColumns = count($tableInstanceColumns); - - foreach ($rowElement->children() as $columnValue) { - - if ($index >= $numOfTableInstanceColumns) { - throw new PHPUnit_Extensions_Database_Exception("Row contains more values than the number of columns defined for table $tableName."); - } - switch ($columnValue->getName()) { - case 'value': - $rowValues[$tableInstanceColumns[$index]] = (string) $columnValue; - $index++; - break; - case 'null': - $rowValues[$tableInstanceColumns[$index]] = NULL; - $index++; - break; - default: - throw new PHPUnit_Extensions_Database_Exception('Unknown element ' . $columnValue->getName() . ' in a row element.'); - } - } - - $tableValues[$tableName][] = $rowValues; - } - } - } - - public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) - { - $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Xml(); - $pers->setFileName($filename); - - try { - $pers->write($dataset); - } - - catch (RuntimeException $e) { - throw new PHPUnit_Framework_Exception(__METHOD__ . ' called with an unwritable file.'); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 YamlDataSets. - * - * You can incrementally add YAML files as tables to your datasets - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DataSet_YamlDataSet extends PHPUnit_Extensions_Database_DataSet_AbstractDataSet -{ - /** - * @var array - */ - protected $tables = []; - - /** - * @var PHPUnit_Extensions_Database_DataSet_IYamlParser - */ - protected $parser; - - /** - * Creates a new YAML dataset - * - * @param string $yamlFile - * @param PHPUnit_Extensions_Database_DataSet_IYamlParser $parser - */ - public function __construct($yamlFile, $parser = NULL) - { - if ($parser == NULL) { - $parser = new PHPUnit_Extensions_Database_DataSet_SymfonyYamlParser(); - } - $this->parser = $parser; - $this->addYamlFile($yamlFile); - } - - /** - * Adds a new yaml file to the dataset. - * @param string $yamlFile - */ - public function addYamlFile($yamlFile) - { - $data = $this->parser->parseYaml($yamlFile); - - foreach ($data as $tableName => $rows) { - if (!isset($rows)) { - $rows = []; - } - - if (!is_array($rows)) { - continue; - } - - if (!array_key_exists($tableName, $this->tables)) { - $columns = $this->getColumns($rows); - - $tableMetaData = new PHPUnit_Extensions_Database_DataSet_DefaultTableMetaData( - $tableName, $columns - ); - - $this->tables[$tableName] = new PHPUnit_Extensions_Database_DataSet_DefaultTable( - $tableMetaData - ); - } - - foreach ($rows as $row) { - $this->tables[$tableName]->addRow($row); - } - } - } - - /** - * Creates a unique list of columns from all the rows in a table. - * If the table is defined another time in the Yaml, and if the Yaml - * parser could return the multiple occerrences, then this would be - * insufficient unless we grouped all the occurences of the table - * into onwe row set. sfYaml, however, does not provide multiple tables - * with the same name, it only supplies the last table. - * - * @params all the rows in a table. - */ - private function getColumns($rows) { - $columns = []; - - foreach ($rows as $row) { - $columns = array_merge($columns, array_keys($row)); - } - - return array_values(array_unique($columns)); - } - - /** - * Creates an iterator over the tables in the data set. If $reverse is - * true a reverse iterator will be returned. - * - * @param bool $reverse - * @return PHPUnit_Extensions_Database_DataSet_ITableIterator - */ - protected function createIterator($reverse = FALSE) - { - return new PHPUnit_Extensions_Database_DataSet_DefaultTableIterator( - $this->tables, $reverse - ); - } - - /** - * Saves a given $dataset to $filename in YAML format - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataset - * @param string $filename - */ - public static function write(PHPUnit_Extensions_Database_DataSet_IDataSet $dataset, $filename) - { - $pers = new PHPUnit_Extensions_Database_DataSet_Persistors_Yaml(); - $pers->setFileName($filename); - - try { - $pers->write($dataset); - } - - catch (RuntimeException $e) { - throw new PHPUnit_Framework_Exception( - __METHOD__ . ' called with an unwritable file.' - ); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * This is the default implementation of the database tester. It receives its - * connection object from the constructor. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_DefaultTester extends PHPUnit_Extensions_Database_AbstractTester -{ - /** - * @var PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - protected $connection; - - /** - * Creates a new default database tester using the given connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - */ - public function __construct(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - parent::__construct(); - - $this->connection = $connection; - } - - /** - * Returns the test database connection. - * - * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - public function getConnection() - { - return $this->connection; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 for exceptions encountered with database operations. Provides - * information regarding which operations failed and the query (if any) it - * failed on. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Exception extends Exception -{ -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 for classes that require a list of databases to operate. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_IDatabaseListConsumer -{ - /** - * Sets the database for the spec - * - * @param array $databases - */ - public function setDatabases(array $databases); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * This is the interface for DatabaseTester objects. These objects are used to - * add database testing to existing test cases using composition instead of - * extension. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_ITester -{ - /** - * Closes the specified connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - */ - public function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection); - - /** - * Returns the test database connection. - * - * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - public function getConnection(); - - /** - * Returns the test dataset. - * - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - public function getDataSet(); - - /** - * TestCases must call this method inside setUp(). - */ - public function onSetUp(); - - /** - * TestCases must call this method inside tearDown(). - */ - public function onTearDown(); - - /** - * Sets the test dataset to use. - * - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function setDataSet(PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet); - - /** - * Sets the schema value. - * - * @param string $schema - */ - public function setSchema($schema); - - /** - * Sets the DatabaseOperation to call when starting the test. - * - * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $setUpOperation - */ - public function setSetUpOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $setUpOperation); - - /** - * Sets the DatabaseOperation to call when stopping the test. - * - * @param PHPUnit_Extensions_Database_Operation_DatabaseOperation $tearDownOperation - */ - public function setTearDownOperation(PHPUnit_Extensions_Database_Operation_IDatabaseOperation $tearDownOperation); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * This class facilitates combining database operations. To create a composite - * operation pass an array of classes that implement - * PHPUnit_Extensions_Database_Operation_IDatabaseOperation and they will be - * executed in that order against all data sets. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Composite implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - /** - * @var array - */ - protected $operations = []; - - /** - * Creates a composite operation. - * - * @param array $operations - */ - public function __construct(Array $operations) - { - foreach ($operations as $operation) { - if ($operation instanceof PHPUnit_Extensions_Database_Operation_IDatabaseOperation) { - $this->operations[] = $operation; - } else { - throw new InvalidArgumentException('Only database operation instances can be passed to a composite database operation.'); - } - } - } - - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - try { - foreach ($this->operations as $operation) { - /* @var $operation PHPUnit_Extensions_Database_Operation_IDatabaseOperation */ - $operation->execute($connection, $dataSet); - } - } catch (PHPUnit_Extensions_Database_Operation_Exception $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception("COMPOSITE[{$e->getOperation()}]", $e->getQuery(), $e->getArgs(), $e->getTable(), $e->getError()); - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Deletes the rows in a given dataset using primary key columns. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Delete extends PHPUnit_Extensions_Database_Operation_RowBased -{ - protected $operationName = 'DELETE'; - - protected $iteratorDirection = self::ITERATOR_TYPE_REVERSE; - - protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $keys = $databaseTableMetaData->getPrimaryKeys(); - - $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection)); - - $query = " - DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} - {$whereStatement} - "; - - return $query; - } - - protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) - { - $args = []; - foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) { - $args[] = $table->getValue($row, $columnName); - } - - return $args; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Deletes all rows from all tables in a dataset. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_DeleteAll implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - foreach ($dataSet->getReverseIterator() as $table) { - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - - $query = " - DELETE FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} - "; - - try { - $connection->getConnection()->query($query); - } catch (PDOException $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception('DELETE_ALL', $query, [], $table, $e->getMessage()); - } - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 for exceptions encountered with database operations. Provides - * information regarding which operations failed and the query (if any) it - * failed on. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Exception extends RuntimeException -{ - /** - * @var string - */ - protected $operation; - - /** - * @var string - */ - protected $preparedQuery; - - /** - * @var array - */ - protected $preparedArgs; - - /** - * @var PHPUnit_Extensions_Database_DataSet_ITable - */ - protected $table; - - /** - * @var string - */ - protected $error; - - /** - * Creates a new dbunit operation exception - * - * @param string $operation - * @param string $current_query - * @param PHPUnit_Extensions_Database_DataSet_ITable $current_table - * @param string $error - */ - public function __construct($operation, $current_query, $current_args, $current_table, $error) - { - parent::__construct("{$operation} operation failed on query: {$current_query} using args: " . print_r($current_args, TRUE) . " [{$error}]"); - - $this->operation = $operation; - $this->preparedQuery = $current_query; - $this->preparedArgs = $current_args; - $this->table = $current_table; - $this->error = $error; - } - - public function getOperation() - { - return $this->operation; - } - - public function getQuery() - { - return $this->preparedQuery; - } - - public function getTable() - { - return $this->table; - } - - public function getArgs() - { - return $this->preparedArgs; - } - - public function getError() - { - return $this->error; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 factory to easily return database operations. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Factory -{ - /** - * Returns a null database operation - * - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function NONE() - { - return new PHPUnit_Extensions_Database_Operation_Null(); - } - - /** - * Returns a clean insert database operation. It will remove all contents - * from the table prior to re-inserting rows. - * - * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this. - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function CLEAN_INSERT($cascadeTruncates = FALSE) - { - return new PHPUnit_Extensions_Database_Operation_Composite([ - self::TRUNCATE($cascadeTruncates), - self::INSERT() - ]); - } - - /** - * Returns an insert database operation. - * - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function INSERT() - { - return new PHPUnit_Extensions_Database_Operation_Insert(); - } - - /** - * Returns a truncate database operation. - * - * @param bool $cascadeTruncates Set to true to force truncates to cascade on databases that support this. - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function TRUNCATE($cascadeTruncates = FALSE) - { - $truncate = new PHPUnit_Extensions_Database_Operation_Truncate(); - $truncate->setCascade($cascadeTruncates); - - return $truncate; - } - - /** - * Returns a delete database operation. - * - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function DELETE() - { - return new PHPUnit_Extensions_Database_Operation_Delete(); - } - - /** - * Returns a delete_all database operation. - * - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function DELETE_ALL() - { - return new PHPUnit_Extensions_Database_Operation_DeleteAll(); - } - - /** - * Returns an update database operation. - * - * @return PHPUnit_Extensions_Database_Operation_IDatabaseOperation - */ - public static function UPDATE() - { - return new PHPUnit_Extensions_Database_Operation_Update(); - } - -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 a basic interface and functionality for executing database - * operations against a connection using a specific dataSet. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - /** - * Executes the database operation against the given $connection for the - * given $dataSet. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - * @throws PHPUnit_Extensions_Database_Operation_Exception - */ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet); -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * This class provides functionality for inserting rows from a dataset into a database. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Insert extends PHPUnit_Extensions_Database_Operation_RowBased -{ - protected $operationName = 'INSERT'; - - protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $columnCount = count($table->getTableMetaData()->getColumns()); - - if ($columnCount > 0) { - $placeHolders = implode(', ', array_fill(0, $columnCount, '?')); - - $columns = ''; - foreach ($table->getTableMetaData()->getColumns() as $column) { - $columns .= $connection->quoteSchemaObject($column) . ', '; - } - - $columns = substr($columns, 0, -2); - - $query = " - INSERT INTO {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} - ({$columns}) - VALUES - ({$placeHolders}) - "; - - return $query; - } else { - return FALSE; - } - } - - protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) - { - $args = []; - foreach ($table->getTableMetaData()->getColumns() as $columnName) { - $args[] = $table->getValue($row, $columnName); - } - - return $args; - } - - protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - if (count($databaseTableMetaData->getPrimaryKeys())) { - return TRUE; - } - - return FALSE; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * This class represents a null database operation. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Null implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - /* do nothing */ - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Updates the rows in a given dataset using primary key columns. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Replace extends PHPUnit_Extensions_Database_Operation_RowBased -{ - protected $operationName = 'REPLACE'; - - protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $keys = $databaseTableMetaData->getPrimaryKeys(); - - $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection)); - - $query = " - SELECT COUNT(*) - FROM {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} - {$whereStatement} - "; - - return $query; - } - - protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) - { - $args = []; - - foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) { - $args[] = $table->getValue($row, $columnName); - } - - return $args; - } - - /** - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - $insertOperation = new PHPUnit_Extensions_Database_Operation_Insert; - $updateOperation = new PHPUnit_Extensions_Database_Operation_Update; - $databaseDataSet = $connection->createDataSet(); - - foreach ($dataSet as $table) { - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName()); - - $insertQuery = $insertOperation->buildOperationQuery($databaseTableMetaData, $table, $connection); - $updateQuery = $updateOperation->buildOperationQuery($databaseTableMetaData, $table, $connection); - $selectQuery = $this->buildOperationQuery($databaseTableMetaData, $table, $connection); - - $insertStatement = $connection->getConnection()->prepare($insertQuery); - $updateStatement = $connection->getConnection()->prepare($updateQuery); - $selectStatement = $connection->getConnection()->prepare($selectQuery); - - $rowCount = $table->getRowCount(); - - for ($i = 0; $i < $rowCount; $i++) { - $selectArgs = $this->buildOperationArguments($databaseTableMetaData, $table, $i); - $query = $selectQuery; - $args = $selectArgs; - - try { - $selectStatement->execute($selectArgs); - - if ($selectStatement->fetchColumn(0) > 0) { - $updateArgs = $updateOperation->buildOperationArguments($databaseTableMetaData, $table, $i); - $query = $updateQuery; - $args = $updateArgs; - - $updateStatement->execute($updateArgs); - } else { - $insertArgs = $insertOperation->buildOperationArguments($databaseTableMetaData, $table, $i); - $query = $insertQuery; - $args = $insertArgs; - - $insertStatement->execute($insertArgs); - } - } - - catch (Exception $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception( - $this->operationName, $query, $args, $table, $e->getMessage() - ); - } - } - } - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 basic functionality for row based operations. - * - * To create a row based operation you must create two functions. The first - * one, buildOperationQuery(), must return a query that will be used to create - * a prepared statement. The second one, buildOperationArguments(), should - * return an array containing arguments for each row. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_Operation_RowBased implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - const ITERATOR_TYPE_FORWARD = 0; - const ITERATOR_TYPE_REVERSE = 1; - - protected $operationName; - - protected $iteratorDirection = self::ITERATOR_TYPE_FORWARD; - - /** - * @return string|bool String containing the query or FALSE if a valid query cannot be constructed - */ - protected abstract function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection); - - protected abstract function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row); - - /** - * Allows an operation to disable primary keys if necessary. - * - * @param PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData - * @param PHPUnit_Extensions_Database_DataSet_ITable $table - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - */ - protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - return FALSE; - } - - /** - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - * @param PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet - */ - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - $databaseDataSet = $connection->createDataSet(); - - $dsIterator = $this->iteratorDirection == self::ITERATOR_TYPE_REVERSE ? $dataSet->getReverseIterator() : $dataSet->getIterator(); - - foreach ($dsIterator as $table) { - $rowCount = $table->getRowCount(); - - if($rowCount == 0) continue; - - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - $databaseTableMetaData = $databaseDataSet->getTableMetaData($table->getTableMetaData()->getTableName()); - $query = $this->buildOperationQuery($databaseTableMetaData, $table, $connection); - $disablePrimaryKeys = $this->disablePrimaryKeys($databaseTableMetaData, $table, $connection); - - if ($query === FALSE) { - if ($table->getRowCount() > 0) { - throw new PHPUnit_Extensions_Database_Operation_Exception($this->operationName, '', [], $table, 'Rows requested for insert, but no columns provided!'); - } - continue; - } - - if ($disablePrimaryKeys) { - $connection->disablePrimaryKeys($databaseTableMetaData->getTableName()); - } - - $statement = $connection->getConnection()->prepare($query); - - for ($i = 0; $i < $rowCount; $i++) { - $args = $this->buildOperationArguments($databaseTableMetaData, $table, $i); - - try { - $statement->execute($args); - } - - catch (Exception $e) { - throw new PHPUnit_Extensions_Database_Operation_Exception( - $this->operationName, $query, $args, $table, $e->getMessage() - ); - } - } - - if ($disablePrimaryKeys) { - $connection->enablePrimaryKeys($databaseTableMetaData->getTableName()); - } - } - } - - protected function buildPreparedColumnArray($columns, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $columnArray = []; - - foreach ($columns as $columnName) { - $columnArray[] = "{$connection->quoteSchemaObject($columnName)} = ?"; - } - - return $columnArray; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Executes a truncate against all tables in a dataset. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Truncate implements PHPUnit_Extensions_Database_Operation_IDatabaseOperation -{ - protected $useCascade = FALSE; - - public function setCascade($cascade = TRUE) - { - $this->useCascade = $cascade; - } - - public function execute(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection, PHPUnit_Extensions_Database_DataSet_IDataSet $dataSet) - { - foreach ($dataSet->getReverseIterator() as $table) { - /* @var $table PHPUnit_Extensions_Database_DataSet_ITable */ - $query = " - {$connection->getTruncateCommand()} {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} - "; - - if ($this->useCascade && $connection->allowsCascading()) { - $query .= ' CASCADE'; - } - - try { - $this->disableForeignKeyChecksForMysql($connection); - $connection->getConnection()->query($query); - $this->enableForeignKeyChecksForMysql($connection); - } catch (\Exception $e) { - $this->enableForeignKeyChecksForMysql($connection); - - if ($e instanceof PDOException) { - throw new PHPUnit_Extensions_Database_Operation_Exception('TRUNCATE', $query, [], $table, $e->getMessage()); - } - - throw $e; - } - } - } - - private function disableForeignKeyChecksForMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - if ($this->isMysql($connection)) { - $connection->getConnection()->query('SET FOREIGN_KEY_CHECKS = 0'); - } - } - - private function enableForeignKeyChecksForMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - if ($this->isMysql($connection)) { - $connection->getConnection()->query('SET FOREIGN_KEY_CHECKS = 1'); - } - } - - private function isMysql(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - return $connection->getConnection()->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql'; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Updates the rows in a given dataset using primary key columns. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_Operation_Update extends PHPUnit_Extensions_Database_Operation_RowBased -{ - protected $operationName = 'UPDATE'; - - protected function buildOperationQuery(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $keys = $databaseTableMetaData->getPrimaryKeys(); - $columns = $table->getTableMetaData()->getColumns(); - $whereStatement = 'WHERE ' . implode(' AND ', $this->buildPreparedColumnArray($keys, $connection)); - $setStatement = 'SET ' . implode(', ', $this->buildPreparedColumnArray($columns, $connection)); - - $query = " - UPDATE {$connection->quoteSchemaObject($table->getTableMetaData()->getTableName())} - {$setStatement} - {$whereStatement} - "; - - return $query; - } - - protected function buildOperationArguments(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, $row) - { - $args = []; - foreach ($table->getTableMetaData()->getColumns() as $columnName) { - $args[] = $table->getValue($row, $columnName); - } - - foreach ($databaseTableMetaData->getPrimaryKeys() as $columnName) { - $args[] = $table->getValue($row, $columnName); - } - - return $args; - } - - protected function disablePrimaryKeys(PHPUnit_Extensions_Database_DataSet_ITableMetaData $databaseTableMetaData, PHPUnit_Extensions_Database_DataSet_ITable $table, PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - if (count($databaseTableMetaData->getPrimaryKeys())) { - return TRUE; - } - - return FALSE; - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 TestCase extension that provides functionality for testing and asserting - * against a real database. - * - * @since Class available since Release 1.0.0 - */ -abstract class PHPUnit_Extensions_Database_TestCase extends PHPUnit_Framework_TestCase -{ - use PHPUnit_Extensions_Database_TestCase_Trait; -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -trait PHPUnit_Extensions_Database_TestCase_Trait -{ - /** - * @var PHPUnit_Extensions_Database_ITester - */ - protected $databaseTester; - - /** - * Closes the specified connection. - * - * @param PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection - */ - protected function closeConnection(PHPUnit_Extensions_Database_DB_IDatabaseConnection $connection) - { - $this->getDatabaseTester()->closeConnection($connection); - } - - /** - * Returns the test database connection. - * - * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection - */ - protected abstract function getConnection(); - - /** - * Gets the IDatabaseTester for this testCase. If the IDatabaseTester is - * not set yet, this method calls newDatabaseTester() to obtain a new - * instance. - * - * @return PHPUnit_Extensions_Database_ITester - */ - protected function getDatabaseTester() - { - if (empty($this->databaseTester)) { - $this->databaseTester = $this->newDatabaseTester(); - } - - return $this->databaseTester; - } - - /** - * Returns the test dataset. - * - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - protected abstract function getDataSet(); - - /** - * Returns the database operation executed in test setup. - * - * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation - */ - protected function getSetUpOperation() - { - return PHPUnit_Extensions_Database_Operation_Factory::CLEAN_INSERT(); - } - - /** - * Returns the database operation executed in test cleanup. - * - * @return PHPUnit_Extensions_Database_Operation_DatabaseOperation - */ - protected function getTearDownOperation() - { - return PHPUnit_Extensions_Database_Operation_Factory::NONE(); - } - - /** - * Creates a IDatabaseTester for this testCase. - * - * @return PHPUnit_Extensions_Database_ITester - */ - protected function newDatabaseTester() - { - return new PHPUnit_Extensions_Database_DefaultTester($this->getConnection()); - } - - /** - * Creates a new DefaultDatabaseConnection using the given PDO connection - * and database schema name. - * - * @param PDO $connection - * @param string $schema - * @return PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection - */ - protected function createDefaultDBConnection(PDO $connection, $schema = '') - { - return new PHPUnit_Extensions_Database_DB_DefaultDatabaseConnection($connection, $schema); - } - - /** - * Creates a new ArrayDataSet with the given array. - * The array parameter is an associative array of tables where the key is - * the table name and the value an array of rows. Each row is an associative - * array by itself with keys representing the field names and the values the - * actual data. - * For example: - * array( - * "addressbook" => array( - * array("id" => 1, "name" => "...", "address" => "..."), - * array("id" => 2, "name" => "...", "address" => "...") - * ) - * ) - * - * @param array $data - * @return PHPUnit_Extensions_Database_DataSet_ArrayDataSet - */ - protected function createArrayDataSet(array $data) - { - return new PHPUnit_Extensions_Database_DataSet_ArrayDataSet($data); - } - - /** - * Creates a new FlatXmlDataSet with the given $xmlFile. (absolute path.) - * - * @param string $xmlFile - * @return PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet - */ - protected function createFlatXMLDataSet($xmlFile) - { - return new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet($xmlFile); - } - - /** - * Creates a new XMLDataSet with the given $xmlFile. (absolute path.) - * - * @param string $xmlFile - * @return PHPUnit_Extensions_Database_DataSet_XmlDataSet - */ - protected function createXMLDataSet($xmlFile) - { - return new PHPUnit_Extensions_Database_DataSet_XmlDataSet($xmlFile); - } - - /** - * Create a a new MysqlXmlDataSet with the given $xmlFile. (absolute path.) - * - * @param string $xmlFile - * @return PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet - * @since Method available since Release 1.0.0 - */ - protected function createMySQLXMLDataSet($xmlFile) - { - return new PHPUnit_Extensions_Database_DataSet_MysqlXmlDataSet($xmlFile); - } - - /** - * Returns an operation factory instance that can be used to instantiate - * new operations. - * - * @return PHPUnit_Extensions_Database_Operation_Factory - */ - protected function getOperations() - { - return new PHPUnit_Extensions_Database_Operation_Factory(); - } - - /** - * Performs operation returned by getSetUpOperation(). - */ - protected function setUp() - { - parent::setUp(); - - $this->databaseTester = NULL; - - $this->getDatabaseTester()->setSetUpOperation($this->getSetUpOperation()); - $this->getDatabaseTester()->setDataSet($this->getDataSet()); - $this->getDatabaseTester()->onSetUp(); - } - - /** - * Performs operation returned by getTearDownOperation(). - */ - protected function tearDown() - { - $this->getDatabaseTester()->setTearDownOperation($this->getTearDownOperation()); - $this->getDatabaseTester()->setDataSet($this->getDataSet()); - $this->getDatabaseTester()->onTearDown(); - - /* - * Destroy the tester after the test is run to keep DB connections - * from piling up. - */ - $this->databaseTester = NULL; - } - - /** - * Asserts that two given tables are equal. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $expected - * @param PHPUnit_Extensions_Database_DataSet_ITable $actual - * @param string $message - */ - public static function assertTablesEqual(PHPUnit_Extensions_Database_DataSet_ITable $expected, PHPUnit_Extensions_Database_DataSet_ITable $actual, $message = '') - { - $constraint = new PHPUnit_Extensions_Database_Constraint_TableIsEqual($expected); - - self::assertThat($actual, $constraint, $message); - } - - /** - * Asserts that two given datasets are equal. - * - * @param PHPUnit_Extensions_Database_DataSet_ITable $expected - * @param PHPUnit_Extensions_Database_DataSet_ITable $actual - * @param string $message - */ - public static function assertDataSetsEqual(PHPUnit_Extensions_Database_DataSet_IDataSet $expected, PHPUnit_Extensions_Database_DataSet_IDataSet $actual, $message = '') - { - $constraint = new PHPUnit_Extensions_Database_Constraint_DataSetIsEqual($expected); - - self::assertThat($actual, $constraint, $message); - } - - /** - * Assert that a given table has a given amount of rows - * - * @param string $tableName Name of the table - * @param int $expected Expected amount of rows in the table - * @param string $message Optional message - */ - public function assertTableRowCount($tableName, $expected, $message = '') - { - $constraint = new PHPUnit_Extensions_Database_Constraint_TableRowCount($tableName, $expected); - $actual = $this->getConnection()->getRowCount($tableName); - - self::assertThat($actual, $constraint, $message); - } - - /** - * Asserts that a given table contains a given row - * - * @param array $expectedRow Row expected to find - * @param PHPUnit_Extensions_Database_DataSet_ITable $table Table to look into - * @param string $message Optional message - */ - public function assertTableContains(array $expectedRow, PHPUnit_Extensions_Database_DataSet_ITable $table, $message = '') - { - self::assertThat($table->assertContainsRow($expectedRow), self::isTrue(), $message); - } -} -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Delegates database extension commands to the appropriate mode classes. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_Command -{ - /** - * @var PHPUnit_Extensions_Database_UI_IModeFactory - */ - protected $modeFactory; - - /** - * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory - */ - public function __construct(PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory) - { - $this->modeFactory = $modeFactory; - } - - /** - * Executes the database extension ui. - * - * @param PHPUnit_Extensions_Database_UI_IMedium $medium - * @param PHPUnit_Extensions_Database_UI_Context $context - */ - public function main(PHPUnit_Extensions_Database_UI_IMedium $medium, PHPUnit_Extensions_Database_UI_Context $context) - { - try { - $medium->buildContext($context); - $mode = $this->modeFactory->getMode($context->getMode()); - $mode->execute($context->getModeArguments(), $medium); - - } catch (Exception $e) { - $medium->handleException($e); - } - } -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Holds the context of a particular database extension ui call. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_Context -{ - /** - * @var string - */ - protected $mode; - - /** - * @var array - */ - protected $modeArguments; - - /** - * @param string $mode - */ - public function setMode($mode) - { - $this->mode = $mode; - } - - /** - * @return string - */ - public function getMode() - { - return $this->mode; - } - - /** - * @param array $arguments - */ - public function setModeArguments(array $arguments) - { - $this->mode_arguments = $arguments; - } - - /** - * @return array - */ - public function getModeArguments() - { - return $this->mode_arguments; - } -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Defines the interface necessary to create new mediums. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_UI_IMedium extends PHPUnit_Extensions_Database_UI_IMediumPrinter -{ - /** - * Builds the context for the application. - * - * @param PHPUnit_Extensions_Database_UI_Context $context - */ - public function buildContext(PHPUnit_Extensions_Database_UI_Context $context); - - /** - * Handles the displaying of exceptions received from the application. - * - * @param Exception $e - */ - public function handleException(Exception $e); -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Defines the interface necessary to create new medium printers. - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_UI_IMediumPrinter -{ - /** - * Prints standard output messages. - * - * @param string $message - */ - public function output($message); - - /** - * Prints standard error messages. - * - * @param string $message - */ - public function error($message); -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Defines the interface necessary to create new modes - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_UI_IMode -{ - /** - * Executes the mode using the given arguments and medium. - * - * @param array $modeArguments - * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium - */ - public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium); -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) Sebastian Bergmann <sebastian@phpunit.de> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -/** - * Defines the interface necessary to create new mode factories - * - * @since Class available since Release 1.0.0 - */ -interface PHPUnit_Extensions_Database_UI_IModeFactory -{ - /** - * Generates a new mode based on a given name. - * - * @param string $mode - * @return PHPUnit_Extensions_Database_UI_IMode - */ - public function getMode($mode); - - /** - * Returns the names of valid modes this factory can create. - * - * @return array - */ - public function getModeList(); -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 exception thrown when an invalid mode is requested from a mode factory. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_InvalidModeException extends LogicException -{ - /** - * @var string - */ - protected $mode; - - /** - * @var PHPUnit_Extensions_Database_UI_IModeFactory - */ - protected $modeFactory; - - /** - * @param string $mode - * @param string $msg - * @param PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory - */ - public function __construct($mode, $msg, PHPUnit_Extensions_Database_UI_IModeFactory $modeFactory) - { - $this->mode = $mode; - $this->modeFactory = $modeFactory; - parent::__construct($msg); - } - - /** - * @return string - */ - public function getMode() - { - return $this->mode; - } - - /** - * @return array - */ - public function getValidModes() - { - return $this->modeFactory->getModeList(); - } -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 text medium for the database extension tool. - * - * This class builds the call context based on command line parameters and - * prints output to stdout and stderr as appropriate. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_Mediums_Text implements PHPUnit_Extensions_Database_UI_IMedium -{ - /** - * @var array - */ - protected $arguments; - - /** - * @var string - */ - protected $command; - - /** - * @param array $arguments - */ - public function __construct(Array $arguments) - { - $this->arguments = $arguments; - } - - /** - * Builds the context for the application. - * - * @param PHPUnit_Extensions_Database_UI_Context $context - */ - public function buildContext(PHPUnit_Extensions_Database_UI_Context $context) - { - $arguments = $this->arguments; - $this->command = array_shift($arguments); - - $context->setMode(array_shift($arguments)); - $context->setModeArguments($arguments); - } - - /** - * Handles the displaying of exceptions received from the application. - * - * @param Exception $e - */ - public function handleException(Exception $e) - { - try { - throw $e; - } catch (PHPUnit_Extensions_Database_UI_InvalidModeException $invalidMode) { - if ($invalidMode->getMode() == '') { - $this->error('Please Specify a Command!' . PHP_EOL); - } else { - $this->error('Command Does Not Exist: ' . $invalidMode->getMode() . PHP_EOL); - } - $this->error('Valid Commands:' . PHP_EOL); - - foreach ($invalidMode->getValidModes() as $mode) { - $this->error(' ' . $mode . PHP_EOL); - } - } catch (Exception $e) { - $this->error('Unknown Error: ' . $e->getMessage() . PHP_EOL); - } - } - - /** - * Prints the message to stdout. - * - * @param string $message - */ - public function output($message) - { - echo $message; - } - - /** - * Prints the message to stderr - * - * @param string $message - */ - public function error($message) - { - fputs(STDERR, $message); - } -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 default factory for db extension modes. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_ModeFactory implements PHPUnit_Extensions_Database_UI_IModeFactory -{ - /** - * Generates a new mode based on a given name. - * - * @param string $mode - * @return PHPUnit_Extensions_Database_UI_IMode - */ - public function getMode($mode) - { - if ($mode == '') { - throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'A mode was not provided.', $this); - } - - $modeMap = $this->getModeMap(); - if (isset($modeMap[$mode])) { - $modeClass = $this->getModeClass($mode, $modeMap[$mode]); - - return new $modeClass(); - } else { - throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode does not exist. Attempting to load mode ' . $mode, $this); - } - } - - /** - * Returns the names of valid modes this factory can create. - * - * @return array - */ - public function getModeList() - { - return array_keys($this->getModeMap()); - } - - /** - * Returns a map of modes to class name parts - * - * @return array - */ - protected function getModeMap() - { - return ['export-dataset' => 'ExportDataSet']; - } - - /** - * Given a $mode label and a $mode_name class part attempts to return the - * class name necessary to instantiate the mode. - * - * @param string $mode - * @param string $mode_name - * @return string - */ - protected function getModeClass($mode, $mode_name) - { - $modeClass = 'PHPUnit_Extensions_Database_UI_Modes_' . $mode_name; - $modeFile = dirname(__FILE__) . '/Modes/' . $mode_name . '.php'; - - if (class_exists($modeClass)) { - return $modeClass; - } - - if (!is_readable($modeFile)) { - throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode\'s file could not be loaded. Trying file ' . $modeFile, $this); - } - - require_once ($modeFile); - - if (!class_exists($modeClass)) { - throw new PHPUnit_Extensions_Database_UI_InvalidModeException($mode, 'The mode class was not found in the file. Expecting class name ' . $modeClass, $this); - } - - return $modeClass; - } -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 class for the export-dataset command. - * - * This command is used to convert existing data sets or data in the database - * into a valid data set format. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet implements PHPUnit_Extensions_Database_UI_IMode -{ - /** - * Executes the export dataset command. - * - * @param array $modeArguments - * @param PHPUnit_Extensions_Database_UI_IMediumPrinter $medium - */ - public function execute(array $modeArguments, PHPUnit_Extensions_Database_UI_IMediumPrinter $medium) - { - $arguments = new PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments($modeArguments); - - if (FALSE && !$arguments->areValid()) { - throw new InvalidArgumentException('The arguments for this command are incorrect.'); - } - - $datasets = []; - foreach ($arguments->getArgumentArray('dataset') as $argString) { - $datasets[] = $this->getDataSetFromArgument($argString, $arguments->getDatabases()); - } - - $finalDataset = new PHPUnit_Extensions_Database_DataSet_CompositeDataSet($datasets); - - $outputDataset = $this->getPersistorFromArgument($arguments->getSingleArgument('output')); - $outputDataset->write($finalDataset); - } - - /** - * Returns the correct dataset given an argument containing a dataset spec. - * - * @param string $argString - * @param array $databaseList - * @return PHPUnit_Extensions_Database_DataSet_IDataSet - */ - protected function getDataSetFromArgument($argString, $databaseList) - { - $dataSetSpecFactory = new PHPUnit_Extensions_Database_DataSet_Specs_Factory(); - list($type, $dataSetSpecStr) = explode(':', $argString, 2); - $dataSetSpec = $dataSetSpecFactory->getDataSetSpecByType($type); - - if ($dataSetSpec instanceof PHPUnit_Extensions_Database_IDatabaseListConsumer) { - $dataSetSpec->setDatabases($databaseList); - } - - return $dataSetSpec->getDataSet($dataSetSpecStr); - } - - /** - * Returns the correct persistor given an argument containing a persistor spec. - * - * @param string $argString - * @return PHPUnit_Extensions_Database_DataSet_IPersistable - */ - protected function getPersistorFromArgument($argString) - { - $persistorFactory = new PHPUnit_Extensions_Database_DataSet_Persistors_Factory(); - list($type, $spec) = explode(':', $argString, 2); - - return $persistorFactory->getPersistorBySpec($type, $spec); - } -} - -<?php -/* - * This file is part of DBUnit. - * - * (c) 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 arguments received from a medium. - * - * @since Class available since Release 1.0.0 - */ -class PHPUnit_Extensions_Database_UI_Modes_ExportDataSet_Arguments -{ - /** - * @var array - */ - protected $arguments = []; - - /** - * @param array $arguments - */ - public function __construct(array $arguments) - { - foreach ($arguments as $argument) { - list($argName, $argValue) = explode('=', $argument, 2); - - $argName = trim($argName, '-'); - - if (!isset($this->arguments[$argName])) { - $this->arguments[$argName] = []; - } - - $this->arguments[$argName][] = $argValue; - } - } - - /** - * Returns an array of arguments matching the given $argName - * - * @param string $argName - * @return array - */ - public function getArgumentArray($argName) - { - if ($this->argumentIsSet($argName)) { - return $this->arguments[$argName]; - } else { - return NULL; - } - } - - /** - * Returns a single argument value. - * - * If $argName points to an array the first argument will be returned. - * - * @param string $argName - * @return mixed - */ - public function getSingleArgument($argName) - { - if ($this->argumentIsSet($argName)) { - return reset($this->arguments[$argName]); - } else { - return NULL; - } - } - - /** - * Returns whether an argument is set. - * - * @param string $argName - * @return bool - */ - public function argumentIsSet($argName) - { - return array_key_exists($argName, $this->arguments); - } - - /** - * Returns an array containing the names of all arguments provided. - * - * @return array - */ - public function getArgumentNames() - { - return array_keys($this->arguments); - } - - /** - * Returns an array of database arguments keyed by name. - * - * @todo this should be moved. - * @return array - */ - public function getDatabases() - { - $databases = $this->getArgumentArray('database'); - - $retDb = []; - foreach ($databases as $db) { - list($name, $arg) = explode(':', $db, 2); - $retDb[$name] = $arg; - } - - return $retDb; - } -} - -<?php -/* - * This file is part of the PHP_Invoker 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. - */ - -declare(ticks = 1); - -/** - * Utility class for invoking callables with a timeout. - * - * @since Class available since Release 1.0.0 - */ -class PHP_Invoker -{ - /** - * @var int - */ - protected $timeout; - - /** - * Invokes a callable and raises an exception when the execution does not - * finish before the specified timeout. - * - * @param callable $callable - * @param array $arguments - * @param int $timeout in seconds - * @return mixed - * @throws InvalidArgumentException - */ - public function invoke($callable, array $arguments, $timeout) - { - if (!is_callable($callable)) { - throw new InvalidArgumentException; - } - - if (!is_integer($timeout)) { - throw new InvalidArgumentException; - } - - pcntl_signal(SIGALRM, array($this, 'callback'), TRUE); - pcntl_alarm($timeout); - - $this->timeout = $timeout; - - try { - $result = call_user_func_array($callable, $arguments); - } - - catch (Exception $e) { - pcntl_alarm(0); - throw $e; - } - - pcntl_alarm(0); - - return $result; - } - - /** - * Invoked by pcntl_signal() when a SIGALRM occurs. - */ - public function callback() - { - throw new PHP_Invoker_TimeoutException( - sprintf( - 'Execution aborted after %s', - PHP_Timer::secondsToTimeString($this->timeout) - ) - ); - } -} -<?php -/* - * This file is part of the PHP_Invoker 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 PHP_Invoker_TimeoutException extends RuntimeException -{ -} -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. - -<?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(); -}<?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(); -} -<?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('/^\\\\([\\w_\\\\]*)(?:[:]{2}\\$?([\\w_]+))?(?:\\(\\))?$/', $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; - } -} -<?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; - } -} -<?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(); -} -<?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); -} -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. -<?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 = array(); - - /** @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 = array(); - - /** @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; - } - - /** - * Adds a tag to this DocBlock. - * - * @param Tag $tag The tag to add. - * - * @return void - */ - private function addTag(Tag $tag) - { - $this->tags[] = $tag; - } -} -<?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; - } - - /** - * 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(); - } -} -<?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 "}". - //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); - } - -} -<?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\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 = array(); - - /** - * 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, '"') - ); - } -} -<?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; - - /** - * 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. - */ - public function __construct($indent = 0, $indentString = ' ', $indentFirstLine = true, $lineLength = null) - { - Assert::integer($indent); - Assert::string($indentString); - Assert::boolean($indentFirstLine); - Assert::nullOrInteger($lineLength); - - $this->indent = $indent; - $this->indentString = $indentString; - $this->isFirstLineIndented = $indentFirstLine; - $this->lineLength = $lineLength; - } - - /** - * 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{$indent} * {$text}\n{$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) { - $formatter = new DocBlock\Tags\Formatter\PassthroughFormatter(); - $tagText = $formatter->format($tag); - if ($wrapLength !== null) { - $tagText = wordwrap($tagText, $wrapLength); - } - $tagText = str_replace("\n", "\n{$indent} * ", $tagText); - - $comment .= "{$indent} * {$tagText}\n"; - } - - return $comment; - } -} -<?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); - - 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 = array(); - 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; - } -} -<?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(); -} -<?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); -} -<?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 . '<' . $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); - } -} -<?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); - } -} -<?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\DescriptionFactory; -use phpDocumentor\Reflection\Fqsen; -use phpDocumentor\Reflection\DocBlock\Description; -use phpDocumentor\Reflection\Types\Context as TypeContext; -use phpDocumentor\Reflection\FqsenResolver; -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() : ''); - } -} -<?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\Types\Context as TypeContext; -use phpDocumentor\Reflection\DocBlock\Description; -use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -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 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() : ''); - } -} -<?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; - -/** - * 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; - - /** - * {@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; - } - - $this->description = $filePath . ' ' . parent::getContent(); - } - - 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; - - // Starting line / Number of lines / Description - if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $matches[3], $matches)) { - $startingLine = (int)$matches[1]; - if (isset($matches[2]) && $matches[2] !== '') { - $lineCount = (int)$matches[2]; - } - $description = $matches[3]; - } - - return new static($filePath, $fileUri, $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; - } - - /** - * Sets the file path. - * - * @param string $filePath The new file path to use for the example. - * - * @return $this - */ - public function setFilePath($filePath) - { - $this->isURI = false; - $this->filePath = trim($filePath); - - $this->description = null; - return $this; - } - - /** - * Sets the file path as an URI. - * - * This function is equivalent to {@link setFilePath()}, except that it - * converts an URI to a file path before that. - * - * There is no getFileURI(), as {@link getFilePath()} is compatible. - * - * @param string $uri The new file URI to use as an example. - * - * @return $this - */ - public function setFileURI($uri) - { - $this->isURI = true; - $this->description = null; - - $this->filePath = $this->isUriRelative($uri) - ? rawurldecode(str_replace(array('/', '\\'), '%2F', $uri)) - : $this->filePath = $uri; - - return $this; - } - - /** - * Returns a string representation for this tag. - * - * @return string - */ - public function __toString() - { - return $this->filePath . ($this->description ? ' ' . $this->description->render() : ''); - } - - /** - * 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, ':'); - } -} -<?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); -} -<?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); -} -<?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); -} -<?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 '@' . $tag->getName() . ' ' . (string)$tag; - } -} -<?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.' - ); - } - } -} -<?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() : ''); - } -} -<?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\|_\\\\]+) - # 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'; - $returnType = $typeResolver->resolve($returnType, $context); - $description = $descriptionFactory->create($description, $context); - - if ('' !== $arguments) { - $arguments = explode(',', $arguments); - foreach($arguments as &$argument) { - $argument = explode(' ', trim($argument)); - if ($argument[0][0] === '$') { - $argumentName = substr($argument[0], 1); - $argumentType = new Void_(); - } else { - $argumentType = $typeResolver->resolve($argument[0], $context); - $argumentName = ''; - if (isset($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 ($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); - if ($keys !== [ 'name', 'type' ]) { - throw new \InvalidArgumentException( - 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true) - ); - } - } - - return $arguments; - } -} -<?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 : ''); - } -} -<?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 : ''); - } -} -<?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 : ''); - } -} -<?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 : ''); - } -} -<?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; - } -} -<?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\DescriptionFactory; -use phpDocumentor\Reflection\Fqsen; -use phpDocumentor\Reflection\FqsenResolver; -use phpDocumentor\Reflection\Types\Context as TypeContext; -use phpDocumentor\Reflection\DocBlock\Description; -use Webmozart\Assert\Assert; - -/** - * Reflection class for an {@}see tag in a Docblock. - */ -class See extends BaseTag implements Factory\StaticMethod -{ - protected $name = 'see'; - - /** @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); - $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; - - return new static($resolver->resolve($parts[0], $context), $description); - } - - /** - * 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() : ''); - } -} -<?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\Types\Context as TypeContext; -use phpDocumentor\Reflection\DocBlock\Description; -use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -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() : ''); - } -} -<?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() : ''); - } -} -<?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; - } -} -<?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(); - } -} -<?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 . ' ' : '') - . '$' . $this->variableName - . ($this->description ? ' ' . $this->description : ''); - } -} -<?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\Types\Context as TypeContext; -use phpDocumentor\Reflection\DocBlock\Description; -use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -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() : ''); - } -} -<?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(array("\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 array('', '', '', $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 = array(); - 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; - } -} -<?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); -} -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. -<?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 - */ - 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)); - } -} -<?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(); -} -<?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\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' => 'phpDocumentor\Reflection\Types\String_', - 'int' => 'phpDocumentor\Reflection\Types\Integer', - 'integer' => 'phpDocumentor\Reflection\Types\Integer', - 'bool' => 'phpDocumentor\Reflection\Types\Boolean', - 'boolean' => 'phpDocumentor\Reflection\Types\Boolean', - 'float' => 'phpDocumentor\Reflection\Types\Float_', - 'double' => 'phpDocumentor\Reflection\Types\Float_', - 'object' => 'phpDocumentor\Reflection\Types\Object_', - 'mixed' => 'phpDocumentor\Reflection\Types\Mixed', - 'array' => 'phpDocumentor\Reflection\Types\Array_', - 'resource' => 'phpDocumentor\Reflection\Types\Resource', - 'void' => 'phpDocumentor\Reflection\Types\Void_', - 'null' => 'phpDocumentor\Reflection\Types\Null_', - 'scalar' => 'phpDocumentor\Reflection\Types\Scalar', - 'callback' => 'phpDocumentor\Reflection\Types\Callable_', - 'callable' => 'phpDocumentor\Reflection\Types\Callable_', - 'false' => 'phpDocumentor\Reflection\Types\Boolean', - 'true' => 'phpDocumentor\Reflection\Types\Boolean', - 'self' => 'phpDocumentor\Reflection\Types\Self_', - '$this' => 'phpDocumentor\Reflection\Types\This', - 'static' => 'phpDocumentor\Reflection\Types\Static_' - ); - - /** @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->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; - } - - /** - * 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 - * - * @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); - } -} -<?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; - -/** - * 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 . '[]'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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 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 -{ - /** @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 - */ - 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); - } -} -<?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[count($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; - } -} -<?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 \ReflectionClass $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); - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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 - */ - 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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -<?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'; - } -} -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. -<?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); - } -} -<?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; - } -} -<?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 '*'; - } -} -<?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 '* [, ...]'; - } -} -<?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)); - } -} -<?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); - } -} -<?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(); - } -} -<?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; - } -} -<?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()'; - } -} -<?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; - } -} -<?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; - } -} -<?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)); - } -} -<?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); - } -} -<?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( - $actual, $this->value - ); - - try { - $comparator->assertEquals($actual, $this->value); - 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) - ); - } -} -<?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 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); - } -} -<?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(); -} -<?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); - } -} -<?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; - -/** - * Call object. - * - * @author Konstantin Kudryashov <ever.zet@gmail.com> - */ -class Call -{ - private $methodName; - private $arguments; - private $returnValue; - private $exception; - private $file; - private $line; - - /** - * 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; - - 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); - } -} -<?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\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]; }); - - // If Highest rated method prophecy has a promise - execute it or return null instead - $returnValue = null; - $exception = null; - if ($promise = $matches[0][1]->getPromise()) { - try { - $returnValue = $promise->execute($arguments, $prophecy, $matches[0][1]); - } catch (\Exception $e) { - $exception = $e; - } - } - - $this->recordedCalls[] = new Call( - $methodName, $arguments, $returnValue, $exception, $file, $line - ); - - 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 < $wildcard->scoreArguments($call->getArguments()) - ; - }) - ); - } - - private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName, - array $arguments) - { - $classname = get_class($prophecy->reveal()); - $argstring = implode(', ', array_map(array($this->util, 'stringify'), $arguments)); - $expected = implode("\n", array_map(function (MethodProphecy $methodProphecy) { - return sprintf(' - %s(%s)', - $methodProphecy->getMethodName(), - $methodProphecy->getArgumentsWildcard() - ); - }, call_user_func_array('array_merge', $prophecy->getMethodProphecies()))); - - return new UnexpectedCallException( - sprintf( - "Method call:\n". - " - %s(%s)\n". - "on %s was not expected, expected calls were:\n%s", - - $methodName, $argstring, $classname, $expected - ), - $prophecy, $methodName, $arguments - ); - } -} -<?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' - ); - } -} -<?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; - } -} -<?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); - } -} -<?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)); - } -} -<?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(); -} -<?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; - } -} -<?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; - } -} -<?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() { - - 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', - ); - } -} -<?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) - { - $parentClass = $node->getParentClass(); - $reflectionClass = new \ReflectionClass($parentClass); - - $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); - } - } - } - - /** - * Returns patch priority, which determines when patch will be applied. - * - * @return integer Priority number (higher - earlier) - */ - public function getPriority() - { - return 50; - } -} - -<?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; - } - - $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); - } - - $__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); - $node->addMethod($prophecyGetter); - } - - /** - * Returns patch priority, which determines when patch will be applied. - * - * @return int Priority number (higher - earlier) - */ - public function getPriority() - { - return 0; - } -} -<?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; - } -} -<?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)) { - $constructor->setCode('return parent::__construct("' . __FILE__ .'");'); - - 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'); - } -} -<?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; - } -} -<?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 -{ -} -<?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; - } -} -<?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 -{ - /** - * 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())), - version_compare(PHP_VERSION, '7.0', '>=') && $method->hasReturnType() - ? sprintf(': %s', $method->getReturnType()) - : '' - ); - $php .= $method->getCode()."\n"; - - return $php.'}'; - } - - private function generateArguments(array $arguments) - { - return array_map(function (Node\ArgumentNode $argument) { - $php = ''; - - if ($hint = $argument->getTypeHint()) { - switch ($hint) { - case 'array': - case 'callable': - $php .= $hint; - break; - - case 'string': - case 'int': - case 'float': - case 'bool': - if (version_compare(PHP_VERSION, '7.0', '>=')) { - $php .= $hint; - break; - } - // Fall-through to default case for PHP 5.x - - default: - $php .= '\\'.$hint; - } - } - - $php .= ' '.($argument->isPassedByReference() ? '&' : ''); - - $php .= $argument->isVariadic() ? '...' : ''; - - $php .= '$'.$argument->getName(); - - if ($argument->isOptional() && !$argument->isVariadic()) { - $php .= ' = '.var_export($argument->getDefault(), true); - } - - return $php; - }, $arguments); - } -} -<?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; - } -} -<?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', '>=') && true === $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 (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(); - } - - $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; - } - } -} -<?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; - - /** - * @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; - } -} -<?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) - { - 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()); - } - $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); - } -} -<?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\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; - - /** - * @var ArgumentNode[] - */ - private $arguments = array(); - - /** - * @param string $name - * @param string $code - */ - public function __construct($name, $code = null) - { - $this->name = $name; - $this->code = $code; - } - - 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) - { - switch ($type) { - case '': - $this->returnType = null; - break; - - case 'string'; - case 'float': - case 'int': - case 'bool': - case 'array': - case 'callable': - $this->returnType = $type; - break; - - case 'double': - case 'real': - $this->returnType = 'float'; - break; - - case 'boolean': - $this->returnType = 'bool'; - break; - - case 'integer': - $this->returnType = 'int'; - break; - - default: - $this->returnType = '\\' . ltrim($type, '\\'); - } - } - - public function getReturnType() - { - return $this->returnType; - } - - /** - * @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; - } -} -<?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 -{ -} -<?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; - } -} -<?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++); - } -} -<?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; - } -} -<?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; - } -} -<?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; - } -} -<?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; - } -} -<?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 -{ -} -<?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 -{ -} -<?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(); - } -} -<?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; - } - - } -<?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 - */ - private $classname; - - /** - * @var string - */ - private $methodName; - - /** - * @var array - */ - private $arguments; - - /** - * @param string $message - * @param string $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; - } -} -<?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; - } -} -<?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(); -} -<?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 -{ -} -<?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"; - - $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; - } -} -<?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 -{ -} -<?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 -{ -} -<?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 -{ -} -<?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; - } -} -<?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; - } -} -<?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; - } -} -<?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; - } -} -<?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 -{ -} -<?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; - } -} -<?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(); - } - } -} -<?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'); - } -} -<?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); -} -<?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); - } -} -<?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); - } -} -<?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); - } -} -<?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); - } -} -<?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); -} -<?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); - } -} -<?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); -} -<?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; - } -} -<?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; - } -} -<?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 $exception Exception class name or instance - * - * @throws \Prophecy\Exception\InvalidArgumentException - */ - public function __construct($exception) - { - if (is_string($exception)) { - if (!class_exists($exception) - && 'Exception' !== $exception - && !is_subclass_of($exception, 'Exception')) { - throw new InvalidArgumentException(sprintf( - 'Exception class or instance expected as argument to ThrowPromise, but got %s.', - $exception - )); - } - } elseif (!$exception instanceof \Exception) { - throw new InvalidArgumentException(sprintf( - 'Exception 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; - } -} -<?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; - - /** - * 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(); - $this->will(function () use ($type) { - switch ($type) { - 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() - { - 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) - { - 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)); - } - - /** - * 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->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 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; - } - - private function bindToObjectProphecy() - { - if ($this->bound) { - return; - } - - $this->getObjectProphecy()->addMethodProphecy($this); - $this->bound = true; - } -} -<?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); - } -} -<?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(); -} -<?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(); -} -<?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; - } -} -<?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); -} -<?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\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; - } - } -} -<?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; - } - - $key = $processed->add($value); - $values = ''; - - if (count($value) > 0) { - foreach ($value 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); - } -} -<?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 -{ - /** - * 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 (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)); - } -} -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. -<?php - -namespace DeepCopy; - -use DeepCopy\Exception\CloneException; -use DeepCopy\Filter\Filter; -use DeepCopy\Matcher\Matcher; -use DeepCopy\TypeFilter\TypeFilter; -use DeepCopy\TypeMatcher\TypeMatcher; -use ReflectionProperty; -use DeepCopy\Reflection\ReflectionHelper; - -/** - * DeepCopy - */ -class DeepCopy -{ - /** - * @var array - */ - private $hashMap = []; - - /** - * Filters to apply. - * @var array - */ - private $filters = []; - - /** - * Type Filters to apply. - * @var array - */ - private $typeFilters = []; - - private $skipUncloneable = false; - - /** - * Cloning uncloneable properties won't throw exception. - * @param $skipUncloneable - * @return $this - */ - public function skipUncloneable($skipUncloneable = true) - { - $this->skipUncloneable = $skipUncloneable; - return $this; - } - - /** - * Perform a deep copy of the 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) - { - $copier = function($item) { - return $this->recursiveCopy($item); - }; - - return array_map($copier, $array); - } - - /** - * Copy an object - * @param object $object - * @return object - */ - private function copyObject($object) - { - $objectHash = spl_object_hash($object); - - if (isset($this->hashMap[$objectHash])) { - return $this->hashMap[$objectHash]; - } - - $reflectedObject = new \ReflectionObject($object); - - if (false === $isCloneable = $reflectedObject->isCloneable() and $this->skipUncloneable) { - $this->hashMap[$objectHash] = $object; - return $object; - } - - if (false === $isCloneable) { - throw new CloneException(sprintf( - 'Class "%s" is not cloneable.', - $reflectedObject->getName() - )); - } - - $newObject = clone $object; - $this->hashMap[$objectHash] = $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 - * @param callable $predicate Predicate arguments are: element. - * @return mixed|null - */ - private function first(array $elements, callable $predicate) - { - foreach ($elements as $element) { - if (call_user_func($predicate, $element)) { - return $element; - } - } - - return null; - } -} -<?php -namespace DeepCopy\Exception; - -class CloneException extends \UnexpectedValueException -{ -} <?php - -namespace DeepCopy\Filter\Doctrine; - -use DeepCopy\Filter\Filter; -use ReflectionProperty; - -/** - * Set a null value for a property - */ -class DoctrineCollectionFilter implements Filter -{ - /** - * {@inheritdoc} - */ - public function apply($object, $property, $objectCopier) - { - $reflectionProperty = new ReflectionProperty($object, $property); - - $reflectionProperty->setAccessible(true); - $oldCollection = $reflectionProperty->getValue($object); - - $newCollection = $oldCollection->map( - function ($item) use ($objectCopier) { - return $objectCopier($item); - } - ); - - $reflectionProperty->setValue($object, $newCollection); - } -} -<?php - -namespace DeepCopy\Filter\Doctrine; - -use DeepCopy\Filter\Filter; -use Doctrine\Common\Collections\ArrayCollection; - -class DoctrineEmptyCollectionFilter implements Filter -{ - /** - * Apply the filter to the object. - * - * @param object $object - * @param string $property - * @param callable $objectCopier - */ - public function apply($object, $property, $objectCopier) - { - $reflectionProperty = new \ReflectionProperty($object, $property); - $reflectionProperty->setAccessible(true); - - $reflectionProperty->setValue($object, new ArrayCollection()); - } -} <?php - -namespace DeepCopy\Filter; - -/** - * Filter to apply to a property while copying an object - */ -interface Filter -{ - /** - * Apply the filter to the object. - * @param object $object - * @param string $property - * @param callable $objectCopier - */ - public function apply($object, $property, $objectCopier); -} -<?php - -namespace DeepCopy\Filter; - -/** - * Keep the value of a property - */ -class KeepFilter implements Filter -{ - /** - * {@inheritdoc} - */ - public function apply($object, $property, $objectCopier) - { - // Nothing to do - } -} -<?php - -namespace DeepCopy\Filter; - -/** - * Replace the value of a property - */ -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; - } - - /** - * {@inheritdoc} - */ - public function apply($object, $property, $objectCopier) - { - $reflectionProperty = new \ReflectionProperty($object, $property); - $reflectionProperty->setAccessible(true); - - $value = call_user_func($this->callback, $reflectionProperty->getValue($object)); - - $reflectionProperty->setValue($object, $value); - } -} -<?php - -namespace DeepCopy\Filter; - -use ReflectionProperty; - -/** - * Set a null value for a property - */ -class SetNullFilter implements Filter -{ - /** - * {@inheritdoc} - */ - public function apply($object, $property, $objectCopier) - { - $reflectionProperty = new ReflectionProperty($object, $property); - - $reflectionProperty->setAccessible(true); - $reflectionProperty->setValue($object, null); - } -} -<?php - -namespace DeepCopy\Matcher; - -/** - * Matcher interface - */ -interface Matcher -{ - /** - * @param object $object - * @param string $property - * @return boolean - */ - public function matches($object, $property); -} -<?php - -namespace DeepCopy\Matcher; - -/** - * Match a specific property of a specific class - */ -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; - } - - /** - * {@inheritdoc} - */ - public function matches($object, $property) - { - return ($object instanceof $this->class) && ($property == $this->property); - } -} -<?php - -namespace DeepCopy\Matcher; - -/** - * Match a property by its name - */ -class PropertyNameMatcher implements Matcher -{ - /** - * @var string - */ - private $property; - - /** - * @param string $property Property name - */ - public function __construct($property) - { - $this->property = $property; - } - - /** - * {@inheritdoc} - */ - public function matches($object, $property) - { - return $property == $this->property; - } -} -<?php - -namespace DeepCopy\Matcher; - -use ReflectionProperty; - -/** - * Match a property by its type - * - * @deprecated 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. - */ -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) - { - $reflectionProperty = new ReflectionProperty($object, $property); - $reflectionProperty->setAccessible(true); - - return $reflectionProperty->getValue($object) instanceof $this->propertyType; - } -} -<?php - -namespace DeepCopy\Reflection; - -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) { - $f = $prop->getName(); - $propsArr[$f] = $prop; - } - - if ($parentClass = $ref->getParentClass()) { - $parentPropsArr = self::getProperties($parentClass); - if (count($parentPropsArr) > 0) { - $propsArr = array_merge($parentPropsArr, $propsArr); - } - } - return $propsArr; - } -} -<?php - -namespace DeepCopy\TypeFilter; - -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); - } -} -<?php - -namespace DeepCopy\TypeFilter; - -class ShallowCopyFilter implements TypeFilter -{ - /** - * {@inheritdoc} - */ - public function apply($element) - { - return clone $element; - } -} -<?php - -namespace DeepCopy\TypeFilter; - -interface TypeFilter -{ - /** - * Apply the filter to the object. - * @param mixed $element - */ - public function apply($element); -} -<?php - -namespace DeepCopy\TypeMatcher; - -/** - * TypeMatcher class - */ -class TypeMatcher -{ - /** - * @var string - */ - private $type; - - /** - * @param string $type - */ - public function __construct($type) - { - $this->type = $type; - } - - /** - * @param $element - * @return boolean - */ - public function matches($element) - { - return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type; - } -} -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. -<?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 BadMethodCallException; -use InvalidArgumentException; -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 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 nullOrIsInstanceOf($value, $class, $message = '') - * @method static void nullOrNotInstanceOf($value, $class, $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 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 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 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 allIsInstanceOf($values, $class, $message = '') - * @method static void allNotInstanceOf($values, $class, $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 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 = '') - * - * @since 1.0 - * - * @author Bernhard Schussek <bschussek@gmail.com> - */ -class Assert -{ - public static function string($value, $message = '') - { - if (!is_string($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a string. Got: %s', - self::typeToString($value) - )); - } - } - - public static function stringNotEmpty($value, $message = '') - { - self::string($value, $message); - self::notEmpty($value, $message); - } - - public static function integer($value, $message = '') - { - if (!is_int($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an integer. Got: %s', - self::typeToString($value) - )); - } - } - - public static function integerish($value, $message = '') - { - if (!is_numeric($value) || $value != (int) $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an integerish value. Got: %s', - self::typeToString($value) - )); - } - } - - public static function float($value, $message = '') - { - if (!is_float($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a float. Got: %s', - self::typeToString($value) - )); - } - } - - public static function numeric($value, $message = '') - { - if (!is_numeric($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a numeric. Got: %s', - self::typeToString($value) - )); - } - } - - public static function boolean($value, $message = '') - { - if (!is_bool($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a boolean. Got: %s', - self::typeToString($value) - )); - } - } - - public static function scalar($value, $message = '') - { - if (!is_scalar($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a scalar. Got: %s', - self::typeToString($value) - )); - } - } - - public static function resource($value, $type = null, $message = '') - { - if (!is_resource($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a resource. Got: %s', - self::typeToString($value) - )); - } - - if ($type && $type !== get_resource_type($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a resource of type %2$s. Got: %s', - self::typeToString($value), - $type - )); - } - } - - public static function isCallable($value, $message = '') - { - if (!is_callable($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a callable. Got: %s', - self::typeToString($value) - )); - } - } - - public static function isArray($value, $message = '') - { - if (!is_array($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an array. Got: %s', - self::typeToString($value) - )); - } - } - - public static function isTraversable($value, $message = '') - { - if (!is_array($value) && !($value instanceof Traversable)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a traversable. Got: %s', - self::typeToString($value) - )); - } - } - - public static function isInstanceOf($value, $class, $message = '') - { - if (!($value instanceof $class)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an instance of %2$s. Got: %s', - self::typeToString($value), - $class - )); - } - } - - public static function notInstanceOf($value, $class, $message = '') - { - if ($value instanceof $class) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an instance other than %2$s. Got: %s', - self::typeToString($value), - $class - )); - } - } - - public static function isEmpty($value, $message = '') - { - if (!empty($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an empty value. Got: %s', - self::valueToString($value) - )); - } - } - - public static function notEmpty($value, $message = '') - { - if (empty($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a non-empty value. Got: %s', - self::valueToString($value) - )); - } - } - - public static function null($value, $message = '') - { - if (null !== $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected null. Got: %s', - self::valueToString($value) - )); - } - } - - public static function notNull($value, $message = '') - { - if (null === $value) { - throw new InvalidArgumentException( - $message ?: 'Expected a value other than null.' - ); - } - } - - public static function true($value, $message = '') - { - if (true !== $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to be true. Got: %s', - self::valueToString($value) - )); - } - } - - public static function false($value, $message = '') - { - if (false !== $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to be false. Got: %s', - self::valueToString($value) - )); - } - } - - public static function eq($value, $value2, $message = '') - { - if ($value2 != $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value equal to %2$s. Got: %s', - self::valueToString($value), - self::valueToString($value2) - )); - } - } - - public static function notEq($value, $value2, $message = '') - { - if ($value2 == $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a different value than %s.', - self::valueToString($value2) - )); - } - } - - public static function same($value, $value2, $message = '') - { - if ($value2 !== $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value identical to %2$s. Got: %s', - self::valueToString($value), - self::valueToString($value2) - )); - } - } - - public static function notSame($value, $value2, $message = '') - { - if ($value2 === $value) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value not identical to %s.', - self::valueToString($value2) - )); - } - } - - public static function greaterThan($value, $limit, $message = '') - { - if ($value <= $limit) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value greater than %2$s. Got: %s', - self::valueToString($value), - self::valueToString($limit) - )); - } - } - - public static function greaterThanEq($value, $limit, $message = '') - { - if ($value < $limit) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value greater than or equal to %2$s. Got: %s', - self::valueToString($value), - self::valueToString($limit) - )); - } - } - - public static function lessThan($value, $limit, $message = '') - { - if ($value >= $limit) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value less than %2$s. Got: %s', - self::valueToString($value), - self::valueToString($limit) - )); - } - } - - public static function lessThanEq($value, $limit, $message = '') - { - if ($value > $limit) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value less than or equal to %2$s. Got: %s', - self::valueToString($value), - self::valueToString($limit) - )); - } - } - - public static function range($value, $min, $max, $message = '') - { - if ($value < $min || $value > $max) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value between %2$s and %3$s. Got: %s', - self::valueToString($value), - self::valueToString($min), - self::valueToString($max) - )); - } - } - - public static function oneOf($value, array $values, $message = '') - { - if (!in_array($value, $values, true)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected one of: %2$s. Got: %s', - self::valueToString($value), - implode(', ', array_map(array(__CLASS__, 'valueToString'), $values)) - )); - } - } - - public static function contains($value, $subString, $message = '') - { - if (false === strpos($value, $subString)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain %2$s. Got: %s', - self::valueToString($value), - self::valueToString($subString) - )); - } - } - - public static function startsWith($value, $prefix, $message = '') - { - if (0 !== strpos($value, $prefix)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to start with %2$s. Got: %s', - self::valueToString($value), - self::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) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to start with a letter. Got: %s', - self::valueToString($value) - )); - } - } - - public static function endsWith($value, $suffix, $message = '') - { - if ($suffix !== substr($value, -self::strlen($suffix))) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to end with %2$s. Got: %s', - self::valueToString($value), - self::valueToString($suffix) - )); - } - } - - public static function regex($value, $pattern, $message = '') - { - if (!preg_match($pattern, $value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'The value %s does not match the expected pattern.', - self::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) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain only letters. Got: %s', - self::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) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain digits only. Got: %s', - self::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) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain letters and digits only. Got: %s', - self::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) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain lowercase characters only. Got: %s', - self::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) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain uppercase characters only. Got: %s', - self::valueToString($value) - )); - } - } - - public static function length($value, $length, $message = '') - { - if ($length !== self::strlen($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain %2$s characters. Got: %s', - self::valueToString($value), - $length - )); - } - } - - public static function minLength($value, $min, $message = '') - { - if (self::strlen($value) < $min) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain at least %2$s characters. Got: %s', - self::valueToString($value), - $min - )); - } - } - - public static function maxLength($value, $max, $message = '') - { - if (self::strlen($value) > $max) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain at most %2$s characters. Got: %s', - self::valueToString($value), - $max - )); - } - } - - public static function lengthBetween($value, $min, $max, $message = '') - { - $length = self::strlen($value); - - if ($length < $min || $length > $max) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s', - self::valueToString($value), - $min, - $max - )); - } - } - - public static function fileExists($value, $message = '') - { - self::string($value); - - if (!file_exists($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'The file %s does not exist.', - self::valueToString($value) - )); - } - } - - public static function file($value, $message = '') - { - self::fileExists($value, $message); - - if (!is_file($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'The path %s is not a file.', - self::valueToString($value) - )); - } - } - - public static function directory($value, $message = '') - { - self::fileExists($value, $message); - - if (!is_dir($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'The path %s is no directory.', - self::valueToString($value) - )); - } - } - - public static function readable($value, $message = '') - { - if (!is_readable($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'The path %s is not readable.', - self::valueToString($value) - )); - } - } - - public static function writable($value, $message = '') - { - if (!is_writable($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'The path %s is not writable.', - self::valueToString($value) - )); - } - } - - public static function classExists($value, $message = '') - { - if (!class_exists($value)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an existing class name. Got: %s', - self::valueToString($value) - )); - } - } - - public static function subclassOf($value, $class, $message = '') - { - if (!is_subclass_of($value, $class)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected a sub-class of %2$s. Got: %s', - self::valueToString($value), - self::valueToString($class) - )); - } - } - - public static function implementsInterface($value, $interface, $message = '') - { - if (!in_array($interface, class_implements($value))) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected an implementation of %2$s. Got: %s', - self::valueToString($value), - self::valueToString($interface) - )); - } - } - - public static function keyExists($array, $key, $message = '') - { - if (!array_key_exists($key, $array)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected the key %s to exist.', - self::valueToString($key) - )); - } - } - - public static function keyNotExists($array, $key, $message = '') - { - if (array_key_exists($key, $array)) { - throw new InvalidArgumentException(sprintf( - $message ?: 'Expected the key %s to not exist.', - self::valueToString($key) - )); - } - } - - 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)) { - self::isTraversable($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); - } - - private function __construct() - { - } -} -<?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. - * - * @since Interface available since Release 4.0.0 - */ -interface PHPUnit_Exception -{ -} -<?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> - * - * @since Class available since Release 3.3.0 - */ -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); - } - } - } - } - } - } -} -<?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. - * - * @since Class available since Release 3.1.4 - */ -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', - 'track_errors=1', - '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 - ); - } - - /** - * @return array - */ - private function cleanupForCoverage() - { - $files = $this->getCoverageFiles(); - $coverage = @unserialize(file_get_contents($files['coverage'])); - - foreach ($files as $file) { - @unlink($file); - } - - return $coverage; - } - - /** - * 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; - } -} -<?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. - * - * @since Class available since Release 3.1.4 - */ -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'); - } - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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_integer($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; - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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; - } -} -<?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. - * - * @since Class available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 4.0.0 - */ - public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) - { - } - - /** - * Skipped test. - * - * @param PHPUnit_Framework_Test $test - * @param Exception $e - * @param float $time - * - * @since Method available since Release 3.0.0 - */ - public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) - { - } - - /** - * A test suite started. - * - * @param PHPUnit_Framework_TestSuite $suite - * - * @since Method available since Release 2.2.0 - */ - public function startTestSuite(PHPUnit_Framework_TestSuite $suite) - { - } - - /** - * A test suite ended. - * - * @param PHPUnit_Framework_TestSuite $suite - * - * @since Method available since Release 2.2.0 - */ - 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); -} -<?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; - -class TestCase extends PHPUnit_Framework_TestCase -{ -} -<?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 assert methods. - * - * @since Class available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ - public static function assertArrayHasKey($key, $array, $message = '') - { - if (!(is_integer($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 - * - * @since Method available since Release 4.4.0 - */ - public static function assertArraySubset($subset, $array, $strict = false, $message = '') - { - if (!is_array($subset)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory( - 1, - 'array or ArrayAccess' - ); - } - - if (!is_array($array)) { - 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 - * - * @since Method available since Release 3.0.0 - */ - public static function assertArrayNotHasKey($key, $array, $message = '') - { - if (!(is_integer($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 - * - * @since Method available since Release 2.1.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 2.1.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.1.4 - */ - 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 - * - * @since Method available since Release 3.1.4 - */ - 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 - * - * @since Method available since Release 3.1.4 - */ - 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 - * - * @since Method available since Release 3.1.4 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - 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 - * - * @since Method available since Release 2.3.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.2.14 - */ - 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 - * - * @since Method available since Release 3.2.14 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 exists. - * - * @param string $filename - * @param string $message - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 2.1.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.7.20 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - public static function anything() - { - return new PHPUnit_Framework_Constraint_IsAnything; - } - - /** - * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object. - * - * @return PHPUnit_Framework_Constraint_IsTrue - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - public static function isFalse() - { - return new PHPUnit_Framework_Constraint_IsFalse; - } - - /** - * Returns a PHPUnit_Framework_Constraint_IsJson matcher object. - * - * @return PHPUnit_Framework_Constraint_IsJson - * - * @since Method available since Release 3.7.20 - */ - public static function isJson() - { - return new PHPUnit_Framework_Constraint_IsJson; - } - - /** - * Returns a PHPUnit_Framework_Constraint_IsNull matcher object. - * - * @return PHPUnit_Framework_Constraint_IsNull - * - * @since Method available since Release 3.3.0 - */ - public static function isNull() - { - return new PHPUnit_Framework_Constraint_IsNull; - } - - /** - * Returns a PHPUnit_Framework_Constraint_IsFinite matcher object. - * - * @return PHPUnit_Framework_Constraint_IsFinite - * - * @since Method available since Release 5.0.0 - */ - public static function isFinite() - { - return new PHPUnit_Framework_Constraint_IsFinite; - } - - /** - * Returns a PHPUnit_Framework_Constraint_IsInfinite matcher object. - * - * @return PHPUnit_Framework_Constraint_IsInfinite - * - * @since Method available since Release 5.0.0 - */ - public static function isInfinite() - { - return new PHPUnit_Framework_Constraint_IsInfinite; - } - - /** - * Returns a PHPUnit_Framework_Constraint_IsNan matcher object. - * - * @return PHPUnit_Framework_Constraint_IsNan - * - * @since Method available since Release 5.0.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.1.4 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - public static function isEmpty() - { - return new PHPUnit_Framework_Constraint_IsEmpty; - } - - /** - * Returns a PHPUnit_Framework_Constraint_FileExists matcher object. - * - * @return PHPUnit_Framework_Constraint_FileExists - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - public static function markTestIncomplete($message = '') - { - throw new PHPUnit_Framework_IncompleteTestError($message); - } - - /** - * Mark the test as skipped. - * - * @param string $message - * - * @throws PHPUnit_Framework_SkippedTestError - * - * @since Method available since Release 3.0.0 - */ - public static function markTestSkipped($message = '') - { - throw new PHPUnit_Framework_SkippedTestError($message); - } - - /** - * Return the current assertion count. - * - * @return int - * - * @since Method available since Release 3.3.3 - */ - public static function getCount() - { - return self::$count; - } - - /** - * Reset the assertion counter. - * - * @since Method available since Release 3.3.3 - */ - public static function resetCount() - { - self::$count = 0; - } -} -<?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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 4.4.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.4 - */ -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 - * - * @since Method available since Release 3.6.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.4 - */ -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 - * - * @since Method available since Release 3.6.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 2.1.0 - */ -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 - * - * @since Method available since Release 3.1.4 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.2.14 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.2.14 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.7.20 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 2.1.0 - */ -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 - * - * @since Method available since Release 3.1.4 - */ -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 - * - * @since Method available since Release 2.3.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 2.1.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.4 - */ -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_IsEqual matcher object. - * - * @param mixed $value - * @param float $delta - * @param int $maxDepth - * @param bool $canonicalize - * @param bool $ignoreCase - * - * @return PHPUnit_Framework_Constraint_IsEqual - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.7.20 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -function objectHasAttribute($attributeName) -{ - return call_user_func_array( - 'PHPUnit_Framework_Assert::objectHasAttribute', - func_get_args() - ); -} - -/** - * @param mixed $value, ... - * - * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -function once() -{ - return call_user_func_array( - 'PHPUnit_Framework_TestCase::once', - func_get_args() - ); -} - -/** - * @param int $argumentIndex - * - * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument - * - * @since Method available since Release 3.3.0 - */ -function returnArgument($argumentIndex) -{ - return call_user_func_array( - 'PHPUnit_Framework_TestCase::returnArgument', - func_get_args() - ); -} - -/** - * @param mixed $callback - * - * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback - * - * @since Method available since Release 3.3.0 - */ -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 - * - * @since Method available since Release 3.6.0 - */ -function returnSelf() -{ - return call_user_func_array( - 'PHPUnit_Framework_TestCase::returnSelf', - func_get_args() - ); -} - -/** - * @param mixed $value - * - * @return PHPUnit_Framework_MockObject_Stub_Return - * - * @since Method available since Release 3.0.0 - */ -function returnValue($value) -{ - return call_user_func_array( - 'PHPUnit_Framework_TestCase::returnValue', - func_get_args() - ); -} - -/** - * @param array $valueMap - * - * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap - * - * @since Method available since Release 3.6.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ -function stringStartsWith($prefix) -{ - return call_user_func_array( - 'PHPUnit_Framework_Assert::stringStartsWith', - func_get_args() - ); -} - -/** - * @param Exception $exception - * - * @return PHPUnit_Framework_MockObject_Stub_Exception - * - * @since Method available since Release 3.1.0 - */ -function throwException(Exception $exception) -{ - return call_user_func_array( - 'PHPUnit_Framework_TestCase::throwException', - func_get_args() - ); -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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(); - } -} -<?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. - * @since Class available since Release 4.0.0 - */ -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) - { - } -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Framework_CodeCoverageException extends PHPUnit_Framework_Exception -{ -} -<?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 are placed upon any value. - * - * @since Interface available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - 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(); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - public function count() - { - $count = 0; - - foreach ($this->constraints as $constraint) { - $count += count($constraint); - } - - return $count; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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(); - } -} -<?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. - * - * @since Class available since Release 4.4.0 - */ -class PHPUnit_Framework_Constraint_ArraySubset extends PHPUnit_Framework_Constraint -{ - /** - * @var array|ArrayAccess - */ - protected $subset; - - /** - * @var bool - */ - protected $strict; - - /** - * @param array|ArrayAccess $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|ArrayAccess $other Array or ArrayAccess object to evaluate. - * - * @return bool - */ - protected function matches($other) - { - $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(); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.1.0 - */ -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(); - } -} -<?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'; - } -} -<?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. - * - * @since Class available since Release 3.1.0 - */ -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() - ); - } -} -<?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. - * - * @since Class available since Release 3.1.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ - public function toString() - { - return sprintf( - 'has static attribute "%s"', - $this->attributeName - ); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.1.0 - */ -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); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.6.0 - */ -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; - } - - $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 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 - ); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.6.6 - */ -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 - ); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.6.6 - */ -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 '; - } -} -<?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. - */ - -/** - * @since Class available since Release 3.6.6 - */ -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) - { - 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) - { - return sprintf( - "exception message '%s' contains '%s'", - $other->getMessage(), - $this->expectedMessage - ); - } - - /** - * @return string - */ - public function toString() - { - return 'exception message contains '; - } -} -<?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. - */ - -/** - * @since Class available since Release 4.3.0 - */ -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 '; - } -} -<?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(). - * - * @since Class available since Release 3.0.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.5.0 - */ - public function count() - { - return 0; - } -} -<?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(). - * - * @since Class available since Release 3.5.0 - */ -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() - ); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - ); - } - } -} -<?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. - * - * @since Class available since Release 3.3.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 5.0.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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_double($this->value) && is_double($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); - } - } -} -<?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. - * - * @since Class available since Release 5.0.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.7.20 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 5.0.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.3.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.3.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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_integer($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 - ); - } -} -<?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. - * - * @since Class available since Release 3.7.0 - */ -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 - ); - } -} -<?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. - * - * @since Class available since Release 3.7.0 - */ -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; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - public function count() - { - return count($this->constraint); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - public function count() - { - $count = 0; - - foreach ($this->constraints as $constraint) { - $count += count($constraint); - } - - return $count; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - ); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.6.0 - */ -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)); - } -} -<?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 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. - * - * @since Class available since Release 3.0.0 - */ -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 stripos($other, $this->string) !== false; - } else { - return strpos($other, $this->string) !== false; - } - } - - /** - * Returns a string representation of the constraint. - * - * @return string - */ - public function toString() - { - if ($this->ignoreCase) { - $string = strtolower($this->string); - } else { - $string = $this->string; - } - - return sprintf( - 'contains "%s"', - $string - ); - } -} -<?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. - * - * @since Class available since Release 3.4.0 - */ -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 . '"'; - } -} -<?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; - -/** - * ... - * - * @since Class available since Release 3.5.0 - */ -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'; - } -} -<?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. - * - * @since Class available since Release 3.4.0 - */ -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 . '"'; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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() - ); - } -} -<?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. - * - * @since Class available since Release 3.1.4 - */ -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 . '"'; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - public function count() - { - $count = 0; - - foreach ($this->constraints as $constraint) { - $count += count($constraint); - } - - return $count; - } -} -<?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. - * - * @since Class available since Release 2.2.0 - */ -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; - } -} -<?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> - * - * @since Class available since Release 3.3.0 - */ -class PHPUnit_Framework_Error_Deprecated extends PHPUnit_Framework_Error -{ - public static $enabled = true; -} -<?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> - * - * @since Class available since Release 3.3.0 - */ -class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error -{ - public static $enabled = true; -} -<?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> - * - * @since Class available since Release 3.3.0 - */ -class PHPUnit_Framework_Error_Warning extends PHPUnit_Framework_Error -{ - public static $enabled = true; -} -<?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 - * @since Class available since Release 3.4.0 - */ -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)); - } -} -<?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. - * - * @since Class available since Release 4.3.0 - */ -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; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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; - } -} -<?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. - * - * @since Interface available since Release 2.0.0 - */ -interface PHPUnit_Framework_IncompleteTest -{ -} -<?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 - * - * @since Class available since Release 4.3.0 - */ -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(); - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -class PHPUnit_Framework_IncompleteTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_IncompleteTest -{ -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Framework_InvalidCoversTargetException extends PHPUnit_Framework_CodeCoverageException -{ -} -<?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. - * - * @since Class available since Release 3.6.0 - */ -class PHPUnit_Framework_OutputError extends PHPUnit_Framework_AssertionFailedError -{ -} -<?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. - * - * @since Class available since Release 5.2.0 - */ -class PHPUnit_Framework_CoveredCodeNotExecutedException extends PHPUnit_Framework_RiskyTestError -{ -} -<?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. - * - * @since Class available since Release 5.3.0 - */ -class PHPUnit_Framework_MissingCoversAnnotationException extends PHPUnit_Framework_RiskyTestError -{ -} -<?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. - * - * @since Interface available since Release 4.0.0 - */ -interface PHPUnit_Framework_RiskyTest -{ -} -<?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. - * - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Framework_RiskyTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_RiskyTest -{ -} -<?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. - * - * @since Interface available since Release 3.0.0 - */ -interface PHPUnit_Framework_SelfDescribing -{ - /** - * Returns a string representation of the object. - * - * @return string - */ - public function toString(); -} -<?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. - * - * @since Interface available since Release 3.0.0 - */ -interface PHPUnit_Framework_SkippedTest -{ -} -<?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 - * - * @since Class available since Release 4.3.0 - */ -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(); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest -{ -} -<?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. - * - * @since Class available since Release 3.1.0 - */ -class PHPUnit_Framework_SkippedTestSuiteError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest -{ -} -<?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. - * - * @since Class available since Release 3.5.0 - */ -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; - } -} -<?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. - * - * @since Interface available since Release 2.0.0 - */ -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); -} -<?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> - * - * @since Class available since Release 2.0.0 - */ -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 mixed - */ - private $expectedException = null; - - /** - * The message of the expected Exception. - * - * @var string - */ - private $expectedExceptionMessage = ''; - - /** - * The regex pattern to validate the expected Exception message. - * - * @var string - */ - private $expectedExceptionMessageRegExp = ''; - - /** - * The code of the expected Exception. - * - * @var int|string - */ - private $expectedExceptionCode; - - /** - * 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 array - */ - 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 = []; - - /** - * 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; - } - - /** - * @since Method available since Release 5.4.0 - */ - public function getGroups() - { - return $this->groups; - } - - /** - * @param array $groups - * - * @since Method available since Release 5.4.0 - */ - public function setGroups(array $groups) - { - $this->groups = $groups; - } - - /** - * Returns the annotations for this test. - * - * @return array - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - public function getSize() - { - return PHPUnit_Util_Test::getSize( - get_class($this), - $this->getName(false) - ); - } - - /** - * @return bool - * - * @since Method available since Release 5.3.4 - */ - public function hasSize() - { - return $this->getSize() !== PHPUnit_Util_Test::UNKNOWN; - } - - /** - * @return bool - * - * @since Method available since Release 5.3.4 - */ - public function isSmall() - { - return $this->getSize() === PHPUnit_Util_Test::SMALL; - } - - /** - * @return bool - * - * @since Method available since Release 5.3.4 - */ - public function isMedium() - { - return $this->getSize() === PHPUnit_Util_Test::MEDIUM; - } - - /** - * @return bool - * - * @since Method available since Release 5.3.4 - */ - public function isLarge() - { - return $this->getSize() === PHPUnit_Util_Test::LARGE; - } - - /** - * @return string - * - * @since Method available since Release 3.6.0 - */ - public function getActualOutput() - { - if (!$this->outputBufferingActive) { - return $this->output; - } else { - return ob_get_contents(); - } - } - - /** - * @return bool - * - * @since Method available since Release 3.6.0 - */ - public function hasOutput() - { - if (strlen($this->output) === 0) { - return false; - } - - if ($this->hasExpectationOnOutput()) { - return false; - } - - return true; - } - - /** - * @param string $expectedRegex - * - * @since Method available since Release 3.6.0 - * - * @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 - * - * @since Method available since Release 3.6.0 - */ - 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 - * - * @since Method available since Release 3.6.5 - * @deprecated - */ - public function hasPerformedExpectationsOnOutput() - { - return $this->hasExpectationOnOutput(); - } - - /** - * @return bool - * - * @since Method available since Release 4.3.3 - */ - public function hasExpectationOnOutput() - { - return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex); - } - - /** - * @return string - * - * @since Method available since Release 3.2.0 - */ - public function getExpectedException() - { - return $this->expectedException; - } - - /** - * @param mixed $exception - * @param string $message - * @param int|string $code - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.2.0 - * @deprecated Method deprecated since Release 5.2.0 - */ - public function setExpectedException($exception, $message = '', $code = null) - { - $this->expectedException = $exception; - - if ($message !== null && $message !== '') { - $this->expectExceptionMessage($message); - } - - if ($code !== null) { - $this->expectExceptionCode($code); - } - } - - /** - * @param mixed $exception - * @param string $messageRegExp - * @param int $code - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 4.3.0 - */ - 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 mixed $exception - * - * @since Method available since Release 5.2.0 - */ - public function expectException($exception) - { - $this->expectedException = $exception; - } - - /** - * @param int|string $code - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 5.2.0 - */ - public function expectExceptionCode($code) - { - 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 - * - * @since Method available since Release 5.2.0 - */ - public function expectExceptionMessage($message) - { - if (!is_string($message)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); - } - - $this->expectedExceptionMessage = $message; - } - - /** - * @param string $messageRegExp - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 5.2.0 - */ - public function expectExceptionMessageRegExp($messageRegExp) - { - if (!is_string($messageRegExp)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); - } - - $this->expectedExceptionMessageRegExp = $messageRegExp; - } - - /** - * @param bool $flag - * - * @since Method available since Release 5.4.0 - */ - public function setRegisterMockObjectsFromTestArgumentsRecursively($flag) - { - if (!is_bool($flag)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - - $this->registerMockObjectsFromTestArgumentsRecursively = $flag; - } - - /** - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public function setUseErrorHandler($useErrorHandler) - { - $this->useErrorHandler = $useErrorHandler; - } - - /** - * @since Method available since Release 3.4.0 - */ - protected function setUseErrorHandlerFromAnnotation() - { - try { - $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings( - get_class($this), - $this->name - ); - - if ($useErrorHandler !== null) { - $this->setUseErrorHandler($useErrorHandler); - } - } catch (ReflectionException $e) { - } - } - - /** - * @since Method available since Release 3.6.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - public function getStatus() - { - return $this->status; - } - - /** - * Returns the status message of this test. - * - * @return string - * - * @since Method available since Release 3.3.0 - */ - public function getStatusMessage() - { - return $this->statusMessage; - } - - /** - * Returns whether or not this test has failed. - * - * @return bool - * - * @since Method available since Release 3.0.0 - */ - 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->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 ($this->useErrorHandler !== null) { - $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(); - - 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; - } - - if (isset($_e)) { - $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; - $this->statusMessage = $_e->getMessage(); - } - - // 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; - } - } - - 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 (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' || - $reflector->isSubclassOf('PHPUnit_Framework_Exception')) { - $checkException = true; - } - } - - if ($checkException) { - $this->assertThat( - $e, - new PHPUnit_Framework_Constraint_Exception( - $this->expectedException - ) - ); - - if (is_string($this->expectedExceptionMessage) && - !empty($this->expectedExceptionMessage)) { - $this->assertThat( - $e, - new PHPUnit_Framework_Constraint_ExceptionMessage( - $this->expectedExceptionMessage - ) - ); - } - - if (is_string($this->expectedExceptionMessageRegExp) && - !empty($this->expectedExceptionMessageRegExp)) { - $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. - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public function setDependencies(array $dependencies) - { - $this->dependencies = $dependencies; - } - - /** - * Returns true if the tests has dependencies - * - * @return bool - * - * @since Method available since Release 4.0.0 - */ - public function hasDependencies() - { - return count($this->dependencies) > 0; - } - - /** - * Sets - * - * @param array $dependencyInput - * - * @since Method available since Release 3.4.0 - */ - public function setDependencyInput(array $dependencyInput) - { - $this->dependencyInput = $dependencyInput; - } - - /** - * @param bool $beStrictAboutChangesToGlobalState - * - * @since Method available since Release 4.6.0 - */ - public function setBeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState) - { - $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; - } - - /** - * Calling this method in setUp() has no effect! - * - * @param bool $backupGlobals - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public function setBackupStaticAttributes($backupStaticAttributes) - { - if (is_null($this->backupStaticAttributes) && - is_bool($backupStaticAttributes)) { - $this->backupStaticAttributes = $backupStaticAttributes; - } - } - - /** - * @param bool $runTestInSeparateProcess - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public function setInIsolation($inIsolation) - { - if (is_bool($inIsolation)) { - $this->inIsolation = $inIsolation; - } else { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - } - - /** - * @return bool - * - * @since Method available since Release 4.3.0 - */ - public function isInIsolation() - { - return $this->inIsolation; - } - - /** - * @return mixed - * - * @since Method available since Release 3.4.0 - */ - public function getResult() - { - return $this->testResult; - } - - /** - * @param mixed $result - * - * @since Method available since Release 3.4.0 - */ - public function setResult($result) - { - $this->testResult = $result; - } - - /** - * @param callable $callback - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.6.0 - */ - public function setOutputCallback($callback) - { - if (!is_callable($callback)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback'); - } - - $this->outputCallback = $callback; - } - - /** - * @return PHPUnit_Framework_TestResult - * - * @since Method available since Release 3.5.7 - */ - public function getTestResultObject() - { - return $this->result; - } - - /** - * @param PHPUnit_Framework_TestResult $result - * - * @since Method available since Release 3.6.0 - */ - public function setTestResultObject(PHPUnit_Framework_TestResult $result) - { - $this->result = $result; - } - - /** - * @param PHPUnit_Framework_MockObject_MockObject $mockObject - * - * @since Method available since Release 5.4.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 $className - * - * @return PHPUnit_Framework_MockObject_MockBuilder - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 5.4.0 - */ - protected function createMock($originalClassName) - { - return $this->getMockBuilder($originalClassName) - ->disableOriginalConstructor() - ->disableOriginalClone() - ->disableArgumentCloning() - ->disallowMockingUnknownTypes() - ->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 - * - * @since Method available since Release 3.0.0 - * @deprecated Method deprecated since Release 5.4.0 - */ - 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 - * - * @since Method available since Release 5.0.0 - * @deprecated Method deprecated since Release 5.4.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - * - * @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 - * - * @since Method available since Release 3.4.0 - */ - protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = [], $callOriginalConstructor = true, array $options = []) - { - if ($originalClassName === '') { - $originalClassName = str_replace('.wsdl', '', basename($wsdlFile)); - } - - 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 - * - * @since Method available since Release 4.0.0 - * - * @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 - * - * @since Method available since Release 3.6.0 - * - * @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 - * - * @since Method available since Release 4.5.0 - */ - protected function prophesize($classOrInterface = null) - { - return $this->getProphet()->prophesize($classOrInterface); - } - - /** - * Adds a value to the assertion counter. - * - * @param int $count - * - * @since Method available since Release 3.3.3 - */ - public function addToAssertionCount($count) - { - $this->numAssertions += $count; - } - - /** - * Returns the number of assertions performed by this test. - * - * @return int - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 4.2.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 4.2.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - public static function at($index) - { - return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index); - } - - /** - * @param mixed $value - * - * @return PHPUnit_Framework_MockObject_Stub_Return - * - * @since Method available since Release 3.0.0 - */ - public static function returnValue($value) - { - return new PHPUnit_Framework_MockObject_Stub_Return($value); - } - - /** - * @param array $valueMap - * - * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap - * - * @since Method available since Release 3.6.0 - */ - public static function returnValueMap(array $valueMap) - { - return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap); - } - - /** - * @param int $argumentIndex - * - * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument - * - * @since Method available since Release 3.3.0 - */ - public static function returnArgument($argumentIndex) - { - return new PHPUnit_Framework_MockObject_Stub_ReturnArgument( - $argumentIndex - ); - } - - /** - * @param mixed $callback - * - * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - public static function returnSelf() - { - return new PHPUnit_Framework_MockObject_Stub_ReturnSelf(); - } - - /** - * @param Throwable|Exception $exception - * - * @return PHPUnit_Framework_MockObject_Stub_Exception - * - * @since Method available since Release 3.1.0 - * - * @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 - * - * @since Method available since Release 3.0.0 - */ - public static function onConsecutiveCalls() - { - $args = func_get_args(); - - return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args); - } - - /** - * @return bool - * - * @since Method available since Release 5.4.0 - */ - public function usesDataProvider() - { - return !empty($this->data); - } - - /** - * @return string - * - * @since Method available since Release 5.4.0 - */ - public function dataDescription() - { - return is_string($this->dataName) ? $this->dataName : ''; - } - - /** - * Gets the data set description of a TestCase. - * - * @param bool $includeData - * - * @return string - * - * @since Method available since Release 3.3.0 - */ - 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; - } - - /** - * Creates a default TestResult object. - * - * @return PHPUnit_Framework_TestResult - */ - protected function createResult() - { - return new PHPUnit_Framework_TestResult; - } - - /** - * @since Method available since Release 3.5.4 - */ - 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->addError( - $this, - new PHPUnit_Framework_SkippedTestError( - sprintf( - 'This test depends on "%s" to pass.', - $dependency - ) - ), - 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. - * - * @since Method available since Release 3.4.0 - */ - 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. - * - * @since Method available since Release 3.2.8 - */ - protected function assertPreConditions() - { - } - - /** - * Performs assertions shared by all tests of a test case. - * - * This method is called before the execution of a test ends - * and before tearDown() is called. - * - * @since Method available since Release 3.2.8 - */ - 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. - * - * @since Method available since Release 3.4.0 - */ - public static function tearDownAfterClass() - { - } - - /** - * This method is called when a test method did not execute successfully. - * - * @param Exception|Throwable $e - * - * @since Method available since Release 3.4.0 - * - * @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 - * - * @since Method available since Release 3.4.0 - */ - 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; - } - - /** - * @since Method available since Release 4.2.0 - */ - private function startOutputBuffering() - { - while (!defined('PHPUNIT_TESTSUITE') && ob_get_level() > 0) { - ob_end_clean(); - } - - ob_start(); - - $this->outputBufferingActive = true; - $this->outputBufferingLevel = ob_get_level(); - } - - /** - * @since Method available since Release 4.2.0 - */ - private function stopOutputBuffering() - { - if (ob_get_level() != $this->outputBufferingLevel) { - while (ob_get_level() > 0) { - 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'); - - foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) { - foreach ($attributes as $attribute) { - $blacklist->addStaticAttribute($class, $attribute); - } - } - } - - return new Snapshot( - $blacklist, - $backupGlobals, - $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 - * - * @since Method available since Release 4.5.0 - */ - private function getProphet() - { - if ($this->prophet === null) { - $this->prophet = new Prophet; - } - - return $this->prophet; - } - - /** - * @param PHPUnit_Framework_MockObject_MockObject $mock - * - * @return bool - * - * @since Method available since Release 5.0.0 - */ - 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 - * - * @since Method available since Release 5.0.0 - */ - private function registerMockObjectsFromTestArguments(array $testArguments) - { - 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) { - $this->registerMockObject($testArgument); - } elseif (is_array($testArgument)) { - $this->registerMockObjectsFromTestArguments($testArgument); - } - } - } - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - public function getExceptionAsString() - { - return self::exceptionToString($this->thrownException); - } - - /** - * Returns a description for an exception. - * - * @param Exception $e - * - * @return string - * - * @since Method available since Release 3.2.0 - */ - 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 - * - * @since Method available since Release 4.3.0 - */ - 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); - } -} -<?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. - * - * @since Interface available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 6.0.0 - * - * @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 - * - * @since Method available since Release 4.0.0 - */ - public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time); - - /** - * Skipped test. - * - * @param PHPUnit_Framework_Test $test - * @param Exception $e - * @param float $time - * - * @since Method available since Release 3.0.0 - */ - public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time); - - /** - * A test suite started. - * - * @param PHPUnit_Framework_TestSuite $suite - * - * @since Method available since Release 2.2.0 - */ - public function startTestSuite(PHPUnit_Framework_TestSuite $suite); - - /** - * A test suite ended. - * - * @param PHPUnit_Framework_TestSuite $suite - * - * @since Method available since Release 2.2.0 - */ - 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); -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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. - * - * @since Method available since Release 3.0.0 - */ - 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 ($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 - * - * @since Method available since Release 5.1.0 - */ - 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 ($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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - public function allHarmless() - { - return $this->riskyCount() == 0; - } - - /** - * Gets the number of risky tests. - * - * @return int - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - public function noneSkipped() - { - return $this->skippedCount() == 0; - } - - /** - * Gets the number of skipped tests. - * - * @return int - * - * @since Method available since Release 3.0.0 - */ - public function skippedCount() - { - return count($this->skipped); - } - - /** - * Returns an Enumeration for the skipped tests. - * - * @return array - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 5.1.0 - */ - public function warningCount() - { - return count($this->warnings); - } - - /** - * Returns an Enumeration for the warnings. - * - * @return array - * - * @since Method available since Release 5.1.0 - */ - public function warnings() - { - return $this->warnings; - } - - /** - * Returns the names of the tests that have passed. - * - * @return array - * - * @since Method available since Release 3.4.0 - */ - public function passed() - { - return $this->passed; - } - - /** - * Returns the (top) test suite. - * - * @return PHPUnit_Framework_TestSuite - * - * @since Method available since Release 3.0.0 - */ - public function topTestSuite() - { - return $this->topTestSuite; - } - - /** - * Returns whether code coverage information should be collected. - * - * @return bool If code coverage should be collected - * - * @since Method available since Release 3.2.0 - */ - 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(); - - if ($test instanceof PHPUnit_Framework_TestCase) { - $test->setRegisterMockObjectsFromTestArgumentsRecursively( - $this->registerMockObjectsFromTestArgumentsRecursively - ); - } - - $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; - - 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 (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) { - $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) { - if (!$test->isMedium() && !$test->isLarge()) { - $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) { - $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->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 - * - * @since Method available since Release 3.5.0 - */ - public function getCodeCoverage() - { - return $this->codeCoverage; - } - - /** - * Sets the code coverage object. - * - * @param CodeCoverage $codeCoverage - * - * @since Method available since Release 3.6.0 - */ - public function setCodeCoverage(CodeCoverage $codeCoverage) - { - $this->codeCoverage = $codeCoverage; - } - - /** - * Enables or disables the error-to-exception conversion. - * - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.2.14 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public function getConvertErrorsToExceptions() - { - return $this->convertErrorsToExceptions; - } - - /** - * Enables or disables the stopping when an error occurs. - * - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 5.1.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - public function beStrictAboutTestsThatDoNotTestAnything($flag) - { - if (!is_bool($flag)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - - $this->beStrictAboutTestsThatDoNotTestAnything = $flag; - } - - /** - * @return bool - * - * @since Method available since Release 4.0.0 - */ - public function isStrictAboutTestsThatDoNotTestAnything() - { - return $this->beStrictAboutTestsThatDoNotTestAnything; - } - - /** - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 4.0.0 - */ - public function beStrictAboutOutputDuringTests($flag) - { - if (!is_bool($flag)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - - $this->beStrictAboutOutputDuringTests = $flag; - } - - /** - * @return bool - * - * @since Method available since Release 4.0.0 - */ - public function isStrictAboutOutputDuringTests() - { - return $this->beStrictAboutOutputDuringTests; - } - - /** - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 5.0.0 - */ - public function beStrictAboutResourceUsageDuringSmallTests($flag) - { - if (!is_bool($flag)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - - $this->beStrictAboutResourceUsageDuringSmallTests = $flag; - } - - /** - * @return bool - * - * @since Method available since Release 5.0.0 - */ - public function isStrictAboutResourceUsageDuringSmallTests() - { - return $this->beStrictAboutResourceUsageDuringSmallTests; - } - - /** - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 5.0.0 - */ - public function enforceTimeLimit($flag) - { - if (!is_bool($flag)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - - $this->enforceTimeLimit = $flag; - } - - /** - * @return bool - * - * @since Method available since Release 5.0.0 - */ - public function enforcesTimeLimit() - { - return $this->enforceTimeLimit; - } - - /** - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 4.2.0 - */ - public function beStrictAboutTodoAnnotatedTests($flag) - { - if (!is_bool($flag)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - - $this->beStrictAboutTodoAnnotatedTests = $flag; - } - - /** - * @return bool - * - * @since Method available since Release 4.2.0 - */ - public function isStrictAboutTodoAnnotatedTests() - { - return $this->beStrictAboutTodoAnnotatedTests; - } - - /** - * Enables or disables the stopping for risky tests. - * - * @param bool $flag - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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 - * - * @since Method available since Release 3.1.0 - */ - 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. - * - * @return bool - */ - public function wasSuccessful() - { - return empty($this->errors) && empty($this->failures) && empty($this->warnings); - } - - /** - * Sets the timeout for small tests. - * - * @param int $timeout - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.6.0 - */ - public function setTimeoutForSmallTests($timeout) - { - if (!is_integer($timeout)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); - } - - $this->timeoutForSmallTests = $timeout; - } - - /** - * Sets the timeout for medium tests. - * - * @param int $timeout - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.6.0 - */ - public function setTimeoutForMediumTests($timeout) - { - if (!is_integer($timeout)) { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); - } - - $this->timeoutForMediumTests = $timeout; - } - - /** - * Sets the timeout for large tests. - * - * @param int $timeout - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.6.0 - */ - public function setTimeoutForLargeTests($timeout) - { - if (!is_integer($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 - * - * @since Method available since Release 5.4.0 - */ - 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; - } -} -<?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. - * - * Here is an example using the dynamic test definition. - * - * <code> - * <?php - * $suite = new PHPUnit_Framework_TestSuite; - * $suite->addTest(new MathTest('testPass')); - * ?> - * </code> - * - * Alternatively, a TestSuite can extract the tests to be run automatically. - * To do so you pass a ReflectionClass instance for your - * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite - * constructor. - * - * <code> - * <?php - * $suite = new PHPUnit_Framework_TestSuite( - * new ReflectionClass('MathTest') - * ); - * ?> - * </code> - * - * This constructor creates a suite with all the methods starting with - * "test" that take no arguments. - * - * @since Class available since Release 2.0.0 - */ -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; - - /** - * 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 = '') - { - $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()) { - $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 - * - * @since Method available since Release 2.3.0 - */ - 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. - $classes = get_declared_classes(); - $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename); - $newClasses = array_diff(get_declared_classes(), $classes); - - // 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); - } - - // 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) { - $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 - * - * @since Method available since Release 2.3.0 - */ - 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 - * - * @since Method available since Release 3.2.0 - */ - public function getGroups() - { - return array_keys($this->groups); - } - - public function getGroupDetails() - { - return $this->groups; - } - - /** - * Set tests groups of the test case - * - * @param array $groups - * - * @since Method available since Release 4.0.0 - */ - 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++) { - $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 - * - * @since Method available since Release 3.7.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - public function setTests(array $tests) - { - $this->tests = $tests; - } - - /** - * Mark the test suite as skipped. - * - * @param string $message - * - * @throws PHPUnit_Framework_SkippedTestSuiteError - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 4.3.0 - */ - 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 - * - * @since Method available since Release 4.3.0 - */ - protected static function incompleteTest($class, $methodName, $message) - { - return new PHPUnit_Framework_IncompleteTestCase($class, $methodName, $message); - } - - /** - * @param bool $beStrictAboutChangesToGlobalState - * - * @since Method available since Release 4.6.0 - */ - public function setbeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState) - { - if (is_null($this->beStrictAboutChangesToGlobalState) && is_bool($beStrictAboutChangesToGlobalState)) { - $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; - } - } - - /** - * @param bool $backupGlobals - * - * @since Method available since Release 3.3.0 - */ - public function setBackupGlobals($backupGlobals) - { - if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { - $this->backupGlobals = $backupGlobals; - } - } - - /** - * @param bool $backupStaticAttributes - * - * @since Method available since Release 3.4.0 - */ - public function setBackupStaticAttributes($backupStaticAttributes) - { - if (is_null($this->backupStaticAttributes) && - is_bool($backupStaticAttributes)) { - $this->backupStaticAttributes = $backupStaticAttributes; - } - } - - /** - * Returns an iterator for this test suite. - * - * @return RecursiveIteratorIterator - * - * @since Method available since Release 3.1.0 - */ - 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. - * - * @since Method available since Release 3.1.0 - */ - protected function setUp() - { - } - - /** - * Template Method that is called after the tests - * of this test suite have finished running. - * - * @since Method available since Release 3.1.0 - */ - protected function tearDown() - { - } -} -<?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. - */ - -/** - * @since Class available since Release 3.4.0 - */ -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); - } - } -} -<?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. - * - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Framework_UnintentionallyCoveredCodeError extends PHPUnit_Framework_RiskyTestError -{ -} -<?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 there is a warning. - * - * @since Class available since Release 5.0.0 - */ -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(); - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ - public function getMessage() - { - return $this->message; - } - - /** - * Returns a string representation of the test case. - * - * @return string - * - * @since Method available since Release 3.4.0 - */ - public function toString() - { - return 'Warning'; - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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); -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Runner_Exception extends RuntimeException implements PHPUnit_Exception -{ -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -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; - } -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -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); -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Runner_Filter_Group_Exclude extends PHPUnit_Runner_Filter_GroupFilterIterator -{ - protected function doAccept($hash) - { - return !in_array($hash, $this->groupTests); - } -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -class PHPUnit_Runner_Filter_Group_Include extends PHPUnit_Runner_Filter_GroupFilterIterator -{ - protected function doAccept($hash) - { - return in_array($hash, $this->groupTests); - } -} -<?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. - */ - -/** - * @since Class available since Release 4.0.0 - */ -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; - } - - $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; - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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; - } -} -<?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. - * - * @since Interface available since Release 2.0.0 - */ -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); -} -<?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. - */ - -/** - * This class defines the current version of PHPUnit. - * - * @since Class available since Release 2.0.0 - */ -class PHPUnit_Runner_Version -{ - private static $pharVersion = "5.4.6"; - 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 SebastianBergmann\Version('5.4.6', dirname(dirname(__DIR__))); - self::$version = $version->getVersion(); - } - - return self::$version; - } - - /** - * @return string - * - * @since Method available since Release 4.8.13 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - public static function getReleaseChannel() - { - if (strpos(self::$pharVersion, '-') !== false) { - return '-nightly'; - } - - return ''; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -class PHPUnit_TextUI_Command -{ - /** - * @var array - */ - protected $arguments = [ - 'listGroups' => false, - 'loader' => null, - 'useDefaultConfiguration' => true - ]; - - /** - * @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, - 'loader=' => null, - 'log-json=' => null, - 'log-junit=' => null, - 'log-tap=' => null, - 'log-teamcity=' => null, - 'no-configuration' => null, - 'no-coverage' => 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; - } - } - - 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()) { - $return = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT; - } elseif (!isset($result) || $result->errorCount() > 0) { - $return = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT; - } - - return $return; - } - - /** - * Create a TestRunner, override in subclasses. - * - * @return PHPUnit_TextUI_TestRunner - * - * @since Method available since Release 3.6.0 - */ - 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 '--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-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]); - - 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['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 - */ - 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()); - } - } - - /** - * @since Method available since Release 4.0.0 - */ - protected function handleSelfUpdate($upgrade = false) - { - $this->printVersionString(); - - $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); - } - - /** - * @since Method available since Release 4.8.0 - */ - 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-tap <file> Log test execution in TAP format to file. - --log-teamcity <file> Log test execution in TeamCity format to file. - --log-json <file> Log test execution in JSON format. - --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 <pattern> 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. - --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. - --tap Report test execution progress in TAP format. - --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. - --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."; - print "\n --self-update Update PHPUnit to the latest version within the same\n release series.\n"; - print "\n --self-upgrade Upgrade PHPUnit to the latest version.\n"; - } - } - - /** - * 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; - } - - /** - */ - private function showError($message) - { - $this->printVersionString(); - - print $message . "\n"; - - exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - protected function printRisky(PHPUnit_Framework_TestResult $result) - { - $this->printDefects($result->risky(), 'risky test'); - } - - /** - * @param PHPUnit_Framework_TestResult $result - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 5.1.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.6.5 - */ - 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; - } - } -} -<?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. - * - * @since Class available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - 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; - } - - 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_integer($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']) ? '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() - ); - } - } - - if (isset($arguments['deprecatedCheckForUnintentionallyCoveredCodeSettingUsed'])) { - print "Warning: Deprecated configuration setting \"checkForUnintentionallyCoveredCode\" used\n"; - } - } - - 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) { - if (!$this->runtime->canCollectCodeCoverage()) { - $this->writeMessage('Error', 'No code coverage driver is available'); - - $codeCoverageReports = 0; - } elseif (!isset($arguments['whitelist']) && !$this->codeCoverageFilter->hasWhitelist()) { - $this->writeMessage('Error', 'No whitelist configured, no code coverage will be generated'); - - $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->setAddUncoveredFilesFromWhitelist( - $arguments['addUncoveredFilesFromWhitelist'] - ); - - $codeCoverage->setCheckForUnintentionallyCoveredCode( - $arguments['strictCoverage'] - ); - - $codeCoverage->setCheckForMissingCoversAnnotation( - $arguments['strictCoverage'] - ); - - $codeCoverage->setProcessUncoveredFilesFromWhitelist( - $arguments['processUncoveredFilesFromWhitelist'] - ); - - if (isset($arguments['forceCoversAnnotation'])) { - $codeCoverage->setForceCoversAnnotation( - $arguments['forceCoversAnnotation'] - ); - } - - if (isset($arguments['disableCodeCoverageIgnore'])) { - $codeCoverage->setDisableIgnoredLines(true); - } - - if (isset($arguments['whitelist'])) { - $this->codeCoverageFilter->addDirectoryToWhitelist($arguments['whitelist']); - } - - $result->setCodeCoverage($codeCoverage); - } - - if ($codeCoverageReports > 1) { - if (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['reportUselessTests'] - ) - ); - } - - $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()) { - 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 - * - * @since Method available since Release 3.1.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - public function getLoader() - { - if ($this->loader === null) { - $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader; - } - - return $this->loader; - } - - /** - * @param array $arguments - * - * @since Method available since Release 3.2.1 - */ - 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'])) { - if (count($listener['arguments']) == 0) { - $listener = new $listener['class']; - } else { - $listenerClass = new ReflectionClass( - $listener['class'] - ); - $listener = $listenerClass->newInstanceArgs( - $listener['arguments'] - ); - } - - if ($listener instanceof PHPUnit_Framework_TestListener) { - $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['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']; - } - - if ((isset($arguments['coverageClover']) || - isset($arguments['coverageCrap4J']) || - isset($arguments['coverageHtml']) || - isset($arguments['coveragePHP']) || - isset($arguments['coverageText']) || - isset($arguments['coverageXml'])) && - $this->runtime->canCollectCodeCoverage()) { - $filterConfiguration = $arguments['configuration']->getFilterConfiguration(); - $arguments['addUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist']; - $arguments['processUncoveredFilesFromWhitelist'] = $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); - } - } - } - - $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['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 - * - * @since Method available since Release 5.0.0 - */ - private function writeMessage($type, $message) - { - if (!$this->messagePrinted) { - $this->write("\n"); - } - - $this->write( - sprintf( - "%-15s%s\n", - $type . ':', - $message - ) - ); - - $this->messagePrinted = true; - } -} -<?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. - * - * @since Class available since Release 4.0.0 - */ -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 - * - * @since Method available since Release 4.1.0 - */ - 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'; - } - } - } -} -<?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" - * printerClass="PHPUnit_TextUI_ResultPrinter" - * processIsolation="false" - * stopOnError="false" - * stopOnFailure="false" - * stopOnWarning="false" - * stopOnIncomplete="false" - * stopOnRisky="false" - * stopOnSkipped="false" - * failOnWarning="false" - * failOnRisky="false" - * 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"/> - * <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> - * - * @since Class available since Release 3.2.0 - */ -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); - } - - /** - * @since Method available since Release 3.4.0 - */ - final private function __clone() - { - } - - /** - * Returns a PHPUnit configuration object. - * - * @param string $filename - * - * @return PHPUnit_Util_Configuration - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - public function getFilename() - { - return $this->filename; - } - - /** - * Returns the configuration for SUT filtering. - * - * @return array - * - * @since Method available since Release 3.2.1 - */ - 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 - * - * @since Method available since Release 3.2.1 - */ - public function getGroupConfiguration() - { - return $this->parseGroupConfiguration('groups'); - } - - /** - * Returns the configuration for testdox groups. - * - * @return array - * - * @since Method available since Release 5.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 == '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 - * - * @since Method available since Release 3.2.1 - */ - 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. - * - * @since Method available since Release 3.2.20 - */ - 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 - * - * @since Method available since Release 3.2.14 - */ - 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 - ); - } - - return $result; - } - - /** - * Returns the test suite configuration. - * - * @return PHPUnit_Framework_TestSuite - * - * @since Method available since Release 3.2.1 - */ - 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; - } - } - - /** - * @param DOMElement $testSuiteNode - * - * @return PHPUnit_Framework_TestSuite - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.2.3 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - protected function getInteger($value, $default) - { - if (is_numeric($value)) { - return (int) $value; - } - - return $default; - } - - /** - * @param string $query - * - * @return array - * - * @since Method available since Release 3.2.3 - */ - 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 - * - * @since Method available since Release 3.2.3 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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; - } -} -<?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. - */ - -/** - * @since Class available since Release 5.3.0 - */ -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> - <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 - ); - } -} -<?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. - * - * @since Class available since Release 3.3.0 - */ -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; - } -} -<?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. - * - * @since Class available since Release 2.3.0 - */ -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 - * - * @since Method available since Release 3.0.0 - */ - 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; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.4.0 - */ - public static function classNameToFilename($className) - { - return str_replace( - ['_', '\\'], - DIRECTORY_SEPARATOR, - $className - ) . '.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. - */ - -/** - * Utility class for code filtering. - * - * @since Class available since Release 2.0.0 - */ -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 - * - * @since Method available since Release 3.3.2 - */ - 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; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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); - array_map('trim', $args); - - while (list($i, $arg) = each($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 (strlen($spec) > 2 && $spec[2] == ':') { - if ($i + 1 < $argLen) { - $opts[] = [$opt, substr($arg, $i + 1)]; - break; - } - } else { - if ($i + 1 < $argLen) { - $opts[] = [$opt, substr($arg, $i + 1)]; - break; - } elseif (list(, $opt_arg) = each($args)) { - } else { - throw new PHPUnit_Framework_Exception( - "option requires an argument -- $opt" - ); - } - } - } - - $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) && - !(list(, $opt_arg) = each($args))) { - throw new PHPUnit_Framework_Exception( - "option --$opt requires an argument" - ); - } - } - } 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"); - } -} -<?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. - */ - -/** - * @since Class available since Release 3.4.0 - */ -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' - ]; - - public static function getIncludedFilesAsString() - { - return static::processIncludedFilesAsString(get_included_files()); - } - - 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; - } - - 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; - } - - 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; - } - - 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; - } - - 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) . - ')'; - } - - 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; - } -} -<?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. - * - * @since Class available since Release 3.4.0 - */ -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 - ) - ); - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 5.1.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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)); - } -} -<?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. - * - * @since Class available since Release 2.1.0 - */ -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 - * - * @since Method available since Release 5.1.0 - */ - public function addWarning(PHPUnit_Framework_Test $test, PHPUnit_Framework_Warning $e, $time) - { - $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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - 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() . "\n"; - } else { - $buffer = ''; - } - - $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . - "\n" . - PHPUnit_Util_Filter::getFilteredStacktrace($e); - - $fault = $this->document->createElement( - $type, - PHPUnit_Util_XML::prepareString($buffer) - ); - - $fault->setAttribute('type', get_class($e)); - $this->currentTestCase->appendChild($fault); - } -} -<?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). - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 3.3.4 - */ - 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 - * - * @since Method available since Release 5.1.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - ) - ); - } - } -} -<?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). - * - * @since Class available since Release 5.0.0 - */ -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 - * - * @since Method available since Release 5.1.0 - */ - 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_Exception) { - if (strlen(get_class($e)) != 0) { - $message = $message . get_class($e); - } - - 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; - } -} -<?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. - * - * @since Class available since Release 3.4.0 - */ -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 - * - * @since Method available since Release 3.5.12 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.5.0 - */ - 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']; - - if ($result->getCollectCodeCoverageInformation()) { - $result->getCodeCoverage()->merge( - $childResult->getCodeCoverage() - ); - } - - $time = $childResult->time(); - $notImplemented = $childResult->notImplemented(); - $risky = $childResult->risky(); - $skipped = $childResult->skipped(); - $errors = $childResult->errors(); - $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($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 - * - * @since Method available since Release 3.6.0 - * @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; - } -} -<?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. - * - * @since Class available since Release 3.5.12 - */ -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 - * - * @since Method available since Release 3.5.12 - */ - protected function process($pipe, $job) - { - fwrite($pipe, $job); - } - - /** - * @since Method available since Release 3.5.12 - */ - protected function cleanup() - { - if ($this->tempFile) { - unlink($this->tempFile); - } - } -} -<?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); - 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(); -<?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. - * - * @since Class available since Release 3.5.12 - * @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) . '"'; - } -} -<?php - -eval('?>' . file_get_contents('php://input')); -<?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. - * - * @since Class available since Release 2.0.0 - */ -class PHPUnit_Util_Printer -{ - /** - * If true, flush output after every write. - * - * @var bool - */ - protected $autoFlush = false; - - /** - * @var resource - */ - protected $out; - - /** - * @var string - */ - protected $outTarget; - - /** - * @var bool - */ - protected $printsHTML = false; - - /** - * 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 (sizeof($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, optionally tidy up HTML, 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); - } - - if ($this->printsHTML === true && - $this->outTarget !== null && - strpos($this->outTarget, 'php://') !== 0 && - strpos($this->outTarget, 'socket://') !== 0 && - extension_loaded('tidy')) { - file_put_contents( - $this->outTarget, - tidy_repair_file( - $this->outTarget, - ['indent' => true, 'wrap' => 0], - 'utf8' - ) - ); - } - } - - /** - * 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. - * - * @since Method available since Release 3.3.0 - */ - 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); - } - - print $buffer; - - if ($this->autoFlush) { - $this->incrementalFlush(); - } - } - } - - /** - * Check auto-flush mode. - * - * @return bool - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - public function setAutoFlush($autoFlush) - { - if (is_bool($autoFlush)) { - $this->autoFlush = $autoFlush; - } else { - throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); - } - } -} -<?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. - * - * @since Class available since Release 4.2.0 - */ -class PHPUnit_Util_Regex -{ - 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; - } -} -<?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. - * - * @since Class available since Release 3.6.0 - */ -class PHPUnit_Util_String -{ - /** - * Converts a string to UTF-8 encoding. - * - * @param string $string - * - * @return string - */ - public static function convertToUtf8($string) - { - if (!self::isUtf8($string)) { - if (function_exists('mb_convert_encoding')) { - $string = mb_convert_encoding($string, 'UTF-8'); - } else { - $string = utf8_encode($string); - } - } - - return $string; - } - - /** - * 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; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 4.2.0 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - 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 - * - * @since Method available since Release 4.3.0 - */ - 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 - * - * @since Method available since Release 3.3.6 - */ - 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|Iterator when a data provider is specified and exists - * null when no data provider is specified - * - * @throws PHPUnit_Framework_Exception - * - * @since Method available since Release 3.2.0 - */ - public static function getProvidedData($className, $methodName) - { - $reflector = new ReflectionMethod($className, $methodName); - $docComment = $reflector->getDocComment(); - $data = null; - - if ($dataProviderData = self::getDataFromDataProviderAnnotation($docComment, $className, $methodName)) { - $data = $dataProviderData; - } - - if ($testWithData = self::getDataFromTestWithAnnotation($docComment)) { - $data = $testWithData; - } - - if ($data !== null) { - if (is_object($data)) { - $data = iterator_to_array($data); - } - - 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(self::REGEX_DATA_PROVIDER, $docComment, $matches)) { - $dataProviderMethodNameNamespace = explode('\\', $matches[1]); - $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); - } - - return $data; - } - } - - /** - * @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); - $dataSet = json_decode($candidateRow, true); - if (json_last_error() != JSON_ERROR_NONE) { - break; - } - $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 = 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 5.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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]][] = $matches['value'][$i]; - } - } - - return $annotations; - } - - /** - * Returns the backup settings for a test. - * - * @param string $className - * @param string $methodName - * - * @return array - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.2.0 - */ - 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 - * - * @since Method available since Release 3.6.0 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 3.4.1 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public static function getPreserveGlobalStateSettings($className, $methodName) - { - return self::getBooleanAnnotationSetting( - $className, - $methodName, - 'preserveGlobalState' - ); - } - - /** - * @param string $className - * - * @return array - * - * @since Method available since Release 4.0.8 - */ - 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 - * - * @since Method available since Release 4.0.9 - */ - private static function emptyHookMethodsArray() - { - return [ - 'beforeClass' => ['setUpBeforeClass'], - 'before' => ['setUp'], - 'after' => ['tearDown'], - 'afterClass' => ['tearDownAfterClass'] - ]; - } - - /** - * @param string $className - * @param string $methodName - * @param string $settingName - * - * @return bool - * - * @since Method available since Release 3.4.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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_unique( - array_merge( - $result[$filename], - range($reflector->getStartLine(), $reflector->getEndLine()) - ) - ); - } - - return $result; - } - - /** - * @param ReflectionMethod $method - * - * @return bool - * - * @since Method available since Release 4.0.8 - */ - private static function isBeforeClassMethod(ReflectionMethod $method) - { - return $method->isStatic() && strpos($method->getDocComment(), '@beforeClass') !== false; - } - - /** - * @param ReflectionMethod $method - * - * @return bool - * - * @since Method available since Release 4.0.8 - */ - private static function isBeforeMethod(ReflectionMethod $method) - { - return preg_match('/@before\b/', $method->getDocComment()); - } - - /** - * @param ReflectionMethod $method - * - * @return bool - * - * @since Method available since Release 4.0.8 - */ - private static function isAfterClassMethod(ReflectionMethod $method) - { - return $method->isStatic() && strpos($method->getDocComment(), '@afterClass') !== false; - } - - /** - * @param ReflectionMethod $method - * - * @return bool - * - * @since Method available since Release 4.0.8 - */ - private static function isAfterMethod(ReflectionMethod $method) - { - return preg_match('/@after\b/', $method->getDocComment()); - } -} -<?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. - * - * @since Class available since Release 2.1.0 - */ -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; - } -} -<?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. - * - * @since Class available since Release 2.1.0 - */ -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 - * - * @since Method available since Release 5.1.0 - */ - 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 - * - * @since Method available since Release 4.0.0 - */ - 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 - * - * @since Method available since Release 3.0.0 - */ - 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 - * - * @since Method available since Release 2.2.0 - */ - public function startTestSuite(PHPUnit_Framework_TestSuite $suite) - { - } - - /** - * A testsuite ended. - * - * @param PHPUnit_Framework_TestSuite $suite - * - * @since Method available since Release 2.2.0 - */ - 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; - } - - /** - * @since Method available since Release 2.3.0 - */ - 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; - } -} -<?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. - * - * @since Class available since Release 2.1.0 - */ -class PHPUnit_Util_TestDox_ResultPrinter_HTML extends PHPUnit_Util_TestDox_ResultPrinter -{ - /** - * @var bool - */ - protected $printsHTML = true; - - /** - * @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); - } -} -<?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. - * - * @since Class available since Release 2.1.0 - */ -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"); - } -} -<?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. - */ - -/** - * @since Class available since Release 5.4.0 - */ -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); - } -} -<?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. - * - * @since Class available since Release 3.1.0 - */ -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; - } -} -<?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. - * - * @since Class available since Release 3.0.0 - */ -class PHPUnit_Util_Type -{ - public static function isType($type) - { - return in_array( - $type, - [ - 'numeric', - 'integer', - 'int', - 'float', - 'string', - 'boolean', - 'bool', - 'null', - 'array', - 'object', - 'resource', - 'scalar' - ] - ); - } -} -<?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. - * - * @since Class available since Release 3.2.0 - */ -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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.3.0 - */ - 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 - * - * @since Method available since Release 3.4.6 - */ - 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 - * - * @since Method available since Release 3.4.0 - */ - public static function xmlToVariable(DOMElement $element) - { - $variable = null; - - switch ($element->tagName) { - case 'array': - $variable = []; - - foreach ($element->getElementsByTagName('element') as $element) { - $item = $element->childNodes->item(0); - - if ($item instanceof DOMText) { - $item = $element->childNodes->item(1); - } - - $value = self::xmlToVariable($item); - - if ($element->hasAttribute('key')) { - $variable[(string) $element->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; - } -} - ���g���(�=xO����x���GBMB \ No newline at end of file diff --git a/src/main/edu/wisc/doit/LocalUserDetailsAttributeMapper.php b/src/main/edu/wisc/doit/LocalUserDetailsAttributeMapper.php index acdc38893af4d5e112696ca0c0dd0a318da51d13..9f8f0f737949b67e6a05161c46e4eba34b5d799d 100644 --- a/src/main/edu/wisc/doit/LocalUserDetailsAttributeMapper.php +++ b/src/main/edu/wisc/doit/LocalUserDetailsAttributeMapper.php @@ -14,14 +14,12 @@ class LocalUserDetailsAttributeMapper implements UserDetailsAttributeMapper public function mapUser() { $jsonString = file_get_contents(__DIR__ . "/../../../resources/localuser.json"); - if ($jsonString == false) { + if ($jsonString === false) { return null; } - // Load user attributes into a standard PHP array (true specifies array) - $userAttributes = json_decode($jsonString, true); - - return $userAttributes; + // Return user attributes into a standard PHP array (true specifies array) + return json_decode($jsonString, true); } } \ No newline at end of file diff --git a/src/main/edu/wisc/doit/LocalUserDetailsService.php b/src/main/edu/wisc/doit/LocalUserDetailsService.php index f759528a42cf11da80ec951d585298ab318bede2..42704aa298f8a484739c5a3eb9db78e66a30d31f 100644 --- a/src/main/edu/wisc/doit/LocalUserDetailsService.php +++ b/src/main/edu/wisc/doit/LocalUserDetailsService.php @@ -36,17 +36,17 @@ class LocalUserDetailsService implements UserDetailsService return null; } - $userDetails = new UWUserDetails($userAttributes[UserDetailsAttributeMapper::EPPN], - $userAttributes[UserDetailsAttributeMapper::PVI], - $userAttributes[UserDetailsAttributeMapper::FULLNAME], - $userAttributes[UserDetailsAttributeMapper::UDDS], - $userAttributes[UserDetailsAttributeMapper::EMAIL], - $userAttributes[UserDetailsAttributeMapper::SOURCE], - $userAttributes[UserDetailsAttributeMapper::ISIS_EMPLID], - $userAttributes[UserDetailsAttributeMapper::FIRST_NAME], - $userAttributes[UserDetailsAttributeMapper::LAST_NAME]); - - return $userDetails; + return new UWUserDetails( + $userAttributes[UserDetailsAttributeMapper::EPPN], + $userAttributes[UserDetailsAttributeMapper::PVI], + $userAttributes[UserDetailsAttributeMapper::FULLNAME], + $userAttributes[UserDetailsAttributeMapper::UDDS], + $userAttributes[UserDetailsAttributeMapper::EMAIL], + $userAttributes[UserDetailsAttributeMapper::SOURCE], + $userAttributes[UserDetailsAttributeMapper::ISIS_EMPLID], + $userAttributes[UserDetailsAttributeMapper::FIRST_NAME], + $userAttributes[UserDetailsAttributeMapper::LAST_NAME] + ); } } \ No newline at end of file diff --git a/src/main/edu/wisc/doit/PreauthUserDetailsAttributeMapper.php b/src/main/edu/wisc/doit/PreauthUserDetailsAttributeMapper.php new file mode 100644 index 0000000000000000000000000000000000000000..d0b81187dd222752d2b344a62af18d4f69f542f1 --- /dev/null +++ b/src/main/edu/wisc/doit/PreauthUserDetailsAttributeMapper.php @@ -0,0 +1,36 @@ +<?php + +namespace edu\wisc\doit; + +/** + * Default implementation of {@UserDetailsAttributeMapper} for use in preauthenticated (Shibboleth) environments. + */ +class PreauthUserDetailsAttributeMapper implements UserDetailsAttributeMapper +{ + + /** + * {@inheritdoc} + */ + public function mapUser() + { + $userAttributes[UserDetailsAttributeMapper::EPPN] = $_SERVER[UserDetailsAttributeMapper::EPPN]; + $userAttributes[UserDetailsAttributeMapper::PVI] = $_SERVER[UserDetailsAttributeMapper::PVI]; + $userAttributes[UserDetailsAttributeMapper::FULLNAME] = $_SERVER[UserDetailsAttributeMapper::FULLNAME]; + $userAttributes[UserDetailsAttributeMapper::FIRST_NAME] = $_SERVER[UserDetailsAttributeMapper::FIRST_NAME]; + $userAttributes[UserDetailsAttributeMapper::LAST_NAME] = $_SERVER[UserDetailsAttributeMapper::LAST_NAME]; + $userAttributes[UserDetailsAttributeMapper::EMAIL] = $_SERVER[UserDetailsAttributeMapper::EMAIL]; + $userAttributes[UserDetailsAttributeMapper::UDDS] = $_SERVER[UserDetailsAttributeMapper::UDDS]; + $userAttributes[UserDetailsAttributeMapper::SOURCE] = $_SERVER[UserDetailsAttributeMapper::SOURCE]; + $userAttributes[UserDetailsAttributeMapper::ISIS_EMPLID] = $_SERVER[UserDetailsAttributeMapper::ISIS_EMPLID]; + + // Require EPPN, PVI and FULLNAME to be set to consider user loading successful + if (empty($userAttributes[UserDetailsAttributeMapper::EPPN]) || + empty($userAttributes[UserDetailsAttributeMapper::PVI]) || + empty($userAttributes[UserDetailsAttributeMapper::FULLNAME])) { + return null; + } + + return $userAttributes; + } + +} diff --git a/src/main/edu/wisc/doit/PreauthUserDetailsService.php b/src/main/edu/wisc/doit/PreauthUserDetailsService.php new file mode 100644 index 0000000000000000000000000000000000000000..11a5aa01131f4a8b3983cbe966deaff5514a018a --- /dev/null +++ b/src/main/edu/wisc/doit/PreauthUserDetailsService.php @@ -0,0 +1,52 @@ +<?php + +namespace edu\wisc\doit; + +/** + * Default implementation of {@UserDetailsAttributeMapper} for use in preauthenticated (Shibboleth) environments. + */ +class PreauthUserDetailsService implements UserDetailsService +{ + + /** @var UserDetailsAttributeMapper */ + private $attributeMapper; + + /** + * PreauthUserDetailsService constructor. + * @param UserDetailsAttributeMapper|null $mapper + */ + public function __construct(UserDetailsAttributeMapper $mapper = null) + { + if ($mapper == null) { + $this->attributeMapper = new PreauthUserDetailsAttributeMapper(); + } else { + $this->attributeMapper = $mapper; + } + } + + /** + * {@inheritdoc} + */ + public function loadUser() + { + $userAttributes = $this->attributeMapper->mapUser(); + + // Return null if attribute reading failed + if ($userAttributes == null) { + return null; + } + + return new UWUserDetails( + $userAttributes[UserDetailsAttributeMapper::EPPN], + $userAttributes[UserDetailsAttributeMapper::PVI], + $userAttributes[UserDetailsAttributeMapper::FULLNAME], + $userAttributes[UserDetailsAttributeMapper::UDDS], + $userAttributes[UserDetailsAttributeMapper::EMAIL], + $userAttributes[UserDetailsAttributeMapper::SOURCE], + $userAttributes[UserDetailsAttributeMapper::ISIS_EMPLID], + $userAttributes[UserDetailsAttributeMapper::FIRST_NAME], + $userAttributes[UserDetailsAttributeMapper::LAST_NAME] + ); + } + +} \ No newline at end of file diff --git a/src/main/edu/wisc/doit/UserDetailsAttributeMapper.php b/src/main/edu/wisc/doit/UserDetailsAttributeMapper.php index 6fbc06f835ecb8c0af2a40dd161ae135039df7d5..3db782a9e4daef3b6ea82650d4421ac205f23f9c 100644 --- a/src/main/edu/wisc/doit/UserDetailsAttributeMapper.php +++ b/src/main/edu/wisc/doit/UserDetailsAttributeMapper.php @@ -3,7 +3,7 @@ namespace edu\wisc\doit; /** - * + * */ interface UserDetailsAttributeMapper { diff --git a/src/main/edu/wisc/doit/UserDetailsService.php b/src/main/edu/wisc/doit/UserDetailsService.php index d6a60f1d3d00d6cbaac89435b0a34e647128e434..49b30ae0d71f687f52cff085ce4f090ef640fa37 100644 --- a/src/main/edu/wisc/doit/UserDetailsService.php +++ b/src/main/edu/wisc/doit/UserDetailsService.php @@ -3,12 +3,17 @@ namespace edu\wisc\doit; /** - * Interface UserDetailsService - * @package edu\wisc\doit + * */ interface UserDetailsService { - + + /** + * Return a {@link UserDetails} hydrated by a {@link UserDetailsAttributeMapper}, or null if attribute + * mapping failed. + * + * @return UserDetails|null + */ public function loadUser(); } \ No newline at end of file diff --git a/src/test/edu/wisc/doit/LocalUserDetailsAttributeMapperTest.php b/src/test/edu/wisc/doit/LocalUserDetailsAttributeMapperTest.php index 3242e66a80567058ac5bfe6b9b49e4d401282763..d79a9483f357c9ed2e079025b09cd1d5350a51a8 100644 --- a/src/test/edu/wisc/doit/LocalUserDetailsAttributeMapperTest.php +++ b/src/test/edu/wisc/doit/LocalUserDetailsAttributeMapperTest.php @@ -9,7 +9,7 @@ class LocalUserDetailsAttributeMapperTest extends \PHPUnit_Framework_TestCase { /** - * + * Test attribute mapping for local development. */ public function testMapLocalUser() { $attributeMapper = new LocalUserDetailsAttributeMapper(); diff --git a/src/test/edu/wisc/doit/PreauthTestCase.php b/src/test/edu/wisc/doit/PreauthTestCase.php new file mode 100644 index 0000000000000000000000000000000000000000..b79a69bf6f8c1564c3052e1135e74d6df40cc62f --- /dev/null +++ b/src/test/edu/wisc/doit/PreauthTestCase.php @@ -0,0 +1,34 @@ +<?php + +namespace edu\wisc\doit; + +/** + * Class to do basic setup needed to simulate a logged in Shibboleth user. + */ +abstract class PreauthTestCase extends \PHPUnit_Framework_TestCase +{ + + /** + * Populate $_SERVER with Shib attributes to simulate a logged in user + */ + protected function setUp() + { + parent::setUp(); + $jsonString = file_get_contents(__DIR__ . "/../../../resources/testuser.json"); + if ($jsonString === false) { + return null; + } + + $attributes = json_decode($jsonString, true); + $_SERVER[UserDetailsAttributeMapper::EPPN] = $attributes[UserDetailsAttributeMapper::EPPN]; + $_SERVER[UserDetailsAttributeMapper::PVI] = $attributes[UserDetailsAttributeMapper::PVI]; + $_SERVER[UserDetailsAttributeMapper::FULLNAME] = $attributes[UserDetailsAttributeMapper::FULLNAME]; + $_SERVER[UserDetailsAttributeMapper::FIRST_NAME] = $attributes[UserDetailsAttributeMapper::FIRST_NAME]; + $_SERVER[UserDetailsAttributeMapper::LAST_NAME] = $attributes[UserDetailsAttributeMapper::LAST_NAME]; + $_SERVER[UserDetailsAttributeMapper::UDDS] = $attributes[UserDetailsAttributeMapper::UDDS]; + $_SERVER[UserDetailsAttributeMapper::EMAIL] = $attributes[UserDetailsAttributeMapper::EMAIL]; + $_SERVER[UserDetailsAttributeMapper::SOURCE] = $attributes[UserDetailsAttributeMapper::SOURCE]; + $_SERVER[UserDetailsAttributeMapper::ISIS_EMPLID] = $attributes[UserDetailsAttributeMapper::ISIS_EMPLID]; + } + +} \ No newline at end of file diff --git a/src/test/edu/wisc/doit/PreauthUserDetailsAttributeMapperTest.php b/src/test/edu/wisc/doit/PreauthUserDetailsAttributeMapperTest.php new file mode 100644 index 0000000000000000000000000000000000000000..63258c4be3e06e21199ae6072c34391207d88744 --- /dev/null +++ b/src/test/edu/wisc/doit/PreauthUserDetailsAttributeMapperTest.php @@ -0,0 +1,25 @@ +<?php + +namespace edu\wisc\doit; + +/** + * Tests for {@link PreauthUserDetailsAttributeMapper}. + */ +class PreauthUserDetailsAttributeMapperTest extends PreauthTestCase +{ + + public function testMapUser() { + $attributeMapper = new PreauthUserDetailsAttributeMapper(); + $userAttributes = $attributeMapper->mapUser(); + $this->assertEquals("bbadger@wisc.edu", $userAttributes[UserDetailsAttributeMapper::EPPN]); + $this->assertEquals("UW123A456", $userAttributes[UserDetailsAttributeMapper::PVI]); + $this->assertEquals("BUCKINGHAM BADGER", $userAttributes[UserDetailsAttributeMapper::FULLNAME]); + $this->assertEquals("bucky.badger@wisc.edu", $userAttributes[UserDetailsAttributeMapper::EMAIL]); + $this->assertEquals("a_source", $userAttributes[UserDetailsAttributeMapper::SOURCE]); + $this->assertEquals("123456789", $userAttributes[UserDetailsAttributeMapper::ISIS_EMPLID]); + $this->assertEquals("BUCKINGHAM", $userAttributes[UserDetailsAttributeMapper::FIRST_NAME]); + $this->assertEquals("BADGER", $userAttributes[UserDetailsAttributeMapper::LAST_NAME]); + $this->assertEquals(["UW123A456", "UW234A567"], $userAttributes[UserDetailsAttributeMapper::UDDS]); + } + +} diff --git a/src/test/edu/wisc/doit/PreauthUserDetailsServiceTest.php b/src/test/edu/wisc/doit/PreauthUserDetailsServiceTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d2dda40b6b46cbceab6d9073625af154abebdca2 --- /dev/null +++ b/src/test/edu/wisc/doit/PreauthUserDetailsServiceTest.php @@ -0,0 +1,25 @@ +<?php + +namespace edu\wisc\doit; + +/** + * Tests for {@link PreauthUserDetailsService}. + */ +class PreauthUserDetailsServiceTest extends PreauthTestCase +{ + + public function testLoadUser() { + $userService = new PreauthUserDetailsService(); + $user = $userService->loadUser(); + $this->assertNotNull($user); + $this->assertEquals("bbadger@wisc.edu", $user->getEppn()); + $this->assertEquals("UW123A456", $user->getPvi()); + $this->assertEquals("BUCKINGHAM BADGER", $user->getFullName()); + $this->assertEquals("bucky.badger@wisc.edu", $user->getEmailAddress()); + $this->assertEquals("a_source", $user->getSource()); + $this->assertEquals("123456789", $user->getIsisEmplid()); + $this->assertEquals("BUCKINGHAM", $user->getFirstName()); + $this->assertEquals("BADGER", $user->getLastName()); + } + +} diff --git a/src/test/resources/testuser.json b/src/test/resources/testuser.json new file mode 100644 index 0000000000000000000000000000000000000000..a3a534459cfdc2a46fbf549dc978220726505e98 --- /dev/null +++ b/src/test/resources/testuser.json @@ -0,0 +1,15 @@ +{ + "eppn": "bbadger@wisc.edu", + "eduWisconsinSPVI": "UW123A456", + "cn": "BUCKINGHAM BADGER", + "eduWisconsinCommonName": "BUCKINGHAM BADGER", + "eduWisconsinGivenName": "BUCKINGHAM", + "eduWisconsinSurname": "BADGER", + "udds": [ + "UW123A456", + "UW234A567" + ], + "eduWisconsinEmailAddress": "bucky.badger@wisc.edu", + "source": "a_source", + "isisEmplid": "123456789" +} \ No newline at end of file