/Users/johnr/Desktop/IA pdf Downloads/_New Projects Downloads May 7th/CS_IA_Mattew/composer.phar
     1 #!/usr/bin/env php
     2 <?php
     3 /*
     4  * This file is part of Composer.
     5  *
     6  * (c) Nils Adermann <naderman@naderman.de>
     7  *     Jordi Boggiano <j.boggiano@seld.be>
     8  *
     9  * For the full copyright and license information, please view
    10  * the license that is located at the bottom of this file.
    11  */
    12 
    13 // Avoid APC causing random fatal errors per https://github.com/composer/composer/issues/264
    14 if (extension_loaded('apc') && filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN) && filter_var(ini_get('apc.cache_by_default'), FILTER_VALIDATE_BOOLEAN)) {
    15     if (version_compare(phpversion('apc'), '3.0.12', '>=')) {
    16         ini_set('apc.cache_by_default', 0);
    17     } else {
    18         fwrite(STDERR, 'Warning: APC <= 3.0.12 may cause fatal errors when running composer commands.'.PHP_EOL);
    19         fwrite(STDERR, 'Update APC, or set apc.enable_cli or apc.cache_by_default to 0 in your php.ini.'.PHP_EOL);
    20     }
    21 }
    22 
    23 if (!class_exists('Phar')) {
    24     echo 'PHP\'s phar extension is missing. Composer requires it to run. Enable the extension or recompile php without --disable-phar then try again.' . PHP_EOL;
    25     exit(1);
    26 }
    27 
    28 Phar::mapPhar('composer.phar');
    29 require 'phar://composer.phar/bin/composer';
    30 
    31 __HALT_COMPILER(); ?>
    32 ��+
    33 composer.phar+src/Composer/Autoload/AutoloadGenerator.php=��1b=���b��+src/Composer/Autoload/ClassMapGenerator.php��1b�(�m�(src/Composer/Autoload/PhpFileCleaner.php��1b��>��src/Composer/Cache.php��1b�y)�1�%src/Composer/Command/AboutCommand.php7�1b7�,
    34 `�'src/Composer/Command/ArchiveCommand.php��1b�
    35 >�*�$src/Composer/Command/BaseCommand.php��1b�j���.src/Composer/Command/BaseDependencyCommand.php��1b�:��1src/Composer/Command/CheckPlatformReqsCommand.php��1b�����*src/Composer/Command/ClearCacheCommand.php��1b�w�Ȥ&src/Composer/Command/ConfigCommand.php7^�1b7^�h�w�-src/Composer/Command/CreateProjectCommand.php�E�1b�EM
    36 ��'src/Composer/Command/DependsCommand.php��1b�&���(src/Composer/Command/DiagnoseCommand.php�M�1b�M�����,src/Composer/Command/DumpAutoloadCommand.php��1b��+�B�$src/Composer/Command/ExecCommand.php��1b����Ԥ$src/Composer/Command/FundCommand.phpN�1bN+5F�&src/Composer/Command/GlobalCommand.php�
    37 �1b�
    38 ;lۚ�$src/Composer/Command/HomeCommand.php   �1b �S?Y�$src/Composer/Command/InitCommand.phpow�1bow5��8�'src/Composer/Command/InstallCommand.php��1b��d��(src/Composer/Command/LicensesCommand.php~�1b~�+E��(src/Composer/Command/OutdatedCommand.php��1b��4굤)src/Composer/Command/ProhibitsCommand.php<�1b<I�3�)src/Composer/Command/ReinstallCommand.php#�1b#��c@�&src/Composer/Command/RemoveCommand.php2*�1b2*y�⻤'src/Composer/Command/RequireCommand.phpTC�1bTC���)src/Composer/Command/RunScriptCommand.php��1b�P�D�+src/Composer/Command/ScriptAliasCommand.php��1b�W����&src/Composer/Command/SearchCommand.phpe�1be�riw�*src/Composer/Command/SelfUpdateCommand.php�E�1b�E�oV�$src/Composer/Command/ShowCommand.phpޒ�1bޒ*B"��&src/Composer/Command/StatusCommand.php��1b��1��(src/Composer/Command/SuggestsCommand.php��1b�M֭�&src/Composer/Command/UpdateCommand.php5�1b5���(src/Composer/Command/ValidateCommand.php��1b��()�src/Composer/Composer.phpA�1bA�r֤src/Composer/Config.php1�1b1�*�U�-src/Composer/Config/ConfigSourceInterface.php/�1b/��(src/Composer/Config/JsonConfigSource.php��1b���Q
    39 �$src/Composer/Console/Application.php�B�1b�B)͋'�*src/Composer/Console/GithubActionError.php��1b���!C�,src/Composer/Console/HtmlOutputFormatter.php��1b�|(~Ĥ-src/Composer/DependencyResolver/Decisions.php��1b�0��ۤ1src/Composer/DependencyResolver/DefaultPolicy.php��1b���I��/src/Composer/DependencyResolver/GenericRule.phpf�1bf����8src/Composer/DependencyResolver/LocalRepoTransaction.php��1b��  #�3src/Composer/DependencyResolver/LockTransaction.php�1b�]/�5src/Composer/DependencyResolver/MultiConflictRule.php��1b��Lm��>src/Composer/DependencyResolver/Operation/InstallOperation.php��1b��F��Isrc/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php��1b�=����Ksrc/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php��1b����/�@src/Composer/DependencyResolver/Operation/OperationInterface.php��1b�Q���=src/Composer/DependencyResolver/Operation/SolverOperation.php�1bm�a�@src/Composer/DependencyResolver/Operation/UninstallOperation.php��1b��Y<�=src/Composer/DependencyResolver/Operation/UpdateOperation.phpK�1bK�;!�3src/Composer/DependencyResolver/PolicyInterface.phpm�1bm���&�(src/Composer/DependencyResolver/Pool.phpT�1bT��竤/src/Composer/DependencyResolver/PoolBuilder.php;@�1b;@�ҕ�1src/Composer/DependencyResolver/PoolOptimizer.php*�1b*w�:��+src/Composer/DependencyResolver/Problem.php�I�1b�I�Y��+src/Composer/DependencyResolver/Request.php&�1b&͊c��(src/Composer/DependencyResolver/Rule.php�/�1b�/�cκ�1src/Composer/DependencyResolver/Rule2Literals.php��1b���F�+src/Composer/DependencyResolver/RuleSet.php��1b�
    40 K.x�4src/Composer/DependencyResolver/RuleSetGenerator.phpM�1bM����3src/Composer/DependencyResolver/RuleSetIterator.php��1b����j�2src/Composer/DependencyResolver/RuleWatchChain.phpU�1bUB#�2src/Composer/DependencyResolver/RuleWatchGraph.phpS �1bS Uؤ1src/Composer/DependencyResolver/RuleWatchNode.php<�1b<�T�2�*src/Composer/DependencyResolver/Solver.phpr9�1br9��ˤ6src/Composer/DependencyResolver/SolverBugException.php��1b�^Hᕤ;src/Composer/DependencyResolver/SolverProblemsException.php=�1b=��W�/src/Composer/DependencyResolver/Transaction.php��1b���ߧ�-src/Composer/Downloader/ArchiveDownloader.php�1b�b��1src/Composer/Downloader/ChangeReportInterface.php��1b��ਿ�+src/Composer/Downloader/DownloadManager.php��1b��@�^�/src/Composer/Downloader/DownloaderInterface.php�1b_y��3src/Composer/Downloader/DvcsDownloaderInterface.php��1b�&����*src/Composer/Downloader/FileDownloader.php�.�1b�.��^4�/src/Composer/Downloader/FilesystemException.php�1b�^x�,src/Composer/Downloader/FossilDownloader.php\�1b\�$��)src/Composer/Downloader/GitDownloader.php�B�1b�B'�@�*src/Composer/Downloader/GzipDownloader.php�1b����(src/Composer/Downloader/HgDownloader.php
    41 �1b
    42 ԃ0,�8src/Composer/Downloader/MaxFileSizeExceededException.phps�1bs٢�*src/Composer/Downloader/PathDownloader.php��1b�B+�.src/Composer/Downloader/PerforceDownloader.php��1b���ؕ�*src/Composer/Downloader/PharDownloader.phpI�1bI�k0�)src/Composer/Downloader/RarDownloader.php6�1b6��F��)src/Composer/Downloader/SvnDownloader.php6�1b6�u83�)src/Composer/Downloader/TarDownloader.phpG�1bG/P]�.src/Composer/Downloader/TransportException.php&�1b&xc# �9src/Composer/Downloader/VcsCapableDownloaderInterface.php��1b�`����)src/Composer/Downloader/VcsDownloader.phpr�1br6�t��(src/Composer/Downloader/XzDownloader.phpL�1bLb]�ۤ)src/Composer/Downloader/ZipDownloader.php��1b����F�&src/Composer/EventDispatcher/Event.php��1b��Nnj�0src/Composer/EventDispatcher/EventDispatcher.php@3�1b@3����9src/Composer/EventDispatcher/EventSubscriberInterface.php��1b�h�0�9src/Composer/EventDispatcher/ScriptExecutionException.phpv�1bvwZ8S�9src/Composer/Exception/IrrecoverableDownloadException.phpv�1bvDM�y�)src/Composer/Exception/NoSslException.phph�1bh�d�Ӥsrc/Composer/Factory.phppG�1bpG�I�:�Tsrc/Composer/Filter/PlatformRequirementFilter/IgnoreAllPlatformRequirementFilter.php'�1b'����Usrc/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php��1b�����Xsrc/Composer/Filter/PlatformRequirementFilter/IgnoreNothingPlatformRequirementFilter.php��1b��}�7�Rsrc/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterFactory.php��1b�:�U�Tsrc/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterInterface.php��1b�j��"�src/Composer/IO/BaseIO.php��1b�5����src/Composer/IO/BufferIO.php�1b]+�Τsrc/Composer/IO/ConsoleIO.phpZ�1bZ�;u�src/Composer/IO/IOInterface.php��1b��6s�src/Composer/IO/NullIO.php��1b��Z��src/Composer/Installer.php�}�1b�}0d���*src/Composer/Installer/BinaryInstaller.phpA(�1bA(U��P�2src/Composer/Installer/BinaryPresenceInterface.php��1b���`U�.src/Composer/Installer/InstallationManager.php�5�1b�5M�\L�)src/Composer/Installer/InstallerEvent.php��1b��E
    43 N�*src/Composer/Installer/InstallerEvents.php��1b�n�<��-src/Composer/Installer/InstallerInterface.phpI�1bI���\�+src/Composer/Installer/LibraryInstaller.php��1b��F�/src/Composer/Installer/MetapackageInstaller.php��1b���@��(src/Composer/Installer/NoopInstaller.php&�1b&.��'src/Composer/Installer/PackageEvent.php��1b�=��X�(src/Composer/Installer/PackageEvents.php��1b�db�s�*src/Composer/Installer/PluginInstaller.php�
    44 �1b�
    45 9�s�+src/Composer/Installer/ProjectInstaller.phpl�1blf���4src/Composer/Installer/SuggestedPackagesReporter.php�1b�M$�src/Composer/Json/JsonFile.php��1b�����#src/Composer/Json/JsonFormatter.phpl�1bl)�F�%src/Composer/Json/JsonManipulator.phpj3�1bj3����-src/Composer/Json/JsonValidationException.phpo�1boT3�I�%src/Composer/Package/AliasPackage.php��1b�Zd�[�7src/Composer/Package/Archiver/ArchivableFilesFilter.php(�1b(U?�0�7src/Composer/Package/Archiver/ArchivableFilesFinder.php�1bb��0src/Composer/Package/Archiver/ArchiveManager.php�1b߸d��3src/Composer/Package/Archiver/ArchiverInterface.php�1b�����3src/Composer/Package/Archiver/BaseExcludeFilter.php��1b�)/ʤ7src/Composer/Package/Archiver/ComposerExcludeFilter.php�1b�SZ0�2src/Composer/Package/Archiver/GitExcludeFilter.php��1b��k�.src/Composer/Package/Archiver/PharArchiver.php��1b���TL�-src/Composer/Package/Archiver/ZipArchiver.php��1b��r��$src/Composer/Package/BasePackage.php��1b�/�|1�*src/Composer/Package/Comparer/Comparer.php��1b��C��-src/Composer/Package/CompleteAliasPackage.php�        �1b� KW�(src/Composer/Package/CompletePackage.phpR     �1bR �2��1src/Composer/Package/CompletePackageInterface.php��1b��B�$�+src/Composer/Package/Dumper/ArrayDumper.php
    46 �1b
    47 �Q!�src/Composer/Package/Link.phpo�1bo\� @�+src/Composer/Package/Loader/ArrayLoader.php�+�1b�+\n��7src/Composer/Package/Loader/InvalidPackageException.phpV�1bVD��*src/Composer/Package/Loader/JsonLoader.php�1b��o�/src/Composer/Package/Loader/LoaderInterface.php��1b��&<l�1src/Composer/Package/Loader/RootPackageLoader.php��1b��d`�5src/Composer/Package/Loader/ValidatingArrayLoader.php�L�1b�L���U�src/Composer/Package/Locker.phpx%�1bx%��4� src/Composer/Package/Package.php-"�1b-"�^�)src/Composer/Package/PackageInterface.php�   �1b� ���Q�)src/Composer/Package/RootAliasPackage.php*�1b*�/���$src/Composer/Package/RootPackage.phpC�1bC�d�a�-src/Composer/Package/RootPackageInterface.php��1b�����0src/Composer/Package/Version/StabilityFilter.php��1b�'o���/src/Composer/Package/Version/VersionGuesser.phpA%�1bA%�m��.src/Composer/Package/Version/VersionParser.php��1b�Kj��0src/Composer/Package/Version/VersionSelector.php\�1b\����&src/Composer/Platform/HhvmDetector.php      �1b �L��!src/Composer/Platform/Runtime.phpK�1bKA�
    48 �!src/Composer/Platform/Version.php��1b������-src/Composer/Plugin/Capability/Capability.phpW�1bW�_�1�2src/Composer/Plugin/Capability/CommandProvider.php��1b��O�>�src/Composer/Plugin/Capable.php�1b�q+�$src/Composer/Plugin/CommandEvent.php��1b����W�$src/Composer/Plugin/PluginEvents.phpe�1be*U~r�'src/Composer/Plugin/PluginInterface.php��1b��-��%src/Composer/Plugin/PluginManager.php�I�1b�Iүkݤ-src/Composer/Plugin/PostFileDownloadEvent.phpT�1bT/��3�*src/Composer/Plugin/PreCommandRunEvent.php��1b�:�d�,src/Composer/Plugin/PreFileDownloadEvent.php5�1b5a�0z�*src/Composer/Plugin/PrePoolCreateEvent.phpR�1bR�c��4src/Composer/Question/StrictConfirmationQuestion.php>�1b>[�ܧ�+src/Composer/Repository/ArrayRepository.php1�1b1t�뎤.src/Composer/Repository/ArtifactRepository.php�1b�$&�.src/Composer/Repository/ComposerRepository.phpS��1bS�,�I�/src/Composer/Repository/CompositeRepository.php��1b�����;src/Composer/Repository/ConfigurableRepositoryInterface.php��1b��s�0src/Composer/Repository/FilesystemRepository.php��1b��@�,src/Composer/Repository/FilterRepository.php�
    49 �1b�
    50 �����4src/Composer/Repository/InstalledArrayRepository.php1�1b1]�פ9src/Composer/Repository/InstalledFilesystemRepository.php1�1b1y&�ͤ/src/Composer/Repository/InstalledRepository.php+�1b+�kפ8src/Composer/Repository/InstalledRepositoryInterface.php��1b�-B��6src/Composer/Repository/InvalidRepositoryException.phpn�1bn��똤/src/Composer/Repository/LockArrayRepository.php��1b�E��S�-src/Composer/Repository/PackageRepository.php��1b����8�*src/Composer/Repository/PathRepository.phpd�1bd�]���*src/Composer/Repository/PearRepository.php��1b��0�Ǥ.src/Composer/Repository/PlatformRepository.php�R�1b�R��N!�-src/Composer/Repository/RepositoryFactory.php��1b�1F�e�/src/Composer/Repository/RepositoryInterface.phpS�1bS�(�E�-src/Composer/Repository/RepositoryManager.php
    51 �1b
    52 ����7src/Composer/Repository/RepositorySecurityException.phpo�1bopի��)src/Composer/Repository/RepositorySet.phpa�1ba۽rͤ1src/Composer/Repository/RootPackageRepository.php@�1b@X���,src/Composer/Repository/Vcs/FossilDriver.php��1b�1�Ԥ2src/Composer/Repository/Vcs/GitBitbucketDriver.php�&�1b�&�"�ۤ)src/Composer/Repository/Vcs/GitDriver.php��1b��c~W�,src/Composer/Repository/Vcs/GitHubDriver.php6�1b6�����,src/Composer/Repository/Vcs/GitLabDriver.phpB/�1bB/!l^��(src/Composer/Repository/Vcs/HgDriver.phpI�1bI]ǻ֤.src/Composer/Repository/Vcs/PerforceDriver.php'
    53 �1b'
    54 �}�w�)src/Composer/Repository/Vcs/SvnDriver.php��1b��O���)src/Composer/Repository/Vcs/VcsDriver.php�
    55 �1b�
    56 (     �2src/Composer/Repository/Vcs/VcsDriverInterface.php��1b����)src/Composer/Repository/VcsRepository.php�3�1b�3%�c�1src/Composer/Repository/VersionCacheInterface.php��1b�A?R�3src/Composer/Repository/WritableArrayRepository.php��1b�wͤ7src/Composer/Repository/WritableRepositoryInterface.phpY�1bYl�A��src/Composer/Script/Event.php��1b�����$src/Composer/Script/ScriptEvents.php��1b����� src/Composer/SelfUpdate/Keys.php��1b���=�$src/Composer/SelfUpdate/Versions.phpK�1bK��� src/Composer/Util/AuthHelper.php!�1b!�����src/Composer/Util/Bitbucket.php��1b�9���$src/Composer/Util/ComposerMirror.phpt�1bt�N`�%src/Composer/Util/ConfigValidator.phpQ�1bQ�G��"src/Composer/Util/ErrorHandler.php��1b���i� src/Composer/Util/Filesystem.php�9�1b�9�=�5�src/Composer/Util/Git.php�5�1b�5?�E��src/Composer/Util/GitHub.php��1b�|�B�src/Composer/Util/GitLab.php��1b��y�Ǥsrc/Composer/Util/Hg.php �1b ~���)src/Composer/Util/Http/CurlDownloader.php�F�1b�F9Κ�'src/Composer/Util/Http/CurlResponse.phpg�1bg�����&src/Composer/Util/Http/ProxyHelper.phpM
    57 �1bM
    58 ��M��'src/Composer/Util/Http/ProxyManager.php6
    59 �1b6
    60 ���'src/Composer/Util/Http/RequestProxy.php�1b�S��#src/Composer/Util/Http/Response.php��1b��GH��$src/Composer/Util/HttpDownloader.phpN)�1bN)4��R�src/Composer/Util/IniHelper.phph�1bh;FP�src/Composer/Util/Loop.php��1b�Է}��&src/Composer/Util/MetadataMinifier.php*�1b*h�/~�$src/Composer/Util/NoProxyPattern.phpk�1bk��>�#src/Composer/Util/PackageSorter.phpZ�1bZU6+�src/Composer/Util/Perforce.phpm3�1bm3�0ٚ�src/Composer/Util/Platform.php��1b�Y�;�%src/Composer/Util/ProcessExecutor.php<�1b<�?�'�&src/Composer/Util/RemoteFilesystem.phprN�1brN����src/Composer/Util/Silencer.php��1b�pD�*src/Composer/Util/StreamContextFactory.php{�1b{�Z�src/Composer/Util/Svn.php�1b��5\� src/Composer/Util/SyncHelper.php;�1b;*�
    61 ��src/Composer/Util/Tar.phpb�1bb�]��src/Composer/Util/TlsHelper.phpy
    62 �1by
    63 +�V��src/Composer/Util/Url.php@�1b@���]�src/Composer/Util/Zip.php��1b��+�src/bootstrap.php��1b�@�H*�%src/Composer/Autoload/ClassLoader.php�>�1b�>�5Ky�"src/Composer/InstalledVersions.php�:�1b�:T��"�#res/composer-repository-schema.json��1b�|0���res/composer-schema.json���1b����-�vendor/autoload.php��1b��H�ävendor/composer/ClassLoader.php\�1b\�Zu��%vendor/composer/InstalledVersions.phpi�1bi�$�.�%vendor/composer/autoload_classmap.php��1b�x����"vendor/composer/autoload_files.php��1b��
    64 �'vendor/composer/autoload_namespaces.php��1b��R7c�!vendor/composer/autoload_psr4.php��1b����=�!vendor/composer/autoload_real.phph�1bhv2���#vendor/composer/autoload_static.php�
    65 �1b�
    66 ȣ��!vendor/composer/ca-bundle/LICENSE�1bG _�(vendor/composer/ca-bundle/res/cacert.pem�,�1b�,�_~��*vendor/composer/ca-bundle/src/CaBundle.php�$�1b�$�n��vendor/composer/installed.php�1b
    67 �*�)vendor/composer/metadata-minifier/LICENSE�1b���Ǥ:vendor/composer/metadata-minifier/src/MetadataMinifier.php��1b��0&��vendor/composer/pcre/LICENSE�1b���Ǥ+vendor/composer/pcre/src/MatchAllResult.php�1b8aǔ�6vendor/composer/pcre/src/MatchAllWithOffsetsResult.php&�1b&�       |�(vendor/composer/pcre/src/MatchResult.php��1b����3vendor/composer/pcre/src/MatchWithOffsetsResult.php��1b�<��¤*vendor/composer/pcre/src/PcreException.php:�1b:}��!vendor/composer/pcre/src/Preg.php�1bV�ib�"vendor/composer/pcre/src/Regex.php��1b����U�*vendor/composer/pcre/src/ReplaceResult.php�1b�n0��vendor/composer/semver/LICENSE�1b�SRm�)vendor/composer/semver/src/Comparator.php�1b^_E��/vendor/composer/semver/src/CompilingMatcher.php_�1b_��d�/vendor/composer/semver/src/Constraint/Bound.phpw�1bwW4]W�4vendor/composer/semver/src/Constraint/Constraint.php��1b������=vendor/composer/semver/src/Constraint/ConstraintInterface.php��1b��5�y�<vendor/composer/semver/src/Constraint/MatchAllConstraint.php��1b��E��=vendor/composer/semver/src/Constraint/MatchNoneConstraint.php��1b�֯خ�9vendor/composer/semver/src/Constraint/MultiConstraint.php��1b���Ĥ'vendor/composer/semver/src/Interval.php��1b�=[i�(vendor/composer/semver/src/Intervals.php�+�1b�+@1���%vendor/composer/semver/src/Semver.php��1b��-i�,vendor/composer/semver/src/VersionParser.php�,�1b�,*e��%vendor/composer/spdx-licenses/LICENSE�1b�SRm�6vendor/composer/spdx-licenses/res/spdx-exceptions.json��1b��4DC�4vendor/composer/spdx-licenses/res/spdx-licenses.json��1b�e��̤2vendor/composer/spdx-licenses/src/SpdxLicenses.php{�1b{� ��&vendor/composer/xdebug-handler/LICENSE+�1b+��@T�0vendor/composer/xdebug-handler/src/PhpConfig.php\�1b\p�Al�.vendor/composer/xdebug-handler/src/Process.php��1b�6�`ۤ-vendor/composer/xdebug-handler/src/Status.php&�1b&��!�4vendor/composer/xdebug-handler/src/XdebugHandler.php�*�1b�*�"r��(vendor/justinrainbow/json-schema/LICENSE"�1b"|���Nvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php�       �1b� �w�l�Tvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php�
    68 �1b�
    69 ��=��Jvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php�
    70 �1b�
    71 �PFF�Svendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php��1b�� Q��Nvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.php\�1b\_}��Gvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.php��1b��_��Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.phps�1bsdޤPvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php�       �1b� e���Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php��1b�%l���Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php& �1b& 78���Pvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.phpz�1bz�f�~�Xvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.phpa�1ba     qäYvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php��1b�4~���\vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php��1b���+j�Nvendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php�1b�%}�Svendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php,"�1b,"�-�Fvendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php��1b�{N��Pvendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.phpI�1bI%|��Vvendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.php��1b���G�Tvendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.phpl�1blA!LפTvendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.phpl�1bl�2���]vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.phpu�1bu=h��Wvendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.phpw�1bwN-�[�Svendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php��1b�\�
    72 �Wvendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.phpo�1bop����Nvendor/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.php��1b�%���^vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php��1b�u-#1�Rvendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.phpj�1bj�>��Qvendor/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.phpf�1bf�����Kvendor/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php��1b�M����;vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.php��1b�f4���Avendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php�
    73 �1b�
    74 &z�^�Jvendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php�1bo�+}�Tvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.php��1b�[�A��Gvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.php��1b�ǒ���Rvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.php �1b ���Rvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php,�1b,1�5��Xvendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php��1b�����Cvendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php�1b�P�Dvendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php@�1b@5�3�Hvendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php��1b�J��Ivendor/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php��1b���e�=vendor/justinrainbow/json-schema/src/JsonSchema/Validator.phps�1bs���#�vendor/psr/log/LICENSE?�1b?��  �)vendor/psr/log/Psr/Log/AbstractLogger.php;�1b;�>3[�3vendor/psr/log/Psr/Log/InvalidArgumentException.php`�1b` �X1�#vendor/psr/log/Psr/Log/LogLevel.php��1b�j��8�/vendor/psr/log/Psr/Log/LoggerAwareInterface.php|�1b|$���+vendor/psr/log/Psr/Log/LoggerAwareTrait.php��1b�T��B�*vendor/psr/log/Psr/Log/LoggerInterface.php��1b��x�&vendor/psr/log/Psr/Log/LoggerTrait.phpk�1bk�}���%vendor/psr/log/Psr/Log/NullLogger.php��1b��X�)vendor/psr/log/Psr/Log/Test/DummyTest.phpp�1bp��3vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php 
    75 �1b 
    76 $/Ҥ*vendor/psr/log/Psr/Log/Test/TestLogger.php<�1b<�(�I�vendor/react/promise/LICENSE'�1b'�-���Fvendor/react/promise/src/React/Promise/CancellablePromiseInterface.php��1b�       �<��3vendor/react/promise/src/React/Promise/Deferred.php��1b�o(ퟤ:vendor/react/promise/src/React/Promise/DeferredPromise.php��1b��`W�;vendor/react/promise/src/React/Promise/DeferredResolver.php��1b�7�u�;vendor/react/promise/src/React/Promise/FulfilledPromise.php��1b���U�6vendor/react/promise/src/React/Promise/LazyPromise.php�1b���2vendor/react/promise/src/React/Promise/Promise.php�1b�6J��;vendor/react/promise/src/React/Promise/PromiseInterface.php��1b����n�<vendor/react/promise/src/React/Promise/PromisorInterface.php\�1b\W���:vendor/react/promise/src/React/Promise/RejectedPromise.php��1b�fC��<vendor/react/promise/src/React/Promise/ResolverInterface.php��1b���O�/vendor/react/promise/src/React/Promise/Util.php��1b���$:�/vendor/react/promise/src/React/Promise/When.php��1b��o�4vendor/react/promise/src/React/Promise/functions.php��1b�!�O�<vendor/react/promise/src/React/Promise/functions_include.php\�1b\1��^�vendor/seld/jsonlint/LICENSE$�1b$4:�~�@vendor/seld/jsonlint/src/Seld/JsonLint/DuplicateKeyException.phpk�1bkZ��ä5vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.php62�1b6228ˤ0vendor/seld/jsonlint/src/Seld/JsonLint/Lexer.php#�1b#��@,�;vendor/seld/jsonlint/src/Seld/JsonLint/ParsingException.php%�1b%`a�|�4vendor/seld/jsonlint/src/Seld/JsonLint/Undefined.php>�1b>�q���vendor/seld/phar-utils/LICENSE$�1b$�,M��%vendor/seld/phar-utils/src/Linter.phpi�1bi��ޤ)vendor/seld/phar-utils/src/Timestamps.php��1b��4��&vendor/symfony/console/Application.php+X�1b+X��yX�*vendor/symfony/console/Command/Command.php�"�1b�"���¤.vendor/symfony/console/Command/HelpCommand.php��1b���-:�.vendor/symfony/console/Command/ListCommand.phpZ�1bZ�w`�(vendor/symfony/console/ConsoleEvents.php��1b�R��e�<vendor/symfony/console/Descriptor/ApplicationDescription.php��1b�<�U�0vendor/symfony/console/Descriptor/Descriptor.php��1b��N��9vendor/symfony/console/Descriptor/DescriptorInterface.php��1b��Q��4vendor/symfony/console/Descriptor/JsonDescriptor.php�
    77 �1b�
    78 *��ɤ8vendor/symfony/console/Descriptor/MarkdownDescriptor.php��1b���;ݤ4vendor/symfony/console/Descriptor/TextDescriptor.php��1b�c�q��3vendor/symfony/console/Descriptor/XmlDescriptor.php�1bb{<�4vendor/symfony/console/Event/ConsoleCommandEvent.php��1b�!Ȥ-vendor/symfony/console/Event/ConsoleEvent.php��1b��x�\�6vendor/symfony/console/Event/ConsoleExceptionEvent.php�1b�2�6vendor/symfony/console/Event/ConsoleTerminateEvent.phpz�1bz�,�L�=vendor/symfony/console/Exception/CommandNotFoundException.php��1b��� L�7vendor/symfony/console/Exception/ExceptionInterface.phpf�1bf�AB��=vendor/symfony/console/Exception/InvalidArgumentException.php��1b��̽Z�;vendor/symfony/console/Exception/InvalidOptionException.php��1b���H�3vendor/symfony/console/Exception/LogicException.php��1b��O\e�5vendor/symfony/console/Exception/RuntimeException.php��1b���,6�4vendor/symfony/console/Formatter/OutputFormatter.php3�1b3�פ=vendor/symfony/console/Formatter/OutputFormatterInterface.php��1b������9vendor/symfony/console/Formatter/OutputFormatterStyle.phpF�1bF𦴤Bvendor/symfony/console/Formatter/OutputFormatterStyleInterface.php��1b���G�>vendor/symfony/console/Formatter/OutputFormatterStyleStack.php@�1b@G��U�6vendor/symfony/console/Helper/DebugFormatterHelper.phpy�1by�8�Ф2vendor/symfony/console/Helper/DescriptorHelper.phpw�1bw|�C�.vendor/symfony/console/Helper/DialogHelper.php��1b���7�1vendor/symfony/console/Helper/FormatterHelper.phpd�1bd��,��(vendor/symfony/console/Helper/Helper.php��1b��'���1vendor/symfony/console/Helper/HelperInterface.php��1b����+vendor/symfony/console/Helper/HelperSet.php��1b���W"�2vendor/symfony/console/Helper/InputAwareHelper.phpc�1bc����/vendor/symfony/console/Helper/ProcessHelper.php�        �1b� �w�R�-vendor/symfony/console/Helper/ProgressBar.phpc%�1bc%C&w�0vendor/symfony/console/Helper/ProgressHelper.phpY�1bYR!�/�3vendor/symfony/console/Helper/ProgressIndicator.phpM�1bM����0vendor/symfony/console/Helper/QuestionHelper.php[�1b[�6}�7vendor/symfony/console/Helper/SymfonyQuestionHelper.php�
    79 �1b�
    80 ]~R�'vendor/symfony/console/Helper/Table.php�*�1b�*f��!�+vendor/symfony/console/Helper/TableCell.php��1b���[�-vendor/symfony/console/Helper/TableHelper.php�1b�u���0vendor/symfony/console/Helper/TableSeparator.php��1b�az�,vendor/symfony/console/Helper/TableStyle.php 
    81 �1b 
    82 _�I"�*vendor/symfony/console/Input/ArgvInput.php�1b��B-�+vendor/symfony/console/Input/ArrayInput.php)�1b)��C�&vendor/symfony/console/Input/Input.php��1b�f�?�.vendor/symfony/console/Input/InputArgument.php�1bD
    83 ��4vendor/symfony/console/Input/InputAwareInterface.php��1b��O��0vendor/symfony/console/Input/InputDefinition.php��1b��U)��/vendor/symfony/console/Input/InputInterface.php��1b��B�'�,vendor/symfony/console/Input/InputOption.php�1b\��=�,vendor/symfony/console/Input/StringInput.php��1b�{����vendor/symfony/console/LICENSE+�1b+���g�/vendor/symfony/console/Logger/ConsoleLogger.php- �1b- ghT��0vendor/symfony/console/Output/BufferedOutput.php_�1b_��>P�/vendor/symfony/console/Output/ConsoleOutput.php��1b�n�!f�8vendor/symfony/console/Output/ConsoleOutputInterface.php��1b����ʤ,vendor/symfony/console/Output/NullOutput.php��1b��0�f�(vendor/symfony/console/Output/Output.php�   �1b� 0p�1vendor/symfony/console/Output/OutputInterface.php�1b�&�.vendor/symfony/console/Output/StreamOutput.php��1b�.���2vendor/symfony/console/Question/ChoiceQuestion.phpv
    84 �1bv
    85 ��WP�8vendor/symfony/console/Question/ConfirmationQuestion.php��1b�/ԏ�,vendor/symfony/console/Question/Question.php�      �1b� lF�4vendor/symfony/console/Resources/bin/hiddeninput.exe$�1b$���v� vendor/symfony/console/Shell.php��1b�����,vendor/symfony/console/Style/OutputStyle.php\�1b\wפ�/vendor/symfony/console/Style/StyleInterface.php��1b�&n�Ѥ-vendor/symfony/console/Style/SymfonyStyle.php��1b���c�3vendor/symfony/console/Tester/ApplicationTester.php��1b�s�9i�/vendor/symfony/console/Tester/CommandTester.php��1b�<���(vendor/symfony/debug/BufferingLogger.phpt�1bt=hܤvendor/symfony/debug/Debug.php+�1b+.�=��)vendor/symfony/debug/DebugClassLoader.php��1b�^�*�%vendor/symfony/debug/ErrorHandler.php�G�1b�G�zL�9vendor/symfony/debug/Exception/ClassNotFoundException.php��1b�i����8vendor/symfony/debug/Exception/ContextErrorException.php��1b�-
    86 d2�1vendor/symfony/debug/Exception/DummyException.php�1b�+��6vendor/symfony/debug/Exception/FatalErrorException.php�1b4�$��6vendor/symfony/debug/Exception/FatalThrowableError.phpW�1bW?��K�3vendor/symfony/debug/Exception/FlattenException.php��1b�+a&�7vendor/symfony/debug/Exception/OutOfMemoryException.php~�1b~�o�=vendor/symfony/debug/Exception/UndefinedFunctionException.php��1b���J��;vendor/symfony/debug/Exception/UndefinedMethodException.php��1b�n��ؤ)vendor/symfony/debug/ExceptionHandler.php$3�1b$3E�ף�Ivendor/symfony/debug/FatalErrorHandler/ClassNotFoundFatalErrorHandler.php5�1b5��*V�Evendor/symfony/debug/FatalErrorHandler/FatalErrorHandlerInterface.php�1bĹBV�Mvendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandler.phpx�1bx~�"�Kvendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.phpN�1bN'����vendor/symfony/debug/LICENSE+�1b+���g�:vendor/symfony/filesystem/Exception/ExceptionInterface.phpi�1bi$ ���=vendor/symfony/filesystem/Exception/FileNotFoundException.php��1b�p�\��3vendor/symfony/filesystem/Exception/IOException.php��1b���#Ѥ<vendor/symfony/filesystem/Exception/IOExceptionInterface.php��1b�j�wM�(vendor/symfony/filesystem/Filesystem.phpM4�1bM4�z_�!vendor/symfony/filesystem/LICENSE+�1b+���g�)vendor/symfony/filesystem/LockHandler.php��1b�~3�Z�1vendor/symfony/finder/Adapter/AbstractAdapter.php\�1b\h�B�5vendor/symfony/finder/Adapter/AbstractFindAdapter.php��1b�kM�ޤ2vendor/symfony/finder/Adapter/AdapterInterface.php��1b�M��0vendor/symfony/finder/Adapter/BsdFindAdapter.php2�1b2��D)�0vendor/symfony/finder/Adapter/GnuFindAdapter.php�1b���O�,vendor/symfony/finder/Adapter/PhpAdapter.php��1b��d�;�/vendor/symfony/finder/Comparator/Comparator.php��1b������3vendor/symfony/finder/Comparator/DateComparator.php#�1b#�Τ5vendor/symfony/finder/Comparator/NumberComparator.php{�1b{���Y�9vendor/symfony/finder/Exception/AccessDeniedException.php��1b���s��;vendor/symfony/finder/Exception/AdapterFailureException.php��1b�wR�6vendor/symfony/finder/Exception/ExceptionInterface.php��1b�Gz-�Avendor/symfony/finder/Exception/OperationNotPermitedException.php)�1b)x�e�@vendor/symfony/finder/Exception/ShellCommandFailureException.php��1b�����/vendor/symfony/finder/Expression/Expression.php�1bi�:Ť)vendor/symfony/finder/Expression/Glob.phpf�1bfD�cj�*vendor/symfony/finder/Expression/Regex.php�1b�;M)�3vendor/symfony/finder/Expression/ValueInterface.php��1b�\p4�� vendor/symfony/finder/Finder.phpc.�1bc.:�5g�vendor/symfony/finder/Glob.phpL�1bLj�9פ7vendor/symfony/finder/Iterator/CustomFilterIterator.php]�1b]�o�Ƥ:vendor/symfony/finder/Iterator/DateRangeFilterIterator.phpx�1bx�P�;vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php��1b��͝q�Avendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php��1b�n�H�4vendor/symfony/finder/Iterator/FilePathsIterator.php#�1b#G?T��9vendor/symfony/finder/Iterator/FileTypeFilterIterator.phpZ�1bZ(&��<vendor/symfony/finder/Iterator/FilecontentFilterIterator.php5�1b5���9vendor/symfony/finder/Iterator/FilenameFilterIterator.phpr�1brtu�1vendor/symfony/finder/Iterator/FilterIterator.php��1b��㯤=vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php*�1b*����5vendor/symfony/finder/Iterator/PathFilterIterator.php��1b��c�=vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php  �1b O}C�:vendor/symfony/finder/Iterator/SizeRangeFilterIterator.phpe�1be����3vendor/symfony/finder/Iterator/SortableIterator.php+�1b+��� �vendor/symfony/finder/LICENSE+�1b+���g�'vendor/symfony/finder/Shell/Command.php>�1b>_~u�%vendor/symfony/finder/Shell/Shell.phpq�1bq�ӊ0�%vendor/symfony/finder/SplFileInfo.php�1b����'vendor/symfony/polyfill-ctype/Ctype.phpH      �1bH ���ݤ%vendor/symfony/polyfill-ctype/LICENSE+�1b+��E:�+vendor/symfony/polyfill-ctype/bootstrap.php��1b�|p:�(vendor/symfony/polyfill-mbstring/LICENSE+�1b+��{�-vendor/symfony/polyfill-mbstring/Mbstring.php~G�1b~G��T�Dvendor/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8��1b�ڝ.��@vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php�T�1b�T�2�?�Fvendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php��1b��y_��@vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php�U�1b�U`�8Q�.vendor/symfony/polyfill-mbstring/bootstrap.php�1b�J��7vendor/symfony/process/Exception/ExceptionInterface.phpf�1bf]�>T�=vendor/symfony/process/Exception/InvalidArgumentException.php��1b���+_�3vendor/symfony/process/Exception/LogicException.php��1b� ���;vendor/symfony/process/Exception/ProcessFailedException.phpx�1bx��zy�=vendor/symfony/process/Exception/ProcessTimedOutException.php�1b���5vendor/symfony/process/Exception/RuntimeException.php��1b���:�+vendor/symfony/process/ExecutableFinder.php��1b���̤vendor/symfony/process/LICENSE+�1b+���g�.vendor/symfony/process/PhpExecutableFinder.php��1b��0�%vendor/symfony/process/PhpProcess.php��1b�c��Ĥ.vendor/symfony/process/Pipes/AbstractPipes.php��1b�x�,��/vendor/symfony/process/Pipes/PipesInterface.phpD�1bDv�*vendor/symfony/process/Pipes/UnixPipes.php7�1b7b�p��-vendor/symfony/process/Pipes/WindowsPipes.phpi�1bi�
    87 �Ĥ"vendor/symfony/process/Process.php�R�1b�R�ӥ��)vendor/symfony/process/ProcessBuilder.php�
    88 �1b�
    89 �6I��'vendor/symfony/process/ProcessUtils.phpJ�1bJ{�C�bin/composerx
    90 �1bx
    91 ��~�LICENSE.�1b. ��<?php
    92 
    93 
    94 
    95 
    96 
    97 
    98 
    99 
   100 
   101 
   102 
   103 namespace Composer\Autoload;
   104 
   105 use Composer\Config;
   106 use Composer\EventDispatcher\EventDispatcher;
   107 use Composer\Filter\PlatformRequirementFilter\IgnoreAllPlatformRequirementFilter;
   108 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
   109 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterInterface;
   110 use Composer\Installer\InstallationManager;
   111 use Composer\IO\IOInterface;
   112 use Composer\Package\AliasPackage;
   113 use Composer\Package\PackageInterface;
   114 use Composer\Package\RootPackageInterface;
   115 use Composer\Pcre\Preg;
   116 use Composer\Repository\InstalledRepositoryInterface;
   117 use Composer\Semver\Constraint\Bound;
   118 use Composer\Util\Filesystem;
   119 use Composer\Util\Platform;
   120 use Composer\Script\ScriptEvents;
   121 use Composer\Util\PackageSorter;
   122 use Composer\Json\JsonFile;
   123 
   124 
   125 
   126 
   127 
   128 class AutoloadGenerator
   129 {
   130 
   131 
   132 
   133 private $eventDispatcher;
   134 
   135 
   136 
   137 
   138 private $io;
   139 
   140 
   141 
   142 
   143 private $devMode = null;
   144 
   145 
   146 
   147 
   148 private $classMapAuthoritative = false;
   149 
   150 
   151 
   152 
   153 private $apcu = false;
   154 
   155 
   156 
   157 
   158 private $apcuPrefix;
   159 
   160 
   161 
   162 
   163 private $runScripts = false;
   164 
   165 
   166 
   167 
   168 private $platformRequirementFilter;
   169 
   170 public function __construct(EventDispatcher $eventDispatcher, IOInterface $io = null)
   171 {
   172 $this->eventDispatcher = $eventDispatcher;
   173 $this->io = $io;
   174 
   175 $this->platformRequirementFilter = PlatformRequirementFilterFactory::ignoreNothing();
   176 }
   177 
   178 
   179 
   180 
   181 
   182 public function setDevMode($devMode = true)
   183 {
   184 $this->devMode = (bool) $devMode;
   185 }
   186 
   187 
   188 
   189 
   190 
   191 
   192 
   193 public function setClassMapAuthoritative($classMapAuthoritative)
   194 {
   195 $this->classMapAuthoritative = (bool) $classMapAuthoritative;
   196 }
   197 
   198 
   199 
   200 
   201 
   202 
   203 
   204 
   205 public function setApcu($apcu, $apcuPrefix = null)
   206 {
   207 $this->apcu = (bool) $apcu;
   208 $this->apcuPrefix = $apcuPrefix !== null ? (string) $apcuPrefix : $apcuPrefix;
   209 }
   210 
   211 
   212 
   213 
   214 
   215 
   216 
   217 public function setRunScripts($runScripts = true)
   218 {
   219 $this->runScripts = (bool) $runScripts;
   220 }
   221 
   222 
   223 
   224 
   225 
   226 
   227 
   228 
   229 
   230 
   231 
   232 
   233 
   234 public function setIgnorePlatformRequirements($ignorePlatformReqs)
   235 {
   236 trigger_error('AutoloadGenerator::setIgnorePlatformRequirements is deprecated since Composer 2.2, use setPlatformRequirementFilter instead.', E_USER_DEPRECATED);
   237 
   238 $this->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs));
   239 }
   240 
   241 
   242 
   243 
   244 public function setPlatformRequirementFilter(PlatformRequirementFilterInterface $platformRequirementFilter)
   245 {
   246 $this->platformRequirementFilter = $platformRequirementFilter;
   247 }
   248 
   249 
   250 
   251 
   252 
   253 
   254 
   255 
   256 public function dump(Config $config, InstalledRepositoryInterface $localRepo, RootPackageInterface $rootPackage, InstallationManager $installationManager, $targetDir, $scanPsrPackages = false, $suffix = '')
   257 {
   258 if ($this->classMapAuthoritative) {
   259 
   260 $scanPsrPackages = true;
   261 }
   262 
   263 
   264 if (null === $this->devMode) {
   265 
   266 $this->devMode = false;
   267 
   268 $installedJson = new JsonFile($config->get('vendor-dir').'/composer/installed.json');
   269 if ($installedJson->exists()) {
   270 $installedJson = $installedJson->read();
   271 if (isset($installedJson['dev'])) {
   272 $this->devMode = $installedJson['dev'];
   273 }
   274 }
   275 }
   276 
   277 if ($this->runScripts) {
   278 
   279 if (!isset($_SERVER['COMPOSER_DEV_MODE'])) {
   280 Platform::putEnv('COMPOSER_DEV_MODE', $this->devMode ? '1' : '0');
   281 }
   282 
   283 $this->eventDispatcher->dispatchScript(ScriptEvents::PRE_AUTOLOAD_DUMP, $this->devMode, array(), array(
   284 'optimize' => (bool) $scanPsrPackages,
   285 ));
   286 }
   287 
   288 $filesystem = new Filesystem();
   289 $filesystem->ensureDirectoryExists($config->get('vendor-dir'));
   290 
   291 
   292 
   293 $basePath = $filesystem->normalizePath(realpath(realpath(getcwd())));
   294 $vendorPath = $filesystem->normalizePath(realpath(realpath($config->get('vendor-dir'))));
   295 $useGlobalIncludePath = (bool) $config->get('use-include-path');
   296 $prependAutoloader = $config->get('prepend-autoloader') === false ? 'false' : 'true';
   297 $targetDir = $vendorPath.'/'.$targetDir;
   298 $filesystem->ensureDirectoryExists($targetDir);
   299 
   300 $vendorPathCode = $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true);
   301 $vendorPathCode52 = str_replace('__DIR__', 'dirname(__FILE__)', $vendorPathCode);
   302 $vendorPathToTargetDirCode = $filesystem->findShortestPathCode($vendorPath, realpath($targetDir), true);
   303 
   304 $appBaseDirCode = $filesystem->findShortestPathCode($vendorPath, $basePath, true);
   305 $appBaseDirCode = str_replace('__DIR__', '$vendorDir', $appBaseDirCode);
   306 
   307 $namespacesFile = <<<EOF
   308 <?php
   309 
   310 // autoload_namespaces.php @generated by Composer
   311 
   312 \$vendorDir = $vendorPathCode52;
   313 \$baseDir = $appBaseDirCode;
   314 
   315 return array(
   316 
   317 EOF;
   318 
   319 $psr4File = <<<EOF
   320 <?php
   321 
   322 // autoload_psr4.php @generated by Composer
   323 
   324 \$vendorDir = $vendorPathCode52;
   325 \$baseDir = $appBaseDirCode;
   326 
   327 return array(
   328 
   329 EOF;
   330 
   331 
   332 $devPackageNames = $localRepo->getDevPackageNames();
   333 $packageMap = $this->buildPackageMap($installationManager, $rootPackage, $localRepo->getCanonicalPackages());
   334 if ($this->devMode) {
   335 
   336 $filteredDevPackages = false;
   337 } else {
   338 
   339 $filteredDevPackages = $devPackageNames ?: true;
   340 }
   341 $autoloads = $this->parseAutoloads($packageMap, $rootPackage, $filteredDevPackages);
   342 
   343 
   344 foreach ($autoloads['psr-0'] as $namespace => $paths) {
   345 $exportedPaths = array();
   346 foreach ($paths as $path) {
   347 $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
   348 }
   349 $exportedPrefix = var_export($namespace, true);
   350 $namespacesFile .= "    $exportedPrefix => ";
   351 $namespacesFile .= "array(".implode(', ', $exportedPaths)."),\n";
   352 }
   353 $namespacesFile .= ");\n";
   354 
   355 
   356 foreach ($autoloads['psr-4'] as $namespace => $paths) {
   357 $exportedPaths = array();
   358 foreach ($paths as $path) {
   359 $exportedPaths[] = $this->getPathCode($filesystem, $basePath, $vendorPath, $path);
   360 }
   361 $exportedPrefix = var_export($namespace, true);
   362 $psr4File .= "    $exportedPrefix => ";
   363 $psr4File .= "array(".implode(', ', $exportedPaths)."),\n";
   364 }
   365 $psr4File .= ");\n";
   366 
   367 $classmapFile = <<<EOF
   368 <?php
   369 
   370 // autoload_classmap.php @generated by Composer
   371 
   372 \$vendorDir = $vendorPathCode52;
   373 \$baseDir = $appBaseDirCode;
   374 
   375 return array(
   376 
   377 EOF;
   378 
   379 
   380 $targetDirLoader = null;
   381 $mainAutoload = $rootPackage->getAutoload();
   382 if ($rootPackage->getTargetDir() && !empty($mainAutoload['psr-0'])) {
   383 $levels = substr_count($filesystem->normalizePath($rootPackage->getTargetDir()), '/') + 1;
   384 $prefixes = implode(', ', array_map(function ($prefix) {
   385 return var_export($prefix, true);
   386 }, array_keys($mainAutoload['psr-0'])));
   387 $baseDirFromTargetDirCode = $filesystem->findShortestPathCode($targetDir, $basePath, true);
   388 
   389 $targetDirLoader = <<<EOF
   390 
   391     public static function autoload(\$class)
   392     {
   393         \$dir = $baseDirFromTargetDirCode . '/';
   394         \$prefixes = array($prefixes);
   395         foreach (\$prefixes as \$prefix) {
   396             if (0 !== strpos(\$class, \$prefix)) {
   397                 continue;
   398             }
   399             \$path = \$dir . implode('/', array_slice(explode('\\\\', \$class), $levels)).'.php';
   400             if (!\$path = stream_resolve_include_path(\$path)) {
   401                 return false;
   402             }
   403             require \$path;
   404 
   405             return true;
   406         }
   407     }
   408 
   409 EOF;
   410 }
   411 
   412 $excluded = null;
   413 if (!empty($autoloads['exclude-from-classmap'])) {
   414 $excluded = $autoloads['exclude-from-classmap'];
   415 }
   416 
   417 $classMap = array();
   418 $ambiguousClasses = array();
   419 $scannedFiles = array();
   420 foreach ($autoloads['classmap'] as $dir) {
   421 $classMap = $this->addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $excluded, null, null, $classMap, $ambiguousClasses, $scannedFiles);
   422 }
   423 
   424 if ($scanPsrPackages) {
   425 $namespacesToScan = array();
   426 
   427 
   428 foreach (array('psr-4', 'psr-0') as $psrType) {
   429 foreach ($autoloads[$psrType] as $namespace => $paths) {
   430 $namespacesToScan[$namespace][] = array('paths' => $paths, 'type' => $psrType);
   431 }
   432 }
   433 
   434 krsort($namespacesToScan);
   435 
   436 foreach ($namespacesToScan as $namespace => $groups) {
   437 foreach ($groups as $group) {
   438 foreach ($group['paths'] as $dir) {
   439 $dir = $filesystem->normalizePath($filesystem->isAbsolutePath($dir) ? $dir : $basePath.'/'.$dir);
   440 if (!is_dir($dir)) {
   441 continue;
   442 }
   443 
   444 $classMap = $this->addClassMapCode($filesystem, $basePath, $vendorPath, $dir, $excluded, $namespace, $group['type'], $classMap, $ambiguousClasses, $scannedFiles);
   445 }
   446 }
   447 }
   448 }
   449 
   450 foreach ($ambiguousClasses as $className => $ambiguousPaths) {
   451 $cleanPath = str_replace(array('$vendorDir . \'', '$baseDir . \'', "',\n"), array($vendorPath, $basePath, ''), $classMap[$className]);
   452 
   453 $this->io->writeError(
   454 '<warning>Warning: Ambiguous class resolution, "'.$className.'"'.
   455 ' was found '. (count($ambiguousPaths) + 1) .'x: in "'.$cleanPath.'" and "'. implode('", "', $ambiguousPaths) .'", the first will be used.</warning>'
   456 );
   457 }
   458 
   459 $classMap['Composer\\InstalledVersions'] = "\$vendorDir . '/composer/InstalledVersions.php',\n";
   460 ksort($classMap);
   461 foreach ($classMap as $class => $code) {
   462 $classmapFile .= '    '.var_export($class, true).' => '.$code;
   463 }
   464 $classmapFile .= ");\n";
   465 
   466 if (!$suffix) {
   467 if (!$config->get('autoloader-suffix') && Filesystem::isReadable($vendorPath.'/autoload.php')) {
   468 $content = file_get_contents($vendorPath.'/autoload.php');
   469 if (Preg::isMatch('{ComposerAutoloaderInit([^:\s]+)::}', $content, $match)) {
   470 $suffix = $match[1];
   471 }
   472 }
   473 
   474 if (!$suffix) {
   475 $suffix = $config->get('autoloader-suffix') ?: md5(uniqid('', true));
   476 }
   477 }
   478 
   479 $filesystem->filePutContentsIfModified($targetDir.'/autoload_namespaces.php', $namespacesFile);
   480 $filesystem->filePutContentsIfModified($targetDir.'/autoload_psr4.php', $psr4File);
   481 $filesystem->filePutContentsIfModified($targetDir.'/autoload_classmap.php', $classmapFile);
   482 $includePathFilePath = $targetDir.'/include_paths.php';
   483 if ($includePathFileContents = $this->getIncludePathsFile($packageMap, $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
   484 $filesystem->filePutContentsIfModified($includePathFilePath, $includePathFileContents);
   485 } elseif (file_exists($includePathFilePath)) {
   486 unlink($includePathFilePath);
   487 }
   488 $includeFilesFilePath = $targetDir.'/autoload_files.php';
   489 if ($includeFilesFileContents = $this->getIncludeFilesFile($autoloads['files'], $filesystem, $basePath, $vendorPath, $vendorPathCode52, $appBaseDirCode)) {
   490 $filesystem->filePutContentsIfModified($includeFilesFilePath, $includeFilesFileContents);
   491 } elseif (file_exists($includeFilesFilePath)) {
   492 unlink($includeFilesFilePath);
   493 }
   494 $filesystem->filePutContentsIfModified($targetDir.'/autoload_static.php', $this->getStaticFile($suffix, $targetDir, $vendorPath, $basePath, $staticPhpVersion));
   495 $checkPlatform = $config->get('platform-check') && !($this->platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter);
   496 $platformCheckContent = null;
   497 if ($checkPlatform) {
   498 $platformCheckContent = $this->getPlatformCheck($packageMap, $config->get('platform-check'), $devPackageNames);
   499 if (null === $platformCheckContent) {
   500 $checkPlatform = false;
   501 }
   502 }
   503 if ($checkPlatform) {
   504 $filesystem->filePutContentsIfModified($targetDir.'/platform_check.php', $platformCheckContent);
   505 } elseif (file_exists($targetDir.'/platform_check.php')) {
   506 unlink($targetDir.'/platform_check.php');
   507 }
   508 $filesystem->filePutContentsIfModified($vendorPath.'/autoload.php', $this->getAutoloadFile($vendorPathToTargetDirCode, $suffix));
   509 $filesystem->filePutContentsIfModified($targetDir.'/autoload_real.php', $this->getAutoloadRealFile(true, (bool) $includePathFileContents, $targetDirLoader, (bool) $includeFilesFileContents, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion, $checkPlatform));
   510 
   511 $filesystem->safeCopy(__DIR__.'/ClassLoader.php', $targetDir.'/ClassLoader.php');
   512 $filesystem->safeCopy(__DIR__.'/../../../LICENSE', $targetDir.'/LICENSE');
   513 
   514 if ($this->runScripts) {
   515 $this->eventDispatcher->dispatchScript(ScriptEvents::POST_AUTOLOAD_DUMP, $this->devMode, array(), array(
   516 'optimize' => (bool) $scanPsrPackages,
   517 ));
   518 }
   519 
   520 return count($classMap);
   521 }
   522 
   523 
   524 
   525 
   526 
   527 
   528 
   529 
   530 
   531 
   532 
   533 
   534 
   535 private function addClassMapCode(Filesystem $filesystem, $basePath, $vendorPath, $dir, $excluded, $namespaceFilter, $autoloadType, array $classMap, array &$ambiguousClasses, array &$scannedFiles)
   536 {
   537 foreach ($this->generateClassMap($dir, $excluded, $namespaceFilter, $autoloadType, true, $scannedFiles) as $class => $path) {
   538 $pathCode = $this->getPathCode($filesystem, $basePath, $vendorPath, $path).",\n";
   539 if (!isset($classMap[$class])) {
   540 $classMap[$class] = $pathCode;
   541 } elseif ($this->io && $classMap[$class] !== $pathCode && !Preg::isMatch('{/(test|fixture|example|stub)s?/}i', strtr($classMap[$class].' '.$path, '\\', '/'))) {
   542 $ambiguousClasses[$class][] = $path;
   543 }
   544 }
   545 
   546 return $classMap;
   547 }
   548 
   549 
   550 
   551 
   552 
   553 
   554 
   555 
   556 
   557 
   558 private function generateClassMap($dir, $excluded, $namespaceFilter, $autoloadType, $showAmbiguousWarning, array &$scannedFiles)
   559 {
   560 if ($excluded) {
   561 
   562 
   563 
   564 if (file_exists($dir)) {
   565 
   566 $dirMatch = preg_quote(strtr(realpath($dir), '\\', '/'));
   567 foreach ($excluded as $index => $pattern) {
   568 
   569 $pattern = Preg::replace('{^(([^.+*?\[^\]$(){}=!<>|:\\\\#-]+|\\\\[.+*?\[^\]$(){}=!<>|:#-])*).*}', '$1', $pattern);
   570 
   571 if (0 !== strpos($pattern, $dirMatch) && 0 !== strpos($dirMatch, $pattern)) {
   572 unset($excluded[$index]);
   573 }
   574 }
   575 }
   576 
   577 $excluded = $excluded ? '{(' . implode('|', $excluded) . ')}' : null;
   578 }
   579 
   580 return ClassMapGenerator::createMap($dir, $excluded, $showAmbiguousWarning ? $this->io : null, $namespaceFilter, $autoloadType, $scannedFiles);
   581 }
   582 
   583 
   584 
   585 
   586 
   587 
   588 public function buildPackageMap(InstallationManager $installationManager, PackageInterface $rootPackage, array $packages)
   589 {
   590 
   591 $packageMap = array(array($rootPackage, ''));
   592 
   593 foreach ($packages as $package) {
   594 if ($package instanceof AliasPackage) {
   595 continue;
   596 }
   597 $this->validatePackage($package);
   598 
   599 $packageMap[] = array(
   600 $package,
   601 $installationManager->getInstallPath($package),
   602 );
   603 }
   604 
   605 return $packageMap;
   606 }
   607 
   608 
   609 
   610 
   611 
   612 protected function validatePackage(PackageInterface $package)
   613 {
   614 $autoload = $package->getAutoload();
   615 if (!empty($autoload['psr-4']) && null !== $package->getTargetDir()) {
   616 $name = $package->getName();
   617 $package->getTargetDir();
   618 throw new \InvalidArgumentException("PSR-4 autoloading is incompatible with the target-dir property, remove the target-dir in package '$name'.");
   619 }
   620 if (!empty($autoload['psr-4'])) {
   621 foreach ($autoload['psr-4'] as $namespace => $dirs) {
   622 if ($namespace !== '' && '\\' !== substr($namespace, -1)) {
   623 throw new \InvalidArgumentException("psr-4 namespaces must end with a namespace separator, '$namespace' does not, use '$namespace\\'.");
   624 }
   625 }
   626 }
   627 }
   628 
   629 
   630 
   631 
   632 
   633 
   634 
   635 
   636 
   637 
   638 
   639 
   640 
   641 
   642 
   643 
   644 public function parseAutoloads(array $packageMap, PackageInterface $rootPackage, $filteredDevPackages = false)
   645 {
   646 $rootPackageMap = array_shift($packageMap);
   647 if (is_array($filteredDevPackages)) {
   648 $packageMap = array_filter($packageMap, function ($item) use ($filteredDevPackages) {
   649 return !in_array($item[0]->getName(), $filteredDevPackages, true);
   650 });
   651 } elseif ($filteredDevPackages) {
   652 $packageMap = $this->filterPackageMap($packageMap, $rootPackage);
   653 }
   654 $sortedPackageMap = $this->sortPackageMap($packageMap);
   655 $sortedPackageMap[] = $rootPackageMap;
   656 array_unshift($packageMap, $rootPackageMap);
   657 
   658 $psr0 = $this->parseAutoloadsType($packageMap, 'psr-0', $rootPackage);
   659 $psr4 = $this->parseAutoloadsType($packageMap, 'psr-4', $rootPackage);
   660 $classmap = $this->parseAutoloadsType(array_reverse($sortedPackageMap), 'classmap', $rootPackage);
   661 $files = $this->parseAutoloadsType($sortedPackageMap, 'files', $rootPackage);
   662 $exclude = $this->parseAutoloadsType($sortedPackageMap, 'exclude-from-classmap', $rootPackage);
   663 
   664 krsort($psr0);
   665 krsort($psr4);
   666 
   667 return array(
   668 'psr-0' => $psr0,
   669 'psr-4' => $psr4,
   670 'classmap' => $classmap,
   671 'files' => $files,
   672 'exclude-from-classmap' => $exclude,
   673 );
   674 }
   675 
   676 
   677 
   678 
   679 
   680 
   681 
   682 
   683 public function createLoader(array $autoloads, $vendorDir = null)
   684 {
   685 $loader = new ClassLoader($vendorDir);
   686 
   687 if (isset($autoloads['psr-0'])) {
   688 foreach ($autoloads['psr-0'] as $namespace => $path) {
   689 $loader->add($namespace, $path);
   690 }
   691 }
   692 
   693 if (isset($autoloads['psr-4'])) {
   694 foreach ($autoloads['psr-4'] as $namespace => $path) {
   695 $loader->addPsr4($namespace, $path);
   696 }
   697 }
   698 
   699 if (isset($autoloads['classmap'])) {
   700 $excluded = null;
   701 if (!empty($autoloads['exclude-from-classmap'])) {
   702 $excluded = $autoloads['exclude-from-classmap'];
   703 }
   704 
   705 $scannedFiles = array();
   706 foreach ($autoloads['classmap'] as $dir) {
   707 try {
   708 $loader->addClassMap($this->generateClassMap($dir, $excluded, null, null, false, $scannedFiles));
   709 } catch (\RuntimeException $e) {
   710 $this->io->writeError('<warning>'.$e->getMessage().'</warning>');
   711 }
   712 }
   713 }
   714 
   715 return $loader;
   716 }
   717 
   718 
   719 
   720 
   721 
   722 
   723 
   724 
   725 
   726 protected function getIncludePathsFile(array $packageMap, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode)
   727 {
   728 $includePaths = array();
   729 
   730 foreach ($packageMap as $item) {
   731 list($package, $installPath) = $item;
   732 
   733 if (null !== $package->getTargetDir() && strlen($package->getTargetDir()) > 0) {
   734 $installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
   735 }
   736 
   737 foreach ($package->getIncludePaths() as $includePath) {
   738 $includePath = trim($includePath, '/');
   739 $includePaths[] = empty($installPath) ? $includePath : $installPath.'/'.$includePath;
   740 }
   741 }
   742 
   743 if (!$includePaths) {
   744 return null;
   745 }
   746 
   747 $includePathsCode = '';
   748 foreach ($includePaths as $path) {
   749 $includePathsCode .= "    " . $this->getPathCode($filesystem, $basePath, $vendorPath, $path) . ",\n";
   750 }
   751 
   752 return <<<EOF
   753 <?php
   754 
   755 // include_paths.php @generated by Composer
   756 
   757 \$vendorDir = $vendorPathCode;
   758 \$baseDir = $appBaseDirCode;
   759 
   760 return array(
   761 $includePathsCode);
   762 
   763 EOF;
   764 }
   765 
   766 
   767 
   768 
   769 
   770 
   771 
   772 
   773 
   774 protected function getIncludeFilesFile(array $files, Filesystem $filesystem, $basePath, $vendorPath, $vendorPathCode, $appBaseDirCode)
   775 {
   776 $filesCode = '';
   777 foreach ($files as $fileIdentifier => $functionFile) {
   778 $filesCode .= '    ' . var_export($fileIdentifier, true) . ' => '
   779 . $this->getPathCode($filesystem, $basePath, $vendorPath, $functionFile) . ",\n";
   780 }
   781 
   782 if (!$filesCode) {
   783 return null;
   784 }
   785 
   786 return <<<EOF
   787 <?php
   788 
   789 // autoload_files.php @generated by Composer
   790 
   791 \$vendorDir = $vendorPathCode;
   792 \$baseDir = $appBaseDirCode;
   793 
   794 return array(
   795 $filesCode);
   796 
   797 EOF;
   798 }
   799 
   800 
   801 
   802 
   803 
   804 
   805 
   806 protected function getPathCode(Filesystem $filesystem, $basePath, $vendorPath, $path)
   807 {
   808 if (!$filesystem->isAbsolutePath($path)) {
   809 $path = $basePath . '/' . $path;
   810 }
   811 $path = $filesystem->normalizePath($path);
   812 
   813 $baseDir = '';
   814 if (strpos($path.'/', $vendorPath.'/') === 0) {
   815 $path = substr($path, strlen($vendorPath));
   816 $baseDir = '$vendorDir';
   817 
   818 if ($path !== false) {
   819 $baseDir .= " . ";
   820 }
   821 } else {
   822 $path = $filesystem->normalizePath($filesystem->findShortestPath($basePath, $path, true));
   823 if (!$filesystem->isAbsolutePath($path)) {
   824 $baseDir = '$baseDir . ';
   825 $path = '/' . $path;
   826 }
   827 }
   828 
   829 if (strpos($path, '.phar') !== false) {
   830 $baseDir = "'phar://' . " . $baseDir;
   831 }
   832 
   833 return $baseDir . var_export($path, true);
   834 }
   835 
   836 
   837 
   838 
   839 
   840 
   841 
   842 protected function getPlatformCheck(array $packageMap, $checkPlatform, array $devPackageNames)
   843 {
   844 $lowestPhpVersion = Bound::zero();
   845 $requiredExtensions = array();
   846 $extensionProviders = array();
   847 
   848 foreach ($packageMap as $item) {
   849 $package = $item[0];
   850 foreach (array_merge($package->getReplaces(), $package->getProvides()) as $link) {
   851 if (Preg::isMatch('{^ext-(.+)$}iD', $link->getTarget(), $match)) {
   852 $extensionProviders[$match[1]][] = $link->getConstraint();
   853 }
   854 }
   855 }
   856 
   857 foreach ($packageMap as $item) {
   858 $package = $item[0];
   859 
   860 if (in_array($package->getName(), $devPackageNames, true)) {
   861 continue;
   862 }
   863 
   864 foreach ($package->getRequires() as $link) {
   865 if ($this->platformRequirementFilter->isIgnored($link->getTarget())) {
   866 continue;
   867 }
   868 
   869 if ('php' === $link->getTarget()) {
   870 $constraint = $link->getConstraint();
   871 if ($constraint->getLowerBound()->compareTo($lowestPhpVersion, '>')) {
   872 $lowestPhpVersion = $constraint->getLowerBound();
   873 }
   874 }
   875 
   876 if ($checkPlatform === true && Preg::isMatch('{^ext-(.+)$}iD', $link->getTarget(), $match)) {
   877 
   878 if (isset($extensionProviders[$match[1]])) {
   879 foreach ($extensionProviders[$match[1]] as $provided) {
   880 if ($provided->matches($link->getConstraint())) {
   881 continue 2;
   882 }
   883 }
   884 }
   885 
   886 if ($match[1] === 'zend-opcache') {
   887 $match[1] = 'zend opcache';
   888 }
   889 
   890 $extension = var_export($match[1], true);
   891 if ($match[1] === 'pcntl' || $match[1] === 'readline') {
   892 $requiredExtensions[$extension] = "PHP_SAPI !== 'cli' || extension_loaded($extension) || \$missingExtensions[] = $extension;\n";
   893 } else {
   894 $requiredExtensions[$extension] = "extension_loaded($extension) || \$missingExtensions[] = $extension;\n";
   895 }
   896 }
   897 }
   898 }
   899 
   900 ksort($requiredExtensions);
   901 
   902 $formatToPhpVersionId = function (Bound $bound) {
   903 if ($bound->isZero()) {
   904 return 0;
   905 }
   906 
   907 if ($bound->isPositiveInfinity()) {
   908 return 99999;
   909 }
   910 
   911 $version = str_replace('-', '.', $bound->getVersion());
   912 $chunks = array_map('intval', explode('.', $version));
   913 
   914 return $chunks[0] * 10000 + $chunks[1] * 100 + $chunks[2];
   915 };
   916 
   917 $formatToHumanReadable = function (Bound $bound) {
   918 if ($bound->isZero()) {
   919 return 0;
   920 }
   921 
   922 if ($bound->isPositiveInfinity()) {
   923 return 99999;
   924 }
   925 
   926 $version = str_replace('-', '.', $bound->getVersion());
   927 $chunks = explode('.', $version);
   928 $chunks = array_slice($chunks, 0, 3);
   929 
   930 return implode('.', $chunks);
   931 };
   932 
   933 $requiredPhp = '';
   934 $requiredPhpError = '';
   935 if (!$lowestPhpVersion->isZero()) {
   936 $operator = $lowestPhpVersion->isInclusive() ? '>=' : '>';
   937 $requiredPhp = 'PHP_VERSION_ID '.$operator.' '.$formatToPhpVersionId($lowestPhpVersion);
   938 $requiredPhpError = '"'.$operator.' '.$formatToHumanReadable($lowestPhpVersion).'"';
   939 }
   940 
   941 if ($requiredPhp) {
   942 $requiredPhp = <<<PHP_CHECK
   943 
   944 if (!($requiredPhp)) {
   945     \$issues[] = 'Your Composer dependencies require a PHP version $requiredPhpError. You are running ' . PHP_VERSION . '.';
   946 }
   947 
   948 PHP_CHECK;
   949 }
   950 
   951 $requiredExtensions = implode('', $requiredExtensions);
   952 if ('' !== $requiredExtensions) {
   953 $requiredExtensions = <<<EXT_CHECKS
   954 
   955 \$missingExtensions = array();
   956 $requiredExtensions
   957 if (\$missingExtensions) {
   958     \$issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', \$missingExtensions) . '.';
   959 }
   960 
   961 EXT_CHECKS;
   962 }
   963 
   964 if (!$requiredPhp && !$requiredExtensions) {
   965 return null;
   966 }
   967 
   968 return <<<PLATFORM_CHECK
   969 <?php
   970 
   971 // platform_check.php @generated by Composer
   972 
   973 \$issues = array();
   974 ${requiredPhp}${requiredExtensions}
   975 if (\$issues) {
   976     if (!headers_sent()) {
   977         header('HTTP/1.1 500 Internal Server Error');
   978     }
   979     if (!ini_get('display_errors')) {
   980         if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
   981             fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, \$issues) . PHP_EOL.PHP_EOL);
   982         } elseif (!headers_sent()) {
   983             echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, \$issues)) . PHP_EOL.PHP_EOL;
   984         }
   985     }
   986     trigger_error(
   987         'Composer detected issues in your platform: ' . implode(' ', \$issues),
   988         E_USER_ERROR
   989     );
   990 }
   991 
   992 PLATFORM_CHECK;
   993 }
   994 
   995 
   996 
   997 
   998 
   999 
  1000 protected function getAutoloadFile($vendorPathToTargetDirCode, $suffix)
  1001 {
  1002 $lastChar = $vendorPathToTargetDirCode[strlen($vendorPathToTargetDirCode) - 1];
  1003 if ("'" === $lastChar || '"' === $lastChar) {
  1004 $vendorPathToTargetDirCode = substr($vendorPathToTargetDirCode, 0, -1).'/autoload_real.php'.$lastChar;
  1005 } else {
  1006 $vendorPathToTargetDirCode .= " . '/autoload_real.php'";
  1007 }
  1008 
  1009 return <<<AUTOLOAD
  1010 <?php
  1011 
  1012 // autoload.php @generated by Composer
  1013 
  1014 require_once $vendorPathToTargetDirCode;
  1015 
  1016 return ComposerAutoloaderInit$suffix::getLoader();
  1017 
  1018 AUTOLOAD;
  1019 }
  1020 
  1021 
  1022 
  1023 
  1024 
  1025 
  1026 
  1027 
  1028 
  1029 
  1030 
  1031 
  1032 
  1033 
  1034 
  1035 protected function getAutoloadRealFile($useClassMap, $useIncludePath, $targetDirLoader, $useIncludeFiles, $vendorPathCode, $appBaseDirCode, $suffix, $useGlobalIncludePath, $prependAutoloader, $staticPhpVersion, $checkPlatform)
  1036 {
  1037 $file = <<<HEADER
  1038 <?php
  1039 
  1040 // autoload_real.php @generated by Composer
  1041 
  1042 class ComposerAutoloaderInit$suffix
  1043 {
  1044     private static \$loader;
  1045 
  1046     public static function loadClassLoader(\$class)
  1047     {
  1048         if ('Composer\\Autoload\\ClassLoader' === \$class) {
  1049             require __DIR__ . '/ClassLoader.php';
  1050         }
  1051     }
  1052 
  1053     /**
  1054      * @return \Composer\Autoload\ClassLoader
  1055      */
  1056     public static function getLoader()
  1057     {
  1058         if (null !== self::\$loader) {
  1059             return self::\$loader;
  1060         }
  1061 
  1062 
  1063 HEADER;
  1064 
  1065 if ($checkPlatform) {
  1066 $file .= <<<'PLATFORM_CHECK'
  1067         require __DIR__ . '/platform_check.php';
  1068 
  1069 
  1070 PLATFORM_CHECK;
  1071 }
  1072 
  1073 $file .= <<<CLASSLOADER_INIT
  1074         spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'), true, $prependAutoloader);
  1075         self::\$loader = \$loader = new \\Composer\\Autoload\\ClassLoader(\\dirname(\\dirname(__FILE__)));
  1076         spl_autoload_unregister(array('ComposerAutoloaderInit$suffix', 'loadClassLoader'));
  1077 
  1078 
  1079 CLASSLOADER_INIT;
  1080 
  1081 if ($useIncludePath) {
  1082 $file .= <<<'INCLUDE_PATH'
  1083         $includePaths = require __DIR__ . '/include_paths.php';
  1084         $includePaths[] = get_include_path();
  1085         set_include_path(implode(PATH_SEPARATOR, $includePaths));
  1086 
  1087 
  1088 INCLUDE_PATH;
  1089 }
  1090 
  1091 $file .= <<<STATIC_INIT
  1092         \$useStaticLoader = PHP_VERSION_ID >= $staticPhpVersion && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
  1093         if (\$useStaticLoader) {
  1094             require __DIR__ . '/autoload_static.php';
  1095 
  1096             call_user_func(\Composer\Autoload\ComposerStaticInit$suffix::getInitializer(\$loader));
  1097         } else {
  1098 
  1099 STATIC_INIT;
  1100 
  1101 if (!$this->classMapAuthoritative) {
  1102 $file .= <<<'PSR04'
  1103             $map = require __DIR__ . '/autoload_namespaces.php';
  1104             foreach ($map as $namespace => $path) {
  1105                 $loader->set($namespace, $path);
  1106             }
  1107 
  1108             $map = require __DIR__ . '/autoload_psr4.php';
  1109             foreach ($map as $namespace => $path) {
  1110                 $loader->setPsr4($namespace, $path);
  1111             }
  1112 
  1113 
  1114 PSR04;
  1115 }
  1116 
  1117 if ($useClassMap) {
  1118 $file .= <<<'CLASSMAP'
  1119             $classMap = require __DIR__ . '/autoload_classmap.php';
  1120             if ($classMap) {
  1121                 $loader->addClassMap($classMap);
  1122             }
  1123 
  1124 CLASSMAP;
  1125 }
  1126 
  1127 $file .= "        }\n\n";
  1128 
  1129 if ($this->classMapAuthoritative) {
  1130 $file .= <<<'CLASSMAPAUTHORITATIVE'
  1131         $loader->setClassMapAuthoritative(true);
  1132 
  1133 CLASSMAPAUTHORITATIVE;
  1134 }
  1135 
  1136 if ($this->apcu) {
  1137 $apcuPrefix = var_export(($this->apcuPrefix !== null ? $this->apcuPrefix : substr(base64_encode(md5(uniqid('', true), true)), 0, -3)), true);
  1138 $file .= <<<APCU
  1139         \$loader->setApcuPrefix($apcuPrefix);
  1140 
  1141 APCU;
  1142 }
  1143 
  1144 if ($useGlobalIncludePath) {
  1145 $file .= <<<'INCLUDEPATH'
  1146         $loader->setUseIncludePath(true);
  1147 
  1148 INCLUDEPATH;
  1149 }
  1150 
  1151 if ($targetDirLoader) {
  1152 $file .= <<<REGISTER_TARGET_DIR_AUTOLOAD
  1153         spl_autoload_register(array('ComposerAutoloaderInit$suffix', 'autoload'), true, true);
  1154 
  1155 
  1156 REGISTER_TARGET_DIR_AUTOLOAD;
  1157 }
  1158 
  1159 $file .= <<<REGISTER_LOADER
  1160         \$loader->register($prependAutoloader);
  1161 
  1162 
  1163 REGISTER_LOADER;
  1164 
  1165 if ($useIncludeFiles) {
  1166 $file .= <<<INCLUDE_FILES
  1167         if (\$useStaticLoader) {
  1168             \$includeFiles = Composer\Autoload\ComposerStaticInit$suffix::\$files;
  1169         } else {
  1170             \$includeFiles = require __DIR__ . '/autoload_files.php';
  1171         }
  1172         foreach (\$includeFiles as \$fileIdentifier => \$file) {
  1173             composerRequire$suffix(\$fileIdentifier, \$file);
  1174         }
  1175 
  1176 
  1177 INCLUDE_FILES;
  1178 }
  1179 
  1180 $file .= <<<METHOD_FOOTER
  1181         return \$loader;
  1182     }
  1183 
  1184 METHOD_FOOTER;
  1185 
  1186 $file .= $targetDirLoader;
  1187 
  1188 if ($useIncludeFiles) {
  1189 return $file . <<<FOOTER
  1190 }
  1191 
  1192 /**
  1193  * @param string \$fileIdentifier
  1194  * @param string \$file
  1195  * @return void
  1196  */
  1197 function composerRequire$suffix(\$fileIdentifier, \$file)
  1198 {
  1199     if (empty(\$GLOBALS['__composer_autoload_files'][\$fileIdentifier])) {
  1200         \$GLOBALS['__composer_autoload_files'][\$fileIdentifier] = true;
  1201 
  1202         require \$file;
  1203     }
  1204 }
  1205 
  1206 FOOTER;
  1207 }
  1208 
  1209 return $file . <<<FOOTER
  1210 }
  1211 
  1212 FOOTER;
  1213 }
  1214 
  1215 
  1216 
  1217 
  1218 
  1219 
  1220 
  1221 
  1222 
  1223 protected function getStaticFile($suffix, $targetDir, $vendorPath, $basePath, &$staticPhpVersion)
  1224 {
  1225 $staticPhpVersion = 50600;
  1226 
  1227 $file = <<<HEADER
  1228 <?php
  1229 
  1230 // autoload_static.php @generated by Composer
  1231 
  1232 namespace Composer\Autoload;
  1233 
  1234 class ComposerStaticInit$suffix
  1235 {
  1236 
  1237 HEADER;
  1238 
  1239 $loader = new ClassLoader();
  1240 
  1241 $map = require $targetDir . '/autoload_namespaces.php';
  1242 foreach ($map as $namespace => $path) {
  1243 $loader->set($namespace, $path);
  1244 }
  1245 
  1246 $map = require $targetDir . '/autoload_psr4.php';
  1247 foreach ($map as $namespace => $path) {
  1248 $loader->setPsr4($namespace, $path);
  1249 }
  1250 
  1251 $classMap = require $targetDir . '/autoload_classmap.php';
  1252 if ($classMap) {
  1253 $loader->addClassMap($classMap);
  1254 }
  1255 
  1256 $filesystem = new Filesystem();
  1257 
  1258 $vendorPathCode = ' => ' . $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true, true) . " . '/";
  1259 $vendorPharPathCode = ' => \'phar://\' . ' . $filesystem->findShortestPathCode(realpath($targetDir), $vendorPath, true, true) . " . '/";
  1260 $appBaseDirCode = ' => ' . $filesystem->findShortestPathCode(realpath($targetDir), $basePath, true, true) . " . '/";
  1261 $appBaseDirPharCode = ' => \'phar://\' . ' . $filesystem->findShortestPathCode(realpath($targetDir), $basePath, true, true) . " . '/";
  1262 
  1263 $absoluteVendorPathCode = ' => ' . substr(var_export(rtrim($vendorDir, '\\/') . '/', true), 0, -1);
  1264 $absoluteVendorPharPathCode = ' => ' . substr(var_export(rtrim('phar://' . $vendorDir, '\\/') . '/', true), 0, -1);
  1265 $absoluteAppBaseDirCode = ' => ' . substr(var_export(rtrim($baseDir, '\\/') . '/', true), 0, -1);
  1266 $absoluteAppBaseDirPharCode = ' => ' . substr(var_export(rtrim('phar://' . $baseDir, '\\/') . '/', true), 0, -1);
  1267 
  1268 $initializer = '';
  1269 $prefix = "\0Composer\Autoload\ClassLoader\0";
  1270 $prefixLen = strlen($prefix);
  1271 if (file_exists($targetDir . '/autoload_files.php')) {
  1272 $maps = array('files' => require $targetDir . '/autoload_files.php');
  1273 } else {
  1274 $maps = array();
  1275 }
  1276 
  1277 foreach ((array) $loader as $prop => $value) {
  1278 if ($value && 0 === strpos($prop, $prefix)) {
  1279 $maps[substr($prop, $prefixLen)] = $value;
  1280 }
  1281 }
  1282 
  1283 foreach ($maps as $prop => $value) {
  1284 if (count($value) > 32767) {
  1285 
  1286 
  1287 $staticPhpVersion = 70000;
  1288 }
  1289 $value = strtr(
  1290 var_export($value, true),
  1291 array(
  1292 $absoluteVendorPathCode => $vendorPathCode,
  1293 $absoluteVendorPharPathCode => $vendorPharPathCode,
  1294 $absoluteAppBaseDirCode => $appBaseDirCode,
  1295 $absoluteAppBaseDirPharCode => $appBaseDirPharCode,
  1296 )
  1297 );
  1298 $value = ltrim(Preg::replace('/^ */m', '    $0$0', $value));
  1299 
  1300 $file .= sprintf("    public static $%s = %s;\n\n", $prop, $value);
  1301 if ('files' !== $prop) {
  1302 $initializer .= "            \$loader->$prop = ComposerStaticInit$suffix::\$$prop;\n";
  1303 }
  1304 }
  1305 
  1306 return $file . <<<INITIALIZER
  1307     public static function getInitializer(ClassLoader \$loader)
  1308     {
  1309         return \Closure::bind(function () use (\$loader) {
  1310 $initializer
  1311         }, null, ClassLoader::class);
  1312     }
  1313 }
  1314 
  1315 INITIALIZER;
  1316 }
  1317 
  1318 
  1319 
  1320 
  1321 
  1322 
  1323 protected function parseAutoloadsType(array $packageMap, $type, RootPackageInterface $rootPackage)
  1324 {
  1325 $autoloads = array();
  1326 
  1327 foreach ($packageMap as $item) {
  1328 list($package, $installPath) = $item;
  1329 
  1330 $autoload = $package->getAutoload();
  1331 if ($this->devMode && $package === $rootPackage) {
  1332 $autoload = array_merge_recursive($autoload, $package->getDevAutoload());
  1333 }
  1334 
  1335 
  1336 if (!isset($autoload[$type]) || !is_array($autoload[$type])) {
  1337 continue;
  1338 }
  1339 if (null !== $package->getTargetDir() && $package !== $rootPackage) {
  1340 $installPath = substr($installPath, 0, -strlen('/'.$package->getTargetDir()));
  1341 }
  1342 
  1343 foreach ($autoload[$type] as $namespace => $paths) {
  1344 foreach ((array) $paths as $path) {
  1345 if (($type === 'files' || $type === 'classmap' || $type === 'exclude-from-classmap') && $package->getTargetDir() && !Filesystem::isReadable($installPath.'/'.$path)) {
  1346 
  1347 if ($package === $rootPackage) {
  1348 $targetDir = str_replace('\\<dirsep\\>', '[\\\\/]', preg_quote(str_replace(array('/', '\\'), '<dirsep>', $package->getTargetDir())));
  1349 $path = ltrim(Preg::replace('{^'.$targetDir.'}', '', ltrim($path, '\\/')), '\\/');
  1350 } else {
  1351 
  1352 $path = $package->getTargetDir() . '/' . $path;
  1353 }
  1354 }
  1355 
  1356 if ($type === 'exclude-from-classmap') {
  1357 
  1358 $path = Preg::replace('{/+}', '/', preg_quote(trim(strtr($path, '\\', '/'), '/')));
  1359 
  1360 
  1361 $path = strtr($path, array('\\*\\*' => '.+?', '\\*' => '[^/]+?'));
  1362 
  1363 
  1364 $updir = null;
  1365 $path = Preg::replaceCallback(
  1366 '{^((?:(?:\\\\\\.){1,2}+/)+)}',
  1367 function ($matches) use (&$updir) {
  1368 if (isset($matches[1])) {
  1369 
  1370 $updir = str_replace('\\.', '.', $matches[1]);
  1371 }
  1372 
  1373 return '';
  1374 },
  1375 $path
  1376 );
  1377 if (empty($installPath)) {
  1378 $installPath = strtr(getcwd(), '\\', '/');
  1379 }
  1380 
  1381 $resolvedPath = realpath($installPath . '/' . $updir);
  1382 $autoloads[] = preg_quote(strtr($resolvedPath, '\\', '/')) . '/' . $path . '($|/)';
  1383 continue;
  1384 }
  1385 
  1386 $relativePath = empty($installPath) ? (empty($path) ? '.' : $path) : $installPath.'/'.$path;
  1387 
  1388 if ($type === 'files') {
  1389 $autoloads[$this->getFileIdentifier($package, $path)] = $relativePath;
  1390 continue;
  1391 }
  1392 if ($type === 'classmap') {
  1393 $autoloads[] = $relativePath;
  1394 continue;
  1395 }
  1396 
  1397 $autoloads[$namespace][] = $relativePath;
  1398 }
  1399 }
  1400 }
  1401 
  1402 return $autoloads;
  1403 }
  1404 
  1405 
  1406 
  1407 
  1408 
  1409 protected function getFileIdentifier(PackageInterface $package, $path)
  1410 {
  1411 return md5($package->getName() . ':' . $path);
  1412 }
  1413 
  1414 
  1415 
  1416 
  1417 
  1418 
  1419 
  1420 
  1421 
  1422 
  1423 protected function filterPackageMap(array $packageMap, RootPackageInterface $rootPackage)
  1424 {
  1425 $packages = array();
  1426 $include = array();
  1427 $replacedBy = array();
  1428 
  1429 foreach ($packageMap as $item) {
  1430 $package = $item[0];
  1431 $name = $package->getName();
  1432 $packages[$name] = $package;
  1433 foreach ($package->getReplaces() as $replace) {
  1434 $replacedBy[$replace->getTarget()] = $name;
  1435 }
  1436 }
  1437 
  1438 $add = function (PackageInterface $package) use (&$add, $packages, &$include, $replacedBy) {
  1439 foreach ($package->getRequires() as $link) {
  1440 $target = $link->getTarget();
  1441 if (isset($replacedBy[$target])) {
  1442 $target = $replacedBy[$target];
  1443 }
  1444 if (!isset($include[$target])) {
  1445 $include[$target] = true;
  1446 if (isset($packages[$target])) {
  1447 $add($packages[$target]);
  1448 }
  1449 }
  1450 }
  1451 };
  1452 $add($rootPackage);
  1453 
  1454 return array_filter(
  1455 $packageMap,
  1456 function ($item) use ($include) {
  1457 $package = $item[0];
  1458 foreach ($package->getNames() as $name) {
  1459 if (isset($include[$name])) {
  1460 return true;
  1461 }
  1462 }
  1463 
  1464 return false;
  1465 }
  1466 );
  1467 }
  1468 
  1469 
  1470 
  1471 
  1472 
  1473 
  1474 
  1475 
  1476 
  1477 protected function sortPackageMap(array $packageMap)
  1478 {
  1479 $packages = array();
  1480 $paths = array();
  1481 
  1482 foreach ($packageMap as $item) {
  1483 list($package, $path) = $item;
  1484 $name = $package->getName();
  1485 $packages[$name] = $package;
  1486 $paths[$name] = $path;
  1487 }
  1488 
  1489 $sortedPackages = PackageSorter::sortPackages($packages);
  1490 
  1491 $sortedPackageMap = array();
  1492 
  1493 foreach ($sortedPackages as $package) {
  1494 $name = $package->getName();
  1495 $sortedPackageMap[] = array($packages[$name], $paths[$name]);
  1496 }
  1497 
  1498 return $sortedPackageMap;
  1499 }
  1500 }
  1501 
  1502 
  1503 
  1504 
  1505 
  1506 
  1507 function composerRequire($fileIdentifier, $file)
  1508 {
  1509 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
  1510 $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
  1511 
  1512 require $file;
  1513 }
  1514 }
  1515 <?php
  1516 
  1517 
  1518 
  1519 
  1520 
  1521 
  1522 
  1523 
  1524 
  1525 
  1526 
  1527 
  1528 
  1529 
  1530 
  1531 
  1532 
  1533 namespace Composer\Autoload;
  1534 
  1535 use Composer\Pcre\Preg;
  1536 use Symfony\Component\Finder\Finder;
  1537 use Composer\IO\IOInterface;
  1538 use Composer\Util\Filesystem;
  1539 
  1540 
  1541 
  1542 
  1543 
  1544 
  1545 
  1546 class ClassMapGenerator
  1547 {
  1548 
  1549 
  1550 
  1551 
  1552 
  1553 
  1554 
  1555 public static function dump($dirs, $file)
  1556 {
  1557 $maps = array();
  1558 
  1559 foreach ($dirs as $dir) {
  1560 $maps = array_merge($maps, static::createMap($dir));
  1561 }
  1562 
  1563 file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true)));
  1564 }
  1565 
  1566 
  1567 
  1568 
  1569 
  1570 
  1571 
  1572 
  1573 
  1574 
  1575 
  1576 
  1577 
  1578 public static function createMap($path, $excluded = null, IOInterface $io = null, $namespace = null, $autoloadType = null, &$scannedFiles = array())
  1579 {
  1580 $basePath = $path;
  1581 if (is_string($path)) {
  1582 if (is_file($path)) {
  1583 $path = array(new \SplFileInfo($path));
  1584 } elseif (is_dir($path) || strpos($path, '*') !== false) {
  1585 $path = Finder::create()->files()->followLinks()->name('/\.(php|inc|hh)$/')->in($path);
  1586 } else {
  1587 throw new \RuntimeException(
  1588 'Could not scan for classes inside "'.$path.
  1589 '" which does not appear to be a file nor a folder'
  1590 );
  1591 }
  1592 } elseif (null !== $autoloadType) {
  1593 throw new \RuntimeException('Path must be a string when specifying an autoload type');
  1594 }
  1595 
  1596 $map = array();
  1597 $filesystem = new Filesystem();
  1598 $cwd = realpath(getcwd());
  1599 
  1600 foreach ($path as $file) {
  1601 $filePath = $file->getPathname();
  1602 if (!in_array(pathinfo($filePath, PATHINFO_EXTENSION), array('php', 'inc', 'hh'))) {
  1603 continue;
  1604 }
  1605 
  1606 if (!$filesystem->isAbsolutePath($filePath)) {
  1607 $filePath = $cwd . '/' . $filePath;
  1608 $filePath = $filesystem->normalizePath($filePath);
  1609 } else {
  1610 $filePath = Preg::replace('{[\\\\/]{2,}}', '/', $filePath);
  1611 }
  1612 
  1613 $realPath = realpath($filePath);
  1614 
  1615 
  1616 
  1617 if (isset($scannedFiles[$realPath])) {
  1618 continue;
  1619 }
  1620 
  1621 
  1622 if ($excluded && Preg::isMatch($excluded, strtr($realPath, '\\', '/'))) {
  1623 continue;
  1624 }
  1625 
  1626 if ($excluded && Preg::isMatch($excluded, strtr($filePath, '\\', '/'))) {
  1627 continue;
  1628 }
  1629 
  1630 $classes = self::findClasses($filePath);
  1631 if (null !== $autoloadType) {
  1632 $classes = self::filterByNamespace($classes, $filePath, $namespace, $autoloadType, $basePath, $io);
  1633 
  1634 
  1635 if ($classes) {
  1636 $scannedFiles[$realPath] = true;
  1637 }
  1638 } else {
  1639 
  1640 $scannedFiles[$realPath] = true;
  1641 }
  1642 
  1643 foreach ($classes as $class) {
  1644 
  1645 if (null === $autoloadType && null !== $namespace && '' !== $namespace && 0 !== strpos($class, $namespace)) {
  1646 continue;
  1647 }
  1648 
  1649 if (!isset($map[$class])) {
  1650 $map[$class] = $filePath;
  1651 } elseif ($io && $map[$class] !== $filePath && !Preg::isMatch('{/(test|fixture|example|stub)s?/}i', strtr($map[$class].' '.$filePath, '\\', '/'))) {
  1652 $io->writeError(
  1653 '<warning>Warning: Ambiguous class resolution, "'.$class.'"'.
  1654 ' was found in both "'.$map[$class].'" and "'.$filePath.'", the first will be used.</warning>'
  1655 );
  1656 }
  1657 }
  1658 }
  1659 
  1660 return $map;
  1661 }
  1662 
  1663 
  1664 
  1665 
  1666 
  1667 
  1668 
  1669 
  1670 
  1671 
  1672 
  1673 
  1674 private static function filterByNamespace($classes, $filePath, $baseNamespace, $namespaceType, $basePath, $io)
  1675 {
  1676 $validClasses = array();
  1677 $rejectedClasses = array();
  1678 
  1679 $realSubPath = substr($filePath, strlen($basePath) + 1);
  1680 $realSubPath = substr($realSubPath, 0, strrpos($realSubPath, '.'));
  1681 
  1682 foreach ($classes as $class) {
  1683 
  1684 if ('' !== $baseNamespace && 0 !== strpos($class, $baseNamespace)) {
  1685 continue;
  1686 }
  1687 
  1688 if ('psr-0' === $namespaceType) {
  1689 $namespaceLength = strrpos($class, '\\');
  1690 if (false !== $namespaceLength) {
  1691 $namespace = substr($class, 0, $namespaceLength + 1);
  1692 $className = substr($class, $namespaceLength + 1);
  1693 $subPath = str_replace('\\', DIRECTORY_SEPARATOR, $namespace)
  1694 . str_replace('_', DIRECTORY_SEPARATOR, $className);
  1695 } else {
  1696 $subPath = str_replace('_', DIRECTORY_SEPARATOR, $class);
  1697 }
  1698 } elseif ('psr-4' === $namespaceType) {
  1699 $subNamespace = ('' !== $baseNamespace) ? substr($class, strlen($baseNamespace)) : $class;
  1700 $subPath = str_replace('\\', DIRECTORY_SEPARATOR, $subNamespace);
  1701 } else {
  1702 throw new \RuntimeException("namespaceType must be psr-0 or psr-4, $namespaceType given");
  1703 }
  1704 if ($subPath === $realSubPath) {
  1705 $validClasses[] = $class;
  1706 } else {
  1707 $rejectedClasses[] = $class;
  1708 }
  1709 }
  1710 
  1711 if (empty($validClasses)) {
  1712 foreach ($rejectedClasses as $class) {
  1713 if ($io) {
  1714 $io->writeError("<warning>Class $class located in ".Preg::replace('{^'.preg_quote(getcwd()).'}', '.', $filePath, 1)." does not comply with $namespaceType autoloading standard. Skipping.</warning>");
  1715 }
  1716 }
  1717 
  1718 return array();
  1719 }
  1720 
  1721 return $validClasses;
  1722 }
  1723 
  1724 
  1725 
  1726 
  1727 
  1728 
  1729 
  1730 
  1731 private static function findClasses($path)
  1732 {
  1733 $extraTypes = self::getExtraTypes();
  1734 
  1735 
  1736 
  1737 $contents = @php_strip_whitespace($path);
  1738 if (!$contents) {
  1739 if (!file_exists($path)) {
  1740 $message = 'File at "%s" does not exist, check your classmap definitions';
  1741 } elseif (!Filesystem::isReadable($path)) {
  1742 $message = 'File at "%s" is not readable, check its permissions';
  1743 } elseif ('' === trim(file_get_contents($path))) {
  1744 
  1745 return array();
  1746 } else {
  1747 $message = 'File at "%s" could not be parsed as PHP, it may be binary or corrupted';
  1748 }
  1749 $error = error_get_last();
  1750 if (isset($error['message'])) {
  1751 $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];
  1752 }
  1753 throw new \RuntimeException(sprintf($message, $path));
  1754 }
  1755 
  1756 
  1757 Preg::matchAll('{\b(?:class|interface'.$extraTypes.')\s}i', $contents, $matches);
  1758 if (!$matches) {
  1759 return array();
  1760 }
  1761 
  1762 $p = new PhpFileCleaner($contents, count($matches[0]));
  1763 $contents = $p->clean();
  1764 unset($p);
  1765 
  1766 Preg::matchAll('{
  1767             (?:
  1768                  \b(?<![\$:>])(?P<type>class|interface'.$extraTypes.') \s++ (?P<name>[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+)
  1769                | \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s++[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\s*+\\\\\s*+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+)? \s*+ [\{;]
  1770             )
  1771         }ix', $contents, $matches);
  1772 
  1773 $classes = array();
  1774 $namespace = '';
  1775 
  1776 for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {
  1777 if (!empty($matches['ns'][$i])) {
  1778 $namespace = str_replace(array(' ', "\t", "\r", "\n"), '', $matches['nsname'][$i]) . '\\';
  1779 } else {
  1780 $name = $matches['name'][$i];
  1781 
  1782 if ($name === 'extends' || $name === 'implements') {
  1783 continue;
  1784 }
  1785 if ($name[0] === ':') {
  1786 
  1787 $name = 'xhp'.substr(str_replace(array('-', ':'), array('_', '__'), $name), 1);
  1788 } elseif (strtolower($matches['type'][$i]) === 'enum') {
  1789 
  1790 
  1791 
  1792 
  1793 
  1794 
  1795 
  1796 
  1797 $colonPos = strrpos($name, ':');
  1798 if (false !== $colonPos) {
  1799 $name = substr($name, 0, $colonPos);
  1800 }
  1801 }
  1802 $classes[] = ltrim($namespace . $name, '\\');
  1803 }
  1804 }
  1805 
  1806 return $classes;
  1807 }
  1808 
  1809 
  1810 
  1811 
  1812 private static function getExtraTypes()
  1813 {
  1814 static $extraTypes = null;
  1815 if (null === $extraTypes) {
  1816 $extraTypes = PHP_VERSION_ID < 50400 ? '' : '|trait';
  1817 if (PHP_VERSION_ID >= 80100 || (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '3.3', '>='))) {
  1818 $extraTypes .= '|enum';
  1819 }
  1820 PhpFileCleaner::setTypeConfig(array_merge(array('class', 'interface'), array_filter(explode('|', $extraTypes))));
  1821 }
  1822 
  1823 return $extraTypes;
  1824 }
  1825 }
  1826 <?php
  1827 
  1828 
  1829 
  1830 
  1831 
  1832 
  1833 
  1834 
  1835 
  1836 
  1837 
  1838 namespace Composer\Autoload;
  1839 
  1840 use Composer\Pcre\Preg;
  1841 
  1842 
  1843 
  1844 
  1845 
  1846 class PhpFileCleaner
  1847 {
  1848 
  1849 private static $typeConfig;
  1850 
  1851 
  1852 private static $restPattern;
  1853 
  1854 
  1855 
  1856 
  1857 
  1858 private $contents;
  1859 
  1860 
  1861 
  1862 
  1863 
  1864 private $len;
  1865 
  1866 
  1867 
  1868 
  1869 
  1870 private $maxMatches;
  1871 
  1872 
  1873 private $index = 0;
  1874 
  1875 
  1876 
  1877 
  1878 
  1879 public static function setTypeConfig($types)
  1880 {
  1881 foreach ($types as $type) {
  1882 self::$typeConfig[$type[0]] = array(
  1883 'name' => $type,
  1884 'length' => \strlen($type),
  1885 'pattern' => '{.\b(?<![\$:>])'.$type.'\s++[a-zA-Z_\x7f-\xff:][a-zA-Z0-9_\x7f-\xff:\-]*+}Ais',
  1886 );
  1887 }
  1888 
  1889 self::$restPattern = '{[^?"\'</'.implode('', array_keys(self::$typeConfig)).']+}A';
  1890 }
  1891 
  1892 
  1893 
  1894 
  1895 
  1896 public function __construct($contents, $maxMatches)
  1897 {
  1898 $this->contents = $contents;
  1899 $this->len = \strlen($this->contents);
  1900 $this->maxMatches = $maxMatches;
  1901 }
  1902 
  1903 
  1904 
  1905 
  1906 public function clean()
  1907 {
  1908 $clean = '';
  1909 
  1910 while ($this->index < $this->len) {
  1911 $this->skipToPhp();
  1912 $clean .= '<?';
  1913 
  1914 while ($this->index < $this->len) {
  1915 $char = $this->contents[$this->index];
  1916 if ($char === '?' && $this->peek('>')) {
  1917 $clean .= '?>';
  1918 $this->index += 2;
  1919 continue 2;
  1920 }
  1921 
  1922 if ($char === '"') {
  1923 $this->skipString('"');
  1924 $clean .= 'null';
  1925 continue;
  1926 }
  1927 
  1928 if ($char === "'") {
  1929 $this->skipString("'");
  1930 $clean .= 'null';
  1931 continue;
  1932 }
  1933 
  1934 if ($char === "<" && $this->peek('<') && $this->match('{<<<[ \t]*+([\'"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*+)\\1(?:\r\n|\n|\r)}A', $match)) {
  1935 $this->index += \strlen($match[0]);
  1936 $this->skipHeredoc($match[2]);
  1937 $clean .= 'null';
  1938 continue;
  1939 }
  1940 
  1941 if ($char === '/') {
  1942 if ($this->peek('/')) {
  1943 $this->skipToNewline();
  1944 continue;
  1945 }
  1946 if ($this->peek('*')) {
  1947 $this->skipComment();
  1948 continue;
  1949 }
  1950 }
  1951 
  1952 if ($this->maxMatches === 1 && isset(self::$typeConfig[$char])) {
  1953 $type = self::$typeConfig[$char];
  1954 if (
  1955 \substr($this->contents, $this->index, $type['length']) === $type['name']
  1956 && Preg::isMatch($type['pattern'], $this->contents, $match, 0, $this->index - 1)
  1957 ) {
  1958 $clean .= $match[0];
  1959 
  1960 return $clean;
  1961 }
  1962 }
  1963 
  1964 $this->index += 1;
  1965 if ($this->match(self::$restPattern, $match)) {
  1966 $clean .= $char . $match[0];
  1967 $this->index += \strlen($match[0]);
  1968 } else {
  1969 $clean .= $char;
  1970 }
  1971 }
  1972 }
  1973 
  1974 return $clean;
  1975 }
  1976 
  1977 
  1978 
  1979 
  1980 private function skipToPhp()
  1981 {
  1982 while ($this->index < $this->len) {
  1983 if ($this->contents[$this->index] === '<' && $this->peek('?')) {
  1984 $this->index += 2;
  1985 break;
  1986 }
  1987 
  1988 $this->index += 1;
  1989 }
  1990 }
  1991 
  1992 
  1993 
  1994 
  1995 
  1996 private function skipString($delimiter)
  1997 {
  1998 $this->index += 1;
  1999 while ($this->index < $this->len) {
  2000 if ($this->contents[$this->index] === '\\' && ($this->peek('\\') || $this->peek($delimiter))) {
  2001 $this->index += 2;
  2002 continue;
  2003 }
  2004 if ($this->contents[$this->index] === $delimiter) {
  2005 $this->index += 1;
  2006 break;
  2007 }
  2008 $this->index += 1;
  2009 }
  2010 }
  2011 
  2012 
  2013 
  2014 
  2015 private function skipComment()
  2016 {
  2017 $this->index += 2;
  2018 while ($this->index < $this->len) {
  2019 if ($this->contents[$this->index] === '*' && $this->peek('/')) {
  2020 $this->index += 2;
  2021 break;
  2022 }
  2023 
  2024 $this->index += 1;
  2025 }
  2026 }
  2027 
  2028 
  2029 
  2030 
  2031 private function skipToNewline()
  2032 {
  2033 while ($this->index < $this->len) {
  2034 if ($this->contents[$this->index] === "\r" || $this->contents[$this->index] === "\n") {
  2035 return;
  2036 }
  2037 $this->index += 1;
  2038 }
  2039 }
  2040 
  2041 
  2042 
  2043 
  2044 
  2045 private function skipHeredoc($delimiter)
  2046 {
  2047 $firstDelimiterChar = $delimiter[0];
  2048 $delimiterLength = \strlen($delimiter);
  2049 $delimiterPattern = '{'.preg_quote($delimiter).'(?![a-zA-Z0-9_\x80-\xff])}A';
  2050 
  2051 while ($this->index < $this->len) {
  2052 
  2053 switch ($this->contents[$this->index]) {
  2054 case "\t":
  2055 case " ":
  2056 $this->index += 1;
  2057 continue 2;
  2058 case $firstDelimiterChar:
  2059 if (
  2060 \substr($this->contents, $this->index, $delimiterLength) === $delimiter
  2061 && $this->match($delimiterPattern)
  2062 ) {
  2063 $this->index += $delimiterLength;
  2064 
  2065 return;
  2066 }
  2067 break;
  2068 }
  2069 
  2070 
  2071 while ($this->index < $this->len) {
  2072 $this->skipToNewline();
  2073 
  2074 
  2075 while ($this->index < $this->len && ($this->contents[$this->index] === "\r" || $this->contents[$this->index] === "\n")) {
  2076 $this->index += 1;
  2077 }
  2078 
  2079 break;
  2080 }
  2081 }
  2082 }
  2083 
  2084 
  2085 
  2086 
  2087 
  2088 private function peek($char)
  2089 {
  2090 return $this->index + 1 < $this->len && $this->contents[$this->index + 1] === $char;
  2091 }
  2092 
  2093 
  2094 
  2095 
  2096 
  2097 
  2098 private function match($regex, array &$match = null)
  2099 {
  2100 return Preg::isMatch($regex, $this->contents, $match, 0, $this->index);
  2101 }
  2102 }
  2103 <?php
  2104 
  2105 
  2106 
  2107 
  2108 
  2109 
  2110 
  2111 
  2112 
  2113 
  2114 
  2115 namespace Composer;
  2116 
  2117 use Composer\IO\IOInterface;
  2118 use Composer\Pcre\Preg;
  2119 use Composer\Util\Filesystem;
  2120 use Composer\Util\Platform;
  2121 use Composer\Util\Silencer;
  2122 use Symfony\Component\Finder\Finder;
  2123 
  2124 
  2125 
  2126 
  2127 
  2128 
  2129 class Cache
  2130 {
  2131 
  2132 private static $cacheCollected = null;
  2133 
  2134 private $io;
  2135 
  2136 private $root;
  2137 
  2138 private $enabled = null;
  2139 
  2140 private $allowlist;
  2141 
  2142 private $filesystem;
  2143 
  2144 private $readOnly;
  2145 
  2146 
  2147 
  2148 
  2149 
  2150 
  2151 
  2152 
  2153 public function __construct(IOInterface $io, $cacheDir, $allowlist = 'a-z0-9.', Filesystem $filesystem = null, $readOnly = false)
  2154 {
  2155 $this->io = $io;
  2156 $this->root = rtrim($cacheDir, '/\\') . '/';
  2157 $this->allowlist = $allowlist;
  2158 $this->filesystem = $filesystem ?: new Filesystem();
  2159 $this->readOnly = (bool) $readOnly;
  2160 
  2161 if (!self::isUsable($cacheDir)) {
  2162 $this->enabled = false;
  2163 }
  2164 }
  2165 
  2166 
  2167 
  2168 
  2169 
  2170 
  2171 public function setReadOnly($readOnly)
  2172 {
  2173 $this->readOnly = (bool) $readOnly;
  2174 }
  2175 
  2176 
  2177 
  2178 
  2179 public function isReadOnly()
  2180 {
  2181 return $this->readOnly;
  2182 }
  2183 
  2184 
  2185 
  2186 
  2187 
  2188 
  2189 public static function isUsable($path)
  2190 {
  2191 return !Preg::isMatch('{(^|[\\\\/])(\$null|nul|NUL|/dev/null)([\\\\/]|$)}', $path);
  2192 }
  2193 
  2194 
  2195 
  2196 
  2197 public function isEnabled()
  2198 {
  2199 if ($this->enabled === null) {
  2200 $this->enabled = true;
  2201 
  2202 if (
  2203 (!is_dir($this->root) && !Silencer::call('mkdir', $this->root, 0777, true))
  2204 || !is_writable($this->root)
  2205 ) {
  2206 $this->io->writeError('<warning>Cannot create cache directory ' . $this->root . ', or directory is not writable. Proceeding without cache</warning>');
  2207 $this->enabled = false;
  2208 }
  2209 }
  2210 
  2211 return $this->enabled;
  2212 }
  2213 
  2214 
  2215 
  2216 
  2217 public function getRoot()
  2218 {
  2219 return $this->root;
  2220 }
  2221 
  2222 
  2223 
  2224 
  2225 
  2226 
  2227 public function read($file)
  2228 {
  2229 if ($this->isEnabled()) {
  2230 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2231 if (file_exists($this->root . $file)) {
  2232 $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG);
  2233 
  2234 return file_get_contents($this->root . $file);
  2235 }
  2236 }
  2237 
  2238 return false;
  2239 }
  2240 
  2241 
  2242 
  2243 
  2244 
  2245 
  2246 
  2247 public function write($file, $contents)
  2248 {
  2249 if ($this->isEnabled() && !$this->readOnly) {
  2250 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2251 
  2252 $this->io->writeError('Writing '.$this->root . $file.' into cache', true, IOInterface::DEBUG);
  2253 
  2254 $tempFileName = $this->root . $file . uniqid('.', true) . '.tmp';
  2255 try {
  2256 return file_put_contents($tempFileName, $contents) !== false && rename($tempFileName, $this->root . $file);
  2257 } catch (\ErrorException $e) {
  2258 $this->io->writeError('<warning>Failed to write into cache: '.$e->getMessage().'</warning>', true, IOInterface::DEBUG);
  2259 if (Preg::isMatch('{^file_put_contents\(\): Only ([0-9]+) of ([0-9]+) bytes written}', $e->getMessage(), $m)) {
  2260 
  2261 unlink($tempFileName);
  2262 
  2263 $message = sprintf(
  2264 '<warning>Writing %1$s into cache failed after %2$u of %3$u bytes written, only %4$u bytes of free space available</warning>',
  2265 $tempFileName,
  2266 $m[1],
  2267 $m[2],
  2268 @disk_free_space(dirname($tempFileName))
  2269 );
  2270 
  2271 $this->io->writeError($message);
  2272 
  2273 return false;
  2274 }
  2275 
  2276 throw $e;
  2277 }
  2278 }
  2279 
  2280 return false;
  2281 }
  2282 
  2283 
  2284 
  2285 
  2286 
  2287 
  2288 
  2289 
  2290 
  2291 public function copyFrom($file, $source)
  2292 {
  2293 if ($this->isEnabled() && !$this->readOnly) {
  2294 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2295 $this->filesystem->ensureDirectoryExists(dirname($this->root . $file));
  2296 
  2297 if (!file_exists($source)) {
  2298 $this->io->writeError('<error>'.$source.' does not exist, can not write into cache</error>');
  2299 } elseif ($this->io->isDebug()) {
  2300 $this->io->writeError('Writing '.$this->root . $file.' into cache from '.$source);
  2301 }
  2302 
  2303 return copy($source, $this->root . $file);
  2304 }
  2305 
  2306 return false;
  2307 }
  2308 
  2309 
  2310 
  2311 
  2312 
  2313 
  2314 
  2315 
  2316 
  2317 public function copyTo($file, $target)
  2318 {
  2319 if ($this->isEnabled()) {
  2320 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2321 if (file_exists($this->root . $file)) {
  2322 try {
  2323 touch($this->root . $file, filemtime($this->root . $file), time());
  2324 } catch (\ErrorException $e) {
  2325 
  2326 
  2327 Silencer::call('touch', $this->root . $file);
  2328 }
  2329 
  2330 $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG);
  2331 
  2332 return copy($this->root . $file, $target);
  2333 }
  2334 }
  2335 
  2336 return false;
  2337 }
  2338 
  2339 
  2340 
  2341 
  2342 public function gcIsNecessary()
  2343 {
  2344 if (self::$cacheCollected) {
  2345 return false;
  2346 }
  2347 
  2348 self::$cacheCollected = true;
  2349 if (Platform::getEnv('COMPOSER_TEST_SUITE')) {
  2350 return false;
  2351 }
  2352 
  2353 if (PHP_VERSION_ID > 70000) {
  2354 return !random_int(0, 50);
  2355 }
  2356 
  2357 return !mt_rand(0, 50);
  2358 }
  2359 
  2360 
  2361 
  2362 
  2363 
  2364 
  2365 public function remove($file)
  2366 {
  2367 if ($this->isEnabled()) {
  2368 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2369 if (file_exists($this->root . $file)) {
  2370 return $this->filesystem->unlink($this->root . $file);
  2371 }
  2372 }
  2373 
  2374 return false;
  2375 }
  2376 
  2377 
  2378 
  2379 
  2380 public function clear()
  2381 {
  2382 if ($this->isEnabled()) {
  2383 $this->filesystem->emptyDirectory($this->root);
  2384 
  2385 return true;
  2386 }
  2387 
  2388 return false;
  2389 }
  2390 
  2391 
  2392 
  2393 
  2394 
  2395 
  2396 public function getAge($file)
  2397 {
  2398 if ($this->isEnabled()) {
  2399 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2400 if (file_exists($this->root . $file) && ($mtime = filemtime($this->root . $file)) !== false) {
  2401 return abs(time() - $mtime);
  2402 }
  2403 }
  2404 
  2405 return false;
  2406 }
  2407 
  2408 
  2409 
  2410 
  2411 
  2412 
  2413 
  2414 public function gc($ttl, $maxSize)
  2415 {
  2416 if ($this->isEnabled()) {
  2417 $expire = new \DateTime();
  2418 $expire->modify('-'.$ttl.' seconds');
  2419 
  2420 $finder = $this->getFinder()->date('until '.$expire->format('Y-m-d H:i:s'));
  2421 foreach ($finder as $file) {
  2422 $this->filesystem->unlink($file->getPathname());
  2423 }
  2424 
  2425 $totalSize = $this->filesystem->size($this->root);
  2426 if ($totalSize > $maxSize) {
  2427 $iterator = $this->getFinder()->sortByAccessedTime()->getIterator();
  2428 while ($totalSize > $maxSize && $iterator->valid()) {
  2429 $filepath = $iterator->current()->getPathname();
  2430 $totalSize -= $this->filesystem->size($filepath);
  2431 $this->filesystem->unlink($filepath);
  2432 $iterator->next();
  2433 }
  2434 }
  2435 
  2436 self::$cacheCollected = true;
  2437 
  2438 return true;
  2439 }
  2440 
  2441 return false;
  2442 }
  2443 
  2444 
  2445 
  2446 
  2447 
  2448 
  2449 public function sha1($file)
  2450 {
  2451 if ($this->isEnabled()) {
  2452 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2453 if (file_exists($this->root . $file)) {
  2454 return sha1_file($this->root . $file);
  2455 }
  2456 }
  2457 
  2458 return false;
  2459 }
  2460 
  2461 
  2462 
  2463 
  2464 
  2465 
  2466 public function sha256($file)
  2467 {
  2468 if ($this->isEnabled()) {
  2469 $file = Preg::replace('{[^'.$this->allowlist.']}i', '-', $file);
  2470 if (file_exists($this->root . $file)) {
  2471 return hash_file('sha256', $this->root . $file);
  2472 }
  2473 }
  2474 
  2475 return false;
  2476 }
  2477 
  2478 
  2479 
  2480 
  2481 protected function getFinder()
  2482 {
  2483 return Finder::create()->in($this->root)->files();
  2484 }
  2485 }
  2486 <?php
  2487 
  2488 
  2489 
  2490 
  2491 
  2492 
  2493 
  2494 
  2495 
  2496 
  2497 
  2498 namespace Composer\Command;
  2499 
  2500 use Composer\Composer;
  2501 use Symfony\Component\Console\Input\InputInterface;
  2502 use Symfony\Component\Console\Output\OutputInterface;
  2503 
  2504 
  2505 
  2506 
  2507 class AboutCommand extends BaseCommand
  2508 {
  2509 
  2510 
  2511 
  2512 protected function configure()
  2513 {
  2514 $this
  2515 ->setName('about')
  2516 ->setDescription('Shows a short information about Composer.')
  2517 ->setHelp(
  2518 <<<EOT
  2519 <info>php composer.phar about</info>
  2520 EOT
  2521 )
  2522 ;
  2523 }
  2524 
  2525 protected function execute(InputInterface $input, OutputInterface $output)
  2526 {
  2527 $composerVersion = Composer::getVersion();
  2528 
  2529 $this->getIO()->write(
  2530 <<<EOT
  2531 <info>Composer - Dependency Manager for PHP - version $composerVersion</info>
  2532 <comment>Composer is a dependency manager tracking local dependencies of your projects and libraries.
  2533 See https://getcomposer.org/ for more information.</comment>
  2534 EOT
  2535 );
  2536 
  2537 return 0;
  2538 }
  2539 }
  2540 <?php
  2541 
  2542 
  2543 
  2544 
  2545 
  2546 
  2547 
  2548 
  2549 
  2550 
  2551 
  2552 namespace Composer\Command;
  2553 
  2554 use Composer\Factory;
  2555 use Composer\IO\IOInterface;
  2556 use Composer\Config;
  2557 use Composer\Composer;
  2558 use Composer\Package\BasePackage;
  2559 use Composer\Package\CompletePackageInterface;
  2560 use Composer\Repository\CompositeRepository;
  2561 use Composer\Repository\RepositoryFactory;
  2562 use Composer\Script\ScriptEvents;
  2563 use Composer\Plugin\CommandEvent;
  2564 use Composer\Plugin\PluginEvents;
  2565 use Composer\Util\Filesystem;
  2566 use Composer\Util\Loop;
  2567 use Composer\Util\ProcessExecutor;
  2568 use Symfony\Component\Console\Input\InputArgument;
  2569 use Symfony\Component\Console\Input\InputInterface;
  2570 use Symfony\Component\Console\Input\InputOption;
  2571 use Symfony\Component\Console\Output\OutputInterface;
  2572 
  2573 
  2574 
  2575 
  2576 
  2577 
  2578 class ArchiveCommand extends BaseCommand
  2579 {
  2580 
  2581 
  2582 
  2583 protected function configure()
  2584 {
  2585 $this
  2586 ->setName('archive')
  2587 ->setDescription('Creates an archive of this composer package.')
  2588 ->setDefinition(array(
  2589 new InputArgument('package', InputArgument::OPTIONAL, 'The package to archive instead of the current project'),
  2590 new InputArgument('version', InputArgument::OPTIONAL, 'A version constraint to find the package to archive'),
  2591 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the resulting archive: tar, tar.gz, tar.bz2 or zip (default tar)'),
  2592 new InputOption('dir', null, InputOption::VALUE_REQUIRED, 'Write the archive to this directory'),
  2593 new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.'
  2594 .' Note that the format will be appended.'),
  2595 new InputOption('ignore-filters', null, InputOption::VALUE_NONE, 'Ignore filters when saving package'),
  2596 ))
  2597 ->setHelp(
  2598 <<<EOT
  2599 The <info>archive</info> command creates an archive of the specified format
  2600 containing the files and directories of the Composer project or the specified
  2601 package in the specified version and writes it to the specified directory.
  2602 
  2603 <info>php composer.phar archive [--format=zip] [--dir=/foo] [--file=filename] [package [version]]</info>
  2604 
  2605 Read more at https://getcomposer.org/doc/03-cli.md#archive
  2606 EOT
  2607 )
  2608 ;
  2609 }
  2610 
  2611 protected function execute(InputInterface $input, OutputInterface $output)
  2612 {
  2613 $composer = $this->getComposer(false);
  2614 $config = null;
  2615 
  2616 if ($composer) {
  2617 $config = $composer->getConfig();
  2618 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'archive', $input, $output);
  2619 $eventDispatcher = $composer->getEventDispatcher();
  2620 $eventDispatcher->dispatch($commandEvent->getName(), $commandEvent);
  2621 $eventDispatcher->dispatchScript(ScriptEvents::PRE_ARCHIVE_CMD);
  2622 }
  2623 
  2624 if (!$config) {
  2625 $config = Factory::createConfig();
  2626 }
  2627 
  2628 if (null === $input->getOption('format')) {
  2629 $input->setOption('format', $config->get('archive-format'));
  2630 }
  2631 if (null === $input->getOption('dir')) {
  2632 $input->setOption('dir', $config->get('archive-dir'));
  2633 }
  2634 
  2635 $returnCode = $this->archive(
  2636 $this->getIO(),
  2637 $config,
  2638 $input->getArgument('package'),
  2639 $input->getArgument('version'),
  2640 $input->getOption('format'),
  2641 $input->getOption('dir'),
  2642 $input->getOption('file'),
  2643 $input->getOption('ignore-filters'),
  2644 $composer
  2645 );
  2646 
  2647 if (0 === $returnCode && $composer) {
  2648 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_ARCHIVE_CMD);
  2649 }
  2650 
  2651 return $returnCode;
  2652 }
  2653 
  2654 
  2655 
  2656 
  2657 
  2658 
  2659 
  2660 
  2661 
  2662 
  2663 
  2664 
  2665 protected function archive(IOInterface $io, Config $config, $packageName = null, $version = null, $format = 'tar', $dest = '.', $fileName = null, $ignoreFilters = false, Composer $composer = null)
  2666 {
  2667 if ($composer) {
  2668 $archiveManager = $composer->getArchiveManager();
  2669 } else {
  2670 $factory = new Factory;
  2671 $process = new ProcessExecutor();
  2672 $httpDownloader = Factory::createHttpDownloader($io, $config);
  2673 $downloadManager = $factory->createDownloadManager($io, $config, $httpDownloader, $process);
  2674 $archiveManager = $factory->createArchiveManager($config, $downloadManager, new Loop($httpDownloader, $process));
  2675 }
  2676 
  2677 if ($packageName) {
  2678 $package = $this->selectPackage($io, $packageName, $version);
  2679 
  2680 if (!$package) {
  2681 return 1;
  2682 }
  2683 } else {
  2684 $package = $this->getComposer()->getPackage();
  2685 }
  2686 
  2687 $io->writeError('<info>Creating the archive into "'.$dest.'".</info>');
  2688 $packagePath = $archiveManager->archive($package, $format, $dest, $fileName, $ignoreFilters);
  2689 $fs = new Filesystem;
  2690 $shortPath = $fs->findShortestPath(getcwd(), $packagePath, true);
  2691 
  2692 $io->writeError('Created: ', false);
  2693 $io->write(strlen($shortPath) < strlen($packagePath) ? $shortPath : $packagePath);
  2694 
  2695 return 0;
  2696 }
  2697 
  2698 
  2699 
  2700 
  2701 
  2702 
  2703 
  2704 protected function selectPackage(IOInterface $io, $packageName, $version = null)
  2705 {
  2706 $io->writeError('<info>Searching for the specified package.</info>');
  2707 
  2708 if ($composer = $this->getComposer(false)) {
  2709 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
  2710 $repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
  2711 } else {
  2712 $defaultRepos = RepositoryFactory::defaultRepos($this->getIO());
  2713 $io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
  2714 $repo = new CompositeRepository($defaultRepos);
  2715 }
  2716 
  2717 $packages = $repo->findPackages($packageName, $version);
  2718 
  2719 if (count($packages) > 1) {
  2720 $package = reset($packages);
  2721 $io->writeError('<info>Found multiple matches, selected '.$package->getPrettyString().'.</info>');
  2722 $io->writeError('Alternatives were '.implode(', ', array_map(function ($p) {
  2723 return $p->getPrettyString();
  2724 }, $packages)).'.');
  2725 $io->writeError('<comment>Please use a more specific constraint to pick a different package.</comment>');
  2726 } elseif ($packages) {
  2727 $package = reset($packages);
  2728 $io->writeError('<info>Found an exact match '.$package->getPrettyString().'.</info>');
  2729 } else {
  2730 $io->writeError('<error>Could not find a package matching '.$packageName.'.</error>');
  2731 
  2732 return false;
  2733 }
  2734 
  2735 if (!$package instanceof CompletePackageInterface) {
  2736 throw new \LogicException('Expected a CompletePackageInterface instance but found '.get_class($package));
  2737 }
  2738 
  2739 return $package;
  2740 }
  2741 }
  2742 <?php
  2743 
  2744 
  2745 
  2746 
  2747 
  2748 
  2749 
  2750 
  2751 
  2752 
  2753 
  2754 namespace Composer\Command;
  2755 
  2756 use Composer\Composer;
  2757 use Composer\Config;
  2758 use Composer\Console\Application;
  2759 use Composer\Factory;
  2760 use Composer\IO\IOInterface;
  2761 use Composer\IO\NullIO;
  2762 use Composer\Plugin\PreCommandRunEvent;
  2763 use Composer\Package\Version\VersionParser;
  2764 use Composer\Plugin\PluginEvents;
  2765 use Composer\Util\Platform;
  2766 use Symfony\Component\Console\Helper\Table;
  2767 use Symfony\Component\Console\Helper\TableSeparator;
  2768 use Symfony\Component\Console\Input\InputInterface;
  2769 use Symfony\Component\Console\Output\OutputInterface;
  2770 use Symfony\Component\Console\Command\Command;
  2771 use Symfony\Component\Console\Terminal;
  2772 
  2773 
  2774 
  2775 
  2776 
  2777 
  2778 
  2779 
  2780 
  2781 abstract class BaseCommand extends Command
  2782 {
  2783 
  2784 
  2785 
  2786 private $composer;
  2787 
  2788 
  2789 
  2790 
  2791 private $io;
  2792 
  2793 
  2794 
  2795 
  2796 
  2797 
  2798 
  2799 
  2800 public function getComposer($required = true, $disablePlugins = null, $disableScripts = null)
  2801 {
  2802 if (null === $this->composer) {
  2803 $application = $this->getApplication();
  2804 if ($application instanceof Application) {
  2805 
  2806 $this->composer = $application->getComposer($required, $disablePlugins, $disableScripts);
  2807 
  2808 } elseif ($required) {
  2809 throw new \RuntimeException(
  2810 'Could not create a Composer\Composer instance, you must inject '.
  2811 'one if this command is not used with a Composer\Console\Application instance'
  2812 );
  2813 }
  2814 }
  2815 
  2816 return $this->composer;
  2817 }
  2818 
  2819 
  2820 
  2821 
  2822 public function setComposer(Composer $composer)
  2823 {
  2824 $this->composer = $composer;
  2825 }
  2826 
  2827 
  2828 
  2829 
  2830 
  2831 
  2832 public function resetComposer()
  2833 {
  2834 $this->composer = null;
  2835 $this->getApplication()->resetComposer();
  2836 }
  2837 
  2838 
  2839 
  2840 
  2841 
  2842 
  2843 
  2844 
  2845 public function isProxyCommand()
  2846 {
  2847 return false;
  2848 }
  2849 
  2850 
  2851 
  2852 
  2853 public function getIO()
  2854 {
  2855 if (null === $this->io) {
  2856 $application = $this->getApplication();
  2857 if ($application instanceof Application) {
  2858 $this->io = $application->getIO();
  2859 
  2860 } else {
  2861 $this->io = new NullIO();
  2862 }
  2863 }
  2864 
  2865 return $this->io;
  2866 }
  2867 
  2868 
  2869 
  2870 
  2871 public function setIO(IOInterface $io)
  2872 {
  2873 $this->io = $io;
  2874 }
  2875 
  2876 
  2877 
  2878 
  2879 
  2880 
  2881 protected function initialize(InputInterface $input, OutputInterface $output)
  2882 {
  2883 
  2884 $disablePlugins = $input->hasParameterOption('--no-plugins');
  2885 $disableScripts = $input->hasParameterOption('--no-scripts');
  2886 if ($this instanceof SelfUpdateCommand) {
  2887 $disablePlugins = true;
  2888 $disableScripts = true;
  2889 }
  2890 
  2891 $composer = $this->getComposer(false, $disablePlugins, $disableScripts);
  2892 if (null === $composer) {
  2893 $composer = Factory::createGlobal($this->getIO(), $disablePlugins, $disableScripts);
  2894 }
  2895 if ($composer) {
  2896 $preCommandRunEvent = new PreCommandRunEvent(PluginEvents::PRE_COMMAND_RUN, $input, $this->getName());
  2897 $composer->getEventDispatcher()->dispatch($preCommandRunEvent->getName(), $preCommandRunEvent);
  2898 }
  2899 
  2900 if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) {
  2901 $input->setOption('no-progress', true);
  2902 }
  2903 
  2904 if (true == $input->hasOption('no-dev')) {
  2905 if (!$input->getOption('no-dev') && true == Platform::getEnv('COMPOSER_NO_DEV')) {
  2906 $input->setOption('no-dev', true);
  2907 }
  2908 }
  2909 
  2910 parent::initialize($input, $output);
  2911 }
  2912 
  2913 
  2914 
  2915 
  2916 
  2917 
  2918 
  2919 
  2920 protected function getPreferredInstallOptions(Config $config, InputInterface $input, $keepVcsRequiresPreferSource = false)
  2921 {
  2922 $preferSource = false;
  2923 $preferDist = false;
  2924 
  2925 switch ($config->get('preferred-install')) {
  2926 case 'source':
  2927 $preferSource = true;
  2928 break;
  2929 case 'dist':
  2930 $preferDist = true;
  2931 break;
  2932 case 'auto':
  2933 default:
  2934 
  2935 break;
  2936 }
  2937 
  2938 if ($input->hasOption('prefer-install') && $input->getOption('prefer-install')) {
  2939 if ($input->getOption('prefer-source')) {
  2940 throw new \InvalidArgumentException('--prefer-source can not be used together with --prefer-install');
  2941 }
  2942 if ($input->getOption('prefer-dist')) {
  2943 throw new \InvalidArgumentException('--prefer-dist can not be used together with --prefer-install');
  2944 }
  2945 switch ($input->getOption('prefer-install')) {
  2946 case 'dist':
  2947 $input->setOption('prefer-dist', true);
  2948 break;
  2949 case 'source':
  2950 $input->setOption('prefer-source', true);
  2951 break;
  2952 case 'auto':
  2953 $preferDist = false;
  2954 $preferSource = false;
  2955 break;
  2956 default:
  2957 throw new \UnexpectedValueException('--prefer-install accepts one of "dist", "source" or "auto", got '.$input->getOption('prefer-install'));
  2958 }
  2959 }
  2960 
  2961 if ($input->getOption('prefer-source') || $input->getOption('prefer-dist') || ($keepVcsRequiresPreferSource && $input->hasOption('keep-vcs') && $input->getOption('keep-vcs'))) {
  2962 $preferSource = $input->getOption('prefer-source') || ($keepVcsRequiresPreferSource && $input->hasOption('keep-vcs') && $input->getOption('keep-vcs'));
  2963 $preferDist = (bool) $input->getOption('prefer-dist');
  2964 }
  2965 
  2966 return array($preferSource, $preferDist);
  2967 }
  2968 
  2969 
  2970 
  2971 
  2972 
  2973 
  2974 protected function formatRequirements(array $requirements)
  2975 {
  2976 $requires = array();
  2977 $requirements = $this->normalizeRequirements($requirements);
  2978 foreach ($requirements as $requirement) {
  2979 if (!isset($requirement['version'])) {
  2980 throw new \UnexpectedValueException('Option '.$requirement['name'] .' is missing a version constraint, use e.g. '.$requirement['name'].':^1.0');
  2981 }
  2982 $requires[$requirement['name']] = $requirement['version'];
  2983 }
  2984 
  2985 return $requires;
  2986 }
  2987 
  2988 
  2989 
  2990 
  2991 
  2992 
  2993 protected function normalizeRequirements(array $requirements)
  2994 {
  2995 $parser = new VersionParser();
  2996 
  2997 return $parser->parseNameVersionPairs($requirements);
  2998 }
  2999 
  3000 
  3001 
  3002 
  3003 
  3004 
  3005 protected function renderTable(array $table, OutputInterface $output)
  3006 {
  3007 $renderer = new Table($output);
  3008 $renderer->setStyle('compact');
  3009 $rendererStyle = $renderer->getStyle();
  3010 if (method_exists($rendererStyle, 'setVerticalBorderChars')) {
  3011 $rendererStyle->setVerticalBorderChars('');
  3012 } else {
  3013 
  3014 
  3015 $rendererStyle->setVerticalBorderChar('');
  3016 }
  3017 $rendererStyle->setCellRowContentFormat('%s  ');
  3018 $renderer->setRows($table)->render();
  3019 }
  3020 
  3021 
  3022 
  3023 
  3024 protected function getTerminalWidth()
  3025 {
  3026 if (class_exists('Symfony\Component\Console\Terminal')) {
  3027 $terminal = new Terminal();
  3028 $width = $terminal->getWidth();
  3029 } else {
  3030 
  3031 
  3032 
  3033 list($width) = $this->getApplication()->getTerminalDimensions();
  3034 }
  3035 if (null === $width) {
  3036 
  3037 
  3038 $width = PHP_INT_MAX;
  3039 }
  3040 if (Platform::isWindows()) {
  3041 $width--;
  3042 } else {
  3043 $width = max(80, $width);
  3044 }
  3045 
  3046 return $width;
  3047 }
  3048 }
  3049 <?php
  3050 
  3051 
  3052 
  3053 
  3054 
  3055 
  3056 
  3057 
  3058 
  3059 
  3060 
  3061 namespace Composer\Command;
  3062 
  3063 use Composer\Package\Link;
  3064 use Composer\Package\PackageInterface;
  3065 use Composer\Package\CompletePackageInterface;
  3066 use Composer\Package\RootPackage;
  3067 use Composer\Repository\InstalledArrayRepository;
  3068 use Composer\Repository\CompositeRepository;
  3069 use Composer\Repository\RootPackageRepository;
  3070 use Composer\Repository\InstalledRepository;
  3071 use Composer\Repository\PlatformRepository;
  3072 use Composer\Repository\RepositoryFactory;
  3073 use Composer\Plugin\CommandEvent;
  3074 use Composer\Plugin\PluginEvents;
  3075 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
  3076 use Composer\Package\Version\VersionParser;
  3077 use Symfony\Component\Console\Input\InputInterface;
  3078 use Symfony\Component\Console\Output\OutputInterface;
  3079 
  3080 
  3081 
  3082 
  3083 
  3084 
  3085 class BaseDependencyCommand extends BaseCommand
  3086 {
  3087 const ARGUMENT_PACKAGE = 'package';
  3088 const ARGUMENT_CONSTRAINT = 'version';
  3089 const OPTION_RECURSIVE = 'recursive';
  3090 const OPTION_TREE = 'tree';
  3091 
  3092 
  3093 protected $colors;
  3094 
  3095 
  3096 
  3097 
  3098 
  3099 
  3100 
  3101 protected function doExecute(InputInterface $input, OutputInterface $output, $inverted = false)
  3102 {
  3103 
  3104 $composer = $this->getComposer();
  3105 $commandEvent = new CommandEvent(PluginEvents::COMMAND, $this->getName(), $input, $output);
  3106 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  3107 
  3108 $platformOverrides = $composer->getConfig()->get('platform') ?: array();
  3109 $installedRepo = new InstalledRepository(array(
  3110 new RootPackageRepository($composer->getPackage()),
  3111 $composer->getRepositoryManager()->getLocalRepository(),
  3112 new PlatformRepository(array(), $platformOverrides),
  3113 ));
  3114 
  3115 
  3116 list($needle, $textConstraint) = array_pad(
  3117 explode(':', $input->getArgument(self::ARGUMENT_PACKAGE)),
  3118 2,
  3119 $input->hasArgument(self::ARGUMENT_CONSTRAINT) ? $input->getArgument(self::ARGUMENT_CONSTRAINT) : '*'
  3120 );
  3121 
  3122 
  3123 $packages = $installedRepo->findPackagesWithReplacersAndProviders($needle);
  3124 if (empty($packages)) {
  3125 throw new \InvalidArgumentException(sprintf('Could not find package "%s" in your project', $needle));
  3126 }
  3127 
  3128 
  3129 
  3130 if (!$installedRepo->findPackage($needle, $textConstraint)) {
  3131 $defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO()));
  3132 if ($match = $defaultRepos->findPackage($needle, $textConstraint)) {
  3133 $installedRepo->addRepository(new InstalledArrayRepository(array(clone $match)));
  3134 }
  3135 }
  3136 
  3137 
  3138 $needles = array($needle);
  3139 if ($inverted) {
  3140 foreach ($packages as $package) {
  3141 $needles = array_merge($needles, array_map(function (Link $link) {
  3142 return $link->getTarget();
  3143 }, $package->getReplaces()));
  3144 }
  3145 }
  3146 
  3147 
  3148 if ('*' !== $textConstraint) {
  3149 $versionParser = new VersionParser();
  3150 $constraint = $versionParser->parseConstraints($textConstraint);
  3151 } else {
  3152 $constraint = null;
  3153 }
  3154 
  3155 
  3156 $renderTree = $input->getOption(self::OPTION_TREE);
  3157 $recursive = $renderTree || $input->getOption(self::OPTION_RECURSIVE);
  3158 
  3159 
  3160 $results = $installedRepo->getDependents($needles, $constraint, $inverted, $recursive);
  3161 if (empty($results)) {
  3162 $extra = (null !== $constraint) ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : '';
  3163 $this->getIO()->writeError(sprintf(
  3164 '<info>There is no installed package depending on "%s"%s</info>',
  3165 $needle,
  3166 $extra
  3167 ));
  3168 } elseif ($renderTree) {
  3169 $this->initStyles($output);
  3170 $root = $packages[0];
  3171 $this->getIO()->write(sprintf('<info>%s</info> %s %s', $root->getPrettyName(), $root->getPrettyVersion(), $root instanceof CompletePackageInterface ? $root->getDescription() : ''));
  3172 $this->printTree($results);
  3173 } else {
  3174 $this->printTable($output, $results);
  3175 }
  3176 
  3177 return 0;
  3178 }
  3179 
  3180 
  3181 
  3182 
  3183 
  3184 
  3185 
  3186 
  3187 protected function printTable(OutputInterface $output, $results)
  3188 {
  3189 $table = array();
  3190 $doubles = array();
  3191 do {
  3192 $queue = array();
  3193 $rows = array();
  3194 foreach ($results as $result) {
  3195 
  3196 
  3197 
  3198 
  3199 list($package, $link, $children) = $result;
  3200 $unique = (string) $link;
  3201 if (isset($doubles[$unique])) {
  3202 continue;
  3203 }
  3204 $doubles[$unique] = true;
  3205 $version = $package->getPrettyVersion() === RootPackage::DEFAULT_PRETTY_VERSION ? '-' : $package->getPrettyVersion();
  3206 $rows[] = array($package->getPrettyName(), $version, $link->getDescription(), sprintf('%s (%s)', $link->getTarget(), $link->getPrettyConstraint()));
  3207 if ($children) {
  3208 $queue = array_merge($queue, $children);
  3209 }
  3210 }
  3211 $results = $queue;
  3212 $table = array_merge($rows, $table);
  3213 } while (!empty($results));
  3214 
  3215 $this->renderTable($table, $output);
  3216 }
  3217 
  3218 
  3219 
  3220 
  3221 
  3222 
  3223 protected function initStyles(OutputInterface $output)
  3224 {
  3225 $this->colors = array(
  3226 'green',
  3227 'yellow',
  3228 'cyan',
  3229 'magenta',
  3230 'blue',
  3231 );
  3232 
  3233 foreach ($this->colors as $color) {
  3234 $style = new OutputFormatterStyle($color);
  3235 $output->getFormatter()->setStyle($color, $style);
  3236 }
  3237 }
  3238 
  3239 
  3240 
  3241 
  3242 
  3243 
  3244 
  3245 
  3246 
  3247 
  3248 protected function printTree($results, $prefix = '', $level = 1)
  3249 {
  3250 $count = count($results);
  3251 $idx = 0;
  3252 foreach ($results as $result) {
  3253 list($package, $link, $children) = $result;
  3254 
  3255 $color = $this->colors[$level % count($this->colors)];
  3256 $prevColor = $this->colors[($level - 1) % count($this->colors)];
  3257 $isLast = (++$idx == $count);
  3258 $versionText = $package->getPrettyVersion() === RootPackage::DEFAULT_PRETTY_VERSION ? '' : $package->getPrettyVersion();
  3259 $packageText = rtrim(sprintf('<%s>%s</%1$s> %s', $color, $package->getPrettyName(), $versionText));
  3260 $linkText = sprintf('%s <%s>%s</%2$s> %s', $link->getDescription(), $prevColor, $link->getTarget(), $link->getPrettyConstraint());
  3261 $circularWarn = $children === false ? '(circular dependency aborted here)' : '';
  3262 $this->writeTreeLine(rtrim(sprintf("%s%s%s (%s) %s", $prefix, $isLast ? '└──' : '├──', $packageText, $linkText, $circularWarn)));
  3263 if ($children) {
  3264 $this->printTree($children, $prefix . ($isLast ? '   ' : '│  '), $level + 1);
  3265 }
  3266 }
  3267 }
  3268 
  3269 
  3270 
  3271 
  3272 
  3273 
  3274 private function writeTreeLine($line)
  3275 {
  3276 $io = $this->getIO();
  3277 if (!$io->isDecorated()) {
  3278 $line = str_replace(array('└', '├', '──', '│'), array('`-', '|-', '-', '|'), $line);
  3279 }
  3280 
  3281 $io->write($line);
  3282 }
  3283 }
  3284 <?php
  3285 
  3286 
  3287 
  3288 
  3289 
  3290 
  3291 
  3292 
  3293 
  3294 
  3295 
  3296 namespace Composer\Command;
  3297 
  3298 use Composer\Package\Link;
  3299 use Composer\Semver\Constraint\Constraint;
  3300 use Symfony\Component\Console\Input\InputInterface;
  3301 use Symfony\Component\Console\Input\InputOption;
  3302 use Symfony\Component\Console\Output\OutputInterface;
  3303 use Composer\Repository\PlatformRepository;
  3304 use Composer\Repository\RootPackageRepository;
  3305 use Composer\Repository\InstalledRepository;
  3306 
  3307 class CheckPlatformReqsCommand extends BaseCommand
  3308 {
  3309 
  3310 
  3311 
  3312 protected function configure()
  3313 {
  3314 $this->setName('check-platform-reqs')
  3315 ->setDescription('Check that platform requirements are satisfied.')
  3316 ->setDefinition(array(
  3317 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables checking of require-dev packages requirements.'),
  3318 new InputOption('lock', null, InputOption::VALUE_NONE, 'Checks requirements only from the lock file, not from installed packages.'),
  3319 ))
  3320 ->setHelp(
  3321 <<<EOT
  3322 Checks that your PHP and extensions versions match the platform requirements of the installed packages.
  3323 
  3324 Unlike update/install, this command will ignore config.platform settings and check the real platform packages so you can be certain you have the required platform dependencies.
  3325 
  3326 <info>php composer.phar check-platform-reqs</info>
  3327 
  3328 EOT
  3329 );
  3330 }
  3331 
  3332 
  3333 
  3334 
  3335 protected function execute(InputInterface $input, OutputInterface $output)
  3336 {
  3337 $composer = $this->getComposer();
  3338 
  3339 $requires = array();
  3340 $removePackages = array();
  3341 if ($input->getOption('lock')) {
  3342 $this->getIO()->writeError('<info>Checking '.($input->getOption('no-dev') ? 'non-dev ' : '').'platform requirements using the lock file</info>');
  3343 $installedRepo = $composer->getLocker()->getLockedRepository(!$input->getOption('no-dev'));
  3344 } else {
  3345 $installedRepo = $composer->getRepositoryManager()->getLocalRepository();
  3346 
  3347 if (!$installedRepo->getPackages()) {
  3348 $this->getIO()->writeError('<warning>No vendor dir present, checking '.($input->getOption('no-dev') ? 'non-dev ' : '').'platform requirements from the lock file</warning>');
  3349 $installedRepo = $composer->getLocker()->getLockedRepository(!$input->getOption('no-dev'));
  3350 } else {
  3351 if ($input->getOption('no-dev')) {
  3352 $removePackages = $installedRepo->getDevPackageNames();
  3353 }
  3354 
  3355 $this->getIO()->writeError('<info>Checking '.($input->getOption('no-dev') ? 'non-dev ' : '').'platform requirements for packages in the vendor dir</info>');
  3356 }
  3357 }
  3358 if (!$input->getOption('no-dev')) {
  3359 $requires += $composer->getPackage()->getDevRequires();
  3360 }
  3361 
  3362 foreach ($requires as $require => $link) {
  3363 $requires[$require] = array($link);
  3364 }
  3365 
  3366 $installedRepo = new InstalledRepository(array($installedRepo, new RootPackageRepository($composer->getPackage())));
  3367 foreach ($installedRepo->getPackages() as $package) {
  3368 if (in_array($package->getName(), $removePackages, true)) {
  3369 continue;
  3370 }
  3371 foreach ($package->getRequires() as $require => $link) {
  3372 $requires[$require][] = $link;
  3373 }
  3374 }
  3375 
  3376 ksort($requires);
  3377 
  3378 $installedRepo->addRepository(new PlatformRepository(array(), array()));
  3379 
  3380 $results = array();
  3381 $exitCode = 0;
  3382 
  3383 
  3384 
  3385 
  3386 foreach ($requires as $require => $links) {
  3387 if (PlatformRepository::isPlatformPackage($require)) {
  3388 $candidates = $installedRepo->findPackagesWithReplacersAndProviders($require);
  3389 if ($candidates) {
  3390 $reqResults = array();
  3391 foreach ($candidates as $candidate) {
  3392 $candidateConstraint = null;
  3393 if ($candidate->getName() === $require) {
  3394 $candidateConstraint = new Constraint('=', $candidate->getVersion());
  3395 $candidateConstraint->setPrettyString($candidate->getPrettyVersion());
  3396 } else {
  3397 foreach (array_merge($candidate->getProvides(), $candidate->getReplaces()) as $link) {
  3398 if ($link->getTarget() === $require) {
  3399 $candidateConstraint = $link->getConstraint();
  3400 break;
  3401 }
  3402 }
  3403 }
  3404 
  3405 
  3406 if (!$candidateConstraint) {
  3407 continue;
  3408 }
  3409 
  3410 foreach ($links as $link) {
  3411 if (!$link->getConstraint()->matches($candidateConstraint)) {
  3412 $reqResults[] = array(
  3413 $candidate->getName() === $require ? $candidate->getPrettyName() : $require,
  3414 $candidateConstraint->getPrettyString(),
  3415 $link,
  3416 '<error>failed</error>'.($candidate->getName() === $require ? '' : ' <comment>provided by '.$candidate->getPrettyName().'</comment>'),
  3417 );
  3418 
  3419 
  3420 continue 2;
  3421 }
  3422 }
  3423 
  3424 $results[] = array(
  3425 $candidate->getName() === $require ? $candidate->getPrettyName() : $require,
  3426 $candidateConstraint->getPrettyString(),
  3427 null,
  3428 '<info>success</info>'.($candidate->getName() === $require ? '' : ' <comment>provided by '.$candidate->getPrettyName().'</comment>'),
  3429 );
  3430 
  3431 
  3432 continue 2;
  3433 }
  3434 
  3435 
  3436 $results = array_merge($results, $reqResults);
  3437 $exitCode = max($exitCode, 1);
  3438 
  3439 continue;
  3440 }
  3441 
  3442 $results[] = array(
  3443 $require,
  3444 'n/a',
  3445 $links[0],
  3446 '<error>missing</error>',
  3447 );
  3448 
  3449 $exitCode = max($exitCode, 2);
  3450 }
  3451 }
  3452 
  3453 $this->printTable($output, $results);
  3454 
  3455 return $exitCode;
  3456 }
  3457 
  3458 
  3459 
  3460 
  3461 
  3462 
  3463 protected function printTable(OutputInterface $output, $results)
  3464 {
  3465 $rows = array();
  3466 foreach ($results as $result) {
  3467 
  3468 
  3469 
  3470 list($platformPackage, $version, $link, $status) = $result;
  3471 $rows[] = array(
  3472 $platformPackage,
  3473 $version,
  3474 $link ? sprintf('%s %s %s (%s)', $link->getSource(), $link->getDescription(), $link->getTarget(), $link->getPrettyConstraint()) : '',
  3475 $status,
  3476 );
  3477 }
  3478 
  3479 $this->renderTable($rows, $output);
  3480 }
  3481 }
  3482 <?php
  3483 
  3484 
  3485 
  3486 
  3487 
  3488 
  3489 
  3490 
  3491 
  3492 
  3493 
  3494 namespace Composer\Command;
  3495 
  3496 use Composer\Cache;
  3497 use Composer\Factory;
  3498 use Symfony\Component\Console\Input\InputInterface;
  3499 use Symfony\Component\Console\Output\OutputInterface;
  3500 
  3501 
  3502 
  3503 
  3504 class ClearCacheCommand extends BaseCommand
  3505 {
  3506 
  3507 
  3508 
  3509 protected function configure()
  3510 {
  3511 $this
  3512 ->setName('clear-cache')
  3513 ->setAliases(array('clearcache', 'cc'))
  3514 ->setDescription('Clears composer\'s internal package cache.')
  3515 ->setHelp(
  3516 <<<EOT
  3517 The <info>clear-cache</info> deletes all cached packages from composer's
  3518 cache directory.
  3519 
  3520 Read more at https://getcomposer.org/doc/03-cli.md#clear-cache-clearcache-cc
  3521 EOT
  3522 )
  3523 ;
  3524 }
  3525 
  3526 
  3527 
  3528 
  3529 protected function execute(InputInterface $input, OutputInterface $output)
  3530 {
  3531 $config = Factory::createConfig();
  3532 $io = $this->getIO();
  3533 
  3534 $cachePaths = array(
  3535 'cache-vcs-dir' => $config->get('cache-vcs-dir'),
  3536 'cache-repo-dir' => $config->get('cache-repo-dir'),
  3537 'cache-files-dir' => $config->get('cache-files-dir'),
  3538 'cache-dir' => $config->get('cache-dir'),
  3539 );
  3540 
  3541 foreach ($cachePaths as $key => $cachePath) {
  3542 $cachePath = realpath($cachePath);
  3543 if (!$cachePath) {
  3544 $io->writeError("<info>Cache directory does not exist ($key): $cachePath</info>");
  3545 
  3546 continue;
  3547 }
  3548 $cache = new Cache($io, $cachePath);
  3549 $cache->setReadOnly($config->get('cache-read-only'));
  3550 if (!$cache->isEnabled()) {
  3551 $io->writeError("<info>Cache is not enabled ($key): $cachePath</info>");
  3552 
  3553 continue;
  3554 }
  3555 
  3556 $io->writeError("<info>Clearing cache ($key): $cachePath</info>");
  3557 $cache->clear();
  3558 }
  3559 
  3560 $io->writeError('<info>All caches cleared.</info>');
  3561 
  3562 return 0;
  3563 }
  3564 }
  3565 <?php
  3566 
  3567 
  3568 
  3569 
  3570 
  3571 
  3572 
  3573 
  3574 
  3575 
  3576 
  3577 namespace Composer\Command;
  3578 
  3579 use Composer\Pcre\Preg;
  3580 use Composer\Util\Filesystem;
  3581 use Composer\Util\Platform;
  3582 use Composer\Util\Silencer;
  3583 use Symfony\Component\Console\Input\InputInterface;
  3584 use Symfony\Component\Console\Input\InputArgument;
  3585 use Symfony\Component\Console\Input\InputOption;
  3586 use Symfony\Component\Console\Output\OutputInterface;
  3587 use Composer\Config;
  3588 use Composer\Config\JsonConfigSource;
  3589 use Composer\Factory;
  3590 use Composer\IO\IOInterface;
  3591 use Composer\Json\JsonFile;
  3592 use Composer\Semver\VersionParser;
  3593 use Composer\Package\BasePackage;
  3594 
  3595 
  3596 
  3597 
  3598 
  3599 class ConfigCommand extends BaseCommand
  3600 {
  3601 
  3602 
  3603 
  3604 protected $config;
  3605 
  3606 
  3607 
  3608 
  3609 protected $configFile;
  3610 
  3611 
  3612 
  3613 
  3614 protected $configSource;
  3615 
  3616 
  3617 
  3618 
  3619 protected $authConfigFile;
  3620 
  3621 
  3622 
  3623 
  3624 protected $authConfigSource;
  3625 
  3626 
  3627 
  3628 
  3629 protected function configure()
  3630 {
  3631 $this
  3632 ->setName('config')
  3633 ->setDescription('Sets config options.')
  3634 ->setDefinition(array(
  3635 new InputOption('global', 'g', InputOption::VALUE_NONE, 'Apply command to the global config file'),
  3636 new InputOption('editor', 'e', InputOption::VALUE_NONE, 'Open editor'),
  3637 new InputOption('auth', 'a', InputOption::VALUE_NONE, 'Affect auth config file (only used for --editor)'),
  3638 new InputOption('unset', null, InputOption::VALUE_NONE, 'Unset the given setting-key'),
  3639 new InputOption('list', 'l', InputOption::VALUE_NONE, 'List configuration settings'),
  3640 new InputOption('file', 'f', InputOption::VALUE_REQUIRED, 'If you want to choose a different composer.json or config.json'),
  3641 new InputOption('absolute', null, InputOption::VALUE_NONE, 'Returns absolute paths when fetching *-dir config values instead of relative'),
  3642 new InputOption('json', 'j', InputOption::VALUE_NONE, 'JSON decode the setting value, to be used with extra.* keys'),
  3643 new InputOption('merge', 'm', InputOption::VALUE_NONE, 'Merge the setting value with the current value, to be used with extra.* keys in combination with --json'),
  3644 new InputOption('append', null, InputOption::VALUE_NONE, 'When adding a repository, append it (lowest priority) to the existing ones instead of prepending it (highest priority)'),
  3645 new InputOption('source', null, InputOption::VALUE_NONE, 'Display where the config value is loaded from'),
  3646 new InputArgument('setting-key', null, 'Setting key'),
  3647 new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'),
  3648 ))
  3649 ->setHelp(
  3650 <<<EOT
  3651 This command allows you to edit composer config settings and repositories
  3652 in either the local composer.json file or the global config.json file.
  3653 
  3654 Additionally it lets you edit most properties in the local composer.json.
  3655 
  3656 To set a config setting:
  3657 
  3658     <comment>%command.full_name% bin-dir bin/</comment>
  3659 
  3660 To read a config setting:
  3661 
  3662     <comment>%command.full_name% bin-dir</comment>
  3663     Outputs: <info>bin</info>
  3664 
  3665 To edit the global config.json file:
  3666 
  3667     <comment>%command.full_name% --global</comment>
  3668 
  3669 To add a repository:
  3670 
  3671     <comment>%command.full_name% repositories.foo vcs https://bar.com</comment>
  3672 
  3673 To remove a repository (repo is a short alias for repositories):
  3674 
  3675     <comment>%command.full_name% --unset repo.foo</comment>
  3676 
  3677 To disable packagist:
  3678 
  3679     <comment>%command.full_name% repo.packagist false</comment>
  3680 
  3681 You can alter repositories in the global config.json file by passing in the
  3682 <info>--global</info> option.
  3683 
  3684 To add or edit suggested packages you can use:
  3685 
  3686     <comment>%command.full_name% suggest.package reason for the suggestion</comment>
  3687 
  3688 To add or edit extra properties you can use:
  3689 
  3690     <comment>%command.full_name% extra.property value</comment>
  3691 
  3692 Or to add a complex value you can use json with:
  3693 
  3694     <comment>%command.full_name% extra.property --json '{"foo":true, "bar": []}'</comment>
  3695 
  3696 To edit the file in an external editor:
  3697 
  3698     <comment>%command.full_name% --editor</comment>
  3699 
  3700 To choose your editor you can set the "EDITOR" env variable.
  3701 
  3702 To get a list of configuration values in the file:
  3703 
  3704     <comment>%command.full_name% --list</comment>
  3705 
  3706 You can always pass more than one option. As an example, if you want to edit the
  3707 global config.json file.
  3708 
  3709     <comment>%command.full_name% --editor --global</comment>
  3710 
  3711 Read more at https://getcomposer.org/doc/03-cli.md#config
  3712 EOT
  3713 )
  3714 ;
  3715 }
  3716 
  3717 
  3718 
  3719 
  3720 
  3721 protected function initialize(InputInterface $input, OutputInterface $output)
  3722 {
  3723 parent::initialize($input, $output);
  3724 
  3725 if ($input->getOption('global') && null !== $input->getOption('file')) {
  3726 throw new \RuntimeException('--file and --global can not be combined');
  3727 }
  3728 
  3729 $io = $this->getIO();
  3730 $this->config = Factory::createConfig($io);
  3731 
  3732 
  3733 
  3734 $configFile = $input->getOption('global')
  3735 ? ($this->config->get('home') . '/config.json')
  3736 : ($input->getOption('file') ?: Factory::getComposerFile());
  3737 
  3738 
  3739 if (
  3740 ($configFile === 'composer.json' || $configFile === './composer.json')
  3741 && !file_exists($configFile)
  3742 && realpath(getcwd()) === realpath($this->config->get('home'))
  3743 ) {
  3744 file_put_contents($configFile, "{\n}\n");
  3745 }
  3746 
  3747 $this->configFile = new JsonFile($configFile, null, $io);
  3748 $this->configSource = new JsonConfigSource($this->configFile);
  3749 
  3750 $authConfigFile = $input->getOption('global')
  3751 ? ($this->config->get('home') . '/auth.json')
  3752 : dirname(realpath($configFile)) . '/auth.json';
  3753 
  3754 $this->authConfigFile = new JsonFile($authConfigFile, null, $io);
  3755 $this->authConfigSource = new JsonConfigSource($this->authConfigFile, true);
  3756 
  3757 
  3758 if ($input->getOption('global') && !$this->configFile->exists()) {
  3759 touch($this->configFile->getPath());
  3760 $this->configFile->write(array('config' => new \ArrayObject));
  3761 Silencer::call('chmod', $this->configFile->getPath(), 0600);
  3762 }
  3763 if ($input->getOption('global') && !$this->authConfigFile->exists()) {
  3764 touch($this->authConfigFile->getPath());
  3765 $this->authConfigFile->write(array('bitbucket-oauth' => new \ArrayObject, 'github-oauth' => new \ArrayObject, 'gitlab-oauth' => new \ArrayObject, 'gitlab-token' => new \ArrayObject, 'http-basic' => new \ArrayObject, 'bearer' => new \ArrayObject));
  3766 Silencer::call('chmod', $this->authConfigFile->getPath(), 0600);
  3767 }
  3768 
  3769 if (!$this->configFile->exists()) {
  3770 throw new \RuntimeException(sprintf('File "%s" cannot be found in the current directory', $configFile));
  3771 }
  3772 }
  3773 
  3774 
  3775 
  3776 
  3777 
  3778 protected function execute(InputInterface $input, OutputInterface $output)
  3779 {
  3780 
  3781 if (true === $input->getOption('editor')) {
  3782 $editor = escapeshellcmd(Platform::getEnv('EDITOR'));
  3783 if (!$editor) {
  3784 if (Platform::isWindows()) {
  3785 $editor = 'notepad';
  3786 } else {
  3787 foreach (array('editor', 'vim', 'vi', 'nano', 'pico', 'ed') as $candidate) {
  3788 if (exec('which '.$candidate)) {
  3789 $editor = $candidate;
  3790 break;
  3791 }
  3792 }
  3793 }
  3794 }
  3795 
  3796 $file = $input->getOption('auth') ? $this->authConfigFile->getPath() : $this->configFile->getPath();
  3797 system($editor . ' ' . $file . (Platform::isWindows() ? '' : ' > `tty`'));
  3798 
  3799 return 0;
  3800 }
  3801 
  3802 if (false === $input->getOption('global')) {
  3803 $this->config->merge($this->configFile->read(), $this->configFile->getPath());
  3804 $this->config->merge(array('config' => $this->authConfigFile->exists() ? $this->authConfigFile->read() : array()), $this->authConfigFile->getPath());
  3805 }
  3806 
  3807 
  3808 if (true === $input->getOption('list')) {
  3809 $this->listConfiguration($this->config->all(), $this->config->raw(), $output, null, (bool) $input->getOption('source'));
  3810 
  3811 return 0;
  3812 }
  3813 
  3814 $settingKey = $input->getArgument('setting-key');
  3815 if (!is_string($settingKey)) {
  3816 return 0;
  3817 }
  3818 
  3819 
  3820 if (array() !== $input->getArgument('setting-value') && $input->getOption('unset')) {
  3821 throw new \RuntimeException('You can not combine a setting value with --unset');
  3822 }
  3823 
  3824 
  3825 if (array() === $input->getArgument('setting-value') && !$input->getOption('unset')) {
  3826 $properties = array('name', 'type', 'description', 'homepage', 'version', 'minimum-stability', 'prefer-stable', 'keywords', 'license', 'extra');
  3827 $rawData = $this->configFile->read();
  3828 $data = $this->config->all();
  3829 if (Preg::isMatch('/^repos?(?:itories)?(?:\.(.+))?/', $settingKey, $matches)) {
  3830 if (!isset($matches[1]) || $matches[1] === '') {
  3831 $value = isset($data['repositories']) ? $data['repositories'] : array();
  3832 } else {
  3833 if (!isset($data['repositories'][$matches[1]])) {
  3834 throw new \InvalidArgumentException('There is no '.$matches[1].' repository defined');
  3835 }
  3836 
  3837 $value = $data['repositories'][$matches[1]];
  3838 }
  3839 } elseif (strpos($settingKey, '.')) {
  3840 $bits = explode('.', $settingKey);
  3841 if ($bits[0] === 'extra') {
  3842 $data = $rawData;
  3843 } else {
  3844 $data = $data['config'];
  3845 }
  3846 $match = false;
  3847 foreach ($bits as $bit) {
  3848 $key = isset($key) ? $key.'.'.$bit : $bit;
  3849 $match = false;
  3850 if (isset($data[$key])) {
  3851 $match = true;
  3852 $data = $data[$key];
  3853 unset($key);
  3854 }
  3855 }
  3856 
  3857 if (!$match) {
  3858 throw new \RuntimeException($settingKey.' is not defined.');
  3859 }
  3860 
  3861 $value = $data;
  3862 } elseif (isset($data['config'][$settingKey])) {
  3863 $value = $this->config->get($settingKey, $input->getOption('absolute') ? 0 : Config::RELATIVE_PATHS);
  3864 } elseif (isset($rawData[$settingKey]) && in_array($settingKey, $properties, true)) {
  3865 $value = $rawData[$settingKey];
  3866 } else {
  3867 throw new \RuntimeException($settingKey.' is not defined');
  3868 }
  3869 
  3870 if (is_array($value)) {
  3871 $value = json_encode($value);
  3872 }
  3873 
  3874 $sourceOfConfigValue = '';
  3875 if ($input->getOption('source')) {
  3876 $sourceOfConfigValue = ' (' . $this->config->getSourceOfValue($settingKey) . ')';
  3877 }
  3878 
  3879 $this->getIO()->write($value . $sourceOfConfigValue, true, IOInterface::QUIET);
  3880 
  3881 return 0;
  3882 }
  3883 
  3884 $values = $input->getArgument('setting-value'); 
  3885 
  3886 $booleanValidator = function ($val) {
  3887 return in_array($val, array('true', 'false', '1', '0'), true);
  3888 };
  3889 $booleanNormalizer = function ($val) {
  3890 return $val !== 'false' && (bool) $val;
  3891 };
  3892 
  3893 
  3894 $uniqueConfigValues = array(
  3895 'process-timeout' => array('is_numeric', 'intval'),
  3896 'use-include-path' => array($booleanValidator, $booleanNormalizer),
  3897 'use-github-api' => array($booleanValidator, $booleanNormalizer),
  3898 'preferred-install' => array(
  3899 function ($val) {
  3900 return in_array($val, array('auto', 'source', 'dist'), true);
  3901 },
  3902 function ($val) {
  3903 return $val;
  3904 },
  3905 ),
  3906 'gitlab-protocol' => array(
  3907 function ($val) {
  3908 return in_array($val, array('git', 'http', 'https'), true);
  3909 },
  3910 function ($val) {
  3911 return $val;
  3912 },
  3913 ),
  3914 'store-auths' => array(
  3915 function ($val) {
  3916 return in_array($val, array('true', 'false', 'prompt'), true);
  3917 },
  3918 function ($val) {
  3919 if ('prompt' === $val) {
  3920 return 'prompt';
  3921 }
  3922 
  3923 return $val !== 'false' && (bool) $val;
  3924 },
  3925 ),
  3926 'notify-on-install' => array($booleanValidator, $booleanNormalizer),
  3927 'vendor-dir' => array('is_string', function ($val) {
  3928 return $val;
  3929 }),
  3930 'bin-dir' => array('is_string', function ($val) {
  3931 return $val;
  3932 }),
  3933 'archive-dir' => array('is_string', function ($val) {
  3934 return $val;
  3935 }),
  3936 'archive-format' => array('is_string', function ($val) {
  3937 return $val;
  3938 }),
  3939 'data-dir' => array('is_string', function ($val) {
  3940 return $val;
  3941 }),
  3942 'cache-dir' => array('is_string', function ($val) {
  3943 return $val;
  3944 }),
  3945 'cache-files-dir' => array('is_string', function ($val) {
  3946 return $val;
  3947 }),
  3948 'cache-repo-dir' => array('is_string', function ($val) {
  3949 return $val;
  3950 }),
  3951 'cache-vcs-dir' => array('is_string', function ($val) {
  3952 return $val;
  3953 }),
  3954 'cache-ttl' => array('is_numeric', 'intval'),
  3955 'cache-files-ttl' => array('is_numeric', 'intval'),
  3956 'cache-files-maxsize' => array(
  3957 function ($val) {
  3958 return Preg::isMatch('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $val);
  3959 },
  3960 function ($val) {
  3961 return $val;
  3962 },
  3963 ),
  3964 'bin-compat' => array(
  3965 function ($val) {
  3966 return in_array($val, array('auto', 'full', 'symlink'));
  3967 },
  3968 function ($val) {
  3969 return $val;
  3970 },
  3971 ),
  3972 'discard-changes' => array(
  3973 function ($val) {
  3974 return in_array($val, array('stash', 'true', 'false', '1', '0'), true);
  3975 },
  3976 function ($val) {
  3977 if ('stash' === $val) {
  3978 return 'stash';
  3979 }
  3980 
  3981 return $val !== 'false' && (bool) $val;
  3982 },
  3983 ),
  3984 'autoloader-suffix' => array('is_string', function ($val) {
  3985 return $val === 'null' ? null : $val;
  3986 }),
  3987 'sort-packages' => array($booleanValidator, $booleanNormalizer),
  3988 'optimize-autoloader' => array($booleanValidator, $booleanNormalizer),
  3989 'classmap-authoritative' => array($booleanValidator, $booleanNormalizer),
  3990 'apcu-autoloader' => array($booleanValidator, $booleanNormalizer),
  3991 'prepend-autoloader' => array($booleanValidator, $booleanNormalizer),
  3992 'disable-tls' => array($booleanValidator, $booleanNormalizer),
  3993 'secure-http' => array($booleanValidator, $booleanNormalizer),
  3994 'cafile' => array(
  3995 function ($val) {
  3996 return file_exists($val) && Filesystem::isReadable($val);
  3997 },
  3998 function ($val) {
  3999 return $val === 'null' ? null : $val;
  4000 },
  4001 ),
  4002 'capath' => array(
  4003 function ($val) {
  4004 return is_dir($val) && Filesystem::isReadable($val);
  4005 },
  4006 function ($val) {
  4007 return $val === 'null' ? null : $val;
  4008 },
  4009 ),
  4010 'github-expose-hostname' => array($booleanValidator, $booleanNormalizer),
  4011 'htaccess-protect' => array($booleanValidator, $booleanNormalizer),
  4012 'lock' => array($booleanValidator, $booleanNormalizer),
  4013 'allow-plugins' => array($booleanValidator, $booleanNormalizer),
  4014 'platform-check' => array(
  4015 function ($val) {
  4016 return in_array($val, array('php-only', 'true', 'false', '1', '0'), true);
  4017 },
  4018 function ($val) {
  4019 if ('php-only' === $val) {
  4020 return 'php-only';
  4021 }
  4022 
  4023 return $val !== 'false' && (bool)$val;
  4024 },
  4025 ),
  4026 'use-parent-dir' => array(
  4027 function ($val) {
  4028 return in_array($val, array('true', 'false', 'prompt'), true);
  4029 },
  4030 function ($val) {
  4031 if ('prompt' === $val) {
  4032 return 'prompt';
  4033 }
  4034 
  4035 return $val !== 'false' && (bool) $val;
  4036 },
  4037 ),
  4038 );
  4039 $multiConfigValues = array(
  4040 'github-protocols' => array(
  4041 function ($vals) {
  4042 if (!is_array($vals)) {
  4043 return 'array expected';
  4044 }
  4045 
  4046 foreach ($vals as $val) {
  4047 if (!in_array($val, array('git', 'https', 'ssh'))) {
  4048 return 'valid protocols include: git, https, ssh';
  4049 }
  4050 }
  4051 
  4052 return true;
  4053 },
  4054 function ($vals) {
  4055 return $vals;
  4056 },
  4057 ),
  4058 'github-domains' => array(
  4059 function ($vals) {
  4060 if (!is_array($vals)) {
  4061 return 'array expected';
  4062 }
  4063 
  4064 return true;
  4065 },
  4066 function ($vals) {
  4067 return $vals;
  4068 },
  4069 ),
  4070 'gitlab-domains' => array(
  4071 function ($vals) {
  4072 if (!is_array($vals)) {
  4073 return 'array expected';
  4074 }
  4075 
  4076 return true;
  4077 },
  4078 function ($vals) {
  4079 return $vals;
  4080 },
  4081 ),
  4082 );
  4083 
  4084 if ($input->getOption('unset') && (isset($uniqueConfigValues[$settingKey]) || isset($multiConfigValues[$settingKey]))) {
  4085 if ($settingKey === 'disable-tls' && $this->config->get('disable-tls')) {
  4086 $this->getIO()->writeError('<info>You are now running Composer with SSL/TLS protection enabled.</info>');
  4087 }
  4088 
  4089 $this->configSource->removeConfigSetting($settingKey);
  4090 
  4091 return 0;
  4092 }
  4093 if (isset($uniqueConfigValues[$settingKey])) {
  4094 $this->handleSingleValue($settingKey, $uniqueConfigValues[$settingKey], $values, 'addConfigSetting');
  4095 
  4096 return 0;
  4097 }
  4098 if (isset($multiConfigValues[$settingKey])) {
  4099 $this->handleMultiValue($settingKey, $multiConfigValues[$settingKey], $values, 'addConfigSetting');
  4100 
  4101 return 0;
  4102 }
  4103 
  4104 if (Preg::isMatch('/^preferred-install\.(.+)/', $settingKey, $matches)) {
  4105 if ($input->getOption('unset')) {
  4106 $this->configSource->removeConfigSetting($settingKey);
  4107 
  4108 return 0;
  4109 }
  4110 
  4111 list($validator) = $uniqueConfigValues['preferred-install'];
  4112 if (!$validator($values[0])) {
  4113 throw new \RuntimeException('Invalid value for '.$settingKey.'. Should be one of: auto, source, or dist');
  4114 }
  4115 
  4116 $this->configSource->addConfigSetting($settingKey, $values[0]);
  4117 
  4118 return 0;
  4119 }
  4120 
  4121 
  4122 if (Preg::isMatch('{^allow-plugins\.([a-zA-Z0-9/*-]+)}', $settingKey, $matches)) {
  4123 if ($input->getOption('unset')) {
  4124 $this->configSource->removeConfigSetting($settingKey);
  4125 
  4126 return 0;
  4127 }
  4128 
  4129 if (true !== $booleanValidator($values[0])) {
  4130 throw new \RuntimeException(sprintf(
  4131 '"%s" is an invalid value',
  4132 $values[0]
  4133 ));
  4134 }
  4135 
  4136 $normalizedValue = $booleanNormalizer($values[0]);
  4137 
  4138 $this->configSource->addConfigSetting($settingKey, $normalizedValue);
  4139 
  4140 return 0;
  4141 }
  4142 
  4143 
  4144 $uniqueProps = array(
  4145 'name' => array('is_string', function ($val) {
  4146 return $val;
  4147 }),
  4148 'type' => array('is_string', function ($val) {
  4149 return $val;
  4150 }),
  4151 'description' => array('is_string', function ($val) {
  4152 return $val;
  4153 }),
  4154 'homepage' => array('is_string', function ($val) {
  4155 return $val;
  4156 }),
  4157 'version' => array('is_string', function ($val) {
  4158 return $val;
  4159 }),
  4160 'minimum-stability' => array(
  4161 function ($val) {
  4162 return isset(BasePackage::$stabilities[VersionParser::normalizeStability($val)]);
  4163 },
  4164 function ($val) {
  4165 return VersionParser::normalizeStability($val);
  4166 },
  4167 ),
  4168 'prefer-stable' => array($booleanValidator, $booleanNormalizer),
  4169 );
  4170 $multiProps = array(
  4171 'keywords' => array(
  4172 function ($vals) {
  4173 if (!is_array($vals)) {
  4174 return 'array expected';
  4175 }
  4176 
  4177 return true;
  4178 },
  4179 function ($vals) {
  4180 return $vals;
  4181 },
  4182 ),
  4183 'license' => array(
  4184 function ($vals) {
  4185 if (!is_array($vals)) {
  4186 return 'array expected';
  4187 }
  4188 
  4189 return true;
  4190 },
  4191 function ($vals) {
  4192 return $vals;
  4193 },
  4194 ),
  4195 );
  4196 
  4197 if ($input->getOption('global') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]) || strpos($settingKey, 'extra.') === 0)) {
  4198 throw new \InvalidArgumentException('The ' . $settingKey . ' property can not be set in the global config.json file. Use `composer global config` to apply changes to the global composer.json');
  4199 }
  4200 if ($input->getOption('unset') && (isset($uniqueProps[$settingKey]) || isset($multiProps[$settingKey]))) {
  4201 $this->configSource->removeProperty($settingKey);
  4202 
  4203 return 0;
  4204 }
  4205 if (isset($uniqueProps[$settingKey])) {
  4206 $this->handleSingleValue($settingKey, $uniqueProps[$settingKey], $values, 'addProperty');
  4207 
  4208 return 0;
  4209 }
  4210 if (isset($multiProps[$settingKey])) {
  4211 $this->handleMultiValue($settingKey, $multiProps[$settingKey], $values, 'addProperty');
  4212 
  4213 return 0;
  4214 }
  4215 
  4216 
  4217 if (Preg::isMatch('/^repos?(?:itories)?\.(.+)/', $settingKey, $matches)) {
  4218 if ($input->getOption('unset')) {
  4219 $this->configSource->removeRepository($matches[1]);
  4220 
  4221 return 0;
  4222 }
  4223 
  4224 if (2 === count($values)) {
  4225 $this->configSource->addRepository($matches[1], array(
  4226 'type' => $values[0],
  4227 'url' => $values[1],
  4228 ), $input->getOption('append'));
  4229 
  4230 return 0;
  4231 }
  4232 
  4233 if (1 === count($values)) {
  4234 $value = strtolower($values[0]);
  4235 if (true === $booleanValidator($value)) {
  4236 if (false === $booleanNormalizer($value)) {
  4237 $this->configSource->addRepository($matches[1], false, $input->getOption('append'));
  4238 
  4239 return 0;
  4240 }
  4241 } else {
  4242 $value = JsonFile::parseJson($values[0]);
  4243 $this->configSource->addRepository($matches[1], $value, $input->getOption('append'));
  4244 
  4245 return 0;
  4246 }
  4247 }
  4248 
  4249 throw new \RuntimeException('You must pass the type and a url. Example: php composer.phar config repositories.foo vcs https://bar.com');
  4250 }
  4251 
  4252 
  4253 if (Preg::isMatch('/^extra\.(.+)/', $settingKey, $matches)) {
  4254 if ($input->getOption('unset')) {
  4255 $this->configSource->removeProperty($settingKey);
  4256 
  4257 return 0;
  4258 }
  4259 
  4260 $value = $values[0];
  4261 if ($input->getOption('json')) {
  4262 $value = JsonFile::parseJson($value);
  4263 if ($input->getOption('merge')) {
  4264 $currentValue = $this->configFile->read();
  4265 $bits = explode('.', $settingKey);
  4266 foreach ($bits as $bit) {
  4267 $currentValue = isset($currentValue[$bit]) ? $currentValue[$bit] : null;
  4268 }
  4269 if (is_array($currentValue)) {
  4270 $value = array_merge($currentValue, $value);
  4271 }
  4272 }
  4273 }
  4274 $this->configSource->addProperty($settingKey, $value);
  4275 
  4276 return 0;
  4277 }
  4278 
  4279 
  4280 if (Preg::isMatch('/^suggest\.(.+)/', $settingKey, $matches)) {
  4281 if ($input->getOption('unset')) {
  4282 $this->configSource->removeProperty($settingKey);
  4283 
  4284 return 0;
  4285 }
  4286 
  4287 $this->configSource->addProperty($settingKey, implode(' ', $values));
  4288 
  4289 return 0;
  4290 }
  4291 
  4292 
  4293 if (in_array($settingKey, array('suggest', 'extra'), true) && $input->getOption('unset')) {
  4294 $this->configSource->removeProperty($settingKey);
  4295 
  4296 return 0;
  4297 }
  4298 
  4299 
  4300 if (Preg::isMatch('/^platform\.(.+)/', $settingKey, $matches)) {
  4301 if ($input->getOption('unset')) {
  4302 $this->configSource->removeConfigSetting($settingKey);
  4303 
  4304 return 0;
  4305 }
  4306 
  4307 $this->configSource->addConfigSetting($settingKey, $values[0] === 'false' ? false : $values[0]);
  4308 
  4309 return 0;
  4310 }
  4311 
  4312 
  4313 if ($settingKey === 'platform' && $input->getOption('unset')) {
  4314 $this->configSource->removeConfigSetting($settingKey);
  4315 
  4316 return 0;
  4317 }
  4318 
  4319 
  4320 if (Preg::isMatch('/^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|http-basic|bearer)\.(.+)/', $settingKey, $matches)) {
  4321 if ($input->getOption('unset')) {
  4322 $this->authConfigSource->removeConfigSetting($matches[1].'.'.$matches[2]);
  4323 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
  4324 
  4325 return 0;
  4326 }
  4327 
  4328 if ($matches[1] === 'bitbucket-oauth') {
  4329 if (2 !== count($values)) {
  4330 throw new \RuntimeException('Expected two arguments (consumer-key, consumer-secret), got '.count($values));
  4331 }
  4332 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
  4333 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('consumer-key' => $values[0], 'consumer-secret' => $values[1]));
  4334 } elseif ($matches[1] === 'gitlab-token' && 2 === count($values)) {
  4335 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
  4336 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'token' => $values[1]));
  4337 } elseif (in_array($matches[1], array('github-oauth', 'gitlab-oauth', 'gitlab-token', 'bearer'), true)) {
  4338 if (1 !== count($values)) {
  4339 throw new \RuntimeException('Too many arguments, expected only one token');
  4340 }
  4341 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
  4342 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], $values[0]);
  4343 } elseif ($matches[1] === 'http-basic') {
  4344 if (2 !== count($values)) {
  4345 throw new \RuntimeException('Expected two arguments (username, password), got '.count($values));
  4346 }
  4347 $this->configSource->removeConfigSetting($matches[1].'.'.$matches[2]);
  4348 $this->authConfigSource->addConfigSetting($matches[1].'.'.$matches[2], array('username' => $values[0], 'password' => $values[1]));
  4349 }
  4350 
  4351 return 0;
  4352 }
  4353 
  4354 
  4355 if (Preg::isMatch('/^scripts\.(.+)/', $settingKey, $matches)) {
  4356 if ($input->getOption('unset')) {
  4357 $this->configSource->removeProperty($settingKey);
  4358 
  4359 return 0;
  4360 }
  4361 
  4362 $this->configSource->addProperty($settingKey, count($values) > 1 ? $values : $values[0]);
  4363 
  4364 return 0;
  4365 }
  4366 
  4367 throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command');
  4368 }
  4369 
  4370 
  4371 
  4372 
  4373 
  4374 
  4375 
  4376 
  4377 
  4378 protected function handleSingleValue($key, array $callbacks, array $values, $method)
  4379 {
  4380 list($validator, $normalizer) = $callbacks;
  4381 if (1 !== count($values)) {
  4382 throw new \RuntimeException('You can only pass one value. Example: php composer.phar config process-timeout 300');
  4383 }
  4384 
  4385 if (true !== $validation = $validator($values[0])) {
  4386 throw new \RuntimeException(sprintf(
  4387 '"%s" is an invalid value'.($validation ? ' ('.$validation.')' : ''),
  4388 $values[0]
  4389 ));
  4390 }
  4391 
  4392 $normalizedValue = $normalizer($values[0]);
  4393 
  4394 if ($key === 'disable-tls') {
  4395 if (!$normalizedValue && $this->config->get('disable-tls')) {
  4396 $this->getIO()->writeError('<info>You are now running Composer with SSL/TLS protection enabled.</info>');
  4397 } elseif ($normalizedValue && !$this->config->get('disable-tls')) {
  4398 $this->getIO()->writeError('<warning>You are now running Composer with SSL/TLS protection disabled.</warning>');
  4399 }
  4400 }
  4401 
  4402 call_user_func(array($this->configSource, $method), $key, $normalizedValue);
  4403 }
  4404 
  4405 
  4406 
  4407 
  4408 
  4409 
  4410 
  4411 
  4412 
  4413 protected function handleMultiValue($key, array $callbacks, array $values, $method)
  4414 {
  4415 list($validator, $normalizer) = $callbacks;
  4416 if (true !== $validation = $validator($values)) {
  4417 throw new \RuntimeException(sprintf(
  4418 '%s is an invalid value'.($validation ? ' ('.$validation.')' : ''),
  4419 json_encode($values)
  4420 ));
  4421 }
  4422 
  4423 call_user_func(array($this->configSource, $method), $key, $normalizer($values));
  4424 }
  4425 
  4426 
  4427 
  4428 
  4429 
  4430 
  4431 
  4432 
  4433 
  4434 
  4435 
  4436 protected function listConfiguration(array $contents, array $rawContents, OutputInterface $output, $k = null, $showSource = false)
  4437 {
  4438 $origK = $k;
  4439 $io = $this->getIO();
  4440 foreach ($contents as $key => $value) {
  4441 if ($k === null && !in_array($key, array('config', 'repositories'))) {
  4442 continue;
  4443 }
  4444 
  4445 $rawVal = isset($rawContents[$key]) ? $rawContents[$key] : null;
  4446 
  4447 if (is_array($value) && (!is_numeric(key($value)) || ($key === 'repositories' && null === $k))) {
  4448 $k .= Preg::replace('{^config\.}', '', $key . '.');
  4449 $this->listConfiguration($value, $rawVal, $output, $k, $showSource);
  4450 $k = $origK;
  4451 
  4452 continue;
  4453 }
  4454 
  4455 if (is_array($value)) {
  4456 $value = array_map(function ($val) {
  4457 return is_array($val) ? json_encode($val) : $val;
  4458 }, $value);
  4459 
  4460 $value = '['.implode(', ', $value).']';
  4461 }
  4462 
  4463 if (is_bool($value)) {
  4464 $value = var_export($value, true);
  4465 }
  4466 
  4467 $source = '';
  4468 if ($showSource) {
  4469 $source = ' (' . $this->config->getSourceOfValue($k . $key) . ')';
  4470 }
  4471 if (is_string($rawVal) && $rawVal != $value) {
  4472 $io->write('[<comment>' . $k . $key . '</comment>] <info>' . $rawVal . ' (' . $value . ')</info>' . $source, true, IOInterface::QUIET);
  4473 } else {
  4474 $io->write('[<comment>' . $k . $key . '</comment>] <info>' . $value . '</info>' . $source, true, IOInterface::QUIET);
  4475 }
  4476 }
  4477 }
  4478 }
  4479 <?php
  4480 
  4481 
  4482 
  4483 
  4484 
  4485 
  4486 
  4487 
  4488 
  4489 
  4490 
  4491 namespace Composer\Command;
  4492 
  4493 use Composer\Config;
  4494 use Composer\Factory;
  4495 use Composer\Filter\PlatformRequirementFilter\IgnoreAllPlatformRequirementFilter;
  4496 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  4497 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterInterface;
  4498 use Composer\Installer;
  4499 use Composer\Installer\ProjectInstaller;
  4500 use Composer\Installer\SuggestedPackagesReporter;
  4501 use Composer\IO\IOInterface;
  4502 use Composer\Package\BasePackage;
  4503 use Composer\DependencyResolver\Operation\InstallOperation;
  4504 use Composer\Package\Version\VersionSelector;
  4505 use Composer\Package\AliasPackage;
  4506 use Composer\Pcre\Preg;
  4507 use Composer\Repository\RepositoryFactory;
  4508 use Composer\Repository\CompositeRepository;
  4509 use Composer\Repository\PlatformRepository;
  4510 use Composer\Repository\InstalledArrayRepository;
  4511 use Composer\Repository\RepositorySet;
  4512 use Composer\Script\ScriptEvents;
  4513 use Composer\Util\Silencer;
  4514 use Symfony\Component\Console\Input\InputArgument;
  4515 use Symfony\Component\Console\Input\InputInterface;
  4516 use Symfony\Component\Console\Input\InputOption;
  4517 use Symfony\Component\Console\Output\OutputInterface;
  4518 use Symfony\Component\Finder\Finder;
  4519 use Composer\Json\JsonFile;
  4520 use Composer\Config\JsonConfigSource;
  4521 use Composer\Util\Filesystem;
  4522 use Composer\Util\Platform;
  4523 use Composer\Util\ProcessExecutor;
  4524 use Composer\Package\Version\VersionParser;
  4525 
  4526 
  4527 
  4528 
  4529 
  4530 
  4531 
  4532 
  4533 
  4534 class CreateProjectCommand extends BaseCommand
  4535 {
  4536 
  4537 
  4538 
  4539 protected $suggestedPackagesReporter;
  4540 
  4541 
  4542 
  4543 
  4544 protected function configure()
  4545 {
  4546 $this
  4547 ->setName('create-project')
  4548 ->setDescription('Creates new project from a package into given directory.')
  4549 ->setDefinition(array(
  4550 new InputArgument('package', InputArgument::OPTIONAL, 'Package name to be installed'),
  4551 new InputArgument('directory', InputArgument::OPTIONAL, 'Directory where the files should be created'),
  4552 new InputArgument('version', InputArgument::OPTIONAL, 'Version, will default to latest'),
  4553 new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum-stability allowed (unless a version is specified).'),
  4554 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
  4555 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
  4556 new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'),
  4557 new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories to look the package up, either by URL or using JSON arrays'),
  4558 new InputOption('repository-url', null, InputOption::VALUE_REQUIRED, 'DEPRECATED: Use --repository instead.'),
  4559 new InputOption('add-repository', null, InputOption::VALUE_NONE, 'Add the custom repository in the composer.json. If a lock file is present it will be deleted and an update will be run instead of install.'),
  4560 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables installation of require-dev packages (enabled by default, only present for BC).'),
  4561 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
  4562 new InputOption('no-custom-installers', null, InputOption::VALUE_NONE, 'DEPRECATED: Use no-plugins instead.'),
  4563 new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Whether to prevent execution of all defined scripts in the root package.'),
  4564 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
  4565 new InputOption('no-secure-http', null, InputOption::VALUE_NONE, 'Disable the secure-http config option temporarily while installing the root package. Use at your own risk. Using this flag is a bad idea.'),
  4566 new InputOption('keep-vcs', null, InputOption::VALUE_NONE, 'Whether to prevent deleting the vcs folder.'),
  4567 new InputOption('remove-vcs', null, InputOption::VALUE_NONE, 'Whether to force deletion of the vcs folder without prompting.'),
  4568 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Whether to skip installation of the package dependencies.'),
  4569 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
  4570 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
  4571 new InputOption('ask', null, InputOption::VALUE_NONE, 'Whether to ask for project directory.'),
  4572 ))
  4573 ->setHelp(
  4574 <<<EOT
  4575 The <info>create-project</info> command creates a new project from a given
  4576 package into a new directory. If executed without params and in a directory
  4577 with a composer.json file it installs the packages for the current project.
  4578 
  4579 You can use this command to bootstrap new projects or setup a clean
  4580 version-controlled installation for developers of your project.
  4581 
  4582 <info>php composer.phar create-project vendor/project target-directory [version]</info>
  4583 
  4584 You can also specify the version with the package name using = or : as separator.
  4585 
  4586 <info>php composer.phar create-project vendor/project:version target-directory</info>
  4587 
  4588 To install unstable packages, either specify the version you want, or use the
  4589 --stability=dev (where dev can be one of RC, beta, alpha or dev).
  4590 
  4591 To setup a developer workable version you should create the project using the source
  4592 controlled code by appending the <info>'--prefer-source'</info> flag.
  4593 
  4594 To install a package from another repository than the default one you
  4595 can pass the <info>'--repository=https://myrepository.org'</info> flag.
  4596 
  4597 Read more at https://getcomposer.org/doc/03-cli.md#create-project
  4598 EOT
  4599 )
  4600 ;
  4601 }
  4602 
  4603 
  4604 
  4605 
  4606 protected function execute(InputInterface $input, OutputInterface $output)
  4607 {
  4608 $config = Factory::createConfig();
  4609 $io = $this->getIO();
  4610 
  4611 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input, true);
  4612 
  4613 if ($input->getOption('dev')) {
  4614 $io->writeError('<warning>You are using the deprecated option "dev". Dev packages are installed by default now.</warning>');
  4615 }
  4616 if ($input->getOption('no-custom-installers')) {
  4617 $io->writeError('<warning>You are using the deprecated option "no-custom-installers". Use "no-plugins" instead.</warning>');
  4618 $input->setOption('no-plugins', true);
  4619 }
  4620 
  4621 if ($input->isInteractive() && $input->getOption('ask')) {
  4622 $parts = explode("/", strtolower($input->getArgument('package')), 2);
  4623 $input->setArgument('directory', $io->ask('New project directory [<comment>'.array_pop($parts).'</comment>]: '));
  4624 }
  4625 
  4626 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  4627 
  4628 return $this->installProject(
  4629 $io,
  4630 $config,
  4631 $input,
  4632 $input->getArgument('package'),
  4633 $input->getArgument('directory'),
  4634 $input->getArgument('version'),
  4635 $input->getOption('stability'),
  4636 $preferSource,
  4637 $preferDist,
  4638 !$input->getOption('no-dev'),
  4639 $input->getOption('repository') ?: $input->getOption('repository-url'),
  4640 $input->getOption('no-plugins'),
  4641 $input->getOption('no-scripts'),
  4642 $input->getOption('no-progress'),
  4643 $input->getOption('no-install'),
  4644 PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs),
  4645 !$input->getOption('no-secure-http'),
  4646 $input->getOption('add-repository')
  4647 );
  4648 }
  4649 
  4650 
  4651 
  4652 
  4653 
  4654 
  4655 
  4656 
  4657 
  4658 
  4659 
  4660 
  4661 
  4662 
  4663 
  4664 
  4665 
  4666 
  4667 
  4668 
  4669 public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName = null, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositories = null, $disablePlugins = false, $disableScripts = false, $noProgress = false, $noInstall = false, PlatformRequirementFilterInterface $platformRequirementFilter = null, $secureHttp = true, $addRepository = false)
  4670 {
  4671 $oldCwd = getcwd();
  4672 
  4673 if ($repositories !== null && !is_array($repositories)) {
  4674 $repositories = (array) $repositories;
  4675 }
  4676 
  4677 $platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
  4678 
  4679 
  4680 $io->loadConfiguration($config);
  4681 
  4682 $this->suggestedPackagesReporter = new SuggestedPackagesReporter($io);
  4683 
  4684 if ($packageName !== null) {
  4685 $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $platformRequirementFilter, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositories, $disablePlugins, $disableScripts, $noProgress, $secureHttp);
  4686 } else {
  4687 $installedFromVcs = false;
  4688 }
  4689 
  4690 if ($repositories !== null && $addRepository && is_file('composer.lock')) {
  4691 unlink('composer.lock');
  4692 }
  4693 
  4694 $composer = Factory::create($io, null, $disablePlugins, $disableScripts);
  4695 
  4696 
  4697 if ($repositories !== null && $addRepository) {
  4698 foreach ($repositories as $index => $repo) {
  4699 $repoConfig = RepositoryFactory::configFromString($io, $composer->getConfig(), $repo, true);
  4700 $composerJsonRepositoriesConfig = $composer->getConfig()->getRepositories();
  4701 $name = RepositoryFactory::generateRepositoryName($index, $repoConfig, $composerJsonRepositoriesConfig);
  4702 $configSource = new JsonConfigSource(new JsonFile('composer.json'));
  4703 
  4704 if (
  4705 (isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
  4706 || (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
  4707 ) {
  4708 $configSource->addRepository('packagist.org', false);
  4709 } else {
  4710 $configSource->addRepository($name, $repoConfig, false);
  4711 }
  4712 
  4713 $composer = Factory::create($io, null, $disablePlugins);
  4714 }
  4715 }
  4716 
  4717 $process = new ProcessExecutor($io);
  4718 $fs = new Filesystem($process);
  4719 
  4720 
  4721 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_ROOT_PACKAGE_INSTALL, $installDevPackages);
  4722 
  4723 
  4724 $config = $composer->getConfig();
  4725 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
  4726 
  4727 
  4728 if ($noInstall === false) {
  4729 $composer->getInstallationManager()->setOutputProgress(!$noProgress);
  4730 
  4731 $installer = Installer::create($io, $composer);
  4732 $installer->setPreferSource($preferSource)
  4733 ->setPreferDist($preferDist)
  4734 ->setDevMode($installDevPackages)
  4735 ->setPlatformRequirementFilter($platformRequirementFilter)
  4736 ->setSuggestedPackagesReporter($this->suggestedPackagesReporter)
  4737 ->setOptimizeAutoloader($config->get('optimize-autoloader'))
  4738 ->setClassMapAuthoritative($config->get('classmap-authoritative'))
  4739 ->setApcuAutoloader($config->get('apcu-autoloader'));
  4740 
  4741 if (!$composer->getLocker()->isLocked()) {
  4742 $installer->setUpdate(true);
  4743 }
  4744 
  4745 if ($disablePlugins) {
  4746 $installer->disablePlugins();
  4747 }
  4748 
  4749 $status = $installer->run();
  4750 if (0 !== $status) {
  4751 return $status;
  4752 }
  4753 }
  4754 
  4755 $hasVcs = $installedFromVcs;
  4756 if (
  4757 !$input->getOption('keep-vcs')
  4758 && $installedFromVcs
  4759 && (
  4760 $input->getOption('remove-vcs')
  4761 || !$io->isInteractive()
  4762 || $io->askConfirmation('<info>Do you want to remove the existing VCS (.git, .svn..) history?</info> [<comment>Y,n</comment>]? ')
  4763 )
  4764 ) {
  4765 $finder = new Finder();
  4766 $finder->depth(0)->directories()->in(getcwd())->ignoreVCS(false)->ignoreDotFiles(false);
  4767 foreach (array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg', '.fslckout', '_FOSSIL_') as $vcsName) {
  4768 $finder->name($vcsName);
  4769 }
  4770 
  4771 try {
  4772 $dirs = iterator_to_array($finder);
  4773 unset($finder);
  4774 foreach ($dirs as $dir) {
  4775 if (!$fs->removeDirectory($dir)) {
  4776 throw new \RuntimeException('Could not remove '.$dir);
  4777 }
  4778 }
  4779 } catch (\Exception $e) {
  4780 $io->writeError('<error>An error occurred while removing the VCS metadata: '.$e->getMessage().'</error>');
  4781 }
  4782 
  4783 $hasVcs = false;
  4784 }
  4785 
  4786 
  4787 if (!$hasVcs) {
  4788 $package = $composer->getPackage();
  4789 $configSource = new JsonConfigSource(new JsonFile('composer.json'));
  4790 foreach (BasePackage::$supportedLinkTypes as $type => $meta) {
  4791 foreach ($package->{'get'.$meta['method']}() as $link) {
  4792 if ($link->getPrettyConstraint() === 'self.version') {
  4793 $configSource->addLink($type, $link->getTarget(), $package->getPrettyVersion());
  4794 }
  4795 }
  4796 }
  4797 }
  4798 
  4799 
  4800 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_CREATE_PROJECT_CMD, $installDevPackages);
  4801 
  4802 chdir($oldCwd);
  4803 $vendorComposerDir = $config->get('vendor-dir').'/composer';
  4804 if (is_dir($vendorComposerDir) && $fs->isDirEmpty($vendorComposerDir)) {
  4805 Silencer::call('rmdir', $vendorComposerDir);
  4806 $vendorDir = $config->get('vendor-dir');
  4807 if (is_dir($vendorDir) && $fs->isDirEmpty($vendorDir)) {
  4808 Silencer::call('rmdir', $vendorDir);
  4809 }
  4810 }
  4811 
  4812 return 0;
  4813 }
  4814 
  4815 
  4816 
  4817 
  4818 
  4819 
  4820 
  4821 
  4822 
  4823 
  4824 
  4825 
  4826 
  4827 
  4828 
  4829 
  4830 
  4831 
  4832 protected function installRootPackage(IOInterface $io, Config $config, $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, array $repositories = null, $disablePlugins = false, $disableScripts = false, $noProgress = false, $secureHttp = true)
  4833 {
  4834 if (!$secureHttp) {
  4835 $config->merge(array('config' => array('secure-http' => false)), Config::SOURCE_COMMAND);
  4836 }
  4837 
  4838 $parser = new VersionParser();
  4839 $requirements = $parser->parseNameVersionPairs(array($packageName));
  4840 $name = strtolower($requirements[0]['name']);
  4841 if (!$packageVersion && isset($requirements[0]['version'])) {
  4842 $packageVersion = $requirements[0]['version'];
  4843 }
  4844 
  4845 
  4846 if (null === $directory) {
  4847 $parts = explode("/", $name, 2);
  4848 $directory = getcwd() . DIRECTORY_SEPARATOR . array_pop($parts);
  4849 }
  4850 
  4851 $process = new ProcessExecutor($io);
  4852 $fs = new Filesystem($process);
  4853 if (!$fs->isAbsolutePath($directory)) {
  4854 $directory = getcwd() . DIRECTORY_SEPARATOR . $directory;
  4855 }
  4856 
  4857 $io->writeError('<info>Creating a "' . $packageName . '" project at "' . $fs->findShortestPath(getcwd(), $directory, true) . '"</info>');
  4858 
  4859 if (file_exists($directory)) {
  4860 if (!is_dir($directory)) {
  4861 throw new \InvalidArgumentException('Cannot create project directory at "'.$directory.'", it exists as a file.');
  4862 }
  4863 if (!$fs->isDirEmpty($directory)) {
  4864 throw new \InvalidArgumentException('Project directory "'.$directory.'" is not empty.');
  4865 }
  4866 }
  4867 
  4868 if (null === $stability) {
  4869 if (null === $packageVersion) {
  4870 $stability = 'stable';
  4871 } elseif (Preg::isMatch('{^[^,\s]*?@('.implode('|', array_keys(BasePackage::$stabilities)).')$}i', $packageVersion, $match)) {
  4872 $stability = $match[1];
  4873 } else {
  4874 $stability = VersionParser::parseStability($packageVersion);
  4875 }
  4876 }
  4877 
  4878 $stability = VersionParser::normalizeStability($stability);
  4879 
  4880 if (!isset(BasePackage::$stabilities[$stability])) {
  4881 throw new \InvalidArgumentException('Invalid stability provided ('.$stability.'), must be one of: '.implode(', ', array_keys(BasePackage::$stabilities)));
  4882 }
  4883 
  4884 $composer = Factory::create($io, $config->all(), $disablePlugins);
  4885 $config = $composer->getConfig();
  4886 $rm = $composer->getRepositoryManager();
  4887 
  4888 $repositorySet = new RepositorySet($stability);
  4889 if (null === $repositories) {
  4890 $repositorySet->addRepository(new CompositeRepository(RepositoryFactory::defaultRepos($io, $config, $rm)));
  4891 } else {
  4892 foreach ($repositories as $repo) {
  4893 $repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
  4894 if (
  4895 (isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
  4896 || (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
  4897 ) {
  4898 continue;
  4899 }
  4900 $repositorySet->addRepository(RepositoryFactory::createRepo($io, $config, $repoConfig, $rm));
  4901 }
  4902 }
  4903 
  4904 $platformOverrides = $config->get('platform') ?: array();
  4905 $platformRepo = new PlatformRepository(array(), $platformOverrides);
  4906 
  4907 
  4908 $versionSelector = new VersionSelector($repositorySet, $platformRepo);
  4909 $package = $versionSelector->findBestCandidate($name, $packageVersion, $stability, $platformRequirementFilter);
  4910 
  4911 if (!$package) {
  4912 $errorMessage = "Could not find package $name with " . ($packageVersion ? "version $packageVersion" : "stability $stability");
  4913 if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && $versionSelector->findBestCandidate($name, $packageVersion, $stability, PlatformRequirementFilterFactory::ignoreAll())) {
  4914 throw new \InvalidArgumentException($errorMessage .' in a version installable using your PHP version, PHP extensions and Composer version.');
  4915 }
  4916 
  4917 throw new \InvalidArgumentException($errorMessage .'.');
  4918 }
  4919 
  4920 
  4921 if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
  4922 @mkdir($directory, 0777, true);
  4923 if ($realDir = realpath($directory)) {
  4924 pcntl_async_signals(true);
  4925 pcntl_signal(SIGINT, function () use ($realDir) {
  4926 $fs = new Filesystem();
  4927 $fs->removeDirectory($realDir);
  4928 exit(130);
  4929 });
  4930 }
  4931 }
  4932 
  4933 if (function_exists('sapi_windows_set_ctrl_handler') && PHP_SAPI === 'cli') {
  4934 @mkdir($directory, 0777, true);
  4935 if ($realDir = realpath($directory)) {
  4936 sapi_windows_set_ctrl_handler(function () use ($realDir) {
  4937 $fs = new Filesystem();
  4938 $fs->removeDirectory($realDir);
  4939 exit(130);
  4940 });
  4941 }
  4942 }
  4943 
  4944 
  4945 if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
  4946 $package = $package->getAliasOf();
  4947 }
  4948 
  4949 $io->writeError('<info>Installing ' . $package->getName() . ' (' . $package->getFullPrettyVersion(false) . ')</info>');
  4950 
  4951 if ($disablePlugins) {
  4952 $io->writeError('<info>Plugins have been disabled.</info>');
  4953 }
  4954 
  4955 if ($package instanceof AliasPackage) {
  4956 $package = $package->getAliasOf();
  4957 }
  4958 
  4959 $dm = $composer->getDownloadManager();
  4960 $dm->setPreferSource($preferSource)
  4961 ->setPreferDist($preferDist);
  4962 
  4963 $projectInstaller = new ProjectInstaller($directory, $dm, $fs);
  4964 $im = $composer->getInstallationManager();
  4965 $im->setOutputProgress(!$noProgress);
  4966 $im->addInstaller($projectInstaller);
  4967 $im->execute(new InstalledArrayRepository(), array(new InstallOperation($package)));
  4968 $im->notifyInstalls($io);
  4969 
  4970 
  4971 $this->suggestedPackagesReporter->addSuggestionsFromPackage($package);
  4972 
  4973 $installedFromVcs = 'source' === $package->getInstallationSource();
  4974 
  4975 $io->writeError('<info>Created project in ' . $directory . '</info>');
  4976 chdir($directory);
  4977 
  4978 Platform::putEnv('COMPOSER_ROOT_VERSION', $package->getPrettyVersion());
  4979 
  4980 return $installedFromVcs;
  4981 }
  4982 }
  4983 <?php
  4984 
  4985 
  4986 
  4987 
  4988 
  4989 
  4990 
  4991 
  4992 
  4993 
  4994 
  4995 namespace Composer\Command;
  4996 
  4997 use Symfony\Component\Console\Input\InputInterface;
  4998 use Symfony\Component\Console\Output\OutputInterface;
  4999 use Symfony\Component\Console\Input\InputArgument;
  5000 use Symfony\Component\Console\Input\InputOption;
  5001 
  5002 
  5003 
  5004 
  5005 class DependsCommand extends BaseDependencyCommand
  5006 {
  5007 
  5008 
  5009 
  5010 
  5011 
  5012 protected function configure()
  5013 {
  5014 $this
  5015 ->setName('depends')
  5016 ->setAliases(array('why'))
  5017 ->setDescription('Shows which packages cause the given package to be installed.')
  5018 ->setDefinition(array(
  5019 new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect'),
  5020 new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
  5021 new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
  5022 ))
  5023 ->setHelp(
  5024 <<<EOT
  5025 Displays detailed information about where a package is referenced.
  5026 
  5027 <info>php composer.phar depends composer/composer</info>
  5028 
  5029 Read more at https://getcomposer.org/doc/03-cli.md#depends-why-
  5030 EOT
  5031 )
  5032 ;
  5033 }
  5034 
  5035 
  5036 
  5037 
  5038 
  5039 
  5040 protected function execute(InputInterface $input, OutputInterface $output)
  5041 {
  5042 return parent::doExecute($input, $output);
  5043 }
  5044 }
  5045 <?php
  5046 
  5047 
  5048 
  5049 
  5050 
  5051 
  5052 
  5053 
  5054 
  5055 
  5056 
  5057 namespace Composer\Command;
  5058 
  5059 use Composer\Composer;
  5060 use Composer\Factory;
  5061 use Composer\Config;
  5062 use Composer\Downloader\TransportException;
  5063 use Composer\Pcre\Preg;
  5064 use Composer\Repository\PlatformRepository;
  5065 use Composer\Plugin\CommandEvent;
  5066 use Composer\Plugin\PluginEvents;
  5067 use Composer\Util\ConfigValidator;
  5068 use Composer\Util\IniHelper;
  5069 use Composer\Util\ProcessExecutor;
  5070 use Composer\Util\HttpDownloader;
  5071 use Composer\Util\StreamContextFactory;
  5072 use Composer\Util\Platform;
  5073 use Composer\SelfUpdate\Keys;
  5074 use Composer\SelfUpdate\Versions;
  5075 use Composer\IO\NullIO;
  5076 use Composer\Package\CompletePackageInterface;
  5077 use Composer\XdebugHandler\XdebugHandler;
  5078 use Symfony\Component\Console\Input\InputInterface;
  5079 use Symfony\Component\Console\Output\OutputInterface;
  5080 use Symfony\Component\Process\ExecutableFinder;
  5081 
  5082 
  5083 
  5084 
  5085 class DiagnoseCommand extends BaseCommand
  5086 {
  5087 
  5088 protected $httpDownloader;
  5089 
  5090 
  5091 protected $process;
  5092 
  5093 
  5094 protected $exitCode = 0;
  5095 
  5096 
  5097 
  5098 
  5099 protected function configure()
  5100 {
  5101 $this
  5102 ->setName('diagnose')
  5103 ->setDescription('Diagnoses the system to identify common errors.')
  5104 ->setHelp(
  5105 <<<EOT
  5106 The <info>diagnose</info> command checks common errors to help debugging problems.
  5107 
  5108 The process exit code will be 1 in case of warnings and 2 for errors.
  5109 
  5110 Read more at https://getcomposer.org/doc/03-cli.md#diagnose
  5111 EOT
  5112 )
  5113 ;
  5114 }
  5115 
  5116 
  5117 
  5118 
  5119 protected function execute(InputInterface $input, OutputInterface $output)
  5120 {
  5121 $composer = $this->getComposer(false);
  5122 $io = $this->getIO();
  5123 
  5124 if ($composer) {
  5125 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'diagnose', $input, $output);
  5126 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  5127 
  5128 $io->write('Checking composer.json: ', false);
  5129 $this->outputResult($this->checkComposerSchema());
  5130 }
  5131 
  5132 if ($composer) {
  5133 $config = $composer->getConfig();
  5134 } else {
  5135 $config = Factory::createConfig();
  5136 }
  5137 
  5138 $config->merge(array('config' => array('secure-http' => false)), Config::SOURCE_COMMAND);
  5139 $config->prohibitUrlByConfig('http://repo.packagist.org', new NullIO);
  5140 
  5141 $this->httpDownloader = Factory::createHttpDownloader($io, $config);
  5142 $this->process = new ProcessExecutor($io);
  5143 
  5144 $io->write('Checking platform settings: ', false);
  5145 $this->outputResult($this->checkPlatform());
  5146 
  5147 $io->write('Checking git settings: ', false);
  5148 $this->outputResult($this->checkGit());
  5149 
  5150 $io->write('Checking http connectivity to packagist: ', false);
  5151 $this->outputResult($this->checkHttp('http', $config));
  5152 
  5153 $io->write('Checking https connectivity to packagist: ', false);
  5154 $this->outputResult($this->checkHttp('https', $config));
  5155 
  5156 $opts = stream_context_get_options(StreamContextFactory::getContext('http://example.org'));
  5157 if (!empty($opts['http']['proxy'])) {
  5158 $io->write('Checking HTTP proxy: ', false);
  5159 $this->outputResult($this->checkHttpProxy());
  5160 }
  5161 
  5162 if ($oauth = $config->get('github-oauth')) {
  5163 foreach ($oauth as $domain => $token) {
  5164 $io->write('Checking '.$domain.' oauth access: ', false);
  5165 $this->outputResult($this->checkGithubOauth($domain, $token));
  5166 }
  5167 } else {
  5168 $io->write('Checking github.com rate limit: ', false);
  5169 try {
  5170 $rate = $this->getGithubRateLimit('github.com');
  5171 if (!is_array($rate)) {
  5172 $this->outputResult($rate);
  5173 } elseif (10 > $rate['remaining']) {
  5174 $io->write('<warning>WARNING</warning>');
  5175 $io->write(sprintf(
  5176 '<comment>Github has a rate limit on their API. '
  5177 . 'You currently have <options=bold>%u</options=bold> '
  5178 . 'out of <options=bold>%u</options=bold> requests left.' . PHP_EOL
  5179 . 'See https://developer.github.com/v3/#rate-limiting and also' . PHP_EOL
  5180 . '    https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens</comment>',
  5181 $rate['remaining'],
  5182 $rate['limit']
  5183 ));
  5184 } else {
  5185 $this->outputResult(true);
  5186 }
  5187 } catch (\Exception $e) {
  5188 if ($e instanceof TransportException && $e->getCode() === 401) {
  5189 $this->outputResult('<comment>The oauth token for github.com seems invalid, run "composer config --global --unset github-oauth.github.com" to remove it</comment>');
  5190 } else {
  5191 $this->outputResult($e);
  5192 }
  5193 }
  5194 }
  5195 
  5196 $io->write('Checking disk free space: ', false);
  5197 $this->outputResult($this->checkDiskSpace($config));
  5198 
  5199 if (strpos(__FILE__, 'phar:') === 0) {
  5200 $io->write('Checking pubkeys: ', false);
  5201 $this->outputResult($this->checkPubKeys($config));
  5202 
  5203 $io->write('Checking composer version: ', false);
  5204 $this->outputResult($this->checkVersion($config));
  5205 }
  5206 
  5207 $io->write(sprintf('Composer version: <comment>%s</comment>', Composer::getVersion()));
  5208 
  5209 $platformOverrides = $config->get('platform') ?: array();
  5210 $platformRepo = new PlatformRepository(array(), $platformOverrides);
  5211 $phpPkg = $platformRepo->findPackage('php', '*');
  5212 $phpVersion = $phpPkg->getPrettyVersion();
  5213 if ($phpPkg instanceof CompletePackageInterface && false !== strpos($phpPkg->getDescription(), 'overridden')) {
  5214 $phpVersion .= ' - ' . $phpPkg->getDescription();
  5215 }
  5216 
  5217 $io->write(sprintf('PHP version: <comment>%s</comment>', $phpVersion));
  5218 
  5219 if (defined('PHP_BINARY')) {
  5220 $io->write(sprintf('PHP binary path: <comment>%s</comment>', PHP_BINARY));
  5221 }
  5222 
  5223 $io->write('OpenSSL version: ' . (defined('OPENSSL_VERSION_TEXT') ? '<comment>'.OPENSSL_VERSION_TEXT.'</comment>' : '<error>missing</error>'));
  5224 $io->write('cURL version: ' . $this->getCurlVersion());
  5225 
  5226 $finder = new ExecutableFinder;
  5227 $hasSystemUnzip = (bool) $finder->find('unzip');
  5228 $bin7zip = '';
  5229 if ($hasSystem7zip = (bool) $finder->find('7z', null, array('C:\Program Files\7-Zip'))) {
  5230 $bin7zip = '7z';
  5231 }
  5232 if (!Platform::isWindows() && !$hasSystem7zip && $hasSystem7zip = (bool) $finder->find('7zz')) {
  5233 $bin7zip = '7zz';
  5234 }
  5235 
  5236 $io->write(
  5237 'zip: ' . (extension_loaded('zip') ? '<comment>extension present</comment>' : '<comment>extension not loaded</comment>')
  5238 . ', ' . ($hasSystemUnzip ? '<comment>unzip present</comment>' : '<comment>unzip not available</comment>')
  5239 . ', ' . ($hasSystem7zip ? '<comment>7-Zip present ('.$bin7zip.')</comment>' : '<comment>7-Zip not available</comment>')
  5240 . (($hasSystem7zip || $hasSystemUnzip) && !function_exists('proc_open') ? ', <warning>proc_open is disabled or not present, unzip/7-z will not be usable</warning>' : '')
  5241 );
  5242 
  5243 return $this->exitCode;
  5244 }
  5245 
  5246 
  5247 
  5248 
  5249 private function checkComposerSchema()
  5250 {
  5251 $validator = new ConfigValidator($this->getIO());
  5252 list($errors, , $warnings) = $validator->validate(Factory::getComposerFile());
  5253 
  5254 if ($errors || $warnings) {
  5255 $messages = array(
  5256 'error' => $errors,
  5257 'warning' => $warnings,
  5258 );
  5259 
  5260 $output = '';
  5261 foreach ($messages as $style => $msgs) {
  5262 foreach ($msgs as $msg) {
  5263 $output .= '<' . $style . '>' . $msg . '</' . $style . '>' . PHP_EOL;
  5264 }
  5265 }
  5266 
  5267 return rtrim($output);
  5268 }
  5269 
  5270 return true;
  5271 }
  5272 
  5273 
  5274 
  5275 
  5276 private function checkGit()
  5277 {
  5278 if (!function_exists('proc_open')) {
  5279 return '<comment>proc_open is not available, git cannot be used</comment>';
  5280 }
  5281 
  5282 $this->process->execute('git config color.ui', $output);
  5283 if (strtolower(trim($output)) === 'always') {
  5284 return '<comment>Your git color.ui setting is set to always, this is known to create issues. Use "git config --global color.ui true" to set it correctly.</comment>';
  5285 }
  5286 
  5287 return true;
  5288 }
  5289 
  5290 
  5291 
  5292 
  5293 
  5294 
  5295 private function checkHttp($proto, Config $config)
  5296 {
  5297 $result = $this->checkConnectivity();
  5298 if ($result !== true) {
  5299 return $result;
  5300 }
  5301 
  5302 $result = array();
  5303 if ($proto === 'https' && $config->get('disable-tls') === true) {
  5304 $tlsWarning = '<warning>Composer is configured to disable SSL/TLS protection. This will leave remote HTTPS requests vulnerable to Man-In-The-Middle attacks.</warning>';
  5305 }
  5306 
  5307 try {
  5308 $this->httpDownloader->get($proto . '://repo.packagist.org/packages.json');
  5309 } catch (TransportException $e) {
  5310 if ($hints = HttpDownloader::getExceptionHints($e)) {
  5311 foreach ($hints as $hint) {
  5312 $result[] = $hint;
  5313 }
  5314 }
  5315 
  5316 $result[] = '<error>[' . get_class($e) . '] ' . $e->getMessage() . '</error>';
  5317 }
  5318 
  5319 if (isset($tlsWarning)) {
  5320 $result[] = $tlsWarning;
  5321 }
  5322 
  5323 if (count($result) > 0) {
  5324 return $result;
  5325 }
  5326 
  5327 return true;
  5328 }
  5329 
  5330 
  5331 
  5332 
  5333 private function checkHttpProxy()
  5334 {
  5335 $result = $this->checkConnectivity();
  5336 if ($result !== true) {
  5337 return $result;
  5338 }
  5339 
  5340 $protocol = extension_loaded('openssl') ? 'https' : 'http';
  5341 try {
  5342 $json = $this->httpDownloader->get($protocol . '://repo.packagist.org/packages.json')->decodeJson();
  5343 $hash = reset($json['provider-includes']);
  5344 $hash = $hash['sha256'];
  5345 $path = str_replace('%hash%', $hash, key($json['provider-includes']));
  5346 $provider = $this->httpDownloader->get($protocol . '://repo.packagist.org/'.$path)->getBody();
  5347 
  5348 if (hash('sha256', $provider) !== $hash) {
  5349 return 'It seems that your proxy is modifying http traffic on the fly';
  5350 }
  5351 } catch (\Exception $e) {
  5352 return $e;
  5353 }
  5354 
  5355 return true;
  5356 }
  5357 
  5358 
  5359 
  5360 
  5361 
  5362 
  5363 
  5364 private function checkGithubOauth($domain, $token)
  5365 {
  5366 $result = $this->checkConnectivity();
  5367 if ($result !== true) {
  5368 return $result;
  5369 }
  5370 
  5371 $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
  5372 try {
  5373 $url = $domain === 'github.com' ? 'https://api.'.$domain.'/' : 'https://'.$domain.'/api/v3/';
  5374 
  5375 $this->httpDownloader->get($url, array(
  5376 'retry-auth-failure' => false,
  5377 ));
  5378 
  5379 return true;
  5380 } catch (\Exception $e) {
  5381 if ($e instanceof TransportException && $e->getCode() === 401) {
  5382 return '<comment>The oauth token for '.$domain.' seems invalid, run "composer config --global --unset github-oauth.'.$domain.'" to remove it</comment>';
  5383 }
  5384 
  5385 return $e;
  5386 }
  5387 }
  5388 
  5389 
  5390 
  5391 
  5392 
  5393 
  5394 
  5395 private function getGithubRateLimit($domain, $token = null)
  5396 {
  5397 $result = $this->checkConnectivity();
  5398 if ($result !== true) {
  5399 return $result;
  5400 }
  5401 
  5402 if ($token) {
  5403 $this->getIO()->setAuthentication($domain, $token, 'x-oauth-basic');
  5404 }
  5405 
  5406 $url = $domain === 'github.com' ? 'https://api.'.$domain.'/rate_limit' : 'https://'.$domain.'/api/rate_limit';
  5407 $data = $this->httpDownloader->get($url, array('retry-auth-failure' => false))->decodeJson();
  5408 
  5409 return $data['resources']['core'];
  5410 }
  5411 
  5412 
  5413 
  5414 
  5415 private function checkDiskSpace(Config $config)
  5416 {
  5417 $minSpaceFree = 1024 * 1024;
  5418 if ((($df = @disk_free_space($dir = $config->get('home'))) !== false && $df < $minSpaceFree)
  5419 || (($df = @disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
  5420 ) {
  5421 return '<error>The disk hosting '.$dir.' is full</error>';
  5422 }
  5423 
  5424 return true;
  5425 }
  5426 
  5427 
  5428 
  5429 
  5430 private function checkPubKeys(Config $config)
  5431 {
  5432 $home = $config->get('home');
  5433 $errors = array();
  5434 $io = $this->getIO();
  5435 
  5436 if (file_exists($home.'/keys.tags.pub') && file_exists($home.'/keys.dev.pub')) {
  5437 $io->write('');
  5438 }
  5439 
  5440 if (file_exists($home.'/keys.tags.pub')) {
  5441 $io->write('Tags Public Key Fingerprint: ' . Keys::fingerprint($home.'/keys.tags.pub'));
  5442 } else {
  5443 $errors[] = '<error>Missing pubkey for tags verification</error>';
  5444 }
  5445 
  5446 if (file_exists($home.'/keys.dev.pub')) {
  5447 $io->write('Dev Public Key Fingerprint: ' . Keys::fingerprint($home.'/keys.dev.pub'));
  5448 } else {
  5449 $errors[] = '<error>Missing pubkey for dev verification</error>';
  5450 }
  5451 
  5452 if ($errors) {
  5453 $errors[] = '<error>Run composer self-update --update-keys to set them up</error>';
  5454 }
  5455 
  5456 return $errors ?: true;
  5457 }
  5458 
  5459 
  5460 
  5461 
  5462 private function checkVersion(Config $config)
  5463 {
  5464 $result = $this->checkConnectivity();
  5465 if ($result !== true) {
  5466 return $result;
  5467 }
  5468 
  5469 $versionsUtil = new Versions($config, $this->httpDownloader);
  5470 try {
  5471 $latest = $versionsUtil->getLatest();
  5472 } catch (\Exception $e) {
  5473 return $e;
  5474 }
  5475 
  5476 if (Composer::VERSION !== $latest['version'] && Composer::VERSION !== '@package_version@') {
  5477 return '<comment>You are not running the latest '.$versionsUtil->getChannel().' version, run `composer self-update` to update ('.Composer::VERSION.' => '.$latest['version'].')</comment>';
  5478 }
  5479 
  5480 return true;
  5481 }
  5482 
  5483 
  5484 
  5485 
  5486 private function getCurlVersion()
  5487 {
  5488 if (extension_loaded('curl')) {
  5489 if (!HttpDownloader::isCurlEnabled()) {
  5490 return '<error>disabled via disable_functions, using php streams fallback, which reduces performance</error>';
  5491 }
  5492 
  5493 $version = curl_version();
  5494 
  5495 return '<comment>'.$version['version'].'</comment> '.
  5496 'libz <comment>'.(!empty($version['libz_version']) ? $version['libz_version'] : 'missing').'</comment> '.
  5497 'ssl <comment>'.(isset($version['ssl_version']) ? $version['ssl_version'] : 'missing').'</comment>';
  5498 }
  5499 
  5500 return '<error>missing, using php streams fallback, which reduces performance</error>';
  5501 }
  5502 
  5503 
  5504 
  5505 
  5506 
  5507 
  5508 private function outputResult($result)
  5509 {
  5510 $io = $this->getIO();
  5511 if (true === $result) {
  5512 $io->write('<info>OK</info>');
  5513 
  5514 return;
  5515 }
  5516 
  5517 $hadError = false;
  5518 $hadWarning = false;
  5519 if ($result instanceof \Exception) {
  5520 $result = '<error>['.get_class($result).'] '.$result->getMessage().'</error>';
  5521 }
  5522 
  5523 if (!$result) {
  5524 
  5525 $hadError = true;
  5526 } else {
  5527 if (!is_array($result)) {
  5528 $result = array($result);
  5529 }
  5530 foreach ($result as $message) {
  5531 if (false !== strpos($message, '<error>')) {
  5532 $hadError = true;
  5533 } elseif (false !== strpos($message, '<warning>')) {
  5534 $hadWarning = true;
  5535 }
  5536 }
  5537 }
  5538 
  5539 if ($hadError) {
  5540 $io->write('<error>FAIL</error>');
  5541 $this->exitCode = max($this->exitCode, 2);
  5542 } elseif ($hadWarning) {
  5543 $io->write('<warning>WARNING</warning>');
  5544 $this->exitCode = max($this->exitCode, 1);
  5545 }
  5546 
  5547 if ($result) {
  5548 foreach ($result as $message) {
  5549 $io->write($message);
  5550 }
  5551 }
  5552 }
  5553 
  5554 
  5555 
  5556 
  5557 private function checkPlatform()
  5558 {
  5559 $output = '';
  5560 $out = function ($msg, $style) use (&$output) {
  5561 $output .= '<'.$style.'>'.$msg.'</'.$style.'>'.PHP_EOL;
  5562 };
  5563 
  5564 
  5565 $errors = array();
  5566 $warnings = array();
  5567 $displayIniMessage = false;
  5568 
  5569 $iniMessage = PHP_EOL.PHP_EOL.IniHelper::getMessage();
  5570 $iniMessage .= PHP_EOL.'If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple times.';
  5571 
  5572 if (!function_exists('json_decode')) {
  5573 $errors['json'] = true;
  5574 }
  5575 
  5576 if (!extension_loaded('Phar')) {
  5577 $errors['phar'] = true;
  5578 }
  5579 
  5580 if (!extension_loaded('filter')) {
  5581 $errors['filter'] = true;
  5582 }
  5583 
  5584 if (!extension_loaded('hash')) {
  5585 $errors['hash'] = true;
  5586 }
  5587 
  5588 if (!extension_loaded('iconv') && !extension_loaded('mbstring')) {
  5589 $errors['iconv_mbstring'] = true;
  5590 }
  5591 
  5592 if (!filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN)) {
  5593 $errors['allow_url_fopen'] = true;
  5594 }
  5595 
  5596 if (extension_loaded('ionCube Loader') && ioncube_loader_iversion() < 40009) {
  5597 $errors['ioncube'] = ioncube_loader_version();
  5598 }
  5599 
  5600 if (PHP_VERSION_ID < 50302) {
  5601 $errors['php'] = PHP_VERSION;
  5602 }
  5603 
  5604 if (!isset($errors['php']) && PHP_VERSION_ID < 50304) {
  5605 $warnings['php'] = PHP_VERSION;
  5606 }
  5607 
  5608 if (!extension_loaded('openssl')) {
  5609 $errors['openssl'] = true;
  5610 }
  5611 
  5612 if (extension_loaded('openssl') && OPENSSL_VERSION_NUMBER < 0x1000100f) {
  5613 $warnings['openssl_version'] = true;
  5614 }
  5615 
  5616 if (!defined('HHVM_VERSION') && !extension_loaded('apcu') && filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) {
  5617 $warnings['apc_cli'] = true;
  5618 }
  5619 
  5620 if (!extension_loaded('zlib')) {
  5621 $warnings['zlib'] = true;
  5622 }
  5623 
  5624 ob_start();
  5625 phpinfo(INFO_GENERAL);
  5626 $phpinfo = ob_get_clean();
  5627 if (Preg::isMatch('{Configure Command(?: *</td><td class="v">| *=> *)(.*?)(?:</td>|$)}m', $phpinfo, $match)) {
  5628 $configure = $match[1];
  5629 
  5630 if (false !== strpos($configure, '--enable-sigchild')) {
  5631 $warnings['sigchild'] = true;
  5632 }
  5633 
  5634 if (false !== strpos($configure, '--with-curlwrappers')) {
  5635 $warnings['curlwrappers'] = true;
  5636 }
  5637 }
  5638 
  5639 if (filter_var(ini_get('xdebug.profiler_enabled'), FILTER_VALIDATE_BOOLEAN)) {
  5640 $warnings['xdebug_profile'] = true;
  5641 } elseif (XdebugHandler::isXdebugActive()) {
  5642 $warnings['xdebug_loaded'] = true;
  5643 }
  5644 
  5645 if (defined('PHP_WINDOWS_VERSION_BUILD')
  5646 && (version_compare(PHP_VERSION, '7.2.23', '<')
  5647 || (version_compare(PHP_VERSION, '7.3.0', '>=')
  5648 && version_compare(PHP_VERSION, '7.3.10', '<')))) {
  5649 $warnings['onedrive'] = PHP_VERSION;
  5650 }
  5651 
  5652 if (!empty($errors)) {
  5653 foreach ($errors as $error => $current) {
  5654 switch ($error) {
  5655 case 'json':
  5656 $text = PHP_EOL."The json extension is missing.".PHP_EOL;
  5657 $text .= "Install it or recompile php without --disable-json";
  5658 break;
  5659 
  5660 case 'phar':
  5661 $text = PHP_EOL."The phar extension is missing.".PHP_EOL;
  5662 $text .= "Install it or recompile php without --disable-phar";
  5663 break;
  5664 
  5665 case 'filter':
  5666 $text = PHP_EOL."The filter extension is missing.".PHP_EOL;
  5667 $text .= "Install it or recompile php without --disable-filter";
  5668 break;
  5669 
  5670 case 'hash':
  5671 $text = PHP_EOL."The hash extension is missing.".PHP_EOL;
  5672 $text .= "Install it or recompile php without --disable-hash";
  5673 break;
  5674 
  5675 case 'iconv_mbstring':
  5676 $text = PHP_EOL."The iconv OR mbstring extension is required and both are missing.".PHP_EOL;
  5677 $text .= "Install either of them or recompile php without --disable-iconv";
  5678 break;
  5679 
  5680 case 'php':
  5681 $text = PHP_EOL."Your PHP ({$current}) is too old, you must upgrade to PHP 5.3.2 or higher.";
  5682 break;
  5683 
  5684 case 'allow_url_fopen':
  5685 $text = PHP_EOL."The allow_url_fopen setting is incorrect.".PHP_EOL;
  5686 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
  5687 $text .= "    allow_url_fopen = On";
  5688 $displayIniMessage = true;
  5689 break;
  5690 
  5691 case 'ioncube':
  5692 $text = PHP_EOL."Your ionCube Loader extension ($current) is incompatible with Phar files.".PHP_EOL;
  5693 $text .= "Upgrade to ionCube 4.0.9 or higher or remove this line (path may be different) from your `php.ini` to disable it:".PHP_EOL;
  5694 $text .= "    zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so";
  5695 $displayIniMessage = true;
  5696 break;
  5697 
  5698 case 'openssl':
  5699 $text = PHP_EOL."The openssl extension is missing, which means that secure HTTPS transfers are impossible.".PHP_EOL;
  5700 $text .= "If possible you should enable it or recompile php with --with-openssl";
  5701 break;
  5702 
  5703 default:
  5704 throw new \InvalidArgumentException(sprintf("DiagnoseCommand: Unknown error type \"%s\". Please report at https://github.com/composer/composer/issues/new.", $error));
  5705 }
  5706 $out($text, 'error');
  5707 }
  5708 
  5709 $output .= PHP_EOL;
  5710 }
  5711 
  5712 if (!empty($warnings)) {
  5713 foreach ($warnings as $warning => $current) {
  5714 switch ($warning) {
  5715 case 'apc_cli':
  5716 $text = "The apc.enable_cli setting is incorrect.".PHP_EOL;
  5717 $text .= "Add the following to the end of your `php.ini`:".PHP_EOL;
  5718 $text .= "  apc.enable_cli = Off";
  5719 $displayIniMessage = true;
  5720 break;
  5721 
  5722 case 'zlib':
  5723 $text = 'The zlib extension is not loaded, this can slow down Composer a lot.'.PHP_EOL;
  5724 $text .= 'If possible, enable it or recompile php with --with-zlib'.PHP_EOL;
  5725 $displayIniMessage = true;
  5726 break;
  5727 
  5728 case 'sigchild':
  5729 $text = "PHP was compiled with --enable-sigchild which can cause issues on some platforms.".PHP_EOL;
  5730 $text .= "Recompile it without this flag if possible, see also:".PHP_EOL;
  5731 $text .= "  https://bugs.php.net/bug.php?id=22999";
  5732 break;
  5733 
  5734 case 'curlwrappers':
  5735 $text = "PHP was compiled with --with-curlwrappers which will cause issues with HTTP authentication and GitHub.".PHP_EOL;
  5736 $text .= " Recompile it without this flag if possible";
  5737 break;
  5738 
  5739 case 'php':
  5740 $text = "Your PHP ({$current}) is quite old, upgrading to PHP 5.3.4 or higher is recommended.".PHP_EOL;
  5741 $text .= " Composer works with 5.3.2+ for most people, but there might be edge case issues.";
  5742 break;
  5743 
  5744 case 'openssl_version':
  5745 
  5746 $opensslVersion = strstr(trim(strstr(OPENSSL_VERSION_TEXT, ' ')), ' ', true);
  5747 $opensslVersion = $opensslVersion ?: OPENSSL_VERSION_TEXT;
  5748 
  5749 $text = "The OpenSSL library ({$opensslVersion}) used by PHP does not support TLSv1.2 or TLSv1.1.".PHP_EOL;
  5750 $text .= "If possible you should upgrade OpenSSL to version 1.0.1 or above.";
  5751 break;
  5752 
  5753 case 'xdebug_loaded':
  5754 $text = "The xdebug extension is loaded, this can slow down Composer a little.".PHP_EOL;
  5755 $text .= " Disabling it when using Composer is recommended.";
  5756 break;
  5757 
  5758 case 'xdebug_profile':
  5759 $text = "The xdebug.profiler_enabled setting is enabled, this can slow down Composer a lot.".PHP_EOL;
  5760 $text .= "Add the following to the end of your `php.ini` to disable it:".PHP_EOL;
  5761 $text .= "  xdebug.profiler_enabled = 0";
  5762 $displayIniMessage = true;
  5763 break;
  5764 
  5765 case 'onedrive':
  5766 $text = "The Windows OneDrive folder is not supported on PHP versions below 7.2.23 and 7.3.10.".PHP_EOL;
  5767 $text .= "Upgrade your PHP ({$current}) to use this location with Composer.".PHP_EOL;
  5768 break;
  5769 
  5770 default:
  5771 throw new \InvalidArgumentException(sprintf("DiagnoseCommand: Unknown warning type \"%s\". Please report at https://github.com/composer/composer/issues/new.", $warning));
  5772 }
  5773 $out($text, 'comment');
  5774 }
  5775 }
  5776 
  5777 if ($displayIniMessage) {
  5778 $out($iniMessage, 'comment');
  5779 }
  5780 
  5781 return !$warnings && !$errors ? true : $output;
  5782 }
  5783 
  5784 
  5785 
  5786 
  5787 
  5788 
  5789 private function checkConnectivity()
  5790 {
  5791 if (!ini_get('allow_url_fopen')) {
  5792 return '<info>Skipped because allow_url_fopen is missing.</info>';
  5793 }
  5794 
  5795 return true;
  5796 }
  5797 }
  5798 <?php
  5799 
  5800 
  5801 
  5802 
  5803 
  5804 
  5805 
  5806 
  5807 
  5808 
  5809 
  5810 namespace Composer\Command;
  5811 
  5812 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  5813 use Composer\Plugin\CommandEvent;
  5814 use Composer\Plugin\PluginEvents;
  5815 use Symfony\Component\Console\Input\InputInterface;
  5816 use Symfony\Component\Console\Input\InputOption;
  5817 use Symfony\Component\Console\Output\OutputInterface;
  5818 
  5819 
  5820 
  5821 
  5822 class DumpAutoloadCommand extends BaseCommand
  5823 {
  5824 
  5825 
  5826 
  5827 protected function configure()
  5828 {
  5829 $this
  5830 ->setName('dump-autoload')
  5831 ->setAliases(array('dumpautoload'))
  5832 ->setDescription('Dumps the autoloader.')
  5833 ->setDefinition(array(
  5834 new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'),
  5835 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'),
  5836 new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
  5837 new InputOption('apcu-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu'),
  5838 new InputOption('dev', null, InputOption::VALUE_NONE, 'Enables autoload-dev rules. Composer will by default infer this automatically according to the last install or update --no-dev state.'),
  5839 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables autoload-dev rules. Composer will by default infer this automatically according to the last install or update --no-dev state.'),
  5840 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
  5841 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
  5842 ))
  5843 ->setHelp(
  5844 <<<EOT
  5845 <info>php composer.phar dump-autoload</info>
  5846 
  5847 Read more at https://getcomposer.org/doc/03-cli.md#dump-autoload-dumpautoload-
  5848 EOT
  5849 )
  5850 ;
  5851 }
  5852 
  5853 
  5854 
  5855 
  5856 protected function execute(InputInterface $input, OutputInterface $output)
  5857 {
  5858 $composer = $this->getComposer();
  5859 
  5860 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'dump-autoload', $input, $output);
  5861 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  5862 
  5863 $installationManager = $composer->getInstallationManager();
  5864 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
  5865 $package = $composer->getPackage();
  5866 $config = $composer->getConfig();
  5867 
  5868 $optimize = $input->getOption('optimize') || $config->get('optimize-autoloader');
  5869 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
  5870 $apcuPrefix = $input->getOption('apcu-prefix');
  5871 $apcu = $apcuPrefix !== null || $input->getOption('apcu') || $config->get('apcu-autoloader');
  5872 
  5873 if ($authoritative) {
  5874 $this->getIO()->write('<info>Generating optimized autoload files (authoritative)</info>');
  5875 } elseif ($optimize) {
  5876 $this->getIO()->write('<info>Generating optimized autoload files</info>');
  5877 } else {
  5878 $this->getIO()->write('<info>Generating autoload files</info>');
  5879 }
  5880 
  5881 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  5882 
  5883 $generator = $composer->getAutoloadGenerator();
  5884 if ($input->getOption('no-dev')) {
  5885 $generator->setDevMode(false);
  5886 }
  5887 if ($input->getOption('dev')) {
  5888 if ($input->getOption('no-dev')) {
  5889 throw new \InvalidArgumentException('You can not use both --no-dev and --dev as they conflict with each other.');
  5890 }
  5891 $generator->setDevMode(true);
  5892 }
  5893 $generator->setClassMapAuthoritative($authoritative);
  5894 $generator->setRunScripts(true);
  5895 $generator->setApcu($apcu, $apcuPrefix);
  5896 $generator->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs));
  5897 $numberOfClasses = $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize);
  5898 
  5899 if ($authoritative) {
  5900 $this->getIO()->write('<info>Generated optimized autoload files (authoritative) containing '. $numberOfClasses .' classes</info>');
  5901 } elseif ($optimize) {
  5902 $this->getIO()->write('<info>Generated optimized autoload files containing '. $numberOfClasses .' classes</info>');
  5903 } else {
  5904 $this->getIO()->write('<info>Generated autoload files</info>');
  5905 }
  5906 
  5907 return 0;
  5908 }
  5909 }
  5910 <?php
  5911 
  5912 
  5913 
  5914 
  5915 
  5916 
  5917 
  5918 
  5919 
  5920 
  5921 
  5922 namespace Composer\Command;
  5923 
  5924 use Symfony\Component\Console\Input\InputInterface;
  5925 use Symfony\Component\Console\Input\InputOption;
  5926 use Symfony\Component\Console\Output\OutputInterface;
  5927 use Symfony\Component\Console\Input\InputArgument;
  5928 
  5929 
  5930 
  5931 
  5932 class ExecCommand extends BaseCommand
  5933 {
  5934 
  5935 
  5936 
  5937 protected function configure()
  5938 {
  5939 $this
  5940 ->setName('exec')
  5941 ->setDescription('Executes a vendored binary/script.')
  5942 ->setDefinition(array(
  5943 new InputOption('list', 'l', InputOption::VALUE_NONE),
  5944 new InputArgument('binary', InputArgument::OPTIONAL, 'The binary to run, e.g. phpunit'),
  5945 new InputArgument(
  5946 'args',
  5947 InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
  5948 'Arguments to pass to the binary. Use <info>--</info> to separate from composer arguments'
  5949 ),
  5950 ))
  5951 ->setHelp(
  5952 <<<EOT
  5953 Executes a vendored binary/script.
  5954 
  5955 Read more at https://getcomposer.org/doc/03-cli.md#exec
  5956 EOT
  5957 )
  5958 ;
  5959 }
  5960 
  5961 
  5962 
  5963 
  5964 protected function execute(InputInterface $input, OutputInterface $output)
  5965 {
  5966 $composer = $this->getComposer();
  5967 $binDir = $composer->getConfig()->get('bin-dir');
  5968 if ($input->getOption('list') || !$input->getArgument('binary')) {
  5969 $bins = glob($binDir . '/*');
  5970 $bins = array_merge($bins, array_map(function ($e) {
  5971 return "$e (local)";
  5972 }, $composer->getPackage()->getBinaries()));
  5973 
  5974 if (!$bins) {
  5975 throw new \RuntimeException("No binaries found in composer.json or in bin-dir ($binDir)");
  5976 }
  5977 
  5978 $this->getIO()->write(
  5979 <<<EOT
  5980 <comment>Available binaries:</comment>
  5981 EOT
  5982 );
  5983 
  5984 foreach ($bins as $bin) {
  5985 
  5986 if (isset($previousBin) && $bin === $previousBin.'.bat') {
  5987 continue;
  5988 }
  5989 
  5990 $previousBin = $bin;
  5991 $bin = basename($bin);
  5992 $this->getIO()->write(
  5993 <<<EOT
  5994 <info>- $bin</info>
  5995 EOT
  5996 );
  5997 }
  5998 
  5999 return 0;
  6000 }
  6001 
  6002 $binary = $input->getArgument('binary');
  6003 
  6004 $dispatcher = $composer->getEventDispatcher();
  6005 $dispatcher->addListener('__exec_command', $binary);
  6006 
  6007 
  6008 
  6009 
  6010 if (getcwd() !== $this->getApplication()->getInitialWorkingDirectory()) {
  6011 try {
  6012 chdir($this->getApplication()->getInitialWorkingDirectory());
  6013 } catch (\Exception $e) {
  6014 throw new \RuntimeException('Could not switch back to working directory "'.$this->getApplication()->getInitialWorkingDirectory().'"', 0, $e);
  6015 }
  6016 }
  6017 
  6018 return $dispatcher->dispatchScript('__exec_command', true, $input->getArgument('args'));
  6019 }
  6020 }
  6021 <?php
  6022 
  6023 
  6024 
  6025 
  6026 
  6027 
  6028 
  6029 
  6030 
  6031 
  6032 
  6033 namespace Composer\Command;
  6034 
  6035 use Composer\Json\JsonFile;
  6036 use Composer\Package\AliasPackage;
  6037 use Composer\Package\BasePackage;
  6038 use Composer\Package\CompletePackageInterface;
  6039 use Composer\Pcre\Preg;
  6040 use Composer\Repository\CompositeRepository;
  6041 use Composer\Semver\Constraint\MatchAllConstraint;
  6042 use Symfony\Component\Console\Input\InputInterface;
  6043 use Symfony\Component\Console\Input\InputOption;
  6044 use Symfony\Component\Console\Output\OutputInterface;
  6045 
  6046 
  6047 
  6048 
  6049 
  6050 class FundCommand extends BaseCommand
  6051 {
  6052 
  6053 
  6054 
  6055 protected function configure()
  6056 {
  6057 $this->setName('fund')
  6058 ->setDescription('Discover how to help fund the maintenance of your dependencies.')
  6059 ->setDefinition(array(
  6060 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
  6061 ))
  6062 ;
  6063 }
  6064 
  6065 
  6066 
  6067 
  6068 protected function execute(InputInterface $input, OutputInterface $output)
  6069 {
  6070 $composer = $this->getComposer();
  6071 
  6072 $repo = $composer->getRepositoryManager()->getLocalRepository();
  6073 $remoteRepos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
  6074 $fundings = array();
  6075 
  6076 $packagesToLoad = array();
  6077 foreach ($repo->getPackages() as $package) {
  6078 if ($package instanceof AliasPackage) {
  6079 continue;
  6080 }
  6081 $packagesToLoad[$package->getName()] = new MatchAllConstraint();
  6082 }
  6083 
  6084 
  6085 $result = $remoteRepos->loadPackages($packagesToLoad, array('dev' => BasePackage::STABILITY_DEV), array());
  6086 
  6087 
  6088 foreach ($result['packages'] as $package) {
  6089 if (
  6090 !$package instanceof AliasPackage
  6091 && $package instanceof CompletePackageInterface
  6092 && $package->isDefaultBranch()
  6093 && $package->getFunding()
  6094 && isset($packagesToLoad[$package->getName()])
  6095 ) {
  6096 $fundings = $this->insertFundingData($fundings, $package);
  6097 unset($packagesToLoad[$package->getName()]);
  6098 }
  6099 }
  6100 
  6101 
  6102 foreach ($repo->getPackages() as $package) {
  6103 if ($package instanceof AliasPackage || !isset($packagesToLoad[$package->getName()])) {
  6104 continue;
  6105 }
  6106 
  6107 if ($package instanceof CompletePackageInterface && $package->getFunding()) {
  6108 $fundings = $this->insertFundingData($fundings, $package);
  6109 }
  6110 }
  6111 
  6112 ksort($fundings);
  6113 
  6114 $io = $this->getIO();
  6115 
  6116 $format = $input->getOption('format');
  6117 if (!in_array($format, array('text', 'json'))) {
  6118 $io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
  6119 
  6120 return 1;
  6121 }
  6122 
  6123 if ($fundings && $format === 'text') {
  6124 $prev = null;
  6125 
  6126 $io->write('The following packages were found in your dependencies which publish funding information:');
  6127 
  6128 foreach ($fundings as $vendor => $links) {
  6129 $io->write('');
  6130 $io->write(sprintf("<comment>%s</comment>", $vendor));
  6131 foreach ($links as $url => $packages) {
  6132 $line = sprintf('  <info>%s</info>', implode(', ', $packages));
  6133 
  6134 if ($prev !== $line) {
  6135 $io->write($line);
  6136 $prev = $line;
  6137 }
  6138 
  6139 $io->write(sprintf('    %s', $url));
  6140 }
  6141 }
  6142 
  6143 $io->write("");
  6144 $io->write("Please consider following these links and sponsoring the work of package authors!");
  6145 $io->write("Thank you!");
  6146 } elseif ($format === 'json') {
  6147 $io->write(JsonFile::encode($fundings));
  6148 } else {
  6149 $io->write("No funding links were found in your package dependencies. This doesn't mean they don't need your support!");
  6150 }
  6151 
  6152 return 0;
  6153 }
  6154 
  6155 
  6156 
  6157 
  6158 
  6159 private function insertFundingData(array $fundings, CompletePackageInterface $package)
  6160 {
  6161 foreach ($package->getFunding() as $fundingOption) {
  6162 list($vendor, $packageName) = explode('/', $package->getPrettyName());
  6163 
  6164 if (empty($fundingOption['url'])) {
  6165 continue;
  6166 }
  6167 $url = $fundingOption['url'];
  6168 if (!empty($fundingOption['type']) && $fundingOption['type'] === 'github' && Preg::isMatch('{^https://github.com/([^/]+)$}', $url, $match)) {
  6169 $url = 'https://github.com/sponsors/'.$match[1];
  6170 }
  6171 $fundings[$vendor][$url][] = $packageName;
  6172 }
  6173 
  6174 return $fundings;
  6175 }
  6176 }
  6177 <?php
  6178 
  6179 
  6180 
  6181 
  6182 
  6183 
  6184 
  6185 
  6186 
  6187 
  6188 
  6189 namespace Composer\Command;
  6190 
  6191 use Composer\Factory;
  6192 use Composer\Pcre\Preg;
  6193 use Composer\Util\Filesystem;
  6194 use Composer\Util\Platform;
  6195 use Symfony\Component\Console\Input\InputInterface;
  6196 use Symfony\Component\Console\Input\InputArgument;
  6197 use Symfony\Component\Console\Input\StringInput;
  6198 use Symfony\Component\Console\Output\OutputInterface;
  6199 
  6200 
  6201 
  6202 
  6203 class GlobalCommand extends BaseCommand
  6204 {
  6205 
  6206 
  6207 
  6208 protected function configure()
  6209 {
  6210 $this
  6211 ->setName('global')
  6212 ->setDescription('Allows running commands in the global composer dir ($COMPOSER_HOME).')
  6213 ->setDefinition(array(
  6214 new InputArgument('command-name', InputArgument::REQUIRED, ''),
  6215 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
  6216 ))
  6217 ->setHelp(
  6218 <<<EOT
  6219 Use this command as a wrapper to run other Composer commands
  6220 within the global context of COMPOSER_HOME.
  6221 
  6222 You can use this to install CLI utilities globally, all you need
  6223 is to add the COMPOSER_HOME/vendor/bin dir to your PATH env var.
  6224 
  6225 COMPOSER_HOME is c:\Users\<user>\AppData\Roaming\Composer on Windows
  6226 and /home/<user>/.composer on unix systems.
  6227 
  6228 If your system uses freedesktop.org standards, then it will first check
  6229 XDG_CONFIG_HOME or default to /home/<user>/.config/composer
  6230 
  6231 Note: This path may vary depending on customizations to bin-dir in
  6232 composer.json or the environmental variable COMPOSER_BIN_DIR.
  6233 
  6234 Read more at https://getcomposer.org/doc/03-cli.md#global
  6235 EOT
  6236 )
  6237 ;
  6238 }
  6239 
  6240 
  6241 
  6242 
  6243 
  6244 public function run(InputInterface $input, OutputInterface $output)
  6245 {
  6246 if (!method_exists($input, '__toString')) {
  6247 throw new \LogicException('Expected an Input instance that is stringable, got '.get_class($input));
  6248 }
  6249 
  6250 
  6251 $tokens = Preg::split('{\s+}', $input->__toString());
  6252 $args = array();
  6253 foreach ($tokens as $token) {
  6254 if ($token && $token[0] !== '-') {
  6255 $args[] = $token;
  6256 if (count($args) >= 2) {
  6257 break;
  6258 }
  6259 }
  6260 }
  6261 
  6262 
  6263 if (count($args) < 2) {
  6264 return parent::run($input, $output);
  6265 }
  6266 
  6267 
  6268 if (Platform::getEnv('COMPOSER')) {
  6269 Platform::clearEnv('COMPOSER');
  6270 }
  6271 
  6272 
  6273 $config = Factory::createConfig();
  6274 $home = $config->get('home');
  6275 
  6276 if (!is_dir($home)) {
  6277 $fs = new Filesystem();
  6278 $fs->ensureDirectoryExists($home);
  6279 if (!is_dir($home)) {
  6280 throw new \RuntimeException('Could not create home directory');
  6281 }
  6282 }
  6283 
  6284 try {
  6285 chdir($home);
  6286 } catch (\Exception $e) {
  6287 throw new \RuntimeException('Could not switch to home directory "'.$home.'"', 0, $e);
  6288 }
  6289 $this->getIO()->writeError('<info>Changed current directory to '.$home.'</info>');
  6290 
  6291 
  6292 $input = new StringInput(Preg::replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1));
  6293 $this->getApplication()->resetComposer();
  6294 
  6295 return $this->getApplication()->run($input, $output);
  6296 }
  6297 
  6298 
  6299 
  6300 
  6301 public function isProxyCommand()
  6302 {
  6303 return true;
  6304 }
  6305 }
  6306 <?php
  6307 
  6308 
  6309 
  6310 
  6311 
  6312 
  6313 
  6314 
  6315 
  6316 
  6317 
  6318 namespace Composer\Command;
  6319 
  6320 use Composer\Package\CompletePackageInterface;
  6321 use Composer\Repository\RepositoryInterface;
  6322 use Composer\Repository\RootPackageRepository;
  6323 use Composer\Repository\RepositoryFactory;
  6324 use Composer\Util\Platform;
  6325 use Composer\Util\ProcessExecutor;
  6326 use Symfony\Component\Console\Input\InputArgument;
  6327 use Symfony\Component\Console\Input\InputOption;
  6328 use Symfony\Component\Console\Input\InputInterface;
  6329 use Symfony\Component\Console\Output\OutputInterface;
  6330 
  6331 
  6332 
  6333 
  6334 class HomeCommand extends BaseCommand
  6335 {
  6336 
  6337 
  6338 
  6339 
  6340 
  6341 protected function configure()
  6342 {
  6343 $this
  6344 ->setName('browse')
  6345 ->setAliases(array('home'))
  6346 ->setDescription('Opens the package\'s repository URL or homepage in your browser.')
  6347 ->setDefinition(array(
  6348 new InputArgument('packages', InputArgument::IS_ARRAY, 'Package(s) to browse to.'),
  6349 new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'),
  6350 new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'),
  6351 ))
  6352 ->setHelp(
  6353 <<<EOT
  6354 The home command opens or shows a package's repository URL or
  6355 homepage in your default browser.
  6356 
  6357 To open the homepage by default, use -H or --homepage.
  6358 To show instead of open the repository or homepage URL, use -s or --show.
  6359 
  6360 Read more at https://getcomposer.org/doc/03-cli.md#browse-home
  6361 EOT
  6362 );
  6363 }
  6364 
  6365 
  6366 
  6367 
  6368 protected function execute(InputInterface $input, OutputInterface $output)
  6369 {
  6370 $repos = $this->initializeRepos();
  6371 $io = $this->getIO();
  6372 $return = 0;
  6373 
  6374 $packages = $input->getArgument('packages');
  6375 if (!$packages) {
  6376 $io->writeError('No package specified, opening homepage for the root package');
  6377 $packages = array($this->getComposer()->getPackage()->getName());
  6378 }
  6379 
  6380 foreach ($packages as $packageName) {
  6381 $handled = false;
  6382 $packageExists = false;
  6383 foreach ($repos as $repo) {
  6384 foreach ($repo->findPackages($packageName) as $package) {
  6385 $packageExists = true;
  6386 if ($package instanceof CompletePackageInterface && $this->handlePackage($package, $input->getOption('homepage'), $input->getOption('show'))) {
  6387 $handled = true;
  6388 break 2;
  6389 }
  6390 }
  6391 }
  6392 
  6393 if (!$packageExists) {
  6394 $return = 1;
  6395 $io->writeError('<warning>Package '.$packageName.' not found</warning>');
  6396 }
  6397 
  6398 if (!$handled) {
  6399 $return = 1;
  6400 $io->writeError('<warning>'.($input->getOption('homepage') ? 'Invalid or missing homepage' : 'Invalid or missing repository URL').' for '.$packageName.'</warning>');
  6401 }
  6402 }
  6403 
  6404 return $return;
  6405 }
  6406 
  6407 
  6408 
  6409 
  6410 
  6411 
  6412 private function handlePackage(CompletePackageInterface $package, $showHomepage, $showOnly)
  6413 {
  6414 $support = $package->getSupport();
  6415 $url = isset($support['source']) ? $support['source'] : $package->getSourceUrl();
  6416 if (!$url || $showHomepage) {
  6417 $url = $package->getHomepage();
  6418 }
  6419 
  6420 if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
  6421 return false;
  6422 }
  6423 
  6424 if ($showOnly) {
  6425 $this->getIO()->write(sprintf('<info>%s</info>', $url));
  6426 } else {
  6427 $this->openBrowser($url);
  6428 }
  6429 
  6430 return true;
  6431 }
  6432 
  6433 
  6434 
  6435 
  6436 
  6437 
  6438 
  6439 private function openBrowser($url)
  6440 {
  6441 $url = ProcessExecutor::escape($url);
  6442 
  6443 $process = new ProcessExecutor($this->getIO());
  6444 if (Platform::isWindows()) {
  6445 $process->execute('start "web" explorer ' . $url, $output);
  6446 
  6447 return;
  6448 }
  6449 
  6450 $linux = $process->execute('which xdg-open', $output);
  6451 $osx = $process->execute('which open', $output);
  6452 
  6453 if (0 === $linux) {
  6454 $process->execute('xdg-open ' . $url, $output);
  6455 } elseif (0 === $osx) {
  6456 $process->execute('open ' . $url, $output);
  6457 } else {
  6458 $this->getIO()->writeError('No suitable browser opening command found, open yourself: ' . $url);
  6459 }
  6460 }
  6461 
  6462 
  6463 
  6464 
  6465 
  6466 
  6467 
  6468 
  6469 private function initializeRepos()
  6470 {
  6471 $composer = $this->getComposer(false);
  6472 
  6473 if ($composer) {
  6474 return array_merge(
  6475 array(new RootPackageRepository($composer->getPackage())), 
  6476 array($composer->getRepositoryManager()->getLocalRepository()), 
  6477 $composer->getRepositoryManager()->getRepositories() 
  6478 );
  6479 }
  6480 
  6481 return RepositoryFactory::defaultRepos($this->getIO());
  6482 }
  6483 }
  6484 <?php
  6485 
  6486 
  6487 
  6488 
  6489 
  6490 
  6491 
  6492 
  6493 
  6494 
  6495 
  6496 namespace Composer\Command;
  6497 
  6498 use Composer\Factory;
  6499 use Composer\Filter\PlatformRequirementFilter\IgnoreAllPlatformRequirementFilter;
  6500 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  6501 use Composer\Json\JsonFile;
  6502 use Composer\Json\JsonValidationException;
  6503 use Composer\Package\BasePackage;
  6504 use Composer\Package\CompletePackageInterface;
  6505 use Composer\Package\Package;
  6506 use Composer\Package\PackageInterface;
  6507 use Composer\Package\Version\VersionParser;
  6508 use Composer\Package\Version\VersionSelector;
  6509 use Composer\Pcre\Preg;
  6510 use Composer\Repository\CompositeRepository;
  6511 use Composer\Repository\PlatformRepository;
  6512 use Composer\Repository\RepositoryFactory;
  6513 use Composer\Repository\RepositorySet;
  6514 use Composer\Util\Filesystem;
  6515 use Composer\Util\ProcessExecutor;
  6516 use Composer\Semver\Constraint\Constraint;
  6517 use Composer\Util\Silencer;
  6518 use Symfony\Component\Console\Input\ArrayInput;
  6519 use Symfony\Component\Console\Input\InputInterface;
  6520 use Symfony\Component\Console\Input\InputOption;
  6521 use Symfony\Component\Console\Output\OutputInterface;
  6522 use Symfony\Component\Process\ExecutableFinder;
  6523 use Symfony\Component\Process\Process;
  6524 use Symfony\Component\Console\Helper\FormatterHelper;
  6525 
  6526 
  6527 
  6528 
  6529 
  6530 class InitCommand extends BaseCommand
  6531 {
  6532 
  6533 protected $repos;
  6534 
  6535 
  6536 private $gitConfig;
  6537 
  6538 
  6539 private $repositorySets;
  6540 
  6541 
  6542 
  6543 
  6544 
  6545 
  6546 protected function configure()
  6547 {
  6548 $this
  6549 ->setName('init')
  6550 ->setDescription('Creates a basic composer.json file in current directory.')
  6551 ->setDefinition(array(
  6552 new InputOption('name', null, InputOption::VALUE_REQUIRED, 'Name of the package'),
  6553 new InputOption('description', null, InputOption::VALUE_REQUIRED, 'Description of package'),
  6554 new InputOption('author', null, InputOption::VALUE_REQUIRED, 'Author name of package'),
  6555 
  6556 new InputOption('type', null, InputOption::VALUE_OPTIONAL, 'Type of package (e.g. library, project, metapackage, composer-plugin)'),
  6557 new InputOption('homepage', null, InputOption::VALUE_REQUIRED, 'Homepage of package'),
  6558 new InputOption('require', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
  6559 new InputOption('require-dev', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Package to require for development with a version constraint, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
  6560 new InputOption('stability', 's', InputOption::VALUE_REQUIRED, 'Minimum stability (empty or one of: '.implode(', ', array_keys(BasePackage::$stabilities)).')'),
  6561 new InputOption('license', 'l', InputOption::VALUE_REQUIRED, 'License of package'),
  6562 new InputOption('repository', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Add custom repositories, either by URL or using JSON arrays'),
  6563 new InputOption('autoload', 'a', InputOption::VALUE_REQUIRED, 'Add PSR-4 autoload mapping. Maps your package\'s namespace to the provided directory. (Expects a relative path, e.g. src/)'),
  6564 ))
  6565 ->setHelp(
  6566 <<<EOT
  6567 The <info>init</info> command creates a basic composer.json file
  6568 in the current directory.
  6569 
  6570 <info>php composer.phar init</info>
  6571 
  6572 Read more at https://getcomposer.org/doc/03-cli.md#init
  6573 EOT
  6574 )
  6575 ;
  6576 }
  6577 
  6578 
  6579 
  6580 
  6581 
  6582 
  6583 
  6584 protected function execute(InputInterface $input, OutputInterface $output)
  6585 {
  6586 $io = $this->getIO();
  6587 
  6588 $allowlist = array('name', 'description', 'author', 'type', 'homepage', 'require', 'require-dev', 'stability', 'license', 'autoload');
  6589 $options = array_filter(array_intersect_key($input->getOptions(), array_flip($allowlist)));
  6590 
  6591 if (isset($options['name']) && !Preg::isMatch('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $options['name'])) {
  6592 throw new \InvalidArgumentException(
  6593 'The package name '.$options['name'].' is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+'
  6594 );
  6595 }
  6596 
  6597 if (isset($options['author'])) {
  6598 $options['authors'] = $this->formatAuthors($options['author']);
  6599 unset($options['author']);
  6600 }
  6601 
  6602 $repositories = $input->getOption('repository');
  6603 if ($repositories) {
  6604 $config = Factory::createConfig($io);
  6605 foreach ($repositories as $repo) {
  6606 $options['repositories'][] = RepositoryFactory::configFromString($io, $config, $repo, true);
  6607 }
  6608 }
  6609 
  6610 if (isset($options['stability'])) {
  6611 $options['minimum-stability'] = $options['stability'];
  6612 unset($options['stability']);
  6613 }
  6614 
  6615 $options['require'] = isset($options['require']) ? $this->formatRequirements($options['require']) : new \stdClass;
  6616 if (array() === $options['require']) {
  6617 $options['require'] = new \stdClass;
  6618 }
  6619 
  6620 if (isset($options['require-dev'])) {
  6621 $options['require-dev'] = $this->formatRequirements($options['require-dev']);
  6622 if (array() === $options['require-dev']) {
  6623 $options['require-dev'] = new \stdClass;
  6624 }
  6625 }
  6626 
  6627 
  6628 $autoloadPath = null;
  6629 if (isset($options['autoload'])) {
  6630 $autoloadPath = $options['autoload'];
  6631 $namespace = $this->namespaceFromPackageName($input->getOption('name'));
  6632 $options['autoload'] = (object) array(
  6633 'psr-4' => array(
  6634 $namespace . '\\' => $autoloadPath,
  6635 ),
  6636 );
  6637 }
  6638 
  6639 $file = new JsonFile(Factory::getComposerFile());
  6640 $json = JsonFile::encode($options);
  6641 
  6642 if ($input->isInteractive()) {
  6643 $io->writeError(array('', $json, ''));
  6644 if (!$io->askConfirmation('Do you confirm generation [<comment>yes</comment>]? ')) {
  6645 $io->writeError('<error>Command aborted</error>');
  6646 
  6647 return 1;
  6648 }
  6649 } else {
  6650 if (json_encode($options) === '{"require":{}}') {
  6651 throw new \RuntimeException('You have to run this command in interactive mode, or specify at least some data using --name, --require, etc.');
  6652 }
  6653 
  6654 $io->writeError('Writing '.$file->getPath());
  6655 }
  6656 
  6657 $file->write($options);
  6658 try {
  6659 $file->validateSchema(JsonFile::LAX_SCHEMA);
  6660 } catch (JsonValidationException $e) {
  6661 $io->writeError('<error>Schema validation error, aborting</error>');
  6662 $errors = ' - ' . implode(PHP_EOL . ' - ', $e->getErrors());
  6663 $io->writeError($e->getMessage() . ':' . PHP_EOL . $errors);
  6664 Silencer::call('unlink', $file->getPath());
  6665 
  6666 return 1;
  6667 }
  6668 
  6669 
  6670 if ($autoloadPath) {
  6671 $filesystem = new Filesystem();
  6672 $filesystem->ensureDirectoryExists($autoloadPath);
  6673 
  6674 
  6675 if (!$this->hasDependencies($options)) {
  6676 $this->runDumpAutoloadCommand($output);
  6677 }
  6678 }
  6679 
  6680 if ($input->isInteractive() && is_dir('.git')) {
  6681 $ignoreFile = realpath('.gitignore');
  6682 
  6683 if (false === $ignoreFile) {
  6684 $ignoreFile = realpath('.') . '/.gitignore';
  6685 }
  6686 
  6687 if (!$this->hasVendorIgnore($ignoreFile)) {
  6688 $question = 'Would you like the <info>vendor</info> directory added to your <info>.gitignore</info> [<comment>yes</comment>]? ';
  6689 
  6690 if ($io->askConfirmation($question)) {
  6691 $this->addVendorIgnore($ignoreFile);
  6692 }
  6693 }
  6694 }
  6695 
  6696 $question = 'Would you like to install dependencies now [<comment>yes</comment>]? ';
  6697 if ($input->isInteractive() && $this->hasDependencies($options) && $io->askConfirmation($question)) {
  6698 $this->updateDependencies($output);
  6699 }
  6700 
  6701 
  6702 if ($autoloadPath) {
  6703 $namespace = $this->namespaceFromPackageName($input->getOption('name'));
  6704 
  6705 $io->writeError('PSR-4 autoloading configured. Use "<comment>namespace '.$namespace.';</comment>" in '.$autoloadPath);
  6706 $io->writeError('Include the Composer autoloader with: <comment>require \'vendor/autoload.php\';</comment>');
  6707 }
  6708 
  6709 return 0;
  6710 }
  6711 
  6712 
  6713 
  6714 
  6715 
  6716 
  6717 protected function interact(InputInterface $input, OutputInterface $output)
  6718 {
  6719 $git = $this->getGitConfig();
  6720 $io = $this->getIO();
  6721 
  6722 $formatter = $this->getHelperSet()->get('formatter');
  6723 
  6724 
  6725 $repositories = $input->getOption('repository');
  6726 if ($repositories) {
  6727 $config = Factory::createConfig($io);
  6728 $repos = array(new PlatformRepository);
  6729 $createDefaultPackagistRepo = true;
  6730 foreach ($repositories as $repo) {
  6731 $repoConfig = RepositoryFactory::configFromString($io, $config, $repo, true);
  6732 if (
  6733 (isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
  6734 || (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
  6735 ) {
  6736 $createDefaultPackagistRepo = false;
  6737 continue;
  6738 }
  6739 $repos[] = RepositoryFactory::createRepo($io, $config, $repoConfig);
  6740 }
  6741 
  6742 if ($createDefaultPackagistRepo) {
  6743 $repos[] = RepositoryFactory::createRepo($io, $config, array(
  6744 'type' => 'composer',
  6745 'url' => 'https://repo.packagist.org',
  6746 ));
  6747 }
  6748 
  6749 $this->repos = new CompositeRepository($repos);
  6750 unset($repos, $config, $repositories);
  6751 }
  6752 
  6753 $io->writeError(array(
  6754 '',
  6755 $formatter->formatBlock('Welcome to the Composer config generator', 'bg=blue;fg=white', true),
  6756 '',
  6757 ));
  6758 
  6759 
  6760 $io->writeError(array(
  6761 '',
  6762 'This command will guide you through creating your composer.json config.',
  6763 '',
  6764 ));
  6765 
  6766 $cwd = realpath(".");
  6767 
  6768 if (!$name = $input->getOption('name')) {
  6769 $name = basename($cwd);
  6770 $name = Preg::replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $name);
  6771 $name = strtolower($name);
  6772 if (!empty($_SERVER['COMPOSER_DEFAULT_VENDOR'])) {
  6773 $name = $_SERVER['COMPOSER_DEFAULT_VENDOR'] . '/' . $name;
  6774 } elseif (isset($git['github.user'])) {
  6775 $name = $git['github.user'] . '/' . $name;
  6776 } elseif (!empty($_SERVER['USERNAME'])) {
  6777 $name = $_SERVER['USERNAME'] . '/' . $name;
  6778 } elseif (!empty($_SERVER['USER'])) {
  6779 $name = $_SERVER['USER'] . '/' . $name;
  6780 } elseif (get_current_user()) {
  6781 $name = get_current_user() . '/' . $name;
  6782 } else {
  6783 
  6784 $name .= '/' . $name;
  6785 }
  6786 $name = strtolower($name);
  6787 }
  6788 
  6789 $name = $io->askAndValidate(
  6790 'Package name (<vendor>/<name>) [<comment>'.$name.'</comment>]: ',
  6791 function ($value) use ($name) {
  6792 if (null === $value) {
  6793 return $name;
  6794 }
  6795 
  6796 if (!Preg::isMatch('{^[a-z0-9_.-]+/[a-z0-9_.-]+$}D', $value)) {
  6797 throw new \InvalidArgumentException(
  6798 'The package name '.$value.' is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+'
  6799 );
  6800 }
  6801 
  6802 return $value;
  6803 },
  6804 null,
  6805 $name
  6806 );
  6807 $input->setOption('name', $name);
  6808 
  6809 $description = $input->getOption('description') ?: false;
  6810 $description = $io->ask(
  6811 'Description [<comment>'.$description.'</comment>]: ',
  6812 $description
  6813 );
  6814 $input->setOption('description', $description);
  6815 
  6816 if (null === $author = $input->getOption('author')) {
  6817 if (!empty($_SERVER['COMPOSER_DEFAULT_AUTHOR'])) {
  6818 $author_name = $_SERVER['COMPOSER_DEFAULT_AUTHOR'];
  6819 } elseif (isset($git['user.name'])) {
  6820 $author_name = $git['user.name'];
  6821 }
  6822 
  6823 if (!empty($_SERVER['COMPOSER_DEFAULT_EMAIL'])) {
  6824 $author_email = $_SERVER['COMPOSER_DEFAULT_EMAIL'];
  6825 } elseif (isset($git['user.email'])) {
  6826 $author_email = $git['user.email'];
  6827 }
  6828 
  6829 if (isset($author_name, $author_email)) {
  6830 $author = sprintf('%s <%s>', $author_name, $author_email);
  6831 }
  6832 }
  6833 
  6834 $self = $this;
  6835 $author = $io->askAndValidate(
  6836 'Author ['.(is_string($author) ? '<comment>'.$author.'</comment>, ' : '') . 'n to skip]: ',
  6837 function ($value) use ($self, $author) {
  6838 if ($value === 'n' || $value === 'no') {
  6839 return;
  6840 }
  6841 $value = $value ?: $author;
  6842 $author = $self->parseAuthorString($value);
  6843 
  6844 if ($author['email'] === null) {
  6845 return $author['name'];
  6846 }
  6847 
  6848 return sprintf('%s <%s>', $author['name'], $author['email']);
  6849 },
  6850 null,
  6851 $author
  6852 );
  6853 $input->setOption('author', $author);
  6854 
  6855 $minimumStability = $input->getOption('stability') ?: null;
  6856 $minimumStability = $io->askAndValidate(
  6857 'Minimum Stability [<comment>'.$minimumStability.'</comment>]: ',
  6858 function ($value) use ($minimumStability) {
  6859 if (null === $value) {
  6860 return $minimumStability;
  6861 }
  6862 
  6863 if (!isset(BasePackage::$stabilities[$value])) {
  6864 throw new \InvalidArgumentException(
  6865 'Invalid minimum stability "'.$value.'". Must be empty or one of: '.
  6866 implode(', ', array_keys(BasePackage::$stabilities))
  6867 );
  6868 }
  6869 
  6870 return $value;
  6871 },
  6872 null,
  6873 $minimumStability
  6874 );
  6875 $input->setOption('stability', $minimumStability);
  6876 
  6877 $type = $input->getOption('type') ?: false;
  6878 $type = $io->ask(
  6879 'Package Type (e.g. library, project, metapackage, composer-plugin) [<comment>'.$type.'</comment>]: ',
  6880 $type
  6881 );
  6882 $input->setOption('type', $type);
  6883 
  6884 if (null === $license = $input->getOption('license')) {
  6885 if (!empty($_SERVER['COMPOSER_DEFAULT_LICENSE'])) {
  6886 $license = $_SERVER['COMPOSER_DEFAULT_LICENSE'];
  6887 }
  6888 }
  6889 
  6890 $license = $io->ask(
  6891 'License [<comment>'.$license.'</comment>]: ',
  6892 $license
  6893 );
  6894 $input->setOption('license', $license);
  6895 
  6896 $io->writeError(array('', 'Define your dependencies.', ''));
  6897 
  6898 
  6899 $repos = $this->getRepos();
  6900 $preferredStability = $minimumStability ?: 'stable';
  6901 $platformRepo = null;
  6902 if ($repos instanceof CompositeRepository) {
  6903 foreach ($repos->getRepositories() as $candidateRepo) {
  6904 if ($candidateRepo instanceof PlatformRepository) {
  6905 $platformRepo = $candidateRepo;
  6906 break;
  6907 }
  6908 }
  6909 }
  6910 
  6911 $question = 'Would you like to define your dependencies (require) interactively [<comment>yes</comment>]? ';
  6912 $require = $input->getOption('require');
  6913 $requirements = array();
  6914 if ($require || $io->askConfirmation($question)) {
  6915 $requirements = $this->determineRequirements($input, $output, $require, $platformRepo, $preferredStability);
  6916 }
  6917 $input->setOption('require', $requirements);
  6918 
  6919 $question = 'Would you like to define your dev dependencies (require-dev) interactively [<comment>yes</comment>]? ';
  6920 $requireDev = $input->getOption('require-dev');
  6921 $devRequirements = array();
  6922 if ($requireDev || $io->askConfirmation($question)) {
  6923 $devRequirements = $this->determineRequirements($input, $output, $requireDev, $platformRepo, $preferredStability);
  6924 }
  6925 $input->setOption('require-dev', $devRequirements);
  6926 
  6927 
  6928 $autoload = $input->getOption('autoload') ?: 'src/';
  6929 $namespace = $this->namespaceFromPackageName($input->getOption('name'));
  6930 $autoload = $io->askAndValidate(
  6931 'Add PSR-4 autoload mapping? Maps namespace "'.$namespace.'" to the entered relative path. [<comment>'.$autoload.'</comment>, n to skip]: ',
  6932 function ($value) use ($autoload) {
  6933 if (null === $value) {
  6934 return $autoload;
  6935 }
  6936 
  6937 if ($value === 'n' || $value === 'no') {
  6938 return;
  6939 }
  6940 
  6941 $value = $value ?: $autoload;
  6942 
  6943 if (!Preg::isMatch('{^[^/][A-Za-z0-9\-_/]+/$}', $value)) {
  6944 throw new \InvalidArgumentException(sprintf(
  6945 'The src folder name "%s" is invalid. Please add a relative path with tailing forward slash. [A-Za-z0-9_-/]+/',
  6946 $value
  6947 ));
  6948 }
  6949 
  6950 return $value;
  6951 },
  6952 null,
  6953 $autoload
  6954 );
  6955 $input->setOption('autoload', $autoload);
  6956 }
  6957 
  6958 
  6959 
  6960 
  6961 
  6962 
  6963 public function parseAuthorString($author)
  6964 {
  6965 if (Preg::isMatch('/^(?P<name>[- .,\p{L}\p{N}\p{Mn}\'’"()]+)(?:\s+<(?P<email>.+?)>)?$/u', $author, $match)) {
  6966 $hasEmail = isset($match['email']) && '' !== $match['email'];
  6967 if ($hasEmail && !$this->isValidEmail($match['email'])) {
  6968 throw new \InvalidArgumentException('Invalid email "'.$match['email'].'"');
  6969 }
  6970 
  6971 return array(
  6972 'name' => trim($match['name']),
  6973 'email' => $hasEmail ? $match['email'] : null,
  6974 );
  6975 }
  6976 
  6977 throw new \InvalidArgumentException(
  6978 'Invalid author string.  Must be in the formats: '.
  6979 'Jane Doe or John Smith <john@example.com>'
  6980 );
  6981 }
  6982 
  6983 
  6984 
  6985 
  6986 protected function getRepos()
  6987 {
  6988 if (!$this->repos) {
  6989 $this->repos = new CompositeRepository(array_merge(
  6990 array(new PlatformRepository),
  6991 RepositoryFactory::defaultRepos($this->getIO())
  6992 ));
  6993 }
  6994 
  6995 return $this->repos;
  6996 }
  6997 
  6998 
  6999 
  7000 
  7001 
  7002 
  7003 
  7004 
  7005 
  7006 
  7007 
  7008 final protected function determineRequirements(InputInterface $input, OutputInterface $output, $requires = array(), PlatformRepository $platformRepo = null, $preferredStability = 'stable', $checkProvidedVersions = true, $fixed = false)
  7009 {
  7010 if ($requires) {
  7011 $requires = $this->normalizeRequirements($requires);
  7012 $result = array();
  7013 $io = $this->getIO();
  7014 
  7015 foreach ($requires as $requirement) {
  7016 if (!isset($requirement['version'])) {
  7017 
  7018 list($name, $version) = $this->findBestVersionAndNameForPackage($input, $requirement['name'], $platformRepo, $preferredStability, null, null, $fixed);
  7019 $requirement['version'] = $version;
  7020 
  7021 
  7022 $requirement['name'] = $name;
  7023 
  7024 $io->writeError(sprintf(
  7025 'Using version <info>%s</info> for <info>%s</info>',
  7026 $requirement['version'],
  7027 $requirement['name']
  7028 ));
  7029 }
  7030 
  7031 $result[] = $requirement['name'] . ' ' . $requirement['version'];
  7032 }
  7033 
  7034 return $result;
  7035 }
  7036 
  7037 $versionParser = new VersionParser();
  7038 
  7039 
  7040 $composer = $this->getComposer(false);
  7041 $installedRepo = $composer ? $composer->getRepositoryManager()->getLocalRepository() : null;
  7042 $existingPackages = array();
  7043 if ($installedRepo) {
  7044 foreach ($installedRepo->getPackages() as $package) {
  7045 $existingPackages[] = $package->getName();
  7046 }
  7047 }
  7048 unset($composer, $installedRepo);
  7049 
  7050 $io = $this->getIO();
  7051 while (null !== $package = $io->ask('Search for a package: ')) {
  7052 $matches = $this->getRepos()->search($package);
  7053 
  7054 if (count($matches)) {
  7055 
  7056 foreach ($matches as $position => $foundPackage) {
  7057 if (in_array($foundPackage['name'], $existingPackages, true)) {
  7058 unset($matches[$position]);
  7059 }
  7060 }
  7061 $matches = array_values($matches);
  7062 
  7063 $exactMatch = false;
  7064 foreach ($matches as $match) {
  7065 if ($match['name'] === $package) {
  7066 $exactMatch = true;
  7067 break;
  7068 }
  7069 }
  7070 
  7071 
  7072 if (!$exactMatch) {
  7073 $providers = $this->getRepos()->getProviders($package);
  7074 if (count($providers) > 0) {
  7075 array_unshift($matches, array('name' => $package, 'description' => ''));
  7076 }
  7077 
  7078 $choices = array();
  7079 foreach ($matches as $position => $foundPackage) {
  7080 $abandoned = '';
  7081 if (isset($foundPackage['abandoned'])) {
  7082 if (is_string($foundPackage['abandoned'])) {
  7083 $replacement = sprintf('Use %s instead', $foundPackage['abandoned']);
  7084 } else {
  7085 $replacement = 'No replacement was suggested';
  7086 }
  7087 $abandoned = sprintf('<warning>Abandoned. %s.</warning>', $replacement);
  7088 }
  7089 
  7090 $choices[] = sprintf(' <info>%5s</info> %s %s', "[$position]", $foundPackage['name'], $abandoned);
  7091 }
  7092 
  7093 $io->writeError(array(
  7094 '',
  7095 sprintf('Found <info>%s</info> packages matching <info>%s</info>', count($matches), $package),
  7096 '',
  7097 ));
  7098 
  7099 $io->writeError($choices);
  7100 $io->writeError('');
  7101 
  7102 $validator = function ($selection) use ($matches, $versionParser) {
  7103 if ('' === $selection) {
  7104 return false;
  7105 }
  7106 
  7107 if (is_numeric($selection) && isset($matches[(int) $selection])) {
  7108 $package = $matches[(int) $selection];
  7109 
  7110 return $package['name'];
  7111 }
  7112 
  7113 if (Preg::isMatch('{^\s*(?P<name>[\S/]+)(?:\s+(?P<version>\S+))?\s*$}', $selection, $packageMatches)) {
  7114 if (isset($packageMatches['version'])) {
  7115 
  7116 
  7117 
  7118 $versionParser->parseConstraints($packageMatches['version']);
  7119 
  7120 return $packageMatches['name'].' '.$packageMatches['version'];
  7121 }
  7122 
  7123 
  7124 return $packageMatches['name'];
  7125 }
  7126 
  7127 throw new \Exception('Not a valid selection');
  7128 };
  7129 
  7130 $package = $io->askAndValidate(
  7131 'Enter package # to add, or the complete package name if it is not listed: ',
  7132 $validator,
  7133 3,
  7134 false
  7135 );
  7136 }
  7137 
  7138 
  7139 if (false !== $package && false === strpos($package, ' ')) {
  7140 $validator = function ($input) {
  7141 $input = trim($input);
  7142 
  7143 return $input ?: false;
  7144 };
  7145 
  7146 $constraint = $io->askAndValidate(
  7147 'Enter the version constraint to require (or leave blank to use the latest version): ',
  7148 $validator,
  7149 3,
  7150 false
  7151 );
  7152 
  7153 if (false === $constraint) {
  7154 list(, $constraint) = $this->findBestVersionAndNameForPackage($input, $package, $platformRepo, $preferredStability);
  7155 
  7156 $io->writeError(sprintf(
  7157 'Using version <info>%s</info> for <info>%s</info>',
  7158 $constraint,
  7159 $package
  7160 ));
  7161 }
  7162 
  7163 $package .= ' '.$constraint;
  7164 }
  7165 
  7166 if (false !== $package) {
  7167 $requires[] = $package;
  7168 $existingPackages[] = substr($package, 0, strpos($package, ' '));
  7169 }
  7170 }
  7171 }
  7172 
  7173 return $requires;
  7174 }
  7175 
  7176 
  7177 
  7178 
  7179 
  7180 
  7181 protected function formatAuthors($author)
  7182 {
  7183 $author = $this->parseAuthorString($author);
  7184 if (null === $author['email']) {
  7185 unset($author['email']);
  7186 }
  7187 
  7188 return array($author);
  7189 }
  7190 
  7191 
  7192 
  7193 
  7194 
  7195 
  7196 
  7197 
  7198 
  7199 
  7200 public function namespaceFromPackageName($packageName)
  7201 {
  7202 if (!$packageName || strpos($packageName, '/') === false) {
  7203 return null;
  7204 }
  7205 
  7206 $namespace = array_map(
  7207 function ($part) {
  7208 $part = Preg::replace('/[^a-z0-9]/i', ' ', $part);
  7209 $part = ucwords($part);
  7210 
  7211 return str_replace(' ', '', $part);
  7212 },
  7213 explode('/', $packageName)
  7214 );
  7215 
  7216 return join('\\', $namespace);
  7217 }
  7218 
  7219 
  7220 
  7221 
  7222 protected function getGitConfig()
  7223 {
  7224 if (null !== $this->gitConfig) {
  7225 return $this->gitConfig;
  7226 }
  7227 
  7228 $finder = new ExecutableFinder();
  7229 $gitBin = $finder->find('git');
  7230 
  7231 
  7232 if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
  7233 $cmd = new Process(array($gitBin, 'config', '-l'));
  7234 } else {
  7235 
  7236 $cmd = new Process(sprintf('%s config -l', ProcessExecutor::escape($gitBin)));
  7237 }
  7238 $cmd->run();
  7239 
  7240 if ($cmd->isSuccessful()) {
  7241 $this->gitConfig = array();
  7242 Preg::matchAll('{^([^=]+)=(.*)$}m', $cmd->getOutput(), $matches);
  7243 foreach ($matches[1] as $key => $match) {
  7244 $this->gitConfig[$match] = $matches[2][$key];
  7245 }
  7246 
  7247 return $this->gitConfig;
  7248 }
  7249 
  7250 return $this->gitConfig = array();
  7251 }
  7252 
  7253 
  7254 
  7255 
  7256 
  7257 
  7258 
  7259 
  7260 
  7261 
  7262 
  7263 
  7264 
  7265 
  7266 
  7267 
  7268 
  7269 protected function hasVendorIgnore($ignoreFile, $vendor = 'vendor')
  7270 {
  7271 if (!file_exists($ignoreFile)) {
  7272 return false;
  7273 }
  7274 
  7275 $pattern = sprintf('{^/?%s(/\*?)?$}', preg_quote($vendor));
  7276 
  7277 $lines = file($ignoreFile, FILE_IGNORE_NEW_LINES);
  7278 foreach ($lines as $line) {
  7279 if (Preg::isMatch($pattern, $line)) {
  7280 return true;
  7281 }
  7282 }
  7283 
  7284 return false;
  7285 }
  7286 
  7287 
  7288 
  7289 
  7290 
  7291 
  7292 
  7293 protected function addVendorIgnore($ignoreFile, $vendor = '/vendor/')
  7294 {
  7295 $contents = "";
  7296 if (file_exists($ignoreFile)) {
  7297 $contents = file_get_contents($ignoreFile);
  7298 
  7299 if (strpos($contents, "\n") !== 0) {
  7300 $contents .= "\n";
  7301 }
  7302 }
  7303 
  7304 file_put_contents($ignoreFile, $contents . $vendor. "\n");
  7305 }
  7306 
  7307 
  7308 
  7309 
  7310 
  7311 
  7312 protected function isValidEmail($email)
  7313 {
  7314 
  7315 if (!function_exists('filter_var')) {
  7316 return true;
  7317 }
  7318 
  7319 
  7320 if (PHP_VERSION_ID < 50303) {
  7321 return true;
  7322 }
  7323 
  7324 return false !== filter_var($email, FILTER_VALIDATE_EMAIL);
  7325 }
  7326 
  7327 
  7328 
  7329 
  7330 
  7331 
  7332 private function getRepositorySet(InputInterface $input, $minimumStability = null)
  7333 {
  7334 $key = $minimumStability ?: 'default';
  7335 
  7336 if (!isset($this->repositorySets[$key])) {
  7337 $this->repositorySets[$key] = $repositorySet = new RepositorySet($minimumStability ?: $this->getMinimumStability($input));
  7338 $repositorySet->addRepository($this->getRepos());
  7339 }
  7340 
  7341 return $this->repositorySets[$key];
  7342 }
  7343 
  7344 
  7345 
  7346 
  7347 private function getMinimumStability(InputInterface $input)
  7348 {
  7349 if ($input->hasOption('stability')) {
  7350 return VersionParser::normalizeStability($input->getOption('stability') ?: 'stable');
  7351 }
  7352 
  7353 $file = Factory::getComposerFile();
  7354 if (is_file($file) && Filesystem::isReadable($file) && is_array($composer = json_decode(file_get_contents($file), true))) {
  7355 if (!empty($composer['minimum-stability'])) {
  7356 return VersionParser::normalizeStability($composer['minimum-stability']);
  7357 }
  7358 }
  7359 
  7360 return 'stable';
  7361 }
  7362 
  7363 
  7364 
  7365 
  7366 
  7367 
  7368 
  7369 
  7370 
  7371 
  7372 
  7373 
  7374 
  7375 
  7376 
  7377 private function findBestVersionAndNameForPackage(InputInterface $input, $name, PlatformRepository $platformRepo = null, $preferredStability = 'stable', $requiredVersion = null, $minimumStability = null, $fixed = null)
  7378 {
  7379 
  7380 $ignorePlatformReqs = false;
  7381 if ($input->hasOption('ignore-platform-reqs') && $input->hasOption('ignore-platform-req')) {
  7382 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  7383 }
  7384 $platformRequirementFilter = PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs);
  7385 
  7386 
  7387 $repoSet = $this->getRepositorySet($input, $minimumStability);
  7388 $versionSelector = new VersionSelector($repoSet, $platformRepo);
  7389 $effectiveMinimumStability = $minimumStability ?: $this->getMinimumStability($input);
  7390 
  7391 $package = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter);
  7392 
  7393 if (!$package) {
  7394 
  7395 
  7396 if ($platformRequirementFilter->isIgnored($name)) {
  7397 return array($name, $requiredVersion ?: '*');
  7398 }
  7399 
  7400 
  7401 $providers = $repoSet->getProviders($name);
  7402 if (count($providers) > 0) {
  7403 $constraint = '*';
  7404 if ($input->isInteractive()) {
  7405 $constraint = $this->getIO()->askAndValidate('Package "<info>'.$name.'</info>" does not exist but is provided by '.count($providers).' packages. Which version constraint would you like to use? [<info>*</info>] ', function ($value) {
  7406 $parser = new VersionParser();
  7407 $parser->parseConstraints($value);
  7408 
  7409 return $value;
  7410 }, 3, '*');
  7411 }
  7412 
  7413 return array($name, $constraint);
  7414 }
  7415 
  7416 
  7417 if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && ($candidate = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, PlatformRequirementFilterFactory::ignoreAll()))) {
  7418 throw new \InvalidArgumentException(sprintf(
  7419 'Package %s%s has requirements incompatible with your PHP version, PHP extensions and Composer version' . $this->getPlatformExceptionDetails($candidate, $platformRepo),
  7420 $name,
  7421 $requiredVersion ? ' at version '.$requiredVersion : ''
  7422 ));
  7423 }
  7424 
  7425 if ($package = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) {
  7426 
  7427 if ($allReposPackage = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, $platformRequirementFilter, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
  7428 throw new \InvalidArgumentException(
  7429 'Package '.$name.' exists in '.$allReposPackage->getRepository()->getRepoName().' and '.$package->getRepository()->getRepoName().' which has a higher repository priority. The packages from the higher priority repository do not match your minimum-stability and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.'
  7430 );
  7431 }
  7432 
  7433 throw new \InvalidArgumentException(sprintf(
  7434 'Could not find a version of package %s matching your minimum-stability (%s). Require it with an explicit version constraint allowing its desired stability.',
  7435 $name,
  7436 $effectiveMinimumStability
  7437 ));
  7438 }
  7439 
  7440 if ($requiredVersion && $package = $versionSelector->findBestCandidate($name, null, $preferredStability, $platformRequirementFilter)) {
  7441 
  7442 if ($allReposPackage = $versionSelector->findBestCandidate($name, $requiredVersion, $preferredStability, PlatformRequirementFilterFactory::ignoreNothing(), RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
  7443 throw new \InvalidArgumentException(
  7444 'Package '.$name.' exists in '.$allReposPackage->getRepository()->getRepoName().' and '.$package->getRepository()->getRepoName().' which has a higher repository priority. The packages from the higher priority repository do not match your constraint and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.'
  7445 );
  7446 }
  7447 
  7448 throw new \InvalidArgumentException(sprintf(
  7449 'Could not find package %s in a version matching "%s" and a stability matching "'.$effectiveMinimumStability.'".',
  7450 $name,
  7451 $requiredVersion
  7452 ));
  7453 }
  7454 
  7455 if (!($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter) && ($candidate = $versionSelector->findBestCandidate($name, null, $preferredStability, PlatformRequirementFilterFactory::ignoreAll(), RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES))) {
  7456 $additional = '';
  7457 if (false === $versionSelector->findBestCandidate($name, null, $preferredStability, PlatformRequirementFilterFactory::ignoreAll())) {
  7458 $additional = PHP_EOL.PHP_EOL.'Additionally, the package was only found with a stability of "'.$candidate->getStability().'" while your minimum stability is "'.$effectiveMinimumStability.'".';
  7459 }
  7460 
  7461 throw new \InvalidArgumentException(sprintf(
  7462 'Could not find package %s in any version matching your PHP version, PHP extensions and Composer version' . $this->getPlatformExceptionDetails($candidate, $platformRepo) . '%s',
  7463 $name,
  7464 $additional
  7465 ));
  7466 }
  7467 
  7468 
  7469 $similar = $this->findSimilar($name);
  7470 if ($similar) {
  7471 if (in_array($name, $similar, true)) {
  7472 throw new \InvalidArgumentException(sprintf(
  7473 "Could not find package %s. It was however found via repository search, which indicates a consistency issue with the repository.",
  7474 $name
  7475 ));
  7476 }
  7477 
  7478 throw new \InvalidArgumentException(sprintf(
  7479 "Could not find package %s.\n\nDid you mean " . (count($similar) > 1 ? 'one of these' : 'this') . "?\n    %s",
  7480 $name,
  7481 implode("\n    ", $similar)
  7482 ));
  7483 }
  7484 
  7485 throw new \InvalidArgumentException(sprintf(
  7486 'Could not find a matching version of package %s. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability (%s).',
  7487 $name,
  7488 $effectiveMinimumStability
  7489 ));
  7490 }
  7491 
  7492 return array(
  7493 $package->getPrettyName(),
  7494 $fixed ? $package->getPrettyVersion() : $versionSelector->findRecommendedRequireVersion($package),
  7495 );
  7496 }
  7497 
  7498 
  7499 
  7500 
  7501 private function getPlatformExceptionDetails(PackageInterface $candidate, PlatformRepository $platformRepo = null)
  7502 {
  7503 $details = array();
  7504 if (!$platformRepo) {
  7505 return '';
  7506 }
  7507 
  7508 foreach ($candidate->getRequires() as $link) {
  7509 if (!PlatformRepository::isPlatformPackage($link->getTarget())) {
  7510 continue;
  7511 }
  7512 $platformPkg = $platformRepo->findPackage($link->getTarget(), '*');
  7513 if (!$platformPkg) {
  7514 if ($platformRepo->isPlatformPackageDisabled($link->getTarget())) {
  7515 $details[] = $candidate->getPrettyName().' '.$candidate->getPrettyVersion().' requires '.$link->getTarget().' '.$link->getPrettyConstraint().' but it is disabled by your platform config. Enable it again with "composer config platform.'.$link->getTarget().' --unset".';
  7516 } else {
  7517 $details[] = $candidate->getPrettyName().' '.$candidate->getPrettyVersion().' requires '.$link->getTarget().' '.$link->getPrettyConstraint().' but it is not present.';
  7518 }
  7519 continue;
  7520 }
  7521 if (!$link->getConstraint()->matches(new Constraint('==', $platformPkg->getVersion()))) {
  7522 $platformPkgVersion = $platformPkg->getPrettyVersion();
  7523 $platformExtra = $platformPkg->getExtra();
  7524 if (isset($platformExtra['config.platform']) && $platformPkg instanceof CompletePackageInterface) {
  7525 $platformPkgVersion .= ' ('.$platformPkg->getDescription().')';
  7526 }
  7527 $details[] = $candidate->getPrettyName().' '.$candidate->getPrettyVersion().' requires '.$link->getTarget().' '.$link->getPrettyConstraint().' which does not match your installed version '.$platformPkgVersion.'.';
  7528 }
  7529 }
  7530 
  7531 if (!$details) {
  7532 return '';
  7533 }
  7534 
  7535 return ':'.PHP_EOL.'  - ' . implode(PHP_EOL.'  - ', $details);
  7536 }
  7537 
  7538 
  7539 
  7540 
  7541 
  7542 
  7543 private function findSimilar($package)
  7544 {
  7545 try {
  7546 $results = $this->repos->search($package);
  7547 } catch (\Exception $e) {
  7548 
  7549 return array();
  7550 }
  7551 $similarPackages = array();
  7552 
  7553 $installedRepo = $this->getComposer()->getRepositoryManager()->getLocalRepository();
  7554 
  7555 foreach ($results as $result) {
  7556 if ($installedRepo->findPackage($result['name'], '*')) {
  7557 
  7558 continue;
  7559 }
  7560 $similarPackages[$result['name']] = levenshtein($package, $result['name']);
  7561 }
  7562 asort($similarPackages);
  7563 
  7564 return array_keys(array_slice($similarPackages, 0, 5));
  7565 }
  7566 
  7567 
  7568 
  7569 
  7570 private function updateDependencies(OutputInterface $output)
  7571 {
  7572 try {
  7573 $updateCommand = $this->getApplication()->find('update');
  7574 $this->getApplication()->resetComposer();
  7575 $updateCommand->run(new ArrayInput(array()), $output);
  7576 } catch (\Exception $e) {
  7577 $this->getIO()->writeError('Could not update dependencies. Run `composer update` to see more information.');
  7578 }
  7579 }
  7580 
  7581 
  7582 
  7583 
  7584 private function runDumpAutoloadCommand(OutputInterface $output)
  7585 {
  7586 try {
  7587 $command = $this->getApplication()->find('dump-autoload');
  7588 $this->getApplication()->resetComposer();
  7589 $command->run(new ArrayInput(array()), $output);
  7590 } catch (\Exception $e) {
  7591 $this->getIO()->writeError('Could not run dump-autoload.');
  7592 }
  7593 }
  7594 
  7595 
  7596 
  7597 
  7598 
  7599 private function hasDependencies($options)
  7600 {
  7601 $requires = (array) $options['require'];
  7602 $devRequires = isset($options['require-dev']) ? (array) $options['require-dev'] : array();
  7603 
  7604 return !empty($requires) || !empty($devRequires);
  7605 }
  7606 }
  7607 <?php
  7608 
  7609 
  7610 
  7611 
  7612 
  7613 
  7614 
  7615 
  7616 
  7617 
  7618 
  7619 namespace Composer\Command;
  7620 
  7621 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  7622 use Composer\Installer;
  7623 use Composer\Plugin\CommandEvent;
  7624 use Composer\Plugin\PluginEvents;
  7625 use Composer\Util\HttpDownloader;
  7626 use Symfony\Component\Console\Input\InputInterface;
  7627 use Symfony\Component\Console\Input\InputOption;
  7628 use Symfony\Component\Console\Input\InputArgument;
  7629 use Symfony\Component\Console\Output\OutputInterface;
  7630 
  7631 
  7632 
  7633 
  7634 
  7635 
  7636 
  7637 class InstallCommand extends BaseCommand
  7638 {
  7639 
  7640 
  7641 
  7642 protected function configure()
  7643 {
  7644 $this
  7645 ->setName('install')
  7646 ->setAliases(array('i'))
  7647 ->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.')
  7648 ->setDefinition(array(
  7649 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
  7650 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
  7651 new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'),
  7652 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
  7653 new InputOption('dev', null, InputOption::VALUE_NONE, 'DEPRECATED: Enables installation of require-dev packages (enabled by default, only present for BC).'),
  7654 new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'),
  7655 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
  7656 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
  7657 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
  7658 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Do not use, only defined here to catch misuse of the install command.'),
  7659 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
  7660 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
  7661 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
  7662 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
  7663 new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
  7664 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
  7665 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
  7666 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'),
  7667 ))
  7668 ->setHelp(
  7669 <<<EOT
  7670 The <info>install</info> command reads the composer.lock file from
  7671 the current directory, processes it, and downloads and installs all the
  7672 libraries and dependencies outlined in that file. If the file does not
  7673 exist it will look for composer.json and do the same.
  7674 
  7675 <info>php composer.phar install</info>
  7676 
  7677 Read more at https://getcomposer.org/doc/03-cli.md#install-i
  7678 EOT
  7679 )
  7680 ;
  7681 }
  7682 
  7683 protected function execute(InputInterface $input, OutputInterface $output)
  7684 {
  7685 $io = $this->getIO();
  7686 if ($input->getOption('dev')) {
  7687 $io->writeError('<warning>You are using the deprecated option "--dev". It has no effect and will break in Composer 3.</warning>');
  7688 }
  7689 if ($input->getOption('no-suggest')) {
  7690 $io->writeError('<warning>You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.</warning>');
  7691 }
  7692 
  7693 if ($args = $input->getArgument('packages')) {
  7694 $io->writeError('<error>Invalid argument '.implode(' ', $args).'. Use "composer require '.implode(' ', $args).'" instead to add packages to your composer.json.</error>');
  7695 
  7696 return 1;
  7697 }
  7698 
  7699 if ($input->getOption('no-install')) {
  7700 $io->writeError('<error>Invalid option "--no-install". Use "composer update --no-install" instead if you are trying to update the composer.lock file.</error>');
  7701 
  7702 return 1;
  7703 }
  7704 
  7705 $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
  7706 
  7707 if ((!$composer->getLocker() || !$composer->getLocker()->isLocked()) && !HttpDownloader::isCurlEnabled()) {
  7708 $io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>');
  7709 }
  7710 
  7711 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'install', $input, $output);
  7712 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  7713 
  7714 $install = Installer::create($io, $composer);
  7715 
  7716 $config = $composer->getConfig();
  7717 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
  7718 
  7719 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
  7720 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
  7721 $apcuPrefix = $input->getOption('apcu-autoloader-prefix');
  7722 $apcu = $apcuPrefix !== null || $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader');
  7723 
  7724 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  7725 
  7726 $composer->getInstallationManager()->setOutputProgress(!$input->getOption('no-progress'));
  7727 
  7728 $install
  7729 ->setDryRun($input->getOption('dry-run'))
  7730 ->setVerbose($input->getOption('verbose'))
  7731 ->setPreferSource($preferSource)
  7732 ->setPreferDist($preferDist)
  7733 ->setDevMode(!$input->getOption('no-dev'))
  7734 ->setDumpAutoloader(!$input->getOption('no-autoloader'))
  7735 ->setOptimizeAutoloader($optimize)
  7736 ->setClassMapAuthoritative($authoritative)
  7737 ->setApcuAutoloader($apcu, $apcuPrefix)
  7738 ->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs))
  7739 ;
  7740 
  7741 if ($input->getOption('no-plugins')) {
  7742 $install->disablePlugins();
  7743 }
  7744 
  7745 return $install->run();
  7746 }
  7747 }
  7748 <?php
  7749 
  7750 
  7751 
  7752 
  7753 
  7754 
  7755 
  7756 
  7757 
  7758 
  7759 
  7760 namespace Composer\Command;
  7761 
  7762 use Composer\Json\JsonFile;
  7763 use Composer\Package\CompletePackageInterface;
  7764 use Composer\Plugin\CommandEvent;
  7765 use Composer\Plugin\PluginEvents;
  7766 use Composer\Package\PackageInterface;
  7767 use Composer\Repository\RepositoryInterface;
  7768 use Symfony\Component\Console\Helper\Table;
  7769 use Symfony\Component\Console\Input\InputInterface;
  7770 use Symfony\Component\Console\Input\InputOption;
  7771 use Symfony\Component\Console\Output\OutputInterface;
  7772 use Symfony\Component\Console\Style\SymfonyStyle;
  7773 
  7774 
  7775 
  7776 
  7777 class LicensesCommand extends BaseCommand
  7778 {
  7779 
  7780 
  7781 
  7782 protected function configure()
  7783 {
  7784 $this
  7785 ->setName('licenses')
  7786 ->setDescription('Shows information about licenses of dependencies.')
  7787 ->setDefinition(array(
  7788 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text, json or summary', 'text'),
  7789 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
  7790 ))
  7791 ->setHelp(
  7792 <<<EOT
  7793 The license command displays detailed information about the licenses of
  7794 the installed dependencies.
  7795 
  7796 Read more at https://getcomposer.org/doc/03-cli.md#licenses
  7797 EOT
  7798 )
  7799 ;
  7800 }
  7801 
  7802 
  7803 
  7804 
  7805 protected function execute(InputInterface $input, OutputInterface $output)
  7806 {
  7807 $composer = $this->getComposer();
  7808 
  7809 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'licenses', $input, $output);
  7810 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  7811 
  7812 $root = $composer->getPackage();
  7813 $repo = $composer->getRepositoryManager()->getLocalRepository();
  7814 
  7815 if ($input->getOption('no-dev')) {
  7816 $packages = $this->filterRequiredPackages($repo, $root);
  7817 } else {
  7818 $packages = $this->appendPackages($repo->getPackages(), array());
  7819 }
  7820 
  7821 ksort($packages);
  7822 $io = $this->getIO();
  7823 
  7824 switch ($format = $input->getOption('format')) {
  7825 case 'text':
  7826 $io->write('Name: <comment>'.$root->getPrettyName().'</comment>');
  7827 $io->write('Version: <comment>'.$root->getFullPrettyVersion().'</comment>');
  7828 $io->write('Licenses: <comment>'.(implode(', ', $root->getLicense()) ?: 'none').'</comment>');
  7829 $io->write('Dependencies:');
  7830 $io->write('');
  7831 
  7832 $table = new Table($output);
  7833 $table->setStyle('compact');
  7834 $tableStyle = $table->getStyle();
  7835 if (method_exists($tableStyle, 'setVerticalBorderChars')) {
  7836 $tableStyle->setVerticalBorderChars('');
  7837 } else {
  7838 
  7839 
  7840 $tableStyle->setVerticalBorderChar('');
  7841 }
  7842 $tableStyle->setCellRowContentFormat('%s  ');
  7843 $table->setHeaders(array('Name', 'Version', 'Licenses'));
  7844 foreach ($packages as $package) {
  7845 $table->addRow(array(
  7846 $package->getPrettyName(),
  7847 $package->getFullPrettyVersion(),
  7848 implode(', ', $package instanceof CompletePackageInterface ? $package->getLicense() : array()) ?: 'none',
  7849 ));
  7850 }
  7851 $table->render();
  7852 break;
  7853 
  7854 case 'json':
  7855 $dependencies = array();
  7856 foreach ($packages as $package) {
  7857 $dependencies[$package->getPrettyName()] = array(
  7858 'version' => $package->getFullPrettyVersion(),
  7859 'license' => $package instanceof CompletePackageInterface ? $package->getLicense() : array(),
  7860 );
  7861 }
  7862 
  7863 $io->write(JsonFile::encode(array(
  7864 'name' => $root->getPrettyName(),
  7865 'version' => $root->getFullPrettyVersion(),
  7866 'license' => $root->getLicense(),
  7867 'dependencies' => $dependencies,
  7868 )));
  7869 break;
  7870 
  7871 case 'summary':
  7872 $usedLicenses = array();
  7873 foreach ($packages as $package) {
  7874 $licenses = $package instanceof CompletePackageInterface ? $package->getLicense() : array();
  7875 if (count($licenses) === 0) {
  7876 $licenses[] = 'none';
  7877 }
  7878 foreach ($licenses as $licenseName) {
  7879 if (!isset($usedLicenses[$licenseName])) {
  7880 $usedLicenses[$licenseName] = 0;
  7881 }
  7882 $usedLicenses[$licenseName]++;
  7883 }
  7884 }
  7885 
  7886 
  7887 arsort($usedLicenses, SORT_NUMERIC);
  7888 
  7889 $rows = array();
  7890 foreach ($usedLicenses as $usedLicense => $numberOfDependencies) {
  7891 $rows[] = array($usedLicense, $numberOfDependencies);
  7892 }
  7893 
  7894 $symfonyIo = new SymfonyStyle($input, $output);
  7895 $symfonyIo->table(
  7896 array('License', 'Number of dependencies'),
  7897 $rows
  7898 );
  7899 break;
  7900 default:
  7901 throw new \RuntimeException(sprintf('Unsupported format "%s".  See help for supported formats.', $format));
  7902 }
  7903 
  7904 return 0;
  7905 }
  7906 
  7907 
  7908 
  7909 
  7910 
  7911 
  7912 
  7913 private function filterRequiredPackages(RepositoryInterface $repo, PackageInterface $package, $bucket = array())
  7914 {
  7915 $requires = array_keys($package->getRequires());
  7916 
  7917 $packageListNames = array_keys($bucket);
  7918 $packages = array_filter(
  7919 $repo->getPackages(),
  7920 function ($package) use ($requires, $packageListNames) {
  7921 return in_array($package->getName(), $requires) && !in_array($package->getName(), $packageListNames);
  7922 }
  7923 );
  7924 
  7925 $bucket = $this->appendPackages($packages, $bucket);
  7926 
  7927 foreach ($packages as $package) {
  7928 $bucket = $this->filterRequiredPackages($repo, $package, $bucket);
  7929 }
  7930 
  7931 return $bucket;
  7932 }
  7933 
  7934 
  7935 
  7936 
  7937 
  7938 
  7939 
  7940 
  7941 public function appendPackages(array $packages, array $bucket)
  7942 {
  7943 foreach ($packages as $package) {
  7944 $bucket[$package->getName()] = $package;
  7945 }
  7946 
  7947 return $bucket;
  7948 }
  7949 }
  7950 <?php
  7951 
  7952 
  7953 
  7954 
  7955 
  7956 
  7957 
  7958 
  7959 
  7960 
  7961 
  7962 namespace Composer\Command;
  7963 
  7964 use Symfony\Component\Console\Input\InputInterface;
  7965 use Symfony\Component\Console\Input\InputArgument;
  7966 use Symfony\Component\Console\Input\ArrayInput;
  7967 use Symfony\Component\Console\Input\InputOption;
  7968 use Symfony\Component\Console\Output\OutputInterface;
  7969 
  7970 
  7971 
  7972 
  7973 class OutdatedCommand extends ShowCommand
  7974 {
  7975 
  7976 
  7977 
  7978 protected function configure()
  7979 {
  7980 $this
  7981 ->setName('outdated')
  7982 ->setDescription('Shows a list of installed packages that have updates available, including their latest version.')
  7983 ->setDefinition(array(
  7984 new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.'),
  7985 new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show only packages that are outdated (this is the default, but present here for compat with `show`'),
  7986 new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show all installed packages with their latest versions'),
  7987 new InputOption('locked', null, InputOption::VALUE_NONE, 'Shows updates for packages from the lock file, regardless of what is currently in vendor dir'),
  7988 new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
  7989 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
  7990 new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
  7991 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
  7992 new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.'),
  7993 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
  7994 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
  7995 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
  7996 ))
  7997 ->setHelp(
  7998 <<<EOT
  7999 The outdated command is just a proxy for `composer show -l`
  8000 
  8001 The color coding (or signage if you have ANSI colors disabled) for dependency versions is as such:
  8002 
  8003 - <info>green</info> (=): Dependency is in the latest version and is up to date.
  8004 - <comment>yellow</comment> (~): Dependency has a new version available that includes backwards
  8005   compatibility breaks according to semver, so upgrade when you can but it
  8006   may involve work.
  8007 - <highlight>red</highlight> (!): Dependency has a new version that is semver-compatible and you should upgrade it.
  8008 
  8009 Read more at https://getcomposer.org/doc/03-cli.md#outdated
  8010 EOT
  8011 )
  8012 ;
  8013 }
  8014 
  8015 protected function execute(InputInterface $input, OutputInterface $output)
  8016 {
  8017 $args = array(
  8018 'command' => 'show',
  8019 '--latest' => true,
  8020 );
  8021 if (!$input->getOption('all')) {
  8022 $args['--outdated'] = true;
  8023 }
  8024 if ($input->getOption('direct')) {
  8025 $args['--direct'] = true;
  8026 }
  8027 if ($input->getArgument('package')) {
  8028 $args['package'] = $input->getArgument('package');
  8029 }
  8030 if ($input->getOption('strict')) {
  8031 $args['--strict'] = true;
  8032 }
  8033 if ($input->getOption('minor-only')) {
  8034 $args['--minor-only'] = true;
  8035 }
  8036 if ($input->getOption('locked')) {
  8037 $args['--locked'] = true;
  8038 }
  8039 if ($input->getOption('no-dev')) {
  8040 $args['--no-dev'] = true;
  8041 }
  8042 if ($input->getOption('ignore-platform-req')) {
  8043 $args['--ignore-platform-req'] = $input->getOption('ignore-platform-req');
  8044 }
  8045 if ($input->getOption('ignore-platform-reqs')) {
  8046 $args['--ignore-platform-reqs'] = true;
  8047 }
  8048 $args['--format'] = $input->getOption('format');
  8049 $args['--ignore'] = $input->getOption('ignore');
  8050 
  8051 $input = new ArrayInput($args);
  8052 
  8053 return $this->getApplication()->run($input, $output);
  8054 }
  8055 
  8056 
  8057 
  8058 
  8059 public function isProxyCommand()
  8060 {
  8061 return true;
  8062 }
  8063 }
  8064 <?php
  8065 
  8066 
  8067 
  8068 
  8069 
  8070 
  8071 
  8072 
  8073 
  8074 
  8075 
  8076 namespace Composer\Command;
  8077 
  8078 use Symfony\Component\Console\Input\InputInterface;
  8079 use Symfony\Component\Console\Output\OutputInterface;
  8080 use Symfony\Component\Console\Input\InputArgument;
  8081 use Symfony\Component\Console\Input\InputOption;
  8082 
  8083 
  8084 
  8085 
  8086 class ProhibitsCommand extends BaseDependencyCommand
  8087 {
  8088 
  8089 
  8090 
  8091 
  8092 
  8093 protected function configure()
  8094 {
  8095 $this
  8096 ->setName('prohibits')
  8097 ->setAliases(array('why-not'))
  8098 ->setDescription('Shows which packages prevent the given package from being installed.')
  8099 ->setDefinition(array(
  8100 new InputArgument(self::ARGUMENT_PACKAGE, InputArgument::REQUIRED, 'Package to inspect'),
  8101 new InputArgument(self::ARGUMENT_CONSTRAINT, InputArgument::REQUIRED, 'Version constraint, which version you expected to be installed'),
  8102 new InputOption(self::OPTION_RECURSIVE, 'r', InputOption::VALUE_NONE, 'Recursively resolves up to the root package'),
  8103 new InputOption(self::OPTION_TREE, 't', InputOption::VALUE_NONE, 'Prints the results as a nested tree'),
  8104 ))
  8105 ->setHelp(
  8106 <<<EOT
  8107 Displays detailed information about why a package cannot be installed.
  8108 
  8109 <info>php composer.phar prohibits composer/composer</info>
  8110 
  8111 Read more at https://getcomposer.org/doc/03-cli.md#prohibits-why-not-
  8112 EOT
  8113 )
  8114 ;
  8115 }
  8116 
  8117 
  8118 
  8119 
  8120 
  8121 
  8122 protected function execute(InputInterface $input, OutputInterface $output)
  8123 {
  8124 return parent::doExecute($input, $output, true);
  8125 }
  8126 }
  8127 <?php
  8128 
  8129 
  8130 
  8131 
  8132 
  8133 
  8134 
  8135 
  8136 
  8137 
  8138 
  8139 namespace Composer\Command;
  8140 
  8141 use Composer\DependencyResolver\Operation\InstallOperation;
  8142 use Composer\DependencyResolver\Operation\UninstallOperation;
  8143 use Composer\DependencyResolver\Transaction;
  8144 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  8145 use Composer\Package\AliasPackage;
  8146 use Composer\Package\BasePackage;
  8147 use Composer\Pcre\Preg;
  8148 use Composer\Plugin\CommandEvent;
  8149 use Composer\Plugin\PluginEvents;
  8150 use Composer\Script\ScriptEvents;
  8151 use Composer\Util\Platform;
  8152 use Symfony\Component\Console\Input\InputInterface;
  8153 use Symfony\Component\Console\Input\InputOption;
  8154 use Symfony\Component\Console\Input\InputArgument;
  8155 use Symfony\Component\Console\Output\OutputInterface;
  8156 
  8157 
  8158 
  8159 
  8160 class ReinstallCommand extends BaseCommand
  8161 {
  8162 
  8163 
  8164 
  8165 protected function configure()
  8166 {
  8167 $this
  8168 ->setName('reinstall')
  8169 ->setDescription('Uninstalls and reinstalls the given package names')
  8170 ->setDefinition(array(
  8171 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
  8172 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
  8173 new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'),
  8174 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
  8175 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
  8176 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
  8177 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
  8178 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
  8179 new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
  8180 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
  8181 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
  8182 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'List of package names to reinstall, can include a wildcard (*) to match any substring.'),
  8183 ))
  8184 ->setHelp(
  8185 <<<EOT
  8186 The <info>reinstall</info> command looks up installed packages by name,
  8187 uninstalls them and reinstalls them. This lets you do a clean install
  8188 of a package if you messed with its files, or if you wish to change
  8189 the installation type using --prefer-install.
  8190 
  8191 <info>php composer.phar reinstall acme/foo "acme/bar-*"</info>
  8192 
  8193 Read more at https://getcomposer.org/doc/03-cli.md#reinstall
  8194 EOT
  8195 )
  8196 ;
  8197 }
  8198 
  8199 protected function execute(InputInterface $input, OutputInterface $output)
  8200 {
  8201 $io = $this->getIO();
  8202 
  8203 $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
  8204 
  8205 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
  8206 $packagesToReinstall = array();
  8207 $packageNamesToReinstall = array();
  8208 foreach ($input->getArgument('packages') as $pattern) {
  8209 $patternRegexp = BasePackage::packageNameToRegexp($pattern);
  8210 $matched = false;
  8211 foreach ($localRepo->getCanonicalPackages() as $package) {
  8212 if (Preg::isMatch($patternRegexp, $package->getName())) {
  8213 $matched = true;
  8214 $packagesToReinstall[] = $package;
  8215 $packageNamesToReinstall[] = $package->getName();
  8216 }
  8217 }
  8218 
  8219 if (!$matched) {
  8220 $io->writeError('<warning>Pattern "' . $pattern . '" does not match any currently installed packages.</warning>');
  8221 }
  8222 }
  8223 
  8224 if (!$packagesToReinstall) {
  8225 $io->writeError('<warning>Found no packages to reinstall, aborting.</warning>');
  8226 
  8227 return 1;
  8228 }
  8229 
  8230 $uninstallOperations = array();
  8231 foreach ($packagesToReinstall as $package) {
  8232 $uninstallOperations[] = new UninstallOperation($package);
  8233 }
  8234 
  8235 
  8236 $presentPackages = $localRepo->getPackages();
  8237 $resultPackages = $presentPackages;
  8238 foreach ($presentPackages as $index => $package) {
  8239 if (in_array($package->getName(), $packageNamesToReinstall, true)) {
  8240 unset($presentPackages[$index]);
  8241 }
  8242 }
  8243 $transaction = new Transaction($presentPackages, $resultPackages);
  8244 $installOperations = $transaction->getOperations();
  8245 
  8246 
  8247 $installOrder = array();
  8248 foreach ($installOperations as $index => $op) {
  8249 if ($op instanceof InstallOperation && !$op->getPackage() instanceof AliasPackage) {
  8250 $installOrder[$op->getPackage()->getName()] = $index;
  8251 }
  8252 }
  8253 usort($uninstallOperations, function ($a, $b) use ($installOrder) {
  8254 return $installOrder[$b->getPackage()->getName()] - $installOrder[$a->getPackage()->getName()];
  8255 });
  8256 
  8257 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'reinstall', $input, $output);
  8258 $eventDispatcher = $composer->getEventDispatcher();
  8259 $eventDispatcher->dispatch($commandEvent->getName(), $commandEvent);
  8260 
  8261 $config = $composer->getConfig();
  8262 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
  8263 
  8264 $installationManager = $composer->getInstallationManager();
  8265 $downloadManager = $composer->getDownloadManager();
  8266 $package = $composer->getPackage();
  8267 
  8268 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  8269 
  8270 $installationManager->setOutputProgress(!$input->getOption('no-progress'));
  8271 if ($input->getOption('no-plugins')) {
  8272 $installationManager->disablePlugins();
  8273 }
  8274 
  8275 $downloadManager->setPreferSource($preferSource);
  8276 $downloadManager->setPreferDist($preferDist);
  8277 
  8278 $devMode = $localRepo->getDevMode() !== null ? $localRepo->getDevMode() : true;
  8279 
  8280 Platform::putEnv('COMPOSER_DEV_MODE', $devMode ? '1' : '0');
  8281 $eventDispatcher->dispatchScript(ScriptEvents::PRE_INSTALL_CMD, $devMode);
  8282 
  8283 $installationManager->execute($localRepo, $uninstallOperations, $devMode);
  8284 $installationManager->execute($localRepo, $installOperations, $devMode);
  8285 
  8286 if (!$input->getOption('no-autoloader')) {
  8287 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
  8288 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
  8289 $apcuPrefix = $input->getOption('apcu-autoloader-prefix');
  8290 $apcu = $apcuPrefix !== null || $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader');
  8291 
  8292 $generator = $composer->getAutoloadGenerator();
  8293 $generator->setClassMapAuthoritative($authoritative);
  8294 $generator->setApcu($apcu, $apcuPrefix);
  8295 $generator->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs));
  8296 $generator->dump($config, $localRepo, $package, $installationManager, 'composer', $optimize);
  8297 }
  8298 
  8299 $eventDispatcher->dispatchScript(ScriptEvents::POST_INSTALL_CMD, $devMode);
  8300 
  8301 return 0;
  8302 }
  8303 }
  8304 <?php
  8305 
  8306 
  8307 
  8308 
  8309 
  8310 
  8311 
  8312 
  8313 
  8314 
  8315 
  8316 namespace Composer\Command;
  8317 
  8318 use Composer\Config\JsonConfigSource;
  8319 use Composer\DependencyResolver\Request;
  8320 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  8321 use Composer\Installer;
  8322 use Composer\Pcre\Preg;
  8323 use Composer\Plugin\CommandEvent;
  8324 use Composer\Plugin\PluginEvents;
  8325 use Composer\Json\JsonFile;
  8326 use Composer\Factory;
  8327 use Symfony\Component\Console\Input\InputInterface;
  8328 use Symfony\Component\Console\Input\InputOption;
  8329 use Symfony\Component\Console\Input\InputArgument;
  8330 use Symfony\Component\Console\Output\OutputInterface;
  8331 use Composer\Package\BasePackage;
  8332 
  8333 
  8334 
  8335 
  8336 
  8337 class RemoveCommand extends BaseCommand
  8338 {
  8339 
  8340 
  8341 
  8342 protected function configure()
  8343 {
  8344 $this
  8345 ->setName('remove')
  8346 ->setDescription('Removes a package from the require or require-dev.')
  8347 ->setDefinition(array(
  8348 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Packages that should be removed.'),
  8349 new InputOption('dev', null, InputOption::VALUE_NONE, 'Removes a package from the require-dev section.'),
  8350 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
  8351 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
  8352 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies (implies --no-install).'),
  8353 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'),
  8354 new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
  8355 new InputOption('update-with-dependencies', 'w', InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies. (Deprecrated, is now default behavior)'),
  8356 new InputOption('update-with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Allows all inherited dependencies to be updated, including those that are root requirements.'),
  8357 new InputOption('with-all-dependencies', null, InputOption::VALUE_NONE, 'Alias for --update-with-all-dependencies'),
  8358 new InputOption('no-update-with-dependencies', null, InputOption::VALUE_NONE, 'Does not allow inherited dependencies to be updated with explicit dependencies.'),
  8359 new InputOption('unused', null, InputOption::VALUE_NONE, 'Remove all packages which are locked but not required by any other package.'),
  8360 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
  8361 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
  8362 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
  8363 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
  8364 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
  8365 new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
  8366 ))
  8367 ->setHelp(
  8368 <<<EOT
  8369 The <info>remove</info> command removes a package from the current
  8370 list of installed packages
  8371 
  8372 <info>php composer.phar remove</info>
  8373 
  8374 Read more at https://getcomposer.org/doc/03-cli.md#remove
  8375 EOT
  8376 )
  8377 ;
  8378 }
  8379 
  8380 
  8381 
  8382 
  8383 protected function interact(InputInterface $input, OutputInterface $output)
  8384 {
  8385 if ($input->getOption('unused')) {
  8386 $composer = $this->getComposer();
  8387 $locker = $composer->getLocker();
  8388 if (!$locker->isLocked()) {
  8389 throw new \UnexpectedValueException('A valid composer.lock file is required to run this command with --unused');
  8390 }
  8391 
  8392 $lockedPackages = $locker->getLockedRepository()->getPackages();
  8393 
  8394 $required = array();
  8395 foreach (array_merge($composer->getPackage()->getRequires(), $composer->getPackage()->getDevRequires()) as $link) {
  8396 $required[$link->getTarget()] = true;
  8397 }
  8398 
  8399 do {
  8400 $found = false;
  8401 foreach ($lockedPackages as $index => $package) {
  8402 foreach ($package->getNames() as $name) {
  8403 if (isset($required[$name])) {
  8404 foreach ($package->getRequires() as $link) {
  8405 $required[$link->getTarget()] = true;
  8406 }
  8407 $found = true;
  8408 unset($lockedPackages[$index]);
  8409 break;
  8410 }
  8411 }
  8412 }
  8413 } while ($found);
  8414 
  8415 $unused = array();
  8416 foreach ($lockedPackages as $package) {
  8417 $unused[] = $package->getName();
  8418 }
  8419 $input->setArgument('packages', array_merge($input->getArgument('packages'), $unused));
  8420 
  8421 if (!$input->getArgument('packages')) {
  8422 $this->getIO()->writeError('<info>No unused packages to remove</info>');
  8423 $this->setCode(function () {
  8424 return 0;
  8425 });
  8426 }
  8427 }
  8428 }
  8429 
  8430 
  8431 
  8432 
  8433 
  8434 protected function execute(InputInterface $input, OutputInterface $output)
  8435 {
  8436 $packages = $input->getArgument('packages');
  8437 $packages = array_map('strtolower', $packages);
  8438 
  8439 $file = Factory::getComposerFile();
  8440 
  8441 $jsonFile = new JsonFile($file);
  8442 $composer = $jsonFile->read();
  8443 $composerBackup = file_get_contents($jsonFile->getPath());
  8444 
  8445 $json = new JsonConfigSource($jsonFile);
  8446 
  8447 $type = $input->getOption('dev') ? 'require-dev' : 'require';
  8448 $altType = !$input->getOption('dev') ? 'require-dev' : 'require';
  8449 $io = $this->getIO();
  8450 
  8451 if ($input->getOption('update-with-dependencies')) {
  8452 $io->writeError('<warning>You are using the deprecated option "update-with-dependencies". This is now default behaviour. The --no-update-with-dependencies option can be used to remove a package without its dependencies.</warning>');
  8453 }
  8454 
  8455 
  8456 foreach (array('require', 'require-dev') as $linkType) {
  8457 if (isset($composer[$linkType])) {
  8458 foreach ($composer[$linkType] as $name => $version) {
  8459 $composer[$linkType][strtolower($name)] = $name;
  8460 }
  8461 }
  8462 }
  8463 
  8464 $dryRun = $input->getOption('dry-run');
  8465 $toRemove = array();
  8466 foreach ($packages as $package) {
  8467 if (isset($composer[$type][$package])) {
  8468 if ($dryRun) {
  8469 $toRemove[$type][] = $composer[$type][$package];
  8470 } else {
  8471 $json->removeLink($type, $composer[$type][$package]);
  8472 }
  8473 } elseif (isset($composer[$altType][$package])) {
  8474 $io->writeError('<warning>' . $composer[$altType][$package] . ' could not be found in ' . $type . ' but it is present in ' . $altType . '</warning>');
  8475 if ($io->isInteractive()) {
  8476 if ($io->askConfirmation('Do you want to remove it from ' . $altType . ' [<comment>yes</comment>]? ')) {
  8477 if ($dryRun) {
  8478 $toRemove[$altType][] = $composer[$altType][$package];
  8479 } else {
  8480 $json->removeLink($altType, $composer[$altType][$package]);
  8481 }
  8482 }
  8483 }
  8484 } elseif (isset($composer[$type]) && $matches = Preg::grep(BasePackage::packageNameToRegexp($package), array_keys($composer[$type]))) {
  8485 foreach ($matches as $matchedPackage) {
  8486 if ($dryRun) {
  8487 $toRemove[$type][] = $matchedPackage;
  8488 } else {
  8489 $json->removeLink($type, $matchedPackage);
  8490 }
  8491 }
  8492 } elseif (isset($composer[$altType]) && $matches = Preg::grep(BasePackage::packageNameToRegexp($package), array_keys($composer[$altType]))) {
  8493 foreach ($matches as $matchedPackage) {
  8494 $io->writeError('<warning>' . $matchedPackage . ' could not be found in ' . $type . ' but it is present in ' . $altType . '</warning>');
  8495 if ($io->isInteractive()) {
  8496 if ($io->askConfirmation('Do you want to remove it from ' . $altType . ' [<comment>yes</comment>]? ')) {
  8497 if ($dryRun) {
  8498 $toRemove[$altType][] = $matchedPackage;
  8499 } else {
  8500 $json->removeLink($altType, $matchedPackage);
  8501 }
  8502 }
  8503 }
  8504 }
  8505 } else {
  8506 $io->writeError('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
  8507 }
  8508 }
  8509 
  8510 $io->writeError('<info>'.$file.' has been updated</info>');
  8511 
  8512 if ($input->getOption('no-update')) {
  8513 return 0;
  8514 }
  8515 
  8516 if ($composer = $this->getComposer(false)) {
  8517 $composer->getPluginManager()->deactivateInstalledPlugins();
  8518 }
  8519 
  8520 
  8521 $this->resetComposer();
  8522 $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
  8523 
  8524 if ($dryRun) {
  8525 $rootPackage = $composer->getPackage();
  8526 $links = array(
  8527 'require' => $rootPackage->getRequires(),
  8528 'require-dev' => $rootPackage->getDevRequires(),
  8529 );
  8530 foreach ($toRemove as $type => $names) {
  8531 foreach ($names as $name) {
  8532 unset($links[$type][$name]);
  8533 }
  8534 }
  8535 $rootPackage->setRequires($links['require']);
  8536 $rootPackage->setDevRequires($links['require-dev']);
  8537 }
  8538 
  8539 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'remove', $input, $output);
  8540 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  8541 
  8542 $composer->getInstallationManager()->setOutputProgress(!$input->getOption('no-progress'));
  8543 
  8544 $install = Installer::create($io, $composer);
  8545 
  8546 $updateDevMode = !$input->getOption('update-no-dev');
  8547 $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader');
  8548 $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative');
  8549 $apcuPrefix = $input->getOption('apcu-autoloader-prefix');
  8550 $apcu = $apcuPrefix !== null || $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader');
  8551 
  8552 $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE;
  8553 $flags = '';
  8554 if ($input->getOption('update-with-all-dependencies') || $input->getOption('with-all-dependencies')) {
  8555 $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
  8556 $flags .= ' --with-all-dependencies';
  8557 } elseif ($input->getOption('no-update-with-dependencies')) {
  8558 $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED;
  8559 $flags .= ' --with-dependencies';
  8560 }
  8561 
  8562 $io->writeError('<info>Running composer update '.implode(' ', $packages).$flags.'</info>');
  8563 
  8564 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  8565 
  8566 $install
  8567 ->setVerbose($input->getOption('verbose'))
  8568 ->setDevMode($updateDevMode)
  8569 ->setOptimizeAutoloader($optimize)
  8570 ->setClassMapAuthoritative($authoritative)
  8571 ->setApcuAutoloader($apcu, $apcuPrefix)
  8572 ->setUpdate(true)
  8573 ->setInstall(!$input->getOption('no-install'))
  8574 ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies)
  8575 ->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs))
  8576 ->setDryRun($dryRun)
  8577 ;
  8578 
  8579 
  8580 
  8581 if ($composer->getLocker()->isLocked()) {
  8582 $install->setUpdateAllowList($packages);
  8583 }
  8584 
  8585 $status = $install->run();
  8586 if ($status !== 0) {
  8587 $io->writeError("\n".'<error>Removal failed, reverting '.$file.' to its original content.</error>');
  8588 file_put_contents($jsonFile->getPath(), $composerBackup);
  8589 }
  8590 
  8591 if (!$dryRun) {
  8592 foreach ($packages as $package) {
  8593 if ($composer->getRepositoryManager()->getLocalRepository()->findPackages($package)) {
  8594 $io->writeError('<error>Removal failed, '.$package.' is still present, it may be required by another package. See `composer why '.$package.'`.</error>');
  8595 
  8596 return 2;
  8597 }
  8598 }
  8599 }
  8600 
  8601 return $status;
  8602 }
  8603 }
  8604 <?php
  8605 
  8606 
  8607 
  8608 
  8609 
  8610 
  8611 
  8612 
  8613 
  8614 
  8615 
  8616 namespace Composer\Command;
  8617 
  8618 use Composer\DependencyResolver\Request;
  8619 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
  8620 use Composer\Util\Filesystem;
  8621 use Symfony\Component\Console\Input\InputInterface;
  8622 use Symfony\Component\Console\Input\InputArgument;
  8623 use Symfony\Component\Console\Input\InputOption;
  8624 use Symfony\Component\Console\Output\OutputInterface;
  8625 use Composer\Factory;
  8626 use Composer\Installer;
  8627 use Composer\Installer\InstallerEvents;
  8628 use Composer\Json\JsonFile;
  8629 use Composer\Json\JsonManipulator;
  8630 use Composer\Package\Version\VersionParser;
  8631 use Composer\Package\Loader\ArrayLoader;
  8632 use Composer\Package\BasePackage;
  8633 use Composer\Plugin\CommandEvent;
  8634 use Composer\Plugin\PluginEvents;
  8635 use Composer\Repository\CompositeRepository;
  8636 use Composer\Repository\PlatformRepository;
  8637 use Composer\IO\IOInterface;
  8638 use Composer\Util\Silencer;
  8639 
  8640 
  8641 
  8642 
  8643 
  8644 class RequireCommand extends InitCommand
  8645 {
  8646 
  8647 private $newlyCreated;
  8648 
  8649 private $firstRequire;
  8650 
  8651 private $json;
  8652 
  8653 private $file;
  8654 
  8655 private $composerBackup;
  8656 
  8657 private $lock;
  8658 
  8659 private $lockBackup;
  8660 
  8661 private $dependencyResolutionCompleted = false;
  8662 
  8663 
  8664 
  8665 
  8666 protected function configure()
  8667 {
  8668 $this
  8669 ->setName('require')
  8670 ->setDescription('Adds required packages to your composer.json and installs them.')
  8671 ->setDefinition(array(
  8672 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Optional package name can also include a version constraint, e.g. foo/bar or foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"'),
  8673 new InputOption('dev', null, InputOption::VALUE_NONE, 'Add requirement to require-dev.'),
  8674 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
  8675 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
  8676 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
  8677 new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'),
  8678 new InputOption('fixed', null, InputOption::VALUE_NONE, 'Write fixed version to the composer.json.'),
  8679 new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'),
  8680 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
  8681 new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies (implies --no-install).'),
  8682 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'),
  8683 new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
  8684 new InputOption('update-with-dependencies', 'w', InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated, except those that are root requirements.'),
  8685 new InputOption('update-with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Allows all inherited dependencies to be updated, including those that are root requirements.'),
  8686 new InputOption('with-dependencies', null, InputOption::VALUE_NONE, 'Alias for --update-with-dependencies'),
  8687 new InputOption('with-all-dependencies', null, InputOption::VALUE_NONE, 'Alias for --update-with-all-dependencies'),
  8688 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
  8689 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
  8690 new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies.'),
  8691 new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies.'),
  8692 new InputOption('sort-packages', null, InputOption::VALUE_NONE, 'Sorts packages when adding/updating a new dependency'),
  8693 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'),
  8694 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
  8695 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
  8696 new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
  8697 ))
  8698 ->setHelp(
  8699 <<<EOT
  8700 The require command adds required packages to your composer.json and installs them.
  8701 
  8702 If you do not specify a package, composer will prompt you to search for a package, and given results, provide a list of
  8703 matches to require.
  8704 
  8705 If you do not specify a version constraint, composer will choose a suitable one based on the available package versions.
  8706 
  8707 If you do not want to install the new dependencies immediately you can call it with --no-update
  8708 
  8709 Read more at https://getcomposer.org/doc/03-cli.md#require
  8710 EOT
  8711 )
  8712 ;
  8713 }
  8714 
  8715 
  8716 
  8717 
  8718 
  8719 protected function execute(InputInterface $input, OutputInterface $output)
  8720 {
  8721 if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
  8722 pcntl_async_signals(true);
  8723 pcntl_signal(SIGINT, array($this, 'revertComposerFile'));
  8724 pcntl_signal(SIGTERM, array($this, 'revertComposerFile'));
  8725 pcntl_signal(SIGHUP, array($this, 'revertComposerFile'));
  8726 }
  8727 
  8728 $this->file = Factory::getComposerFile();
  8729 $io = $this->getIO();
  8730 
  8731 if ($input->getOption('no-suggest')) {
  8732 $io->writeError('<warning>You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.</warning>');
  8733 }
  8734 
  8735 $this->newlyCreated = !file_exists($this->file);
  8736 if ($this->newlyCreated && !file_put_contents($this->file, "{\n}\n")) {
  8737 $io->writeError('<error>'.$this->file.' could not be created.</error>');
  8738 
  8739 return 1;
  8740 }
  8741 if (!Filesystem::isReadable($this->file)) {
  8742 $io->writeError('<error>'.$this->file.' is not readable.</error>');
  8743 
  8744 return 1;
  8745 }
  8746 
  8747 if (filesize($this->file) === 0) {
  8748 file_put_contents($this->file, "{\n}\n");
  8749 }
  8750 
  8751 $this->json = new JsonFile($this->file);
  8752 $this->lock = Factory::getLockFile($this->file);
  8753 $this->composerBackup = file_get_contents($this->json->getPath());
  8754 $this->lockBackup = file_exists($this->lock) ? file_get_contents($this->lock) : null;
  8755 
  8756 
  8757 
  8758 if (!is_writable($this->file) && !Silencer::call('file_put_contents', $this->file, $this->composerBackup)) {
  8759 $io->writeError('<error>'.$this->file.' is not writable.</error>');
  8760 
  8761 return 1;
  8762 }
  8763 
  8764 if ($input->getOption('fixed') === true) {
  8765 $config = $this->json->read();
  8766 
  8767 $packageType = empty($config['type']) ? 'library' : $config['type'];
  8768 
  8769 
  8770 
  8771 
  8772 if ($packageType !== 'project') {
  8773 $io->writeError('<error>"--fixed" option is allowed for "project" package types only to prevent possible misuses.</error>');
  8774 
  8775 if (empty($config['type'])) {
  8776 $io->writeError('<error>If your package is not library, you should explicitly specify "type" parameter in composer.json.</error>');
  8777 }
  8778 
  8779 return 1;
  8780 }
  8781 }
  8782 
  8783 $composer = $this->getComposer(true, $input->getOption('no-plugins'));
  8784 $repos = $composer->getRepositoryManager()->getRepositories();
  8785 
  8786 $platformOverrides = $composer->getConfig()->get('platform') ?: array();
  8787 
  8788 $this->repos = new CompositeRepository(array_merge(
  8789 array($platformRepo = new PlatformRepository(array(), $platformOverrides)),
  8790 $repos
  8791 ));
  8792 
  8793 if ($composer->getPackage()->getPreferStable()) {
  8794 $preferredStability = 'stable';
  8795 } else {
  8796 $preferredStability = $composer->getPackage()->getMinimumStability();
  8797 }
  8798 
  8799 try {
  8800 $requirements = $this->determineRequirements(
  8801 $input,
  8802 $output,
  8803 $input->getArgument('packages'),
  8804 $platformRepo,
  8805 $preferredStability,
  8806 !$input->getOption('no-update'),
  8807 $input->getOption('fixed')
  8808 );
  8809 } catch (\Exception $e) {
  8810 if ($this->newlyCreated) {
  8811 $this->revertComposerFile(false);
  8812 
  8813 throw new \RuntimeException('No composer.json present in the current directory ('.$this->file.'), this may be the cause of the following exception.', 0, $e);
  8814 }
  8815 
  8816 throw $e;
  8817 }
  8818 
  8819 $requireKey = $input->getOption('dev') ? 'require-dev' : 'require';
  8820 $removeKey = $input->getOption('dev') ? 'require' : 'require-dev';
  8821 $requirements = $this->formatRequirements($requirements);
  8822 
  8823 
  8824 $versionParser = new VersionParser();
  8825 foreach ($requirements as $package => $constraint) {
  8826 if (strtolower($package) === $composer->getPackage()->getName()) {
  8827 $io->writeError(sprintf('<error>Root package \'%s\' cannot require itself in its composer.json</error>', $package));
  8828 
  8829 return 1;
  8830 }
  8831 if ($constraint === 'self.version') {
  8832 continue;
  8833 }
  8834 $versionParser->parseConstraints($constraint);
  8835 }
  8836 
  8837 $inconsistentRequireKeys = $this->getInconsistentRequireKeys($requirements, $requireKey);
  8838 if (count($inconsistentRequireKeys) > 0) {
  8839 foreach ($inconsistentRequireKeys as $package) {
  8840 $io->warning(sprintf(
  8841 '%s is currently present in the %s key and you ran the command %s the --dev flag, which would move it to the %s key.',
  8842 $package,
  8843 $removeKey,
  8844 $input->getOption('dev') ? 'with' : 'without',
  8845 $requireKey
  8846 ));
  8847 }
  8848 
  8849 if ($io->isInteractive()) {
  8850 if (!$io->askConfirmation(sprintf('<info>Do you want to move %s?</info> [<comment>no</comment>]? ', count($inconsistentRequireKeys) > 1 ? 'these requirements' : 'this requirement'), false)) {
  8851 if (!$io->askConfirmation(sprintf('<info>Do you want to re-run the command %s --dev?</info> [<comment>yes</comment>]? ', $input->getOption('dev') ? 'without' : 'with'), true)) {
  8852 return 0;
  8853 }
  8854 
  8855 list($requireKey, $removeKey) = array($removeKey, $requireKey);
  8856 }
  8857 }
  8858 }
  8859 
  8860 $sortPackages = $input->getOption('sort-packages') || $composer->getConfig()->get('sort-packages');
  8861 
  8862 $this->firstRequire = $this->newlyCreated;
  8863 if (!$this->firstRequire) {
  8864 $composerDefinition = $this->json->read();
  8865 if (empty($composerDefinition['require']) && empty($composerDefinition['require-dev'])) {
  8866 $this->firstRequire = true;
  8867 }
  8868 }
  8869 
  8870 if (!$input->getOption('dry-run') && !$this->updateFileCleanly($this->json, $requirements, $requireKey, $removeKey, $sortPackages)) {
  8871 $composerDefinition = $this->json->read();
  8872 foreach ($requirements as $package => $version) {
  8873 $composerDefinition[$requireKey][$package] = $version;
  8874 unset($composerDefinition[$removeKey][$package]);
  8875 if (isset($composerDefinition[$removeKey]) && count($composerDefinition[$removeKey]) === 0) {
  8876 unset($composerDefinition[$removeKey]);
  8877 }
  8878 }
  8879 $this->json->write($composerDefinition);
  8880 }
  8881 
  8882 $io->writeError('<info>'.$this->file.' has been '.($this->newlyCreated ? 'created' : 'updated').'</info>');
  8883 
  8884 if ($input->getOption('no-update')) {
  8885 return 0;
  8886 }
  8887 
  8888 $composer->getPluginManager()->deactivateInstalledPlugins();
  8889 
  8890 try {
  8891 return $this->doUpdate($input, $output, $io, $requirements, $requireKey, $removeKey);
  8892 } catch (\Exception $e) {
  8893 if (!$this->dependencyResolutionCompleted) {
  8894 $this->revertComposerFile(false);
  8895 }
  8896 throw $e;
  8897 }
  8898 }
  8899 
  8900 
  8901 
  8902 
  8903 
  8904 
  8905 private function getInconsistentRequireKeys(array $newRequirements, $requireKey)
  8906 {
  8907 $requireKeys = $this->getPackagesByRequireKey();
  8908 $inconsistentRequirements = array();
  8909 foreach ($requireKeys as $package => $packageRequireKey) {
  8910 if (!isset($newRequirements[$package])) {
  8911 continue;
  8912 }
  8913 if ($requireKey !== $packageRequireKey) {
  8914 $inconsistentRequirements[] = $package;
  8915 }
  8916 }
  8917 
  8918 return $inconsistentRequirements;
  8919 }
  8920 
  8921 
  8922 
  8923 
  8924 private function getPackagesByRequireKey()
  8925 {
  8926 $composerDefinition = $this->json->read();
  8927 $require = array();
  8928 $requireDev = array();
  8929 
  8930 if (isset($composerDefinition['require'])) {
  8931 $require = $composerDefinition['require'];
  8932 }
  8933 
  8934 if (isset($composerDefinition['require-dev'])) {
  8935 $requireDev = $composerDefinition['require-dev'];
  8936 }
  8937 
  8938 return array_merge(
  8939 array_fill_keys(array_keys($require), 'require'),
  8940 array_fill_keys(array_keys($requireDev), 'require-dev')
  8941 );
  8942 }
  8943 
  8944 
  8945 
  8946 
  8947 
  8948 public function markSolverComplete()
  8949 {
  8950 $this->dependencyResolutionCompleted = true;
  8951 }
  8952 
  8953 
  8954 
  8955 
  8956 
  8957 
  8958 
  8959 
  8960 private function doUpdate(InputInterface $input, OutputInterface $output, IOInterface $io, array $requirements, $requireKey, $removeKey)
  8961 {
  8962 
  8963 $this->resetComposer();
  8964 $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
  8965 
  8966 $this->dependencyResolutionCompleted = false;
  8967 $composer->getEventDispatcher()->addListener(InstallerEvents::PRE_OPERATIONS_EXEC, array($this, 'markSolverComplete'), 10000);
  8968 
  8969 if ($input->getOption('dry-run')) {
  8970 $rootPackage = $composer->getPackage();
  8971 $links = array(
  8972 'require' => $rootPackage->getRequires(),
  8973 'require-dev' => $rootPackage->getDevRequires(),
  8974 );
  8975 $loader = new ArrayLoader();
  8976 $newLinks = $loader->parseLinks($rootPackage->getName(), $rootPackage->getPrettyVersion(), BasePackage::$supportedLinkTypes[$requireKey]['method'], $requirements);
  8977 $links[$requireKey] = array_merge($links[$requireKey], $newLinks);
  8978 foreach ($requirements as $package => $constraint) {
  8979 unset($links[$removeKey][$package]);
  8980 }
  8981 $rootPackage->setRequires($links['require']);
  8982 $rootPackage->setDevRequires($links['require-dev']);
  8983 }
  8984 
  8985 $updateDevMode = !$input->getOption('update-no-dev');
  8986 $optimize = $input->getOption('optimize-autoloader') || $composer->getConfig()->get('optimize-autoloader');
  8987 $authoritative = $input->getOption('classmap-authoritative') || $composer->getConfig()->get('classmap-authoritative');
  8988 $apcuPrefix = $input->getOption('apcu-autoloader-prefix');
  8989 $apcu = $apcuPrefix !== null || $input->getOption('apcu-autoloader') || $composer->getConfig()->get('apcu-autoloader');
  8990 
  8991 $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED;
  8992 $flags = '';
  8993 if ($input->getOption('update-with-all-dependencies') || $input->getOption('with-all-dependencies')) {
  8994 $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
  8995 $flags .= ' --with-all-dependencies';
  8996 } elseif ($input->getOption('update-with-dependencies') || $input->getOption('with-dependencies')) {
  8997 $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE;
  8998 $flags .= ' --with-dependencies';
  8999 }
  9000 
  9001 $io->writeError('<info>Running composer update '.implode(' ', array_keys($requirements)).$flags.'</info>');
  9002 
  9003 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'require', $input, $output);
  9004 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  9005 
  9006 $composer->getInstallationManager()->setOutputProgress(!$input->getOption('no-progress'));
  9007 
  9008 $install = Installer::create($io, $composer);
  9009 
  9010 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
  9011 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($composer->getConfig(), $input);
  9012 
  9013 $install
  9014 ->setDryRun($input->getOption('dry-run'))
  9015 ->setVerbose($input->getOption('verbose'))
  9016 ->setPreferSource($preferSource)
  9017 ->setPreferDist($preferDist)
  9018 ->setDevMode($updateDevMode)
  9019 ->setOptimizeAutoloader($optimize)
  9020 ->setClassMapAuthoritative($authoritative)
  9021 ->setApcuAutoloader($apcu, $apcuPrefix)
  9022 ->setUpdate(true)
  9023 ->setInstall(!$input->getOption('no-install'))
  9024 ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies)
  9025 ->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs))
  9026 ->setPreferStable($input->getOption('prefer-stable'))
  9027 ->setPreferLowest($input->getOption('prefer-lowest'))
  9028 ;
  9029 
  9030 
  9031 
  9032 if (!$this->firstRequire && $composer->getLocker()->isLocked()) {
  9033 $install->setUpdateAllowList(array_keys($requirements));
  9034 }
  9035 
  9036 $status = $install->run();
  9037 if ($status !== 0) {
  9038 if ($status === Installer::ERROR_DEPENDENCY_RESOLUTION_FAILED) {
  9039 foreach ($this->normalizeRequirements($input->getArgument('packages')) as $req) {
  9040 if (!isset($req['version'])) {
  9041 $io->writeError('You can also try re-running composer require with an explicit version constraint, e.g. "composer require '.$req['name'].':*" to figure out if any version is installable, or "composer require '.$req['name'].':^2.1" if you know which you need.');
  9042 break;
  9043 }
  9044 }
  9045 }
  9046 $this->revertComposerFile(false);
  9047 }
  9048 
  9049 return $status;
  9050 }
  9051 
  9052 
  9053 
  9054 
  9055 
  9056 
  9057 
  9058 
  9059 private function updateFileCleanly(JsonFile $json, array $new, $requireKey, $removeKey, $sortPackages)
  9060 {
  9061 $contents = file_get_contents($json->getPath());
  9062 
  9063 $manipulator = new JsonManipulator($contents);
  9064 
  9065 foreach ($new as $package => $constraint) {
  9066 if (!$manipulator->addLink($requireKey, $package, $constraint, $sortPackages)) {
  9067 return false;
  9068 }
  9069 if (!$manipulator->removeSubNode($removeKey, $package)) {
  9070 return false;
  9071 }
  9072 }
  9073 
  9074 $manipulator->removeMainKeyIfEmpty($removeKey);
  9075 
  9076 file_put_contents($json->getPath(), $manipulator->getContents());
  9077 
  9078 return true;
  9079 }
  9080 
  9081 protected function interact(InputInterface $input, OutputInterface $output)
  9082 {
  9083 return;
  9084 }
  9085 
  9086 
  9087 
  9088 
  9089 
  9090 public function revertComposerFile($hardExit = true)
  9091 {
  9092 $io = $this->getIO();
  9093 
  9094 if ($this->newlyCreated) {
  9095 $io->writeError("\n".'<error>Installation failed, deleting '.$this->file.'.</error>');
  9096 unlink($this->json->getPath());
  9097 if (file_exists($this->lock)) {
  9098 unlink($this->lock);
  9099 }
  9100 } else {
  9101 $msg = ' to its ';
  9102 if ($this->lockBackup) {
  9103 $msg = ' and '.$this->lock.' to their ';
  9104 }
  9105 $io->writeError("\n".'<error>Installation failed, reverting '.$this->file.$msg.'original content.</error>');
  9106 file_put_contents($this->json->getPath(), $this->composerBackup);
  9107 if ($this->lockBackup) {
  9108 file_put_contents($this->lock, $this->lockBackup);
  9109 }
  9110 }
  9111 
  9112 if ($hardExit) {
  9113 exit(1);
  9114 }
  9115 }
  9116 }
  9117 <?php
  9118 
  9119 
  9120 
  9121 
  9122 
  9123 
  9124 
  9125 
  9126 
  9127 
  9128 
  9129 namespace Composer\Command;
  9130 
  9131 use Composer\Script\Event as ScriptEvent;
  9132 use Composer\Script\ScriptEvents;
  9133 use Composer\Util\ProcessExecutor;
  9134 use Composer\Util\Platform;
  9135 use Symfony\Component\Console\Input\InputInterface;
  9136 use Symfony\Component\Console\Input\InputOption;
  9137 use Symfony\Component\Console\Input\InputArgument;
  9138 use Symfony\Component\Console\Output\OutputInterface;
  9139 
  9140 
  9141 
  9142 
  9143 class RunScriptCommand extends BaseCommand
  9144 {
  9145 
  9146 
  9147 
  9148 protected $scriptEvents = array(
  9149 ScriptEvents::PRE_INSTALL_CMD,
  9150 ScriptEvents::POST_INSTALL_CMD,
  9151 ScriptEvents::PRE_UPDATE_CMD,
  9152 ScriptEvents::POST_UPDATE_CMD,
  9153 ScriptEvents::PRE_STATUS_CMD,
  9154 ScriptEvents::POST_STATUS_CMD,
  9155 ScriptEvents::POST_ROOT_PACKAGE_INSTALL,
  9156 ScriptEvents::POST_CREATE_PROJECT_CMD,
  9157 ScriptEvents::PRE_ARCHIVE_CMD,
  9158 ScriptEvents::POST_ARCHIVE_CMD,
  9159 ScriptEvents::PRE_AUTOLOAD_DUMP,
  9160 ScriptEvents::POST_AUTOLOAD_DUMP,
  9161 );
  9162 
  9163 
  9164 
  9165 
  9166 protected function configure()
  9167 {
  9168 $this
  9169 ->setName('run-script')
  9170 ->setAliases(array('run'))
  9171 ->setDescription('Runs the scripts defined in composer.json.')
  9172 ->setDefinition(array(
  9173 new InputArgument('script', InputArgument::OPTIONAL, 'Script name to run.'),
  9174 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
  9175 new InputOption('timeout', null, InputOption::VALUE_REQUIRED, 'Sets script timeout in seconds, or 0 for never.'),
  9176 new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
  9177 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
  9178 new InputOption('list', 'l', InputOption::VALUE_NONE, 'List scripts.'),
  9179 ))
  9180 ->setHelp(
  9181 <<<EOT
  9182 The <info>run-script</info> command runs scripts defined in composer.json:
  9183 
  9184 <info>php composer.phar run-script post-update-cmd</info>
  9185 
  9186 Read more at https://getcomposer.org/doc/03-cli.md#run-script
  9187 EOT
  9188 )
  9189 ;
  9190 }
  9191 
  9192 protected function execute(InputInterface $input, OutputInterface $output)
  9193 {
  9194 if ($input->getOption('list')) {
  9195 return $this->listScripts($output);
  9196 }
  9197 if (!$input->getArgument('script')) {
  9198 throw new \RuntimeException('Missing required argument "script"');
  9199 }
  9200 
  9201 $script = $input->getArgument('script');
  9202 if (!in_array($script, $this->scriptEvents)) {
  9203 if (defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
  9204 throw new \InvalidArgumentException(sprintf('Script "%s" cannot be run with this command', $script));
  9205 }
  9206 }
  9207 
  9208 $composer = $this->getComposer();
  9209 $devMode = $input->getOption('dev') || !$input->getOption('no-dev');
  9210 $event = new ScriptEvent($script, $composer, $this->getIO(), $devMode);
  9211 $hasListeners = $composer->getEventDispatcher()->hasEventListeners($event);
  9212 if (!$hasListeners) {
  9213 throw new \InvalidArgumentException(sprintf('Script "%s" is not defined in this package', $script));
  9214 }
  9215 
  9216 $args = $input->getArgument('args');
  9217 
  9218 if (null !== $timeout = $input->getOption('timeout')) {
  9219 if (!ctype_digit($timeout)) {
  9220 throw new \RuntimeException('Timeout value must be numeric and positive if defined, or 0 for forever');
  9221 }
  9222 
  9223 ProcessExecutor::setTimeout((int) $timeout);
  9224 }
  9225 
  9226 Platform::putEnv('COMPOSER_DEV_MODE', $devMode ? '1' : '0');
  9227 
  9228 return $composer->getEventDispatcher()->dispatchScript($script, $devMode, $args);
  9229 }
  9230 
  9231 
  9232 
  9233 
  9234 protected function listScripts(OutputInterface $output)
  9235 {
  9236 $scripts = $this->getComposer()->getPackage()->getScripts();
  9237 
  9238 if (!count($scripts)) {
  9239 return 0;
  9240 }
  9241 
  9242 $io = $this->getIO();
  9243 $io->writeError('<info>scripts:</info>');
  9244 $table = array();
  9245 foreach ($scripts as $name => $script) {
  9246 $description = '';
  9247 try {
  9248 $cmd = $this->getApplication()->find($name);
  9249 if ($cmd instanceof ScriptAliasCommand) {
  9250 $description = $cmd->getDescription();
  9251 }
  9252 } catch (\Symfony\Component\Console\Exception\CommandNotFoundException $e) {
  9253 
  9254 }
  9255 $table[] = array('  '.$name, $description);
  9256 }
  9257 
  9258 $this->renderTable($table, $output);
  9259 
  9260 return 0;
  9261 }
  9262 }
  9263 <?php
  9264 
  9265 
  9266 
  9267 
  9268 
  9269 
  9270 
  9271 
  9272 
  9273 
  9274 
  9275 namespace Composer\Command;
  9276 
  9277 use Symfony\Component\Console\Input\InputInterface;
  9278 use Symfony\Component\Console\Input\InputOption;
  9279 use Symfony\Component\Console\Input\InputArgument;
  9280 use Symfony\Component\Console\Output\OutputInterface;
  9281 
  9282 
  9283 
  9284 
  9285 class ScriptAliasCommand extends BaseCommand
  9286 {
  9287 
  9288 private $script;
  9289 
  9290 private $description;
  9291 
  9292 
  9293 
  9294 
  9295 
  9296 public function __construct($script, $description)
  9297 {
  9298 $this->script = $script;
  9299 $this->description = empty($description) ? 'Runs the '.$script.' script as defined in composer.json.' : $description;
  9300 
  9301 parent::__construct();
  9302 }
  9303 
  9304 
  9305 
  9306 
  9307 protected function configure()
  9308 {
  9309 $this
  9310 ->setName($this->script)
  9311 ->setDescription($this->description)
  9312 ->setDefinition(array(
  9313 new InputOption('dev', null, InputOption::VALUE_NONE, 'Sets the dev mode.'),
  9314 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'),
  9315 new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''),
  9316 ))
  9317 ->setHelp(
  9318 <<<EOT
  9319 The <info>run-script</info> command runs scripts defined in composer.json:
  9320 
  9321 <info>php composer.phar run-script post-update-cmd</info>
  9322 
  9323 Read more at https://getcomposer.org/doc/03-cli.md#run-script
  9324 EOT
  9325 )
  9326 ;
  9327 }
  9328 
  9329 
  9330 
  9331 
  9332 protected function execute(InputInterface $input, OutputInterface $output)
  9333 {
  9334 $composer = $this->getComposer();
  9335 
  9336 $args = $input->getArguments();
  9337 
  9338 return $composer->getEventDispatcher()->dispatchScript($this->script, $input->getOption('dev') || !$input->getOption('no-dev'), $args['args']);
  9339 }
  9340 }
  9341 <?php
  9342 
  9343 
  9344 
  9345 
  9346 
  9347 
  9348 
  9349 
  9350 
  9351 
  9352 
  9353 namespace Composer\Command;
  9354 
  9355 use Composer\Factory;
  9356 use Composer\Json\JsonFile;
  9357 use Symfony\Component\Console\Input\InputInterface;
  9358 use Symfony\Component\Console\Input\InputArgument;
  9359 use Symfony\Component\Console\Input\InputOption;
  9360 use Symfony\Component\Console\Output\OutputInterface;
  9361 use Composer\Repository\CompositeRepository;
  9362 use Composer\Repository\PlatformRepository;
  9363 use Composer\Repository\RepositoryInterface;
  9364 use Composer\Plugin\CommandEvent;
  9365 use Composer\Plugin\PluginEvents;
  9366 
  9367 
  9368 
  9369 
  9370 class SearchCommand extends BaseCommand
  9371 {
  9372 
  9373 
  9374 
  9375 protected function configure()
  9376 {
  9377 $this
  9378 ->setName('search')
  9379 ->setDescription('Searches for packages.')
  9380 ->setDefinition(array(
  9381 new InputOption('only-name', 'N', InputOption::VALUE_NONE, 'Search only in package names'),
  9382 new InputOption('only-vendor', 'O', InputOption::VALUE_NONE, 'Search only for vendor / organization names, returns only "vendor" as result'),
  9383 new InputOption('type', 't', InputOption::VALUE_REQUIRED, 'Search for a specific package type'),
  9384 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
  9385 new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'),
  9386 ))
  9387 ->setHelp(
  9388 <<<EOT
  9389 The search command searches for packages by its name
  9390 <info>php composer.phar search symfony composer</info>
  9391 
  9392 Read more at https://getcomposer.org/doc/03-cli.md#search
  9393 EOT
  9394 )
  9395 ;
  9396 }
  9397 
  9398 protected function execute(InputInterface $input, OutputInterface $output)
  9399 {
  9400 
  9401 $platformRepo = new PlatformRepository;
  9402 $io = $this->getIO();
  9403 
  9404 $format = $input->getOption('format');
  9405 if (!in_array($format, array('text', 'json'))) {
  9406 $io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
  9407 
  9408 return 1;
  9409 }
  9410 
  9411 if (!($composer = $this->getComposer(false))) {
  9412 $composer = Factory::create($this->getIO(), array(), $input->hasParameterOption('--no-plugins'));
  9413 }
  9414 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
  9415 $installedRepo = new CompositeRepository(array($localRepo, $platformRepo));
  9416 $repos = new CompositeRepository(array_merge(array($installedRepo), $composer->getRepositoryManager()->getRepositories()));
  9417 
  9418 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output);
  9419 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
  9420 
  9421 $mode = RepositoryInterface::SEARCH_FULLTEXT;
  9422 if ($input->getOption('only-name') === true) {
  9423 if ($input->getOption('only-vendor') === true) {
  9424 throw new \InvalidArgumentException('--only-name and --only-vendor cannot be used together');
  9425 }
  9426 $mode = RepositoryInterface::SEARCH_NAME;
  9427 } elseif ($input->getOption('only-vendor') === true) {
  9428 $mode = RepositoryInterface::SEARCH_VENDOR;
  9429 }
  9430 
  9431 $type = $input->getOption('type');
  9432 
  9433 $query = implode(' ', $input->getArgument('tokens'));
  9434 if ($mode !== RepositoryInterface::SEARCH_FULLTEXT) {
  9435 $query = preg_quote($query);
  9436 }
  9437 
  9438 $results = $repos->search($query, $mode, $type);
  9439 
  9440 if ($results && $format === 'text') {
  9441 $width = $this->getTerminalWidth();
  9442 
  9443 $nameLength = 0;
  9444 foreach ($results as $result) {
  9445 $nameLength = max(strlen($result['name']), $nameLength);
  9446 }
  9447 $nameLength += 1;
  9448 foreach ($results as $result) {
  9449 $description = isset($result['description']) ? $result['description'] : '';
  9450 $warning = !empty($result['abandoned']) ? '<warning>! Abandoned !</warning> ' : '';
  9451 $remaining = $width - $nameLength - strlen($warning) - 2;
  9452 if (strlen($description) > $remaining) {
  9453 $description = substr($description, 0, $remaining - 3) . '...';
  9454 }
  9455 
  9456 $io->write(str_pad($result['name'], $nameLength, ' ') . $warning . $description);
  9457 }
  9458 } elseif ($format === 'json') {
  9459 $io->write(JsonFile::encode($results));
  9460 }
  9461 
  9462 return 0;
  9463 }
  9464 }
  9465 <?php
  9466 
  9467 
  9468 
  9469 
  9470 
  9471 
  9472 
  9473 
  9474 
  9475 
  9476 
  9477 namespace Composer\Command;
  9478 
  9479 use Composer\Composer;
  9480 use Composer\Factory;
  9481 use Composer\Config;
  9482 use Composer\Pcre\Preg;
  9483 use Composer\Util\Filesystem;
  9484 use Composer\Util\Platform;
  9485 use Composer\SelfUpdate\Keys;
  9486 use Composer\SelfUpdate\Versions;
  9487 use Composer\IO\IOInterface;
  9488 use Composer\Downloader\FilesystemException;
  9489 use Composer\Downloader\TransportException;
  9490 use Symfony\Component\Console\Input\InputInterface;
  9491 use Symfony\Component\Console\Input\InputOption;
  9492 use Symfony\Component\Console\Input\InputArgument;
  9493 use Symfony\Component\Console\Output\OutputInterface;
  9494 use Symfony\Component\Finder\Finder;
  9495 
  9496 
  9497 
  9498 
  9499 
  9500 
  9501 class SelfUpdateCommand extends BaseCommand
  9502 {
  9503 const HOMEPAGE = 'getcomposer.org';
  9504 const OLD_INSTALL_EXT = '-old.phar';
  9505 
  9506 
  9507 
  9508 
  9509 protected function configure()
  9510 {
  9511 $this
  9512 ->setName('self-update')
  9513 ->setAliases(array('selfupdate'))
  9514 ->setDescription('Updates composer.phar to the latest version.')
  9515 ->setDefinition(array(
  9516 new InputOption('rollback', 'r', InputOption::VALUE_NONE, 'Revert to an older installation of composer'),
  9517 new InputOption('clean-backups', null, InputOption::VALUE_NONE, 'Delete old backups during an update. This makes the current version of composer the only backup available after the update'),
  9518 new InputArgument('version', InputArgument::OPTIONAL, 'The version to update to'),
  9519 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
  9520 new InputOption('update-keys', null, InputOption::VALUE_NONE, 'Prompt user for a key update'),
  9521 new InputOption('stable', null, InputOption::VALUE_NONE, 'Force an update to the stable channel'),
  9522 new InputOption('preview', null, InputOption::VALUE_NONE, 'Force an update to the preview channel'),
  9523 new InputOption('snapshot', null, InputOption::VALUE_NONE, 'Force an update to the snapshot channel'),
  9524 new InputOption('1', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 1.x versions'),
  9525 new InputOption('2', null, InputOption::VALUE_NONE, 'Force an update to the stable channel, but only use 2.x versions'),
  9526 new InputOption('set-channel-only', null, InputOption::VALUE_NONE, 'Only store the channel as the default one and then exit'),
  9527 ))
  9528 ->setHelp(
  9529 <<<EOT
  9530 The <info>self-update</info> command checks getcomposer.org for newer
  9531 versions of composer and if found, installs the latest.
  9532 
  9533 <info>php composer.phar self-update</info>
  9534 
  9535 Read more at https://getcomposer.org/doc/03-cli.md#self-update-selfupdate-
  9536 EOT
  9537 )
  9538 ;
  9539 }
  9540 
  9541 
  9542 
  9543 
  9544 
  9545 protected function execute(InputInterface $input, OutputInterface $output)
  9546 {
  9547 
  9548 
  9549 class_exists('Composer\Util\Platform');
  9550 class_exists('Composer\Downloader\FilesystemException');
  9551 
  9552 $config = Factory::createConfig();
  9553 
  9554 if ($config->get('disable-tls') === true) {
  9555 $baseUrl = 'http://' . self::HOMEPAGE;
  9556 } else {
  9557 $baseUrl = 'https://' . self::HOMEPAGE;
  9558 }
  9559 
  9560 $io = $this->getIO();
  9561 $httpDownloader = Factory::createHttpDownloader($io, $config);
  9562 
  9563 $versionsUtil = new Versions($config, $httpDownloader);
  9564 
  9565 
  9566 $requestedChannel = null;
  9567 foreach (Versions::$channels as $channel) {
  9568 if ($input->getOption($channel)) {
  9569 $requestedChannel = $channel;
  9570 $versionsUtil->setChannel($channel);
  9571 break;
  9572 }
  9573 }
  9574 
  9575 if ($input->getOption('set-channel-only')) {
  9576 return 0;
  9577 }
  9578 
  9579 $cacheDir = $config->get('cache-dir');
  9580 $rollbackDir = $config->get('data-dir');
  9581 $home = $config->get('home');
  9582 $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0];
  9583 
  9584 if ($input->getOption('update-keys')) {
  9585 $this->fetchKeys($io, $config);
  9586 
  9587 return 0;
  9588 }
  9589 
  9590 
  9591 if (!file_exists($localFilename)) {
  9592 throw new FilesystemException('Composer update failed: the "'.$localFilename.'" is not accessible');
  9593 }
  9594 
  9595 
  9596 $tmpDir = is_writable(dirname($localFilename)) ? dirname($localFilename) : $cacheDir;
  9597 
  9598 
  9599 if (!is_writable($tmpDir)) {
  9600 throw new FilesystemException('Composer update failed: the "'.$tmpDir.'" directory used to download the temp file could not be written');
  9601 }
  9602 
  9603 
  9604 if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
  9605 $composeUser = posix_getpwuid(posix_geteuid());
  9606 $homeOwner = posix_getpwuid(fileowner($home));
  9607 if (isset($composeUser['name'], $homeOwner['name']) && $composeUser['name'] !== $homeOwner['name']) {
  9608 $io->writeError('<warning>You are running Composer as "'.$composeUser['name'].'", while "'.$home.'" is owned by "'.$homeOwner['name'].'"</warning>');
  9609 }
  9610 }
  9611 
  9612 if ($input->getOption('rollback')) {
  9613 return $this->rollback($output, $rollbackDir, $localFilename);
  9614 }
  9615 
  9616 $latest = $versionsUtil->getLatest();
  9617 $latestStable = $versionsUtil->getLatest('stable');
  9618 try {
  9619 $latestPreview = $versionsUtil->getLatest('preview');
  9620 } catch (\UnexpectedValueException $e) {
  9621 $latestPreview = $latestStable;
  9622 }
  9623 $latestVersion = $latest['version'];
  9624 $updateVersion = $input->getArgument('version') ?: $latestVersion;
  9625 $currentMajorVersion = Preg::replace('{^(\d+).*}', '$1', Composer::getVersion());
  9626 $updateMajorVersion = Preg::replace('{^(\d+).*}', '$1', $updateVersion);
  9627 $previewMajorVersion = Preg::replace('{^(\d+).*}', '$1', $latestPreview['version']);
  9628 
  9629 if ($versionsUtil->getChannel() === 'stable' && !$input->getArgument('version')) {
  9630 
  9631 
  9632 if ($currentMajorVersion < $updateMajorVersion) {
  9633 $skippedVersion = $updateVersion;
  9634 
  9635 $versionsUtil->setChannel($currentMajorVersion);
  9636 
  9637 $latest = $versionsUtil->getLatest();
  9638 $latestStable = $versionsUtil->getLatest('stable');
  9639 $latestVersion = $latest['version'];
  9640 $updateVersion = $latestVersion;
  9641 
  9642 $io->writeError('<warning>A new stable major version of Composer is available ('.$skippedVersion.'), run "composer self-update --'.$updateMajorVersion.'" to update to it. See also https://getcomposer.org/'.$updateMajorVersion.'</warning>');
  9643 } elseif ($currentMajorVersion < $previewMajorVersion) {
  9644 
  9645 $io->writeError('<warning>A preview release of the next major version of Composer is available ('.$latestPreview['version'].'), run "composer self-update --preview" to give it a try. See also https://github.com/composer/composer/releases for changelogs.</warning>');
  9646 }
  9647 }
  9648 
  9649 if ($requestedChannel && is_numeric($requestedChannel) && strpos($latestStable['version'], $requestedChannel) !== 0) {
  9650 $io->writeError('<warning>Warning: You forced the install of '.$latestVersion.' via --'.$requestedChannel.', but '.$latestStable['version'].' is the latest stable version. Updating to it via composer self-update --stable is recommended.</warning>');
  9651 }
  9652 
  9653 if (Preg::isMatch('{^[0-9a-f]{40}$}', $updateVersion) && $updateVersion !== $latestVersion) {
  9654 $io->writeError('<error>You can not update to a specific SHA-1 as those phars are not available for download</error>');
  9655 
  9656 return 1;
  9657 }
  9658 
  9659 $channelString = $versionsUtil->getChannel();
  9660 if (is_numeric($channelString)) {
  9661 $channelString .= '.x';
  9662 }
  9663 
  9664 if (Composer::VERSION === $updateVersion) {
  9665 $io->writeError(
  9666 sprintf(
  9667 '<info>You are already using the latest available Composer version %s (%s channel).</info>',
  9668 $updateVersion,
  9669 $channelString
  9670 )
  9671 );
  9672 
  9673 
  9674 if ($input->getOption('clean-backups')) {
  9675 $this->cleanBackups($rollbackDir, $this->getLastBackupVersion($rollbackDir));
  9676 }
  9677 
  9678 return 0;
  9679 }
  9680 
  9681 $tempFilename = $tmpDir . '/' . basename($localFilename, '.phar').'-temp'.rand(0, 10000000).'.phar';
  9682 $backupFile = sprintf(
  9683 '%s/%s-%s%s',
  9684 $rollbackDir,
  9685 strtr(Composer::RELEASE_DATE, ' :', '_-'),
  9686 Preg::replace('{^([0-9a-f]{7})[0-9a-f]{33}$}', '$1', Composer::VERSION),
  9687 self::OLD_INSTALL_EXT
  9688 );
  9689 
  9690 $updatingToTag = !Preg::isMatch('{^[0-9a-f]{40}$}', $updateVersion);
  9691 
  9692 $io->write(sprintf("Upgrading to version <info>%s</info> (%s channel).", $updateVersion, $channelString));
  9693 $remoteFilename = $baseUrl . ($updatingToTag ? "/download/{$updateVersion}/composer.phar" : '/composer.phar');
  9694 try {
  9695 $signature = $httpDownloader->get($remoteFilename.'.sig')->getBody();
  9696 } catch (TransportException $e) {
  9697 if ($e->getStatusCode() === 404) {
  9698 throw new \InvalidArgumentException('Version "'.$updateVersion.'" could not be found.', 0, $e);
  9699 }
  9700 throw $e;
  9701 }
  9702 $io->writeError('   ', false);
  9703 $httpDownloader->copy($remoteFilename, $tempFilename);
  9704 $io->writeError('');
  9705 
  9706 if (!file_exists($tempFilename) || !$signature) {
  9707 $io->writeError('<error>The download of the new composer version failed for an unexpected reason</error>');
  9708 
  9709 return 1;
  9710 }
  9711 
  9712 
  9713 if (!extension_loaded('openssl') && $config->get('disable-tls')) {
  9714 $io->writeError('<warning>Skipping phar signature verification as you have disabled OpenSSL via config.disable-tls</warning>');
  9715 } else {
  9716 if (!extension_loaded('openssl')) {
  9717 throw new \RuntimeException('The openssl extension is required for phar signatures to be verified but it is not available. '
  9718 . 'If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the \'disable-tls\' option to true.');
  9719 }
  9720 
  9721 $sigFile = 'file://'.$home.'/' . ($updatingToTag ? 'keys.tags.pub' : 'keys.dev.pub');
  9722 if (!file_exists($sigFile)) {
  9723 file_put_contents(
  9724 $home.'/keys.dev.pub',
  9725 <<<DEVPUBKEY
  9726 -----BEGIN PUBLIC KEY-----
  9727 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnBDHjZS6e0ZMoK3xTD7f
  9728 FNCzlXjX/Aie2dit8QXA03pSrOTbaMnxON3hUL47Lz3g1SC6YJEMVHr0zYq4elWi
  9729 i3ecFEgzLcj+pZM5X6qWu2Ozz4vWx3JYo1/a/HYdOuW9e3lwS8VtS0AVJA+U8X0A
  9730 hZnBmGpltHhO8hPKHgkJtkTUxCheTcbqn4wGHl8Z2SediDcPTLwqezWKUfrYzu1f
  9731 o/j3WFwFs6GtK4wdYtiXr+yspBZHO3y1udf8eFFGcb2V3EaLOrtfur6XQVizjOuk
  9732 8lw5zzse1Qp/klHqbDRsjSzJ6iL6F4aynBc6Euqt/8ccNAIz0rLjLhOraeyj4eNn
  9733 8iokwMKiXpcrQLTKH+RH1JCuOVxQ436bJwbSsp1VwiqftPQieN+tzqy+EiHJJmGf
  9734 TBAbWcncicCk9q2md+AmhNbvHO4PWbbz9TzC7HJb460jyWeuMEvw3gNIpEo2jYa9
  9735 pMV6cVqnSa+wOc0D7pC9a6bne0bvLcm3S+w6I5iDB3lZsb3A9UtRiSP7aGSo7D72
  9736 8tC8+cIgZcI7k9vjvOqH+d7sdOU2yPCnRY6wFh62/g8bDnUpr56nZN1G89GwM4d4
  9737 r/TU7BQQIzsZgAiqOGXvVklIgAMiV0iucgf3rNBLjjeNEwNSTTG9F0CtQ+7JLwaE
  9738 wSEuAuRm+pRqi8BRnQ/GKUcCAwEAAQ==
  9739 -----END PUBLIC KEY-----
  9740 DEVPUBKEY
  9741 );
  9742 
  9743 file_put_contents(
  9744 $home.'/keys.tags.pub',
  9745 <<<TAGSPUBKEY
  9746 -----BEGIN PUBLIC KEY-----
  9747 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0Vi/2K6apCVj76nCnCl2
  9748 MQUPdK+A9eqkYBacXo2wQBYmyVlXm2/n/ZsX6pCLYPQTHyr5jXbkQzBw8SKqPdlh
  9749 vA7NpbMeNCz7wP/AobvUXM8xQuXKbMDTY2uZ4O7sM+PfGbptKPBGLe8Z8d2sUnTO
  9750 bXtX6Lrj13wkRto7st/w/Yp33RHe9SlqkiiS4MsH1jBkcIkEHsRaveZzedUaxY0M
  9751 mba0uPhGUInpPzEHwrYqBBEtWvP97t2vtfx8I5qv28kh0Y6t+jnjL1Urid2iuQZf
  9752 noCMFIOu4vksK5HxJxxrN0GOmGmwVQjOOtxkwikNiotZGPR4KsVj8NnBrLX7oGuM
  9753 nQvGciiu+KoC2r3HDBrpDeBVdOWxDzT5R4iI0KoLzFh2pKqwbY+obNPS2bj+2dgJ
  9754 rV3V5Jjry42QOCBN3c88wU1PKftOLj2ECpewY6vnE478IipiEu7EAdK8Zwj2LmTr
  9755 RKQUSa9k7ggBkYZWAeO/2Ag0ey3g2bg7eqk+sHEq5ynIXd5lhv6tC5PBdHlWipDK
  9756 tl2IxiEnejnOmAzGVivE1YGduYBjN+mjxDVy8KGBrjnz1JPgAvgdwJ2dYw4Rsc/e
  9757 TzCFWGk/HM6a4f0IzBWbJ5ot0PIi4amk07IotBXDWwqDiQTwyuGCym5EqWQ2BD95
  9758 RGv89BPD+2DLnJysngsvVaUCAwEAAQ==
  9759 -----END PUBLIC KEY-----
  9760 TAGSPUBKEY
  9761 );
  9762 }
  9763 
  9764 $pubkeyid = openssl_pkey_get_public($sigFile);
  9765 $algo = defined('OPENSSL_ALGO_SHA384') ? OPENSSL_ALGO_SHA384 : 'SHA384';
  9766 if (!in_array('sha384', array_map('strtolower', openssl_get_md_methods()))) {
  9767 throw new \RuntimeException('SHA384 is not supported by your openssl extension, could not verify the phar file integrity');
  9768 }
  9769 $signature = json_decode($signature, true);
  9770 $signature = base64_decode($signature['sha384']);
  9771 $verified = 1 === openssl_verify(file_get_contents($tempFilename), $signature, $pubkeyid, $algo);
  9772 
  9773 
  9774 if (PHP_VERSION_ID < 80000) {
  9775 openssl_free_key($pubkeyid);
  9776 }
  9777 
  9778 if (!$verified) {
  9779 throw new \RuntimeException('The phar signature did not match the file you downloaded, this means your public keys are outdated or that the phar file is corrupt/has been modified');
  9780 }
  9781 }
  9782 
  9783 
  9784 if ($input->getOption('clean-backups')) {
  9785 $this->cleanBackups($rollbackDir);
  9786 }
  9787 
  9788 if (!$this->setLocalPhar($localFilename, $tempFilename, $backupFile)) {
  9789 @unlink($tempFilename);
  9790 
  9791 return 1;
  9792 }
  9793 
  9794 if (file_exists($backupFile)) {
  9795 $io->writeError(sprintf(
  9796 'Use <info>composer self-update --rollback</info> to return to version <comment>%s</comment>',
  9797 Composer::VERSION
  9798 ));
  9799 } else {
  9800 $io->writeError('<warning>A backup of the current version could not be written to '.$backupFile.', no rollback possible</warning>');
  9801 }
  9802 
  9803 return 0;
  9804 }
  9805 
  9806 
  9807 
  9808 
  9809 
  9810 protected function fetchKeys(IOInterface $io, Config $config)
  9811 {
  9812 if (!$io->isInteractive()) {
  9813 throw new \RuntimeException('Public keys can not be fetched in non-interactive mode, please run Composer interactively');
  9814 }
  9815 
  9816 $io->write('Open <info>https://composer.github.io/pubkeys.html</info> to find the latest keys');
  9817 
  9818 $validator = function ($value) {
  9819 if (!Preg::isMatch('{^-----BEGIN PUBLIC KEY-----$}', trim($value))) {
  9820 throw new \UnexpectedValueException('Invalid input');
  9821 }
  9822 
  9823 return trim($value)."\n";
  9824 };
  9825 
  9826 $devKey = '';
  9827 while (!Preg::isMatch('{(-----BEGIN PUBLIC KEY-----.+?-----END PUBLIC KEY-----)}s', $devKey, $match)) {
  9828 $devKey = $io->askAndValidate('Enter Dev / Snapshot Public Key (including lines with -----): ', $validator);
  9829 while ($line = $io->ask('')) {
  9830 $devKey .= trim($line)."\n";
  9831 if (trim($line) === '-----END PUBLIC KEY-----') {
  9832 break;
  9833 }
  9834 }
  9835 }
  9836 file_put_contents($keyPath = $config->get('home').'/keys.dev.pub', $match[0]);
  9837 $io->write('Stored key with fingerprint: ' . Keys::fingerprint($keyPath));
  9838 
  9839 $tagsKey = '';
  9840 while (!Preg::isMatch('{(-----BEGIN PUBLIC KEY-----.+?-----END PUBLIC KEY-----)}s', $tagsKey, $match)) {
  9841 $tagsKey = $io->askAndValidate('Enter Tags Public Key (including lines with -----): ', $validator);
  9842 while ($line = $io->ask('')) {
  9843 $tagsKey .= trim($line)."\n";
  9844 if (trim($line) === '-----END PUBLIC KEY-----') {
  9845 break;
  9846 }
  9847 }
  9848 }
  9849 file_put_contents($keyPath = $config->get('home').'/keys.tags.pub', $match[0]);
  9850 $io->write('Stored key with fingerprint: ' . Keys::fingerprint($keyPath));
  9851 
  9852 $io->write('Public keys stored in '.$config->get('home'));
  9853 }
  9854 
  9855 
  9856 
  9857 
  9858 
  9859 
  9860 
  9861 protected function rollback(OutputInterface $output, $rollbackDir, $localFilename)
  9862 {
  9863 $rollbackVersion = $this->getLastBackupVersion($rollbackDir);
  9864 if (!$rollbackVersion) {
  9865 throw new \UnexpectedValueException('Composer rollback failed: no installation to roll back to in "'.$rollbackDir.'"');
  9866 }
  9867 
  9868 $oldFile = $rollbackDir . '/' . $rollbackVersion . self::OLD_INSTALL_EXT;
  9869 
  9870 if (!is_file($oldFile)) {
  9871 throw new FilesystemException('Composer rollback failed: "'.$oldFile.'" could not be found');
  9872 }
  9873 if (!Filesystem::isReadable($oldFile)) {
  9874 throw new FilesystemException('Composer rollback failed: "'.$oldFile.'" could not be read');
  9875 }
  9876 
  9877 $io = $this->getIO();
  9878 $io->writeError(sprintf("Rolling back to version <info>%s</info>.", $rollbackVersion));
  9879 if (!$this->setLocalPhar($localFilename, $oldFile)) {
  9880 return 1;
  9881 }
  9882 
  9883 return 0;
  9884 }
  9885 
  9886 
  9887 
  9888 
  9889 
  9890 
  9891 
  9892 
  9893 
  9894 
  9895 protected function setLocalPhar($localFilename, $newFilename, $backupTarget = null)
  9896 {
  9897 $io = $this->getIO();
  9898 @chmod($newFilename, fileperms($localFilename));
  9899 
  9900 
  9901 if (!$this->validatePhar($newFilename, $error)) {
  9902 $io->writeError('<error>The '.($backupTarget ? 'update' : 'backup').' file is corrupted ('.$error.')</error>');
  9903 
  9904 if ($backupTarget) {
  9905 $io->writeError('<error>Please re-run the self-update command to try again.</error>');
  9906 }
  9907 
  9908 return false;
  9909 }
  9910 
  9911 
  9912 if ($backupTarget) {
  9913 @copy($localFilename, $backupTarget);
  9914 }
  9915 
  9916 try {
  9917 if (Platform::isWindows()) {
  9918 
  9919 
  9920 copy($newFilename, $localFilename);
  9921 @unlink($newFilename);
  9922 } else {
  9923 rename($newFilename, $localFilename);
  9924 }
  9925 
  9926 return true;
  9927 } catch (\Exception $e) {
  9928 
  9929 if (!is_writable(dirname($localFilename))
  9930 && $io->isInteractive()
  9931 && $this->isWindowsNonAdminUser()) {
  9932 return $this->tryAsWindowsAdmin($localFilename, $newFilename);
  9933 }
  9934 
  9935 @unlink($newFilename);
  9936 $action = 'Composer '.($backupTarget ? 'update' : 'rollback');
  9937 throw new FilesystemException($action.' failed: "'.$localFilename.'" could not be written.'.PHP_EOL.$e->getMessage());
  9938 }
  9939 }
  9940 
  9941 
  9942 
  9943 
  9944 
  9945 
  9946 
  9947 protected function cleanBackups($rollbackDir, $except = null)
  9948 {
  9949 $finder = $this->getOldInstallationFinder($rollbackDir);
  9950 $io = $this->getIO();
  9951 $fs = new Filesystem;
  9952 
  9953 foreach ($finder as $file) {
  9954 if ($except && $file->getBasename(self::OLD_INSTALL_EXT) === $except) {
  9955 continue;
  9956 }
  9957 $file = (string) $file;
  9958 $io->writeError('<info>Removing: '.$file.'</info>');
  9959 $fs->remove($file);
  9960 }
  9961 }
  9962 
  9963 
  9964 
  9965 
  9966 
  9967 protected function getLastBackupVersion($rollbackDir)
  9968 {
  9969 $finder = $this->getOldInstallationFinder($rollbackDir);
  9970 $finder->sortByName();
  9971 $files = iterator_to_array($finder);
  9972 
  9973 if (count($files)) {
  9974 return basename(end($files), self::OLD_INSTALL_EXT);
  9975 }
  9976 
  9977 return false;
  9978 }
  9979 
  9980 
  9981 
  9982 
  9983 
  9984 protected function getOldInstallationFinder($rollbackDir)
  9985 {
  9986 return Finder::create()
  9987 ->depth(0)
  9988 ->files()
  9989 ->name('*' . self::OLD_INSTALL_EXT)
  9990 ->in($rollbackDir);
  9991 }
  9992 
  9993 
  9994 
  9995 
  9996 
  9997 
  9998 
  9999 
 10000 
 10001 
 10002 
 10003 
 10004 
 10005 protected function validatePhar($pharFile, &$error)
 10006 {
 10007 if (ini_get('phar.readonly')) {
 10008 return true;
 10009 }
 10010 
 10011 try {
 10012 
 10013 $phar = new \Phar($pharFile);
 10014 
 10015 unset($phar);
 10016 $result = true;
 10017 } catch (\Exception $e) {
 10018 if (!$e instanceof \UnexpectedValueException && !$e instanceof \PharException) {
 10019 throw $e;
 10020 }
 10021 $error = $e->getMessage();
 10022 $result = false;
 10023 }
 10024 
 10025 return $result;
 10026 }
 10027 
 10028 
 10029 
 10030 
 10031 
 10032 
 10033 protected function isWindowsNonAdminUser()
 10034 {
 10035 if (!Platform::isWindows()) {
 10036 return false;
 10037 }
 10038 
 10039 
 10040 exec('fltmc.exe filters', $output, $exitCode);
 10041 
 10042 return $exitCode !== 0;
 10043 }
 10044 
 10045 
 10046 
 10047 
 10048 
 10049 
 10050 
 10051 
 10052 
 10053 
 10054 protected function tryAsWindowsAdmin($localFilename, $newFilename)
 10055 {
 10056 $io = $this->getIO();
 10057 
 10058 $io->writeError('<error>Unable to write "'.$localFilename.'". Access is denied.</error>');
 10059 $helpMessage = 'Please run the self-update command as an Administrator.';
 10060 $question = 'Complete this operation with Administrator privileges [<comment>Y,n</comment>]? ';
 10061 
 10062 if (!$io->askConfirmation($question, false)) {
 10063 $io->writeError('<warning>Operation cancelled. '.$helpMessage.'</warning>');
 10064 
 10065 return false;
 10066 }
 10067 
 10068 $tmpFile = tempnam(sys_get_temp_dir(), '');
 10069 $script = $tmpFile.'.vbs';
 10070 rename($tmpFile, $script);
 10071 
 10072 $checksum = hash_file('sha256', $newFilename);
 10073 
 10074 
 10075 $source = str_replace('/', '\\', $newFilename);
 10076 $destination = str_replace('/', '\\', $localFilename);
 10077 
 10078 $vbs = <<<EOT
 10079 Set UAC = CreateObject("Shell.Application")
 10080 UAC.ShellExecute "cmd.exe", "/c copy /b /y ""$source"" ""$destination""", "", "runas", 0
 10081 Wscript.Sleep(300)
 10082 EOT;
 10083 
 10084 file_put_contents($script, $vbs);
 10085 exec('"'.$script.'"');
 10086 @unlink($script);
 10087 
 10088 
 10089 if ($result = Filesystem::isReadable($localFilename) && (hash_file('sha256', $localFilename) === $checksum)) {
 10090 $io->writeError('<info>Operation succeeded.</info>');
 10091 @unlink($newFilename);
 10092 } else {
 10093 $io->writeError('<error>Operation failed.'.$helpMessage.'</error>');
 10094 }
 10095 
 10096 return $result;
 10097 }
 10098 }
 10099 <?php
 10100 
 10101 
 10102 
 10103 
 10104 
 10105 
 10106 
 10107 
 10108 
 10109 
 10110 
 10111 namespace Composer\Command;
 10112 
 10113 use Composer\Composer;
 10114 use Composer\DependencyResolver\DefaultPolicy;
 10115 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
 10116 use Composer\Json\JsonFile;
 10117 use Composer\Package\BasePackage;
 10118 use Composer\Package\CompletePackageInterface;
 10119 use Composer\Package\Link;
 10120 use Composer\Package\AliasPackage;
 10121 use Composer\Package\Package;
 10122 use Composer\Package\PackageInterface;
 10123 use Composer\Package\Version\VersionParser;
 10124 use Composer\Package\Version\VersionSelector;
 10125 use Composer\Pcre\Preg;
 10126 use Composer\Plugin\CommandEvent;
 10127 use Composer\Plugin\PluginEvents;
 10128 use Composer\Repository\InstalledArrayRepository;
 10129 use Composer\Repository\ComposerRepository;
 10130 use Composer\Repository\CompositeRepository;
 10131 use Composer\Repository\FilterRepository;
 10132 use Composer\Repository\PlatformRepository;
 10133 use Composer\Repository\RepositoryFactory;
 10134 use Composer\Repository\InstalledRepository;
 10135 use Composer\Repository\RepositoryInterface;
 10136 use Composer\Repository\RepositorySet;
 10137 use Composer\Repository\RootPackageRepository;
 10138 use Composer\Semver\Constraint\ConstraintInterface;
 10139 use Composer\Semver\Semver;
 10140 use Composer\Spdx\SpdxLicenses;
 10141 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
 10142 use Symfony\Component\Console\Input\InputArgument;
 10143 use Symfony\Component\Console\Input\InputInterface;
 10144 use Symfony\Component\Console\Input\InputOption;
 10145 use Symfony\Component\Console\Output\OutputInterface;
 10146 
 10147 
 10148 
 10149 
 10150 
 10151 
 10152 
 10153 class ShowCommand extends BaseCommand
 10154 {
 10155 
 10156 protected $versionParser;
 10157 
 10158 protected $colors;
 10159 
 10160 
 10161 private $repositorySet;
 10162 
 10163 
 10164 
 10165 
 10166 protected function configure()
 10167 {
 10168 $this
 10169 ->setName('show')
 10170 ->setAliases(array('info'))
 10171 ->setDescription('Shows information about packages.')
 10172 ->setDefinition(array(
 10173 new InputArgument('package', InputArgument::OPTIONAL, 'Package to inspect. Or a name including a wildcard (*) to filter lists of packages instead.'),
 10174 new InputArgument('version', InputArgument::OPTIONAL, 'Version or version constraint to inspect'),
 10175 new InputOption('all', null, InputOption::VALUE_NONE, 'List all packages'),
 10176 new InputOption('locked', null, InputOption::VALUE_NONE, 'List all locked packages'),
 10177 new InputOption('installed', 'i', InputOption::VALUE_NONE, 'List installed packages only (enabled by default, only present for BC).'),
 10178 new InputOption('platform', 'p', InputOption::VALUE_NONE, 'List platform packages only'),
 10179 new InputOption('available', 'a', InputOption::VALUE_NONE, 'List available packages only'),
 10180 new InputOption('self', 's', InputOption::VALUE_NONE, 'Show the root package information'),
 10181 new InputOption('name-only', 'N', InputOption::VALUE_NONE, 'List package names only'),
 10182 new InputOption('path', 'P', InputOption::VALUE_NONE, 'Show package paths'),
 10183 new InputOption('tree', 't', InputOption::VALUE_NONE, 'List the dependencies as a tree'),
 10184 new InputOption('latest', 'l', InputOption::VALUE_NONE, 'Show the latest version'),
 10185 new InputOption('outdated', 'o', InputOption::VALUE_NONE, 'Show the latest version but only for packages that are outdated'),
 10186 new InputOption('ignore', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore specified package(s). Use it with the --outdated option if you don\'t want to be informed about new versions of some packages.'),
 10187 new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'),
 10188 new InputOption('direct', 'D', InputOption::VALUE_NONE, 'Shows only packages that are directly required by the root package'),
 10189 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code when there are outdated packages'),
 10190 new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'),
 10191 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'),
 10192 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages). Use with the --outdated option'),
 10193 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages). Use with the --outdated option'),
 10194 ))
 10195 ->setHelp(
 10196 <<<EOT
 10197 The show command displays detailed information about a package, or
 10198 lists all packages available.
 10199 
 10200 Read more at https://getcomposer.org/doc/03-cli.md#show
 10201 EOT
 10202 )
 10203 ;
 10204 }
 10205 
 10206 protected function execute(InputInterface $input, OutputInterface $output)
 10207 {
 10208 $this->versionParser = new VersionParser;
 10209 if ($input->getOption('tree')) {
 10210 $this->initStyles($output);
 10211 }
 10212 
 10213 $composer = $this->getComposer(false);
 10214 $io = $this->getIO();
 10215 
 10216 if ($input->getOption('installed')) {
 10217 $io->writeError('<warning>You are using the deprecated option "installed". Only installed packages are shown by default now. The --all option can be used to show all packages.</warning>');
 10218 }
 10219 
 10220 if ($input->getOption('outdated')) {
 10221 $input->setOption('latest', true);
 10222 } elseif ($input->getOption('ignore')) {
 10223 $io->writeError('<warning>You are using the option "ignore" for action other than "outdated", it will be ignored.</warning>');
 10224 }
 10225 
 10226 if ($input->getOption('direct') && ($input->getOption('all') || $input->getOption('available') || $input->getOption('platform'))) {
 10227 $io->writeError('The --direct (-D) option is not usable in combination with --all, --platform (-p) or --available (-a)');
 10228 
 10229 return 1;
 10230 }
 10231 
 10232 if ($input->getOption('tree') && ($input->getOption('all') || $input->getOption('available'))) {
 10233 $io->writeError('The --tree (-t) option is not usable in combination with --all or --available (-a)');
 10234 
 10235 return 1;
 10236 }
 10237 
 10238 if ($input->getOption('tree') && $input->getOption('latest')) {
 10239 $io->writeError('The --tree (-t) option is not usable in combination with --latest (-l)');
 10240 
 10241 return 1;
 10242 }
 10243 
 10244 if ($input->getOption('tree') && $input->getOption('path')) {
 10245 $io->writeError('The --tree (-t) option is not usable in combination with --path (-P)');
 10246 
 10247 return 1;
 10248 }
 10249 
 10250 $format = $input->getOption('format');
 10251 if (!in_array($format, array('text', 'json'))) {
 10252 $io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format));
 10253 
 10254 return 1;
 10255 }
 10256 
 10257 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
 10258 
 10259 
 10260 $platformOverrides = array();
 10261 if ($composer) {
 10262 $platformOverrides = $composer->getConfig()->get('platform') ?: array();
 10263 }
 10264 $platformRepo = new PlatformRepository(array(), $platformOverrides);
 10265 $lockedRepo = null;
 10266 
 10267 if ($input->getOption('self')) {
 10268 $package = $this->getComposer()->getPackage();
 10269 if ($input->getOption('name-only')) {
 10270 $io->write($package->getName());
 10271 
 10272 return 0;
 10273 }
 10274 $repos = $installedRepo = new InstalledRepository(array(new RootPackageRepository($package)));
 10275 } elseif ($input->getOption('platform')) {
 10276 $repos = $installedRepo = new InstalledRepository(array($platformRepo));
 10277 } elseif ($input->getOption('available')) {
 10278 $installedRepo = new InstalledRepository(array($platformRepo));
 10279 if ($composer) {
 10280 $repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
 10281 $installedRepo->addRepository($composer->getRepositoryManager()->getLocalRepository());
 10282 } else {
 10283 $defaultRepos = RepositoryFactory::defaultRepos($io);
 10284 $repos = new CompositeRepository($defaultRepos);
 10285 $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
 10286 }
 10287 } elseif ($input->getOption('all') && $composer) {
 10288 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
 10289 $locker = $composer->getLocker();
 10290 if ($locker->isLocked()) {
 10291 $lockedRepo = $locker->getLockedRepository(true);
 10292 $installedRepo = new InstalledRepository(array($lockedRepo, $localRepo, $platformRepo));
 10293 } else {
 10294 $installedRepo = new InstalledRepository(array($localRepo, $platformRepo));
 10295 }
 10296 $repos = new CompositeRepository(array_merge(array(new FilterRepository($installedRepo, array('canonical' => false))), $composer->getRepositoryManager()->getRepositories()));
 10297 } elseif ($input->getOption('all')) {
 10298 $defaultRepos = RepositoryFactory::defaultRepos($io);
 10299 $io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
 10300 $installedRepo = new InstalledRepository(array($platformRepo));
 10301 $repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
 10302 } elseif ($input->getOption('locked')) {
 10303 if (!$composer || !$composer->getLocker()->isLocked()) {
 10304 throw new \UnexpectedValueException('A valid composer.json and composer.lock files is required to run this command with --locked');
 10305 }
 10306 $locker = $composer->getLocker();
 10307 $lockedRepo = $locker->getLockedRepository(!$input->getOption('no-dev'));
 10308 $repos = $installedRepo = new InstalledRepository(array($lockedRepo));
 10309 } else {
 10310 
 10311 if (!$composer) {
 10312 $composer = $this->getComposer();
 10313 }
 10314 $rootPkg = $composer->getPackage();
 10315 $repos = $installedRepo = new InstalledRepository(array($composer->getRepositoryManager()->getLocalRepository()));
 10316 
 10317 if ($input->getOption('no-dev')) {
 10318 $packages = $this->filterRequiredPackages($installedRepo, $rootPkg);
 10319 $repos = $installedRepo = new InstalledRepository(array(new InstalledArrayRepository(array_map(function ($pkg) {
 10320 return clone $pkg;
 10321 }, $packages))));
 10322 }
 10323 
 10324 if (!$installedRepo->getPackages() && ($rootPkg->getRequires() || $rootPkg->getDevRequires())) {
 10325 $io->writeError('<warning>No dependencies installed. Try running composer install or update.</warning>');
 10326 }
 10327 }
 10328 
 10329 if ($composer) {
 10330 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'show', $input, $output);
 10331 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
 10332 }
 10333 
 10334 if ($input->getOption('latest') && null === $composer) {
 10335 $io->writeError('No composer.json found in the current directory, disabling "latest" option');
 10336 $input->setOption('latest', false);
 10337 }
 10338 
 10339 $packageFilter = $input->getArgument('package');
 10340 
 10341 
 10342 if (($packageFilter && false === strpos($packageFilter, '*')) || !empty($package)) {
 10343 if (empty($package)) {
 10344 list($package, $versions) = $this->getPackage($installedRepo, $repos, $input->getArgument('package'), $input->getArgument('version'));
 10345 
 10346 if (empty($package)) {
 10347 $options = $input->getOptions();
 10348 $hint = '';
 10349 if ($input->getOption('locked')) {
 10350 $hint .= ' in lock file';
 10351 }
 10352 if (isset($options['working-dir'])) {
 10353 $hint .= ' in ' . $options['working-dir'] . '/composer.json';
 10354 }
 10355 if (PlatformRepository::isPlatformPackage($input->getArgument('package')) && !$input->getOption('platform')) {
 10356 $hint .= ', try using --platform (-p) to show platform packages';
 10357 }
 10358 if (!$input->getOption('all')) {
 10359 $hint .= ', try using --all (-a) to show all available packages';
 10360 }
 10361 
 10362 throw new \InvalidArgumentException('Package "' . $packageFilter . '" not found'.$hint.'.');
 10363 }
 10364 } else {
 10365 $versions = array($package->getPrettyVersion() => $package->getVersion());
 10366 }
 10367 
 10368 $exitCode = 0;
 10369 if ($input->getOption('tree')) {
 10370 $arrayTree = $this->generatePackageTree($package, $installedRepo, $repos);
 10371 
 10372 if ('json' === $format) {
 10373 $io->write(JsonFile::encode(array('installed' => array($arrayTree))));
 10374 } else {
 10375 $this->displayPackageTree(array($arrayTree));
 10376 }
 10377 } else {
 10378 $latestPackage = null;
 10379 if ($input->getOption('latest')) {
 10380 $latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $input->getOption('minor-only'), $ignorePlatformReqs);
 10381 }
 10382 if (
 10383 $input->getOption('outdated')
 10384 && $input->getOption('strict')
 10385 && $latestPackage
 10386 && $latestPackage->getFullPrettyVersion() !== $package->getFullPrettyVersion()
 10387 && (!$latestPackage instanceof CompletePackageInterface || !$latestPackage->isAbandoned())
 10388 ) {
 10389 $exitCode = 1;
 10390 }
 10391 if ($input->getOption('path')) {
 10392 $io->write($package->getName(), false);
 10393 $io->write(' ' . strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n"));
 10394 
 10395 return $exitCode;
 10396 }
 10397 
 10398 if ('json' === $format) {
 10399 $this->printPackageInfoAsJson($package, $versions, $installedRepo, $latestPackage ?: null);
 10400 } else {
 10401 $this->printPackageInfo($package, $versions, $installedRepo, $latestPackage ?: null);
 10402 }
 10403 }
 10404 
 10405 return $exitCode;
 10406 }
 10407 
 10408 
 10409 if ($input->getOption('tree')) {
 10410 $rootRequires = $this->getRootRequires();
 10411 $packages = $installedRepo->getPackages();
 10412 usort($packages, function (BasePackage $a, BasePackage $b) {
 10413 return strcmp((string) $a, (string) $b);
 10414 });
 10415 $arrayTree = array();
 10416 foreach ($packages as $package) {
 10417 if (in_array($package->getName(), $rootRequires, true)) {
 10418 $arrayTree[] = $this->generatePackageTree($package, $installedRepo, $repos);
 10419 }
 10420 }
 10421 
 10422 if ('json' === $format) {
 10423 $io->write(JsonFile::encode(array('installed' => $arrayTree)));
 10424 } else {
 10425 $this->displayPackageTree($arrayTree);
 10426 }
 10427 
 10428 return 0;
 10429 }
 10430 
 10431 
 10432 $packages = array();
 10433 $packageFilterRegex = null;
 10434 if (null !== $packageFilter) {
 10435 $packageFilterRegex = '{^'.str_replace('\\*', '.*?', preg_quote($packageFilter)).'$}i';
 10436 }
 10437 
 10438 $packageListFilter = array();
 10439 if ($input->getOption('direct')) {
 10440 $packageListFilter = $this->getRootRequires();
 10441 }
 10442 
 10443 if ($input->getOption('path') && null === $composer) {
 10444 $io->writeError('No composer.json found in the current directory, disabling "path" option');
 10445 $input->setOption('path', false);
 10446 }
 10447 
 10448 foreach ($repos->getRepositories() as $repo) {
 10449 if ($repo === $platformRepo) {
 10450 $type = 'platform';
 10451 } elseif ($lockedRepo !== null && $repo === $lockedRepo) {
 10452 $type = 'locked';
 10453 } elseif ($repo === $installedRepo || in_array($repo, $installedRepo->getRepositories(), true)) {
 10454 $type = 'installed';
 10455 } else {
 10456 $type = 'available';
 10457 }
 10458 if ($repo instanceof ComposerRepository) {
 10459 foreach ($repo->getPackageNames($packageFilter) as $name) {
 10460 $packages[$type][$name] = $name;
 10461 }
 10462 } else {
 10463 foreach ($repo->getPackages() as $package) {
 10464 if (!isset($packages[$type][$package->getName()])
 10465 || !is_object($packages[$type][$package->getName()])
 10466 || version_compare($packages[$type][$package->getName()]->getVersion(), $package->getVersion(), '<')
 10467 ) {
 10468 while ($package instanceof AliasPackage) {
 10469 $package = $package->getAliasOf();
 10470 }
 10471 if (!$packageFilterRegex || Preg::isMatch($packageFilterRegex, $package->getName())) {
 10472 if (!$packageListFilter || in_array($package->getName(), $packageListFilter, true)) {
 10473 $packages[$type][$package->getName()] = $package;
 10474 }
 10475 }
 10476 }
 10477 }
 10478 if ($repo === $platformRepo) {
 10479 foreach ($platformRepo->getDisabledPackages() as $name => $package) {
 10480 $packages[$type][$name] = $package;
 10481 }
 10482 }
 10483 }
 10484 }
 10485 
 10486 $showAllTypes = $input->getOption('all');
 10487 $showLatest = $input->getOption('latest');
 10488 $showMinorOnly = $input->getOption('minor-only');
 10489 $ignoredPackages = array_map('strtolower', $input->getOption('ignore'));
 10490 $indent = $showAllTypes ? '  ' : '';
 10491 
 10492 $latestPackages = array();
 10493 $exitCode = 0;
 10494 $viewData = array();
 10495 $viewMetaData = array();
 10496 foreach (array('platform' => true, 'locked' => true, 'available' => false, 'installed' => true) as $type => $showVersion) {
 10497 if (isset($packages[$type])) {
 10498 ksort($packages[$type]);
 10499 
 10500 $nameLength = $versionLength = $latestLength = 0;
 10501 
 10502 if ($showLatest && $showVersion) {
 10503 foreach ($packages[$type] as $package) {
 10504 if (is_object($package)) {
 10505 $latestPackage = $this->findLatestPackage($package, $composer, $platformRepo, $showMinorOnly, $ignorePlatformReqs);
 10506 if ($latestPackage === false) {
 10507 continue;
 10508 }
 10509 
 10510 $latestPackages[$package->getPrettyName()] = $latestPackage;
 10511 }
 10512 }
 10513 }
 10514 
 10515 $writePath = !$input->getOption('name-only') && $input->getOption('path');
 10516 $writeVersion = !$input->getOption('name-only') && !$input->getOption('path') && $showVersion;
 10517 $writeLatest = $writeVersion && $showLatest;
 10518 $writeDescription = !$input->getOption('name-only') && !$input->getOption('path');
 10519 
 10520 $hasOutdatedPackages = false;
 10521 
 10522 $viewData[$type] = array();
 10523 foreach ($packages[$type] as $package) {
 10524 $packageViewData = array();
 10525 if (is_object($package)) {
 10526 $latestPackage = null;
 10527 if ($showLatest && isset($latestPackages[$package->getPrettyName()])) {
 10528 $latestPackage = $latestPackages[$package->getPrettyName()];
 10529 }
 10530 
 10531 
 10532 $packageIsUpToDate = $latestPackage && $latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion() && (!$latestPackage instanceof CompletePackageInterface || !$latestPackage->isAbandoned());
 10533 $packageIsIgnored = \in_array($package->getPrettyName(), $ignoredPackages, true);
 10534 if ($input->getOption('outdated') && ($packageIsUpToDate || $packageIsIgnored)) {
 10535 continue;
 10536 }
 10537 
 10538 if ($input->getOption('outdated') || $input->getOption('strict')) {
 10539 $hasOutdatedPackages = true;
 10540 }
 10541 
 10542 $packageViewData['name'] = $package->getPrettyName();
 10543 $nameLength = max($nameLength, strlen($package->getPrettyName()));
 10544 if ($writeVersion) {
 10545 $packageViewData['version'] = $package->getFullPrettyVersion();
 10546 $versionLength = max($versionLength, strlen($package->getFullPrettyVersion()));
 10547 }
 10548 if ($writeLatest && $latestPackage) {
 10549 $packageViewData['latest'] = $latestPackage->getFullPrettyVersion();
 10550 $packageViewData['latest-status'] = $this->getUpdateStatus($latestPackage, $package);
 10551 $latestLength = max($latestLength, strlen($latestPackage->getFullPrettyVersion()));
 10552 }
 10553 if ($writeDescription && $package instanceof CompletePackageInterface) {
 10554 $packageViewData['description'] = $package->getDescription();
 10555 }
 10556 if ($writePath) {
 10557 $packageViewData['path'] = strtok(realpath($composer->getInstallationManager()->getInstallPath($package)), "\r\n");
 10558 }
 10559 
 10560 if ($latestPackage instanceof CompletePackageInterface && $latestPackage->isAbandoned()) {
 10561 $replacement = is_string($latestPackage->getReplacementPackage())
 10562 ? 'Use ' . $latestPackage->getReplacementPackage() . ' instead'
 10563 : 'No replacement was suggested';
 10564 $packageWarning = sprintf(
 10565 'Package %s is abandoned, you should avoid using it. %s.',
 10566 $package->getPrettyName(),
 10567 $replacement
 10568 );
 10569 $packageViewData['warning'] = $packageWarning;
 10570 }
 10571 } else {
 10572 $packageViewData['name'] = $package;
 10573 $nameLength = max($nameLength, strlen($package));
 10574 }
 10575 $viewData[$type][] = $packageViewData;
 10576 }
 10577 $viewMetaData[$type] = array(
 10578 'nameLength' => $nameLength,
 10579 'versionLength' => $versionLength,
 10580 'latestLength' => $latestLength,
 10581 );
 10582 if ($input->getOption('strict') && $hasOutdatedPackages) {
 10583 $exitCode = 1;
 10584 break;
 10585 }
 10586 }
 10587 }
 10588 
 10589 if ('json' === $format) {
 10590 $io->write(JsonFile::encode($viewData));
 10591 } else {
 10592 if ($input->getOption('latest') && array_filter($viewData)) {
 10593 if (!$io->isDecorated()) {
 10594 $io->writeError('Legend:');
 10595 $io->writeError('! patch or minor release available - update recommended');
 10596 $io->writeError('~ major release available - update possible');
 10597 if (!$input->getOption('outdated')) {
 10598 $io->writeError('= up to date version');
 10599 }
 10600 } else {
 10601 $io->writeError('<info>Color legend:</info>');
 10602 $io->writeError('- <highlight>patch or minor</highlight> release available - update recommended');
 10603 $io->writeError('- <comment>major</comment> release available - update possible');
 10604 if (!$input->getOption('outdated')) {
 10605 $io->writeError('- <info>up to date</info> version');
 10606 }
 10607 }
 10608 }
 10609 
 10610 $width = $this->getTerminalWidth();
 10611 
 10612 foreach ($viewData as $type => $packages) {
 10613 $nameLength = $viewMetaData[$type]['nameLength'];
 10614 $versionLength = $viewMetaData[$type]['versionLength'];
 10615 $latestLength = $viewMetaData[$type]['latestLength'];
 10616 
 10617 $writeVersion = $nameLength + $versionLength + 3 <= $width;
 10618 $writeLatest = $nameLength + $versionLength + $latestLength + 3 <= $width;
 10619 $writeDescription = $nameLength + $versionLength + $latestLength + 24 <= $width;
 10620 
 10621 if ($writeLatest && !$io->isDecorated()) {
 10622 $latestLength += 2;
 10623 }
 10624 
 10625 if ($showAllTypes) {
 10626 if ('available' === $type) {
 10627 $io->write('<comment>' . $type . '</comment>:');
 10628 } else {
 10629 $io->write('<info>' . $type . '</info>:');
 10630 }
 10631 }
 10632 
 10633 foreach ($packages as $package) {
 10634 $io->write($indent . str_pad($package['name'], $nameLength, ' '), false);
 10635 if (isset($package['version']) && $writeVersion) {
 10636 $io->write(' ' . str_pad($package['version'], $versionLength, ' '), false);
 10637 }
 10638 if (isset($package['latest']) && $writeLatest) {
 10639 $latestVersion = $package['latest'];
 10640 $updateStatus = $package['latest-status'];
 10641 $style = $this->updateStatusToVersionStyle($updateStatus);
 10642 if (!$io->isDecorated()) {
 10643 $latestVersion = str_replace(array('up-to-date', 'semver-safe-update', 'update-possible'), array('=', '!', '~'), $updateStatus) . ' ' . $latestVersion;
 10644 }
 10645 $io->write(' <' . $style . '>' . str_pad($latestVersion, $latestLength, ' ') . '</' . $style . '>', false);
 10646 }
 10647 if (isset($package['description']) && $writeDescription) {
 10648 $description = strtok($package['description'], "\r\n");
 10649 $remaining = $width - $nameLength - $versionLength - 4;
 10650 if ($writeLatest) {
 10651 $remaining -= $latestLength;
 10652 }
 10653 if (strlen($description) > $remaining) {
 10654 $description = substr($description, 0, $remaining - 3) . '...';
 10655 }
 10656 $io->write(' ' . $description, false);
 10657 }
 10658 if (isset($package['path'])) {
 10659 $io->write(' ' . $package['path'], false);
 10660 }
 10661 $io->write('');
 10662 if (isset($package['warning'])) {
 10663 $io->write('<warning>' . $package['warning'] . '</warning>');
 10664 }
 10665 }
 10666 
 10667 if ($showAllTypes) {
 10668 $io->write('');
 10669 }
 10670 }
 10671 }
 10672 
 10673 return $exitCode;
 10674 }
 10675 
 10676 
 10677 
 10678 
 10679 protected function getRootRequires()
 10680 {
 10681 $rootPackage = $this->getComposer()->getPackage();
 10682 
 10683 return array_map(
 10684 'strtolower',
 10685 array_keys(array_merge($rootPackage->getRequires(), $rootPackage->getDevRequires()))
 10686 );
 10687 }
 10688 
 10689 
 10690 
 10691 
 10692 protected function getVersionStyle(PackageInterface $latestPackage, PackageInterface $package)
 10693 {
 10694 return $this->updateStatusToVersionStyle($this->getUpdateStatus($latestPackage, $package));
 10695 }
 10696 
 10697 
 10698 
 10699 
 10700 
 10701 
 10702 
 10703 
 10704 
 10705 protected function getPackage(InstalledRepository $installedRepo, RepositoryInterface $repos, $name, $version = null)
 10706 {
 10707 $name = strtolower($name);
 10708 $constraint = is_string($version) ? $this->versionParser->parseConstraints($version) : $version;
 10709 
 10710 $policy = new DefaultPolicy();
 10711 $repositorySet = new RepositorySet('dev');
 10712 $repositorySet->allowInstalledRepositories();
 10713 $repositorySet->addRepository($repos);
 10714 
 10715 $matchedPackage = null;
 10716 $versions = array();
 10717 if (PlatformRepository::isPlatformPackage($name)) {
 10718 $pool = $repositorySet->createPoolWithAllPackages();
 10719 } else {
 10720 $pool = $repositorySet->createPoolForPackage($name);
 10721 }
 10722 $matches = $pool->whatProvides($name, $constraint);
 10723 foreach ($matches as $index => $package) {
 10724 
 10725 if ($package instanceof AliasPackage && $package->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 10726 $package = $package->getAliasOf();
 10727 }
 10728 
 10729 
 10730 if (null === $version && $installedRepo->hasPackage($package)) {
 10731 $matchedPackage = $package;
 10732 }
 10733 
 10734 $versions[$package->getPrettyVersion()] = $package->getVersion();
 10735 $matches[$index] = $package->getId();
 10736 }
 10737 
 10738 
 10739 if (!$matchedPackage && $matches && $preferred = $policy->selectPreferredPackages($pool, $matches)) {
 10740 $matchedPackage = $pool->literalToPackage($preferred[0]);
 10741 }
 10742 
 10743 return array($matchedPackage, $versions);
 10744 }
 10745 
 10746 
 10747 
 10748 
 10749 
 10750 
 10751 
 10752 
 10753 
 10754 protected function printPackageInfo(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null)
 10755 {
 10756 $io = $this->getIO();
 10757 
 10758 $this->printMeta($package, $versions, $installedRepo, $latestPackage ?: null);
 10759 $this->printLinks($package, Link::TYPE_REQUIRE);
 10760 $this->printLinks($package, Link::TYPE_DEV_REQUIRE, 'requires (dev)');
 10761 
 10762 if ($package->getSuggests()) {
 10763 $io->write("\n<info>suggests</info>");
 10764 foreach ($package->getSuggests() as $suggested => $reason) {
 10765 $io->write($suggested . ' <comment>' . $reason . '</comment>');
 10766 }
 10767 }
 10768 
 10769 $this->printLinks($package, Link::TYPE_PROVIDE);
 10770 $this->printLinks($package, Link::TYPE_CONFLICT);
 10771 $this->printLinks($package, Link::TYPE_REPLACE);
 10772 }
 10773 
 10774 
 10775 
 10776 
 10777 
 10778 
 10779 
 10780 
 10781 
 10782 protected function printMeta(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null)
 10783 {
 10784 $io = $this->getIO();
 10785 $io->write('<info>name</info>     : ' . $package->getPrettyName());
 10786 $io->write('<info>descrip.</info> : ' . $package->getDescription());
 10787 $io->write('<info>keywords</info> : ' . implode(', ', $package->getKeywords() ?: array()));
 10788 $this->printVersions($package, $versions, $installedRepo);
 10789 if ($latestPackage) {
 10790 $style = $this->getVersionStyle($latestPackage, $package);
 10791 $io->write('<info>latest</info>   : <'.$style.'>' . $latestPackage->getPrettyVersion() . '</'.$style.'>');
 10792 } else {
 10793 $latestPackage = $package;
 10794 }
 10795 $io->write('<info>type</info>     : ' . $package->getType());
 10796 $this->printLicenses($package);
 10797 $io->write('<info>homepage</info> : ' . $package->getHomepage());
 10798 $io->write('<info>source</info>   : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getSourceType(), $package->getSourceUrl(), $package->getSourceReference()));
 10799 $io->write('<info>dist</info>     : ' . sprintf('[%s] <comment>%s</comment> %s', $package->getDistType(), $package->getDistUrl(), $package->getDistReference()));
 10800 if ($installedRepo->hasPackage($package)) {
 10801 $io->write('<info>path</info>     : ' . sprintf('%s', realpath($this->getComposer()->getInstallationManager()->getInstallPath($package))));
 10802 }
 10803 $io->write('<info>names</info>    : ' . implode(', ', $package->getNames()));
 10804 
 10805 if ($latestPackage instanceof CompletePackageInterface && $latestPackage->isAbandoned()) {
 10806 $replacement = ($latestPackage->getReplacementPackage() !== null)
 10807 ? ' The author suggests using the ' . $latestPackage->getReplacementPackage(). ' package instead.'
 10808 : null;
 10809 
 10810 $io->writeError(
 10811 sprintf('<warning>Attention: This package is abandoned and no longer maintained.%s</warning>', $replacement)
 10812 );
 10813 }
 10814 
 10815 if ($package->getSupport()) {
 10816 $io->write("\n<info>support</info>");
 10817 foreach ($package->getSupport() as $type => $value) {
 10818 $io->write('<comment>' . $type . '</comment> : '.$value);
 10819 }
 10820 }
 10821 
 10822 if ($package->getAutoload()) {
 10823 $io->write("\n<info>autoload</info>");
 10824 $autoloadConfig = $package->getAutoload();
 10825 foreach ($autoloadConfig as $type => $autoloads) {
 10826 $io->write('<comment>' . $type . '</comment>');
 10827 
 10828 if ($type === 'psr-0' || $type === 'psr-4') {
 10829 foreach ($autoloads as $name => $path) {
 10830 $io->write(($name ?: '*') . ' => ' . (is_array($path) ? implode(', ', $path) : ($path ?: '.')));
 10831 }
 10832 } elseif ($type === 'classmap') {
 10833 $io->write(implode(', ', $autoloadConfig[$type]));
 10834 }
 10835 }
 10836 if ($package->getIncludePaths()) {
 10837 $io->write('<comment>include-path</comment>');
 10838 $io->write(implode(', ', $package->getIncludePaths()));
 10839 }
 10840 }
 10841 }
 10842 
 10843 
 10844 
 10845 
 10846 
 10847 
 10848 
 10849 
 10850 protected function printVersions(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo)
 10851 {
 10852 $versions = array_keys($versions);
 10853 $versions = Semver::rsort($versions);
 10854 
 10855 
 10856 if ($installedPackages = $installedRepo->findPackages($package->getName())) {
 10857 foreach ($installedPackages as $installedPackage) {
 10858 $installedVersion = $installedPackage->getPrettyVersion();
 10859 $key = array_search($installedVersion, $versions);
 10860 if (false !== $key) {
 10861 $versions[$key] = '<info>* ' . $installedVersion . '</info>';
 10862 }
 10863 }
 10864 }
 10865 
 10866 $versions = implode(', ', $versions);
 10867 
 10868 $this->getIO()->write('<info>versions</info> : ' . $versions);
 10869 }
 10870 
 10871 
 10872 
 10873 
 10874 
 10875 
 10876 
 10877 
 10878 
 10879 protected function printLinks(CompletePackageInterface $package, $linkType, $title = null)
 10880 {
 10881 $title = $title ?: $linkType;
 10882 $io = $this->getIO();
 10883 if ($links = $package->{'get'.ucfirst($linkType)}()) {
 10884 $io->write("\n<info>" . $title . "</info>");
 10885 
 10886 foreach ($links as $link) {
 10887 $io->write($link->getTarget() . ' <comment>' . $link->getPrettyConstraint() . '</comment>');
 10888 }
 10889 }
 10890 }
 10891 
 10892 
 10893 
 10894 
 10895 
 10896 
 10897 protected function printLicenses(CompletePackageInterface $package)
 10898 {
 10899 $spdxLicenses = new SpdxLicenses();
 10900 
 10901 $licenses = $package->getLicense();
 10902 $io = $this->getIO();
 10903 
 10904 foreach ($licenses as $licenseId) {
 10905 $license = $spdxLicenses->getLicenseByIdentifier($licenseId); 
 10906 
 10907 if (!$license) {
 10908 $out = $licenseId;
 10909 } else {
 10910 
 10911 if ($license[1] === true) {
 10912 $out = sprintf('%s (%s) (OSI approved) %s', $license[0], $licenseId, $license[2]);
 10913 } else {
 10914 $out = sprintf('%s (%s) %s', $license[0], $licenseId, $license[2]);
 10915 }
 10916 }
 10917 
 10918 $io->write('<info>license</info>  : ' . $out);
 10919 }
 10920 }
 10921 
 10922 
 10923 
 10924 
 10925 
 10926 
 10927 
 10928 
 10929 protected function printPackageInfoAsJson(CompletePackageInterface $package, array $versions, InstalledRepository $installedRepo, PackageInterface $latestPackage = null)
 10930 {
 10931 $json = array(
 10932 'name' => $package->getPrettyName(),
 10933 'description' => $package->getDescription(),
 10934 'keywords' => $package->getKeywords() ?: array(),
 10935 'type' => $package->getType(),
 10936 'homepage' => $package->getHomepage(),
 10937 'names' => $package->getNames(),
 10938 );
 10939 
 10940 $json = $this->appendVersions($json, $versions);
 10941 $json = $this->appendLicenses($json, $package);
 10942 
 10943 if ($latestPackage) {
 10944 $json['latest'] = $latestPackage->getPrettyVersion();
 10945 } else {
 10946 $latestPackage = $package;
 10947 }
 10948 
 10949 if ($package->getSourceType()) {
 10950 $json['source'] = array(
 10951 'type' => $package->getSourceType(),
 10952 'url' => $package->getSourceUrl(),
 10953 'reference' => $package->getSourceReference(),
 10954 );
 10955 }
 10956 
 10957 if ($package->getDistType()) {
 10958 $json['dist'] = array(
 10959 'type' => $package->getDistType(),
 10960 'url' => $package->getDistUrl(),
 10961 'reference' => $package->getDistReference(),
 10962 );
 10963 }
 10964 
 10965 if ($installedRepo->hasPackage($package)) {
 10966 $json['path'] = realpath($this->getComposer()->getInstallationManager()->getInstallPath($package));
 10967 if ($json['path'] === false) {
 10968 unset($json['path']);
 10969 }
 10970 }
 10971 
 10972 if ($latestPackage instanceof CompletePackageInterface && $latestPackage->isAbandoned()) {
 10973 $json['replacement'] = $latestPackage->getReplacementPackage();
 10974 }
 10975 
 10976 if ($package->getSuggests()) {
 10977 $json['suggests'] = $package->getSuggests();
 10978 }
 10979 
 10980 if ($package->getSupport()) {
 10981 $json['support'] = $package->getSupport();
 10982 }
 10983 
 10984 $json = $this->appendAutoload($json, $package);
 10985 
 10986 if ($package->getIncludePaths()) {
 10987 $json['include_path'] = $package->getIncludePaths();
 10988 }
 10989 
 10990 $json = $this->appendLinks($json, $package);
 10991 
 10992 $this->getIO()->write(JsonFile::encode($json));
 10993 }
 10994 
 10995 
 10996 
 10997 
 10998 
 10999 
 11000 private function appendVersions($json, array $versions)
 11001 {
 11002 uasort($versions, 'version_compare');
 11003 $versions = array_keys(array_reverse($versions));
 11004 $json['versions'] = $versions;
 11005 
 11006 return $json;
 11007 }
 11008 
 11009 
 11010 
 11011 
 11012 
 11013 private function appendLicenses($json, CompletePackageInterface $package)
 11014 {
 11015 if ($licenses = $package->getLicense()) {
 11016 $spdxLicenses = new SpdxLicenses();
 11017 
 11018 $json['licenses'] = array_map(function ($licenseId) use ($spdxLicenses) {
 11019 $license = $spdxLicenses->getLicenseByIdentifier($licenseId); 
 11020 
 11021 if (!$license) {
 11022 return $licenseId;
 11023 }
 11024 
 11025 return array(
 11026 'name' => $license[0],
 11027 'osi' => $licenseId,
 11028 'url' => $license[2],
 11029 );
 11030 }, $licenses);
 11031 }
 11032 
 11033 return $json;
 11034 }
 11035 
 11036 
 11037 
 11038 
 11039 
 11040 private function appendAutoload($json, CompletePackageInterface $package)
 11041 {
 11042 if ($package->getAutoload()) {
 11043 $autoload = array();
 11044 
 11045 foreach ($package->getAutoload() as $type => $autoloads) {
 11046 if ($type === 'psr-0' || $type === 'psr-4') {
 11047 $psr = array();
 11048 
 11049 foreach ($autoloads as $name => $path) {
 11050 if (!$path) {
 11051 $path = '.';
 11052 }
 11053 
 11054 $psr[$name ?: '*'] = $path;
 11055 }
 11056 
 11057 $autoload[$type] = $psr;
 11058 } elseif ($type === 'classmap') {
 11059 $autoload['classmap'] = $autoloads;
 11060 }
 11061 }
 11062 
 11063 $json['autoload'] = $autoload;
 11064 }
 11065 
 11066 return $json;
 11067 }
 11068 
 11069 
 11070 
 11071 
 11072 
 11073 private function appendLinks($json, CompletePackageInterface $package)
 11074 {
 11075 foreach (Link::$TYPES as $linkType) {
 11076 $json = $this->appendLink($json, $package, $linkType);
 11077 }
 11078 
 11079 return $json;
 11080 }
 11081 
 11082 
 11083 
 11084 
 11085 
 11086 
 11087 private function appendLink($json, CompletePackageInterface $package, $linkType)
 11088 {
 11089 $links = $package->{'get' . ucfirst($linkType)}();
 11090 
 11091 if ($links) {
 11092 $json[$linkType] = array();
 11093 
 11094 foreach ($links as $link) {
 11095 $json[$linkType][$link->getTarget()] = $link->getPrettyConstraint();
 11096 }
 11097 }
 11098 
 11099 return $json;
 11100 }
 11101 
 11102 
 11103 
 11104 
 11105 
 11106 
 11107 protected function initStyles(OutputInterface $output)
 11108 {
 11109 $this->colors = array(
 11110 'green',
 11111 'yellow',
 11112 'cyan',
 11113 'magenta',
 11114 'blue',
 11115 );
 11116 
 11117 foreach ($this->colors as $color) {
 11118 $style = new OutputFormatterStyle($color);
 11119 $output->getFormatter()->setStyle($color, $style);
 11120 }
 11121 }
 11122 
 11123 
 11124 
 11125 
 11126 
 11127 
 11128 
 11129 protected function displayPackageTree(array $arrayTree)
 11130 {
 11131 $io = $this->getIO();
 11132 foreach ($arrayTree as $package) {
 11133 $io->write(sprintf('<info>%s</info>', $package['name']), false);
 11134 $io->write(' ' . $package['version'], false);
 11135 $io->write(' ' . strtok($package['description'], "\r\n"));
 11136 
 11137 if (isset($package['requires'])) {
 11138 $requires = $package['requires'];
 11139 $treeBar = '├';
 11140 $j = 0;
 11141 $total = count($requires);
 11142 foreach ($requires as $require) {
 11143 $requireName = $require['name'];
 11144 $j++;
 11145 if ($j === $total) {
 11146 $treeBar = '└';
 11147 }
 11148 $level = 1;
 11149 $color = $this->colors[$level];
 11150 $info = sprintf(
 11151 '%s──<%s>%s</%s> %s',
 11152 $treeBar,
 11153 $color,
 11154 $requireName,
 11155 $color,
 11156 $require['version']
 11157 );
 11158 $this->writeTreeLine($info);
 11159 
 11160 $treeBar = str_replace('└', ' ', $treeBar);
 11161 $packagesInTree = array($package['name'], $requireName);
 11162 
 11163 $this->displayTree($require, $packagesInTree, $treeBar, $level + 1);
 11164 }
 11165 }
 11166 }
 11167 }
 11168 
 11169 
 11170 
 11171 
 11172 
 11173 
 11174 protected function generatePackageTree(
 11175 PackageInterface $package,
 11176 InstalledRepository $installedRepo,
 11177 RepositoryInterface $remoteRepos
 11178 ) {
 11179 $requires = $package->getRequires();
 11180 ksort($requires);
 11181 $children = array();
 11182 foreach ($requires as $requireName => $require) {
 11183 $packagesInTree = array($package->getName(), $requireName);
 11184 
 11185 $treeChildDesc = array(
 11186 'name' => $requireName,
 11187 'version' => $require->getPrettyConstraint(),
 11188 );
 11189 
 11190 $deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $packagesInTree);
 11191 
 11192 if ($deepChildren) {
 11193 $treeChildDesc['requires'] = $deepChildren;
 11194 }
 11195 
 11196 $children[] = $treeChildDesc;
 11197 }
 11198 $tree = array(
 11199 'name' => $package->getPrettyName(),
 11200 'version' => $package->getPrettyVersion(),
 11201 'description' => $package instanceof CompletePackageInterface ? $package->getDescription() : '',
 11202 );
 11203 
 11204 if ($children) {
 11205 $tree['requires'] = $children;
 11206 }
 11207 
 11208 return $tree;
 11209 }
 11210 
 11211 
 11212 
 11213 
 11214 
 11215 
 11216 
 11217 
 11218 
 11219 
 11220 
 11221 protected function displayTree(
 11222 $package,
 11223 array $packagesInTree,
 11224 $previousTreeBar = '├',
 11225 $level = 1
 11226 ) {
 11227 $previousTreeBar = str_replace('├', '│', $previousTreeBar);
 11228 if (is_array($package) && isset($package['requires'])) {
 11229 $requires = $package['requires'];
 11230 $treeBar = $previousTreeBar . '  ├';
 11231 $i = 0;
 11232 $total = count($requires);
 11233 foreach ($requires as $require) {
 11234 $currentTree = $packagesInTree;
 11235 $i++;
 11236 if ($i === $total) {
 11237 $treeBar = $previousTreeBar . '  └';
 11238 }
 11239 $colorIdent = $level % count($this->colors);
 11240 $color = $this->colors[$colorIdent];
 11241 
 11242 $circularWarn = in_array(
 11243 $require['name'],
 11244 $currentTree,
 11245 true
 11246 ) ? '(circular dependency aborted here)' : '';
 11247 $info = rtrim(sprintf(
 11248 '%s──<%s>%s</%s> %s %s',
 11249 $treeBar,
 11250 $color,
 11251 $require['name'],
 11252 $color,
 11253 $require['version'],
 11254 $circularWarn
 11255 ));
 11256 $this->writeTreeLine($info);
 11257 
 11258 $treeBar = str_replace('└', ' ', $treeBar);
 11259 
 11260 $currentTree[] = $require['name'];
 11261 $this->displayTree($require, $currentTree, $treeBar, $level + 1);
 11262 }
 11263 }
 11264 }
 11265 
 11266 
 11267 
 11268 
 11269 
 11270 
 11271 
 11272 
 11273 protected function addTree(
 11274 $name,
 11275 Link $link,
 11276 InstalledRepository $installedRepo,
 11277 RepositoryInterface $remoteRepos,
 11278 array $packagesInTree
 11279 ) {
 11280 $children = array();
 11281 list($package) = $this->getPackage(
 11282 $installedRepo,
 11283 $remoteRepos,
 11284 $name,
 11285 $link->getPrettyConstraint() === 'self.version' ? $link->getConstraint() : $link->getPrettyConstraint()
 11286 );
 11287 if (is_object($package)) {
 11288 $requires = $package->getRequires();
 11289 ksort($requires);
 11290 foreach ($requires as $requireName => $require) {
 11291 $currentTree = $packagesInTree;
 11292 
 11293 $treeChildDesc = array(
 11294 'name' => $requireName,
 11295 'version' => $require->getPrettyConstraint(),
 11296 );
 11297 
 11298 if (!in_array($requireName, $currentTree, true)) {
 11299 $currentTree[] = $requireName;
 11300 $deepChildren = $this->addTree($requireName, $require, $installedRepo, $remoteRepos, $currentTree);
 11301 if ($deepChildren) {
 11302 $treeChildDesc['requires'] = $deepChildren;
 11303 }
 11304 }
 11305 
 11306 $children[] = $treeChildDesc;
 11307 }
 11308 }
 11309 
 11310 return $children;
 11311 }
 11312 
 11313 
 11314 
 11315 
 11316 
 11317 private function updateStatusToVersionStyle($updateStatus)
 11318 {
 11319 
 11320 
 11321 
 11322 return str_replace(array('up-to-date', 'semver-safe-update', 'update-possible'), array('info', 'highlight', 'comment'), $updateStatus);
 11323 }
 11324 
 11325 
 11326 
 11327 
 11328 private function getUpdateStatus(PackageInterface $latestPackage, PackageInterface $package)
 11329 {
 11330 if ($latestPackage->getFullPrettyVersion() === $package->getFullPrettyVersion()) {
 11331 return 'up-to-date';
 11332 }
 11333 
 11334 $constraint = $package->getVersion();
 11335 if (0 !== strpos($constraint, 'dev-')) {
 11336 $constraint = '^'.$constraint;
 11337 }
 11338 if ($latestPackage->getVersion() && Semver::satisfies($latestPackage->getVersion(), $constraint)) {
 11339 
 11340 return 'semver-safe-update';
 11341 }
 11342 
 11343 
 11344 return 'update-possible';
 11345 }
 11346 
 11347 
 11348 
 11349 
 11350 
 11351 
 11352 private function writeTreeLine($line)
 11353 {
 11354 $io = $this->getIO();
 11355 if (!$io->isDecorated()) {
 11356 $line = str_replace(array('└', '├', '──', '│'), array('`-', '|-', '-', '|'), $line);
 11357 }
 11358 
 11359 $io->write($line);
 11360 }
 11361 
 11362 
 11363 
 11364 
 11365 
 11366 
 11367 
 11368 
 11369 
 11370 private function findLatestPackage(PackageInterface $package, Composer $composer, PlatformRepository $platformRepo, $minorOnly = false, $ignorePlatformReqs = false)
 11371 {
 11372 
 11373 $name = $package->getName();
 11374 $versionSelector = new VersionSelector($this->getRepositorySet($composer), $platformRepo);
 11375 $stability = $composer->getPackage()->getMinimumStability();
 11376 $flags = $composer->getPackage()->getStabilityFlags();
 11377 if (isset($flags[$name])) {
 11378 $stability = array_search($flags[$name], BasePackage::$stabilities, true);
 11379 }
 11380 
 11381 $bestStability = $stability;
 11382 if ($composer->getPackage()->getPreferStable()) {
 11383 $bestStability = $package->getStability();
 11384 }
 11385 
 11386 $targetVersion = null;
 11387 if (0 === strpos($package->getVersion(), 'dev-')) {
 11388 $targetVersion = $package->getVersion();
 11389 }
 11390 
 11391 if ($targetVersion === null && $minorOnly) {
 11392 $targetVersion = '^' . $package->getVersion();
 11393 }
 11394 
 11395 $candidate = $versionSelector->findBestCandidate($name, $targetVersion, $bestStability, PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs));
 11396 while ($candidate instanceof AliasPackage) {
 11397 $candidate = $candidate->getAliasOf();
 11398 }
 11399 
 11400 return $candidate;
 11401 }
 11402 
 11403 
 11404 
 11405 
 11406 private function getRepositorySet(Composer $composer)
 11407 {
 11408 if (!$this->repositorySet) {
 11409 $this->repositorySet = new RepositorySet($composer->getPackage()->getMinimumStability(), $composer->getPackage()->getStabilityFlags());
 11410 $this->repositorySet->addRepository(new CompositeRepository($composer->getRepositoryManager()->getRepositories()));
 11411 }
 11412 
 11413 return $this->repositorySet;
 11414 }
 11415 
 11416 
 11417 
 11418 
 11419 
 11420 
 11421 
 11422 private function filterRequiredPackages(RepositoryInterface $repo, PackageInterface $package, $bucket = array())
 11423 {
 11424 $requires = $package->getRequires();
 11425 
 11426 foreach ($repo->getPackages() as $candidate) {
 11427 foreach ($candidate->getNames() as $name) {
 11428 if (isset($requires[$name])) {
 11429 if (!in_array($candidate, $bucket, true)) {
 11430 $bucket[] = $candidate;
 11431 $bucket = $this->filterRequiredPackages($repo, $candidate, $bucket);
 11432 }
 11433 break;
 11434 }
 11435 }
 11436 }
 11437 
 11438 return $bucket;
 11439 }
 11440 }
 11441 <?php
 11442 
 11443 
 11444 
 11445 
 11446 
 11447 
 11448 
 11449 
 11450 
 11451 
 11452 
 11453 namespace Composer\Command;
 11454 
 11455 use Symfony\Component\Console\Input\InputInterface;
 11456 use Symfony\Component\Console\Input\InputOption;
 11457 use Symfony\Component\Console\Output\OutputInterface;
 11458 use Composer\Downloader\ChangeReportInterface;
 11459 use Composer\Downloader\DvcsDownloaderInterface;
 11460 use Composer\Downloader\VcsCapableDownloaderInterface;
 11461 use Composer\Package\Dumper\ArrayDumper;
 11462 use Composer\Package\Version\VersionGuesser;
 11463 use Composer\Package\Version\VersionParser;
 11464 use Composer\Plugin\CommandEvent;
 11465 use Composer\Plugin\PluginEvents;
 11466 use Composer\Script\ScriptEvents;
 11467 use Composer\Util\ProcessExecutor;
 11468 
 11469 
 11470 
 11471 
 11472 
 11473 class StatusCommand extends BaseCommand
 11474 {
 11475 const EXIT_CODE_ERRORS = 1;
 11476 const EXIT_CODE_UNPUSHED_CHANGES = 2;
 11477 const EXIT_CODE_VERSION_CHANGES = 4;
 11478 
 11479 
 11480 
 11481 
 11482 
 11483 protected function configure()
 11484 {
 11485 $this
 11486 ->setName('status')
 11487 ->setDescription('Shows a list of locally modified packages.')
 11488 ->setDefinition(array(
 11489 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Show modified files for each directory that contains changes.'),
 11490 ))
 11491 ->setHelp(
 11492 <<<EOT
 11493 The status command displays a list of dependencies that have
 11494 been modified locally.
 11495 
 11496 Read more at https://getcomposer.org/doc/03-cli.md#status
 11497 EOT
 11498 )
 11499 ;
 11500 }
 11501 
 11502 
 11503 
 11504 
 11505 protected function execute(InputInterface $input, OutputInterface $output)
 11506 {
 11507 $composer = $this->getComposer();
 11508 
 11509 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'status', $input, $output);
 11510 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
 11511 
 11512 
 11513 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::PRE_STATUS_CMD, true);
 11514 
 11515 $exitCode = $this->doExecute($input);
 11516 
 11517 
 11518 $composer->getEventDispatcher()->dispatchScript(ScriptEvents::POST_STATUS_CMD, true);
 11519 
 11520 return $exitCode;
 11521 }
 11522 
 11523 
 11524 
 11525 
 11526 private function doExecute(InputInterface $input)
 11527 {
 11528 
 11529 $composer = $this->getComposer();
 11530 
 11531 $installedRepo = $composer->getRepositoryManager()->getLocalRepository();
 11532 
 11533 $dm = $composer->getDownloadManager();
 11534 $im = $composer->getInstallationManager();
 11535 
 11536 $errors = array();
 11537 $io = $this->getIO();
 11538 $unpushedChanges = array();
 11539 $vcsVersionChanges = array();
 11540 
 11541 $parser = new VersionParser;
 11542 $guesser = new VersionGuesser($composer->getConfig(), new ProcessExecutor($io), $parser);
 11543 $dumper = new ArrayDumper;
 11544 
 11545 
 11546 foreach ($installedRepo->getCanonicalPackages() as $package) {
 11547 $downloader = $dm->getDownloaderForPackage($package);
 11548 $targetDir = $im->getInstallPath($package);
 11549 
 11550 if ($downloader instanceof ChangeReportInterface) {
 11551 if (is_link($targetDir)) {
 11552 $errors[$targetDir] = $targetDir . ' is a symbolic link.';
 11553 }
 11554 
 11555 if ($changes = $downloader->getLocalChanges($package, $targetDir)) {
 11556 $errors[$targetDir] = $changes;
 11557 }
 11558 }
 11559 
 11560 if ($downloader instanceof VcsCapableDownloaderInterface) {
 11561 if ($downloader->getVcsReference($package, $targetDir)) {
 11562 switch ($package->getInstallationSource()) {
 11563 case 'source':
 11564 $previousRef = $package->getSourceReference();
 11565 break;
 11566 case 'dist':
 11567 $previousRef = $package->getDistReference();
 11568 break;
 11569 default:
 11570 $previousRef = null;
 11571 }
 11572 
 11573 $currentVersion = $guesser->guessVersion($dumper->dump($package), $targetDir);
 11574 
 11575 if ($previousRef && $currentVersion && $currentVersion['commit'] !== $previousRef) {
 11576 $vcsVersionChanges[$targetDir] = array(
 11577 'previous' => array(
 11578 'version' => $package->getPrettyVersion(),
 11579 'ref' => $previousRef,
 11580 ),
 11581 'current' => array(
 11582 'version' => $currentVersion['pretty_version'],
 11583 'ref' => $currentVersion['commit'],
 11584 ),
 11585 );
 11586 }
 11587 }
 11588 }
 11589 
 11590 if ($downloader instanceof DvcsDownloaderInterface) {
 11591 if ($unpushed = $downloader->getUnpushedChanges($package, $targetDir)) {
 11592 $unpushedChanges[$targetDir] = $unpushed;
 11593 }
 11594 }
 11595 }
 11596 
 11597 
 11598 if (!$errors && !$unpushedChanges && !$vcsVersionChanges) {
 11599 $io->writeError('<info>No local changes</info>');
 11600 
 11601 return 0;
 11602 }
 11603 
 11604 if ($errors) {
 11605 $io->writeError('<error>You have changes in the following dependencies:</error>');
 11606 
 11607 foreach ($errors as $path => $changes) {
 11608 if ($input->getOption('verbose')) {
 11609 $indentedChanges = implode("\n", array_map(function ($line) {
 11610 return '    ' . ltrim($line);
 11611 }, explode("\n", $changes)));
 11612 $io->write('<info>'.$path.'</info>:');
 11613 $io->write($indentedChanges);
 11614 } else {
 11615 $io->write($path);
 11616 }
 11617 }
 11618 }
 11619 
 11620 if ($unpushedChanges) {
 11621 $io->writeError('<warning>You have unpushed changes on the current branch in the following dependencies:</warning>');
 11622 
 11623 foreach ($unpushedChanges as $path => $changes) {
 11624 if ($input->getOption('verbose')) {
 11625 $indentedChanges = implode("\n", array_map(function ($line) {
 11626 return '    ' . ltrim($line);
 11627 }, explode("\n", $changes)));
 11628 $io->write('<info>'.$path.'</info>:');
 11629 $io->write($indentedChanges);
 11630 } else {
 11631 $io->write($path);
 11632 }
 11633 }
 11634 }
 11635 
 11636 if ($vcsVersionChanges) {
 11637 $io->writeError('<warning>You have version variations in the following dependencies:</warning>');
 11638 
 11639 foreach ($vcsVersionChanges as $path => $changes) {
 11640 if ($input->getOption('verbose')) {
 11641 
 11642 $currentVersion = $changes['current']['version'] ?: $changes['current']['ref'];
 11643 $previousVersion = $changes['previous']['version'] ?: $changes['previous']['ref'];
 11644 
 11645 if ($io->isVeryVerbose()) {
 11646 
 11647 $currentVersion .= sprintf(' (%s)', $changes['current']['ref']);
 11648 $previousVersion .= sprintf(' (%s)', $changes['previous']['ref']);
 11649 }
 11650 
 11651 $io->write('<info>'.$path.'</info>:');
 11652 $io->write(sprintf('    From <comment>%s</comment> to <comment>%s</comment>', $previousVersion, $currentVersion));
 11653 } else {
 11654 $io->write($path);
 11655 }
 11656 }
 11657 }
 11658 
 11659 if (($errors || $unpushedChanges || $vcsVersionChanges) && !$input->getOption('verbose')) {
 11660 $io->writeError('Use --verbose (-v) to see a list of files');
 11661 }
 11662 
 11663 return ($errors ? self::EXIT_CODE_ERRORS : 0) + ($unpushedChanges ? self::EXIT_CODE_UNPUSHED_CHANGES : 0) + ($vcsVersionChanges ? self::EXIT_CODE_VERSION_CHANGES : 0);
 11664 }
 11665 }
 11666 <?php
 11667 
 11668 
 11669 
 11670 
 11671 
 11672 
 11673 
 11674 
 11675 
 11676 
 11677 
 11678 namespace Composer\Command;
 11679 
 11680 use Composer\Repository\PlatformRepository;
 11681 use Composer\Repository\RootPackageRepository;
 11682 use Composer\Repository\InstalledRepository;
 11683 use Composer\Installer\SuggestedPackagesReporter;
 11684 use Symfony\Component\Console\Input\InputArgument;
 11685 use Symfony\Component\Console\Input\InputInterface;
 11686 use Symfony\Component\Console\Input\InputOption;
 11687 use Symfony\Component\Console\Output\OutputInterface;
 11688 
 11689 class SuggestsCommand extends BaseCommand
 11690 {
 11691 
 11692 
 11693 
 11694 protected function configure()
 11695 {
 11696 $this
 11697 ->setName('suggests')
 11698 ->setDescription('Shows package suggestions.')
 11699 ->setDefinition(array(
 11700 new InputOption('by-package', null, InputOption::VALUE_NONE, 'Groups output by suggesting package (default)'),
 11701 new InputOption('by-suggestion', null, InputOption::VALUE_NONE, 'Groups output by suggested package'),
 11702 new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show suggestions from all dependencies, including transitive ones'),
 11703 new InputOption('list', null, InputOption::VALUE_NONE, 'Show only list of suggested package names'),
 11704 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Exclude suggestions from require-dev packages'),
 11705 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that you want to list suggestions from.'),
 11706 ))
 11707 ->setHelp(
 11708 <<<EOT
 11709 
 11710 The <info>%command.name%</info> command shows a sorted list of suggested packages.
 11711 
 11712 Read more at https://getcomposer.org/doc/03-cli.md#suggests
 11713 EOT
 11714 )
 11715 ;
 11716 }
 11717 
 11718 
 11719 
 11720 
 11721 protected function execute(InputInterface $input, OutputInterface $output)
 11722 {
 11723 $composer = $this->getComposer();
 11724 
 11725 $installedRepos = array(
 11726 new RootPackageRepository(clone $composer->getPackage()),
 11727 );
 11728 
 11729 $locker = $composer->getLocker();
 11730 if ($locker->isLocked()) {
 11731 $installedRepos[] = new PlatformRepository(array(), $locker->getPlatformOverrides());
 11732 $installedRepos[] = $locker->getLockedRepository(!$input->getOption('no-dev'));
 11733 } else {
 11734 $installedRepos[] = new PlatformRepository(array(), $composer->getConfig()->get('platform') ?: array());
 11735 $installedRepos[] = $composer->getRepositoryManager()->getLocalRepository();
 11736 }
 11737 
 11738 $installedRepo = new InstalledRepository($installedRepos);
 11739 $reporter = new SuggestedPackagesReporter($this->getIO());
 11740 
 11741 $filter = $input->getArgument('packages');
 11742 $packages = $installedRepo->getPackages();
 11743 $packages[] = $composer->getPackage();
 11744 foreach ($packages as $package) {
 11745 if (!empty($filter) && !in_array($package->getName(), $filter)) {
 11746 continue;
 11747 }
 11748 
 11749 $reporter->addSuggestionsFromPackage($package);
 11750 }
 11751 
 11752 
 11753 $mode = SuggestedPackagesReporter::MODE_BY_PACKAGE;
 11754 
 11755 
 11756 if ($input->getOption('by-suggestion')) {
 11757 $mode = SuggestedPackagesReporter::MODE_BY_SUGGESTION;
 11758 }
 11759 
 11760 if ($input->getOption('by-package')) {
 11761 $mode |= SuggestedPackagesReporter::MODE_BY_PACKAGE;
 11762 }
 11763 
 11764 if ($input->getOption('list')) {
 11765 $mode = SuggestedPackagesReporter::MODE_LIST;
 11766 }
 11767 
 11768 $reporter->output($mode, $installedRepo, empty($filter) && !$input->getOption('all') ? $composer->getPackage() : null);
 11769 
 11770 return 0;
 11771 }
 11772 }
 11773 <?php
 11774 
 11775 
 11776 
 11777 
 11778 
 11779 
 11780 
 11781 
 11782 
 11783 
 11784 
 11785 namespace Composer\Command;
 11786 
 11787 use Composer\Composer;
 11788 use Composer\DependencyResolver\Request;
 11789 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
 11790 use Composer\Installer;
 11791 use Composer\IO\IOInterface;
 11792 use Composer\Package\Loader\RootPackageLoader;
 11793 use Composer\Pcre\Preg;
 11794 use Composer\Plugin\CommandEvent;
 11795 use Composer\Plugin\PluginEvents;
 11796 use Composer\Package\Version\VersionParser;
 11797 use Composer\Util\HttpDownloader;
 11798 use Composer\Semver\Constraint\MultiConstraint;
 11799 use Composer\Package\Link;
 11800 use Symfony\Component\Console\Helper\Table;
 11801 use Symfony\Component\Console\Input\InputInterface;
 11802 use Symfony\Component\Console\Input\InputOption;
 11803 use Symfony\Component\Console\Input\InputArgument;
 11804 use Symfony\Component\Console\Output\OutputInterface;
 11805 use Symfony\Component\Console\Question\Question;
 11806 
 11807 
 11808 
 11809 
 11810 
 11811 class UpdateCommand extends BaseCommand
 11812 {
 11813 
 11814 
 11815 
 11816 protected function configure()
 11817 {
 11818 $this
 11819 ->setName('update')
 11820 ->setAliases(array('u', 'upgrade'))
 11821 ->setDescription('Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.')
 11822 ->setDefinition(array(
 11823 new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.'),
 11824 new InputOption('with', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Temporary version constraint to add, e.g. foo/bar:1.0.0 or foo/bar=1.0.0'),
 11825 new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'),
 11826 new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
 11827 new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'),
 11828 new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'),
 11829 new InputOption('dev', null, InputOption::VALUE_NONE, 'DEPRECATED: Enables installation of require-dev packages (enabled by default, only present for BC).'),
 11830 new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
 11831 new InputOption('lock', null, InputOption::VALUE_NONE, 'Overwrites the lock file hash to suppress warning about the lock file being out of date without updating package versions. Package metadata like mirrors and URLs are updated if they changed.'),
 11832 new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'),
 11833 new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'),
 11834 new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'),
 11835 new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
 11836 new InputOption('with-dependencies', 'w', InputOption::VALUE_NONE, 'Update also dependencies of packages in the argument list, except those which are root requirements.'),
 11837 new InputOption('with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Update also dependencies of packages in the argument list, including those which are root requirements.'),
 11838 new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
 11839 new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump.'),
 11840 new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
 11841 new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
 11842 new InputOption('apcu-autoloader-prefix', null, InputOption::VALUE_REQUIRED, 'Use a custom prefix for the APCu autoloader cache. Implicitly enables --apcu-autoloader'),
 11843 new InputOption('ignore-platform-req', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Ignore a specific platform requirement (php & ext- packages).'),
 11844 new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore all platform requirements (php & ext- packages).'),
 11845 new InputOption('prefer-stable', null, InputOption::VALUE_NONE, 'Prefer stable versions of dependencies.'),
 11846 new InputOption('prefer-lowest', null, InputOption::VALUE_NONE, 'Prefer lowest versions of dependencies.'),
 11847 new InputOption('interactive', 'i', InputOption::VALUE_NONE, 'Interactive interface with autocompletion to select the packages to update.'),
 11848 new InputOption('root-reqs', null, InputOption::VALUE_NONE, 'Restricts the update to your first degree dependencies.'),
 11849 ))
 11850 ->setHelp(
 11851 <<<EOT
 11852 The <info>update</info> command reads the composer.json file from the
 11853 current directory, processes it, and updates, removes or installs all the
 11854 dependencies.
 11855 
 11856 <info>php composer.phar update</info>
 11857 
 11858 To limit the update operation to a few packages, you can list the package(s)
 11859 you want to update as such:
 11860 
 11861 <info>php composer.phar update vendor/package1 foo/mypackage [...]</info>
 11862 
 11863 You may also use an asterisk (*) pattern to limit the update operation to package(s)
 11864 from a specific vendor:
 11865 
 11866 <info>php composer.phar update vendor/package1 foo/* [...]</info>
 11867 
 11868 To run an update with more restrictive constraints you can use:
 11869 
 11870 <info>php composer.phar update --with vendor/package:1.0.*</info>
 11871 
 11872 To run a partial update with more restrictive constraints you can use the shorthand:
 11873 
 11874 <info>php composer.phar update vendor/package:1.0.*</info>
 11875 
 11876 To select packages names interactively with auto-completion use <info>-i</info>.
 11877 
 11878 Read more at https://getcomposer.org/doc/03-cli.md#update-u
 11879 EOT
 11880 )
 11881 ;
 11882 }
 11883 
 11884 
 11885 
 11886 
 11887 
 11888 protected function execute(InputInterface $input, OutputInterface $output)
 11889 {
 11890 $io = $this->getIO();
 11891 if ($input->getOption('dev')) {
 11892 $io->writeError('<warning>You are using the deprecated option "--dev". It has no effect and will break in Composer 3.</warning>');
 11893 }
 11894 if ($input->getOption('no-suggest')) {
 11895 $io->writeError('<warning>You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.</warning>');
 11896 }
 11897 
 11898 $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
 11899 
 11900 if (!HttpDownloader::isCurlEnabled()) {
 11901 $io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>');
 11902 }
 11903 
 11904 $packages = $input->getArgument('packages');
 11905 $reqs = $this->formatRequirements($input->getOption('with'));
 11906 
 11907 
 11908 if ($packages) {
 11909 $allowlistPackagesWithRequirements = array_filter($packages, function ($pkg) {
 11910 return Preg::isMatch('{\S+[ =:]\S+}', $pkg);
 11911 });
 11912 foreach ($this->formatRequirements($allowlistPackagesWithRequirements) as $package => $constraint) {
 11913 $reqs[$package] = $constraint;
 11914 }
 11915 
 11916 
 11917 foreach ($allowlistPackagesWithRequirements as $package) {
 11918 $packageName = Preg::replace('{^([^ =:]+)[ =:].*$}', '$1', $package);
 11919 $index = array_search($package, $packages);
 11920 $packages[$index] = $packageName;
 11921 }
 11922 }
 11923 
 11924 $rootPackage = $composer->getPackage();
 11925 $rootRequires = $rootPackage->getRequires();
 11926 $rootDevRequires = $rootPackage->getDevRequires();
 11927 foreach ($reqs as $package => $constraint) {
 11928 if (isset($rootRequires[$package])) {
 11929 $rootRequires[$package] = $this->appendConstraintToLink($rootRequires[$package], $constraint);
 11930 } elseif (isset($rootDevRequires[$package])) {
 11931 $rootDevRequires[$package] = $this->appendConstraintToLink($rootDevRequires[$package], $constraint);
 11932 } else {
 11933 throw new \UnexpectedValueException('Only root package requirements can receive temporary constraints and '.$package.' is not one');
 11934 }
 11935 }
 11936 $rootPackage->setRequires($rootRequires);
 11937 $rootPackage->setDevRequires($rootDevRequires);
 11938 $rootPackage->setReferences(RootPackageLoader::extractReferences($reqs, $rootPackage->getReferences()));
 11939 $rootPackage->setStabilityFlags(RootPackageLoader::extractStabilityFlags($reqs, $rootPackage->getMinimumStability(), $rootPackage->getStabilityFlags()));
 11940 
 11941 if ($input->getOption('interactive')) {
 11942 $packages = $this->getPackagesInteractively($io, $input, $output, $composer, $packages);
 11943 }
 11944 
 11945 if ($input->getOption('root-reqs')) {
 11946 $requires = array_keys($rootRequires);
 11947 if (!$input->getOption('no-dev')) {
 11948 $requires = array_merge($requires, array_keys($rootDevRequires));
 11949 }
 11950 
 11951 if (!empty($packages)) {
 11952 $packages = array_intersect($packages, $requires);
 11953 } else {
 11954 $packages = $requires;
 11955 }
 11956 }
 11957 
 11958 
 11959 
 11960 $filteredPackages = array_filter($packages, function ($package) {
 11961 return !in_array($package, array('lock', 'nothing', 'mirrors'), true);
 11962 });
 11963 $updateMirrors = $input->getOption('lock') || count($filteredPackages) != count($packages);
 11964 $packages = $filteredPackages;
 11965 
 11966 if ($updateMirrors && !empty($packages)) {
 11967 $io->writeError('<error>You cannot simultaneously update only a selection of packages and regenerate the lock file metadata.</error>');
 11968 
 11969 return -1;
 11970 }
 11971 
 11972 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'update', $input, $output);
 11973 $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
 11974 
 11975 $composer->getInstallationManager()->setOutputProgress(!$input->getOption('no-progress'));
 11976 
 11977 $install = Installer::create($io, $composer);
 11978 
 11979 $config = $composer->getConfig();
 11980 list($preferSource, $preferDist) = $this->getPreferredInstallOptions($config, $input);
 11981 
 11982 $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
 11983 $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
 11984 $apcuPrefix = $input->getOption('apcu-autoloader-prefix');
 11985 $apcu = $apcuPrefix !== null || $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader');
 11986 
 11987 $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED;
 11988 if ($input->getOption('with-all-dependencies')) {
 11989 $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
 11990 } elseif ($input->getOption('with-dependencies')) {
 11991 $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE;
 11992 }
 11993 
 11994 $ignorePlatformReqs = $input->getOption('ignore-platform-reqs') ?: ($input->getOption('ignore-platform-req') ?: false);
 11995 
 11996 $install
 11997 ->setDryRun($input->getOption('dry-run'))
 11998 ->setVerbose($input->getOption('verbose'))
 11999 ->setPreferSource($preferSource)
 12000 ->setPreferDist($preferDist)
 12001 ->setDevMode(!$input->getOption('no-dev'))
 12002 ->setDumpAutoloader(!$input->getOption('no-autoloader'))
 12003 ->setOptimizeAutoloader($optimize)
 12004 ->setClassMapAuthoritative($authoritative)
 12005 ->setApcuAutoloader($apcu, $apcuPrefix)
 12006 ->setUpdate(true)
 12007 ->setInstall(!$input->getOption('no-install'))
 12008 ->setUpdateMirrors($updateMirrors)
 12009 ->setUpdateAllowList($packages)
 12010 ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies)
 12011 ->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs))
 12012 ->setPreferStable($input->getOption('prefer-stable'))
 12013 ->setPreferLowest($input->getOption('prefer-lowest'))
 12014 ;
 12015 
 12016 if ($input->getOption('no-plugins')) {
 12017 $install->disablePlugins();
 12018 }
 12019 
 12020 return $install->run();
 12021 }
 12022 
 12023 
 12024 
 12025 
 12026 
 12027 private function getPackagesInteractively(IOInterface $io, InputInterface $input, OutputInterface $output, Composer $composer, array $packages)
 12028 {
 12029 if (!$input->isInteractive()) {
 12030 throw new \InvalidArgumentException('--interactive cannot be used in non-interactive terminals.');
 12031 }
 12032 
 12033 $requires = array_merge(
 12034 $composer->getPackage()->getRequires(),
 12035 $composer->getPackage()->getDevRequires()
 12036 );
 12037 $autocompleterValues = array();
 12038 foreach ($requires as $require) {
 12039 $target = $require->getTarget();
 12040 $autocompleterValues[strtolower($target)] = $target;
 12041 }
 12042 
 12043 $installedPackages = $composer->getRepositoryManager()->getLocalRepository()->getPackages();
 12044 foreach ($installedPackages as $package) {
 12045 $autocompleterValues[$package->getName()] = $package->getPrettyName();
 12046 }
 12047 
 12048 $helper = $this->getHelper('question');
 12049 $question = new Question('<comment>Enter package name: </comment>', null);
 12050 
 12051 $io->writeError('<info>Press enter without value to end submission</info>');
 12052 
 12053 do {
 12054 $autocompleterValues = array_diff($autocompleterValues, $packages);
 12055 $question->setAutocompleterValues($autocompleterValues);
 12056 $addedPackage = $helper->ask($input, $output, $question);
 12057 
 12058 if (!is_string($addedPackage) || empty($addedPackage)) {
 12059 break;
 12060 }
 12061 
 12062 $addedPackage = strtolower($addedPackage);
 12063 if (!in_array($addedPackage, $packages)) {
 12064 $packages[] = $addedPackage;
 12065 }
 12066 } while (true);
 12067 
 12068 $packages = array_filter($packages);
 12069 if (!$packages) {
 12070 throw new \InvalidArgumentException('You must enter minimum one package.');
 12071 }
 12072 
 12073 $table = new Table($output);
 12074 $table->setHeaders(array('Selected packages'));
 12075 foreach ($packages as $package) {
 12076 $table->addRow(array($package));
 12077 }
 12078 $table->render();
 12079 
 12080 if ($io->askConfirmation(sprintf(
 12081 'Would you like to continue and update the above package%s [<comment>yes</comment>]? ',
 12082 1 === count($packages) ? '' : 's'
 12083 ))) {
 12084 return $packages;
 12085 }
 12086 
 12087 throw new \RuntimeException('Installation aborted.');
 12088 }
 12089 
 12090 
 12091 
 12092 
 12093 
 12094 private function appendConstraintToLink(Link $link, $constraint)
 12095 {
 12096 $parser = new VersionParser;
 12097 $oldPrettyString = $link->getConstraint()->getPrettyString();
 12098 $newConstraint = MultiConstraint::create(array($link->getConstraint(), $parser->parseConstraints($constraint)));
 12099 $newConstraint->setPrettyString($oldPrettyString.', '.$constraint);
 12100 
 12101 return new Link(
 12102 $link->getSource(),
 12103 $link->getTarget(),
 12104 $newConstraint,
 12105 
 12106 $link->getDescription(),
 12107 $link->getPrettyConstraint() . ', ' . $constraint
 12108 );
 12109 }
 12110 }
 12111 <?php
 12112 
 12113 
 12114 
 12115 
 12116 
 12117 
 12118 
 12119 
 12120 
 12121 
 12122 
 12123 namespace Composer\Command;
 12124 
 12125 use Composer\Factory;
 12126 use Composer\IO\IOInterface;
 12127 use Composer\Package\Loader\ValidatingArrayLoader;
 12128 use Composer\Plugin\CommandEvent;
 12129 use Composer\Plugin\PluginEvents;
 12130 use Composer\Repository\InstalledRepository;
 12131 use Composer\Repository\PlatformRepository;
 12132 use Composer\Util\ConfigValidator;
 12133 use Composer\Util\Filesystem;
 12134 use Symfony\Component\Console\Input\InputArgument;
 12135 use Symfony\Component\Console\Input\InputInterface;
 12136 use Symfony\Component\Console\Input\InputOption;
 12137 use Symfony\Component\Console\Output\OutputInterface;
 12138 
 12139 
 12140 
 12141 
 12142 
 12143 
 12144 
 12145 class ValidateCommand extends BaseCommand
 12146 {
 12147 
 12148 
 12149 
 12150 
 12151 protected function configure()
 12152 {
 12153 $this
 12154 ->setName('validate')
 12155 ->setDescription('Validates a composer.json and composer.lock.')
 12156 ->setDefinition(array(
 12157 new InputOption('no-check-all', null, InputOption::VALUE_NONE, 'Do not validate requires for overly strict/loose constraints'),
 12158 new InputOption('no-check-lock', null, InputOption::VALUE_NONE, 'Do not check if lock file is up to date'),
 12159 new InputOption('no-check-publish', null, InputOption::VALUE_NONE, 'Do not check for publish errors'),
 12160 new InputOption('no-check-version', null, InputOption::VALUE_NONE, 'Do not report a warning if the version field is present'),
 12161 new InputOption('with-dependencies', 'A', InputOption::VALUE_NONE, 'Also validate the composer.json of all installed dependencies'),
 12162 new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code for warnings as well as errors'),
 12163 new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file'),
 12164 ))
 12165 ->setHelp(
 12166 <<<EOT
 12167 The validate command validates a given composer.json and composer.lock
 12168 
 12169 Exit codes in case of errors are:
 12170 1 validation warning(s), only when --strict is given
 12171 2 validation error(s)
 12172 3 file unreadable or missing
 12173 
 12174 Read more at https://getcomposer.org/doc/03-cli.md#validate
 12175 EOT
 12176 );
 12177 }
 12178 
 12179 
 12180 
 12181 
 12182 protected function execute(InputInterface $input, OutputInterface $output)
 12183 {
 12184 $file = $input->getArgument('file') ?: Factory::getComposerFile();
 12185 $io = $this->getIO();
 12186 
 12187 if (!file_exists($file)) {
 12188 $io->writeError('<error>' . $file . ' not found.</error>');
 12189 
 12190 return 3;
 12191 }
 12192 if (!Filesystem::isReadable($file)) {
 12193 $io->writeError('<error>' . $file . ' is not readable.</error>');
 12194 
 12195 return 3;
 12196 }
 12197 
 12198 $validator = new ConfigValidator($io);
 12199 $checkAll = $input->getOption('no-check-all') ? 0 : ValidatingArrayLoader::CHECK_ALL;
 12200 $checkPublish = !$input->getOption('no-check-publish');
 12201 $checkLock = !$input->getOption('no-check-lock');
 12202 $checkVersion = $input->getOption('no-check-version') ? 0 : ConfigValidator::CHECK_VERSION;
 12203 $isStrict = $input->getOption('strict');
 12204 list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll, $checkVersion);
 12205 
 12206 $lockErrors = array();
 12207 $composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins'));
 12208 $locker = $composer->getLocker();
 12209 if ($locker->isLocked() && !$locker->isFresh()) {
 12210 $lockErrors[] = '- The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update` or `composer update <package name>`.';
 12211 }
 12212 
 12213 if ($locker->isLocked()) {
 12214 $missingRequirements = false;
 12215 $sets = array(
 12216 array('repo' => $locker->getLockedRepository(false), 'method' => 'getRequires', 'description' => 'Required'),
 12217 array('repo' => $locker->getLockedRepository(true), 'method' => 'getDevRequires', 'description' => 'Required (in require-dev)'),
 12218 );
 12219 foreach ($sets as $set) {
 12220 $installedRepo = new InstalledRepository(array($set['repo']));
 12221 
 12222 foreach (call_user_func(array($composer->getPackage(), $set['method'])) as $link) {
 12223 if (PlatformRepository::isPlatformPackage($link->getTarget())) {
 12224 continue;
 12225 }
 12226 if (!$installedRepo->findPackagesWithReplacersAndProviders($link->getTarget(), $link->getConstraint())) {
 12227 if ($results = $installedRepo->findPackagesWithReplacersAndProviders($link->getTarget())) {
 12228 $provider = reset($results);
 12229 $lockErrors[] = '- ' . $set['description'].' package "' . $link->getTarget() . '" is in the lock file as "'.$provider->getPrettyVersion().'" but that does not satisfy your constraint "'.$link->getPrettyConstraint().'".';
 12230 } else {
 12231 $lockErrors[] = '- ' . $set['description'].' package "' . $link->getTarget() . '" is not present in the lock file.';
 12232 }
 12233 $missingRequirements = true;
 12234 }
 12235 }
 12236 }
 12237 
 12238 if ($missingRequirements) {
 12239 $lockErrors[] = 'This usually happens when composer files are incorrectly merged or the composer.json file is manually edited.';
 12240 $lockErrors[] = 'Read more about correctly resolving merge conflicts https://getcomposer.org/doc/articles/resolving-merge-conflicts.md';
 12241 $lockErrors[] = 'and prefer using the "require" command over editing the composer.json file directly https://getcomposer.org/doc/03-cli.md#require';
 12242 }
 12243 }
 12244 
 12245 $this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true);
 12246 
 12247 
 12248 $exitCode = $errors ? 2 : ($isStrict && $warnings ? 1 : 0);
 12249 
 12250 if ($input->getOption('with-dependencies')) {
 12251 $localRepo = $composer->getRepositoryManager()->getLocalRepository();
 12252 foreach ($localRepo->getPackages() as $package) {
 12253 $path = $composer->getInstallationManager()->getInstallPath($package);
 12254 $file = $path . '/composer.json';
 12255 if (is_dir($path) && file_exists($file)) {
 12256 list($errors, $publishErrors, $warnings) = $validator->validate($file, $checkAll, $checkVersion);
 12257 
 12258 $this->outputResult($io, $package->getPrettyName(), $errors, $warnings, $checkPublish, $publishErrors);
 12259 
 12260 
 12261 $depCode = $errors ? 2 : ($isStrict && $warnings ? 1 : 0);
 12262 $exitCode = max($depCode, $exitCode);
 12263 }
 12264 }
 12265 }
 12266 
 12267 $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'validate', $input, $output);
 12268 $eventCode = $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
 12269 
 12270 return max($eventCode, $exitCode);
 12271 }
 12272 
 12273 
 12274 
 12275 
 12276 
 12277 
 12278 
 12279 
 12280 
 12281 
 12282 
 12283 
 12284 
 12285 private function outputResult(IOInterface $io, $name, &$errors, &$warnings, $checkPublish = false, $publishErrors = array(), $checkLock = false, $lockErrors = array(), $printSchemaUrl = false)
 12286 {
 12287 $doPrintSchemaUrl = false;
 12288 
 12289 if ($errors) {
 12290 $io->writeError('<error>' . $name . ' is invalid, the following errors/warnings were found:</error>');
 12291 } elseif ($publishErrors) {
 12292 $io->writeError('<info>' . $name . ' is valid for simple usage with Composer but has</info>');
 12293 $io->writeError('<info>strict errors that make it unable to be published as a package</info>');
 12294 $doPrintSchemaUrl = $printSchemaUrl;
 12295 } elseif ($warnings) {
 12296 $io->writeError('<info>' . $name . ' is valid, but with a few warnings</info>');
 12297 $doPrintSchemaUrl = $printSchemaUrl;
 12298 } elseif ($lockErrors) {
 12299 $io->write('<info>' . $name . ' is valid but your composer.lock has some '.($checkLock ? 'errors' : 'warnings').'</info>');
 12300 } else {
 12301 $io->write('<info>' . $name . ' is valid</info>');
 12302 }
 12303 
 12304 if ($doPrintSchemaUrl) {
 12305 $io->writeError('<warning>See https://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
 12306 }
 12307 
 12308 if ($errors) {
 12309 $errors = array_map(function ($err) {
 12310 return '- ' . $err;
 12311 }, $errors);
 12312 array_unshift($errors, '# General errors');
 12313 }
 12314 if ($warnings) {
 12315 $warnings = array_map(function ($err) {
 12316 return '- ' . $err;
 12317 }, $warnings);
 12318 array_unshift($warnings, '# General warnings');
 12319 }
 12320 
 12321 
 12322 $extraWarnings = array();
 12323 
 12324 
 12325 if ($publishErrors) {
 12326 $publishErrors = array_map(function ($err) {
 12327 return '- ' . $err;
 12328 }, $publishErrors);
 12329 
 12330 if ($checkPublish) {
 12331 array_unshift($publishErrors, '# Publish errors');
 12332 $errors = array_merge($errors, $publishErrors);
 12333 } else {
 12334 array_unshift($publishErrors, '# Publish warnings');
 12335 $extraWarnings = array_merge($extraWarnings, $publishErrors);
 12336 }
 12337 }
 12338 
 12339 
 12340 if ($lockErrors) {
 12341 if ($checkLock) {
 12342 array_unshift($lockErrors, '# Lock file errors');
 12343 $errors = array_merge($errors, $lockErrors);
 12344 } else {
 12345 array_unshift($lockErrors, '# Lock file warnings');
 12346 $extraWarnings = array_merge($extraWarnings, $lockErrors);
 12347 }
 12348 }
 12349 
 12350 $messages = array(
 12351 'error' => $errors,
 12352 'warning' => array_merge($warnings, $extraWarnings),
 12353 );
 12354 
 12355 foreach ($messages as $style => $msgs) {
 12356 foreach ($msgs as $msg) {
 12357 if (strpos($msg, '#') === 0) {
 12358 $io->writeError('<' . $style . '>' . $msg . '</' . $style . '>');
 12359 } else {
 12360 $io->writeError($msg);
 12361 }
 12362 }
 12363 }
 12364 }
 12365 }
 12366 <?php
 12367 
 12368 
 12369 
 12370 
 12371 
 12372 
 12373 
 12374 
 12375 
 12376 
 12377 
 12378 namespace Composer;
 12379 
 12380 use Composer\Package\RootPackageInterface;
 12381 use Composer\Package\Locker;
 12382 use Composer\Pcre\Preg;
 12383 use Composer\Util\Loop;
 12384 use Composer\Repository\RepositoryManager;
 12385 use Composer\Installer\InstallationManager;
 12386 use Composer\Plugin\PluginManager;
 12387 use Composer\Downloader\DownloadManager;
 12388 use Composer\EventDispatcher\EventDispatcher;
 12389 use Composer\Autoload\AutoloadGenerator;
 12390 use Composer\Package\Archiver\ArchiveManager;
 12391 
 12392 
 12393 
 12394 
 12395 
 12396 
 12397 class Composer
 12398 {
 12399 
 12400 
 12401 
 12402 
 12403 
 12404 
 12405 
 12406 
 12407 
 12408 
 12409 
 12410 
 12411 
 12412 
 12413 
 12414 
 12415 
 12416 
 12417 
 12418 
 12419 
 12420 const VERSION = '2.2.9';
 12421 const BRANCH_ALIAS_VERSION = '';
 12422 const RELEASE_DATE = '2022-03-15 22:13:37';
 12423 const SOURCE_VERSION = '';
 12424 
 12425 
 12426 
 12427 
 12428 
 12429 
 12430 
 12431 
 12432 
 12433 
 12434 const RUNTIME_API_VERSION = '2.2.2';
 12435 
 12436 
 12437 
 12438 
 12439 public static function getVersion()
 12440 {
 12441 
 12442 if (self::VERSION === '@package_version'.'@') {
 12443 return self::SOURCE_VERSION;
 12444 }
 12445 
 12446 
 12447 if (self::BRANCH_ALIAS_VERSION !== '' && Preg::isMatch('{^[a-f0-9]{40}$}', self::VERSION)) {
 12448 return self::BRANCH_ALIAS_VERSION.'+'.self::VERSION;
 12449 }
 12450 
 12451 return self::VERSION;
 12452 }
 12453 
 12454 
 12455 
 12456 
 12457 private $package;
 12458 
 12459 
 12460 
 12461 
 12462 private $locker = null;
 12463 
 12464 
 12465 
 12466 
 12467 private $loop;
 12468 
 12469 
 12470 
 12471 
 12472 private $repositoryManager;
 12473 
 12474 
 12475 
 12476 
 12477 private $downloadManager;
 12478 
 12479 
 12480 
 12481 
 12482 private $installationManager;
 12483 
 12484 
 12485 
 12486 
 12487 private $pluginManager;
 12488 
 12489 
 12490 
 12491 
 12492 private $config;
 12493 
 12494 
 12495 
 12496 
 12497 private $eventDispatcher;
 12498 
 12499 
 12500 
 12501 
 12502 private $autoloadGenerator;
 12503 
 12504 
 12505 
 12506 
 12507 private $archiveManager;
 12508 
 12509 
 12510 
 12511 
 12512 public function setPackage(RootPackageInterface $package)
 12513 {
 12514 $this->package = $package;
 12515 }
 12516 
 12517 
 12518 
 12519 
 12520 public function getPackage()
 12521 {
 12522 return $this->package;
 12523 }
 12524 
 12525 
 12526 
 12527 
 12528 public function setConfig(Config $config)
 12529 {
 12530 $this->config = $config;
 12531 }
 12532 
 12533 
 12534 
 12535 
 12536 public function getConfig()
 12537 {
 12538 return $this->config;
 12539 }
 12540 
 12541 
 12542 
 12543 
 12544 public function setLocker(Locker $locker)
 12545 {
 12546 $this->locker = $locker;
 12547 }
 12548 
 12549 
 12550 
 12551 
 12552 public function getLocker()
 12553 {
 12554 return $this->locker;
 12555 }
 12556 
 12557 
 12558 
 12559 
 12560 public function setLoop(Loop $loop)
 12561 {
 12562 $this->loop = $loop;
 12563 }
 12564 
 12565 
 12566 
 12567 
 12568 public function getLoop()
 12569 {
 12570 return $this->loop;
 12571 }
 12572 
 12573 
 12574 
 12575 
 12576 public function setRepositoryManager(RepositoryManager $manager)
 12577 {
 12578 $this->repositoryManager = $manager;
 12579 }
 12580 
 12581 
 12582 
 12583 
 12584 public function getRepositoryManager()
 12585 {
 12586 return $this->repositoryManager;
 12587 }
 12588 
 12589 
 12590 
 12591 
 12592 public function setDownloadManager(DownloadManager $manager)
 12593 {
 12594 $this->downloadManager = $manager;
 12595 }
 12596 
 12597 
 12598 
 12599 
 12600 public function getDownloadManager()
 12601 {
 12602 return $this->downloadManager;
 12603 }
 12604 
 12605 
 12606 
 12607 
 12608 public function setArchiveManager(ArchiveManager $manager)
 12609 {
 12610 $this->archiveManager = $manager;
 12611 }
 12612 
 12613 
 12614 
 12615 
 12616 public function getArchiveManager()
 12617 {
 12618 return $this->archiveManager;
 12619 }
 12620 
 12621 
 12622 
 12623 
 12624 public function setInstallationManager(InstallationManager $manager)
 12625 {
 12626 $this->installationManager = $manager;
 12627 }
 12628 
 12629 
 12630 
 12631 
 12632 public function getInstallationManager()
 12633 {
 12634 return $this->installationManager;
 12635 }
 12636 
 12637 
 12638 
 12639 
 12640 public function setPluginManager(PluginManager $manager)
 12641 {
 12642 $this->pluginManager = $manager;
 12643 }
 12644 
 12645 
 12646 
 12647 
 12648 public function getPluginManager()
 12649 {
 12650 return $this->pluginManager;
 12651 }
 12652 
 12653 
 12654 
 12655 
 12656 public function setEventDispatcher(EventDispatcher $eventDispatcher)
 12657 {
 12658 $this->eventDispatcher = $eventDispatcher;
 12659 }
 12660 
 12661 
 12662 
 12663 
 12664 public function getEventDispatcher()
 12665 {
 12666 return $this->eventDispatcher;
 12667 }
 12668 
 12669 
 12670 
 12671 
 12672 public function setAutoloadGenerator(AutoloadGenerator $autoloadGenerator)
 12673 {
 12674 $this->autoloadGenerator = $autoloadGenerator;
 12675 }
 12676 
 12677 
 12678 
 12679 
 12680 public function getAutoloadGenerator()
 12681 {
 12682 return $this->autoloadGenerator;
 12683 }
 12684 }
 12685 <?php
 12686 
 12687 
 12688 
 12689 
 12690 
 12691 
 12692 
 12693 
 12694 
 12695 
 12696 
 12697 namespace Composer;
 12698 
 12699 use Composer\Config\ConfigSourceInterface;
 12700 use Composer\Downloader\TransportException;
 12701 use Composer\IO\IOInterface;
 12702 use Composer\Pcre\Preg;
 12703 use Composer\Util\Platform;
 12704 use Composer\Util\ProcessExecutor;
 12705 
 12706 
 12707 
 12708 
 12709 class Config
 12710 {
 12711 const SOURCE_DEFAULT = 'default';
 12712 const SOURCE_COMMAND = 'command';
 12713 const SOURCE_UNKNOWN = 'unknown';
 12714 
 12715 const RELATIVE_PATHS = 1;
 12716 
 12717 
 12718 public static $defaultConfig = array(
 12719 'process-timeout' => 300,
 12720 'use-include-path' => false,
 12721 'allow-plugins' => null, 
 12722 'use-parent-dir' => 'prompt',
 12723 'preferred-install' => 'dist',
 12724 'notify-on-install' => true,
 12725 'github-protocols' => array('https', 'ssh', 'git'),
 12726 'gitlab-protocol' => null,
 12727 'vendor-dir' => 'vendor',
 12728 'bin-dir' => '{$vendor-dir}/bin',
 12729 'cache-dir' => '{$home}/cache',
 12730 'data-dir' => '{$home}',
 12731 'cache-files-dir' => '{$cache-dir}/files',
 12732 'cache-repo-dir' => '{$cache-dir}/repo',
 12733 'cache-vcs-dir' => '{$cache-dir}/vcs',
 12734 'cache-ttl' => 15552000, 
 12735 'cache-files-ttl' => null, 
 12736 'cache-files-maxsize' => '300MiB',
 12737 'cache-read-only' => false,
 12738 'bin-compat' => 'auto',
 12739 'discard-changes' => false,
 12740 'autoloader-suffix' => null,
 12741 'sort-packages' => false,
 12742 'optimize-autoloader' => false,
 12743 'classmap-authoritative' => false,
 12744 'apcu-autoloader' => false,
 12745 'prepend-autoloader' => true,
 12746 'github-domains' => array('github.com'),
 12747 'bitbucket-expose-hostname' => true,
 12748 'disable-tls' => false,
 12749 'secure-http' => true,
 12750 'secure-svn-domains' => array(),
 12751 'cafile' => null,
 12752 'capath' => null,
 12753 'github-expose-hostname' => true,
 12754 'gitlab-domains' => array('gitlab.com'),
 12755 'store-auths' => 'prompt',
 12756 'platform' => array(),
 12757 'archive-format' => 'tar',
 12758 'archive-dir' => '.',
 12759 'htaccess-protect' => true,
 12760 'use-github-api' => true,
 12761 'lock' => true,
 12762 'platform-check' => 'php-only',
 12763 
 12764 
 12765 
 12766 
 12767 
 12768 
 12769 
 12770 );
 12771 
 12772 
 12773 public static $defaultRepositories = array(
 12774 'packagist.org' => array(
 12775 'type' => 'composer',
 12776 'url' => 'https://repo.packagist.org',
 12777 ),
 12778 );
 12779 
 12780 
 12781 private $config;
 12782 
 12783 private $baseDir;
 12784 
 12785 private $repositories;
 12786 
 12787 private $configSource;
 12788 
 12789 private $authConfigSource;
 12790 
 12791 private $useEnvironment;
 12792 
 12793 private $warnedHosts = array();
 12794 
 12795 private $sourceOfConfigValue = array();
 12796 
 12797 
 12798 
 12799 
 12800 
 12801 public function __construct($useEnvironment = true, $baseDir = null)
 12802 {
 12803 
 12804 $this->config = static::$defaultConfig;
 12805 
 12806 
 12807 if (strtotime('2022-07-01') < time()) {
 12808 $this->config['allow-plugins'] = array();
 12809 }
 12810 
 12811 $this->repositories = static::$defaultRepositories;
 12812 $this->useEnvironment = (bool) $useEnvironment;
 12813 $this->baseDir = $baseDir;
 12814 
 12815 foreach ($this->config as $configKey => $configValue) {
 12816 $this->setSourceOfConfigValue($configValue, $configKey, self::SOURCE_DEFAULT);
 12817 }
 12818 
 12819 foreach ($this->repositories as $configKey => $configValue) {
 12820 $this->setSourceOfConfigValue($configValue, 'repositories.' . $configKey, self::SOURCE_DEFAULT);
 12821 }
 12822 }
 12823 
 12824 
 12825 
 12826 
 12827 public function setConfigSource(ConfigSourceInterface $source)
 12828 {
 12829 $this->configSource = $source;
 12830 }
 12831 
 12832 
 12833 
 12834 
 12835 public function getConfigSource()
 12836 {
 12837 return $this->configSource;
 12838 }
 12839 
 12840 
 12841 
 12842 
 12843 public function setAuthConfigSource(ConfigSourceInterface $source)
 12844 {
 12845 $this->authConfigSource = $source;
 12846 }
 12847 
 12848 
 12849 
 12850 
 12851 public function getAuthConfigSource()
 12852 {
 12853 return $this->authConfigSource;
 12854 }
 12855 
 12856 
 12857 
 12858 
 12859 
 12860 
 12861 
 12862 
 12863 
 12864 public function merge($config, $source = self::SOURCE_UNKNOWN)
 12865 {
 12866 
 12867 if (!empty($config['config']) && is_array($config['config'])) {
 12868 foreach ($config['config'] as $key => $val) {
 12869 if (in_array($key, array('bitbucket-oauth', 'github-oauth', 'gitlab-oauth', 'gitlab-token', 'http-basic', 'bearer'), true) && isset($this->config[$key])) {
 12870 $this->config[$key] = array_merge($this->config[$key], $val);
 12871 $this->setSourceOfConfigValue($val, $key, $source);
 12872 } elseif (in_array($key, array('allow-plugins'), true) && isset($this->config[$key]) && is_array($this->config[$key])) {
 12873 
 12874 
 12875 $this->config[$key] = array_merge($val, $this->config[$key], $val);
 12876 $this->setSourceOfConfigValue($val, $key, $source);
 12877 } elseif (in_array($key, array('gitlab-domains', 'github-domains'), true) && isset($this->config[$key])) {
 12878 $this->config[$key] = array_unique(array_merge($this->config[$key], $val));
 12879 $this->setSourceOfConfigValue($val, $key, $source);
 12880 } elseif ('preferred-install' === $key && isset($this->config[$key])) {
 12881 if (is_array($val) || is_array($this->config[$key])) {
 12882 if (is_string($val)) {
 12883 $val = array('*' => $val);
 12884 }
 12885 if (is_string($this->config[$key])) {
 12886 $this->config[$key] = array('*' => $this->config[$key]);
 12887 $this->sourceOfConfigValue[$key . '*'] = $source;
 12888 }
 12889 $this->config[$key] = array_merge($this->config[$key], $val);
 12890 $this->setSourceOfConfigValue($val, $key, $source);
 12891 
 12892 if (isset($this->config[$key]['*'])) {
 12893 $wildcard = $this->config[$key]['*'];
 12894 unset($this->config[$key]['*']);
 12895 $this->config[$key]['*'] = $wildcard;
 12896 }
 12897 } else {
 12898 $this->config[$key] = $val;
 12899 $this->setSourceOfConfigValue($val, $key, $source);
 12900 }
 12901 } else {
 12902 $this->config[$key] = $val;
 12903 $this->setSourceOfConfigValue($val, $key, $source);
 12904 }
 12905 }
 12906 }
 12907 
 12908 if (!empty($config['repositories']) && is_array($config['repositories'])) {
 12909 $this->repositories = array_reverse($this->repositories, true);
 12910 $newRepos = array_reverse($config['repositories'], true);
 12911 foreach ($newRepos as $name => $repository) {
 12912 
 12913 if (false === $repository) {
 12914 $this->disableRepoByName((string) $name);
 12915 continue;
 12916 }
 12917 
 12918 
 12919 if (is_array($repository) && 1 === count($repository) && false === current($repository)) {
 12920 $this->disableRepoByName((string) key($repository));
 12921 continue;
 12922 }
 12923 
 12924 
 12925 if (isset($repository['type'], $repository['url']) && $repository['type'] === 'composer' && Preg::isMatch('{^https?://(?:[a-z0-9-.]+\.)?packagist.org(/|$)}', $repository['url'])) {
 12926 $this->disableRepoByName('packagist.org');
 12927 }
 12928 
 12929 
 12930 if (is_int($name)) {
 12931 $this->repositories[] = $repository;
 12932 $this->setSourceOfConfigValue($repository, 'repositories.' . array_search($repository, $this->repositories, true), $source);
 12933 } else {
 12934 if ($name === 'packagist') { 
 12935 $this->repositories[$name . '.org'] = $repository;
 12936 $this->setSourceOfConfigValue($repository, 'repositories.' . $name . '.org', $source);
 12937 } else {
 12938 $this->repositories[$name] = $repository;
 12939 $this->setSourceOfConfigValue($repository, 'repositories.' . $name, $source);
 12940 }
 12941 }
 12942 }
 12943 $this->repositories = array_reverse($this->repositories, true);
 12944 }
 12945 }
 12946 
 12947 
 12948 
 12949 
 12950 public function getRepositories()
 12951 {
 12952 return $this->repositories;
 12953 }
 12954 
 12955 
 12956 
 12957 
 12958 
 12959 
 12960 
 12961 
 12962 
 12963 
 12964 public function get($key, $flags = 0)
 12965 {
 12966 switch ($key) {
 12967 
 12968 case 'vendor-dir':
 12969 case 'bin-dir':
 12970 case 'process-timeout':
 12971 case 'data-dir':
 12972 case 'cache-dir':
 12973 case 'cache-files-dir':
 12974 case 'cache-repo-dir':
 12975 case 'cache-vcs-dir':
 12976 case 'cafile':
 12977 case 'capath':
 12978 
 12979 $env = 'COMPOSER_' . strtoupper(strtr($key, '-', '_'));
 12980 
 12981 $val = $this->getComposerEnv($env);
 12982 if ($val !== false) {
 12983 $this->setSourceOfConfigValue($val, $key, $env);
 12984 }
 12985 
 12986 $val = rtrim((string) $this->process(false !== $val ? $val : $this->config[$key], $flags), '/\\');
 12987 $val = Platform::expandPath($val);
 12988 
 12989 if (substr($key, -4) !== '-dir') {
 12990 return $val;
 12991 }
 12992 
 12993 return (($flags & self::RELATIVE_PATHS) == self::RELATIVE_PATHS) ? $val : $this->realpath($val);
 12994 
 12995 
 12996 case 'cache-read-only':
 12997 case 'htaccess-protect':
 12998 
 12999 $env = 'COMPOSER_' . strtoupper(strtr($key, '-', '_'));
 13000 
 13001 $val = $this->getComposerEnv($env);
 13002 if (false === $val) {
 13003 $val = $this->config[$key];
 13004 } else {
 13005 $this->setSourceOfConfigValue($val, $key, $env);
 13006 }
 13007 
 13008 return $val !== 'false' && (bool) $val;
 13009 
 13010 
 13011 case 'disable-tls':
 13012 case 'secure-http':
 13013 case 'use-github-api':
 13014 case 'lock':
 13015 
 13016 if ($key === 'secure-http' && $this->get('disable-tls') === true) {
 13017 return false;
 13018 }
 13019 
 13020 return $this->config[$key] !== 'false' && (bool) $this->config[$key];
 13021 
 13022 
 13023 case 'cache-ttl':
 13024 return (int) $this->config[$key];
 13025 
 13026 
 13027 case 'cache-files-maxsize':
 13028 if (!Preg::isMatch('/^\s*([0-9.]+)\s*(?:([kmg])(?:i?b)?)?\s*$/i', $this->config[$key], $matches)) {
 13029 throw new \RuntimeException(
 13030 "Could not parse the value of '$key': {$this->config[$key]}"
 13031 );
 13032 }
 13033 $size = $matches[1];
 13034 if (isset($matches[2])) {
 13035 switch (strtolower($matches[2])) {
 13036 case 'g':
 13037 $size *= 1024;
 13038 
 13039 
 13040 case 'm':
 13041 $size *= 1024;
 13042 
 13043 
 13044 case 'k':
 13045 $size *= 1024;
 13046 break;
 13047 }
 13048 }
 13049 
 13050 return $size;
 13051 
 13052 
 13053 case 'cache-files-ttl':
 13054 if (isset($this->config[$key])) {
 13055 return (int) $this->config[$key];
 13056 }
 13057 
 13058 return (int) $this->config['cache-ttl'];
 13059 
 13060 case 'home':
 13061 $val = Preg::replace('#^(\$HOME|~)(/|$)#', rtrim(Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE'), '/\\') . '/', $this->config[$key]);
 13062 
 13063 return rtrim($this->process($val, $flags), '/\\');
 13064 
 13065 case 'bin-compat':
 13066 $value = $this->getComposerEnv('COMPOSER_BIN_COMPAT') ?: $this->config[$key];
 13067 
 13068 if (!in_array($value, array('auto', 'full', 'proxy', 'symlink'))) {
 13069 throw new \RuntimeException(
 13070 "Invalid value for 'bin-compat': {$value}. Expected auto, full or proxy"
 13071 );
 13072 }
 13073 
 13074 if ($value === 'symlink') {
 13075 trigger_error('config.bin-compat "symlink" is deprecated since Composer 2.2, use auto, full (for Windows compatibility) or proxy instead.', E_USER_DEPRECATED);
 13076 }
 13077 
 13078 return $value;
 13079 
 13080 case 'discard-changes':
 13081 if ($env = $this->getComposerEnv('COMPOSER_DISCARD_CHANGES')) {
 13082 if (!in_array($env, array('stash', 'true', 'false', '1', '0'), true)) {
 13083 throw new \RuntimeException(
 13084 "Invalid value for COMPOSER_DISCARD_CHANGES: {$env}. Expected 1, 0, true, false or stash"
 13085 );
 13086 }
 13087 if ('stash' === $env) {
 13088 return 'stash';
 13089 }
 13090 
 13091 
 13092 return $env !== 'false' && (bool) $env;
 13093 }
 13094 
 13095 if (!in_array($this->config[$key], array(true, false, 'stash'), true)) {
 13096 throw new \RuntimeException(
 13097 "Invalid value for 'discard-changes': {$this->config[$key]}. Expected true, false or stash"
 13098 );
 13099 }
 13100 
 13101 return $this->config[$key];
 13102 
 13103 case 'github-protocols':
 13104 $protos = $this->config['github-protocols'];
 13105 if ($this->config['secure-http'] && false !== ($index = array_search('git', $protos))) {
 13106 unset($protos[$index]);
 13107 }
 13108 if (reset($protos) === 'http') {
 13109 throw new \RuntimeException('The http protocol for github is not available anymore, update your config\'s github-protocols to use "https", "git" or "ssh"');
 13110 }
 13111 
 13112 return $protos;
 13113 
 13114 default:
 13115 if (!isset($this->config[$key])) {
 13116 return null;
 13117 }
 13118 
 13119 return $this->process($this->config[$key], $flags);
 13120 }
 13121 }
 13122 
 13123 
 13124 
 13125 
 13126 
 13127 
 13128 public function all($flags = 0)
 13129 {
 13130 $all = array(
 13131 'repositories' => $this->getRepositories(),
 13132 );
 13133 foreach (array_keys($this->config) as $key) {
 13134 $all['config'][$key] = $this->get($key, $flags);
 13135 }
 13136 
 13137 return $all;
 13138 }
 13139 
 13140 
 13141 
 13142 
 13143 
 13144 public function getSourceOfValue($key)
 13145 {
 13146 $this->get($key);
 13147 
 13148 return isset($this->sourceOfConfigValue[$key]) ? $this->sourceOfConfigValue[$key] : self::SOURCE_UNKNOWN;
 13149 }
 13150 
 13151 
 13152 
 13153 
 13154 
 13155 
 13156 
 13157 
 13158 private function setSourceOfConfigValue($configValue, $path, $source)
 13159 {
 13160 $this->sourceOfConfigValue[$path] = $source;
 13161 
 13162 if (is_array($configValue)) {
 13163 foreach ($configValue as $key => $value) {
 13164 $this->setSourceOfConfigValue($value, $path . '.' . $key, $source);
 13165 }
 13166 }
 13167 }
 13168 
 13169 
 13170 
 13171 
 13172 public function raw()
 13173 {
 13174 return array(
 13175 'repositories' => $this->getRepositories(),
 13176 'config' => $this->config,
 13177 );
 13178 }
 13179 
 13180 
 13181 
 13182 
 13183 
 13184 
 13185 
 13186 public function has($key)
 13187 {
 13188 return array_key_exists($key, $this->config);
 13189 }
 13190 
 13191 
 13192 
 13193 
 13194 
 13195 
 13196 
 13197 
 13198 
 13199 private function process($value, $flags)
 13200 {
 13201 $config = $this;
 13202 
 13203 if (!is_string($value)) {
 13204 return $value;
 13205 }
 13206 
 13207 return Preg::replaceCallback('#\{\$(.+)\}#', function ($match) use ($config, $flags) {
 13208 return $config->get($match[1], $flags);
 13209 }, $value);
 13210 }
 13211 
 13212 
 13213 
 13214 
 13215 
 13216 
 13217 
 13218 
 13219 
 13220 private function realpath($path)
 13221 {
 13222 if (Preg::isMatch('{^(?:/|[a-z]:|[a-z0-9.]+://)}i', $path)) {
 13223 return $path;
 13224 }
 13225 
 13226 return $this->baseDir ? $this->baseDir . '/' . $path : $path;
 13227 }
 13228 
 13229 
 13230 
 13231 
 13232 
 13233 
 13234 
 13235 
 13236 
 13237 
 13238 private function getComposerEnv($var)
 13239 {
 13240 if ($this->useEnvironment) {
 13241 return Platform::getEnv($var);
 13242 }
 13243 
 13244 return false;
 13245 }
 13246 
 13247 
 13248 
 13249 
 13250 
 13251 
 13252 private function disableRepoByName($name)
 13253 {
 13254 if (isset($this->repositories[$name])) {
 13255 unset($this->repositories[$name]);
 13256 } elseif ($name === 'packagist') { 
 13257 unset($this->repositories['packagist.org']);
 13258 }
 13259 }
 13260 
 13261 
 13262 
 13263 
 13264 
 13265 
 13266 
 13267 
 13268 
 13269 public function prohibitUrlByConfig($url, IOInterface $io = null)
 13270 {
 13271 
 13272 if (false === filter_var($url, FILTER_VALIDATE_URL)) {
 13273 return;
 13274 }
 13275 
 13276 
 13277 $scheme = parse_url($url, PHP_URL_SCHEME);
 13278 $hostname = parse_url($url, PHP_URL_HOST);
 13279 if (in_array($scheme, array('http', 'git', 'ftp', 'svn'))) {
 13280 if ($this->get('secure-http')) {
 13281 if ($scheme === 'svn') {
 13282 if (in_array($hostname, $this->get('secure-svn-domains'), true)) {
 13283 return;
 13284 }
 13285 
 13286 throw new TransportException("Your configuration does not allow connections to $url. See https://getcomposer.org/doc/06-config.md#secure-svn-domains for details.");
 13287 }
 13288 
 13289 throw new TransportException("Your configuration does not allow connections to $url. See https://getcomposer.org/doc/06-config.md#secure-http for details.");
 13290 }
 13291 if ($io) {
 13292 $host = parse_url($url, PHP_URL_HOST);
 13293 if (is_string($host)) {
 13294 if (!isset($this->warnedHosts[$host])) {
 13295 $io->writeError("<warning>Warning: Accessing $host over $scheme which is an insecure protocol.</warning>");
 13296 }
 13297 $this->warnedHosts[$host] = true;
 13298 }
 13299 }
 13300 }
 13301 }
 13302 
 13303 
 13304 
 13305 
 13306 
 13307 
 13308 
 13309 
 13310 
 13311 
 13312 
 13313 
 13314 
 13315 public static function disableProcessTimeout()
 13316 {
 13317 
 13318 ProcessExecutor::setTimeout(0);
 13319 }
 13320 }
 13321 <?php
 13322 
 13323 
 13324 
 13325 
 13326 
 13327 
 13328 
 13329 
 13330 
 13331 
 13332 
 13333 namespace Composer\Config;
 13334 
 13335 
 13336 
 13337 
 13338 
 13339 
 13340 
 13341 interface ConfigSourceInterface
 13342 {
 13343 
 13344 
 13345 
 13346 
 13347 
 13348 
 13349 
 13350 
 13351 
 13352 public function addRepository($name, $config, $append = true);
 13353 
 13354 
 13355 
 13356 
 13357 
 13358 
 13359 
 13360 
 13361 public function removeRepository($name);
 13362 
 13363 
 13364 
 13365 
 13366 
 13367 
 13368 
 13369 
 13370 
 13371 public function addConfigSetting($name, $value);
 13372 
 13373 
 13374 
 13375 
 13376 
 13377 
 13378 
 13379 
 13380 public function removeConfigSetting($name);
 13381 
 13382 
 13383 
 13384 
 13385 
 13386 
 13387 
 13388 
 13389 
 13390 public function addProperty($name, $value);
 13391 
 13392 
 13393 
 13394 
 13395 
 13396 
 13397 
 13398 
 13399 public function removeProperty($name);
 13400 
 13401 
 13402 
 13403 
 13404 
 13405 
 13406 
 13407 
 13408 
 13409 
 13410 public function addLink($type, $name, $value);
 13411 
 13412 
 13413 
 13414 
 13415 
 13416 
 13417 
 13418 
 13419 
 13420 public function removeLink($type, $name);
 13421 
 13422 
 13423 
 13424 
 13425 
 13426 
 13427 public function getName();
 13428 }
 13429 <?php
 13430 
 13431 
 13432 
 13433 
 13434 
 13435 
 13436 
 13437 
 13438 
 13439 
 13440 
 13441 namespace Composer\Config;
 13442 
 13443 use Composer\Json\JsonFile;
 13444 use Composer\Json\JsonManipulator;
 13445 use Composer\Json\JsonValidationException;
 13446 use Composer\Pcre\Preg;
 13447 use Composer\Util\Filesystem;
 13448 use Composer\Util\Silencer;
 13449 
 13450 
 13451 
 13452 
 13453 
 13454 
 13455 
 13456 class JsonConfigSource implements ConfigSourceInterface
 13457 {
 13458 
 13459 
 13460 
 13461 private $file;
 13462 
 13463 
 13464 
 13465 
 13466 private $authConfig;
 13467 
 13468 
 13469 
 13470 
 13471 
 13472 
 13473 
 13474 public function __construct(JsonFile $file, $authConfig = false)
 13475 {
 13476 $this->file = $file;
 13477 $this->authConfig = $authConfig;
 13478 }
 13479 
 13480 
 13481 
 13482 
 13483 public function getName()
 13484 {
 13485 return $this->file->getPath();
 13486 }
 13487 
 13488 
 13489 
 13490 
 13491 public function addRepository($name, $config, $append = true)
 13492 {
 13493 $this->manipulateJson('addRepository', $name, $config, $append, function (&$config, $repo, $repoConfig) use ($append) {
 13494 
 13495 
 13496 if (isset($config['repositories'])) {
 13497 foreach ($config['repositories'] as $index => $val) {
 13498 if ($index === $repo) {
 13499 continue;
 13500 }
 13501 if (is_numeric($index) && ($val === array('packagist' => false) || $val === array('packagist.org' => false))) {
 13502 unset($config['repositories'][$index]);
 13503 $config['repositories']['packagist.org'] = false;
 13504 break;
 13505 }
 13506 }
 13507 }
 13508 
 13509 if ($append) {
 13510 $config['repositories'][$repo] = $repoConfig;
 13511 } else {
 13512 $config['repositories'] = array($repo => $repoConfig) + $config['repositories'];
 13513 }
 13514 });
 13515 }
 13516 
 13517 
 13518 
 13519 
 13520 public function removeRepository($name)
 13521 {
 13522 $this->manipulateJson('removeRepository', $name, function (&$config, $repo) {
 13523 unset($config['repositories'][$repo]);
 13524 });
 13525 }
 13526 
 13527 
 13528 
 13529 
 13530 public function addConfigSetting($name, $value)
 13531 {
 13532 $authConfig = $this->authConfig;
 13533 $this->manipulateJson('addConfigSetting', $name, $value, function (&$config, $key, $val) use ($authConfig) {
 13534 if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
 13535 list($key, $host) = explode('.', $key, 2);
 13536 if ($authConfig) {
 13537 $config[$key][$host] = $val;
 13538 } else {
 13539 $config['config'][$key][$host] = $val;
 13540 }
 13541 } else {
 13542 $config['config'][$key] = $val;
 13543 }
 13544 });
 13545 }
 13546 
 13547 
 13548 
 13549 
 13550 public function removeConfigSetting($name)
 13551 {
 13552 $authConfig = $this->authConfig;
 13553 $this->manipulateJson('removeConfigSetting', $name, function (&$config, $key) use ($authConfig) {
 13554 if (Preg::isMatch('{^(bitbucket-oauth|github-oauth|gitlab-oauth|gitlab-token|bearer|http-basic|platform)\.}', $key)) {
 13555 list($key, $host) = explode('.', $key, 2);
 13556 if ($authConfig) {
 13557 unset($config[$key][$host]);
 13558 } else {
 13559 unset($config['config'][$key][$host]);
 13560 }
 13561 } else {
 13562 unset($config['config'][$key]);
 13563 }
 13564 });
 13565 }
 13566 
 13567 
 13568 
 13569 
 13570 public function addProperty($name, $value)
 13571 {
 13572 $this->manipulateJson('addProperty', $name, $value, function (&$config, $key, $val) {
 13573 if (strpos($key, 'extra.') === 0 || strpos($key, 'scripts.') === 0) {
 13574 $bits = explode('.', $key);
 13575 $last = array_pop($bits);
 13576 $arr = &$config[reset($bits)];
 13577 foreach ($bits as $bit) {
 13578 if (!isset($arr[$bit])) {
 13579 $arr[$bit] = array();
 13580 }
 13581 $arr = &$arr[$bit];
 13582 }
 13583 $arr[$last] = $val;
 13584 } else {
 13585 $config[$key] = $val;
 13586 }
 13587 });
 13588 }
 13589 
 13590 
 13591 
 13592 
 13593 public function removeProperty($name)
 13594 {
 13595 $this->manipulateJson('removeProperty', $name, function (&$config, $key) {
 13596 if (strpos($key, 'extra.') === 0 || strpos($key, 'scripts.') === 0) {
 13597 $bits = explode('.', $key);
 13598 $last = array_pop($bits);
 13599 $arr = &$config[reset($bits)];
 13600 foreach ($bits as $bit) {
 13601 if (!isset($arr[$bit])) {
 13602 return;
 13603 }
 13604 $arr = &$arr[$bit];
 13605 }
 13606 unset($arr[$last]);
 13607 } else {
 13608 unset($config[$key]);
 13609 }
 13610 });
 13611 }
 13612 
 13613 
 13614 
 13615 
 13616 public function addLink($type, $name, $value)
 13617 {
 13618 $this->manipulateJson('addLink', $type, $name, $value, function (&$config, $type, $name, $value) {
 13619 $config[$type][$name] = $value;
 13620 });
 13621 }
 13622 
 13623 
 13624 
 13625 
 13626 public function removeLink($type, $name)
 13627 {
 13628 $this->manipulateJson('removeSubNode', $type, $name, function (&$config, $type, $name) {
 13629 unset($config[$type][$name]);
 13630 });
 13631 $this->manipulateJson('removeMainKeyIfEmpty', $type, function (&$config, $type) {
 13632 if (0 === count($config[$type])) {
 13633 unset($config[$type]);
 13634 }
 13635 });
 13636 }
 13637 
 13638 
 13639 
 13640 
 13641 
 13642 
 13643 
 13644 
 13645 protected function manipulateJson($method, $args, $fallback)
 13646 {
 13647 $args = func_get_args();
 13648 
 13649 array_shift($args);
 13650 $fallback = array_pop($args);
 13651 
 13652 if ($this->file->exists()) {
 13653 if (!is_writable($this->file->getPath())) {
 13654 throw new \RuntimeException(sprintf('The file "%s" is not writable.', $this->file->getPath()));
 13655 }
 13656 
 13657 if (!Filesystem::isReadable($this->file->getPath())) {
 13658 throw new \RuntimeException(sprintf('The file "%s" is not readable.', $this->file->getPath()));
 13659 }
 13660 
 13661 $contents = file_get_contents($this->file->getPath());
 13662 } elseif ($this->authConfig) {
 13663 $contents = "{\n}\n";
 13664 } else {
 13665 $contents = "{\n    \"config\": {\n    }\n}\n";
 13666 }
 13667 
 13668 $manipulator = new JsonManipulator($contents);
 13669 
 13670 $newFile = !$this->file->exists();
 13671 
 13672 
 13673 if ($this->authConfig && $method === 'addConfigSetting') {
 13674 $method = 'addSubNode';
 13675 list($mainNode, $name) = explode('.', $args[0], 2);
 13676 $args = array($mainNode, $name, $args[1]);
 13677 } elseif ($this->authConfig && $method === 'removeConfigSetting') {
 13678 $method = 'removeSubNode';
 13679 list($mainNode, $name) = explode('.', $args[0], 2);
 13680 $args = array($mainNode, $name);
 13681 }
 13682 
 13683 
 13684 if (call_user_func_array(array($manipulator, $method), $args)) {
 13685 file_put_contents($this->file->getPath(), $manipulator->getContents());
 13686 } else {
 13687 
 13688 $config = $this->file->read();
 13689 $this->arrayUnshiftRef($args, $config);
 13690 call_user_func_array($fallback, $args);
 13691 
 13692 foreach (array('require', 'require-dev', 'conflict', 'provide', 'replace', 'suggest', 'config', 'autoload', 'autoload-dev', 'scripts', 'scripts-descriptions', 'support') as $prop) {
 13693 if (isset($config[$prop]) && $config[$prop] === array()) {
 13694 $config[$prop] = new \stdClass;
 13695 }
 13696 }
 13697 foreach (array('psr-0', 'psr-4') as $prop) {
 13698 if (isset($config['autoload'][$prop]) && $config['autoload'][$prop] === array()) {
 13699 $config['autoload'][$prop] = new \stdClass;
 13700 }
 13701 if (isset($config['autoload-dev'][$prop]) && $config['autoload-dev'][$prop] === array()) {
 13702 $config['autoload-dev'][$prop] = new \stdClass;
 13703 }
 13704 }
 13705 foreach (array('platform', 'http-basic', 'bearer', 'gitlab-token', 'gitlab-oauth', 'github-oauth', 'preferred-install') as $prop) {
 13706 if (isset($config['config'][$prop]) && $config['config'][$prop] === array()) {
 13707 $config['config'][$prop] = new \stdClass;
 13708 }
 13709 }
 13710 $this->file->write($config);
 13711 }
 13712 
 13713 try {
 13714 $this->file->validateSchema(JsonFile::LAX_SCHEMA);
 13715 } catch (JsonValidationException $e) {
 13716 
 13717 file_put_contents($this->file->getPath(), $contents);
 13718 throw new \RuntimeException('Failed to update composer.json with a valid format, reverting to the original content. Please report an issue to us with details (command you run and a copy of your composer.json). '.PHP_EOL.implode(PHP_EOL, $e->getErrors()), 0, $e);
 13719 }
 13720 
 13721 if ($newFile) {
 13722 Silencer::call('chmod', $this->file->getPath(), 0600);
 13723 }
 13724 }
 13725 
 13726 
 13727 
 13728 
 13729 
 13730 
 13731 
 13732 
 13733 private function arrayUnshiftRef(&$array, &$value)
 13734 {
 13735 $return = array_unshift($array, '');
 13736 $array[0] = &$value;
 13737 
 13738 return $return;
 13739 }
 13740 }
 13741 <?php
 13742 
 13743 
 13744 
 13745 
 13746 
 13747 
 13748 
 13749 
 13750 
 13751 
 13752 
 13753 namespace Composer\Console;
 13754 
 13755 use Composer\IO\NullIO;
 13756 use Composer\Util\Filesystem;
 13757 use Composer\Util\Platform;
 13758 use Composer\Util\Silencer;
 13759 use Symfony\Component\Console\Application as BaseApplication;
 13760 use Symfony\Component\Console\Exception\CommandNotFoundException;
 13761 use Symfony\Component\Console\Helper\HelperSet;
 13762 use Symfony\Component\Console\Helper\QuestionHelper;
 13763 use Symfony\Component\Console\Input\InputDefinition;
 13764 use Symfony\Component\Console\Input\InputInterface;
 13765 use Symfony\Component\Console\Input\InputOption;
 13766 use Symfony\Component\Console\Output\OutputInterface;
 13767 use Seld\JsonLint\ParsingException;
 13768 use Composer\Command;
 13769 use Composer\Composer;
 13770 use Composer\Factory;
 13771 use Composer\IO\IOInterface;
 13772 use Composer\IO\ConsoleIO;
 13773 use Composer\Json\JsonValidationException;
 13774 use Composer\Util\ErrorHandler;
 13775 use Composer\Util\HttpDownloader;
 13776 use Composer\EventDispatcher\ScriptExecutionException;
 13777 use Composer\Exception\NoSslException;
 13778 use Composer\XdebugHandler\XdebugHandler;
 13779 use Symfony\Component\Process\Exception\ProcessTimedOutException;
 13780 
 13781 
 13782 
 13783 
 13784 
 13785 
 13786 
 13787 
 13788 class Application extends BaseApplication
 13789 {
 13790 
 13791 
 13792 
 13793 protected $composer;
 13794 
 13795 
 13796 
 13797 
 13798 protected $io;
 13799 
 13800 
 13801 private static $logo = '   ______
 13802   / ____/___  ____ ___  ____  ____  ________  _____
 13803  / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
 13804 / /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
 13805 \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
 13806                     /_/
 13807 ';
 13808 
 13809 
 13810 private $hasPluginCommands = false;
 13811 
 13812 private $disablePluginsByDefault = false;
 13813 
 13814 private $disableScriptsByDefault = false;
 13815 
 13816 
 13817 
 13818 
 13819 private $initialWorkingDirectory;
 13820 
 13821 public function __construct()
 13822 {
 13823 static $shutdownRegistered = false;
 13824 
 13825 if (function_exists('ini_set') && extension_loaded('xdebug')) {
 13826 ini_set('xdebug.show_exception_trace', '0');
 13827 ini_set('xdebug.scream', '0');
 13828 }
 13829 
 13830 if (function_exists('date_default_timezone_set') && function_exists('date_default_timezone_get')) {
 13831 date_default_timezone_set(Silencer::call('date_default_timezone_get'));
 13832 }
 13833 
 13834 if (!$shutdownRegistered) {
 13835 if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
 13836 pcntl_async_signals(true);
 13837 pcntl_signal(SIGINT, function ($sig) {
 13838 exit(130);
 13839 });
 13840 }
 13841 
 13842 $shutdownRegistered = true;
 13843 
 13844 register_shutdown_function(function () {
 13845 $lastError = error_get_last();
 13846 
 13847 if ($lastError && $lastError['message'] &&
 13848 (strpos($lastError['message'], 'Allowed memory') !== false  ||
 13849 strpos($lastError['message'], 'exceeded memory') !== false )) {
 13850 echo "\n". 'Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.';
 13851 }
 13852 });
 13853 }
 13854 
 13855 $this->io = new NullIO();
 13856 
 13857 $this->initialWorkingDirectory = getcwd();
 13858 
 13859 parent::__construct('Composer', Composer::getVersion());
 13860 }
 13861 
 13862 
 13863 
 13864 
 13865 public function run(InputInterface $input = null, OutputInterface $output = null)
 13866 {
 13867 if (null === $output) {
 13868 $output = Factory::createOutput();
 13869 }
 13870 
 13871 return parent::run($input, $output);
 13872 }
 13873 
 13874 
 13875 
 13876 
 13877 public function doRun(InputInterface $input, OutputInterface $output)
 13878 {
 13879 $this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins');
 13880 $this->disableScriptsByDefault = $input->hasParameterOption('--no-scripts');
 13881 
 13882 if (Platform::getEnv('COMPOSER_NO_INTERACTION') || !Platform::isTty(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'))) {
 13883 $input->setInteractive(false);
 13884 }
 13885 
 13886 $io = $this->io = new ConsoleIO($input, $output, new HelperSet(array(
 13887 new QuestionHelper(),
 13888 )));
 13889 
 13890 
 13891 ErrorHandler::register($io);
 13892 
 13893 if ($input->hasParameterOption('--no-cache')) {
 13894 $io->writeError('Disabling cache usage', true, IOInterface::DEBUG);
 13895 Platform::putEnv('COMPOSER_CACHE_DIR', Platform::isWindows() ? 'nul' : '/dev/null');
 13896 }
 13897 
 13898 
 13899 if ($newWorkDir = $this->getNewWorkingDir($input)) {
 13900 $oldWorkingDir = getcwd();
 13901 chdir($newWorkDir);
 13902 $this->initialWorkingDirectory = $newWorkDir;
 13903 $io->writeError('Changed CWD to ' . getcwd(), true, IOInterface::DEBUG);
 13904 }
 13905 
 13906 
 13907 $commandName = '';
 13908 if ($name = $this->getCommandName($input)) {
 13909 try {
 13910 $commandName = $this->find($name)->getName();
 13911 } catch (CommandNotFoundException $e) {
 13912 
 13913 $commandName = false;
 13914 } catch (\InvalidArgumentException $e) {
 13915 }
 13916 }
 13917 
 13918 
 13919 if ($io->isInteractive() && !$newWorkDir && !in_array($commandName, array('', 'list', 'init', 'about', 'help', 'diagnose', 'self-update', 'global', 'create-project', 'outdated'), true) && !file_exists(Factory::getComposerFile()) && ($useParentDirIfNoJsonAvailable = $this->getUseParentDirConfigValue()) !== false) {
 13920 $dir = dirname(getcwd());
 13921 $home = realpath(Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE') ?: '/');
 13922 
 13923 
 13924 while (dirname($dir) !== $dir && $dir !== $home) {
 13925 if (file_exists($dir.'/'.Factory::getComposerFile())) {
 13926 if ($useParentDirIfNoJsonAvailable === true || $io->askConfirmation('<info>No composer.json in current directory, do you want to use the one at '.$dir.'?</info> [<comment>Y,n</comment>]? ')) {
 13927 if ($useParentDirIfNoJsonAvailable === true) {
 13928 $io->writeError('<info>No composer.json in current directory, changing working directory to '.$dir.'</info>');
 13929 } else {
 13930 $io->writeError('<info>Always want to use the parent dir? Use "composer config --global use-parent-dir true" to change the default.</info>');
 13931 }
 13932 $oldWorkingDir = getcwd();
 13933 chdir($dir);
 13934 }
 13935 break;
 13936 }
 13937 $dir = dirname($dir);
 13938 }
 13939 }
 13940 
 13941 
 13942 
 13943 $mayNeedPluginCommand = false === $input->hasParameterOption(array('--version', '-V'))
 13944 && (
 13945 
 13946 false === $commandName
 13947 
 13948 || in_array($commandName, array('', 'list', 'help'), true)
 13949 );
 13950 
 13951 if ($mayNeedPluginCommand && !$this->disablePluginsByDefault && !$this->hasPluginCommands) {
 13952 try {
 13953 foreach ($this->getPluginCommands() as $command) {
 13954 if ($this->has($command->getName())) {
 13955 $io->writeError('<warning>Plugin command '.$command->getName().' ('.get_class($command).') would override a Composer command and has been skipped</warning>');
 13956 } else {
 13957 $this->add($command);
 13958 }
 13959 }
 13960 } catch (NoSslException $e) {
 13961 
 13962 } catch (ParsingException $e) {
 13963 $details = $e->getDetails();
 13964 
 13965 $file = realpath(Factory::getComposerFile());
 13966 
 13967 $line = null;
 13968 if ($details && isset($details['line'])) {
 13969 $line = $details['line'];
 13970 }
 13971 
 13972 $ghe = new GithubActionError($this->io);
 13973 $ghe->emit($e->getMessage(), $file, $line);
 13974 
 13975 throw $e;
 13976 }
 13977 
 13978 $this->hasPluginCommands = true;
 13979 }
 13980 
 13981 
 13982 $isProxyCommand = false;
 13983 if ($name = $this->getCommandName($input)) {
 13984 try {
 13985 $command = $this->find($name);
 13986 $commandName = $command->getName();
 13987 $isProxyCommand = ($command instanceof Command\BaseCommand && $command->isProxyCommand());
 13988 } catch (\InvalidArgumentException $e) {
 13989 }
 13990 }
 13991 
 13992 if (!$isProxyCommand) {
 13993 $io->writeError(sprintf(
 13994 'Running %s (%s) with %s on %s',
 13995 Composer::getVersion(),
 13996 Composer::RELEASE_DATE,
 13997 defined('HHVM_VERSION') ? 'HHVM '.HHVM_VERSION : 'PHP '.PHP_VERSION,
 13998 function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknown OS'
 13999 ), true, IOInterface::DEBUG);
 14000 
 14001 if (PHP_VERSION_ID < 50302) {
 14002 $io->writeError('<warning>Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.</warning>');
 14003 }
 14004 
 14005 if (XdebugHandler::isXdebugActive() && !Platform::getEnv('COMPOSER_DISABLE_XDEBUG_WARN')) {
 14006 $io->writeError('<warning>Composer is operating slower than normal because you have Xdebug enabled. See https://getcomposer.org/xdebug</warning>');
 14007 }
 14008 
 14009 if (defined('COMPOSER_DEV_WARNING_TIME') && $commandName !== 'self-update' && $commandName !== 'selfupdate' && time() > COMPOSER_DEV_WARNING_TIME) {
 14010 $io->writeError(sprintf('<warning>Warning: This development build of Composer is over 60 days old. It is recommended to update it by running "%s self-update" to get the latest version.</warning>', $_SERVER['PHP_SELF']));
 14011 }
 14012 
 14013 if (
 14014 !Platform::isWindows()
 14015 && function_exists('exec')
 14016 && !Platform::getEnv('COMPOSER_ALLOW_SUPERUSER')
 14017 && (ini_get('open_basedir') || !file_exists('/.dockerenv'))
 14018 ) {
 14019 if (function_exists('posix_getuid') && posix_getuid() === 0) {
 14020 if ($commandName !== 'self-update' && $commandName !== 'selfupdate') {
 14021 $io->writeError('<warning>Do not run Composer as root/super user! See https://getcomposer.org/root for details</warning>');
 14022 
 14023 if ($io->isInteractive()) {
 14024 if (!$io->askConfirmation('<info>Continue as root/super user</info> [<comment>yes</comment>]? ')) {
 14025 return 1;
 14026 }
 14027 }
 14028 }
 14029 if ($uid = (int) Platform::getEnv('SUDO_UID')) {
 14030 
 14031 
 14032 Silencer::call('exec', "sudo -u \\#{$uid} sudo -K > /dev/null 2>&1");
 14033 }
 14034 }
 14035 
 14036 Silencer::call('exec', 'sudo -K > /dev/null 2>&1');
 14037 }
 14038 
 14039 
 14040 Silencer::call(function () use ($io) {
 14041 $tempfile = sys_get_temp_dir() . '/temp-' . md5(microtime());
 14042 if (!(file_put_contents($tempfile, __FILE__) && (file_get_contents($tempfile) == __FILE__) && unlink($tempfile) && !file_exists($tempfile))) {
 14043 $io->writeError(sprintf('<error>PHP temp directory (%s) does not exist or is not writable to Composer. Set sys_temp_dir in your php.ini</error>', sys_get_temp_dir()));
 14044 }
 14045 });
 14046 
 14047 
 14048 $file = Factory::getComposerFile();
 14049 if (is_file($file) && Filesystem::isReadable($file) && is_array($composer = json_decode(file_get_contents($file), true))) {
 14050 if (isset($composer['scripts']) && is_array($composer['scripts'])) {
 14051 foreach ($composer['scripts'] as $script => $dummy) {
 14052 if (!defined('Composer\Script\ScriptEvents::'.str_replace('-', '_', strtoupper($script)))) {
 14053 if ($this->has($script)) {
 14054 $io->writeError('<warning>A script named '.$script.' would override a Composer command and has been skipped</warning>');
 14055 } else {
 14056 $description = null;
 14057 
 14058 if (isset($composer['scripts-descriptions'][$script])) {
 14059 $description = $composer['scripts-descriptions'][$script];
 14060 }
 14061 
 14062 $this->add(new Command\ScriptAliasCommand($script, $description));
 14063 }
 14064 }
 14065 }
 14066 }
 14067 }
 14068 }
 14069 
 14070 try {
 14071 if ($input->hasParameterOption('--profile')) {
 14072 $startTime = microtime(true);
 14073 $this->io->enableDebugging($startTime);
 14074 }
 14075 
 14076 $result = parent::doRun($input, $output);
 14077 
 14078 
 14079 if (isset($oldWorkingDir)) {
 14080 Silencer::call('chdir', $oldWorkingDir);
 14081 }
 14082 
 14083 if (isset($startTime)) {
 14084 $io->writeError('<info>Memory usage: '.round(memory_get_usage() / 1024 / 1024, 2).'MiB (peak: '.round(memory_get_peak_usage() / 1024 / 1024, 2).'MiB), time: '.round(microtime(true) - $startTime, 2).'s');
 14085 }
 14086 
 14087 restore_error_handler();
 14088 
 14089 return $result;
 14090 } catch (ScriptExecutionException $e) {
 14091 return $e->getCode();
 14092 } catch (\Exception $e) {
 14093 $ghe = new GithubActionError($this->io);
 14094 $ghe->emit($e->getMessage());
 14095 
 14096 $this->hintCommonErrors($e);
 14097 
 14098 restore_error_handler();
 14099 
 14100 throw $e;
 14101 }
 14102 }
 14103 
 14104 
 14105 
 14106 
 14107 
 14108 
 14109 private function getNewWorkingDir(InputInterface $input)
 14110 {
 14111 $workingDir = $input->getParameterOption(array('--working-dir', '-d'));
 14112 if (false !== $workingDir && !is_dir($workingDir)) {
 14113 throw new \RuntimeException('Invalid working directory specified, '.$workingDir.' does not exist.');
 14114 }
 14115 
 14116 return $workingDir;
 14117 }
 14118 
 14119 
 14120 
 14121 
 14122 private function hintCommonErrors(\Exception $exception)
 14123 {
 14124 $io = $this->getIO();
 14125 
 14126 Silencer::suppress();
 14127 try {
 14128 $composer = $this->getComposer(false, true);
 14129 if ($composer) {
 14130 $config = $composer->getConfig();
 14131 
 14132 $minSpaceFree = 1024 * 1024;
 14133 if ((($df = disk_free_space($dir = $config->get('home'))) !== false && $df < $minSpaceFree)
 14134 || (($df = disk_free_space($dir = $config->get('vendor-dir'))) !== false && $df < $minSpaceFree)
 14135 || (($df = disk_free_space($dir = sys_get_temp_dir())) !== false && $df < $minSpaceFree)
 14136 ) {
 14137 $io->writeError('<error>The disk hosting '.$dir.' is full, this may be the cause of the following exception</error>', true, IOInterface::QUIET);
 14138 }
 14139 }
 14140 } catch (\Exception $e) {
 14141 }
 14142 Silencer::restore();
 14143 
 14144 if (Platform::isWindows() && false !== strpos($exception->getMessage(), 'The system cannot find the path specified')) {
 14145 $io->writeError('<error>The following exception may be caused by a stale entry in your cmd.exe AutoRun</error>', true, IOInterface::QUIET);
 14146 $io->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#-the-system-cannot-find-the-path-specified-windows- for details</error>', true, IOInterface::QUIET);
 14147 }
 14148 
 14149 if (false !== strpos($exception->getMessage(), 'fork failed - Cannot allocate memory')) {
 14150 $io->writeError('<error>The following exception is caused by a lack of memory or swap, or not having swap configured</error>', true, IOInterface::QUIET);
 14151 $io->writeError('<error>Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details</error>', true, IOInterface::QUIET);
 14152 }
 14153 
 14154 if ($exception instanceof ProcessTimedOutException) {
 14155 $io->writeError('<error>The following exception is caused by a process timeout</error>', true, IOInterface::QUIET);
 14156 $io->writeError('<error>Check https://getcomposer.org/doc/06-config.md#process-timeout for details</error>', true, IOInterface::QUIET);
 14157 }
 14158 
 14159 if ($hints = HttpDownloader::getExceptionHints($exception)) {
 14160 foreach ($hints as $hint) {
 14161 $io->writeError($hint, true, IOInterface::QUIET);
 14162 }
 14163 }
 14164 }
 14165 
 14166 
 14167 
 14168 
 14169 
 14170 
 14171 
 14172 
 14173 
 14174 public function getComposer($required = true, $disablePlugins = null, $disableScripts = null)
 14175 {
 14176 if (null === $disablePlugins) {
 14177 $disablePlugins = $this->disablePluginsByDefault;
 14178 }
 14179 if (null === $disableScripts) {
 14180 $disableScripts = $this->disableScriptsByDefault;
 14181 }
 14182 
 14183 if (null === $this->composer) {
 14184 try {
 14185 $this->composer = Factory::create($this->io, null, $disablePlugins, $disableScripts);
 14186 } catch (\InvalidArgumentException $e) {
 14187 if ($required) {
 14188 $this->io->writeError($e->getMessage());
 14189 
 14190 if (!method_exists($this, 'areExceptionsCaught') || $this->areExceptionsCaught()) {
 14191 exit(1);
 14192 }
 14193 throw $e;
 14194 }
 14195 } catch (JsonValidationException $e) {
 14196 if ($required) {
 14197 throw $e;
 14198 }
 14199 }
 14200 }
 14201 
 14202 return $this->composer;
 14203 }
 14204 
 14205 
 14206 
 14207 
 14208 
 14209 
 14210 public function resetComposer()
 14211 {
 14212 $this->composer = null;
 14213 if (method_exists($this->getIO(), 'resetAuthentications')) {
 14214 $this->getIO()->resetAuthentications();
 14215 }
 14216 }
 14217 
 14218 
 14219 
 14220 
 14221 public function getIO()
 14222 {
 14223 return $this->io;
 14224 }
 14225 
 14226 
 14227 
 14228 
 14229 public function getHelp()
 14230 {
 14231 return self::$logo . parent::getHelp();
 14232 }
 14233 
 14234 
 14235 
 14236 
 14237 
 14238 protected function getDefaultCommands()
 14239 {
 14240 $commands = array_merge(parent::getDefaultCommands(), array(
 14241 new Command\AboutCommand(),
 14242 new Command\ConfigCommand(),
 14243 new Command\DependsCommand(),
 14244 new Command\ProhibitsCommand(),
 14245 new Command\InitCommand(),
 14246 new Command\InstallCommand(),
 14247 new Command\CreateProjectCommand(),
 14248 new Command\UpdateCommand(),
 14249 new Command\SearchCommand(),
 14250 new Command\ValidateCommand(),
 14251 new Command\ShowCommand(),
 14252 new Command\SuggestsCommand(),
 14253 new Command\RequireCommand(),
 14254 new Command\DumpAutoloadCommand(),
 14255 new Command\StatusCommand(),
 14256 new Command\ArchiveCommand(),
 14257 new Command\DiagnoseCommand(),
 14258 new Command\RunScriptCommand(),
 14259 new Command\LicensesCommand(),
 14260 new Command\GlobalCommand(),
 14261 new Command\ClearCacheCommand(),
 14262 new Command\RemoveCommand(),
 14263 new Command\HomeCommand(),
 14264 new Command\ExecCommand(),
 14265 new Command\OutdatedCommand(),
 14266 new Command\CheckPlatformReqsCommand(),
 14267 new Command\FundCommand(),
 14268 new Command\ReinstallCommand(),
 14269 ));
 14270 
 14271 if (strpos(__FILE__, 'phar:') === 0) {
 14272 $commands[] = new Command\SelfUpdateCommand();
 14273 }
 14274 
 14275 return $commands;
 14276 }
 14277 
 14278 
 14279 
 14280 
 14281 public function getLongVersion()
 14282 {
 14283 if (Composer::BRANCH_ALIAS_VERSION && Composer::BRANCH_ALIAS_VERSION !== '@package_branch_alias_version'.'@') {
 14284 return sprintf(
 14285 '<info>%s</info> version <comment>%s (%s)</comment> %s',
 14286 $this->getName(),
 14287 Composer::BRANCH_ALIAS_VERSION,
 14288 $this->getVersion(),
 14289 Composer::RELEASE_DATE
 14290 );
 14291 }
 14292 
 14293 return parent::getLongVersion() . ' ' . Composer::RELEASE_DATE;
 14294 }
 14295 
 14296 
 14297 
 14298 
 14299 protected function getDefaultInputDefinition()
 14300 {
 14301 $definition = parent::getDefaultInputDefinition();
 14302 $definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information'));
 14303 $definition->addOption(new InputOption('--no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'));
 14304 $definition->addOption(new InputOption('--no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'));
 14305 $definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.'));
 14306 $definition->addOption(new InputOption('--no-cache', null, InputOption::VALUE_NONE, 'Prevent use of the cache'));
 14307 
 14308 return $definition;
 14309 }
 14310 
 14311 
 14312 
 14313 
 14314 private function getPluginCommands()
 14315 {
 14316 $commands = array();
 14317 
 14318 $composer = $this->getComposer(false, false);
 14319 if (null === $composer) {
 14320 $composer = Factory::createGlobal($this->io);
 14321 }
 14322 
 14323 if (null !== $composer) {
 14324 $pm = $composer->getPluginManager();
 14325 foreach ($pm->getPluginCapabilities('Composer\Plugin\Capability\CommandProvider', array('composer' => $composer, 'io' => $this->io)) as $capability) {
 14326 $newCommands = $capability->getCommands();
 14327 if (!is_array($newCommands)) {
 14328 throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' failed to return an array from getCommands');
 14329 }
 14330 foreach ($newCommands as $command) {
 14331 if (!$command instanceof Command\BaseCommand) {
 14332 throw new \UnexpectedValueException('Plugin capability '.get_class($capability).' returned an invalid value, we expected an array of Composer\Command\BaseCommand objects');
 14333 }
 14334 }
 14335 $commands = array_merge($commands, $newCommands);
 14336 }
 14337 }
 14338 
 14339 return $commands;
 14340 }
 14341 
 14342 
 14343 
 14344 
 14345 
 14346 
 14347 public function getInitialWorkingDirectory()
 14348 {
 14349 return $this->initialWorkingDirectory;
 14350 }
 14351 
 14352 
 14353 
 14354 
 14355 private function getUseParentDirConfigValue()
 14356 {
 14357 $config = Factory::createConfig($this->io);
 14358 
 14359 return $config->get('use-parent-dir');
 14360 }
 14361 }
 14362 <?php
 14363 
 14364 
 14365 
 14366 
 14367 
 14368 
 14369 
 14370 
 14371 
 14372 
 14373 
 14374 namespace Composer\Console;
 14375 
 14376 use Composer\IO\IOInterface;
 14377 use Composer\Util\Platform;
 14378 
 14379 final class GithubActionError
 14380 {
 14381 
 14382 
 14383 
 14384 protected $io;
 14385 
 14386 public function __construct(IOInterface $io)
 14387 {
 14388 $this->io = $io;
 14389 }
 14390 
 14391 
 14392 
 14393 
 14394 
 14395 
 14396 
 14397 
 14398 public function emit($message, $file = null, $line = null)
 14399 {
 14400 if (Platform::getEnv('GITHUB_ACTIONS') && !Platform::getEnv('COMPOSER_TESTS_ARE_RUNNING')) {
 14401 $message = $this->escapeData($message);
 14402 
 14403 if ($file && $line) {
 14404 $file = $this->escapeProperty($file);
 14405 $this->io->write("::error file=". $file .",line=". $line ."::". $message);
 14406 } elseif ($file) {
 14407 $file = $this->escapeProperty($file);
 14408 $this->io->write("::error file=". $file ."::". $message);
 14409 } else {
 14410 $this->io->write("::error ::". $message);
 14411 }
 14412 }
 14413 }
 14414 
 14415 
 14416 
 14417 
 14418 
 14419 private function escapeData($data) {
 14420 
 14421 $data = str_replace("%", '%25', $data);
 14422 $data = str_replace("\r", '%0D', $data);
 14423 $data = str_replace("\n", '%0A', $data);
 14424 
 14425 return $data;
 14426 }
 14427 
 14428 
 14429 
 14430 
 14431 
 14432 private function escapeProperty($property) {
 14433 
 14434 $property = str_replace("%", '%25', $property);
 14435 $property = str_replace("\r", '%0D', $property);
 14436 $property = str_replace("\n", '%0A', $property);
 14437 $property = str_replace(":", '%3A', $property);
 14438 $property = str_replace(",", '%2C', $property);
 14439 
 14440 return $property;
 14441 }
 14442 }
 14443 <?php
 14444 
 14445 
 14446 
 14447 
 14448 
 14449 
 14450 
 14451 
 14452 
 14453 
 14454 
 14455 namespace Composer\Console;
 14456 
 14457 use Composer\Pcre\Preg;
 14458 use Symfony\Component\Console\Formatter\OutputFormatter;
 14459 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
 14460 
 14461 
 14462 
 14463 
 14464 class HtmlOutputFormatter extends OutputFormatter
 14465 {
 14466 
 14467 private static $availableForegroundColors = array(
 14468 30 => 'black',
 14469 31 => 'red',
 14470 32 => 'green',
 14471 33 => 'yellow',
 14472 34 => 'blue',
 14473 35 => 'magenta',
 14474 36 => 'cyan',
 14475 37 => 'white',
 14476 );
 14477 
 14478 private static $availableBackgroundColors = array(
 14479 40 => 'black',
 14480 41 => 'red',
 14481 42 => 'green',
 14482 43 => 'yellow',
 14483 44 => 'blue',
 14484 45 => 'magenta',
 14485 46 => 'cyan',
 14486 47 => 'white',
 14487 );
 14488 
 14489 private static $availableOptions = array(
 14490 1 => 'bold',
 14491 4 => 'underscore',
 14492 
 14493 
 14494 
 14495 );
 14496 
 14497 
 14498 
 14499 
 14500 public function __construct(array $styles = array())
 14501 {
 14502 parent::__construct(true, $styles);
 14503 }
 14504 
 14505 
 14506 
 14507 
 14508 
 14509 
 14510 public function format($message)
 14511 {
 14512 $formatted = parent::format($message);
 14513 
 14514 $clearEscapeCodes = '(?:39|49|0|22|24|25|27|28)';
 14515 
 14516 
 14517 return preg_replace_callback("{\033\[([0-9;]+)m(.*?)\033\[(?:".$clearEscapeCodes.";)*?".$clearEscapeCodes."m}s", array($this, 'formatHtml'), $formatted);
 14518 }
 14519 
 14520 
 14521 
 14522 
 14523 
 14524 
 14525 private function formatHtml($matches)
 14526 {
 14527 $out = '<span style="';
 14528 foreach (explode(';', $matches[1]) as $code) {
 14529 if (isset(self::$availableForegroundColors[(int) $code])) {
 14530 $out .= 'color:'.self::$availableForegroundColors[(int) $code].';';
 14531 } elseif (isset(self::$availableBackgroundColors[(int) $code])) {
 14532 $out .= 'background-color:'.self::$availableBackgroundColors[(int) $code].';';
 14533 } elseif (isset(self::$availableOptions[(int) $code])) {
 14534 switch (self::$availableOptions[(int) $code]) {
 14535 case 'bold':
 14536 $out .= 'font-weight:bold;';
 14537 break;
 14538 
 14539 case 'underscore':
 14540 $out .= 'text-decoration:underline;';
 14541 break;
 14542 }
 14543 }
 14544 }
 14545 
 14546 return $out.'">'.$matches[2].'</span>';
 14547 }
 14548 }
 14549 <?php
 14550 
 14551 
 14552 
 14553 
 14554 
 14555 
 14556 
 14557 
 14558 
 14559 
 14560 
 14561 namespace Composer\DependencyResolver;
 14562 
 14563 
 14564 
 14565 
 14566 
 14567 
 14568 
 14569 class Decisions implements \Iterator, \Countable
 14570 {
 14571 const DECISION_LITERAL = 0;
 14572 const DECISION_REASON = 1;
 14573 
 14574 
 14575 protected $pool;
 14576 
 14577 protected $decisionMap;
 14578 
 14579 
 14580 
 14581 protected $decisionQueue = array();
 14582 
 14583 public function __construct(Pool $pool)
 14584 {
 14585 $this->pool = $pool;
 14586 $this->decisionMap = array();
 14587 }
 14588 
 14589 
 14590 
 14591 
 14592 
 14593 
 14594 public function decide($literal, $level, Rule $why)
 14595 {
 14596 $this->addDecision($literal, $level);
 14597 $this->decisionQueue[] = array(
 14598 self::DECISION_LITERAL => $literal,
 14599 self::DECISION_REASON => $why,
 14600 );
 14601 }
 14602 
 14603 
 14604 
 14605 
 14606 
 14607 public function satisfy($literal)
 14608 {
 14609 $packageId = abs($literal);
 14610 
 14611 return (
 14612 $literal > 0 && isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0 ||
 14613 $literal < 0 && isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] < 0
 14614 );
 14615 }
 14616 
 14617 
 14618 
 14619 
 14620 
 14621 public function conflict($literal)
 14622 {
 14623 $packageId = abs($literal);
 14624 
 14625 return (
 14626 (isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0 && $literal < 0) ||
 14627 (isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] < 0 && $literal > 0)
 14628 );
 14629 }
 14630 
 14631 
 14632 
 14633 
 14634 
 14635 public function decided($literalOrPackageId)
 14636 {
 14637 return !empty($this->decisionMap[abs($literalOrPackageId)]);
 14638 }
 14639 
 14640 
 14641 
 14642 
 14643 
 14644 public function undecided($literalOrPackageId)
 14645 {
 14646 return empty($this->decisionMap[abs($literalOrPackageId)]);
 14647 }
 14648 
 14649 
 14650 
 14651 
 14652 
 14653 public function decidedInstall($literalOrPackageId)
 14654 {
 14655 $packageId = abs($literalOrPackageId);
 14656 
 14657 return isset($this->decisionMap[$packageId]) && $this->decisionMap[$packageId] > 0;
 14658 }
 14659 
 14660 
 14661 
 14662 
 14663 
 14664 public function decisionLevel($literalOrPackageId)
 14665 {
 14666 $packageId = abs($literalOrPackageId);
 14667 if (isset($this->decisionMap[$packageId])) {
 14668 return abs($this->decisionMap[$packageId]);
 14669 }
 14670 
 14671 return 0;
 14672 }
 14673 
 14674 
 14675 
 14676 
 14677 
 14678 public function decisionRule($literalOrPackageId)
 14679 {
 14680 $packageId = abs($literalOrPackageId);
 14681 
 14682 foreach ($this->decisionQueue as $decision) {
 14683 if ($packageId === abs($decision[self::DECISION_LITERAL])) {
 14684 return $decision[self::DECISION_REASON];
 14685 }
 14686 }
 14687 
 14688 return null;
 14689 }
 14690 
 14691 
 14692 
 14693 
 14694 
 14695 public function atOffset($queueOffset)
 14696 {
 14697 return $this->decisionQueue[$queueOffset];
 14698 }
 14699 
 14700 
 14701 
 14702 
 14703 
 14704 public function validOffset($queueOffset)
 14705 {
 14706 return $queueOffset >= 0 && $queueOffset < \count($this->decisionQueue);
 14707 }
 14708 
 14709 
 14710 
 14711 
 14712 public function lastReason()
 14713 {
 14714 return $this->decisionQueue[\count($this->decisionQueue) - 1][self::DECISION_REASON];
 14715 }
 14716 
 14717 
 14718 
 14719 
 14720 public function lastLiteral()
 14721 {
 14722 return $this->decisionQueue[\count($this->decisionQueue) - 1][self::DECISION_LITERAL];
 14723 }
 14724 
 14725 
 14726 
 14727 
 14728 public function reset()
 14729 {
 14730 while ($decision = array_pop($this->decisionQueue)) {
 14731 $this->decisionMap[abs($decision[self::DECISION_LITERAL])] = 0;
 14732 }
 14733 }
 14734 
 14735 
 14736 
 14737 
 14738 
 14739 public function resetToOffset($offset)
 14740 {
 14741 while (\count($this->decisionQueue) > $offset + 1) {
 14742 $decision = array_pop($this->decisionQueue);
 14743 $this->decisionMap[abs($decision[self::DECISION_LITERAL])] = 0;
 14744 }
 14745 }
 14746 
 14747 
 14748 
 14749 
 14750 public function revertLast()
 14751 {
 14752 $this->decisionMap[abs($this->lastLiteral())] = 0;
 14753 array_pop($this->decisionQueue);
 14754 }
 14755 
 14756 
 14757 
 14758 
 14759 #[\ReturnTypeWillChange]
 14760 public function count()
 14761 {
 14762 return \count($this->decisionQueue);
 14763 }
 14764 
 14765 
 14766 
 14767 
 14768 #[\ReturnTypeWillChange]
 14769 public function rewind()
 14770 {
 14771 end($this->decisionQueue);
 14772 }
 14773 
 14774 
 14775 
 14776 
 14777 #[\ReturnTypeWillChange]
 14778 public function current()
 14779 {
 14780 return current($this->decisionQueue);
 14781 }
 14782 
 14783 
 14784 
 14785 
 14786 #[\ReturnTypeWillChange]
 14787 public function key()
 14788 {
 14789 return key($this->decisionQueue);
 14790 }
 14791 
 14792 
 14793 
 14794 
 14795 #[\ReturnTypeWillChange]
 14796 public function next()
 14797 {
 14798 prev($this->decisionQueue);
 14799 }
 14800 
 14801 
 14802 
 14803 
 14804 #[\ReturnTypeWillChange]
 14805 public function valid()
 14806 {
 14807 return false !== current($this->decisionQueue);
 14808 }
 14809 
 14810 
 14811 
 14812 
 14813 public function isEmpty()
 14814 {
 14815 return \count($this->decisionQueue) === 0;
 14816 }
 14817 
 14818 
 14819 
 14820 
 14821 
 14822 
 14823 protected function addDecision($literal, $level)
 14824 {
 14825 $packageId = abs($literal);
 14826 
 14827 $previousDecision = isset($this->decisionMap[$packageId]) ? $this->decisionMap[$packageId] : null;
 14828 if ($previousDecision != 0) {
 14829 $literalString = $this->pool->literalToPrettyString($literal, array());
 14830 $package = $this->pool->literalToPackage($literal);
 14831 throw new SolverBugException(
 14832 "Trying to decide $literalString on level $level, even though $package was previously decided as ".(int) $previousDecision."."
 14833 );
 14834 }
 14835 
 14836 if ($literal > 0) {
 14837 $this->decisionMap[$packageId] = $level;
 14838 } else {
 14839 $this->decisionMap[$packageId] = -$level;
 14840 }
 14841 }
 14842 
 14843 
 14844 
 14845 
 14846 public function toString(Pool $pool = null)
 14847 {
 14848 $decisionMap = $this->decisionMap;
 14849 ksort($decisionMap);
 14850 $str = '[';
 14851 foreach ($decisionMap as $packageId => $level) {
 14852 $str .= (($pool) ? $pool->literalToPackage($packageId) : $packageId).':'.$level.',';
 14853 }
 14854 $str .= ']';
 14855 
 14856 return $str;
 14857 }
 14858 
 14859 public function __toString()
 14860 {
 14861 return $this->toString();
 14862 }
 14863 }
 14864 <?php
 14865 
 14866 
 14867 
 14868 
 14869 
 14870 
 14871 
 14872 
 14873 
 14874 
 14875 
 14876 namespace Composer\DependencyResolver;
 14877 
 14878 use Composer\Package\AliasPackage;
 14879 use Composer\Package\BasePackage;
 14880 use Composer\Package\PackageInterface;
 14881 use Composer\Semver\Constraint\Constraint;
 14882 
 14883 
 14884 
 14885 
 14886 
 14887 class DefaultPolicy implements PolicyInterface
 14888 {
 14889 
 14890 private $preferStable;
 14891 
 14892 private $preferLowest;
 14893 
 14894 
 14895 
 14896 
 14897 
 14898 public function __construct($preferStable = false, $preferLowest = false)
 14899 {
 14900 $this->preferStable = $preferStable;
 14901 $this->preferLowest = $preferLowest;
 14902 }
 14903 
 14904 
 14905 
 14906 
 14907 
 14908 
 14909 
 14910 public function versionCompare(PackageInterface $a, PackageInterface $b, $operator)
 14911 {
 14912 if ($this->preferStable && ($stabA = $a->getStability()) !== ($stabB = $b->getStability())) {
 14913 return BasePackage::$stabilities[$stabA] < BasePackage::$stabilities[$stabB];
 14914 }
 14915 
 14916 $constraint = new Constraint($operator, $b->getVersion());
 14917 $version = new Constraint('==', $a->getVersion());
 14918 
 14919 return $constraint->matchSpecific($version, true);
 14920 }
 14921 
 14922 
 14923 
 14924 
 14925 
 14926 
 14927 public function selectPreferredPackages(Pool $pool, array $literals, $requiredPackage = null)
 14928 {
 14929 $packages = $this->groupLiteralsByName($pool, $literals);
 14930 $policy = $this;
 14931 
 14932 foreach ($packages as &$nameLiterals) {
 14933 usort($nameLiterals, function ($a, $b) use ($policy, $pool, $requiredPackage) {
 14934 return $policy->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage, true);
 14935 });
 14936 }
 14937 
 14938 foreach ($packages as &$sortedLiterals) {
 14939 $sortedLiterals = $this->pruneToBestVersion($pool, $sortedLiterals);
 14940 $sortedLiterals = $this->pruneRemoteAliases($pool, $sortedLiterals);
 14941 }
 14942 
 14943 $selected = \call_user_func_array('array_merge', array_values($packages));
 14944 
 14945 
 14946 usort($selected, function ($a, $b) use ($policy, $pool, $requiredPackage) {
 14947 return $policy->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage);
 14948 });
 14949 
 14950 return $selected;
 14951 }
 14952 
 14953 
 14954 
 14955 
 14956 
 14957 protected function groupLiteralsByName(Pool $pool, $literals)
 14958 {
 14959 $packages = array();
 14960 foreach ($literals as $literal) {
 14961 $packageName = $pool->literalToPackage($literal)->getName();
 14962 
 14963 if (!isset($packages[$packageName])) {
 14964 $packages[$packageName] = array();
 14965 }
 14966 $packages[$packageName][] = $literal;
 14967 }
 14968 
 14969 return $packages;
 14970 }
 14971 
 14972 
 14973 
 14974 
 14975 
 14976 
 14977 
 14978 public function compareByPriority(Pool $pool, BasePackage $a, BasePackage $b, $requiredPackage = null, $ignoreReplace = false)
 14979 {
 14980 
 14981 if ($a->getName() === $b->getName()) {
 14982 $aAliased = $a instanceof AliasPackage;
 14983 $bAliased = $b instanceof AliasPackage;
 14984 if ($aAliased && !$bAliased) {
 14985 return -1; 
 14986 }
 14987 if (!$aAliased && $bAliased) {
 14988 return 1; 
 14989 }
 14990 }
 14991 
 14992 if (!$ignoreReplace) {
 14993 
 14994 if ($this->replaces($a, $b)) {
 14995 return 1; 
 14996 }
 14997 if ($this->replaces($b, $a)) {
 14998 return -1; 
 14999 }
 15000 
 15001 
 15002 
 15003 if ($requiredPackage && false !== ($pos = strpos($requiredPackage, '/'))) {
 15004 $requiredVendor = substr($requiredPackage, 0, $pos);
 15005 
 15006 $aIsSameVendor = strpos($a->getName(), $requiredVendor) === 0;
 15007 $bIsSameVendor = strpos($b->getName(), $requiredVendor) === 0;
 15008 
 15009 if ($bIsSameVendor !== $aIsSameVendor) {
 15010 return $aIsSameVendor ? -1 : 1;
 15011 }
 15012 }
 15013 }
 15014 
 15015 
 15016 if ($a->id === $b->id) {
 15017 return 0;
 15018 }
 15019 
 15020 return ($a->id < $b->id) ? -1 : 1;
 15021 }
 15022 
 15023 
 15024 
 15025 
 15026 
 15027 
 15028 
 15029 
 15030 
 15031 protected function replaces(BasePackage $source, BasePackage $target)
 15032 {
 15033 foreach ($source->getReplaces() as $link) {
 15034 if ($link->getTarget() === $target->getName()
 15035 
 15036 
 15037 ) {
 15038 return true;
 15039 }
 15040 }
 15041 
 15042 return false;
 15043 }
 15044 
 15045 
 15046 
 15047 
 15048 
 15049 protected function pruneToBestVersion(Pool $pool, $literals)
 15050 {
 15051 $operator = $this->preferLowest ? '<' : '>';
 15052 $bestLiterals = array($literals[0]);
 15053 $bestPackage = $pool->literalToPackage($literals[0]);
 15054 foreach ($literals as $i => $literal) {
 15055 if (0 === $i) {
 15056 continue;
 15057 }
 15058 
 15059 $package = $pool->literalToPackage($literal);
 15060 
 15061 if ($this->versionCompare($package, $bestPackage, $operator)) {
 15062 $bestPackage = $package;
 15063 $bestLiterals = array($literal);
 15064 } elseif ($this->versionCompare($package, $bestPackage, '==')) {
 15065 $bestLiterals[] = $literal;
 15066 }
 15067 }
 15068 
 15069 return $bestLiterals;
 15070 }
 15071 
 15072 
 15073 
 15074 
 15075 
 15076 
 15077 
 15078 
 15079 
 15080 protected function pruneRemoteAliases(Pool $pool, array $literals)
 15081 {
 15082 $hasLocalAlias = false;
 15083 
 15084 foreach ($literals as $literal) {
 15085 $package = $pool->literalToPackage($literal);
 15086 
 15087 if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
 15088 $hasLocalAlias = true;
 15089 break;
 15090 }
 15091 }
 15092 
 15093 if (!$hasLocalAlias) {
 15094 return $literals;
 15095 }
 15096 
 15097 $selected = array();
 15098 foreach ($literals as $literal) {
 15099 $package = $pool->literalToPackage($literal);
 15100 
 15101 if ($package instanceof AliasPackage && $package->isRootPackageAlias()) {
 15102 $selected[] = $literal;
 15103 }
 15104 }
 15105 
 15106 return $selected;
 15107 }
 15108 }
 15109 <?php
 15110 
 15111 
 15112 
 15113 
 15114 
 15115 
 15116 
 15117 
 15118 
 15119 
 15120 
 15121 namespace Composer\DependencyResolver;
 15122 
 15123 
 15124 
 15125 
 15126 class GenericRule extends Rule
 15127 {
 15128 
 15129 protected $literals;
 15130 
 15131 
 15132 
 15133 
 15134 public function __construct(array $literals, $reason, $reasonData)
 15135 {
 15136 parent::__construct($reason, $reasonData);
 15137 
 15138 
 15139 sort($literals);
 15140 
 15141 $this->literals = $literals;
 15142 }
 15143 
 15144 
 15145 
 15146 
 15147 public function getLiterals()
 15148 {
 15149 return $this->literals;
 15150 }
 15151 
 15152 
 15153 
 15154 
 15155 public function getHash()
 15156 {
 15157 $data = unpack('ihash', md5(implode(',', $this->literals), true));
 15158 
 15159 return $data['hash'];
 15160 }
 15161 
 15162 
 15163 
 15164 
 15165 
 15166 
 15167 
 15168 
 15169 
 15170 public function equals(Rule $rule)
 15171 {
 15172 return $this->literals === $rule->getLiterals();
 15173 }
 15174 
 15175 
 15176 
 15177 
 15178 public function isAssertion()
 15179 {
 15180 return 1 === \count($this->literals);
 15181 }
 15182 
 15183 
 15184 
 15185 
 15186 
 15187 
 15188 public function __toString()
 15189 {
 15190 $result = $this->isDisabled() ? 'disabled(' : '(';
 15191 
 15192 foreach ($this->literals as $i => $literal) {
 15193 if ($i != 0) {
 15194 $result .= '|';
 15195 }
 15196 $result .= $literal;
 15197 }
 15198 
 15199 $result .= ')';
 15200 
 15201 return $result;
 15202 }
 15203 }
 15204 <?php
 15205 
 15206 
 15207 
 15208 
 15209 
 15210 
 15211 
 15212 
 15213 
 15214 
 15215 
 15216 namespace Composer\DependencyResolver;
 15217 
 15218 use Composer\Repository\InstalledRepositoryInterface;
 15219 use Composer\Repository\RepositoryInterface;
 15220 
 15221 
 15222 
 15223 
 15224 
 15225 class LocalRepoTransaction extends Transaction
 15226 {
 15227 public function __construct(RepositoryInterface $lockedRepository, InstalledRepositoryInterface $localRepository)
 15228 {
 15229 parent::__construct(
 15230 $localRepository->getPackages(),
 15231 $lockedRepository->getPackages()
 15232 );
 15233 }
 15234 }
 15235 <?php
 15236 
 15237 
 15238 
 15239 
 15240 
 15241 
 15242 
 15243 
 15244 
 15245 
 15246 
 15247 namespace Composer\DependencyResolver;
 15248 
 15249 use Composer\Package\AliasPackage;
 15250 use Composer\Package\BasePackage;
 15251 use Composer\Package\Package;
 15252 
 15253 
 15254 
 15255 
 15256 
 15257 class LockTransaction extends Transaction
 15258 {
 15259 
 15260 
 15261 
 15262 
 15263 
 15264 
 15265 
 15266 protected $presentMap;
 15267 
 15268 
 15269 
 15270 
 15271 
 15272 
 15273 
 15274 
 15275 protected $unlockableMap;
 15276 
 15277 
 15278 
 15279 
 15280 protected $resultPackages;
 15281 
 15282 
 15283 
 15284 
 15285 
 15286 public function __construct(Pool $pool, array $presentMap, array $unlockableMap, Decisions $decisions)
 15287 {
 15288 $this->presentMap = $presentMap;
 15289 $this->unlockableMap = $unlockableMap;
 15290 
 15291 $this->setResultPackages($pool, $decisions);
 15292 parent::__construct($this->presentMap, $this->resultPackages['all']);
 15293 }
 15294 
 15295 
 15296 
 15297 
 15298 
 15299 public function setResultPackages(Pool $pool, Decisions $decisions)
 15300 {
 15301 $this->resultPackages = array('all' => array(), 'non-dev' => array(), 'dev' => array());
 15302 foreach ($decisions as $i => $decision) {
 15303 $literal = $decision[Decisions::DECISION_LITERAL];
 15304 
 15305 if ($literal > 0) {
 15306 $package = $pool->literalToPackage($literal);
 15307 
 15308 $this->resultPackages['all'][] = $package;
 15309 if (!isset($this->unlockableMap[$package->id])) {
 15310 $this->resultPackages['non-dev'][] = $package;
 15311 }
 15312 }
 15313 }
 15314 }
 15315 
 15316 
 15317 
 15318 
 15319 public function setNonDevPackages(LockTransaction $extractionResult)
 15320 {
 15321 $packages = $extractionResult->getNewLockPackages(false);
 15322 
 15323 $this->resultPackages['dev'] = $this->resultPackages['non-dev'];
 15324 $this->resultPackages['non-dev'] = array();
 15325 
 15326 foreach ($packages as $package) {
 15327 foreach ($this->resultPackages['dev'] as $i => $resultPackage) {
 15328 
 15329 if ($package->getName() == $resultPackage->getName()) {
 15330 $this->resultPackages['non-dev'][] = $resultPackage;
 15331 unset($this->resultPackages['dev'][$i]);
 15332 }
 15333 }
 15334 }
 15335 }
 15336 
 15337 
 15338 
 15339 
 15340 
 15341 
 15342 
 15343 public function getNewLockPackages($devMode, $updateMirrors = false)
 15344 {
 15345 $packages = array();
 15346 foreach ($this->resultPackages[$devMode ? 'dev' : 'non-dev'] as $package) {
 15347 if (!$package instanceof AliasPackage) {
 15348 
 15349 
 15350 if ($updateMirrors && !isset($this->presentMap[spl_object_hash($package)])) {
 15351 foreach ($this->presentMap as $presentPackage) {
 15352 if ($package->getName() == $presentPackage->getName() && $package->getVersion() == $presentPackage->getVersion()) {
 15353 if ($presentPackage->getSourceReference() && $presentPackage->getSourceType() === $package->getSourceType()) {
 15354 $package->setSourceDistReferences($presentPackage->getSourceReference());
 15355 }
 15356 if ($presentPackage->getReleaseDate() && $package instanceof Package) {
 15357 $package->setReleaseDate($presentPackage->getReleaseDate());
 15358 }
 15359 }
 15360 }
 15361 }
 15362 $packages[] = $package;
 15363 }
 15364 }
 15365 
 15366 return $packages;
 15367 }
 15368 
 15369 
 15370 
 15371 
 15372 
 15373 
 15374 public function getAliases($aliases)
 15375 {
 15376 $usedAliases = array();
 15377 
 15378 foreach ($this->resultPackages['all'] as $package) {
 15379 if ($package instanceof AliasPackage) {
 15380 foreach ($aliases as $index => $alias) {
 15381 if ($alias['package'] === $package->getName()) {
 15382 $usedAliases[] = $alias;
 15383 unset($aliases[$index]);
 15384 }
 15385 }
 15386 }
 15387 }
 15388 
 15389 usort($usedAliases, function ($a, $b) {
 15390 return strcmp($a['package'], $b['package']);
 15391 });
 15392 
 15393 return $usedAliases;
 15394 }
 15395 }
 15396 <?php
 15397 
 15398 
 15399 
 15400 
 15401 
 15402 
 15403 
 15404 
 15405 
 15406 
 15407 
 15408 namespace Composer\DependencyResolver;
 15409 
 15410 
 15411 
 15412 
 15413 
 15414 
 15415 class MultiConflictRule extends Rule
 15416 {
 15417 
 15418 protected $literals;
 15419 
 15420 
 15421 
 15422 
 15423 public function __construct(array $literals, $reason, $reasonData)
 15424 {
 15425 parent::__construct($reason, $reasonData);
 15426 
 15427 if (\count($literals) < 3) {
 15428 throw new \RuntimeException("multi conflict rule requires at least 3 literals");
 15429 }
 15430 
 15431 
 15432 sort($literals);
 15433 
 15434 $this->literals = $literals;
 15435 }
 15436 
 15437 
 15438 
 15439 
 15440 public function getLiterals()
 15441 {
 15442 return $this->literals;
 15443 }
 15444 
 15445 
 15446 
 15447 
 15448 public function getHash()
 15449 {
 15450 $data = unpack('ihash', md5('c:'.implode(',', $this->literals), true));
 15451 
 15452 return $data['hash'];
 15453 }
 15454 
 15455 
 15456 
 15457 
 15458 
 15459 
 15460 
 15461 
 15462 
 15463 public function equals(Rule $rule)
 15464 {
 15465 if ($rule instanceof MultiConflictRule) {
 15466 return $this->literals === $rule->getLiterals();
 15467 }
 15468 
 15469 return false;
 15470 }
 15471 
 15472 
 15473 
 15474 
 15475 public function isAssertion()
 15476 {
 15477 return false;
 15478 }
 15479 
 15480 
 15481 
 15482 
 15483 
 15484 public function disable()
 15485 {
 15486 throw new \RuntimeException("Disabling multi conflict rules is not possible. Please contact composer at https://github.com/composer/composer to let us debug what lead to this situation.");
 15487 }
 15488 
 15489 
 15490 
 15491 
 15492 
 15493 
 15494 public function __toString()
 15495 {
 15496 
 15497 $result = $this->isDisabled() ? 'disabled(multi(' : '(multi(';
 15498 
 15499 foreach ($this->literals as $i => $literal) {
 15500 if ($i != 0) {
 15501 $result .= '|';
 15502 }
 15503 $result .= $literal;
 15504 }
 15505 
 15506 $result .= '))';
 15507 
 15508 return $result;
 15509 }
 15510 }
 15511 <?php
 15512 
 15513 
 15514 
 15515 
 15516 
 15517 
 15518 
 15519 
 15520 
 15521 
 15522 
 15523 namespace Composer\DependencyResolver\Operation;
 15524 
 15525 use Composer\Package\PackageInterface;
 15526 
 15527 
 15528 
 15529 
 15530 
 15531 
 15532 class InstallOperation extends SolverOperation implements OperationInterface
 15533 {
 15534 const TYPE = 'install';
 15535 
 15536 
 15537 
 15538 
 15539 protected $package;
 15540 
 15541 public function __construct(PackageInterface $package)
 15542 {
 15543 $this->package = $package;
 15544 }
 15545 
 15546 
 15547 
 15548 
 15549 
 15550 
 15551 public function getPackage()
 15552 {
 15553 return $this->package;
 15554 }
 15555 
 15556 
 15557 
 15558 
 15559 public function show($lock)
 15560 {
 15561 return self::format($this->package, $lock);
 15562 }
 15563 
 15564 
 15565 
 15566 
 15567 
 15568 public static function format(PackageInterface $package, $lock = false)
 15569 {
 15570 return ($lock ? 'Locking ' : 'Installing ').'<info>'.$package->getPrettyName().'</info> (<comment>'.$package->getFullPrettyVersion().'</comment>)';
 15571 }
 15572 }
 15573 <?php
 15574 
 15575 
 15576 
 15577 
 15578 
 15579 
 15580 
 15581 
 15582 
 15583 
 15584 
 15585 namespace Composer\DependencyResolver\Operation;
 15586 
 15587 use Composer\Package\AliasPackage;
 15588 
 15589 
 15590 
 15591 
 15592 
 15593 
 15594 class MarkAliasInstalledOperation extends SolverOperation implements OperationInterface
 15595 {
 15596 const TYPE = 'markAliasInstalled';
 15597 
 15598 
 15599 
 15600 
 15601 protected $package;
 15602 
 15603 public function __construct(AliasPackage $package)
 15604 {
 15605 $this->package = $package;
 15606 }
 15607 
 15608 
 15609 
 15610 
 15611 
 15612 
 15613 public function getPackage()
 15614 {
 15615 return $this->package;
 15616 }
 15617 
 15618 
 15619 
 15620 
 15621 public function show($lock)
 15622 {
 15623 return 'Marking <info>'.$this->package->getPrettyName().'</info> (<comment>'.$this->package->getFullPrettyVersion().'</comment>) as installed, alias of <info>'.$this->package->getAliasOf()->getPrettyName().'</info> (<comment>'.$this->package->getAliasOf()->getFullPrettyVersion().'</comment>)';
 15624 }
 15625 }
 15626 <?php
 15627 
 15628 
 15629 
 15630 
 15631 
 15632 
 15633 
 15634 
 15635 
 15636 
 15637 
 15638 namespace Composer\DependencyResolver\Operation;
 15639 
 15640 use Composer\Package\AliasPackage;
 15641 
 15642 
 15643 
 15644 
 15645 
 15646 
 15647 class MarkAliasUninstalledOperation extends SolverOperation implements OperationInterface
 15648 {
 15649 const TYPE = 'markAliasUninstalled';
 15650 
 15651 
 15652 
 15653 
 15654 protected $package;
 15655 
 15656 public function __construct(AliasPackage $package)
 15657 {
 15658 $this->package = $package;
 15659 }
 15660 
 15661 
 15662 
 15663 
 15664 
 15665 
 15666 public function getPackage()
 15667 {
 15668 return $this->package;
 15669 }
 15670 
 15671 
 15672 
 15673 
 15674 public function show($lock)
 15675 {
 15676 return 'Marking <info>'.$this->package->getPrettyName().'</info> (<comment>'.$this->package->getFullPrettyVersion().'</comment>) as uninstalled, alias of <info>'.$this->package->getAliasOf()->getPrettyName().'</info> (<comment>'.$this->package->getAliasOf()->getFullPrettyVersion().'</comment>)';
 15677 }
 15678 }
 15679 <?php
 15680 
 15681 
 15682 
 15683 
 15684 
 15685 
 15686 
 15687 
 15688 
 15689 
 15690 
 15691 namespace Composer\DependencyResolver\Operation;
 15692 
 15693 
 15694 
 15695 
 15696 
 15697 
 15698 interface OperationInterface
 15699 {
 15700 
 15701 
 15702 
 15703 
 15704 
 15705 public function getOperationType();
 15706 
 15707 
 15708 
 15709 
 15710 
 15711 
 15712 
 15713 public function show($lock);
 15714 
 15715 
 15716 
 15717 
 15718 
 15719 
 15720 public function __toString();
 15721 }
 15722 <?php
 15723 
 15724 
 15725 
 15726 
 15727 
 15728 
 15729 
 15730 
 15731 
 15732 
 15733 
 15734 namespace Composer\DependencyResolver\Operation;
 15735 
 15736 
 15737 
 15738 
 15739 
 15740 
 15741 abstract class SolverOperation implements OperationInterface
 15742 {
 15743 const TYPE = null;
 15744 
 15745 
 15746 
 15747 
 15748 
 15749 
 15750 public function getOperationType()
 15751 {
 15752 return static::TYPE;
 15753 }
 15754 
 15755 
 15756 
 15757 
 15758 public function __toString()
 15759 {
 15760 return $this->show(false);
 15761 }
 15762 }
 15763 <?php
 15764 
 15765 
 15766 
 15767 
 15768 
 15769 
 15770 
 15771 
 15772 
 15773 
 15774 
 15775 namespace Composer\DependencyResolver\Operation;
 15776 
 15777 use Composer\Package\PackageInterface;
 15778 
 15779 
 15780 
 15781 
 15782 
 15783 
 15784 class UninstallOperation extends SolverOperation implements OperationInterface
 15785 {
 15786 const TYPE = 'uninstall';
 15787 
 15788 
 15789 
 15790 
 15791 protected $package;
 15792 
 15793 public function __construct(PackageInterface $package)
 15794 {
 15795 $this->package = $package;
 15796 }
 15797 
 15798 
 15799 
 15800 
 15801 
 15802 
 15803 public function getPackage()
 15804 {
 15805 return $this->package;
 15806 }
 15807 
 15808 
 15809 
 15810 
 15811 public function show($lock)
 15812 {
 15813 return self::format($this->package, $lock);
 15814 }
 15815 
 15816 
 15817 
 15818 
 15819 
 15820 public static function format(PackageInterface $package, $lock = false)
 15821 {
 15822 return 'Removing <info>'.$package->getPrettyName().'</info> (<comment>'.$package->getFullPrettyVersion().'</comment>)';
 15823 }
 15824 }
 15825 <?php
 15826 
 15827 
 15828 
 15829 
 15830 
 15831 
 15832 
 15833 
 15834 
 15835 
 15836 
 15837 namespace Composer\DependencyResolver\Operation;
 15838 
 15839 use Composer\Package\PackageInterface;
 15840 use Composer\Package\Version\VersionParser;
 15841 
 15842 
 15843 
 15844 
 15845 
 15846 
 15847 class UpdateOperation extends SolverOperation implements OperationInterface
 15848 {
 15849 const TYPE = 'update';
 15850 
 15851 
 15852 
 15853 
 15854 protected $initialPackage;
 15855 
 15856 
 15857 
 15858 
 15859 protected $targetPackage;
 15860 
 15861 
 15862 
 15863 
 15864 
 15865 public function __construct(PackageInterface $initial, PackageInterface $target)
 15866 {
 15867 $this->initialPackage = $initial;
 15868 $this->targetPackage = $target;
 15869 }
 15870 
 15871 
 15872 
 15873 
 15874 
 15875 
 15876 public function getInitialPackage()
 15877 {
 15878 return $this->initialPackage;
 15879 }
 15880 
 15881 
 15882 
 15883 
 15884 
 15885 
 15886 public function getTargetPackage()
 15887 {
 15888 return $this->targetPackage;
 15889 }
 15890 
 15891 
 15892 
 15893 
 15894 public function show($lock)
 15895 {
 15896 return self::format($this->initialPackage, $this->targetPackage, $lock);
 15897 }
 15898 
 15899 
 15900 
 15901 
 15902 
 15903 public static function format(PackageInterface $initialPackage, PackageInterface $targetPackage, $lock = false)
 15904 {
 15905 $fromVersion = $initialPackage->getFullPrettyVersion();
 15906 $toVersion = $targetPackage->getFullPrettyVersion();
 15907 
 15908 if ($fromVersion === $toVersion && $initialPackage->getSourceReference() !== $targetPackage->getSourceReference()) {
 15909 $fromVersion = $initialPackage->getFullPrettyVersion(true, PackageInterface::DISPLAY_SOURCE_REF);
 15910 $toVersion = $targetPackage->getFullPrettyVersion(true, PackageInterface::DISPLAY_SOURCE_REF);
 15911 } elseif ($fromVersion === $toVersion && $initialPackage->getDistReference() !== $targetPackage->getDistReference()) {
 15912 $fromVersion = $initialPackage->getFullPrettyVersion(true, PackageInterface::DISPLAY_DIST_REF);
 15913 $toVersion = $targetPackage->getFullPrettyVersion(true, PackageInterface::DISPLAY_DIST_REF);
 15914 }
 15915 
 15916 $actionName = VersionParser::isUpgrade($initialPackage->getVersion(), $targetPackage->getVersion()) ? 'Upgrading' : 'Downgrading';
 15917 
 15918 return $actionName.' <info>'.$initialPackage->getPrettyName().'</info> (<comment>'.$fromVersion.'</comment> => <comment>'.$toVersion.'</comment>)';
 15919 }
 15920 }
 15921 <?php
 15922 
 15923 
 15924 
 15925 
 15926 
 15927 
 15928 
 15929 
 15930 
 15931 
 15932 
 15933 namespace Composer\DependencyResolver;
 15934 
 15935 use Composer\Package\PackageInterface;
 15936 use Composer\Semver\Constraint\Constraint;
 15937 
 15938 
 15939 
 15940 
 15941 interface PolicyInterface
 15942 {
 15943 
 15944 
 15945 
 15946 
 15947 
 15948 
 15949 public function versionCompare(PackageInterface $a, PackageInterface $b, $operator);
 15950 
 15951 
 15952 
 15953 
 15954 
 15955 
 15956 public function selectPreferredPackages(Pool $pool, array $literals, $requiredPackage = null);
 15957 }
 15958 <?php
 15959 
 15960 
 15961 
 15962 
 15963 
 15964 
 15965 
 15966 
 15967 
 15968 
 15969 
 15970 namespace Composer\DependencyResolver;
 15971 
 15972 use Composer\Package\BasePackage;
 15973 use Composer\Package\Version\VersionParser;
 15974 use Composer\Semver\CompilingMatcher;
 15975 use Composer\Semver\Constraint\ConstraintInterface;
 15976 use Composer\Semver\Constraint\Constraint;
 15977 
 15978 
 15979 
 15980 
 15981 
 15982 
 15983 
 15984 class Pool implements \Countable
 15985 {
 15986 
 15987 protected $packages = array();
 15988 
 15989 protected $packageByName = array();
 15990 
 15991 protected $versionParser;
 15992 
 15993 protected $providerCache = array();
 15994 
 15995 protected $unacceptableFixedOrLockedPackages;
 15996 
 15997 protected $removedVersions = array();
 15998 
 15999 protected $removedVersionsByPackage = array();
 16000 
 16001 
 16002 
 16003 
 16004 
 16005 
 16006 
 16007 public function __construct(array $packages = array(), array $unacceptableFixedOrLockedPackages = array(), array $removedVersions = array(), array $removedVersionsByPackage = array())
 16008 {
 16009 $this->versionParser = new VersionParser;
 16010 $this->setPackages($packages);
 16011 $this->unacceptableFixedOrLockedPackages = $unacceptableFixedOrLockedPackages;
 16012 $this->removedVersions = $removedVersions;
 16013 $this->removedVersionsByPackage = $removedVersionsByPackage;
 16014 }
 16015 
 16016 
 16017 
 16018 
 16019 
 16020 public function getRemovedVersions($name, ConstraintInterface $constraint)
 16021 {
 16022 if (!isset($this->removedVersions[$name])) {
 16023 return array();
 16024 }
 16025 
 16026 $result = array();
 16027 foreach ($this->removedVersions[$name] as $version => $prettyVersion) {
 16028 if ($constraint->matches(new Constraint('==', $version))) {
 16029 $result[$version] = $prettyVersion;
 16030 }
 16031 }
 16032 
 16033 return $result;
 16034 }
 16035 
 16036 
 16037 
 16038 
 16039 
 16040 public function getRemovedVersionsByPackage($objectHash)
 16041 {
 16042 if (!isset($this->removedVersionsByPackage[$objectHash])) {
 16043 return array();
 16044 }
 16045 
 16046 return $this->removedVersionsByPackage[$objectHash];
 16047 }
 16048 
 16049 
 16050 
 16051 
 16052 
 16053 private function setPackages(array $packages)
 16054 {
 16055 $id = 1;
 16056 
 16057 foreach ($packages as $package) {
 16058 $this->packages[] = $package;
 16059 
 16060 $package->id = $id++;
 16061 
 16062 foreach ($package->getNames() as $provided) {
 16063 $this->packageByName[$provided][] = $package;
 16064 }
 16065 }
 16066 }
 16067 
 16068 
 16069 
 16070 
 16071 public function getPackages()
 16072 {
 16073 return $this->packages;
 16074 }
 16075 
 16076 
 16077 
 16078 
 16079 
 16080 
 16081 
 16082 public function packageById($id)
 16083 {
 16084 return $this->packages[$id - 1];
 16085 }
 16086 
 16087 
 16088 
 16089 
 16090 
 16091 #[\ReturnTypeWillChange]
 16092 public function count()
 16093 {
 16094 return \count($this->packages);
 16095 }
 16096 
 16097 
 16098 
 16099 
 16100 
 16101 
 16102 
 16103 
 16104 
 16105 public function whatProvides($name, ConstraintInterface $constraint = null)
 16106 {
 16107 $key = (string) $constraint;
 16108 if (isset($this->providerCache[$name][$key])) {
 16109 return $this->providerCache[$name][$key];
 16110 }
 16111 
 16112 return $this->providerCache[$name][$key] = $this->computeWhatProvides($name, $constraint);
 16113 }
 16114 
 16115 
 16116 
 16117 
 16118 
 16119 
 16120 
 16121 private function computeWhatProvides($name, ConstraintInterface $constraint = null)
 16122 {
 16123 if (!isset($this->packageByName[$name])) {
 16124 return array();
 16125 }
 16126 
 16127 $matches = array();
 16128 
 16129 foreach ($this->packageByName[$name] as $candidate) {
 16130 if ($this->match($candidate, $name, $constraint)) {
 16131 $matches[] = $candidate;
 16132 }
 16133 }
 16134 
 16135 return $matches;
 16136 }
 16137 
 16138 
 16139 
 16140 
 16141 
 16142 public function literalToPackage($literal)
 16143 {
 16144 $packageId = abs($literal);
 16145 
 16146 return $this->packageById($packageId);
 16147 }
 16148 
 16149 
 16150 
 16151 
 16152 
 16153 
 16154 public function literalToPrettyString($literal, $installedMap)
 16155 {
 16156 $package = $this->literalToPackage($literal);
 16157 
 16158 if (isset($installedMap[$package->id])) {
 16159 $prefix = ($literal > 0 ? 'keep' : 'remove');
 16160 } else {
 16161 $prefix = ($literal > 0 ? 'install' : 'don\'t install');
 16162 }
 16163 
 16164 return $prefix.' '.$package->getPrettyString();
 16165 }
 16166 
 16167 
 16168 
 16169 
 16170 
 16171 
 16172 
 16173 
 16174 public function match(BasePackage $candidate, $name, ConstraintInterface $constraint = null)
 16175 {
 16176 $candidateName = $candidate->getName();
 16177 $candidateVersion = $candidate->getVersion();
 16178 
 16179 if ($candidateName === $name) {
 16180 return $constraint === null || CompilingMatcher::match($constraint, Constraint::OP_EQ, $candidateVersion);
 16181 }
 16182 
 16183 $provides = $candidate->getProvides();
 16184 $replaces = $candidate->getReplaces();
 16185 
 16186 
 16187 if (isset($replaces[0]) || isset($provides[0])) {
 16188 foreach ($provides as $link) {
 16189 if ($link->getTarget() === $name && ($constraint === null || $constraint->matches($link->getConstraint()))) {
 16190 return true;
 16191 }
 16192 }
 16193 
 16194 foreach ($replaces as $link) {
 16195 if ($link->getTarget() === $name && ($constraint === null || $constraint->matches($link->getConstraint()))) {
 16196 return true;
 16197 }
 16198 }
 16199 
 16200 return false;
 16201 }
 16202 
 16203 if (isset($provides[$name]) && ($constraint === null || $constraint->matches($provides[$name]->getConstraint()))) {
 16204 return true;
 16205 }
 16206 
 16207 if (isset($replaces[$name]) && ($constraint === null || $constraint->matches($replaces[$name]->getConstraint()))) {
 16208 return true;
 16209 }
 16210 
 16211 return false;
 16212 }
 16213 
 16214 
 16215 
 16216 
 16217 public function isUnacceptableFixedOrLockedPackage(BasePackage $package)
 16218 {
 16219 return \in_array($package, $this->unacceptableFixedOrLockedPackages, true);
 16220 }
 16221 
 16222 
 16223 
 16224 
 16225 public function getUnacceptableFixedOrLockedPackages()
 16226 {
 16227 return $this->unacceptableFixedOrLockedPackages;
 16228 }
 16229 
 16230 public function __toString()
 16231 {
 16232 $str = "Pool:\n";
 16233 
 16234 foreach ($this->packages as $package) {
 16235 $str .= '- '.str_pad((string) $package->id, 6, ' ', STR_PAD_LEFT).': '.$package->getName()."\n";
 16236 }
 16237 
 16238 return $str;
 16239 }
 16240 }
 16241 <?php
 16242 
 16243 
 16244 
 16245 
 16246 
 16247 
 16248 
 16249 
 16250 
 16251 
 16252 
 16253 namespace Composer\DependencyResolver;
 16254 
 16255 use Composer\EventDispatcher\EventDispatcher;
 16256 use Composer\IO\IOInterface;
 16257 use Composer\Package\AliasPackage;
 16258 use Composer\Package\BasePackage;
 16259 use Composer\Package\CompleteAliasPackage;
 16260 use Composer\Package\CompletePackage;
 16261 use Composer\Package\PackageInterface;
 16262 use Composer\Package\Version\StabilityFilter;
 16263 use Composer\Pcre\Preg;
 16264 use Composer\Plugin\PluginEvents;
 16265 use Composer\Plugin\PrePoolCreateEvent;
 16266 use Composer\Repository\PlatformRepository;
 16267 use Composer\Repository\RepositoryInterface;
 16268 use Composer\Repository\RootPackageRepository;
 16269 use Composer\Semver\CompilingMatcher;
 16270 use Composer\Semver\Constraint\Constraint;
 16271 use Composer\Semver\Constraint\ConstraintInterface;
 16272 use Composer\Semver\Constraint\MatchAllConstraint;
 16273 use Composer\Semver\Constraint\MultiConstraint;
 16274 use Composer\Semver\Intervals;
 16275 
 16276 
 16277 
 16278 
 16279 class PoolBuilder
 16280 {
 16281 
 16282 
 16283 
 16284 
 16285 private $acceptableStabilities;
 16286 
 16287 
 16288 
 16289 
 16290 private $stabilityFlags;
 16291 
 16292 
 16293 
 16294 
 16295 private $rootAliases;
 16296 
 16297 
 16298 
 16299 
 16300 private $rootReferences;
 16301 
 16302 
 16303 
 16304 private $eventDispatcher;
 16305 
 16306 
 16307 
 16308 private $poolOptimizer;
 16309 
 16310 
 16311 
 16312 private $io;
 16313 
 16314 
 16315 
 16316 
 16317 private $aliasMap = array();
 16318 
 16319 
 16320 
 16321 
 16322 private $packagesToLoad = array();
 16323 
 16324 
 16325 
 16326 
 16327 private $loadedPackages = array();
 16328 
 16329 
 16330 
 16331 
 16332 private $loadedPerRepo = array();
 16333 
 16334 
 16335 
 16336 private $packages = array();
 16337 
 16338 
 16339 
 16340 private $unacceptableFixedOrLockedPackages = array();
 16341 
 16342 private $updateAllowList = array();
 16343 
 16344 private $skippedLoad = array();
 16345 
 16346 
 16347 
 16348 
 16349 
 16350 
 16351 
 16352 
 16353 
 16354 private $pathRepoUnlocked = array();
 16355 
 16356 
 16357 
 16358 
 16359 
 16360 
 16361 
 16362 
 16363 
 16364 
 16365 
 16366 private $maxExtendedReqs = array();
 16367 
 16368 
 16369 
 16370 
 16371 private $updateAllowWarned = array();
 16372 
 16373 
 16374 private $indexCounter = 0;
 16375 
 16376 
 16377 
 16378 
 16379 
 16380 
 16381 
 16382 
 16383 
 16384 
 16385 
 16386 public function __construct(array $acceptableStabilities, array $stabilityFlags, array $rootAliases, array $rootReferences, IOInterface $io, EventDispatcher $eventDispatcher = null, PoolOptimizer $poolOptimizer = null)
 16387 {
 16388 $this->acceptableStabilities = $acceptableStabilities;
 16389 $this->stabilityFlags = $stabilityFlags;
 16390 $this->rootAliases = $rootAliases;
 16391 $this->rootReferences = $rootReferences;
 16392 $this->eventDispatcher = $eventDispatcher;
 16393 $this->poolOptimizer = $poolOptimizer;
 16394 $this->io = $io;
 16395 }
 16396 
 16397 
 16398 
 16399 
 16400 
 16401 public function buildPool(array $repositories, Request $request)
 16402 {
 16403 if ($request->getUpdateAllowList()) {
 16404 $this->updateAllowList = $request->getUpdateAllowList();
 16405 $this->warnAboutNonMatchingUpdateAllowList($request);
 16406 
 16407 foreach ($request->getLockedRepository()->getPackages() as $lockedPackage) {
 16408 if (!$this->isUpdateAllowed($lockedPackage)) {
 16409 
 16410 $this->skippedLoad[$lockedPackage->getName()][] = $lockedPackage;
 16411 foreach ($lockedPackage->getReplaces() as $link) {
 16412 $this->skippedLoad[$link->getTarget()][] = $lockedPackage;
 16413 }
 16414 
 16415 
 16416 
 16417 
 16418 
 16419 if ($lockedPackage->getDistType() === 'path') {
 16420 $transportOptions = $lockedPackage->getTransportOptions();
 16421 if (!isset($transportOptions['symlink']) || $transportOptions['symlink'] !== false) {
 16422 $this->pathRepoUnlocked[$lockedPackage->getName()] = true;
 16423 continue;
 16424 }
 16425 }
 16426 
 16427 $request->lockPackage($lockedPackage);
 16428 }
 16429 }
 16430 }
 16431 
 16432 foreach ($request->getFixedOrLockedPackages() as $package) {
 16433 
 16434 
 16435 $this->loadedPackages[$package->getName()] = new MatchAllConstraint();
 16436 
 16437 
 16438 foreach ($package->getReplaces() as $link) {
 16439 $this->loadedPackages[$link->getTarget()] = new MatchAllConstraint();
 16440 }
 16441 
 16442 
 16443 
 16444 
 16445 if (
 16446 $package->getRepository() instanceof RootPackageRepository
 16447 || $package->getRepository() instanceof PlatformRepository
 16448 || StabilityFilter::isPackageAcceptable($this->acceptableStabilities, $this->stabilityFlags, $package->getNames(), $package->getStability())
 16449 ) {
 16450 $this->loadPackage($request, $repositories, $package, false);
 16451 } else {
 16452 $this->unacceptableFixedOrLockedPackages[] = $package;
 16453 }
 16454 }
 16455 
 16456 foreach ($request->getRequires() as $packageName => $constraint) {
 16457 
 16458 if (isset($this->loadedPackages[$packageName])) {
 16459 continue;
 16460 }
 16461 
 16462 $this->packagesToLoad[$packageName] = $constraint;
 16463 $this->maxExtendedReqs[$packageName] = true;
 16464 }
 16465 
 16466 
 16467 foreach ($this->packagesToLoad as $name => $constraint) {
 16468 if (isset($this->loadedPackages[$name])) {
 16469 unset($this->packagesToLoad[$name]);
 16470 }
 16471 }
 16472 
 16473 while (!empty($this->packagesToLoad)) {
 16474 $this->loadPackagesMarkedForLoading($request, $repositories);
 16475 }
 16476 
 16477 foreach ($this->packages as $i => $package) {
 16478 
 16479 
 16480 if (!$package instanceof AliasPackage) {
 16481 $constraint = new Constraint('==', $package->getVersion());
 16482 $aliasedPackages = array($i => $package);
 16483 if (isset($this->aliasMap[spl_object_hash($package)])) {
 16484 $aliasedPackages += $this->aliasMap[spl_object_hash($package)];
 16485 }
 16486 
 16487 $found = false;
 16488 foreach ($aliasedPackages as $packageOrAlias) {
 16489 if (CompilingMatcher::match($constraint, Constraint::OP_EQ, $packageOrAlias->getVersion())) {
 16490 $found = true;
 16491 }
 16492 }
 16493 if (!$found) {
 16494 foreach ($aliasedPackages as $index => $packageOrAlias) {
 16495 unset($this->packages[$index]);
 16496 }
 16497 }
 16498 }
 16499 }
 16500 
 16501 if ($this->eventDispatcher) {
 16502 $prePoolCreateEvent = new PrePoolCreateEvent(
 16503 PluginEvents::PRE_POOL_CREATE,
 16504 $repositories,
 16505 $request,
 16506 $this->acceptableStabilities,
 16507 $this->stabilityFlags,
 16508 $this->rootAliases,
 16509 $this->rootReferences,
 16510 $this->packages,
 16511 $this->unacceptableFixedOrLockedPackages
 16512 );
 16513 $this->eventDispatcher->dispatch($prePoolCreateEvent->getName(), $prePoolCreateEvent);
 16514 $this->packages = $prePoolCreateEvent->getPackages();
 16515 $this->unacceptableFixedOrLockedPackages = $prePoolCreateEvent->getUnacceptableFixedPackages();
 16516 }
 16517 
 16518 $pool = new Pool($this->packages, $this->unacceptableFixedOrLockedPackages);
 16519 
 16520 $this->aliasMap = array();
 16521 $this->packagesToLoad = array();
 16522 $this->loadedPackages = array();
 16523 $this->loadedPerRepo = array();
 16524 $this->packages = array();
 16525 $this->unacceptableFixedOrLockedPackages = array();
 16526 $this->maxExtendedReqs = array();
 16527 $this->skippedLoad = array();
 16528 $this->indexCounter = 0;
 16529 
 16530 $pool = $this->runOptimizer($request, $pool);
 16531 
 16532 Intervals::clear();
 16533 
 16534 return $pool;
 16535 }
 16536 
 16537 
 16538 
 16539 
 16540 
 16541 private function markPackageNameForLoading(Request $request, $name, ConstraintInterface $constraint)
 16542 {
 16543 
 16544 if (PlatformRepository::isPlatformPackage($name)) {
 16545 return;
 16546 }
 16547 
 16548 
 16549 
 16550 if (isset($this->maxExtendedReqs[$name])) {
 16551 return;
 16552 }
 16553 
 16554 
 16555 
 16556 
 16557 
 16558 $rootRequires = $request->getRequires();
 16559 if (isset($rootRequires[$name]) && !Intervals::isSubsetOf($constraint, $rootRequires[$name])) {
 16560 $constraint = $rootRequires[$name];
 16561 }
 16562 
 16563 
 16564 if (!isset($this->loadedPackages[$name])) {
 16565 
 16566 
 16567 
 16568 if (isset($this->packagesToLoad[$name])) {
 16569 
 16570 if (Intervals::isSubsetOf($constraint, $this->packagesToLoad[$name])) {
 16571 return;
 16572 }
 16573 
 16574 
 16575 $constraint = Intervals::compactConstraint(MultiConstraint::create(array($this->packagesToLoad[$name], $constraint), false));
 16576 }
 16577 
 16578 $this->packagesToLoad[$name] = $constraint;
 16579 
 16580 return;
 16581 }
 16582 
 16583 
 16584 
 16585 if (Intervals::isSubsetOf($constraint, $this->loadedPackages[$name])) {
 16586 return;
 16587 }
 16588 
 16589 
 16590 
 16591 
 16592 $this->packagesToLoad[$name] = Intervals::compactConstraint(MultiConstraint::create(array($this->loadedPackages[$name], $constraint), false));
 16593 unset($this->loadedPackages[$name]);
 16594 }
 16595 
 16596 
 16597 
 16598 
 16599 
 16600 private function loadPackagesMarkedForLoading(Request $request, array $repositories)
 16601 {
 16602 foreach ($this->packagesToLoad as $name => $constraint) {
 16603 $this->loadedPackages[$name] = $constraint;
 16604 }
 16605 
 16606 $packageBatch = $this->packagesToLoad;
 16607 $this->packagesToLoad = array();
 16608 
 16609 foreach ($repositories as $repoIndex => $repository) {
 16610 if (empty($packageBatch)) {
 16611 break;
 16612 }
 16613 
 16614 
 16615 
 16616 if ($repository instanceof PlatformRepository || $repository === $request->getLockedRepository()) {
 16617 continue;
 16618 }
 16619 $result = $repository->loadPackages($packageBatch, $this->acceptableStabilities, $this->stabilityFlags, isset($this->loadedPerRepo[$repoIndex]) ? $this->loadedPerRepo[$repoIndex] : array());
 16620 
 16621 foreach ($result['namesFound'] as $name) {
 16622 
 16623 unset($packageBatch[$name]);
 16624 }
 16625 foreach ($result['packages'] as $package) {
 16626 $this->loadedPerRepo[$repoIndex][$package->getName()][$package->getVersion()] = $package;
 16627 $this->loadPackage($request, $repositories, $package, !isset($this->pathRepoUnlocked[$package->getName()]));
 16628 }
 16629 }
 16630 }
 16631 
 16632 
 16633 
 16634 
 16635 
 16636 
 16637 private function loadPackage(Request $request, array $repositories, BasePackage $package, $propagateUpdate)
 16638 {
 16639 $index = $this->indexCounter++;
 16640 $this->packages[$index] = $package;
 16641 
 16642 if ($package instanceof AliasPackage) {
 16643 $this->aliasMap[spl_object_hash($package->getAliasOf())][$index] = $package;
 16644 }
 16645 
 16646 $name = $package->getName();
 16647 
 16648 
 16649 
 16650 
 16651 if (isset($this->rootReferences[$name])) {
 16652 
 16653 if (!$request->isLockedPackage($package) && !$request->isFixedPackage($package)) {
 16654 $package->setSourceDistReferences($this->rootReferences[$name]);
 16655 }
 16656 }
 16657 
 16658 
 16659 
 16660 if ($propagateUpdate && isset($this->rootAliases[$name][$package->getVersion()])) {
 16661 $alias = $this->rootAliases[$name][$package->getVersion()];
 16662 if ($package instanceof AliasPackage) {
 16663 $basePackage = $package->getAliasOf();
 16664 } else {
 16665 $basePackage = $package;
 16666 }
 16667 if ($basePackage instanceof CompletePackage) {
 16668 $aliasPackage = new CompleteAliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']);
 16669 } else {
 16670 $aliasPackage = new AliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']);
 16671 }
 16672 $aliasPackage->setRootPackageAlias(true);
 16673 
 16674 $newIndex = $this->indexCounter++;
 16675 $this->packages[$newIndex] = $aliasPackage;
 16676 $this->aliasMap[spl_object_hash($aliasPackage->getAliasOf())][$newIndex] = $aliasPackage;
 16677 }
 16678 
 16679 foreach ($package->getRequires() as $link) {
 16680 $require = $link->getTarget();
 16681 $linkConstraint = $link->getConstraint();
 16682 
 16683 
 16684 if (isset($this->skippedLoad[$require])) {
 16685 
 16686 
 16687 
 16688 if ($propagateUpdate && $request->getUpdateAllowTransitiveDependencies()) {
 16689 $skippedRootRequires = $this->getSkippedRootRequires($request, $require);
 16690 
 16691 if ($request->getUpdateAllowTransitiveRootDependencies() || !$skippedRootRequires) {
 16692 $this->unlockPackage($request, $repositories, $require);
 16693 $this->markPackageNameForLoading($request, $require, $linkConstraint);
 16694 } else {
 16695 foreach ($skippedRootRequires as $rootRequire) {
 16696 if (!isset($this->updateAllowWarned[$rootRequire])) {
 16697 $this->updateAllowWarned[$rootRequire] = true;
 16698 $this->io->writeError('<warning>Dependency '.$rootRequire.' is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies (-W) to include root dependencies.</warning>');
 16699 }
 16700 }
 16701 }
 16702 } elseif (isset($this->pathRepoUnlocked[$require]) && !isset($this->loadedPackages[$require])) {
 16703 
 16704 
 16705 $this->markPackageNameForLoading($request, $require, $linkConstraint);
 16706 }
 16707 } else {
 16708 $this->markPackageNameForLoading($request, $require, $linkConstraint);
 16709 }
 16710 }
 16711 
 16712 
 16713 
 16714 if ($propagateUpdate && $request->getUpdateAllowTransitiveDependencies()) {
 16715 foreach ($package->getReplaces() as $link) {
 16716 $replace = $link->getTarget();
 16717 if (isset($this->loadedPackages[$replace], $this->skippedLoad[$replace])) {
 16718 $skippedRootRequires = $this->getSkippedRootRequires($request, $replace);
 16719 
 16720 if ($request->getUpdateAllowTransitiveRootDependencies() || !$skippedRootRequires) {
 16721 $this->unlockPackage($request, $repositories, $replace);
 16722 $this->markPackageNameForLoading($request, $replace, $link->getConstraint());
 16723 } else {
 16724 foreach ($skippedRootRequires as $rootRequire) {
 16725 if (!isset($this->updateAllowWarned[$rootRequire])) {
 16726 $this->updateAllowWarned[$rootRequire] = true;
 16727 $this->io->writeError('<warning>Dependency '.$rootRequire.' is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies (-W) to include root dependencies.</warning>');
 16728 }
 16729 }
 16730 }
 16731 }
 16732 }
 16733 }
 16734 }
 16735 
 16736 
 16737 
 16738 
 16739 
 16740 
 16741 
 16742 private function isRootRequire(Request $request, $name)
 16743 {
 16744 $rootRequires = $request->getRequires();
 16745 
 16746 return isset($rootRequires[$name]);
 16747 }
 16748 
 16749 
 16750 
 16751 
 16752 
 16753 private function getSkippedRootRequires(Request $request, $name)
 16754 {
 16755 if (!isset($this->skippedLoad[$name])) {
 16756 return array();
 16757 }
 16758 
 16759 $rootRequires = $request->getRequires();
 16760 $matches = array();
 16761 
 16762 if (isset($rootRequires[$name])) {
 16763 return array_map(function (PackageInterface $package) use ($name) {
 16764 if ($name !== $package->getName()) {
 16765 return $package->getName() .' (via replace of '.$name.')';
 16766 }
 16767 
 16768 return $package->getName();
 16769 }, $this->skippedLoad[$name]);
 16770 }
 16771 
 16772 foreach ($this->skippedLoad[$name] as $packageOrReplacer) {
 16773 if (isset($rootRequires[$packageOrReplacer->getName()])) {
 16774 $matches[] = $packageOrReplacer->getName();
 16775 }
 16776 foreach ($packageOrReplacer->getReplaces() as $link) {
 16777 if (isset($rootRequires[$link->getTarget()])) {
 16778 if ($name !== $packageOrReplacer->getName()) {
 16779 $matches[] = $packageOrReplacer->getName() .' (via replace of '.$name.')';
 16780 } else {
 16781 $matches[] = $packageOrReplacer->getName();
 16782 }
 16783 break;
 16784 }
 16785 }
 16786 }
 16787 
 16788 return $matches;
 16789 }
 16790 
 16791 
 16792 
 16793 
 16794 
 16795 
 16796 private function isUpdateAllowed(BasePackage $package)
 16797 {
 16798 foreach ($this->updateAllowList as $pattern => $void) {
 16799 $patternRegexp = BasePackage::packageNameToRegexp($pattern);
 16800 if (Preg::isMatch($patternRegexp, $package->getName())) {
 16801 return true;
 16802 }
 16803 }
 16804 
 16805 return false;
 16806 }
 16807 
 16808 
 16809 
 16810 
 16811 private function warnAboutNonMatchingUpdateAllowList(Request $request)
 16812 {
 16813 foreach ($this->updateAllowList as $pattern => $void) {
 16814 $patternRegexp = BasePackage::packageNameToRegexp($pattern);
 16815 
 16816 foreach ($request->getLockedRepository()->getPackages() as $package) {
 16817 if (Preg::isMatch($patternRegexp, $package->getName())) {
 16818 continue 2;
 16819 }
 16820 }
 16821 
 16822 foreach ($request->getRequires() as $packageName => $constraint) {
 16823 if (Preg::isMatch($patternRegexp, $packageName)) {
 16824 continue 2;
 16825 }
 16826 }
 16827 if (strpos($pattern, '*') !== false) {
 16828 $this->io->writeError('<warning>Pattern "' . $pattern . '" listed for update does not match any locked packages.</warning>');
 16829 } else {
 16830 $this->io->writeError('<warning>Package "' . $pattern . '" listed for update is not locked.</warning>');
 16831 }
 16832 }
 16833 }
 16834 
 16835 
 16836 
 16837 
 16838 
 16839 
 16840 
 16841 
 16842 
 16843 private function unlockPackage(Request $request, array $repositories, $name)
 16844 {
 16845 foreach ($this->skippedLoad[$name] as $packageOrReplacer) {
 16846 
 16847 
 16848 if ($packageOrReplacer->getName() !== $name && isset($this->skippedLoad[$packageOrReplacer->getName()])) {
 16849 $replacerName = $packageOrReplacer->getName();
 16850 if ($request->getUpdateAllowTransitiveRootDependencies() || (!$this->isRootRequire($request, $name) && !$this->isRootRequire($request, $replacerName))) {
 16851 $this->unlockPackage($request, $repositories, $replacerName);
 16852 
 16853 if ($this->isRootRequire($request, $replacerName)) {
 16854 $this->markPackageNameForLoading($request, $replacerName, new MatchAllConstraint);
 16855 } else {
 16856 foreach ($this->packages as $loadedPackage) {
 16857 $requires = $loadedPackage->getRequires();
 16858 if (isset($requires[$replacerName])) {
 16859 $this->markPackageNameForLoading($request, $replacerName, $requires[$replacerName]->getConstraint());
 16860 }
 16861 }
 16862 }
 16863 }
 16864 }
 16865 }
 16866 
 16867 if (isset($this->pathRepoUnlocked[$name])) {
 16868 foreach ($this->packages as $index => $package) {
 16869 if ($package->getName() === $name) {
 16870 $this->removeLoadedPackage($request, $repositories, $package, $index);
 16871 }
 16872 }
 16873 }
 16874 
 16875 unset($this->skippedLoad[$name], $this->loadedPackages[$name], $this->maxExtendedReqs[$name], $this->pathRepoUnlocked[$name]);
 16876 
 16877 
 16878 foreach ($request->getLockedPackages() as $lockedPackage) {
 16879 if (!($lockedPackage instanceof AliasPackage) && $lockedPackage->getName() === $name) {
 16880 if (false !== $index = array_search($lockedPackage, $this->packages, true)) {
 16881 $request->unlockPackage($lockedPackage);
 16882 $this->removeLoadedPackage($request, $repositories, $lockedPackage, $index);
 16883 
 16884 
 16885 
 16886 
 16887 foreach ($request->getFixedOrLockedPackages() as $fixedOrLockedPackage) {
 16888 if ($fixedOrLockedPackage === $lockedPackage) {
 16889 continue;
 16890 }
 16891 
 16892 if (isset($this->skippedLoad[$fixedOrLockedPackage->getName()])) {
 16893 $requires = $fixedOrLockedPackage->getRequires();
 16894 if (isset($requires[$lockedPackage->getName()])) {
 16895 $this->markPackageNameForLoading($request, $lockedPackage->getName(), $requires[$lockedPackage->getName()]->getConstraint());
 16896 }
 16897 }
 16898 }
 16899 }
 16900 }
 16901 }
 16902 }
 16903 
 16904 
 16905 
 16906 
 16907 
 16908 
 16909 private function removeLoadedPackage(Request $request, array $repositories, BasePackage $package, $index)
 16910 {
 16911 $repoIndex = array_search($package->getRepository(), $repositories, true);
 16912 
 16913 unset($this->loadedPerRepo[$repoIndex][$package->getName()][$package->getVersion()]);
 16914 unset($this->packages[$index]);
 16915 if (isset($this->aliasMap[spl_object_hash($package)])) {
 16916 foreach ($this->aliasMap[spl_object_hash($package)] as $aliasIndex => $aliasPackage) {
 16917 unset($this->loadedPerRepo[$repoIndex][$aliasPackage->getName()][$aliasPackage->getVersion()]);
 16918 unset($this->packages[$aliasIndex]);
 16919 }
 16920 unset($this->aliasMap[spl_object_hash($package)]);
 16921 }
 16922 }
 16923 
 16924 
 16925 
 16926 
 16927 private function runOptimizer(Request $request, Pool $pool)
 16928 {
 16929 if (null === $this->poolOptimizer) {
 16930 return $pool;
 16931 }
 16932 
 16933 $total = \count($pool->getPackages());
 16934 
 16935 $pool = $this->poolOptimizer->optimize($request, $pool);
 16936 
 16937 $filtered = $total - \count($pool->getPackages());
 16938 
 16939 if (0 === $filtered) {
 16940 return $pool;
 16941 }
 16942 
 16943 $this->io->write(sprintf(
 16944 '<info>Found %s package versions referenced in your dependency graph. %s (%d%%) were optimized away.</info>',
 16945 number_format($total),
 16946 number_format($filtered),
 16947 round(100/$total*$filtered)
 16948 ), true, IOInterface::VERY_VERBOSE);
 16949 
 16950 return $pool;
 16951 }
 16952 }
 16953 <?php
 16954 
 16955 
 16956 
 16957 
 16958 
 16959 
 16960 
 16961 
 16962 
 16963 
 16964 
 16965 namespace Composer\DependencyResolver;
 16966 
 16967 use Composer\Package\AliasPackage;
 16968 use Composer\Package\BasePackage;
 16969 use Composer\Package\Version\VersionParser;
 16970 use Composer\Semver\CompilingMatcher;
 16971 use Composer\Semver\Constraint\ConstraintInterface;
 16972 use Composer\Semver\Constraint\Constraint;
 16973 use Composer\Semver\Constraint\MultiConstraint;
 16974 use Composer\Semver\Intervals;
 16975 
 16976 
 16977 
 16978 
 16979 
 16980 
 16981 class PoolOptimizer
 16982 {
 16983 
 16984 
 16985 
 16986 private $policy;
 16987 
 16988 
 16989 
 16990 
 16991 private $irremovablePackages = array();
 16992 
 16993 
 16994 
 16995 
 16996 private $requireConstraintsPerPackage = array();
 16997 
 16998 
 16999 
 17000 
 17001 private $conflictConstraintsPerPackage = array();
 17002 
 17003 
 17004 
 17005 
 17006 private $packagesToRemove = array();
 17007 
 17008 
 17009 
 17010 
 17011 private $aliasesPerPackage = array();
 17012 
 17013 
 17014 
 17015 
 17016 private $removedVersionsByPackage = array();
 17017 
 17018 public function __construct(PolicyInterface $policy)
 17019 {
 17020 $this->policy = $policy;
 17021 }
 17022 
 17023 
 17024 
 17025 
 17026 public function optimize(Request $request, Pool $pool)
 17027 {
 17028 $this->prepare($request, $pool);
 17029 
 17030 $this->optimizeByIdenticalDependencies($request, $pool);
 17031 
 17032 $this->optimizeImpossiblePackagesAway($request, $pool);
 17033 
 17034 $optimizedPool = $this->applyRemovalsToPool($pool);
 17035 
 17036 
 17037 
 17038 
 17039 
 17040 
 17041 $this->irremovablePackages = array();
 17042 $this->requireConstraintsPerPackage = array();
 17043 $this->conflictConstraintsPerPackage = array();
 17044 $this->packagesToRemove = array();
 17045 $this->aliasesPerPackage = array();
 17046 $this->removedVersionsByPackage = array();
 17047 
 17048 return $optimizedPool;
 17049 }
 17050 
 17051 
 17052 
 17053 
 17054 private function prepare(Request $request, Pool $pool)
 17055 {
 17056 $irremovablePackageConstraintGroups = array();
 17057 
 17058 
 17059 foreach ($request->getFixedOrLockedPackages() as $package) {
 17060 $irremovablePackageConstraintGroups[$package->getName()][] = new Constraint('==', $package->getVersion());
 17061 }
 17062 
 17063 
 17064 foreach ($request->getRequires() as $require => $constraint) {
 17065 $this->extractRequireConstraintsPerPackage($require, $constraint);
 17066 }
 17067 
 17068 
 17069 foreach ($pool->getPackages() as $package) {
 17070 
 17071 foreach ($package->getRequires() as $link) {
 17072 $this->extractRequireConstraintsPerPackage($link->getTarget(), $link->getConstraint());
 17073 }
 17074 
 17075 foreach ($package->getConflicts() as $link) {
 17076 $this->extractConflictConstraintsPerPackage($link->getTarget(), $link->getConstraint());
 17077 }
 17078 
 17079 
 17080 
 17081 if ($package instanceof AliasPackage) {
 17082 $this->aliasesPerPackage[$package->getAliasOf()->id][] = $package;
 17083 }
 17084 }
 17085 
 17086 $irremovablePackageConstraints = array();
 17087 foreach ($irremovablePackageConstraintGroups as $packageName => $constraints) {
 17088 $irremovablePackageConstraints[$packageName] = 1 === \count($constraints) ? $constraints[0] : new MultiConstraint($constraints, false);
 17089 }
 17090 unset($irremovablePackageConstraintGroups);
 17091 
 17092 
 17093 foreach ($pool->getPackages() as $package) {
 17094 if (!isset($irremovablePackageConstraints[$package->getName()])) {
 17095 continue;
 17096 }
 17097 
 17098 if (CompilingMatcher::match($irremovablePackageConstraints[$package->getName()], Constraint::OP_EQ, $package->getVersion())) {
 17099 $this->markPackageIrremovable($package);
 17100 }
 17101 }
 17102 }
 17103 
 17104 
 17105 
 17106 
 17107 private function markPackageIrremovable(BasePackage $package)
 17108 {
 17109 $this->irremovablePackages[$package->id] = true;
 17110 if ($package instanceof AliasPackage) {
 17111 
 17112 
 17113 $this->markPackageIrremovable($package->getAliasOf());
 17114 }
 17115 if (isset($this->aliasesPerPackage[$package->id])) {
 17116 foreach ($this->aliasesPerPackage[$package->id] as $aliasPackage) {
 17117 $this->irremovablePackages[$aliasPackage->id] = true;
 17118 }
 17119 }
 17120 }
 17121 
 17122 
 17123 
 17124 
 17125 private function applyRemovalsToPool(Pool $pool)
 17126 {
 17127 $packages = array();
 17128 $removedVersions = array();
 17129 foreach ($pool->getPackages() as $package) {
 17130 if (!isset($this->packagesToRemove[$package->id])) {
 17131 $packages[] = $package;
 17132 } else {
 17133 $removedVersions[$package->getName()][$package->getVersion()] = $package->getPrettyVersion();
 17134 }
 17135 }
 17136 
 17137 $optimizedPool = new Pool($packages, $pool->getUnacceptableFixedOrLockedPackages(), $removedVersions, $this->removedVersionsByPackage);
 17138 
 17139 return $optimizedPool;
 17140 }
 17141 
 17142 
 17143 
 17144 
 17145 private function optimizeByIdenticalDependencies(Request $request, Pool $pool)
 17146 {
 17147 $identicalDefinitionsPerPackage = array();
 17148 $packageIdenticalDefinitionLookup = array();
 17149 
 17150 foreach ($pool->getPackages() as $package) {
 17151 
 17152 
 17153 
 17154 if (isset($this->irremovablePackages[$package->id])) {
 17155 continue;
 17156 }
 17157 
 17158 $this->markPackageForRemoval($package->id);
 17159 
 17160 $dependencyHash = $this->calculateDependencyHash($package);
 17161 
 17162 foreach ($package->getNames(false) as $packageName) {
 17163 
 17164 if (!isset($this->requireConstraintsPerPackage[$packageName])) {
 17165 continue;
 17166 }
 17167 
 17168 foreach ($this->requireConstraintsPerPackage[$packageName] as $requireConstraint) {
 17169 $groupHashParts = array();
 17170 
 17171 if (CompilingMatcher::match($requireConstraint, Constraint::OP_EQ, $package->getVersion())) {
 17172 $groupHashParts[] = 'require:' . (string) $requireConstraint;
 17173 }
 17174 
 17175 if ($package->getReplaces()) {
 17176 foreach ($package->getReplaces() as $link) {
 17177 if (CompilingMatcher::match($link->getConstraint(), Constraint::OP_EQ, $package->getVersion())) {
 17178 
 17179 $groupHashParts[] = 'require:' . (string) $link->getConstraint();
 17180 }
 17181 }
 17182 }
 17183 
 17184 if (isset($this->conflictConstraintsPerPackage[$packageName])) {
 17185 foreach ($this->conflictConstraintsPerPackage[$packageName] as $conflictConstraint) {
 17186 if (CompilingMatcher::match($conflictConstraint, Constraint::OP_EQ, $package->getVersion())) {
 17187 $groupHashParts[] = 'conflict:' . (string) $conflictConstraint;
 17188 }
 17189 }
 17190 }
 17191 
 17192 if (!$groupHashParts) {
 17193 continue;
 17194 }
 17195 
 17196 $groupHash = implode('', $groupHashParts);
 17197 $identicalDefinitionsPerPackage[$packageName][$groupHash][$dependencyHash][] = $package;
 17198 $packageIdenticalDefinitionLookup[$package->id][$packageName] = array('groupHash' => $groupHash, 'dependencyHash' => $dependencyHash);
 17199 }
 17200 }
 17201 }
 17202 
 17203 foreach ($identicalDefinitionsPerPackage as $constraintGroups) {
 17204 foreach ($constraintGroups as $constraintGroup) {
 17205 foreach ($constraintGroup as $packages) {
 17206 
 17207 if (1 === \count($packages)) {
 17208 $this->keepPackage($packages[0], $identicalDefinitionsPerPackage, $packageIdenticalDefinitionLookup);
 17209 continue;
 17210 }
 17211 
 17212 
 17213 
 17214 $literals = array();
 17215 
 17216 foreach ($packages as $package) {
 17217 $literals[] = $package->id;
 17218 }
 17219 
 17220 foreach ($this->policy->selectPreferredPackages($pool, $literals) as $preferredLiteral) {
 17221 $this->keepPackage($pool->literalToPackage($preferredLiteral), $identicalDefinitionsPerPackage, $packageIdenticalDefinitionLookup);
 17222 }
 17223 }
 17224 }
 17225 }
 17226 }
 17227 
 17228 
 17229 
 17230 
 17231 private function calculateDependencyHash(BasePackage $package)
 17232 {
 17233 $hash = '';
 17234 
 17235 $hashRelevantLinks = array(
 17236 'requires' => $package->getRequires(),
 17237 'conflicts' => $package->getConflicts(),
 17238 'replaces' => $package->getReplaces(),
 17239 'provides' => $package->getProvides()
 17240 );
 17241 
 17242 foreach ($hashRelevantLinks as $key => $links) {
 17243 if (0 === \count($links)) {
 17244 continue;
 17245 }
 17246 
 17247 
 17248 $hash .= $key . ':';
 17249 
 17250 $subhash = array();
 17251 
 17252 foreach ($links as $link) {
 17253 
 17254 
 17255 
 17256 
 17257 $subhash[$link->getTarget()] = (string) $link->getConstraint();
 17258 }
 17259 
 17260 
 17261 ksort($subhash);
 17262 
 17263 foreach ($subhash as $target => $constraint) {
 17264 $hash .= $target . '@' . $constraint;
 17265 }
 17266 }
 17267 
 17268 return $hash;
 17269 }
 17270 
 17271 
 17272 
 17273 
 17274 
 17275 private function markPackageForRemoval($id)
 17276 {
 17277 
 17278 if (isset($this->irremovablePackages[$id])) {
 17279 throw new \LogicException('Attempted removing a package which was previously marked irremovable');
 17280 }
 17281 
 17282 $this->packagesToRemove[$id] = true;
 17283 }
 17284 
 17285 
 17286 
 17287 
 17288 
 17289 
 17290 private function keepPackage(BasePackage $package, $identicalDefinitionsPerPackage, $packageIdenticalDefinitionLookup)
 17291 {
 17292 
 17293 if (!isset($this->packagesToRemove[$package->id])) {
 17294 return;
 17295 }
 17296 
 17297 unset($this->packagesToRemove[$package->id]);
 17298 
 17299 if ($package instanceof AliasPackage) {
 17300 
 17301 
 17302 $this->keepPackage($package->getAliasOf(), $identicalDefinitionsPerPackage, $packageIdenticalDefinitionLookup);
 17303 }
 17304 
 17305 
 17306 foreach ($package->getNames(false) as $name) {
 17307 if (isset($packageIdenticalDefinitionLookup[$package->id][$name])) {
 17308 $packageGroupPointers = $packageIdenticalDefinitionLookup[$package->id][$name];
 17309 $packageGroup = $identicalDefinitionsPerPackage[$name][$packageGroupPointers['groupHash']][$packageGroupPointers['dependencyHash']];
 17310 foreach ($packageGroup as $pkg) {
 17311 if ($pkg instanceof AliasPackage && $pkg->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 17312 $pkg = $pkg->getAliasOf();
 17313 }
 17314 $this->removedVersionsByPackage[spl_object_hash($package)][$pkg->getVersion()] = $pkg->getPrettyVersion();
 17315 }
 17316 }
 17317 }
 17318 
 17319 if (isset($this->aliasesPerPackage[$package->id])) {
 17320 foreach ($this->aliasesPerPackage[$package->id] as $aliasPackage) {
 17321 unset($this->packagesToRemove[$aliasPackage->id]);
 17322 
 17323 
 17324 foreach ($aliasPackage->getNames(false) as $name) {
 17325 if (isset($packageIdenticalDefinitionLookup[$aliasPackage->id][$name])) {
 17326 $packageGroupPointers = $packageIdenticalDefinitionLookup[$aliasPackage->id][$name];
 17327 $packageGroup = $identicalDefinitionsPerPackage[$name][$packageGroupPointers['groupHash']][$packageGroupPointers['dependencyHash']];
 17328 foreach ($packageGroup as $pkg) {
 17329 if ($pkg instanceof AliasPackage && $pkg->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 17330 $pkg = $pkg->getAliasOf();
 17331 }
 17332 $this->removedVersionsByPackage[spl_object_hash($aliasPackage)][$pkg->getVersion()] = $pkg->getPrettyVersion();
 17333 }
 17334 }
 17335 }
 17336 }
 17337 }
 17338 }
 17339 
 17340 
 17341 
 17342 
 17343 
 17344 
 17345 
 17346 
 17347 private function optimizeImpossiblePackagesAway(Request $request, Pool $pool)
 17348 {
 17349 if (count($request->getLockedPackages()) === 0) {
 17350 return;
 17351 }
 17352 
 17353 $packageIndex = array();
 17354 
 17355 foreach ($pool->getPackages() as $package) {
 17356 $id = $package->id;
 17357 
 17358 
 17359 if (isset($this->irremovablePackages[$id])) {
 17360 continue;
 17361 }
 17362 
 17363 if (isset($this->aliasesPerPackage[$id]) || $package instanceof AliasPackage) {
 17364 continue;
 17365 }
 17366 
 17367 if ($request->isFixedPackage($package) || $request->isLockedPackage($package)) {
 17368 continue;
 17369 }
 17370 
 17371 $packageIndex[$package->getName()][$package->id] = $package;
 17372 }
 17373 
 17374 foreach ($request->getLockedPackages() as $package) {
 17375 
 17376 
 17377 $isUnusedPackage = true;
 17378 foreach ($package->getNames(false) as $packageName) {
 17379 if (isset($this->requireConstraintsPerPackage[$packageName])) {
 17380 $isUnusedPackage = false;
 17381 break;
 17382 }
 17383 }
 17384 
 17385 if ($isUnusedPackage) {
 17386 continue;
 17387 }
 17388 
 17389 foreach ($package->getRequires() as $link) {
 17390 $require = $link->getTarget();
 17391 if (!isset($packageIndex[$require])) {
 17392 continue;
 17393 }
 17394 
 17395 $linkConstraint = $link->getConstraint();
 17396 foreach ($packageIndex[$require] as $id => $requiredPkg) {
 17397 if (false === CompilingMatcher::match($linkConstraint, Constraint::OP_EQ, $requiredPkg->getVersion())) {
 17398 $this->markPackageForRemoval($id);
 17399 unset($packageIndex[$require][$id]);
 17400 }
 17401 }
 17402 }
 17403 }
 17404 }
 17405 
 17406 
 17407 
 17408 
 17409 
 17410 
 17411 
 17412 
 17413 
 17414 
 17415 private function extractRequireConstraintsPerPackage($package, ConstraintInterface $constraint)
 17416 {
 17417 foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) {
 17418 $this->requireConstraintsPerPackage[$package][(string) $expanded] = $expanded;
 17419 }
 17420 }
 17421 
 17422 
 17423 
 17424 
 17425 
 17426 
 17427 
 17428 
 17429 
 17430 
 17431 private function extractConflictConstraintsPerPackage($package, ConstraintInterface $constraint)
 17432 {
 17433 foreach ($this->expandDisjunctiveMultiConstraints($constraint) as $expanded) {
 17434 $this->conflictConstraintsPerPackage[$package][(string) $expanded] = $expanded;
 17435 }
 17436 }
 17437 
 17438 
 17439 
 17440 
 17441 
 17442 
 17443 private function expandDisjunctiveMultiConstraints(ConstraintInterface $constraint)
 17444 {
 17445 $constraint = Intervals::compactConstraint($constraint);
 17446 
 17447 if ($constraint instanceof MultiConstraint && $constraint->isDisjunctive()) {
 17448 
 17449 
 17450 return $constraint->getConstraints();
 17451 }
 17452 
 17453 
 17454 return array($constraint);
 17455 }
 17456 }
 17457 <?php
 17458 
 17459 
 17460 
 17461 
 17462 
 17463 
 17464 
 17465 
 17466 
 17467 
 17468 
 17469 namespace Composer\DependencyResolver;
 17470 
 17471 use Composer\Package\CompletePackageInterface;
 17472 use Composer\Package\AliasPackage;
 17473 use Composer\Package\BasePackage;
 17474 use Composer\Package\Link;
 17475 use Composer\Package\PackageInterface;
 17476 use Composer\Package\RootPackageInterface;
 17477 use Composer\Pcre\Preg;
 17478 use Composer\Repository\RepositorySet;
 17479 use Composer\Repository\LockArrayRepository;
 17480 use Composer\Semver\Constraint\Constraint;
 17481 use Composer\Semver\Constraint\ConstraintInterface;
 17482 use Composer\Package\Version\VersionParser;
 17483 use Composer\Repository\PlatformRepository;
 17484 
 17485 
 17486 
 17487 
 17488 
 17489 
 17490 class Problem
 17491 {
 17492 
 17493 
 17494 
 17495 
 17496 protected $reasonSeen;
 17497 
 17498 
 17499 
 17500 
 17501 
 17502 protected $reasons = array();
 17503 
 17504 
 17505 protected $section = 0;
 17506 
 17507 
 17508 
 17509 
 17510 
 17511 
 17512 
 17513 public function addRule(Rule $rule)
 17514 {
 17515 $this->addReason(spl_object_hash($rule), $rule);
 17516 }
 17517 
 17518 
 17519 
 17520 
 17521 
 17522 
 17523 public function getReasons()
 17524 {
 17525 return $this->reasons;
 17526 }
 17527 
 17528 
 17529 
 17530 
 17531 
 17532 
 17533 
 17534 
 17535 
 17536 public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, array $installedMap = array(), array $learnedPool = array())
 17537 {
 17538 
 17539 $reasons = call_user_func_array('array_merge', array_reverse($this->reasons));
 17540 
 17541 if (count($reasons) === 1) {
 17542 reset($reasons);
 17543 $rule = current($reasons);
 17544 
 17545 if (!in_array($rule->getReason(), array(Rule::RULE_ROOT_REQUIRE, Rule::RULE_FIXED), true)) {
 17546 throw new \LogicException("Single reason problems must contain a request rule.");
 17547 }
 17548 
 17549 $reasonData = $rule->getReasonData();
 17550 $packageName = $reasonData['packageName'];
 17551 $constraint = $reasonData['constraint'];
 17552 
 17553 if (isset($constraint)) {
 17554 $packages = $pool->whatProvides($packageName, $constraint);
 17555 } else {
 17556 $packages = array();
 17557 }
 17558 
 17559 if (empty($packages)) {
 17560 return "\n    ".implode(self::getMissingPackageReason($repositorySet, $request, $pool, $isVerbose, $packageName, $constraint));
 17561 }
 17562 }
 17563 
 17564 return self::formatDeduplicatedRules($reasons, '    ', $repositorySet, $request, $pool, $isVerbose, $installedMap, $learnedPool);
 17565 }
 17566 
 17567 
 17568 
 17569 
 17570 
 17571 
 17572 
 17573 
 17574 
 17575 
 17576 public static function formatDeduplicatedRules($rules, $indent, RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, array $installedMap = array(), array $learnedPool = array())
 17577 {
 17578 $messages = array();
 17579 $templates = array();
 17580 $parser = new VersionParser;
 17581 $deduplicatableRuleTypes = array(Rule::RULE_PACKAGE_REQUIRES, Rule::RULE_PACKAGE_CONFLICT);
 17582 foreach ($rules as $rule) {
 17583 $message = $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose, $installedMap, $learnedPool);
 17584 if (in_array($rule->getReason(), $deduplicatableRuleTypes, true) && Preg::isMatch('{^(?P<package>\S+) (?P<version>\S+) (?P<type>requires|conflicts)}', $message, $m)) {
 17585 $template = Preg::replace('{^\S+ \S+ }', '%s%s ', $message);
 17586 $messages[] = $template;
 17587 $templates[$template][$m[1]][$parser->normalize($m[2])] = $m[2];
 17588 $sourcePackage = $rule->getSourcePackage($pool);
 17589 foreach ($pool->getRemovedVersionsByPackage(spl_object_hash($sourcePackage)) as $version => $prettyVersion) {
 17590 $templates[$template][$m[1]][$version] = $prettyVersion;
 17591 }
 17592 } elseif ($message !== '') {
 17593 $messages[] = $message;
 17594 }
 17595 }
 17596 
 17597 $result = array();
 17598 foreach (array_unique($messages) as $message) {
 17599 if (isset($templates[$message])) {
 17600 foreach ($templates[$message] as $package => $versions) {
 17601 uksort($versions, 'version_compare');
 17602 if (!$isVerbose) {
 17603 $versions = self::condenseVersionList($versions, 1);
 17604 }
 17605 if (count($versions) > 1) {
 17606 
 17607 $message = Preg::replace('{^(%s%s (?:require|conflict))s}', '$1', $message);
 17608 $result[] = sprintf($message, $package, '['.implode(', ', $versions).']');
 17609 } else {
 17610 $result[] = sprintf($message, $package, ' '.reset($versions));
 17611 }
 17612 }
 17613 } else {
 17614 $result[] = $message;
 17615 }
 17616 }
 17617 
 17618 return "\n$indent- ".implode("\n$indent- ", $result);
 17619 }
 17620 
 17621 
 17622 
 17623 
 17624 public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool)
 17625 {
 17626 foreach ($this->reasons as $sectionRules) {
 17627 foreach ($sectionRules as $rule) {
 17628 if ($rule->isCausedByLock($repositorySet, $request, $pool)) {
 17629 return true;
 17630 }
 17631 }
 17632 }
 17633 
 17634 return false;
 17635 }
 17636 
 17637 
 17638 
 17639 
 17640 
 17641 
 17642 
 17643 
 17644 protected function addReason($id, Rule $reason)
 17645 {
 17646 
 17647 
 17648 
 17649 if (!isset($this->reasonSeen[$id])) {
 17650 $this->reasonSeen[$id] = true;
 17651 $this->reasons[$this->section][] = $reason;
 17652 }
 17653 }
 17654 
 17655 
 17656 
 17657 
 17658 public function nextSection()
 17659 {
 17660 $this->section++;
 17661 }
 17662 
 17663 
 17664 
 17665 
 17666 
 17667 
 17668 
 17669 public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, $packageName, ConstraintInterface $constraint = null)
 17670 {
 17671 if (PlatformRepository::isPlatformPackage($packageName)) {
 17672 
 17673 if (0 === stripos($packageName, 'php') || $packageName === 'hhvm') {
 17674 $version = self::getPlatformPackageVersion($pool, $packageName, phpversion());
 17675 
 17676 $msg = "- Root composer.json requires ".$packageName.self::constraintToText($constraint).' but ';
 17677 
 17678 if (defined('HHVM_VERSION') || ($packageName === 'hhvm' && count($pool->whatProvides($packageName)) > 0)) {
 17679 return array($msg, 'your HHVM version does not satisfy that requirement.');
 17680 }
 17681 
 17682 if ($packageName === 'hhvm') {
 17683 return array($msg, 'HHVM was not detected on this machine, make sure it is in your PATH.');
 17684 }
 17685 
 17686 if (null === $version) {
 17687 return array($msg, 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".');
 17688 }
 17689 
 17690 return array($msg, 'your '.$packageName.' version ('. $version .') does not satisfy that requirement.');
 17691 }
 17692 
 17693 
 17694 if (0 === stripos($packageName, 'ext-')) {
 17695 if (false !== strpos($packageName, ' ')) {
 17696 return array('- ', "PHP extension ".$packageName.' should be required as '.str_replace(' ', '-', $packageName).'.');
 17697 }
 17698 
 17699 $ext = substr($packageName, 4);
 17700 $msg = "- Root composer.json requires PHP extension ".$packageName.self::constraintToText($constraint).' but ';
 17701 
 17702 $version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) ?: '0');
 17703 if (null === $version) {
 17704 if (extension_loaded($ext)) {
 17705 return array(
 17706 $msg,
 17707 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".',
 17708 );
 17709 }
 17710 
 17711 return array($msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.');
 17712 }
 17713 
 17714 return array($msg, 'it has the wrong version installed ('.$version.').');
 17715 }
 17716 
 17717 
 17718 if (0 === stripos($packageName, 'lib-')) {
 17719 if (strtolower($packageName) === 'lib-icu') {
 17720 $error = extension_loaded('intl') ? 'it has the wrong version installed, try upgrading the intl extension.' : 'it is missing from your system, make sure the intl extension is loaded.';
 17721 
 17722 return array("- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', $error);
 17723 }
 17724 
 17725 return array("- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.');
 17726 }
 17727 }
 17728 
 17729 $lockedPackage = null;
 17730 foreach ($request->getLockedPackages() as $package) {
 17731 if ($package->getName() === $packageName) {
 17732 $lockedPackage = $package;
 17733 if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
 17734 return array("- ", $package->getPrettyName().' is fixed to '.$package->getPrettyVersion().' (lock file version) by a partial update but that version is rejected by your minimum-stability. Make sure you list it as an argument for the update command.');
 17735 }
 17736 break;
 17737 }
 17738 }
 17739 
 17740 
 17741 
 17742 if ($packages = $repositorySet->findPackages($packageName, $constraint)) {
 17743 $rootReqs = $repositorySet->getRootRequires();
 17744 if (isset($rootReqs[$packageName])) {
 17745 $filtered = array_filter($packages, function ($p) use ($rootReqs, $packageName) {
 17746 return $rootReqs[$packageName]->matches(new Constraint('==', $p->getVersion()));
 17747 });
 17748 if (0 === count($filtered)) {
 17749 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these conflict' : 'it conflicts').' with your root composer.json require ('.$rootReqs[$packageName]->getPrettyString().').');
 17750 }
 17751 }
 17752 
 17753 if ($lockedPackage) {
 17754 $fixedConstraint = new Constraint('==', $lockedPackage->getVersion());
 17755 $filtered = array_filter($packages, function ($p) use ($fixedConstraint) {
 17756 return $fixedConstraint->matches(new Constraint('==', $p->getVersion()));
 17757 });
 17758 if (0 === count($filtered)) {
 17759 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but the package is fixed to '.$lockedPackage->getPrettyVersion().' (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.');
 17760 }
 17761 }
 17762 
 17763 $nonLockedPackages = array_filter($packages, function ($p) {
 17764 return !$p->getRepository() instanceof LockArrayRepository;
 17765 });
 17766 
 17767 if (!$nonLockedPackages) {
 17768 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.');
 17769 }
 17770 
 17771 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but these were not loaded, likely because '.(self::hasMultipleNames($packages) ? 'they conflict' : 'it conflicts').' with another require.');
 17772 }
 17773 
 17774 
 17775 if ($packages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) {
 17776 
 17777 if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
 17778 return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'minimum-stability', $constraint);
 17779 }
 17780 
 17781 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match your minimum-stability.');
 17782 }
 17783 
 17784 
 17785 if ($packages = $repositorySet->findPackages($packageName, null, RepositorySet::ALLOW_UNACCEPTABLE_STABILITIES)) {
 17786 
 17787 if ($allReposPackages = $repositorySet->findPackages($packageName, $constraint, RepositorySet::ALLOW_SHADOWED_REPOSITORIES)) {
 17788 return self::computeCheckForLowerPrioRepo($pool, $isVerbose, $packageName, $packages, $allReposPackages, 'constraint', $constraint);
 17789 }
 17790 
 17791 $suffix = '';
 17792 if ($constraint instanceof Constraint && $constraint->getVersion() === 'dev-master') {
 17793 foreach ($packages as $candidate) {
 17794 if (in_array($candidate->getVersion(), array('dev-default', 'dev-main'), true)) {
 17795 $suffix = ' Perhaps dev-master was renamed to '.$candidate->getPrettyVersion().'?';
 17796 break;
 17797 }
 17798 }
 17799 }
 17800 
 17801 
 17802 $allReposPackages = $packages;
 17803 $topPackage = reset($allReposPackages);
 17804 if ($topPackage instanceof RootPackageInterface) {
 17805 $suffix = ' See https://getcomposer.org/dep-on-root for details and assistance.';
 17806 }
 17807 
 17808 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose, $pool, $constraint).' but '.(self::hasMultipleNames($packages) ? 'these do' : 'it does').' not match the constraint.' . $suffix);
 17809 }
 17810 
 17811 if (!Preg::isMatch('{^[A-Za-z0-9_./-]+$}', $packageName)) {
 17812 $illegalChars = Preg::replace('{[A-Za-z0-9_./-]+}', '', $packageName);
 17813 
 17814 return array("- Root composer.json requires $packageName, it ", 'could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.');
 17815 }
 17816 
 17817 if ($providers = $repositorySet->getProviders($packageName)) {
 17818 $maxProviders = 20;
 17819 $providersStr = implode(array_map(function ($p) {
 17820 $description = $p['description'] ? ' '.substr($p['description'], 0, 100) : '';
 17821 
 17822 return "      - ${p['name']}".$description."\n";
 17823 }, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers));
 17824 if (count($providers) > $maxProviders + 1) {
 17825 $providersStr .= '      ... and '.(count($providers) - $maxProviders).' more.'."\n";
 17826 }
 17827 
 17828 return array("- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it:\n".$providersStr."      Consider requiring one of these to satisfy the $packageName requirement.");
 17829 }
 17830 
 17831 return array("- Root composer.json requires $packageName, it ", "could not be found in any version, there may be a typo in the package name.");
 17832 }
 17833 
 17834 
 17835 
 17836 
 17837 
 17838 
 17839 
 17840 
 17841 public static function getPackageList(array $packages, $isVerbose, Pool $pool = null, ConstraintInterface $constraint = null, $useRemovedVersionGroup = false)
 17842 {
 17843 $prepared = array();
 17844 $hasDefaultBranch = array();
 17845 foreach ($packages as $package) {
 17846 $prepared[$package->getName()]['name'] = $package->getPrettyName();
 17847 $prepared[$package->getName()]['versions'][$package->getVersion()] = $package->getPrettyVersion().($package instanceof AliasPackage ? ' (alias of '.$package->getAliasOf()->getPrettyVersion().')' : '');
 17848 if ($pool && $constraint) {
 17849 foreach ($pool->getRemovedVersions($package->getName(), $constraint) as $version => $prettyVersion) {
 17850 $prepared[$package->getName()]['versions'][$version] = $prettyVersion;
 17851 }
 17852 }
 17853 if ($pool && $useRemovedVersionGroup) {
 17854 foreach ($pool->getRemovedVersionsByPackage(spl_object_hash($package)) as $version => $prettyVersion) {
 17855 $prepared[$package->getName()]['versions'][$version] = $prettyVersion;
 17856 }
 17857 }
 17858 if ($package->isDefaultBranch()) {
 17859 $hasDefaultBranch[$package->getName()] = true;
 17860 }
 17861 }
 17862 
 17863 $preparedStrings = array();
 17864 foreach ($prepared as $name => $package) {
 17865 
 17866 if (isset($package['versions'][VersionParser::DEFAULT_BRANCH_ALIAS], $hasDefaultBranch[$name])) {
 17867 unset($package['versions'][VersionParser::DEFAULT_BRANCH_ALIAS]);
 17868 }
 17869 
 17870 uksort($package['versions'], 'version_compare');
 17871 
 17872 if (!$isVerbose) {
 17873 $package['versions'] = self::condenseVersionList($package['versions'], 4);
 17874 }
 17875 $preparedStrings[] = $package['name'].'['.implode(', ', $package['versions']).']';
 17876 }
 17877 
 17878 return implode(', ', $preparedStrings);
 17879 }
 17880 
 17881 
 17882 
 17883 
 17884 
 17885 
 17886 private static function getPlatformPackageVersion(Pool $pool, $packageName, $version)
 17887 {
 17888 $available = $pool->whatProvides($packageName);
 17889 
 17890 if (count($available)) {
 17891 $selected = null;
 17892 foreach ($available as $pkg) {
 17893 if ($pkg->getRepository() instanceof PlatformRepository) {
 17894 $selected = $pkg;
 17895 break;
 17896 }
 17897 }
 17898 if ($selected === null) {
 17899 $selected = reset($available);
 17900 }
 17901 
 17902 
 17903 if ($selected->getName() !== $packageName) {
 17904 
 17905 foreach (array_merge(array_values($selected->getProvides()), array_values($selected->getReplaces())) as $link) {
 17906 if ($link->getTarget() === $packageName) {
 17907 return $link->getPrettyConstraint().' '.substr($link->getDescription(), 0, -1).'d by '.$selected->getPrettyString();
 17908 }
 17909 }
 17910 }
 17911 
 17912 $version = $selected->getPrettyVersion();
 17913 $extra = $selected->getExtra();
 17914 if ($selected instanceof CompletePackageInterface && isset($extra['config.platform']) && $extra['config.platform'] === true) {
 17915 $version .= '; ' . str_replace('Package ', '', $selected->getDescription());
 17916 }
 17917 } else {
 17918 return null;
 17919 }
 17920 
 17921 return $version;
 17922 }
 17923 
 17924 
 17925 
 17926 
 17927 
 17928 
 17929 
 17930 private static function condenseVersionList(array $versions, $max, $maxDev = 16)
 17931 {
 17932 if (count($versions) <= $max) {
 17933 return $versions;
 17934 }
 17935 
 17936 $filtered = array();
 17937 $byMajor = array();
 17938 foreach ($versions as $version => $pretty) {
 17939 if (0 === stripos($version, 'dev-')) {
 17940 $byMajor['dev'][] = $pretty;
 17941 } else {
 17942 $byMajor[Preg::replace('{^(\d+)\..*}', '$1', $version)][] = $pretty;
 17943 }
 17944 }
 17945 foreach ($byMajor as $majorVersion => $versionsForMajor) {
 17946 $maxVersions = $majorVersion === 'dev' ? $maxDev : $max;
 17947 if (count($versionsForMajor) > $maxVersions) {
 17948 
 17949 $filtered[] = $versionsForMajor[0];
 17950 $filtered[] = '...';
 17951 $filtered[] = $versionsForMajor[count($versionsForMajor) - 1];
 17952 } else {
 17953 $filtered = array_merge($filtered, $versionsForMajor);
 17954 }
 17955 }
 17956 
 17957 return $filtered;
 17958 }
 17959 
 17960 
 17961 
 17962 
 17963 
 17964 private static function hasMultipleNames(array $packages)
 17965 {
 17966 $name = null;
 17967 foreach ($packages as $package) {
 17968 if ($name === null || $name === $package->getName()) {
 17969 $name = $package->getName();
 17970 } else {
 17971 return true;
 17972 }
 17973 }
 17974 
 17975 return false;
 17976 }
 17977 
 17978 
 17979 
 17980 
 17981 
 17982 
 17983 
 17984 
 17985 
 17986 private static function computeCheckForLowerPrioRepo(Pool $pool, $isVerbose, $packageName, array $higherRepoPackages, array $allReposPackages, $reason, ConstraintInterface $constraint = null)
 17987 {
 17988 $nextRepoPackages = array();
 17989 $nextRepo = null;
 17990 
 17991 foreach ($allReposPackages as $package) {
 17992 if ($nextRepo === null || $nextRepo === $package->getRepository()) {
 17993 $nextRepoPackages[] = $package;
 17994 $nextRepo = $package->getRepository();
 17995 } else {
 17996 break;
 17997 }
 17998 }
 17999 
 18000 if ($higherRepoPackages) {
 18001 $topPackage = reset($higherRepoPackages);
 18002 if ($topPackage instanceof RootPackageInterface) {
 18003 return array(
 18004 "- Root composer.json requires $packageName".self::constraintToText($constraint).', it is ',
 18005 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.$topPackage->getPrettyName().' is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.',
 18006 );
 18007 }
 18008 }
 18009 
 18010 if ($nextRepo instanceof LockArrayRepository) {
 18011 $singular = count($higherRepoPackages) === 1;
 18012 
 18013 $suggestion = 'Make sure you either fix the '.$reason.' or avoid updating this package to keep the one present in the lock file ('.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).').';
 18014 
 18015 if ($nextRepoPackages[0]->getDistType() === 'path') {
 18016 $transportOptions = $nextRepoPackages[0]->getTransportOptions();
 18017 if (!isset($transportOptions['symlink']) || $transportOptions['symlink'] !== false) {
 18018 $suggestion = 'Make sure you fix the '.$reason.' as packages installed from symlinked path repos are updated even in partial updates and the one from the lock file can thus not be used.';
 18019 }
 18020 }
 18021 
 18022 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ',
 18023 'found ' . self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' but ' . ($singular ? 'it does' : 'these do') . ' not match your '.$reason.' and ' . ($singular ? 'is' : 'are') . ' therefore not installable. '.$suggestion,
 18024 );
 18025 }
 18026 
 18027 return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose, $pool, $constraint).' from '.$nextRepo->getRepoName().' but '.self::getPackageList($higherRepoPackages, $isVerbose, $pool, $constraint).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' has higher repository priority. The packages from the higher priority repository do not match your '.$reason.' and are therefore not installable. That repository is canonical so the lower priority repo\'s packages are not installable. See https://getcomposer.org/repoprio for details and assistance.');
 18028 }
 18029 
 18030 
 18031 
 18032 
 18033 
 18034 
 18035 protected static function constraintToText(ConstraintInterface $constraint = null)
 18036 {
 18037 return $constraint ? ' '.$constraint->getPrettyString() : '';
 18038 }
 18039 }
 18040 <?php
 18041 
 18042 
 18043 
 18044 
 18045 
 18046 
 18047 
 18048 
 18049 
 18050 
 18051 
 18052 namespace Composer\DependencyResolver;
 18053 
 18054 use Composer\Package\BasePackage;
 18055 use Composer\Package\PackageInterface;
 18056 use Composer\Repository\LockArrayRepository;
 18057 use Composer\Semver\Constraint\ConstraintInterface;
 18058 use Composer\Semver\Constraint\MatchAllConstraint;
 18059 
 18060 
 18061 
 18062 
 18063 class Request
 18064 {
 18065 
 18066 
 18067 
 18068 const UPDATE_ONLY_LISTED = 0;
 18069 
 18070 
 18071 
 18072 
 18073 
 18074 const UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE = 1;
 18075 
 18076 
 18077 
 18078 
 18079 
 18080 const UPDATE_LISTED_WITH_TRANSITIVE_DEPS = 2;
 18081 
 18082 
 18083 protected $lockedRepository;
 18084 
 18085 protected $requires = array();
 18086 
 18087 protected $fixedPackages = array();
 18088 
 18089 protected $lockedPackages = array();
 18090 
 18091 protected $fixedLockedPackages = array();
 18092 
 18093 protected $updateAllowList = array();
 18094 
 18095 protected $updateAllowTransitiveDependencies = false;
 18096 
 18097 public function __construct(LockArrayRepository $lockedRepository = null)
 18098 {
 18099 $this->lockedRepository = $lockedRepository;
 18100 }
 18101 
 18102 
 18103 
 18104 
 18105 
 18106 public function requireName($packageName, ConstraintInterface $constraint = null)
 18107 {
 18108 $packageName = strtolower($packageName);
 18109 
 18110 if ($constraint === null) {
 18111 $constraint = new MatchAllConstraint();
 18112 }
 18113 if (isset($this->requires[$packageName])) {
 18114 throw new \LogicException('Overwriting requires seems like a bug ('.$packageName.' '.$this->requires[$packageName]->getPrettyString().' => '.$constraint->getPrettyString().', check why it is happening, might be a root alias');
 18115 }
 18116 $this->requires[$packageName] = $constraint;
 18117 }
 18118 
 18119 
 18120 
 18121 
 18122 
 18123 
 18124 
 18125 
 18126 
 18127 public function fixPackage(BasePackage $package)
 18128 {
 18129 $this->fixedPackages[spl_object_hash($package)] = $package;
 18130 }
 18131 
 18132 
 18133 
 18134 
 18135 
 18136 
 18137 
 18138 
 18139 
 18140 
 18141 
 18142 
 18143 
 18144 public function lockPackage(BasePackage $package)
 18145 {
 18146 $this->lockedPackages[spl_object_hash($package)] = $package;
 18147 }
 18148 
 18149 
 18150 
 18151 
 18152 
 18153 
 18154 
 18155 
 18156 
 18157 
 18158 public function fixLockedPackage(BasePackage $package)
 18159 {
 18160 $this->fixedPackages[spl_object_hash($package)] = $package;
 18161 $this->fixedLockedPackages[spl_object_hash($package)] = $package;
 18162 }
 18163 
 18164 
 18165 
 18166 
 18167 public function unlockPackage(BasePackage $package)
 18168 {
 18169 unset($this->lockedPackages[spl_object_hash($package)]);
 18170 }
 18171 
 18172 
 18173 
 18174 
 18175 
 18176 
 18177 public function setUpdateAllowList($updateAllowList, $updateAllowTransitiveDependencies)
 18178 {
 18179 $this->updateAllowList = $updateAllowList;
 18180 $this->updateAllowTransitiveDependencies = $updateAllowTransitiveDependencies;
 18181 }
 18182 
 18183 
 18184 
 18185 
 18186 public function getUpdateAllowList()
 18187 {
 18188 return $this->updateAllowList;
 18189 }
 18190 
 18191 
 18192 
 18193 
 18194 public function getUpdateAllowTransitiveDependencies()
 18195 {
 18196 return $this->updateAllowTransitiveDependencies !== self::UPDATE_ONLY_LISTED;
 18197 }
 18198 
 18199 
 18200 
 18201 
 18202 public function getUpdateAllowTransitiveRootDependencies()
 18203 {
 18204 return $this->updateAllowTransitiveDependencies === self::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
 18205 }
 18206 
 18207 
 18208 
 18209 
 18210 public function getRequires()
 18211 {
 18212 return $this->requires;
 18213 }
 18214 
 18215 
 18216 
 18217 
 18218 public function getFixedPackages()
 18219 {
 18220 return $this->fixedPackages;
 18221 }
 18222 
 18223 
 18224 
 18225 
 18226 public function isFixedPackage(BasePackage $package)
 18227 {
 18228 return isset($this->fixedPackages[spl_object_hash($package)]);
 18229 }
 18230 
 18231 
 18232 
 18233 
 18234 public function getLockedPackages()
 18235 {
 18236 return $this->lockedPackages;
 18237 }
 18238 
 18239 
 18240 
 18241 
 18242 public function isLockedPackage(PackageInterface $package)
 18243 {
 18244 return isset($this->lockedPackages[spl_object_hash($package)]) || isset($this->fixedLockedPackages[spl_object_hash($package)]);
 18245 }
 18246 
 18247 
 18248 
 18249 
 18250 public function getFixedOrLockedPackages()
 18251 {
 18252 return array_merge($this->fixedPackages, $this->lockedPackages);
 18253 }
 18254 
 18255 
 18256 
 18257 
 18258 
 18259 
 18260 
 18261 
 18262 
 18263 
 18264 public function getPresentMap($packageIds = false)
 18265 {
 18266 $presentMap = array();
 18267 
 18268 if ($this->lockedRepository) {
 18269 foreach ($this->lockedRepository->getPackages() as $package) {
 18270 $presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package;
 18271 }
 18272 }
 18273 
 18274 foreach ($this->fixedPackages as $package) {
 18275 $presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package;
 18276 }
 18277 
 18278 return $presentMap;
 18279 }
 18280 
 18281 
 18282 
 18283 
 18284 public function getFixedPackagesMap()
 18285 {
 18286 $fixedPackagesMap = array();
 18287 
 18288 foreach ($this->fixedPackages as $package) {
 18289 $fixedPackagesMap[$package->getId()] = $package;
 18290 }
 18291 
 18292 return $fixedPackagesMap;
 18293 }
 18294 
 18295 
 18296 
 18297 
 18298 public function getLockedRepository()
 18299 {
 18300 return $this->lockedRepository;
 18301 }
 18302 }
 18303 <?php
 18304 
 18305 
 18306 
 18307 
 18308 
 18309 
 18310 
 18311 
 18312 
 18313 
 18314 
 18315 namespace Composer\DependencyResolver;
 18316 
 18317 use Composer\Package\AliasPackage;
 18318 use Composer\Package\BasePackage;
 18319 use Composer\Package\Link;
 18320 use Composer\Repository\PlatformRepository;
 18321 use Composer\Repository\RepositorySet;
 18322 use Composer\Package\Version\VersionParser;
 18323 use Composer\Semver\Constraint\Constraint;
 18324 use Composer\Semver\Constraint\ConstraintInterface;
 18325 
 18326 
 18327 
 18328 
 18329 
 18330 
 18331 abstract class Rule
 18332 {
 18333 
 18334 const RULE_ROOT_REQUIRE = 2; 
 18335 const RULE_FIXED = 3; 
 18336 const RULE_PACKAGE_CONFLICT = 6; 
 18337 const RULE_PACKAGE_REQUIRES = 7; 
 18338 const RULE_PACKAGE_SAME_NAME = 10; 
 18339 const RULE_LEARNED = 12; 
 18340 const RULE_PACKAGE_ALIAS = 13; 
 18341 const RULE_PACKAGE_INVERSE_ALIAS = 14; 
 18342 
 18343 
 18344 const BITFIELD_TYPE = 0;
 18345 const BITFIELD_REASON = 8;
 18346 const BITFIELD_DISABLED = 16;
 18347 
 18348 
 18349 protected $bitfield;
 18350 
 18351 protected $request;
 18352 
 18353 
 18354 
 18355 
 18356 protected $reasonData;
 18357 
 18358 
 18359 
 18360 
 18361 
 18362 
 18363 
 18364 public function __construct($reason, $reasonData)
 18365 {
 18366 $this->reasonData = $reasonData;
 18367 
 18368 $this->bitfield = (0 << self::BITFIELD_DISABLED) |
 18369 ($reason << self::BITFIELD_REASON) |
 18370 (255 << self::BITFIELD_TYPE);
 18371 }
 18372 
 18373 
 18374 
 18375 
 18376 abstract public function getLiterals();
 18377 
 18378 
 18379 
 18380 
 18381 abstract public function getHash();
 18382 
 18383 abstract public function __toString();
 18384 
 18385 
 18386 
 18387 
 18388 
 18389 abstract public function equals(Rule $rule);
 18390 
 18391 
 18392 
 18393 
 18394 public function getReason()
 18395 {
 18396 return ($this->bitfield & (255 << self::BITFIELD_REASON)) >> self::BITFIELD_REASON;
 18397 }
 18398 
 18399 
 18400 
 18401 
 18402 public function getReasonData()
 18403 {
 18404 return $this->reasonData;
 18405 }
 18406 
 18407 
 18408 
 18409 
 18410 public function getRequiredPackage()
 18411 {
 18412 $reason = $this->getReason();
 18413 
 18414 if ($reason === self::RULE_ROOT_REQUIRE) {
 18415 return $this->reasonData['packageName'];
 18416 }
 18417 
 18418 if ($reason === self::RULE_FIXED) {
 18419 return $this->reasonData['package']->getName();
 18420 }
 18421 
 18422 if ($reason === self::RULE_PACKAGE_REQUIRES) {
 18423 return $this->reasonData->getTarget();
 18424 }
 18425 
 18426 return null;
 18427 }
 18428 
 18429 
 18430 
 18431 
 18432 
 18433 public function setType($type)
 18434 {
 18435 $this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_TYPE)) | ((255 & $type) << self::BITFIELD_TYPE);
 18436 }
 18437 
 18438 
 18439 
 18440 
 18441 public function getType()
 18442 {
 18443 return ($this->bitfield & (255 << self::BITFIELD_TYPE)) >> self::BITFIELD_TYPE;
 18444 }
 18445 
 18446 
 18447 
 18448 
 18449 public function disable()
 18450 {
 18451 $this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_DISABLED)) | (1 << self::BITFIELD_DISABLED);
 18452 }
 18453 
 18454 
 18455 
 18456 
 18457 public function enable()
 18458 {
 18459 $this->bitfield &= ~(255 << self::BITFIELD_DISABLED);
 18460 }
 18461 
 18462 
 18463 
 18464 
 18465 public function isDisabled()
 18466 {
 18467 return (bool) (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
 18468 }
 18469 
 18470 
 18471 
 18472 
 18473 public function isEnabled()
 18474 {
 18475 return !(($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
 18476 }
 18477 
 18478 
 18479 
 18480 
 18481 abstract public function isAssertion();
 18482 
 18483 
 18484 
 18485 
 18486 public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool)
 18487 {
 18488 if ($this->getReason() === self::RULE_PACKAGE_REQUIRES) {
 18489 if (PlatformRepository::isPlatformPackage($this->reasonData->getTarget())) {
 18490 return false;
 18491 }
 18492 if ($request->getLockedRepository()) {
 18493 foreach ($request->getLockedRepository()->getPackages() as $package) {
 18494 if ($package->getName() === $this->reasonData->getTarget()) {
 18495 if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
 18496 return true;
 18497 }
 18498 if (!$this->reasonData->getConstraint()->matches(new Constraint('=', $package->getVersion()))) {
 18499 return true;
 18500 }
 18501 
 18502 if (!$request->isLockedPackage($package)) {
 18503 return true;
 18504 }
 18505 break;
 18506 }
 18507 }
 18508 }
 18509 }
 18510 
 18511 if ($this->getReason() === self::RULE_ROOT_REQUIRE) {
 18512 if (PlatformRepository::isPlatformPackage($this->reasonData['packageName'])) {
 18513 return false;
 18514 }
 18515 if ($request->getLockedRepository()) {
 18516 foreach ($request->getLockedRepository()->getPackages() as $package) {
 18517 if ($package->getName() === $this->reasonData['packageName']) {
 18518 if ($pool->isUnacceptableFixedOrLockedPackage($package)) {
 18519 return true;
 18520 }
 18521 if (!$this->reasonData['constraint']->matches(new Constraint('=', $package->getVersion()))) {
 18522 return true;
 18523 }
 18524 break;
 18525 }
 18526 }
 18527 }
 18528 }
 18529 
 18530 return false;
 18531 }
 18532 
 18533 
 18534 
 18535 
 18536 
 18537 public function getSourcePackage(Pool $pool)
 18538 {
 18539 $literals = $this->getLiterals();
 18540 
 18541 switch ($this->getReason()) {
 18542 case self::RULE_PACKAGE_CONFLICT:
 18543 $package1 = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($literals[0]));
 18544 $package2 = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($literals[1]));
 18545 
 18546 if ($reasonData = $this->getReasonData()) {
 18547 
 18548 if ($reasonData->getSource() === $package1->getName()) {
 18549 list($package2, $package1) = array($package1, $package2);
 18550 }
 18551 }
 18552 
 18553 return $package2;
 18554 
 18555 case self::RULE_PACKAGE_REQUIRES:
 18556 $sourceLiteral = array_shift($literals);
 18557 $sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral));
 18558 
 18559 return $sourcePackage;
 18560 
 18561 default:
 18562 throw new \LogicException('Not implemented');
 18563 }
 18564 }
 18565 
 18566 
 18567 
 18568 
 18569 
 18570 
 18571 
 18572 
 18573 public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, array $installedMap = array(), array $learnedPool = array())
 18574 {
 18575 $literals = $this->getLiterals();
 18576 
 18577 switch ($this->getReason()) {
 18578 case self::RULE_ROOT_REQUIRE:
 18579 $packageName = $this->reasonData['packageName'];
 18580 $constraint = $this->reasonData['constraint'];
 18581 
 18582 $packages = $pool->whatProvides($packageName, $constraint);
 18583 if (!$packages) {
 18584 return 'No package found to satisfy root composer.json require '.$packageName.($constraint ? ' '.$constraint->getPrettyString() : '');
 18585 }
 18586 
 18587 $packagesNonAlias = array_values(array_filter($packages, function ($p) {
 18588 return !($p instanceof AliasPackage);
 18589 }));
 18590 if (count($packagesNonAlias) === 1) {
 18591 $package = $packagesNonAlias[0];
 18592 if ($request->isLockedPackage($package)) {
 18593 return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion()." and an update of this package was not requested.";
 18594 }
 18595 }
 18596 
 18597 return 'Root composer.json requires '.$packageName.($constraint ? ' '.$constraint->getPrettyString() : '').' -> satisfiable by '.$this->formatPackagesUnique($pool, $packages, $isVerbose, $constraint).'.';
 18598 
 18599 case self::RULE_FIXED:
 18600 $package = $this->deduplicateDefaultBranchAlias($this->reasonData['package']);
 18601 
 18602 if ($request->isLockedPackage($package)) {
 18603 return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion().' and an update of this package was not requested.';
 18604 }
 18605 
 18606 return $package->getPrettyName().' is present at version '.$package->getPrettyVersion() . ' and cannot be modified by Composer';
 18607 
 18608 case self::RULE_PACKAGE_CONFLICT:
 18609 $package1 = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($literals[0]));
 18610 $package2 = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($literals[1]));
 18611 
 18612 $conflictTarget = $package1->getPrettyString();
 18613 if ($reasonData = $this->getReasonData()) {
 18614 assert($reasonData instanceof Link);
 18615 
 18616 
 18617 if ($reasonData->getSource() === $package1->getName()) {
 18618 list($package2, $package1) = array($package1, $package2);
 18619 $conflictTarget = $package1->getPrettyName().' '.$reasonData->getPrettyConstraint();
 18620 }
 18621 
 18622 
 18623 
 18624 if ($reasonData->getTarget() !== $package1->getName()) {
 18625 $provideType = null;
 18626 $provided = null;
 18627 foreach ($package1->getProvides() as $provide) {
 18628 if ($provide->getTarget() === $reasonData->getTarget()) {
 18629 $provideType = 'provides';
 18630 $provided = $provide->getPrettyConstraint();
 18631 break;
 18632 }
 18633 }
 18634 foreach ($package1->getReplaces() as $replace) {
 18635 if ($replace->getTarget() === $reasonData->getTarget()) {
 18636 $provideType = 'replaces';
 18637 $provided = $replace->getPrettyConstraint();
 18638 break;
 18639 }
 18640 }
 18641 if (null !== $provideType) {
 18642 $conflictTarget = $reasonData->getTarget().' '.$reasonData->getPrettyConstraint().' ('.$package1->getPrettyString().' '.$provideType.' '.$reasonData->getTarget().' '.$provided.')';
 18643 }
 18644 }
 18645 }
 18646 
 18647 return $package2->getPrettyString().' conflicts with '.$conflictTarget.'.';
 18648 
 18649 case self::RULE_PACKAGE_REQUIRES:
 18650 $sourceLiteral = array_shift($literals);
 18651 $sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral));
 18652 
 18653 $reasonData = $this->reasonData;
 18654 
 18655 $requires = array();
 18656 foreach ($literals as $literal) {
 18657 $requires[] = $pool->literalToPackage($literal);
 18658 }
 18659 
 18660 $text = $reasonData->getPrettyString($sourcePackage);
 18661 if ($requires) {
 18662 $text .= ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $requires, $isVerbose, $this->reasonData->getConstraint()) . '.';
 18663 } else {
 18664 $targetName = $reasonData->getTarget();
 18665 
 18666 $reason = Problem::getMissingPackageReason($repositorySet, $request, $pool, $isVerbose, $targetName, $this->reasonData->getConstraint());
 18667 
 18668 return $text . ' -> ' . $reason[1];
 18669 }
 18670 
 18671 return $text;
 18672 
 18673 case self::RULE_PACKAGE_SAME_NAME:
 18674 $packageNames = array();
 18675 foreach ($literals as $literal) {
 18676 $package = $pool->literalToPackage($literal);
 18677 $packageNames[$package->getName()] = true;
 18678 }
 18679 $replacedName = $this->reasonData;
 18680 
 18681 if (count($packageNames) > 1) {
 18682 $reason = null;
 18683 
 18684 if (!isset($packageNames[$replacedName])) {
 18685 $reason = 'They '.(count($literals) == 2 ? 'both' : 'all').' replace '.$replacedName.' and thus cannot coexist.';
 18686 } else {
 18687 $replacerNames = $packageNames;
 18688 unset($replacerNames[$replacedName]);
 18689 $replacerNames = array_keys($replacerNames);
 18690 
 18691 if (count($replacerNames) == 1) {
 18692 $reason = $replacerNames[0] . ' replaces ';
 18693 } else {
 18694 $reason = '['.implode(', ', $replacerNames).'] replace ';
 18695 }
 18696 $reason .= $replacedName.' and thus cannot coexist with it.';
 18697 }
 18698 
 18699 $installedPackages = array();
 18700 $removablePackages = array();
 18701 foreach ($literals as $literal) {
 18702 if (isset($installedMap[abs($literal)])) {
 18703 $installedPackages[] = $pool->literalToPackage($literal);
 18704 } else {
 18705 $removablePackages[] = $pool->literalToPackage($literal);
 18706 }
 18707 }
 18708 
 18709 if ($installedPackages && $removablePackages) {
 18710 return $this->formatPackagesUnique($pool, $removablePackages, $isVerbose, null, true).' cannot be installed as that would require removing '.$this->formatPackagesUnique($pool, $installedPackages, $isVerbose, null, true).'. '.$reason;
 18711 }
 18712 
 18713 return 'Only one of these can be installed: '.$this->formatPackagesUnique($pool, $literals, $isVerbose, null, true).'. '.$reason;
 18714 }
 18715 
 18716 return 'You can only install one version of a package, so only one of these can be installed: ' . $this->formatPackagesUnique($pool, $literals, $isVerbose, null, true) . '.';
 18717 case self::RULE_LEARNED:
 18718 
 18719 
 18720 
 18721 
 18722 
 18723 
 18724 
 18725 $learnedString = ' (conflict analysis result)';
 18726 
 18727 if (count($literals) === 1) {
 18728 $ruleText = $pool->literalToPrettyString($literals[0], $installedMap);
 18729 } else {
 18730 $groups = array();
 18731 foreach ($literals as $literal) {
 18732 $package = $pool->literalToPackage($literal);
 18733 if (isset($installedMap[$package->id])) {
 18734 $group = $literal > 0 ? 'keep' : 'remove';
 18735 } else {
 18736 $group = $literal > 0 ? 'install' : 'don\'t install';
 18737 }
 18738 
 18739 $groups[$group][] = $this->deduplicateDefaultBranchAlias($package);
 18740 }
 18741 $ruleTexts = array();
 18742 foreach ($groups as $group => $packages) {
 18743 $ruleTexts[] = $group . (count($packages) > 1 ? ' one of' : '').' ' . $this->formatPackagesUnique($pool, $packages, $isVerbose);
 18744 }
 18745 
 18746 $ruleText = implode(' | ', $ruleTexts);
 18747 }
 18748 
 18749 return 'Conclusion: '.$ruleText.$learnedString;
 18750 case self::RULE_PACKAGE_ALIAS:
 18751 $aliasPackage = $pool->literalToPackage($literals[0]);
 18752 
 18753 
 18754 if ($aliasPackage->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 18755 return '';
 18756 }
 18757 $package = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($literals[1]));
 18758 
 18759 return $aliasPackage->getPrettyString() .' is an alias of '.$package->getPrettyString().' and thus requires it to be installed too.';
 18760 case self::RULE_PACKAGE_INVERSE_ALIAS:
 18761 
 18762 $aliasPackage = $pool->literalToPackage($literals[1]);
 18763 
 18764 
 18765 if ($aliasPackage->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 18766 return '';
 18767 }
 18768 $package = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($literals[0]));
 18769 
 18770 return $aliasPackage->getPrettyString() .' is an alias of '.$package->getPrettyString().' and must be installed with it.';
 18771 default:
 18772 $ruleText = '';
 18773 foreach ($literals as $i => $literal) {
 18774 if ($i != 0) {
 18775 $ruleText .= '|';
 18776 }
 18777 $ruleText .= $pool->literalToPrettyString($literal, $installedMap);
 18778 }
 18779 
 18780 return '('.$ruleText.')';
 18781 }
 18782 }
 18783 
 18784 
 18785 
 18786 
 18787 
 18788 
 18789 
 18790 protected function formatPackagesUnique(Pool $pool, array $packages, $isVerbose, ConstraintInterface $constraint = null, $useRemovedVersionGroup = false)
 18791 {
 18792 foreach ($packages as $index => $package) {
 18793 if (!\is_object($package)) {
 18794 $packages[$index] = $pool->literalToPackage($package);
 18795 }
 18796 }
 18797 
 18798 return Problem::getPackageList($packages, $isVerbose, $pool, $constraint, $useRemovedVersionGroup);
 18799 }
 18800 
 18801 
 18802 
 18803 
 18804 private function deduplicateDefaultBranchAlias(BasePackage $package)
 18805 {
 18806 if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 18807 $package = $package->getAliasOf();
 18808 }
 18809 
 18810 return $package;
 18811 }
 18812 }
 18813 <?php
 18814 
 18815 
 18816 
 18817 
 18818 
 18819 
 18820 
 18821 
 18822 
 18823 
 18824 
 18825 namespace Composer\DependencyResolver;
 18826 
 18827 
 18828 
 18829 
 18830 
 18831 class Rule2Literals extends Rule
 18832 {
 18833 
 18834 protected $literal1;
 18835 
 18836 protected $literal2;
 18837 
 18838 
 18839 
 18840 
 18841 
 18842 
 18843 
 18844 
 18845 
 18846 public function __construct($literal1, $literal2, $reason, $reasonData)
 18847 {
 18848 parent::__construct($reason, $reasonData);
 18849 
 18850 if ($literal1 < $literal2) {
 18851 $this->literal1 = $literal1;
 18852 $this->literal2 = $literal2;
 18853 } else {
 18854 $this->literal1 = $literal2;
 18855 $this->literal2 = $literal1;
 18856 }
 18857 }
 18858 
 18859 
 18860 public function getLiterals()
 18861 {
 18862 return array($this->literal1, $this->literal2);
 18863 }
 18864 
 18865 
 18866 
 18867 
 18868 public function getHash()
 18869 {
 18870 return $this->literal1.','.$this->literal2;
 18871 }
 18872 
 18873 
 18874 
 18875 
 18876 
 18877 
 18878 
 18879 
 18880 
 18881 public function equals(Rule $rule)
 18882 {
 18883 
 18884 if ($rule instanceof self) {
 18885 if ($this->literal1 !== $rule->literal1) {
 18886 return false;
 18887 }
 18888 
 18889 if ($this->literal2 !== $rule->literal2) {
 18890 return false;
 18891 }
 18892 
 18893 return true;
 18894 }
 18895 
 18896 $literals = $rule->getLiterals();
 18897 if (2 != \count($literals)) {
 18898 return false;
 18899 }
 18900 
 18901 if ($this->literal1 !== $literals[0]) {
 18902 return false;
 18903 }
 18904 
 18905 if ($this->literal2 !== $literals[1]) {
 18906 return false;
 18907 }
 18908 
 18909 return true;
 18910 }
 18911 
 18912 
 18913 public function isAssertion()
 18914 {
 18915 return false;
 18916 }
 18917 
 18918 
 18919 
 18920 
 18921 
 18922 
 18923 public function __toString()
 18924 {
 18925 $result = $this->isDisabled() ? 'disabled(' : '(';
 18926 
 18927 $result .= $this->literal1 . '|' . $this->literal2 . ')';
 18928 
 18929 return $result;
 18930 }
 18931 }
 18932 <?php
 18933 
 18934 
 18935 
 18936 
 18937 
 18938 
 18939 
 18940 
 18941 
 18942 
 18943 
 18944 namespace Composer\DependencyResolver;
 18945 
 18946 use Composer\Repository\RepositorySet;
 18947 
 18948 
 18949 
 18950 
 18951 
 18952 class RuleSet implements \IteratorAggregate, \Countable
 18953 {
 18954 
 18955 const TYPE_PACKAGE = 0;
 18956 const TYPE_REQUEST = 1;
 18957 const TYPE_LEARNED = 4;
 18958 
 18959 
 18960 
 18961 
 18962 
 18963 
 18964 public $ruleById = array();
 18965 
 18966 
 18967 protected static $types = array(
 18968 self::TYPE_PACKAGE => 'PACKAGE',
 18969 self::TYPE_REQUEST => 'REQUEST',
 18970 self::TYPE_LEARNED => 'LEARNED',
 18971 );
 18972 
 18973 
 18974 protected $rules;
 18975 
 18976 
 18977 protected $nextRuleId = 0;
 18978 
 18979 
 18980 protected $rulesByHash = array();
 18981 
 18982 public function __construct()
 18983 {
 18984 foreach ($this->getTypes() as $type) {
 18985 $this->rules[$type] = array();
 18986 }
 18987 }
 18988 
 18989 
 18990 
 18991 
 18992 
 18993 public function add(Rule $rule, $type)
 18994 {
 18995 if (!isset(self::$types[$type])) {
 18996 throw new \OutOfBoundsException('Unknown rule type: ' . $type);
 18997 }
 18998 
 18999 $hash = $rule->getHash();
 19000 
 19001 
 19002 if (isset($this->rulesByHash[$hash])) {
 19003 $potentialDuplicates = $this->rulesByHash[$hash];
 19004 if (\is_array($potentialDuplicates)) {
 19005 foreach ($potentialDuplicates as $potentialDuplicate) {
 19006 if ($rule->equals($potentialDuplicate)) {
 19007 return;
 19008 }
 19009 }
 19010 } else {
 19011 if ($rule->equals($potentialDuplicates)) {
 19012 return;
 19013 }
 19014 }
 19015 }
 19016 
 19017 if (!isset($this->rules[$type])) {
 19018 $this->rules[$type] = array();
 19019 }
 19020 
 19021 $this->rules[$type][] = $rule;
 19022 $this->ruleById[$this->nextRuleId] = $rule;
 19023 $rule->setType($type);
 19024 
 19025 $this->nextRuleId++;
 19026 
 19027 if (!isset($this->rulesByHash[$hash])) {
 19028 $this->rulesByHash[$hash] = $rule;
 19029 } elseif (\is_array($this->rulesByHash[$hash])) {
 19030 $this->rulesByHash[$hash][] = $rule;
 19031 } else {
 19032 $originalRule = $this->rulesByHash[$hash];
 19033 $this->rulesByHash[$hash] = array($originalRule, $rule);
 19034 }
 19035 }
 19036 
 19037 
 19038 
 19039 
 19040 #[\ReturnTypeWillChange]
 19041 public function count()
 19042 {
 19043 return $this->nextRuleId;
 19044 }
 19045 
 19046 
 19047 
 19048 
 19049 
 19050 public function ruleById($id)
 19051 {
 19052 return $this->ruleById[$id];
 19053 }
 19054 
 19055 
 19056 public function getRules()
 19057 {
 19058 return $this->rules;
 19059 }
 19060 
 19061 
 19062 
 19063 
 19064 #[\ReturnTypeWillChange]
 19065 public function getIterator()
 19066 {
 19067 return new RuleSetIterator($this->getRules());
 19068 }
 19069 
 19070 
 19071 
 19072 
 19073 
 19074 public function getIteratorFor($types)
 19075 {
 19076 if (!\is_array($types)) {
 19077 $types = array($types);
 19078 }
 19079 
 19080 $allRules = $this->getRules();
 19081 
 19082 
 19083 $rules = array();
 19084 
 19085 foreach ($types as $type) {
 19086 $rules[$type] = $allRules[$type];
 19087 }
 19088 
 19089 return new RuleSetIterator($rules);
 19090 }
 19091 
 19092 
 19093 
 19094 
 19095 
 19096 public function getIteratorWithout($types)
 19097 {
 19098 if (!\is_array($types)) {
 19099 $types = array($types);
 19100 }
 19101 
 19102 $rules = $this->getRules();
 19103 
 19104 foreach ($types as $type) {
 19105 unset($rules[$type]);
 19106 }
 19107 
 19108 return new RuleSetIterator($rules);
 19109 }
 19110 
 19111 
 19112 public function getTypes()
 19113 {
 19114 $types = self::$types;
 19115 
 19116 return array_keys($types);
 19117 }
 19118 
 19119 
 19120 
 19121 
 19122 
 19123 public function getPrettyString(RepositorySet $repositorySet = null, Request $request = null, Pool $pool = null, $isVerbose = false)
 19124 {
 19125 $string = "\n";
 19126 foreach ($this->rules as $type => $rules) {
 19127 $string .= str_pad(self::$types[$type], 8, ' ') . ": ";
 19128 foreach ($rules as $rule) {
 19129 $string .= ($repositorySet && $request && $pool ? $rule->getPrettyString($repositorySet, $request, $pool, $isVerbose) : $rule)."\n";
 19130 }
 19131 $string .= "\n\n";
 19132 }
 19133 
 19134 return $string;
 19135 }
 19136 
 19137 public function __toString()
 19138 {
 19139 return $this->getPrettyString();
 19140 }
 19141 }
 19142 <?php
 19143 
 19144 
 19145 
 19146 
 19147 
 19148 
 19149 
 19150 
 19151 
 19152 
 19153 
 19154 namespace Composer\DependencyResolver;
 19155 
 19156 use Composer\Filter\PlatformRequirementFilter\IgnoreListPlatformRequirementFilter;
 19157 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
 19158 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterInterface;
 19159 use Composer\Package\BasePackage;
 19160 use Composer\Package\AliasPackage;
 19161 use Composer\Repository\PlatformRepository;
 19162 
 19163 
 19164 
 19165 
 19166 
 19167 class RuleSetGenerator
 19168 {
 19169 
 19170 protected $policy;
 19171 
 19172 protected $pool;
 19173 
 19174 protected $rules;
 19175 
 19176 protected $addedMap = array();
 19177 
 19178 protected $addedPackagesByNames = array();
 19179 
 19180 public function __construct(PolicyInterface $policy, Pool $pool)
 19181 {
 19182 $this->policy = $policy;
 19183 $this->pool = $pool;
 19184 $this->rules = new RuleSet;
 19185 }
 19186 
 19187 
 19188 
 19189 
 19190 
 19191 
 19192 
 19193 
 19194 
 19195 
 19196 
 19197 
 19198 
 19199 
 19200 
 19201 protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData = null)
 19202 {
 19203 $literals = array(-$package->id);
 19204 
 19205 foreach ($providers as $provider) {
 19206 
 19207 if ($provider === $package) {
 19208 return null;
 19209 }
 19210 $literals[] = $provider->id;
 19211 }
 19212 
 19213 return new GenericRule($literals, $reason, $reasonData);
 19214 }
 19215 
 19216 
 19217 
 19218 
 19219 
 19220 
 19221 
 19222 
 19223 
 19224 
 19225 
 19226 
 19227 
 19228 
 19229 
 19230 protected function createInstallOneOfRule(array $packages, $reason, $reasonData)
 19231 {
 19232 $literals = array();
 19233 foreach ($packages as $package) {
 19234 $literals[] = $package->id;
 19235 }
 19236 
 19237 return new GenericRule($literals, $reason, $reasonData);
 19238 }
 19239 
 19240 
 19241 
 19242 
 19243 
 19244 
 19245 
 19246 
 19247 
 19248 
 19249 
 19250 
 19251 
 19252 
 19253 
 19254 protected function createRule2Literals(BasePackage $issuer, BasePackage $provider, $reason, $reasonData = null)
 19255 {
 19256 
 19257 if ($issuer === $provider) {
 19258 return null;
 19259 }
 19260 
 19261 return new Rule2Literals(-$issuer->id, -$provider->id, $reason, $reasonData);
 19262 }
 19263 
 19264 
 19265 
 19266 
 19267 
 19268 
 19269 
 19270 
 19271 
 19272 protected function createMultiConflictRule(array $packages, $reason, $reasonData)
 19273 {
 19274 $literals = array();
 19275 foreach ($packages as $package) {
 19276 $literals[] = -$package->id;
 19277 }
 19278 
 19279 if (\count($literals) == 2) {
 19280 return new Rule2Literals($literals[0], $literals[1], $reason, $reasonData);
 19281 }
 19282 
 19283 return new MultiConflictRule($literals, $reason, $reasonData);
 19284 }
 19285 
 19286 
 19287 
 19288 
 19289 
 19290 
 19291 
 19292 
 19293 
 19294 
 19295 
 19296 
 19297 private function addRule($type, Rule $newRule = null)
 19298 {
 19299 if (!$newRule) {
 19300 return;
 19301 }
 19302 
 19303 $this->rules->add($newRule, $type);
 19304 }
 19305 
 19306 
 19307 
 19308 
 19309 protected function addRulesForPackage(BasePackage $package, PlatformRequirementFilterInterface $platformRequirementFilter)
 19310 {
 19311 
 19312 $workQueue = new \SplQueue;
 19313 $workQueue->enqueue($package);
 19314 
 19315 while (!$workQueue->isEmpty()) {
 19316 $package = $workQueue->dequeue();
 19317 if (isset($this->addedMap[$package->id])) {
 19318 continue;
 19319 }
 19320 
 19321 $this->addedMap[$package->id] = $package;
 19322 
 19323 if (!$package instanceof AliasPackage) {
 19324 foreach ($package->getNames(false) as $name) {
 19325 $this->addedPackagesByNames[$name][] = $package;
 19326 }
 19327 } else {
 19328 $workQueue->enqueue($package->getAliasOf());
 19329 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package, array($package->getAliasOf()), Rule::RULE_PACKAGE_ALIAS, $package));
 19330 
 19331 
 19332 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package->getAliasOf(), array($package), Rule::RULE_PACKAGE_INVERSE_ALIAS, $package->getAliasOf()));
 19333 
 19334 
 19335 
 19336 if (!$package->hasSelfVersionRequires()) {
 19337 continue;
 19338 }
 19339 }
 19340 
 19341 foreach ($package->getRequires() as $link) {
 19342 $constraint = $link->getConstraint();
 19343 if ($platformRequirementFilter->isIgnored($link->getTarget())) {
 19344 continue;
 19345 } elseif ($platformRequirementFilter instanceof IgnoreListPlatformRequirementFilter) {
 19346 $constraint = $platformRequirementFilter->filterConstraint($link->getTarget(), $constraint);
 19347 }
 19348 
 19349 $possibleRequires = $this->pool->whatProvides($link->getTarget(), $constraint);
 19350 
 19351 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package, $possibleRequires, Rule::RULE_PACKAGE_REQUIRES, $link));
 19352 
 19353 foreach ($possibleRequires as $require) {
 19354 $workQueue->enqueue($require);
 19355 }
 19356 }
 19357 }
 19358 }
 19359 
 19360 
 19361 
 19362 
 19363 protected function addConflictRules(PlatformRequirementFilterInterface $platformRequirementFilter)
 19364 {
 19365 
 19366 foreach ($this->addedMap as $package) {
 19367 foreach ($package->getConflicts() as $link) {
 19368 
 19369 if (!isset($this->addedPackagesByNames[$link->getTarget()])) {
 19370 continue;
 19371 }
 19372 
 19373 $constraint = $link->getConstraint();
 19374 if ($platformRequirementFilter->isIgnored($link->getTarget())) {
 19375 continue;
 19376 } elseif ($platformRequirementFilter instanceof IgnoreListPlatformRequirementFilter) {
 19377 $constraint = $platformRequirementFilter->filterConstraint($link->getTarget(), $constraint);
 19378 }
 19379 
 19380 $conflicts = $this->pool->whatProvides($link->getTarget(), $constraint);
 19381 
 19382 foreach ($conflicts as $conflict) {
 19383 
 19384 
 19385 
 19386 if (!$conflict instanceof AliasPackage || $conflict->getName() === $link->getTarget()) {
 19387 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRule2Literals($package, $conflict, Rule::RULE_PACKAGE_CONFLICT, $link));
 19388 }
 19389 }
 19390 }
 19391 }
 19392 
 19393 foreach ($this->addedPackagesByNames as $name => $packages) {
 19394 if (\count($packages) > 1) {
 19395 $reason = Rule::RULE_PACKAGE_SAME_NAME;
 19396 $this->addRule(RuleSet::TYPE_PACKAGE, $this->createMultiConflictRule($packages, $reason, $name));
 19397 }
 19398 }
 19399 }
 19400 
 19401 
 19402 
 19403 
 19404 protected function addRulesForRequest(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter)
 19405 {
 19406 foreach ($request->getFixedPackages() as $package) {
 19407 if ($package->id == -1) {
 19408 
 19409 if ($this->pool->isUnacceptableFixedOrLockedPackage($package)) {
 19410 continue;
 19411 }
 19412 
 19413 
 19414 throw new \LogicException("Fixed package ".$package->getPrettyString()." was not added to solver pool.");
 19415 }
 19416 
 19417 $this->addRulesForPackage($package, $platformRequirementFilter);
 19418 
 19419 $rule = $this->createInstallOneOfRule(array($package), Rule::RULE_FIXED, array(
 19420 'package' => $package,
 19421 ));
 19422 $this->addRule(RuleSet::TYPE_REQUEST, $rule);
 19423 }
 19424 
 19425 foreach ($request->getRequires() as $packageName => $constraint) {
 19426 if ($platformRequirementFilter->isIgnored($packageName)) {
 19427 continue;
 19428 } elseif ($platformRequirementFilter instanceof IgnoreListPlatformRequirementFilter) {
 19429 $constraint = $platformRequirementFilter->filterConstraint($packageName, $constraint);
 19430 }
 19431 
 19432 $packages = $this->pool->whatProvides($packageName, $constraint);
 19433 if ($packages) {
 19434 foreach ($packages as $package) {
 19435 $this->addRulesForPackage($package, $platformRequirementFilter);
 19436 }
 19437 
 19438 $rule = $this->createInstallOneOfRule($packages, Rule::RULE_ROOT_REQUIRE, array(
 19439 'packageName' => $packageName,
 19440 'constraint' => $constraint,
 19441 ));
 19442 $this->addRule(RuleSet::TYPE_REQUEST, $rule);
 19443 }
 19444 }
 19445 }
 19446 
 19447 
 19448 
 19449 
 19450 protected function addRulesForRootAliases(PlatformRequirementFilterInterface $platformRequirementFilter)
 19451 {
 19452 foreach ($this->pool->getPackages() as $package) {
 19453 
 19454 
 19455 
 19456 if (!isset($this->addedMap[$package->id]) &&
 19457 $package instanceof AliasPackage &&
 19458 ($package->isRootPackageAlias() || isset($this->addedMap[$package->getAliasOf()->id]))
 19459 ) {
 19460 $this->addRulesForPackage($package, $platformRequirementFilter);
 19461 }
 19462 }
 19463 }
 19464 
 19465 
 19466 
 19467 
 19468 public function getRulesFor(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter = null)
 19469 {
 19470 $platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
 19471 
 19472 $this->addRulesForRequest($request, $platformRequirementFilter);
 19473 
 19474 $this->addRulesForRootAliases($platformRequirementFilter);
 19475 
 19476 $this->addConflictRules($platformRequirementFilter);
 19477 
 19478 
 19479 $this->addedMap = $this->addedPackagesByNames = array();
 19480 
 19481 $rules = $this->rules;
 19482 
 19483 $this->rules = new RuleSet;
 19484 
 19485 return $rules;
 19486 }
 19487 }
 19488 <?php
 19489 
 19490 
 19491 
 19492 
 19493 
 19494 
 19495 
 19496 
 19497 
 19498 
 19499 
 19500 namespace Composer\DependencyResolver;
 19501 
 19502 
 19503 
 19504 
 19505 
 19506 class RuleSetIterator implements \Iterator
 19507 {
 19508 
 19509 protected $rules;
 19510 
 19511 protected $types;
 19512 
 19513 
 19514 protected $currentOffset;
 19515 
 19516 protected $currentType;
 19517 
 19518 protected $currentTypeOffset;
 19519 
 19520 
 19521 
 19522 
 19523 public function __construct(array $rules)
 19524 {
 19525 $this->rules = $rules;
 19526 $this->types = array_keys($rules);
 19527 sort($this->types);
 19528 
 19529 $this->rewind();
 19530 }
 19531 
 19532 
 19533 
 19534 
 19535 #[\ReturnTypeWillChange]
 19536 public function current()
 19537 {
 19538 return $this->rules[$this->currentType][$this->currentOffset];
 19539 }
 19540 
 19541 
 19542 
 19543 
 19544 #[\ReturnTypeWillChange]
 19545 public function key()
 19546 {
 19547 return $this->currentType;
 19548 }
 19549 
 19550 
 19551 
 19552 
 19553 #[\ReturnTypeWillChange]
 19554 public function next()
 19555 {
 19556 $this->currentOffset++;
 19557 
 19558 if (!isset($this->rules[$this->currentType])) {
 19559 return;
 19560 }
 19561 
 19562 if ($this->currentOffset >= \count($this->rules[$this->currentType])) {
 19563 $this->currentOffset = 0;
 19564 
 19565 do {
 19566 $this->currentTypeOffset++;
 19567 
 19568 if (!isset($this->types[$this->currentTypeOffset])) {
 19569 $this->currentType = -1;
 19570 break;
 19571 }
 19572 
 19573 $this->currentType = $this->types[$this->currentTypeOffset];
 19574 } while (isset($this->types[$this->currentTypeOffset]) && !\count($this->rules[$this->currentType]));
 19575 }
 19576 }
 19577 
 19578 
 19579 
 19580 
 19581 #[\ReturnTypeWillChange]
 19582 public function rewind()
 19583 {
 19584 $this->currentOffset = 0;
 19585 
 19586 $this->currentTypeOffset = -1;
 19587 $this->currentType = -1;
 19588 
 19589 do {
 19590 $this->currentTypeOffset++;
 19591 
 19592 if (!isset($this->types[$this->currentTypeOffset])) {
 19593 $this->currentType = -1;
 19594 break;
 19595 }
 19596 
 19597 $this->currentType = $this->types[$this->currentTypeOffset];
 19598 } while (isset($this->types[$this->currentTypeOffset]) && !\count($this->rules[$this->currentType]));
 19599 }
 19600 
 19601 
 19602 
 19603 
 19604 #[\ReturnTypeWillChange]
 19605 public function valid()
 19606 {
 19607 return isset($this->rules[$this->currentType], $this->rules[$this->currentType][$this->currentOffset]);
 19608 }
 19609 }
 19610 <?php
 19611 
 19612 
 19613 
 19614 
 19615 
 19616 
 19617 
 19618 
 19619 
 19620 
 19621 
 19622 namespace Composer\DependencyResolver;
 19623 
 19624 
 19625 
 19626 
 19627 
 19628 
 19629 
 19630 
 19631 
 19632 
 19633 class RuleWatchChain extends \SplDoublyLinkedList
 19634 {
 19635 
 19636 
 19637 
 19638 
 19639 
 19640 
 19641 public function seek($offset)
 19642 {
 19643 $this->rewind();
 19644 for ($i = 0; $i < $offset; $i++, $this->next());
 19645 }
 19646 
 19647 
 19648 
 19649 
 19650 
 19651 
 19652 
 19653 
 19654 
 19655 
 19656 
 19657 public function remove()
 19658 {
 19659 $offset = $this->key();
 19660 $this->offsetUnset($offset);
 19661 $this->seek($offset);
 19662 }
 19663 }
 19664 <?php
 19665 
 19666 
 19667 
 19668 
 19669 
 19670 
 19671 
 19672 
 19673 
 19674 
 19675 
 19676 namespace Composer\DependencyResolver;
 19677 
 19678 
 19679 
 19680 
 19681 
 19682 
 19683 
 19684 
 19685 
 19686 
 19687 
 19688 class RuleWatchGraph
 19689 {
 19690 
 19691 protected $watchChains = array();
 19692 
 19693 
 19694 
 19695 
 19696 
 19697 
 19698 
 19699 
 19700 
 19701 
 19702 
 19703 
 19704 
 19705 
 19706 public function insert(RuleWatchNode $node)
 19707 {
 19708 if ($node->getRule()->isAssertion()) {
 19709 return;
 19710 }
 19711 
 19712 if (!$node->getRule() instanceof MultiConflictRule) {
 19713 foreach (array($node->watch1, $node->watch2) as $literal) {
 19714 if (!isset($this->watchChains[$literal])) {
 19715 $this->watchChains[$literal] = new RuleWatchChain;
 19716 }
 19717 
 19718 $this->watchChains[$literal]->unshift($node);
 19719 }
 19720 } else {
 19721 foreach ($node->getRule()->getLiterals() as $literal) {
 19722 if (!isset($this->watchChains[$literal])) {
 19723 $this->watchChains[$literal] = new RuleWatchChain;
 19724 }
 19725 
 19726 $this->watchChains[$literal]->unshift($node);
 19727 }
 19728 }
 19729 }
 19730 
 19731 
 19732 
 19733 
 19734 
 19735 
 19736 
 19737 
 19738 
 19739 
 19740 
 19741 
 19742 
 19743 
 19744 
 19745 
 19746 
 19747 
 19748 
 19749 
 19750 
 19751 
 19752 
 19753 
 19754 public function propagateLiteral($decidedLiteral, $level, Decisions $decisions)
 19755 {
 19756 
 19757 
 19758 
 19759 $literal = -$decidedLiteral;
 19760 
 19761 if (!isset($this->watchChains[$literal])) {
 19762 return null;
 19763 }
 19764 
 19765 $chain = $this->watchChains[$literal];
 19766 
 19767 $chain->rewind();
 19768 while ($chain->valid()) {
 19769 $node = $chain->current();
 19770 if (!$node->getRule() instanceof MultiConflictRule) {
 19771 $otherWatch = $node->getOtherWatch($literal);
 19772 
 19773 if (!$node->getRule()->isDisabled() && !$decisions->satisfy($otherWatch)) {
 19774 $ruleLiterals = $node->getRule()->getLiterals();
 19775 
 19776 $alternativeLiterals = array_filter($ruleLiterals, function ($ruleLiteral) use ($literal, $otherWatch, $decisions) {
 19777 return $literal !== $ruleLiteral &&
 19778 $otherWatch !== $ruleLiteral &&
 19779 !$decisions->conflict($ruleLiteral);
 19780 });
 19781 
 19782 if ($alternativeLiterals) {
 19783 reset($alternativeLiterals);
 19784 $this->moveWatch($literal, current($alternativeLiterals), $node);
 19785 continue;
 19786 }
 19787 
 19788 if ($decisions->conflict($otherWatch)) {
 19789 return $node->getRule();
 19790 }
 19791 
 19792 $decisions->decide($otherWatch, $level, $node->getRule());
 19793 }
 19794 } else {
 19795 foreach ($node->getRule()->getLiterals() as $otherLiteral) {
 19796 if ($literal !== $otherLiteral && !$decisions->satisfy($otherLiteral)) {
 19797 if ($decisions->conflict($otherLiteral)) {
 19798 return $node->getRule();
 19799 }
 19800 
 19801 $decisions->decide($otherLiteral, $level, $node->getRule());
 19802 }
 19803 }
 19804 }
 19805 
 19806 $chain->next();
 19807 }
 19808 
 19809 return null;
 19810 }
 19811 
 19812 
 19813 
 19814 
 19815 
 19816 
 19817 
 19818 
 19819 
 19820 
 19821 
 19822 protected function moveWatch($fromLiteral, $toLiteral, RuleWatchNode $node)
 19823 {
 19824 if (!isset($this->watchChains[$toLiteral])) {
 19825 $this->watchChains[$toLiteral] = new RuleWatchChain;
 19826 }
 19827 
 19828 $node->moveWatch($fromLiteral, $toLiteral);
 19829 $this->watchChains[$fromLiteral]->remove();
 19830 $this->watchChains[$toLiteral]->unshift($node);
 19831 }
 19832 }
 19833 <?php
 19834 
 19835 
 19836 
 19837 
 19838 
 19839 
 19840 
 19841 
 19842 
 19843 
 19844 
 19845 namespace Composer\DependencyResolver;
 19846 
 19847 
 19848 
 19849 
 19850 
 19851 
 19852 
 19853 
 19854 class RuleWatchNode
 19855 {
 19856 
 19857 public $watch1;
 19858 
 19859 public $watch2;
 19860 
 19861 
 19862 protected $rule;
 19863 
 19864 
 19865 
 19866 
 19867 
 19868 
 19869 public function __construct(Rule $rule)
 19870 {
 19871 $this->rule = $rule;
 19872 
 19873 $literals = $rule->getLiterals();
 19874 
 19875 $literalCount = \count($literals);
 19876 $this->watch1 = $literalCount > 0 ? $literals[0] : 0;
 19877 $this->watch2 = $literalCount > 1 ? $literals[1] : 0;
 19878 }
 19879 
 19880 
 19881 
 19882 
 19883 
 19884 
 19885 
 19886 
 19887 
 19888 
 19889 public function watch2OnHighest(Decisions $decisions)
 19890 {
 19891 $literals = $this->rule->getLiterals();
 19892 
 19893 
 19894 if (\count($literals) < 3 || $this->rule instanceof MultiConflictRule) {
 19895 return;
 19896 }
 19897 
 19898 $watchLevel = 0;
 19899 
 19900 foreach ($literals as $literal) {
 19901 $level = $decisions->decisionLevel($literal);
 19902 
 19903 if ($level > $watchLevel) {
 19904 $this->watch2 = $literal;
 19905 $watchLevel = $level;
 19906 }
 19907 }
 19908 }
 19909 
 19910 
 19911 
 19912 
 19913 
 19914 
 19915 public function getRule()
 19916 {
 19917 return $this->rule;
 19918 }
 19919 
 19920 
 19921 
 19922 
 19923 
 19924 
 19925 
 19926 public function getOtherWatch($literal)
 19927 {
 19928 if ($this->watch1 == $literal) {
 19929 return $this->watch2;
 19930 }
 19931 
 19932 return $this->watch1;
 19933 }
 19934 
 19935 
 19936 
 19937 
 19938 
 19939 
 19940 
 19941 
 19942 public function moveWatch($from, $to)
 19943 {
 19944 if ($this->watch1 == $from) {
 19945 $this->watch1 = $to;
 19946 } else {
 19947 $this->watch2 = $to;
 19948 }
 19949 }
 19950 }
 19951 <?php
 19952 
 19953 
 19954 
 19955 
 19956 
 19957 
 19958 
 19959 
 19960 
 19961 
 19962 
 19963 namespace Composer\DependencyResolver;
 19964 
 19965 use Composer\Filter\PlatformRequirementFilter\IgnoreListPlatformRequirementFilter;
 19966 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
 19967 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterInterface;
 19968 use Composer\IO\IOInterface;
 19969 use Composer\Package\BasePackage;
 19970 
 19971 
 19972 
 19973 
 19974 class Solver
 19975 {
 19976 const BRANCH_LITERALS = 0;
 19977 const BRANCH_LEVEL = 1;
 19978 
 19979 
 19980 protected $policy;
 19981 
 19982 protected $pool;
 19983 
 19984 
 19985 protected $rules;
 19986 
 19987 
 19988 protected $watchGraph;
 19989 
 19990 protected $decisions;
 19991 
 19992 protected $fixedMap;
 19993 
 19994 
 19995 protected $propagateIndex;
 19996 
 19997 protected $branches = array();
 19998 
 19999 protected $problems = array();
 20000 
 20001 protected $learnedPool = array();
 20002 
 20003 protected $learnedWhy = array();
 20004 
 20005 
 20006 public $testFlagLearnedPositiveLiteral = false;
 20007 
 20008 
 20009 protected $io;
 20010 
 20011 public function __construct(PolicyInterface $policy, Pool $pool, IOInterface $io)
 20012 {
 20013 $this->io = $io;
 20014 $this->policy = $policy;
 20015 $this->pool = $pool;
 20016 }
 20017 
 20018 
 20019 
 20020 
 20021 public function getRuleSetSize()
 20022 {
 20023 return \count($this->rules);
 20024 }
 20025 
 20026 
 20027 
 20028 
 20029 public function getPool()
 20030 {
 20031 return $this->pool;
 20032 }
 20033 
 20034 
 20035 
 20036 
 20037 
 20038 
 20039 private function makeAssertionRuleDecisions()
 20040 {
 20041 $decisionStart = \count($this->decisions) - 1;
 20042 
 20043 $rulesCount = \count($this->rules);
 20044 for ($ruleIndex = 0; $ruleIndex < $rulesCount; $ruleIndex++) {
 20045 $rule = $this->rules->ruleById[$ruleIndex];
 20046 
 20047 if (!$rule->isAssertion() || $rule->isDisabled()) {
 20048 continue;
 20049 }
 20050 
 20051 $literals = $rule->getLiterals();
 20052 $literal = $literals[0];
 20053 
 20054 if (!$this->decisions->decided($literal)) {
 20055 $this->decisions->decide($literal, 1, $rule);
 20056 continue;
 20057 }
 20058 
 20059 if ($this->decisions->satisfy($literal)) {
 20060 continue;
 20061 }
 20062 
 20063 
 20064 if (RuleSet::TYPE_LEARNED === $rule->getType()) {
 20065 $rule->disable();
 20066 continue;
 20067 }
 20068 
 20069 $conflict = $this->decisions->decisionRule($literal);
 20070 
 20071 if ($conflict && RuleSet::TYPE_PACKAGE === $conflict->getType()) {
 20072 $problem = new Problem();
 20073 
 20074 $problem->addRule($rule);
 20075 $problem->addRule($conflict);
 20076 $rule->disable();
 20077 $this->problems[] = $problem;
 20078 continue;
 20079 }
 20080 
 20081 
 20082 $problem = new Problem();
 20083 $problem->addRule($rule);
 20084 $problem->addRule($conflict);
 20085 
 20086 
 20087 
 20088 foreach ($this->rules->getIteratorFor(RuleSet::TYPE_REQUEST) as $assertRule) {
 20089 if ($assertRule->isDisabled() || !$assertRule->isAssertion()) {
 20090 continue;
 20091 }
 20092 
 20093 $assertRuleLiterals = $assertRule->getLiterals();
 20094 $assertRuleLiteral = $assertRuleLiterals[0];
 20095 
 20096 if (abs($literal) !== abs($assertRuleLiteral)) {
 20097 continue;
 20098 }
 20099 $problem->addRule($assertRule);
 20100 $assertRule->disable();
 20101 }
 20102 $this->problems[] = $problem;
 20103 
 20104 $this->decisions->resetToOffset($decisionStart);
 20105 $ruleIndex = -1;
 20106 }
 20107 }
 20108 
 20109 
 20110 
 20111 
 20112 protected function setupFixedMap(Request $request)
 20113 {
 20114 $this->fixedMap = array();
 20115 foreach ($request->getFixedPackages() as $package) {
 20116 $this->fixedMap[$package->id] = $package;
 20117 }
 20118 }
 20119 
 20120 
 20121 
 20122 
 20123 protected function checkForRootRequireProblems(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter)
 20124 {
 20125 foreach ($request->getRequires() as $packageName => $constraint) {
 20126 if ($platformRequirementFilter->isIgnored($packageName)) {
 20127 continue;
 20128 } elseif ($platformRequirementFilter instanceof IgnoreListPlatformRequirementFilter) {
 20129 $constraint = $platformRequirementFilter->filterConstraint($packageName, $constraint);
 20130 }
 20131 
 20132 if (!$this->pool->whatProvides($packageName, $constraint)) {
 20133 $problem = new Problem();
 20134 $problem->addRule(new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => $packageName, 'constraint' => $constraint)));
 20135 $this->problems[] = $problem;
 20136 }
 20137 }
 20138 }
 20139 
 20140 
 20141 
 20142 
 20143 public function solve(Request $request, PlatformRequirementFilterInterface $platformRequirementFilter = null)
 20144 {
 20145 $platformRequirementFilter = $platformRequirementFilter ?: PlatformRequirementFilterFactory::ignoreNothing();
 20146 
 20147 $this->setupFixedMap($request);
 20148 
 20149 $this->io->writeError('Generating rules', true, IOInterface::DEBUG);
 20150 $ruleSetGenerator = new RuleSetGenerator($this->policy, $this->pool);
 20151 $this->rules = $ruleSetGenerator->getRulesFor($request, $platformRequirementFilter);
 20152 unset($ruleSetGenerator);
 20153 $this->checkForRootRequireProblems($request, $platformRequirementFilter);
 20154 $this->decisions = new Decisions($this->pool);
 20155 $this->watchGraph = new RuleWatchGraph;
 20156 
 20157 foreach ($this->rules as $rule) {
 20158 $this->watchGraph->insert(new RuleWatchNode($rule));
 20159 }
 20160 
 20161 
 20162 $this->makeAssertionRuleDecisions();
 20163 
 20164 $this->io->writeError('Resolving dependencies through SAT', true, IOInterface::DEBUG);
 20165 $before = microtime(true);
 20166 $this->runSat();
 20167 $this->io->writeError('', true, IOInterface::DEBUG);
 20168 $this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE);
 20169 
 20170 if ($this->problems) {
 20171 throw new SolverProblemsException($this->problems, $this->learnedPool);
 20172 }
 20173 
 20174 return new LockTransaction($this->pool, $request->getPresentMap(), $request->getFixedPackagesMap(), $this->decisions);
 20175 }
 20176 
 20177 
 20178 
 20179 
 20180 
 20181 
 20182 
 20183 
 20184 
 20185 
 20186 protected function propagate($level)
 20187 {
 20188 while ($this->decisions->validOffset($this->propagateIndex)) {
 20189 $decision = $this->decisions->atOffset($this->propagateIndex);
 20190 
 20191 $conflict = $this->watchGraph->propagateLiteral(
 20192 $decision[Decisions::DECISION_LITERAL],
 20193 $level,
 20194 $this->decisions
 20195 );
 20196 
 20197 $this->propagateIndex++;
 20198 
 20199 if ($conflict) {
 20200 return $conflict;
 20201 }
 20202 }
 20203 
 20204 return null;
 20205 }
 20206 
 20207 
 20208 
 20209 
 20210 
 20211 
 20212 
 20213 
 20214 private function revert($level)
 20215 {
 20216 while (!$this->decisions->isEmpty()) {
 20217 $literal = $this->decisions->lastLiteral();
 20218 
 20219 if ($this->decisions->undecided($literal)) {
 20220 break;
 20221 }
 20222 
 20223 $decisionLevel = $this->decisions->decisionLevel($literal);
 20224 
 20225 if ($decisionLevel <= $level) {
 20226 break;
 20227 }
 20228 
 20229 $this->decisions->revertLast();
 20230 $this->propagateIndex = \count($this->decisions);
 20231 }
 20232 
 20233 while (!empty($this->branches) && $this->branches[\count($this->branches) - 1][self::BRANCH_LEVEL] >= $level) {
 20234 array_pop($this->branches);
 20235 }
 20236 }
 20237 
 20238 
 20239 
 20240 
 20241 
 20242 
 20243 
 20244 
 20245 
 20246 
 20247 
 20248 
 20249 
 20250 
 20251 
 20252 
 20253 
 20254 
 20255 private function setPropagateLearn($level, $literal, Rule $rule)
 20256 {
 20257 $level++;
 20258 
 20259 $this->decisions->decide($literal, $level, $rule);
 20260 
 20261 while (true) {
 20262 $rule = $this->propagate($level);
 20263 
 20264 if (!$rule) {
 20265 break;
 20266 }
 20267 
 20268 if ($level == 1) {
 20269 return $this->analyzeUnsolvable($rule);
 20270 }
 20271 
 20272 
 20273 list($learnLiteral, $newLevel, $newRule, $why) = $this->analyze($level, $rule);
 20274 
 20275 if ($newLevel <= 0 || $newLevel >= $level) {
 20276 throw new SolverBugException(
 20277 "Trying to revert to invalid level ".$newLevel." from level ".$level."."
 20278 );
 20279 }
 20280 
 20281 $level = $newLevel;
 20282 
 20283 $this->revert($level);
 20284 
 20285 $this->rules->add($newRule, RuleSet::TYPE_LEARNED);
 20286 
 20287 $this->learnedWhy[spl_object_hash($newRule)] = $why;
 20288 
 20289 $ruleNode = new RuleWatchNode($newRule);
 20290 $ruleNode->watch2OnHighest($this->decisions);
 20291 $this->watchGraph->insert($ruleNode);
 20292 
 20293 $this->decisions->decide($learnLiteral, $level, $newRule);
 20294 }
 20295 
 20296 return $level;
 20297 }
 20298 
 20299 
 20300 
 20301 
 20302 
 20303 
 20304 private function selectAndInstall($level, array $decisionQueue, Rule $rule)
 20305 {
 20306 
 20307 $literals = $this->policy->selectPreferredPackages($this->pool, $decisionQueue, $rule->getRequiredPackage());
 20308 
 20309 $selectedLiteral = array_shift($literals);
 20310 
 20311 
 20312 if (\count($literals)) {
 20313 $this->branches[] = array($literals, $level);
 20314 }
 20315 
 20316 return $this->setPropagateLearn($level, $selectedLiteral, $rule);
 20317 }
 20318 
 20319 
 20320 
 20321 
 20322 
 20323 protected function analyze($level, Rule $rule)
 20324 {
 20325 $analyzedRule = $rule;
 20326 $ruleLevel = 1;
 20327 $num = 0;
 20328 $l1num = 0;
 20329 $seen = array();
 20330 $learnedLiterals = array(null);
 20331 
 20332 $decisionId = \count($this->decisions);
 20333 
 20334 $this->learnedPool[] = array();
 20335 
 20336 while (true) {
 20337 $this->learnedPool[\count($this->learnedPool) - 1][] = $rule;
 20338 
 20339 foreach ($rule->getLiterals() as $literal) {
 20340 
 20341 if ($rule instanceof MultiConflictRule && !$this->decisions->decided($literal)) {
 20342 continue;
 20343 }
 20344 
 20345 
 20346 if ($this->decisions->satisfy($literal)) {
 20347 continue;
 20348 }
 20349 
 20350 if (isset($seen[abs($literal)])) {
 20351 continue;
 20352 }
 20353 $seen[abs($literal)] = true;
 20354 
 20355 $l = $this->decisions->decisionLevel($literal);
 20356 
 20357 if (1 === $l) {
 20358 $l1num++;
 20359 } elseif ($level === $l) {
 20360 $num++;
 20361 } else {
 20362 
 20363 $learnedLiterals[] = $literal;
 20364 
 20365 if ($l > $ruleLevel) {
 20366 $ruleLevel = $l;
 20367 }
 20368 }
 20369 }
 20370 unset($literal);
 20371 
 20372 $l1retry = true;
 20373 while ($l1retry) {
 20374 $l1retry = false;
 20375 
 20376 if (0 === $num && 0 === --$l1num) {
 20377 
 20378 break 2;
 20379 }
 20380 
 20381 while (true) {
 20382 if ($decisionId <= 0) {
 20383 throw new SolverBugException(
 20384 "Reached invalid decision id $decisionId while looking through $rule for a literal present in the analyzed rule $analyzedRule."
 20385 );
 20386 }
 20387 
 20388 $decisionId--;
 20389 
 20390 $decision = $this->decisions->atOffset($decisionId);
 20391 $literal = $decision[Decisions::DECISION_LITERAL];
 20392 
 20393 if (isset($seen[abs($literal)])) {
 20394 break;
 20395 }
 20396 }
 20397 
 20398 unset($seen[abs($literal)]);
 20399 
 20400 if (0 !== $num && 0 === --$num) {
 20401 if ($literal < 0) {
 20402 $this->testFlagLearnedPositiveLiteral = true;
 20403 }
 20404 $learnedLiterals[0] = -$literal;
 20405 
 20406 if (!$l1num) {
 20407 break 2;
 20408 }
 20409 
 20410 foreach ($learnedLiterals as $i => $learnedLiteral) {
 20411 if ($i !== 0) {
 20412 unset($seen[abs($learnedLiteral)]);
 20413 }
 20414 }
 20415 
 20416 $l1num++;
 20417 $l1retry = true;
 20418 } else {
 20419 $decision = $this->decisions->atOffset($decisionId);
 20420 $rule = $decision[Decisions::DECISION_REASON];
 20421 
 20422 if ($rule instanceof MultiConflictRule) {
 20423 
 20424 foreach ($rule->getLiterals() as $literal) {
 20425 if (!isset($seen[abs($literal)]) && $this->decisions->satisfy(-$literal)) {
 20426 $this->learnedPool[\count($this->learnedPool) - 1][] = $rule;
 20427 $l = $this->decisions->decisionLevel($literal);
 20428 if (1 === $l) {
 20429 $l1num++;
 20430 } elseif ($level === $l) {
 20431 $num++;
 20432 } else {
 20433 
 20434 $learnedLiterals[] = $literal;
 20435 
 20436 if ($l > $ruleLevel) {
 20437 $ruleLevel = $l;
 20438 }
 20439 }
 20440 $seen[abs($literal)] = true;
 20441 break;
 20442 }
 20443 }
 20444 
 20445 $l1retry = true;
 20446 }
 20447 }
 20448 }
 20449 
 20450 $decision = $this->decisions->atOffset($decisionId);
 20451 $rule = $decision[Decisions::DECISION_REASON];
 20452 }
 20453 
 20454 $why = \count($this->learnedPool) - 1;
 20455 
 20456 if (!$learnedLiterals[0]) {
 20457 throw new SolverBugException(
 20458 "Did not find a learnable literal in analyzed rule $analyzedRule."
 20459 );
 20460 }
 20461 
 20462 $newRule = new GenericRule($learnedLiterals, Rule::RULE_LEARNED, $why);
 20463 
 20464 return array($learnedLiterals[0], $ruleLevel, $newRule, $why);
 20465 }
 20466 
 20467 
 20468 
 20469 
 20470 
 20471 private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule, array &$ruleSeen)
 20472 {
 20473 $why = spl_object_hash($conflictRule);
 20474 $ruleSeen[$why] = true;
 20475 
 20476 if ($conflictRule->getType() == RuleSet::TYPE_LEARNED) {
 20477 $learnedWhy = $this->learnedWhy[$why];
 20478 $problemRules = $this->learnedPool[$learnedWhy];
 20479 
 20480 foreach ($problemRules as $problemRule) {
 20481 if (!isset($ruleSeen[spl_object_hash($problemRule)])) {
 20482 $this->analyzeUnsolvableRule($problem, $problemRule, $ruleSeen);
 20483 }
 20484 }
 20485 
 20486 return;
 20487 }
 20488 
 20489 if ($conflictRule->getType() == RuleSet::TYPE_PACKAGE) {
 20490 
 20491 return;
 20492 }
 20493 
 20494 $problem->nextSection();
 20495 $problem->addRule($conflictRule);
 20496 }
 20497 
 20498 
 20499 
 20500 
 20501 private function analyzeUnsolvable(Rule $conflictRule)
 20502 {
 20503 $problem = new Problem();
 20504 $problem->addRule($conflictRule);
 20505 
 20506 $ruleSeen = array();
 20507 
 20508 $this->analyzeUnsolvableRule($problem, $conflictRule, $ruleSeen);
 20509 
 20510 $this->problems[] = $problem;
 20511 
 20512 $seen = array();
 20513 $literals = $conflictRule->getLiterals();
 20514 
 20515 foreach ($literals as $literal) {
 20516 
 20517 if ($this->decisions->satisfy($literal)) {
 20518 continue;
 20519 }
 20520 $seen[abs($literal)] = true;
 20521 }
 20522 
 20523 foreach ($this->decisions as $decision) {
 20524 $literal = $decision[Decisions::DECISION_LITERAL];
 20525 
 20526 
 20527 if (!isset($seen[abs($literal)])) {
 20528 continue;
 20529 }
 20530 
 20531 $why = $decision[Decisions::DECISION_REASON];
 20532 
 20533 $problem->addRule($why);
 20534 $this->analyzeUnsolvableRule($problem, $why, $ruleSeen);
 20535 
 20536 $literals = $why->getLiterals();
 20537 
 20538 foreach ($literals as $literal) {
 20539 
 20540 if ($this->decisions->satisfy($literal)) {
 20541 continue;
 20542 }
 20543 $seen[abs($literal)] = true;
 20544 }
 20545 }
 20546 
 20547 return 0;
 20548 }
 20549 
 20550 
 20551 
 20552 
 20553 
 20554 
 20555 
 20556 
 20557 
 20558 
 20559 private function enableDisableLearnedRules()
 20560 {
 20561 foreach ($this->rules->getIteratorFor(RuleSet::TYPE_LEARNED) as $rule) {
 20562 $why = $this->learnedWhy[spl_object_hash($rule)];
 20563 $problemRules = $this->learnedPool[$why];
 20564 
 20565 $foundDisabled = false;
 20566 foreach ($problemRules as $problemRule) {
 20567 if ($problemRule->isDisabled()) {
 20568 $foundDisabled = true;
 20569 break;
 20570 }
 20571 }
 20572 
 20573 if ($foundDisabled && $rule->isEnabled()) {
 20574 $rule->disable();
 20575 } elseif (!$foundDisabled && $rule->isDisabled()) {
 20576 $rule->enable();
 20577 }
 20578 }
 20579 }
 20580 
 20581 
 20582 
 20583 
 20584 private function runSat()
 20585 {
 20586 $this->propagateIndex = 0;
 20587 
 20588 
 20589 
 20590 
 20591 
 20592 
 20593 
 20594 
 20595 
 20596 
 20597 
 20598 $level = 1;
 20599 $systemLevel = $level + 1;
 20600 
 20601 while (true) {
 20602 if (1 === $level) {
 20603 $conflictRule = $this->propagate($level);
 20604 if (null !== $conflictRule) {
 20605 if ($this->analyzeUnsolvable($conflictRule)) {
 20606 continue;
 20607 }
 20608 
 20609 return;
 20610 }
 20611 }
 20612 
 20613 
 20614 if ($level < $systemLevel) {
 20615 $iterator = $this->rules->getIteratorFor(RuleSet::TYPE_REQUEST);
 20616 foreach ($iterator as $rule) {
 20617 if ($rule->isEnabled()) {
 20618 $decisionQueue = array();
 20619 $noneSatisfied = true;
 20620 
 20621 foreach ($rule->getLiterals() as $literal) {
 20622 if ($this->decisions->satisfy($literal)) {
 20623 $noneSatisfied = false;
 20624 break;
 20625 }
 20626 if ($literal > 0 && $this->decisions->undecided($literal)) {
 20627 $decisionQueue[] = $literal;
 20628 }
 20629 }
 20630 
 20631 if ($noneSatisfied && \count($decisionQueue)) {
 20632 
 20633 $prunedQueue = array();
 20634 foreach ($decisionQueue as $literal) {
 20635 if (isset($this->fixedMap[abs($literal)])) {
 20636 $prunedQueue[] = $literal;
 20637 }
 20638 }
 20639 if (!empty($prunedQueue)) {
 20640 $decisionQueue = $prunedQueue;
 20641 }
 20642 }
 20643 
 20644 if ($noneSatisfied && \count($decisionQueue)) {
 20645 $oLevel = $level;
 20646 $level = $this->selectAndInstall($level, $decisionQueue, $rule);
 20647 
 20648 if (0 === $level) {
 20649 return;
 20650 }
 20651 if ($level <= $oLevel) {
 20652 break;
 20653 }
 20654 }
 20655 }
 20656 }
 20657 
 20658 $systemLevel = $level + 1;
 20659 
 20660 
 20661 $iterator->next();
 20662 if ($iterator->valid()) {
 20663 continue;
 20664 }
 20665 }
 20666 
 20667 if ($level < $systemLevel) {
 20668 $systemLevel = $level;
 20669 }
 20670 
 20671 $rulesCount = \count($this->rules);
 20672 $pass = 1;
 20673 
 20674 $this->io->writeError('Looking at all rules.', true, IOInterface::DEBUG);
 20675 for ($i = 0, $n = 0; $n < $rulesCount; $i++, $n++) {
 20676 if ($i == $rulesCount) {
 20677 if (1 === $pass) {
 20678 $this->io->writeError("Something's changed, looking at all rules again (pass #$pass)", false, IOInterface::DEBUG);
 20679 } else {
 20680 $this->io->overwriteError("Something's changed, looking at all rules again (pass #$pass)", false, null, IOInterface::DEBUG);
 20681 }
 20682 
 20683 $i = 0;
 20684 $pass++;
 20685 }
 20686 
 20687 $rule = $this->rules->ruleById[$i];
 20688 $literals = $rule->getLiterals();
 20689 
 20690 if ($rule->isDisabled()) {
 20691 continue;
 20692 }
 20693 
 20694 $decisionQueue = array();
 20695 
 20696 
 20697 
 20698 
 20699 
 20700 
 20701 
 20702 foreach ($literals as $literal) {
 20703 if ($literal <= 0) {
 20704 if (!$this->decisions->decidedInstall($literal)) {
 20705 continue 2; 
 20706 }
 20707 } else {
 20708 if ($this->decisions->decidedInstall($literal)) {
 20709 continue 2; 
 20710 }
 20711 if ($this->decisions->undecided($literal)) {
 20712 $decisionQueue[] = $literal;
 20713 }
 20714 }
 20715 }
 20716 
 20717 
 20718 if (\count($decisionQueue) < 2) {
 20719 continue;
 20720 }
 20721 
 20722 $level = $this->selectAndInstall($level, $decisionQueue, $rule);
 20723 
 20724 if (0 === $level) {
 20725 return;
 20726 }
 20727 
 20728 
 20729 $rulesCount = \count($this->rules);
 20730 $n = -1;
 20731 }
 20732 
 20733 if ($level < $systemLevel) {
 20734 continue;
 20735 }
 20736 
 20737 
 20738 if (\count($this->branches)) {
 20739 $lastLiteral = null;
 20740 $lastLevel = null;
 20741 $lastBranchIndex = 0;
 20742 $lastBranchOffset = 0;
 20743 
 20744 for ($i = \count($this->branches) - 1; $i >= 0; $i--) {
 20745 list($literals, $l) = $this->branches[$i];
 20746 
 20747 foreach ($literals as $offset => $literal) {
 20748 if ($literal && $literal > 0 && $this->decisions->decisionLevel($literal) > $l + 1) {
 20749 $lastLiteral = $literal;
 20750 $lastBranchIndex = $i;
 20751 $lastBranchOffset = $offset;
 20752 $lastLevel = $l;
 20753 }
 20754 }
 20755 }
 20756 
 20757 if ($lastLiteral) {
 20758 unset($this->branches[$lastBranchIndex][self::BRANCH_LITERALS][$lastBranchOffset]);
 20759 
 20760 $level = $lastLevel;
 20761 $this->revert($level);
 20762 
 20763 $why = $this->decisions->lastReason();
 20764 
 20765 $level = $this->setPropagateLearn($level, $lastLiteral, $why);
 20766 
 20767 if ($level == 0) {
 20768 return;
 20769 }
 20770 
 20771 continue;
 20772 }
 20773 }
 20774 
 20775 break;
 20776 }
 20777 }
 20778 }
 20779 <?php
 20780 
 20781 
 20782 
 20783 
 20784 
 20785 
 20786 
 20787 
 20788 
 20789 
 20790 
 20791 namespace Composer\DependencyResolver;
 20792 
 20793 
 20794 
 20795 
 20796 class SolverBugException extends \RuntimeException
 20797 {
 20798 
 20799 
 20800 
 20801 public function __construct($message)
 20802 {
 20803 parent::__construct(
 20804 $message."\nThis exception was most likely caused by a bug in Composer.\n".
 20805 "Please report the command you ran, the exact error you received, and your composer.json on https://github.com/composer/composer/issues - thank you!\n"
 20806 );
 20807 }
 20808 }
 20809 <?php
 20810 
 20811 
 20812 
 20813 
 20814 
 20815 
 20816 
 20817 
 20818 
 20819 
 20820 
 20821 namespace Composer\DependencyResolver;
 20822 
 20823 use Composer\Util\IniHelper;
 20824 use Composer\Repository\RepositorySet;
 20825 
 20826 
 20827 
 20828 
 20829 
 20830 
 20831 class SolverProblemsException extends \RuntimeException
 20832 {
 20833 const ERROR_DEPENDENCY_RESOLUTION_FAILED = 2;
 20834 
 20835 
 20836 protected $problems;
 20837 
 20838 protected $learnedPool;
 20839 
 20840 
 20841 
 20842 
 20843 
 20844 public function __construct(array $problems, array $learnedPool)
 20845 {
 20846 $this->problems = $problems;
 20847 $this->learnedPool = $learnedPool;
 20848 
 20849 parent::__construct('Failed resolving dependencies with '.count($problems).' problems, call getPrettyString to get formatted details', self::ERROR_DEPENDENCY_RESOLUTION_FAILED);
 20850 }
 20851 
 20852 
 20853 
 20854 
 20855 
 20856 
 20857 public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, $isDevExtraction = false)
 20858 {
 20859 $installedMap = $request->getPresentMap(true);
 20860 $missingExtensions = array();
 20861 $isCausedByLock = false;
 20862 
 20863 $problems = array();
 20864 foreach ($this->problems as $problem) {
 20865 $problems[] = $problem->getPrettyString($repositorySet, $request, $pool, $isVerbose, $installedMap, $this->learnedPool)."\n";
 20866 
 20867 $missingExtensions = array_merge($missingExtensions, $this->getExtensionProblems($problem->getReasons()));
 20868 
 20869 $isCausedByLock = $isCausedByLock || $problem->isCausedByLock($repositorySet, $request, $pool);
 20870 }
 20871 
 20872 $i = 1;
 20873 $text = "\n";
 20874 foreach (array_unique($problems) as $problem) {
 20875 $text .= "  Problem ".($i++).$problem;
 20876 }
 20877 
 20878 $hints = array();
 20879 if (!$isDevExtraction && (strpos($text, 'could not be found') || strpos($text, 'no matching package found'))) {
 20880 $hints[] = "Potential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n   see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.";
 20881 }
 20882 
 20883 if (!empty($missingExtensions)) {
 20884 $hints[] = $this->createExtensionHint($missingExtensions);
 20885 }
 20886 
 20887 if ($isCausedByLock && !$isDevExtraction && !$request->getUpdateAllowTransitiveRootDependencies()) {
 20888 $hints[] = "Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.";
 20889 }
 20890 
 20891 if (strpos($text, 'found composer-plugin-api[2.0.0] but it does not match') && strpos($text, '- ocramius/package-versions')) {
 20892 $hints[] = "<warning>ocramius/package-versions only provides support for Composer 2 in 1.8+, which requires PHP 7.4.</warning>\nIf you can not upgrade PHP you can require <info>composer/package-versions-deprecated</info> to resolve this with PHP 7.0+.";
 20893 }
 20894 
 20895 if (!class_exists('PHPUnit\Framework\TestCase', false)) {
 20896 if (strpos($text, 'found composer-plugin-api[2.0.0] but it does not match')) {
 20897 $hints[] = "You are using Composer 2, which some of your plugins seem to be incompatible with. Make sure you update your plugins or report a plugin-issue to ask them to support Composer 2.";
 20898 }
 20899 }
 20900 
 20901 if ($hints) {
 20902 $text .= "\n" . implode("\n\n", $hints);
 20903 }
 20904 
 20905 return $text;
 20906 }
 20907 
 20908 
 20909 
 20910 
 20911 public function getProblems()
 20912 {
 20913 return $this->problems;
 20914 }
 20915 
 20916 
 20917 
 20918 
 20919 
 20920 private function createExtensionHint(array $missingExtensions)
 20921 {
 20922 $paths = IniHelper::getAll();
 20923 
 20924 if (count($paths) === 1 && empty($paths[0])) {
 20925 return '';
 20926 }
 20927 
 20928 $ignoreExtensionsArguments = implode(" ", array_map(function ($extension) {
 20929 return "--ignore-platform-req=$extension";
 20930 }, $missingExtensions));
 20931 
 20932 $text = "To enable extensions, verify that they are enabled in your .ini files:\n    - ";
 20933 $text .= implode("\n    - ", $paths);
 20934 $text .= "\nYou can also run `php --ini` in a terminal to see which files are used by PHP in CLI mode.";
 20935 $text .= "\nAlternatively, you can run Composer with `$ignoreExtensionsArguments` to temporarily ignore these required extensions.";
 20936 
 20937 return $text;
 20938 }
 20939 
 20940 
 20941 
 20942 
 20943 
 20944 private function getExtensionProblems(array $reasonSets)
 20945 {
 20946 $missingExtensions = array();
 20947 foreach ($reasonSets as $reasonSet) {
 20948 foreach ($reasonSet as $rule) {
 20949 $required = $rule->getRequiredPackage();
 20950 if (null !== $required && 0 === strpos($required, 'ext-')) {
 20951 $missingExtensions[$required] = 1;
 20952 }
 20953 }
 20954 }
 20955 
 20956 return array_keys($missingExtensions);
 20957 }
 20958 }
 20959 <?php
 20960 
 20961 
 20962 
 20963 
 20964 
 20965 
 20966 
 20967 
 20968 
 20969 
 20970 
 20971 namespace Composer\DependencyResolver;
 20972 
 20973 use Composer\Package\AliasPackage;
 20974 use Composer\Package\Link;
 20975 use Composer\Package\PackageInterface;
 20976 use Composer\Repository\PlatformRepository;
 20977 use Composer\DependencyResolver\Operation\OperationInterface;
 20978 
 20979 
 20980 
 20981 
 20982 
 20983 class Transaction
 20984 {
 20985 
 20986 
 20987 
 20988 protected $operations;
 20989 
 20990 
 20991 
 20992 
 20993 
 20994 protected $presentPackages;
 20995 
 20996 
 20997 
 20998 
 20999 
 21000 protected $resultPackageMap;
 21001 
 21002 
 21003 
 21004 
 21005 protected $resultPackagesByName = array();
 21006 
 21007 
 21008 
 21009 
 21010 
 21011 public function __construct($presentPackages, $resultPackages)
 21012 {
 21013 $this->presentPackages = $presentPackages;
 21014 $this->setResultPackageMaps($resultPackages);
 21015 $this->operations = $this->calculateOperations();
 21016 }
 21017 
 21018 
 21019 
 21020 
 21021 public function getOperations()
 21022 {
 21023 return $this->operations;
 21024 }
 21025 
 21026 
 21027 
 21028 
 21029 
 21030 private function setResultPackageMaps($resultPackages)
 21031 {
 21032 $packageSort = function (PackageInterface $a, PackageInterface $b) {
 21033 
 21034 if ($a->getName() == $b->getName()) {
 21035 if ($a instanceof AliasPackage != $b instanceof AliasPackage) {
 21036 return $a instanceof AliasPackage ? -1 : 1;
 21037 }
 21038 
 21039 return strcmp($b->getVersion(), $a->getVersion());
 21040 }
 21041 
 21042 return strcmp($b->getName(), $a->getName());
 21043 };
 21044 
 21045 $this->resultPackageMap = array();
 21046 foreach ($resultPackages as $package) {
 21047 $this->resultPackageMap[spl_object_hash($package)] = $package;
 21048 foreach ($package->getNames() as $name) {
 21049 $this->resultPackagesByName[$name][] = $package;
 21050 }
 21051 }
 21052 
 21053 uasort($this->resultPackageMap, $packageSort);
 21054 foreach ($this->resultPackagesByName as $name => $packages) {
 21055 uasort($this->resultPackagesByName[$name], $packageSort);
 21056 }
 21057 }
 21058 
 21059 
 21060 
 21061 
 21062 protected function calculateOperations()
 21063 {
 21064 $operations = array();
 21065 
 21066 $presentPackageMap = array();
 21067 $removeMap = array();
 21068 $presentAliasMap = array();
 21069 $removeAliasMap = array();
 21070 foreach ($this->presentPackages as $package) {
 21071 if ($package instanceof AliasPackage) {
 21072 $presentAliasMap[$package->getName().'::'.$package->getVersion()] = $package;
 21073 $removeAliasMap[$package->getName().'::'.$package->getVersion()] = $package;
 21074 } else {
 21075 $presentPackageMap[$package->getName()] = $package;
 21076 $removeMap[$package->getName()] = $package;
 21077 }
 21078 }
 21079 
 21080 $stack = $this->getRootPackages();
 21081 
 21082 $visited = array();
 21083 $processed = array();
 21084 
 21085 while (!empty($stack)) {
 21086 $package = array_pop($stack);
 21087 
 21088 if (isset($processed[spl_object_hash($package)])) {
 21089 continue;
 21090 }
 21091 
 21092 if (!isset($visited[spl_object_hash($package)])) {
 21093 $visited[spl_object_hash($package)] = true;
 21094 
 21095 $stack[] = $package;
 21096 if ($package instanceof AliasPackage) {
 21097 $stack[] = $package->getAliasOf();
 21098 } else {
 21099 foreach ($package->getRequires() as $link) {
 21100 $possibleRequires = $this->getProvidersInResult($link);
 21101 
 21102 foreach ($possibleRequires as $require) {
 21103 $stack[] = $require;
 21104 }
 21105 }
 21106 }
 21107 } elseif (!isset($processed[spl_object_hash($package)])) {
 21108 $processed[spl_object_hash($package)] = true;
 21109 
 21110 if ($package instanceof AliasPackage) {
 21111 $aliasKey = $package->getName().'::'.$package->getVersion();
 21112 if (isset($presentAliasMap[$aliasKey])) {
 21113 unset($removeAliasMap[$aliasKey]);
 21114 } else {
 21115 $operations[] = new Operation\MarkAliasInstalledOperation($package);
 21116 }
 21117 } else {
 21118 if (isset($presentPackageMap[$package->getName()])) {
 21119 $source = $presentPackageMap[$package->getName()];
 21120 
 21121 
 21122 
 21123 if ($package->getVersion() != $presentPackageMap[$package->getName()]->getVersion() ||
 21124 $package->getDistReference() !== $presentPackageMap[$package->getName()]->getDistReference() ||
 21125 $package->getSourceReference() !== $presentPackageMap[$package->getName()]->getSourceReference()
 21126 ) {
 21127 $operations[] = new Operation\UpdateOperation($source, $package);
 21128 }
 21129 unset($removeMap[$package->getName()]);
 21130 } else {
 21131 $operations[] = new Operation\InstallOperation($package);
 21132 unset($removeMap[$package->getName()]);
 21133 }
 21134 }
 21135 }
 21136 }
 21137 
 21138 foreach ($removeMap as $name => $package) {
 21139 array_unshift($operations, new Operation\UninstallOperation($package));
 21140 }
 21141 foreach ($removeAliasMap as $nameVersion => $package) {
 21142 $operations[] = new Operation\MarkAliasUninstalledOperation($package);
 21143 }
 21144 
 21145 $operations = $this->movePluginsToFront($operations);
 21146 
 21147 
 21148 $operations = $this->moveUninstallsToFront($operations);
 21149 
 21150 
 21151 
 21152 
 21153 
 21154 
 21155 
 21156 
 21157 
 21158 
 21159 
 21160 
 21161 
 21162 
 21163 
 21164 
 21165 
 21166 
 21167 
 21168 return $this->operations = $operations;
 21169 }
 21170 
 21171 
 21172 
 21173 
 21174 
 21175 
 21176 
 21177 
 21178 
 21179 protected function getRootPackages()
 21180 {
 21181 $roots = $this->resultPackageMap;
 21182 
 21183 foreach ($this->resultPackageMap as $packageHash => $package) {
 21184 if (!isset($roots[$packageHash])) {
 21185 continue;
 21186 }
 21187 
 21188 foreach ($package->getRequires() as $link) {
 21189 $possibleRequires = $this->getProvidersInResult($link);
 21190 
 21191 foreach ($possibleRequires as $require) {
 21192 if ($require !== $package) {
 21193 unset($roots[spl_object_hash($require)]);
 21194 }
 21195 }
 21196 }
 21197 }
 21198 
 21199 return $roots;
 21200 }
 21201 
 21202 
 21203 
 21204 
 21205 protected function getProvidersInResult(Link $link)
 21206 {
 21207 if (!isset($this->resultPackagesByName[$link->getTarget()])) {
 21208 return array();
 21209 }
 21210 
 21211 return $this->resultPackagesByName[$link->getTarget()];
 21212 }
 21213 
 21214 
 21215 
 21216 
 21217 
 21218 
 21219 
 21220 
 21221 
 21222 
 21223 
 21224 
 21225 
 21226 
 21227 private function movePluginsToFront(array $operations)
 21228 {
 21229 $dlModifyingPluginsNoDeps = array();
 21230 $dlModifyingPluginsWithDeps = array();
 21231 $dlModifyingPluginRequires = array();
 21232 $pluginsNoDeps = array();
 21233 $pluginsWithDeps = array();
 21234 $pluginRequires = array();
 21235 
 21236 foreach (array_reverse($operations, true) as $idx => $op) {
 21237 if ($op instanceof Operation\InstallOperation) {
 21238 $package = $op->getPackage();
 21239 } elseif ($op instanceof Operation\UpdateOperation) {
 21240 $package = $op->getTargetPackage();
 21241 } else {
 21242 continue;
 21243 }
 21244 
 21245 $isDownloadsModifyingPlugin = $package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true;
 21246 
 21247 
 21248 if ($isDownloadsModifyingPlugin || count(array_intersect($package->getNames(), $dlModifyingPluginRequires))) {
 21249 
 21250 $requires = array_filter(array_keys($package->getRequires()), function ($req) {
 21251 return !PlatformRepository::isPlatformPackage($req);
 21252 });
 21253 
 21254 
 21255 if ($isDownloadsModifyingPlugin && !count($requires)) {
 21256 
 21257 array_unshift($dlModifyingPluginsNoDeps, $op);
 21258 } else {
 21259 
 21260 $dlModifyingPluginRequires = array_merge($dlModifyingPluginRequires, $requires);
 21261 
 21262 array_unshift($dlModifyingPluginsWithDeps, $op);
 21263 }
 21264 
 21265 unset($operations[$idx]);
 21266 continue;
 21267 }
 21268 
 21269 
 21270 $isPlugin = $package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer';
 21271 
 21272 
 21273 if ($isPlugin || count(array_intersect($package->getNames(), $pluginRequires))) {
 21274 
 21275 $requires = array_filter(array_keys($package->getRequires()), function ($req) {
 21276 return !PlatformRepository::isPlatformPackage($req);
 21277 });
 21278 
 21279 
 21280 if ($isPlugin && !count($requires)) {
 21281 
 21282 array_unshift($pluginsNoDeps, $op);
 21283 } else {
 21284 
 21285 $pluginRequires = array_merge($pluginRequires, $requires);
 21286 
 21287 array_unshift($pluginsWithDeps, $op);
 21288 }
 21289 
 21290 unset($operations[$idx]);
 21291 }
 21292 }
 21293 
 21294 return array_merge($dlModifyingPluginsNoDeps, $dlModifyingPluginsWithDeps, $pluginsNoDeps, $pluginsWithDeps, $operations);
 21295 }
 21296 
 21297 
 21298 
 21299 
 21300 
 21301 
 21302 
 21303 
 21304 private function moveUninstallsToFront(array $operations)
 21305 {
 21306 $uninstOps = array();
 21307 foreach ($operations as $idx => $op) {
 21308 if ($op instanceof Operation\UninstallOperation || $op instanceof Operation\MarkAliasUninstalledOperation) {
 21309 $uninstOps[] = $op;
 21310 unset($operations[$idx]);
 21311 }
 21312 }
 21313 
 21314 return array_merge($uninstOps, $operations);
 21315 }
 21316 }
 21317 <?php
 21318 
 21319 
 21320 
 21321 
 21322 
 21323 
 21324 
 21325 
 21326 
 21327 
 21328 
 21329 namespace Composer\Downloader;
 21330 
 21331 use Composer\Package\PackageInterface;
 21332 use Symfony\Component\Finder\Finder;
 21333 use React\Promise\PromiseInterface;
 21334 use Composer\DependencyResolver\Operation\InstallOperation;
 21335 
 21336 
 21337 
 21338 
 21339 
 21340 
 21341 
 21342 
 21343 abstract class ArchiveDownloader extends FileDownloader
 21344 {
 21345 
 21346 
 21347 
 21348 
 21349 public $cleanupExecuted = array();
 21350 
 21351 
 21352 
 21353 
 21354 public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
 21355 {
 21356 unset($this->cleanupExecuted[$package->getName()]);
 21357 
 21358 return parent::prepare($type, $package, $path, $prevPackage);
 21359 }
 21360 
 21361 
 21362 
 21363 
 21364 public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
 21365 {
 21366 $this->cleanupExecuted[$package->getName()] = true;
 21367 
 21368 return parent::cleanup($type, $package, $path, $prevPackage);
 21369 }
 21370 
 21371 
 21372 
 21373 
 21374 
 21375 
 21376 
 21377 
 21378 
 21379 
 21380 
 21381 public function install(PackageInterface $package, $path, $output = true)
 21382 {
 21383 if ($output) {
 21384 $this->io->writeError("  - " . InstallOperation::format($package) . $this->getInstallOperationAppendix($package, $path));
 21385 }
 21386 
 21387 $vendorDir = $this->config->get('vendor-dir');
 21388 
 21389 
 21390 
 21391 
 21392 if (false === strpos($this->filesystem->normalizePath($vendorDir), $this->filesystem->normalizePath($path.DIRECTORY_SEPARATOR))) {
 21393 $this->filesystem->emptyDirectory($path);
 21394 }
 21395 
 21396 do {
 21397 $temporaryDir = $vendorDir.'/composer/'.substr(md5(uniqid('', true)), 0, 8);
 21398 } while (is_dir($temporaryDir));
 21399 
 21400 $this->addCleanupPath($package, $temporaryDir);
 21401 
 21402 
 21403 if (!is_dir($path) || realpath($path) !== getcwd()) {
 21404 $this->addCleanupPath($package, $path);
 21405 }
 21406 
 21407 $this->filesystem->ensureDirectoryExists($temporaryDir);
 21408 $fileName = $this->getFileName($package, $path);
 21409 
 21410 $filesystem = $this->filesystem;
 21411 $self = $this;
 21412 
 21413 $cleanup = function () use ($path, $filesystem, $temporaryDir, $package, $self) {
 21414 
 21415 $self->clearLastCacheWrite($package);
 21416 
 21417 
 21418 $filesystem->removeDirectory($temporaryDir);
 21419 if (is_dir($path) && realpath($path) !== getcwd()) {
 21420 $filesystem->removeDirectory($path);
 21421 }
 21422 $self->removeCleanupPath($package, $temporaryDir);
 21423 $self->removeCleanupPath($package, realpath($path));
 21424 };
 21425 
 21426 $promise = null;
 21427 try {
 21428 $promise = $this->extract($package, $fileName, $temporaryDir);
 21429 } catch (\Exception $e) {
 21430 $cleanup();
 21431 throw $e;
 21432 }
 21433 
 21434 if (!$promise instanceof PromiseInterface) {
 21435 $promise = \React\Promise\resolve();
 21436 }
 21437 
 21438 return $promise->then(function () use ($self, $package, $filesystem, $fileName, $temporaryDir, $path) {
 21439 $filesystem->unlink($fileName);
 21440 
 21441 
 21442 
 21443 
 21444 
 21445 
 21446 
 21447 $getFolderContent = function ($dir) {
 21448 $finder = Finder::create()
 21449 ->ignoreVCS(false)
 21450 ->ignoreDotFiles(false)
 21451 ->notName('.DS_Store')
 21452 ->depth(0)
 21453 ->in($dir);
 21454 
 21455 return iterator_to_array($finder);
 21456 };
 21457 $renameRecursively = null;
 21458 
 21459 
 21460 
 21461 
 21462 
 21463 
 21464 
 21465 
 21466 
 21467 
 21468 
 21469 $renameRecursively = function ($from, $to) use ($filesystem, $getFolderContent, $package, &$renameRecursively) {
 21470 $contentDir = $getFolderContent($from);
 21471 
 21472 
 21473 foreach ($contentDir as $file) {
 21474 $file = (string) $file;
 21475 if (is_dir($to . '/' . basename($file))) {
 21476 if (!is_dir($file)) {
 21477 throw new \RuntimeException('Installing '.$package.' would lead to overwriting the '.$to.'/'.basename($file).' directory with a file from the package, invalid operation.');
 21478 }
 21479 $renameRecursively($file, $to . '/' . basename($file));
 21480 } else {
 21481 $filesystem->rename($file, $to . '/' . basename($file));
 21482 }
 21483 }
 21484 };
 21485 
 21486 $renameAsOne = false;
 21487 if (!file_exists($path)) {
 21488 $renameAsOne = true;
 21489 } elseif ($filesystem->isDirEmpty($path)) {
 21490 try {
 21491 if ($filesystem->removeDirectoryPhp($path)) {
 21492 $renameAsOne = true;
 21493 }
 21494 } catch (\RuntimeException $e) {
 21495 
 21496 }
 21497 }
 21498 
 21499 $contentDir = $getFolderContent($temporaryDir);
 21500 $singleDirAtTopLevel = 1 === count($contentDir) && is_dir(reset($contentDir));
 21501 
 21502 if ($renameAsOne) {
 21503 
 21504 if ($singleDirAtTopLevel) {
 21505 $extractedDir = (string) reset($contentDir);
 21506 } else {
 21507 $extractedDir = $temporaryDir;
 21508 }
 21509 $filesystem->rename($extractedDir, $path);
 21510 } else {
 21511 
 21512 $from = $temporaryDir;
 21513 if ($singleDirAtTopLevel) {
 21514 $from = (string) reset($contentDir);
 21515 }
 21516 
 21517 $renameRecursively($from, $path);
 21518 }
 21519 
 21520 $promise = $filesystem->removeDirectoryAsync($temporaryDir);
 21521 
 21522 return $promise->then(function () use ($self, $package, $path, $temporaryDir) {
 21523 $self->removeCleanupPath($package, $temporaryDir);
 21524 $self->removeCleanupPath($package, $path);
 21525 });
 21526 }, function ($e) use ($cleanup) {
 21527 $cleanup();
 21528 
 21529 throw $e;
 21530 });
 21531 }
 21532 
 21533 
 21534 
 21535 
 21536 protected function getInstallOperationAppendix(PackageInterface $package, $path)
 21537 {
 21538 return ': Extracting archive';
 21539 }
 21540 
 21541 
 21542 
 21543 
 21544 
 21545 
 21546 
 21547 
 21548 
 21549 
 21550 abstract protected function extract(PackageInterface $package, $file, $path);
 21551 }
 21552 <?php
 21553 
 21554 
 21555 
 21556 
 21557 
 21558 
 21559 
 21560 
 21561 
 21562 
 21563 
 21564 namespace Composer\Downloader;
 21565 
 21566 use Composer\Package\PackageInterface;
 21567 
 21568 
 21569 
 21570 
 21571 
 21572 
 21573 interface ChangeReportInterface
 21574 {
 21575 
 21576 
 21577 
 21578 
 21579 
 21580 
 21581 
 21582 public function getLocalChanges(PackageInterface $package, $path);
 21583 }
 21584 <?php
 21585 
 21586 
 21587 
 21588 
 21589 
 21590 
 21591 
 21592 
 21593 
 21594 
 21595 
 21596 namespace Composer\Downloader;
 21597 
 21598 use Composer\Package\PackageInterface;
 21599 use Composer\IO\IOInterface;
 21600 use Composer\Pcre\Preg;
 21601 use Composer\Util\Filesystem;
 21602 use Composer\Exception\IrrecoverableDownloadException;
 21603 use React\Promise\PromiseInterface;
 21604 
 21605 
 21606 
 21607 
 21608 
 21609 
 21610 class DownloadManager
 21611 {
 21612 
 21613 private $io;
 21614 
 21615 private $preferDist = false;
 21616 
 21617 private $preferSource;
 21618 
 21619 private $packagePreferences = array();
 21620 
 21621 private $filesystem;
 21622 
 21623 private $downloaders = array();
 21624 
 21625 
 21626 
 21627 
 21628 
 21629 
 21630 
 21631 
 21632 public function __construct(IOInterface $io, $preferSource = false, Filesystem $filesystem = null)
 21633 {
 21634 $this->io = $io;
 21635 $this->preferSource = $preferSource;
 21636 $this->filesystem = $filesystem ?: new Filesystem();
 21637 }
 21638 
 21639 
 21640 
 21641 
 21642 
 21643 
 21644 
 21645 public function setPreferSource($preferSource)
 21646 {
 21647 $this->preferSource = $preferSource;
 21648 
 21649 return $this;
 21650 }
 21651 
 21652 
 21653 
 21654 
 21655 
 21656 
 21657 
 21658 public function setPreferDist($preferDist)
 21659 {
 21660 $this->preferDist = $preferDist;
 21661 
 21662 return $this;
 21663 }
 21664 
 21665 
 21666 
 21667 
 21668 
 21669 
 21670 
 21671 
 21672 public function setPreferences(array $preferences)
 21673 {
 21674 $this->packagePreferences = $preferences;
 21675 
 21676 return $this;
 21677 }
 21678 
 21679 
 21680 
 21681 
 21682 
 21683 
 21684 
 21685 
 21686 public function setDownloader($type, DownloaderInterface $downloader)
 21687 {
 21688 $type = strtolower($type);
 21689 $this->downloaders[$type] = $downloader;
 21690 
 21691 return $this;
 21692 }
 21693 
 21694 
 21695 
 21696 
 21697 
 21698 
 21699 
 21700 
 21701 public function getDownloader($type)
 21702 {
 21703 $type = strtolower($type);
 21704 if (!isset($this->downloaders[$type])) {
 21705 throw new \InvalidArgumentException(sprintf('Unknown downloader type: %s. Available types: %s.', $type, implode(', ', array_keys($this->downloaders))));
 21706 }
 21707 
 21708 return $this->downloaders[$type];
 21709 }
 21710 
 21711 
 21712 
 21713 
 21714 
 21715 
 21716 
 21717 
 21718 
 21719 
 21720 public function getDownloaderForPackage(PackageInterface $package)
 21721 {
 21722 $installationSource = $package->getInstallationSource();
 21723 
 21724 if ('metapackage' === $package->getType()) {
 21725 return null;
 21726 }
 21727 
 21728 if ('dist' === $installationSource) {
 21729 $downloader = $this->getDownloader($package->getDistType());
 21730 } elseif ('source' === $installationSource) {
 21731 $downloader = $this->getDownloader($package->getSourceType());
 21732 } else {
 21733 throw new \InvalidArgumentException(
 21734 'Package '.$package.' does not have an installation source set'
 21735 );
 21736 }
 21737 
 21738 if ($installationSource !== $downloader->getInstallationSource()) {
 21739 throw new \LogicException(sprintf(
 21740 'Downloader "%s" is a %s type downloader and can not be used to download %s for package %s',
 21741 get_class($downloader),
 21742 $downloader->getInstallationSource(),
 21743 $installationSource,
 21744 $package
 21745 ));
 21746 }
 21747 
 21748 return $downloader;
 21749 }
 21750 
 21751 
 21752 
 21753 
 21754 public function getDownloaderType(DownloaderInterface $downloader)
 21755 {
 21756 return array_search($downloader, $this->downloaders);
 21757 }
 21758 
 21759 
 21760 
 21761 
 21762 
 21763 
 21764 
 21765 
 21766 
 21767 
 21768 
 21769 
 21770 public function download(PackageInterface $package, $targetDir, PackageInterface $prevPackage = null)
 21771 {
 21772 $targetDir = $this->normalizeTargetDir($targetDir);
 21773 $this->filesystem->ensureDirectoryExists(dirname($targetDir));
 21774 
 21775 $sources = $this->getAvailableSources($package, $prevPackage);
 21776 
 21777 $io = $this->io;
 21778 $self = $this;
 21779 
 21780 $download = function ($retry = false) use (&$sources, $io, $package, $self, $targetDir, &$download, $prevPackage) {
 21781 $source = array_shift($sources);
 21782 if ($retry) {
 21783 $io->writeError('    <warning>Now trying to download from ' . $source . '</warning>');
 21784 }
 21785 $package->setInstallationSource($source);
 21786 
 21787 $downloader = $self->getDownloaderForPackage($package);
 21788 if (!$downloader) {
 21789 return \React\Promise\resolve();
 21790 }
 21791 
 21792 $handleError = function ($e) use ($sources, $source, $package, $io, $download) {
 21793 if ($e instanceof \RuntimeException && !$e instanceof IrrecoverableDownloadException) {
 21794 if (!$sources) {
 21795 throw $e;
 21796 }
 21797 
 21798 $io->writeError(
 21799 '    <warning>Failed to download '.
 21800 $package->getPrettyName().
 21801 ' from ' . $source . ': '.
 21802 $e->getMessage().'</warning>'
 21803 );
 21804 
 21805 return $download(true);
 21806 }
 21807 
 21808 throw $e;
 21809 };
 21810 
 21811 try {
 21812 $result = $downloader->download($package, $targetDir, $prevPackage);
 21813 } catch (\Exception $e) {
 21814 return $handleError($e);
 21815 }
 21816 if (!$result instanceof PromiseInterface) {
 21817 return \React\Promise\resolve($result);
 21818 }
 21819 
 21820 $res = $result->then(function ($res) {
 21821 return $res;
 21822 }, $handleError);
 21823 
 21824 return $res;
 21825 };
 21826 
 21827 return $download();
 21828 }
 21829 
 21830 
 21831 
 21832 
 21833 
 21834 
 21835 
 21836 
 21837 
 21838 
 21839 
 21840 public function prepare($type, PackageInterface $package, $targetDir, PackageInterface $prevPackage = null)
 21841 {
 21842 $targetDir = $this->normalizeTargetDir($targetDir);
 21843 $downloader = $this->getDownloaderForPackage($package);
 21844 if ($downloader) {
 21845 return $downloader->prepare($type, $package, $targetDir, $prevPackage);
 21846 }
 21847 
 21848 return \React\Promise\resolve();
 21849 }
 21850 
 21851 
 21852 
 21853 
 21854 
 21855 
 21856 
 21857 
 21858 
 21859 
 21860 
 21861 public function install(PackageInterface $package, $targetDir)
 21862 {
 21863 $targetDir = $this->normalizeTargetDir($targetDir);
 21864 $downloader = $this->getDownloaderForPackage($package);
 21865 if ($downloader) {
 21866 return $downloader->install($package, $targetDir);
 21867 }
 21868 
 21869 return \React\Promise\resolve();
 21870 }
 21871 
 21872 
 21873 
 21874 
 21875 
 21876 
 21877 
 21878 
 21879 
 21880 
 21881 
 21882 public function update(PackageInterface $initial, PackageInterface $target, $targetDir)
 21883 {
 21884 $targetDir = $this->normalizeTargetDir($targetDir);
 21885 $downloader = $this->getDownloaderForPackage($target);
 21886 $initialDownloader = $this->getDownloaderForPackage($initial);
 21887 
 21888 
 21889 if (!$initialDownloader && !$downloader) {
 21890 return \React\Promise\resolve();
 21891 }
 21892 
 21893 
 21894 if (!$downloader) {
 21895 return $initialDownloader->remove($initial, $targetDir);
 21896 }
 21897 
 21898 $initialType = $this->getDownloaderType($initialDownloader);
 21899 $targetType = $this->getDownloaderType($downloader);
 21900 if ($initialType === $targetType) {
 21901 try {
 21902 return $downloader->update($initial, $target, $targetDir);
 21903 } catch (\RuntimeException $e) {
 21904 if (!$this->io->isInteractive()) {
 21905 throw $e;
 21906 }
 21907 $this->io->writeError('<error>    Update failed ('.$e->getMessage().')</error>');
 21908 if (!$this->io->askConfirmation('    Would you like to try reinstalling the package instead [<comment>yes</comment>]? ')) {
 21909 throw $e;
 21910 }
 21911 }
 21912 }
 21913 
 21914 
 21915 
 21916 $promise = $initialDownloader->remove($initial, $targetDir);
 21917 if ($promise) {
 21918 $self = $this;
 21919 
 21920 return $promise->then(function ($res) use ($self, $target, $targetDir) {
 21921 return $self->install($target, $targetDir);
 21922 });
 21923 }
 21924 
 21925 return $this->install($target, $targetDir);
 21926 }
 21927 
 21928 
 21929 
 21930 
 21931 
 21932 
 21933 
 21934 
 21935 
 21936 public function remove(PackageInterface $package, $targetDir)
 21937 {
 21938 $targetDir = $this->normalizeTargetDir($targetDir);
 21939 $downloader = $this->getDownloaderForPackage($package);
 21940 if ($downloader) {
 21941 return $downloader->remove($package, $targetDir);
 21942 }
 21943 
 21944 return \React\Promise\resolve();
 21945 }
 21946 
 21947 
 21948 
 21949 
 21950 
 21951 
 21952 
 21953 
 21954 
 21955 
 21956 
 21957 public function cleanup($type, PackageInterface $package, $targetDir, PackageInterface $prevPackage = null)
 21958 {
 21959 $targetDir = $this->normalizeTargetDir($targetDir);
 21960 $downloader = $this->getDownloaderForPackage($package);
 21961 if ($downloader) {
 21962 return $downloader->cleanup($type, $package, $targetDir, $prevPackage);
 21963 }
 21964 
 21965 return \React\Promise\resolve();
 21966 }
 21967 
 21968 
 21969 
 21970 
 21971 
 21972 
 21973 
 21974 
 21975 protected function resolvePackageInstallPreference(PackageInterface $package)
 21976 {
 21977 foreach ($this->packagePreferences as $pattern => $preference) {
 21978 $pattern = '{^'.str_replace('\\*', '.*', preg_quote($pattern)).'$}i';
 21979 if (Preg::isMatch($pattern, $package->getName())) {
 21980 if ('dist' === $preference || (!$package->isDev() && 'auto' === $preference)) {
 21981 return 'dist';
 21982 }
 21983 
 21984 return 'source';
 21985 }
 21986 }
 21987 
 21988 return $package->isDev() ? 'source' : 'dist';
 21989 }
 21990 
 21991 
 21992 
 21993 
 21994 
 21995 private function getAvailableSources(PackageInterface $package, PackageInterface $prevPackage = null)
 21996 {
 21997 $sourceType = $package->getSourceType();
 21998 $distType = $package->getDistType();
 21999 
 22000 
 22001 $sources = array();
 22002 if ($sourceType) {
 22003 $sources[] = 'source';
 22004 }
 22005 if ($distType) {
 22006 $sources[] = 'dist';
 22007 }
 22008 
 22009 if (empty($sources)) {
 22010 throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified');
 22011 }
 22012 
 22013 if (
 22014 $prevPackage
 22015 
 22016 && in_array($prevPackage->getInstallationSource(), $sources, true)
 22017 
 22018 && !(!$prevPackage->isDev() && $prevPackage->getInstallationSource() === 'dist' && $package->isDev())
 22019 ) {
 22020 $prevSource = $prevPackage->getInstallationSource();
 22021 usort($sources, function ($a, $b) use ($prevSource) {
 22022 return $a === $prevSource ? -1 : 1;
 22023 });
 22024 
 22025 return $sources;
 22026 }
 22027 
 22028 
 22029 if (!$this->preferSource && ($this->preferDist || 'dist' === $this->resolvePackageInstallPreference($package))) {
 22030 $sources = array_reverse($sources);
 22031 }
 22032 
 22033 return $sources;
 22034 }
 22035 
 22036 
 22037 
 22038 
 22039 
 22040 
 22041 
 22042 
 22043 
 22044 
 22045 private function normalizeTargetDir($dir)
 22046 {
 22047 if ($dir === '\\' || $dir === '/') {
 22048 return $dir;
 22049 }
 22050 
 22051 return rtrim($dir, '\\/');
 22052 }
 22053 }
 22054 <?php
 22055 
 22056 
 22057 
 22058 
 22059 
 22060 
 22061 
 22062 
 22063 
 22064 
 22065 
 22066 namespace Composer\Downloader;
 22067 
 22068 use Composer\Package\PackageInterface;
 22069 use React\Promise\PromiseInterface;
 22070 
 22071 
 22072 
 22073 
 22074 
 22075 
 22076 
 22077 interface DownloaderInterface
 22078 {
 22079 
 22080 
 22081 
 22082 
 22083 
 22084 public function getInstallationSource();
 22085 
 22086 
 22087 
 22088 
 22089 
 22090 
 22091 
 22092 public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null);
 22093 
 22094 
 22095 
 22096 
 22097 
 22098 
 22099 
 22100 
 22101 
 22102 
 22103 
 22104 
 22105 
 22106 
 22107 
 22108 public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null);
 22109 
 22110 
 22111 
 22112 
 22113 
 22114 
 22115 
 22116 
 22117 public function install(PackageInterface $package, $path);
 22118 
 22119 
 22120 
 22121 
 22122 
 22123 
 22124 
 22125 
 22126 
 22127 public function update(PackageInterface $initial, PackageInterface $target, $path);
 22128 
 22129 
 22130 
 22131 
 22132 
 22133 
 22134 
 22135 
 22136 public function remove(PackageInterface $package, $path);
 22137 
 22138 
 22139 
 22140 
 22141 
 22142 
 22143 
 22144 
 22145 
 22146 
 22147 
 22148 
 22149 
 22150 
 22151 public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null);
 22152 }
 22153 <?php
 22154 
 22155 
 22156 
 22157 
 22158 
 22159 
 22160 
 22161 
 22162 
 22163 
 22164 
 22165 namespace Composer\Downloader;
 22166 
 22167 use Composer\Package\PackageInterface;
 22168 
 22169 
 22170 
 22171 
 22172 
 22173 
 22174 interface DvcsDownloaderInterface
 22175 {
 22176 
 22177 
 22178 
 22179 
 22180 
 22181 
 22182 
 22183 public function getUnpushedChanges(PackageInterface $package, $path);
 22184 }
 22185 <?php
 22186 
 22187 
 22188 
 22189 
 22190 
 22191 
 22192 
 22193 
 22194 
 22195 
 22196 
 22197 namespace Composer\Downloader;
 22198 
 22199 use Composer\Config;
 22200 use Composer\Cache;
 22201 use Composer\IO\IOInterface;
 22202 use Composer\IO\NullIO;
 22203 use Composer\Exception\IrrecoverableDownloadException;
 22204 use Composer\Package\Comparer\Comparer;
 22205 use Composer\DependencyResolver\Operation\UpdateOperation;
 22206 use Composer\DependencyResolver\Operation\InstallOperation;
 22207 use Composer\DependencyResolver\Operation\UninstallOperation;
 22208 use Composer\Package\PackageInterface;
 22209 use Composer\Plugin\PluginEvents;
 22210 use Composer\Plugin\PostFileDownloadEvent;
 22211 use Composer\Plugin\PreFileDownloadEvent;
 22212 use Composer\EventDispatcher\EventDispatcher;
 22213 use Composer\Util\Filesystem;
 22214 use Composer\Util\Silencer;
 22215 use Composer\Util\HttpDownloader;
 22216 use Composer\Util\Url as UrlUtil;
 22217 use Composer\Util\ProcessExecutor;
 22218 use React\Promise\PromiseInterface;
 22219 
 22220 
 22221 
 22222 
 22223 
 22224 
 22225 
 22226 
 22227 
 22228 class FileDownloader implements DownloaderInterface, ChangeReportInterface
 22229 {
 22230 
 22231 protected $io;
 22232 
 22233 protected $config;
 22234 
 22235 protected $httpDownloader;
 22236 
 22237 protected $filesystem;
 22238 
 22239 protected $cache;
 22240 
 22241 protected $eventDispatcher;
 22242 
 22243 protected $process;
 22244 
 22245 
 22246 
 22247 
 22248 
 22249 public static $downloadMetadata = array();
 22250 
 22251 
 22252 
 22253 
 22254 
 22255 
 22256 public $lastCacheWrites = array();
 22257 
 22258 private $additionalCleanupPaths = array();
 22259 
 22260 
 22261 
 22262 
 22263 
 22264 
 22265 
 22266 
 22267 
 22268 
 22269 
 22270 public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, Filesystem $filesystem = null, ProcessExecutor $process = null)
 22271 {
 22272 $this->io = $io;
 22273 $this->config = $config;
 22274 $this->eventDispatcher = $eventDispatcher;
 22275 $this->httpDownloader = $httpDownloader;
 22276 $this->cache = $cache;
 22277 $this->process = $process ?: new ProcessExecutor($io);
 22278 $this->filesystem = $filesystem ?: new Filesystem($this->process);
 22279 
 22280 if ($this->cache && $this->cache->gcIsNecessary()) {
 22281 $this->io->writeError('Running cache garbage collection', true, IOInterface::VERY_VERBOSE);
 22282 $this->cache->gc((int) $config->get('cache-files-ttl'), (int) $config->get('cache-files-maxsize'));
 22283 }
 22284 }
 22285 
 22286 
 22287 
 22288 
 22289 public function getInstallationSource()
 22290 {
 22291 return 'dist';
 22292 }
 22293 
 22294 
 22295 
 22296 
 22297 
 22298 
 22299 public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
 22300 {
 22301 if (!$package->getDistUrl()) {
 22302 throw new \InvalidArgumentException('The given package is missing url information');
 22303 }
 22304 
 22305 $cacheKeyGenerator = function (PackageInterface $package, $key) {
 22306 $cacheKey = sha1($key);
 22307 
 22308 return $package->getName().'/'.$cacheKey.'.'.$package->getDistType();
 22309 };
 22310 
 22311 $retries = 3;
 22312 $distUrls = $package->getDistUrls();
 22313 
 22314 $urls = array();
 22315 foreach ($distUrls as $index => $url) {
 22316 $processedUrl = $this->processUrl($package, $url);
 22317 $urls[$index] = array(
 22318 'base' => $url,
 22319 'processed' => $processedUrl,
 22320 
 22321 
 22322 
 22323 
 22324 'cacheKey' => $cacheKeyGenerator($package, $processedUrl),
 22325 );
 22326 }
 22327 
 22328 $fileName = $this->getFileName($package, $path);
 22329 $this->filesystem->ensureDirectoryExists($path);
 22330 $this->filesystem->ensureDirectoryExists(dirname($fileName));
 22331 
 22332 $io = $this->io;
 22333 $cache = $this->cache;
 22334 $httpDownloader = $this->httpDownloader;
 22335 $eventDispatcher = $this->eventDispatcher;
 22336 $filesystem = $this->filesystem;
 22337 $self = $this;
 22338 
 22339 $accept = null;
 22340 $reject = null;
 22341 $download = function () use ($io, $output, $httpDownloader, $cache, $cacheKeyGenerator, $eventDispatcher, $package, $fileName, &$urls, &$accept, &$reject, $self) {
 22342 
 22343 $url = reset($urls);
 22344 $index = key($urls);
 22345 
 22346 if ($eventDispatcher) {
 22347 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $httpDownloader, $url['processed'], 'package', $package);
 22348 $eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
 22349 if ($preFileDownloadEvent->getCustomCacheKey() !== null) {
 22350 $url['cacheKey'] = $cacheKeyGenerator($package, $preFileDownloadEvent->getCustomCacheKey());
 22351 } elseif ($preFileDownloadEvent->getProcessedUrl() !== $url['processed']) {
 22352 $url['cacheKey'] = $cacheKeyGenerator($package, $preFileDownloadEvent->getProcessedUrl());
 22353 }
 22354 $url['processed'] = $preFileDownloadEvent->getProcessedUrl();
 22355 }
 22356 
 22357 $urls[$index] = $url;
 22358 
 22359 $checksum = $package->getDistSha1Checksum();
 22360 $cacheKey = $url['cacheKey'];
 22361 
 22362 
 22363 if ($cache && (!$checksum || $checksum === $cache->sha1($cacheKey)) && $cache->copyTo($cacheKey, $fileName)) {
 22364 if ($output) {
 22365 $io->writeError("  - Loading <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>) from cache", true, IOInterface::VERY_VERBOSE);
 22366 }
 22367 
 22368 
 22369 
 22370 if (!$cache->isReadOnly()) {
 22371 $self->lastCacheWrites[$package->getName()] = $cacheKey;
 22372 }
 22373 $result = \React\Promise\resolve($fileName);
 22374 } else {
 22375 if ($output) {
 22376 $io->writeError("  - Downloading <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>)");
 22377 }
 22378 
 22379 $result = $httpDownloader->addCopy($url['processed'], $fileName, $package->getTransportOptions())
 22380 ->then($accept, $reject);
 22381 }
 22382 
 22383 return $result->then(function ($result) use ($fileName, $checksum, $url, $package, $eventDispatcher) {
 22384 
 22385 
 22386 
 22387 if (null === $result) {
 22388 return $fileName;
 22389 }
 22390 
 22391 if (!file_exists($fileName)) {
 22392 throw new \UnexpectedValueException($url['base'].' could not be saved to '.$fileName.', make sure the'
 22393 .' directory is writable and you have internet connectivity');
 22394 }
 22395 
 22396 if ($checksum && hash_file('sha1', $fileName) !== $checksum) {
 22397 throw new \UnexpectedValueException('The checksum verification of the file failed (downloaded from '.$url['base'].')');
 22398 }
 22399 
 22400 if ($eventDispatcher) {
 22401 $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, $fileName, $checksum, $url['processed'], 'package', $package);
 22402 $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
 22403 }
 22404 
 22405 return $fileName;
 22406 });
 22407 };
 22408 
 22409 $accept = function ($response) use ($cache, $package, $fileName, $self, &$urls) {
 22410 $url = reset($urls);
 22411 $cacheKey = $url['cacheKey'];
 22412 FileDownloader::$downloadMetadata[$package->getName()] = @filesize($fileName) ?: $response->getHeader('Content-Length') ?: '?';
 22413 
 22414 if ($cache && !$cache->isReadOnly()) {
 22415 $self->lastCacheWrites[$package->getName()] = $cacheKey;
 22416 $cache->copyFrom($cacheKey, $fileName);
 22417 }
 22418 
 22419 $response->collect();
 22420 
 22421 return $fileName;
 22422 };
 22423 
 22424 $reject = function ($e) use ($io, &$urls, $download, $fileName, $package, &$retries, $filesystem, $self) {
 22425 
 22426 if (file_exists($fileName)) {
 22427 $filesystem->unlink($fileName);
 22428 }
 22429 $self->clearLastCacheWrite($package);
 22430 
 22431 if ($e instanceof IrrecoverableDownloadException) {
 22432 throw $e;
 22433 }
 22434 
 22435 if ($e instanceof MaxFileSizeExceededException) {
 22436 throw $e;
 22437 }
 22438 
 22439 if ($e instanceof TransportException) {
 22440 
 22441 if ((0 !== $e->getCode() && !in_array($e->getCode(), array(500, 502, 503, 504))) || !$retries) {
 22442 $retries = 0;
 22443 }
 22444 }
 22445 
 22446 
 22447 if ($e instanceof TransportException && $e->getStatusCode() === 499) {
 22448 $retries = 0;
 22449 $urls = array();
 22450 }
 22451 
 22452 if ($retries) {
 22453 usleep(500000);
 22454 $retries--;
 22455 
 22456 return $download();
 22457 }
 22458 
 22459 array_shift($urls);
 22460 if ($urls) {
 22461 if ($io->isDebug()) {
 22462 $io->writeError('    Failed downloading '.$package->getName().': ['.get_class($e).'] '.$e->getCode().': '.$e->getMessage());
 22463 $io->writeError('    Trying the next URL for '.$package->getName());
 22464 } else {
 22465 $io->writeError('    Failed downloading '.$package->getName().', trying the next URL ('.$e->getCode().': '.$e->getMessage().')');
 22466 }
 22467 
 22468 $retries = 3;
 22469 usleep(100000);
 22470 
 22471 return $download();
 22472 }
 22473 
 22474 throw $e;
 22475 };
 22476 
 22477 return $download();
 22478 }
 22479 
 22480 
 22481 
 22482 
 22483 public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
 22484 {
 22485 return \React\Promise\resolve();
 22486 }
 22487 
 22488 
 22489 
 22490 
 22491 public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
 22492 {
 22493 $fileName = $this->getFileName($package, $path);
 22494 if (file_exists($fileName)) {
 22495 $this->filesystem->unlink($fileName);
 22496 }
 22497 
 22498 $dirsToCleanUp = array(
 22499 $this->config->get('vendor-dir').'/composer/',
 22500 $this->config->get('vendor-dir'),
 22501 $path,
 22502 );
 22503 
 22504 if (isset($this->additionalCleanupPaths[$package->getName()])) {
 22505 foreach ($this->additionalCleanupPaths[$package->getName()] as $path) {
 22506 $this->filesystem->remove($path);
 22507 }
 22508 }
 22509 
 22510 foreach ($dirsToCleanUp as $dir) {
 22511 if (is_dir($dir) && $this->filesystem->isDirEmpty($dir) && realpath($dir) !== getcwd()) {
 22512 $this->filesystem->removeDirectoryPhp($dir);
 22513 }
 22514 }
 22515 
 22516 return \React\Promise\resolve();
 22517 }
 22518 
 22519 
 22520 
 22521 
 22522 
 22523 
 22524 public function install(PackageInterface $package, $path, $output = true)
 22525 {
 22526 if ($output) {
 22527 $this->io->writeError("  - " . InstallOperation::format($package));
 22528 }
 22529 
 22530 $this->filesystem->emptyDirectory($path);
 22531 $this->filesystem->ensureDirectoryExists($path);
 22532 $this->filesystem->rename($this->getFileName($package, $path), $path . '/' . pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME));
 22533 
 22534 if ($package->getBinaries()) {
 22535 
 22536 
 22537 foreach ($package->getBinaries() as $bin) {
 22538 if (file_exists($path . '/' . $bin) && !is_executable($path . '/' . $bin)) {
 22539 Silencer::call('chmod', $path . '/' . $bin, 0777 & ~umask());
 22540 }
 22541 }
 22542 }
 22543 
 22544 return \React\Promise\resolve();
 22545 }
 22546 
 22547 
 22548 
 22549 
 22550 
 22551 
 22552 
 22553 public function clearLastCacheWrite(PackageInterface $package)
 22554 {
 22555 if ($this->cache && isset($this->lastCacheWrites[$package->getName()])) {
 22556 $this->cache->remove($this->lastCacheWrites[$package->getName()]);
 22557 unset($this->lastCacheWrites[$package->getName()]);
 22558 }
 22559 }
 22560 
 22561 
 22562 
 22563 
 22564 
 22565 
 22566 
 22567 
 22568 
 22569 public function addCleanupPath(PackageInterface $package, $path)
 22570 {
 22571 $this->additionalCleanupPaths[$package->getName()][] = $path;
 22572 }
 22573 
 22574 
 22575 
 22576 
 22577 
 22578 
 22579 
 22580 
 22581 
 22582 public function removeCleanupPath(PackageInterface $package, $path)
 22583 {
 22584 if (isset($this->additionalCleanupPaths[$package->getName()])) {
 22585 $idx = array_search($path, $this->additionalCleanupPaths[$package->getName()]);
 22586 if (false !== $idx) {
 22587 unset($this->additionalCleanupPaths[$package->getName()][$idx]);
 22588 }
 22589 }
 22590 }
 22591 
 22592 
 22593 
 22594 
 22595 public function update(PackageInterface $initial, PackageInterface $target, $path)
 22596 {
 22597 $this->io->writeError("  - " . UpdateOperation::format($initial, $target) . $this->getInstallOperationAppendix($target, $path));
 22598 
 22599 $promise = $this->remove($initial, $path, false);
 22600 if (!$promise instanceof PromiseInterface) {
 22601 $promise = \React\Promise\resolve();
 22602 }
 22603 $self = $this;
 22604 $io = $this->io;
 22605 
 22606 return $promise->then(function () use ($self, $target, $path) {
 22607 $promise = $self->install($target, $path, false);
 22608 
 22609 return $promise;
 22610 });
 22611 }
 22612 
 22613 
 22614 
 22615 
 22616 
 22617 
 22618 public function remove(PackageInterface $package, $path, $output = true)
 22619 {
 22620 if ($output) {
 22621 $this->io->writeError("  - " . UninstallOperation::format($package));
 22622 }
 22623 $promise = $this->filesystem->removeDirectoryAsync($path);
 22624 
 22625 return $promise->then(function ($result) use ($path) {
 22626 if (!$result) {
 22627 throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
 22628 }
 22629 });
 22630 }
 22631 
 22632 
 22633 
 22634 
 22635 
 22636 
 22637 
 22638 
 22639 protected function getFileName(PackageInterface $package, $path)
 22640 {
 22641 return rtrim($this->config->get('vendor-dir').'/composer/tmp-'.md5($package.spl_object_hash($package)).'.'.pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_EXTENSION), '.');
 22642 }
 22643 
 22644 
 22645 
 22646 
 22647 
 22648 
 22649 
 22650 
 22651 protected function getInstallOperationAppendix(PackageInterface $package, $path)
 22652 {
 22653 return '';
 22654 }
 22655 
 22656 
 22657 
 22658 
 22659 
 22660 
 22661 
 22662 
 22663 
 22664 protected function processUrl(PackageInterface $package, $url)
 22665 {
 22666 if (!extension_loaded('openssl') && 0 === strpos($url, 'https:')) {
 22667 throw new \RuntimeException('You must enable the openssl extension to download files via https');
 22668 }
 22669 
 22670 if ($package->getDistReference()) {
 22671 $url = UrlUtil::updateDistReference($this->config, $url, $package->getDistReference());
 22672 }
 22673 
 22674 return $url;
 22675 }
 22676 
 22677 
 22678 
 22679 
 22680 
 22681 public function getLocalChanges(PackageInterface $package, $targetDir)
 22682 {
 22683 $prevIO = $this->io;
 22684 
 22685 $this->io = new NullIO;
 22686 $this->io->loadConfiguration($this->config);
 22687 $e = null;
 22688 $output = '';
 22689 
 22690 $targetDir = Filesystem::trimTrailingSlash($targetDir);
 22691 try {
 22692 if (is_dir($targetDir.'_compare')) {
 22693 $this->filesystem->removeDirectory($targetDir.'_compare');
 22694 }
 22695 
 22696 $this->download($package, $targetDir.'_compare', null, false);
 22697 $this->httpDownloader->wait();
 22698 $this->install($package, $targetDir.'_compare', false);
 22699 $this->process->wait();
 22700 
 22701 $comparer = new Comparer();
 22702 $comparer->setSource($targetDir.'_compare');
 22703 $comparer->setUpdate($targetDir);
 22704 $comparer->doCompare();
 22705 $output = $comparer->getChanged(true, true);
 22706 $this->filesystem->removeDirectory($targetDir.'_compare');
 22707 } catch (\Exception $e) {
 22708 }
 22709 
 22710 $this->io = $prevIO;
 22711 
 22712 if ($e) {
 22713 throw $e;
 22714 }
 22715 
 22716 return trim($output);
 22717 }
 22718 }
 22719 <?php
 22720 
 22721 
 22722 
 22723 
 22724 
 22725 
 22726 
 22727 
 22728 
 22729 
 22730 
 22731 namespace Composer\Downloader;
 22732 
 22733 
 22734 
 22735 
 22736 
 22737 
 22738 class FilesystemException extends \Exception
 22739 {
 22740 
 22741 
 22742 
 22743 
 22744 
 22745 public function __construct($message = '', $code = 0, \Exception $previous = null)
 22746 {
 22747 parent::__construct("Filesystem exception: \n".$message, $code, $previous);
 22748 }
 22749 }
 22750 <?php
 22751 
 22752 
 22753 
 22754 
 22755 
 22756 
 22757 
 22758 
 22759 
 22760 
 22761 
 22762 namespace Composer\Downloader;
 22763 
 22764 use Composer\Package\PackageInterface;
 22765 use Composer\Pcre\Preg;
 22766 use Composer\Util\ProcessExecutor;
 22767 
 22768 
 22769 
 22770 
 22771 class FossilDownloader extends VcsDownloader
 22772 {
 22773 
 22774 
 22775 
 22776 protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
 22777 {
 22778 return \React\Promise\resolve();
 22779 }
 22780 
 22781 
 22782 
 22783 
 22784 protected function doInstall(PackageInterface $package, $path, $url)
 22785 {
 22786 
 22787 $this->config->prohibitUrlByConfig($url, $this->io);
 22788 
 22789 $url = ProcessExecutor::escape($url);
 22790 $ref = ProcessExecutor::escape($package->getSourceReference());
 22791 $repoFile = $path . '.fossil';
 22792 $this->io->writeError("Cloning ".$package->getSourceReference());
 22793 $command = sprintf('fossil clone -- %s %s', $url, ProcessExecutor::escape($repoFile));
 22794 if (0 !== $this->process->execute($command, $ignoredOutput)) {
 22795 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 22796 }
 22797 $command = sprintf('fossil open --nested -- %s', ProcessExecutor::escape($repoFile));
 22798 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
 22799 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 22800 }
 22801 $command = sprintf('fossil update -- %s', $ref);
 22802 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
 22803 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 22804 }
 22805 
 22806 return \React\Promise\resolve();
 22807 }
 22808 
 22809 
 22810 
 22811 
 22812 protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
 22813 {
 22814 
 22815 $this->config->prohibitUrlByConfig($url, $this->io);
 22816 
 22817 $ref = ProcessExecutor::escape($target->getSourceReference());
 22818 $this->io->writeError(" Updating to ".$target->getSourceReference());
 22819 
 22820 if (!$this->hasMetadataRepository($path)) {
 22821 throw new \RuntimeException('The .fslckout file is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
 22822 }
 22823 
 22824 $command = sprintf('fossil pull && fossil up %s', $ref);
 22825 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
 22826 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 22827 }
 22828 
 22829 return \React\Promise\resolve();
 22830 }
 22831 
 22832 
 22833 
 22834 
 22835 public function getLocalChanges(PackageInterface $package, $path)
 22836 {
 22837 if (!$this->hasMetadataRepository($path)) {
 22838 return null;
 22839 }
 22840 
 22841 $this->process->execute('fossil changes', $output, realpath($path));
 22842 
 22843 return trim($output) ?: null;
 22844 }
 22845 
 22846 
 22847 
 22848 
 22849 protected function getCommitLogs($fromReference, $toReference, $path)
 22850 {
 22851 $command = sprintf('fossil timeline -t ci -W 0 -n 0 before %s', ProcessExecutor::escape($toReference));
 22852 
 22853 if (0 !== $this->process->execute($command, $output, realpath($path))) {
 22854 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 22855 }
 22856 
 22857 $log = '';
 22858 $match = '/\d\d:\d\d:\d\d\s+\[' . $toReference . '\]/';
 22859 
 22860 foreach ($this->process->splitLines($output) as $line) {
 22861 if (Preg::isMatch($match, $line)) {
 22862 break;
 22863 }
 22864 $log .= $line;
 22865 }
 22866 
 22867 return $log;
 22868 }
 22869 
 22870 
 22871 
 22872 
 22873 protected function hasMetadataRepository($path)
 22874 {
 22875 return is_file($path . '/.fslckout') || is_file($path . '/_FOSSIL_');
 22876 }
 22877 }
 22878 <?php
 22879 
 22880 
 22881 
 22882 
 22883 
 22884 
 22885 
 22886 
 22887 
 22888 
 22889 
 22890 namespace Composer\Downloader;
 22891 
 22892 use Composer\Config;
 22893 use Composer\IO\IOInterface;
 22894 use Composer\Package\PackageInterface;
 22895 use Composer\Pcre\Preg;
 22896 use Composer\Util\Filesystem;
 22897 use Composer\Util\Git as GitUtil;
 22898 use Composer\Util\Url;
 22899 use Composer\Util\Platform;
 22900 use Composer\Util\ProcessExecutor;
 22901 use Composer\Cache;
 22902 use React\Promise\PromiseInterface;
 22903 
 22904 
 22905 
 22906 
 22907 class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
 22908 {
 22909 
 22910 
 22911 
 22912 
 22913 private $hasStashedChanges = array();
 22914 
 22915 
 22916 
 22917 
 22918 private $hasDiscardedChanges = array();
 22919 
 22920 
 22921 
 22922 private $gitUtil;
 22923 
 22924 
 22925 
 22926 
 22927 private $cachedPackages = array();
 22928 
 22929 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
 22930 {
 22931 parent::__construct($io, $config, $process, $fs);
 22932 $this->gitUtil = new GitUtil($this->io, $this->config, $this->process, $this->filesystem);
 22933 }
 22934 
 22935 
 22936 
 22937 
 22938 protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
 22939 {
 22940 GitUtil::cleanEnv();
 22941 
 22942 $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', $url).'/';
 22943 $gitVersion = GitUtil::getVersion($this->process);
 22944 
 22945 
 22946 if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=') && Cache::isUsable($cachePath)) {
 22947 $this->io->writeError("  - Syncing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>) into cache");
 22948 $this->io->writeError(sprintf('    Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
 22949 $ref = $package->getSourceReference();
 22950 if ($this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref) && is_dir($cachePath)) {
 22951 $this->cachedPackages[$package->getId()][$ref] = true;
 22952 }
 22953 } elseif (null === $gitVersion) {
 22954 throw new \RuntimeException('git was not found in your PATH, skipping source download');
 22955 }
 22956 
 22957 return \React\Promise\resolve();
 22958 }
 22959 
 22960 
 22961 
 22962 
 22963 protected function doInstall(PackageInterface $package, $path, $url)
 22964 {
 22965 GitUtil::cleanEnv();
 22966 $path = $this->normalizePath($path);
 22967 $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', $url).'/';
 22968 $ref = $package->getSourceReference();
 22969 $flag = Platform::isWindows() ? '/D ' : '';
 22970 
 22971 if (!empty($this->cachedPackages[$package->getId()][$ref])) {
 22972 $msg = "Cloning ".$this->getShortHash($ref).' from cache';
 22973 
 22974 $cloneFlags = '--dissociate --reference %cachePath% ';
 22975 $transportOptions = $package->getTransportOptions();
 22976 if (isset($transportOptions['git']['single_use_clone']) && $transportOptions['git']['single_use_clone']) {
 22977 $cloneFlags = '';
 22978 }
 22979 
 22980 $command =
 22981 'git clone --no-checkout %cachePath% %path% ' . $cloneFlags
 22982 . '&& cd '.$flag.'%path% '
 22983 . '&& git remote set-url origin -- %sanitizedUrl% && git remote add composer -- %sanitizedUrl%';
 22984 } else {
 22985 $msg = "Cloning ".$this->getShortHash($ref);
 22986 $command = 'git clone --no-checkout -- %url% %path% && cd '.$flag.'%path% && git remote add composer -- %url% && git fetch composer && git remote set-url origin -- %sanitizedUrl% && git remote set-url composer -- %sanitizedUrl%';
 22987 if (Platform::getEnv('COMPOSER_DISABLE_NETWORK')) {
 22988 throw new \RuntimeException('The required git reference for '.$package->getName().' is not in cache and network is disabled, aborting');
 22989 }
 22990 }
 22991 
 22992 $this->io->writeError($msg);
 22993 
 22994 $commandCallable = function ($url) use ($path, $command, $cachePath) {
 22995 return str_replace(
 22996 array('%url%', '%path%', '%cachePath%', '%sanitizedUrl%'),
 22997 array(
 22998 ProcessExecutor::escape($url),
 22999 ProcessExecutor::escape($path),
 23000 ProcessExecutor::escape($cachePath),
 23001 ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)),
 23002 ),
 23003 $command
 23004 );
 23005 };
 23006 
 23007 $this->gitUtil->runCommand($commandCallable, $url, $path, true);
 23008 $sourceUrl = $package->getSourceUrl();
 23009 if ($url !== $sourceUrl && $sourceUrl !== null) {
 23010 $this->updateOriginUrl($path, $sourceUrl);
 23011 } else {
 23012 $this->setPushUrl($path, $url);
 23013 }
 23014 
 23015 if ($newRef = $this->updateToCommit($package, $path, (string) $ref, $package->getPrettyVersion())) {
 23016 if ($package->getDistReference() === $package->getSourceReference()) {
 23017 $package->setDistReference($newRef);
 23018 }
 23019 $package->setSourceReference($newRef);
 23020 }
 23021 
 23022 return \React\Promise\resolve();
 23023 }
 23024 
 23025 
 23026 
 23027 
 23028 protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
 23029 {
 23030 GitUtil::cleanEnv();
 23031 $path = $this->normalizePath($path);
 23032 if (!$this->hasMetadataRepository($path)) {
 23033 throw new \RuntimeException('The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
 23034 }
 23035 
 23036 $cachePath = $this->config->get('cache-vcs-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', $url).'/';
 23037 $ref = $target->getSourceReference();
 23038 
 23039 if (!empty($this->cachedPackages[$target->getId()][$ref])) {
 23040 $msg = "Checking out ".$this->getShortHash($ref).' from cache';
 23041 $command = '(git rev-parse --quiet --verify %ref% || (git remote set-url composer -- %cachePath% && git fetch composer && git fetch --tags composer)) && git remote set-url composer -- %sanitizedUrl%';
 23042 } else {
 23043 $msg = "Checking out ".$this->getShortHash($ref);
 23044 $command = '(git remote set-url composer -- %url% && git rev-parse --quiet --verify %ref% || (git fetch composer && git fetch --tags composer)) && git remote set-url composer -- %sanitizedUrl%';
 23045 if (Platform::getEnv('COMPOSER_DISABLE_NETWORK')) {
 23046 throw new \RuntimeException('The required git reference for '.$target->getName().' is not in cache and network is disabled, aborting');
 23047 }
 23048 }
 23049 
 23050 $this->io->writeError($msg);
 23051 
 23052 $commandCallable = function ($url) use ($ref, $command, $cachePath) {
 23053 return str_replace(
 23054 array('%url%', '%ref%', '%cachePath%', '%sanitizedUrl%'),
 23055 array(
 23056 ProcessExecutor::escape($url),
 23057 ProcessExecutor::escape($ref.'^{commit}'),
 23058 ProcessExecutor::escape($cachePath),
 23059 ProcessExecutor::escape(Preg::replace('{://([^@]+?):(.+?)@}', '://', $url)),
 23060 ),
 23061 $command
 23062 );
 23063 };
 23064 
 23065 $this->gitUtil->runCommand($commandCallable, $url, $path);
 23066 if ($newRef = $this->updateToCommit($target, $path, (string) $ref, $target->getPrettyVersion())) {
 23067 if ($target->getDistReference() === $target->getSourceReference()) {
 23068 $target->setDistReference($newRef);
 23069 }
 23070 $target->setSourceReference($newRef);
 23071 }
 23072 
 23073 $updateOriginUrl = false;
 23074 if (
 23075 0 === $this->process->execute('git remote -v', $output, $path)
 23076 && Preg::isMatch('{^origin\s+(?P<url>\S+)}m', $output, $originMatch)
 23077 && Preg::isMatch('{^composer\s+(?P<url>\S+)}m', $output, $composerMatch)
 23078 ) {
 23079 if ($originMatch['url'] === $composerMatch['url'] && $composerMatch['url'] !== $target->getSourceUrl()) {
 23080 $updateOriginUrl = true;
 23081 }
 23082 }
 23083 if ($updateOriginUrl && $target->getSourceUrl() !== null) {
 23084 $this->updateOriginUrl($path, $target->getSourceUrl());
 23085 }
 23086 
 23087 return \React\Promise\resolve();
 23088 }
 23089 
 23090 
 23091 
 23092 
 23093 public function getLocalChanges(PackageInterface $package, $path)
 23094 {
 23095 GitUtil::cleanEnv();
 23096 if (!$this->hasMetadataRepository($path)) {
 23097 return null;
 23098 }
 23099 
 23100 $command = 'git status --porcelain --untracked-files=no';
 23101 if (0 !== $this->process->execute($command, $output, $path)) {
 23102 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23103 }
 23104 
 23105 return trim($output) ?: null;
 23106 }
 23107 
 23108 
 23109 
 23110 
 23111 public function getUnpushedChanges(PackageInterface $package, $path)
 23112 {
 23113 GitUtil::cleanEnv();
 23114 $path = $this->normalizePath($path);
 23115 if (!$this->hasMetadataRepository($path)) {
 23116 return null;
 23117 }
 23118 
 23119 $command = 'git show-ref --head -d';
 23120 if (0 !== $this->process->execute($command, $output, $path)) {
 23121 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23122 }
 23123 
 23124 $refs = trim($output);
 23125 if (!Preg::isMatch('{^([a-f0-9]+) HEAD$}mi', $refs, $match)) {
 23126 
 23127 return null;
 23128 }
 23129 
 23130 $headRef = $match[1];
 23131 if (!Preg::isMatchAll('{^'.$headRef.' refs/heads/(.+)$}mi', $refs, $matches)) {
 23132 
 23133 return null;
 23134 }
 23135 
 23136 $candidateBranches = $matches[1];
 23137 
 23138 $branch = $candidateBranches[0];
 23139 $unpushedChanges = null;
 23140 $branchNotFoundError = false;
 23141 
 23142 
 23143 for ($i = 0; $i <= 1; $i++) {
 23144 $remoteBranches = array();
 23145 
 23146 
 23147 foreach ($candidateBranches as $candidate) {
 23148 if (Preg::isMatchAll('{^[a-f0-9]+ refs/remotes/((?:[^/]+)/'.preg_quote($candidate).')$}mi', $refs, $matches)) {
 23149 foreach ($matches[1] as $match) {
 23150 $branch = $candidate;
 23151 $remoteBranches[] = $match;
 23152 }
 23153 break;
 23154 }
 23155 }
 23156 
 23157 
 23158 
 23159 
 23160 if (!$remoteBranches) {
 23161 $unpushedChanges = 'Branch ' . $branch . ' could not be found on any remote and appears to be unpushed';
 23162 $branchNotFoundError = true;
 23163 } else {
 23164 
 23165 
 23166 if ($branchNotFoundError) {
 23167 $unpushedChanges = null;
 23168 }
 23169 foreach ($remoteBranches as $remoteBranch) {
 23170 $command = sprintf('git diff --name-status %s...%s --', $remoteBranch, $branch);
 23171 if (0 !== $this->process->execute($command, $output, $path)) {
 23172 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23173 }
 23174 
 23175 $output = trim($output);
 23176 
 23177 if ($unpushedChanges === null || strlen($output) < strlen($unpushedChanges)) {
 23178 $unpushedChanges = $output;
 23179 }
 23180 }
 23181 }
 23182 
 23183 
 23184 
 23185 if ($unpushedChanges && $i === 0) {
 23186 $this->process->execute('git fetch --all', $output, $path);
 23187 
 23188 
 23189 $command = 'git show-ref --head -d';
 23190 if (0 !== $this->process->execute($command, $output, $path)) {
 23191 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23192 }
 23193 $refs = trim($output);
 23194 }
 23195 
 23196 
 23197 if (!$unpushedChanges) {
 23198 break;
 23199 }
 23200 }
 23201 
 23202 return $unpushedChanges;
 23203 }
 23204 
 23205 
 23206 
 23207 
 23208 protected function cleanChanges(PackageInterface $package, $path, $update)
 23209 {
 23210 GitUtil::cleanEnv();
 23211 $path = $this->normalizePath($path);
 23212 
 23213 $unpushed = $this->getUnpushedChanges($package, $path);
 23214 if ($unpushed && ($this->io->isInteractive() || $this->config->get('discard-changes') !== true)) {
 23215 throw new \RuntimeException('Source directory ' . $path . ' has unpushed changes on the current branch: '."\n".$unpushed);
 23216 }
 23217 
 23218 if (!$changes = $this->getLocalChanges($package, $path)) {
 23219 return \React\Promise\resolve();
 23220 }
 23221 
 23222 if (!$this->io->isInteractive()) {
 23223 $discardChanges = $this->config->get('discard-changes');
 23224 if (true === $discardChanges) {
 23225 return $this->discardChanges($path);
 23226 }
 23227 if ('stash' === $discardChanges) {
 23228 if (!$update) {
 23229 return parent::cleanChanges($package, $path, $update);
 23230 }
 23231 
 23232 return $this->stashChanges($path);
 23233 }
 23234 
 23235 return parent::cleanChanges($package, $path, $update);
 23236 }
 23237 
 23238 $changes = array_map(function ($elem) {
 23239 return '    '.$elem;
 23240 }, Preg::split('{\s*\r?\n\s*}', $changes));
 23241 $this->io->writeError('    <error>'.$package->getPrettyName().' has modified files:</error>');
 23242 $this->io->writeError(array_slice($changes, 0, 10));
 23243 if (count($changes) > 10) {
 23244 $this->io->writeError('    <info>' . (count($changes) - 10) . ' more files modified, choose "v" to view the full list</info>');
 23245 }
 23246 
 23247 while (true) {
 23248 switch ($this->io->ask('    <info>Discard changes [y,n,v,d,'.($update ? 's,' : '').'?]?</info> ', '?')) {
 23249 case 'y':
 23250 $this->discardChanges($path);
 23251 break 2;
 23252 
 23253 case 's':
 23254 if (!$update) {
 23255 goto help;
 23256 }
 23257 
 23258 $this->stashChanges($path);
 23259 break 2;
 23260 
 23261 case 'n':
 23262 throw new \RuntimeException('Update aborted');
 23263 
 23264 case 'v':
 23265 $this->io->writeError($changes);
 23266 break;
 23267 
 23268 case 'd':
 23269 $this->viewDiff($path);
 23270 break;
 23271 
 23272 case '?':
 23273 default:
 23274 help :
 23275 $this->io->writeError(array(
 23276 '    y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
 23277 '    n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
 23278 '    v - view modified files',
 23279 '    d - view local modifications (diff)',
 23280 ));
 23281 if ($update) {
 23282 $this->io->writeError('    s - stash changes and try to reapply them after the update');
 23283 }
 23284 $this->io->writeError('    ? - print help');
 23285 break;
 23286 }
 23287 }
 23288 
 23289 return \React\Promise\resolve();
 23290 }
 23291 
 23292 
 23293 
 23294 
 23295 protected function reapplyChanges($path)
 23296 {
 23297 $path = $this->normalizePath($path);
 23298 if (!empty($this->hasStashedChanges[$path])) {
 23299 unset($this->hasStashedChanges[$path]);
 23300 $this->io->writeError('    <info>Re-applying stashed changes</info>');
 23301 if (0 !== $this->process->execute('git stash pop', $output, $path)) {
 23302 throw new \RuntimeException("Failed to apply stashed changes:\n\n".$this->process->getErrorOutput());
 23303 }
 23304 }
 23305 
 23306 unset($this->hasDiscardedChanges[$path]);
 23307 }
 23308 
 23309 
 23310 
 23311 
 23312 
 23313 
 23314 
 23315 
 23316 
 23317 
 23318 protected function updateToCommit(PackageInterface $package, $path, $reference, $prettyVersion)
 23319 {
 23320 $force = !empty($this->hasDiscardedChanges[$path]) || !empty($this->hasStashedChanges[$path]) ? '-f ' : '';
 23321 
 23322 
 23323 
 23324 
 23325 
 23326 
 23327 $template = 'git checkout '.$force.'%s -- && git reset --hard %1$s --';
 23328 $branch = Preg::replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $prettyVersion);
 23329 
 23330 $branches = null;
 23331 if (0 === $this->process->execute('git branch -r', $output, $path)) {
 23332 $branches = $output;
 23333 }
 23334 
 23335 
 23336 $gitRef = $reference;
 23337 if (!Preg::isMatch('{^[a-f0-9]{40}$}', $reference)
 23338 && $branches
 23339 && Preg::isMatch('{^\s+composer/'.preg_quote($reference).'$}m', $branches)
 23340 ) {
 23341 $command = sprintf('git checkout '.$force.'-B %s %s -- && git reset --hard %2$s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$reference));
 23342 if (0 === $this->process->execute($command, $output, $path)) {
 23343 return null;
 23344 }
 23345 }
 23346 
 23347 
 23348 if (Preg::isMatch('{^[a-f0-9]{40}$}', $reference)) {
 23349 
 23350 if (!Preg::isMatch('{^\s+composer/'.preg_quote($branch).'$}m', $branches) && Preg::isMatch('{^\s+composer/v'.preg_quote($branch).'$}m', $branches)) {
 23351 $branch = 'v' . $branch;
 23352 }
 23353 
 23354 $command = sprintf('git checkout %s --', ProcessExecutor::escape($branch));
 23355 $fallbackCommand = sprintf('git checkout '.$force.'-B %s %s --', ProcessExecutor::escape($branch), ProcessExecutor::escape('composer/'.$branch));
 23356 $resetCommand = sprintf('git reset --hard %s --', ProcessExecutor::escape($reference));
 23357 
 23358 if (0 === $this->process->execute("($command || $fallbackCommand) && $resetCommand", $output, $path)) {
 23359 return null;
 23360 }
 23361 }
 23362 
 23363 $command = sprintf($template, ProcessExecutor::escape($gitRef));
 23364 if (0 === $this->process->execute($command, $output, $path)) {
 23365 return null;
 23366 }
 23367 
 23368 $exceptionExtra = '';
 23369 
 23370 
 23371 if (false !== strpos($this->process->getErrorOutput(), $reference)) {
 23372 $this->io->writeError('    <warning>'.$reference.' is gone (history was rewritten?)</warning>');
 23373 $exceptionExtra = "\nIt looks like the commit hash is not available in the repository, maybe ".($package->isDev() ? 'the commit was removed from the branch' : 'the tag was recreated').'? Run "composer update '.$package->getPrettyName().'" to resolve this.';
 23374 }
 23375 
 23376 throw new \RuntimeException(Url::sanitize('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput() . $exceptionExtra));
 23377 }
 23378 
 23379 
 23380 
 23381 
 23382 
 23383 
 23384 
 23385 protected function updateOriginUrl($path, $url)
 23386 {
 23387 $this->process->execute(sprintf('git remote set-url origin -- %s', ProcessExecutor::escape($url)), $output, $path);
 23388 $this->setPushUrl($path, $url);
 23389 }
 23390 
 23391 
 23392 
 23393 
 23394 
 23395 
 23396 
 23397 protected function setPushUrl($path, $url)
 23398 {
 23399 
 23400 if (Preg::isMatch('{^(?:https?|git)://'.GitUtil::getGitHubDomainsRegex($this->config).'/([^/]+)/([^/]+?)(?:\.git)?$}', $url, $match)) {
 23401 $protocols = $this->config->get('github-protocols');
 23402 $pushUrl = 'git@'.$match[1].':'.$match[2].'/'.$match[3].'.git';
 23403 if (!in_array('ssh', $protocols, true)) {
 23404 $pushUrl = 'https://' . $match[1] . '/'.$match[2].'/'.$match[3].'.git';
 23405 }
 23406 $cmd = sprintf('git remote set-url --push origin -- %s', ProcessExecutor::escape($pushUrl));
 23407 $this->process->execute($cmd, $ignoredOutput, $path);
 23408 }
 23409 }
 23410 
 23411 
 23412 
 23413 
 23414 protected function getCommitLogs($fromReference, $toReference, $path)
 23415 {
 23416 $path = $this->normalizePath($path);
 23417 $command = sprintf('git log %s..%s --pretty=format:"%%h - %%an: %%s"'.GitUtil::getNoShowSignatureFlag($this->process), ProcessExecutor::escape($fromReference), ProcessExecutor::escape($toReference));
 23418 
 23419 if (0 !== $this->process->execute($command, $output, $path)) {
 23420 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23421 }
 23422 
 23423 return $output;
 23424 }
 23425 
 23426 
 23427 
 23428 
 23429 
 23430 
 23431 
 23432 
 23433 protected function discardChanges($path)
 23434 {
 23435 $path = $this->normalizePath($path);
 23436 if (0 !== $this->process->execute('git clean -df && git reset --hard', $output, $path)) {
 23437 throw new \RuntimeException("Could not reset changes\n\n:".$output);
 23438 }
 23439 
 23440 $this->hasDiscardedChanges[$path] = true;
 23441 
 23442 return \React\Promise\resolve();
 23443 }
 23444 
 23445 
 23446 
 23447 
 23448 
 23449 
 23450 
 23451 
 23452 protected function stashChanges($path)
 23453 {
 23454 $path = $this->normalizePath($path);
 23455 if (0 !== $this->process->execute('git stash --include-untracked', $output, $path)) {
 23456 throw new \RuntimeException("Could not stash changes\n\n:".$output);
 23457 }
 23458 
 23459 $this->hasStashedChanges[$path] = true;
 23460 
 23461 return \React\Promise\resolve();
 23462 }
 23463 
 23464 
 23465 
 23466 
 23467 
 23468 
 23469 
 23470 
 23471 protected function viewDiff($path)
 23472 {
 23473 $path = $this->normalizePath($path);
 23474 if (0 !== $this->process->execute('git diff HEAD', $output, $path)) {
 23475 throw new \RuntimeException("Could not view diff\n\n:".$output);
 23476 }
 23477 
 23478 $this->io->writeError($output);
 23479 }
 23480 
 23481 
 23482 
 23483 
 23484 
 23485 
 23486 protected function normalizePath($path)
 23487 {
 23488 if (Platform::isWindows() && strlen($path) > 0) {
 23489 $basePath = $path;
 23490 $removed = array();
 23491 
 23492 while (!is_dir($basePath) && $basePath !== '\\') {
 23493 array_unshift($removed, basename($basePath));
 23494 $basePath = dirname($basePath);
 23495 }
 23496 
 23497 if ($basePath === '\\') {
 23498 return $path;
 23499 }
 23500 
 23501 $path = rtrim(realpath($basePath) . '/' . implode('/', $removed), '/');
 23502 }
 23503 
 23504 return $path;
 23505 }
 23506 
 23507 
 23508 
 23509 
 23510 protected function hasMetadataRepository($path)
 23511 {
 23512 $path = $this->normalizePath($path);
 23513 
 23514 return is_dir($path.'/.git');
 23515 }
 23516 
 23517 
 23518 
 23519 
 23520 
 23521 protected function getShortHash($reference)
 23522 {
 23523 if (!$this->io->isVerbose() && Preg::isMatch('{^[0-9a-f]{40}$}', $reference)) {
 23524 return substr($reference, 0, 10);
 23525 }
 23526 
 23527 return $reference;
 23528 }
 23529 }
 23530 <?php
 23531 
 23532 
 23533 
 23534 
 23535 
 23536 
 23537 
 23538 
 23539 
 23540 
 23541 
 23542 namespace Composer\Downloader;
 23543 
 23544 use Composer\Package\PackageInterface;
 23545 use Composer\Util\Platform;
 23546 use Composer\Util\ProcessExecutor;
 23547 
 23548 
 23549 
 23550 
 23551 
 23552 
 23553 class GzipDownloader extends ArchiveDownloader
 23554 {
 23555 protected function extract(PackageInterface $package, $file, $path)
 23556 {
 23557 $filename = pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_FILENAME);
 23558 $targetFilepath = $path . DIRECTORY_SEPARATOR . $filename;
 23559 
 23560 
 23561 if (!Platform::isWindows()) {
 23562 $command = 'gzip -cd -- ' . ProcessExecutor::escape($file) . ' > ' . ProcessExecutor::escape($targetFilepath);
 23563 
 23564 if (0 === $this->process->execute($command, $ignoredOutput)) {
 23565 return \React\Promise\resolve();
 23566 }
 23567 
 23568 if (extension_loaded('zlib')) {
 23569 
 23570 $this->extractUsingExt($file, $targetFilepath);
 23571 
 23572 return \React\Promise\resolve();
 23573 }
 23574 
 23575 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
 23576 throw new \RuntimeException($processError);
 23577 }
 23578 
 23579 
 23580 $this->extractUsingExt($file, $targetFilepath);
 23581 
 23582 return \React\Promise\resolve();
 23583 }
 23584 
 23585 
 23586 
 23587 
 23588 
 23589 
 23590 
 23591 private function extractUsingExt($file, $targetFilepath)
 23592 {
 23593 $archiveFile = gzopen($file, 'rb');
 23594 $targetFile = fopen($targetFilepath, 'wb');
 23595 while ($string = gzread($archiveFile, 4096)) {
 23596 fwrite($targetFile, $string, Platform::strlen($string));
 23597 }
 23598 gzclose($archiveFile);
 23599 fclose($targetFile);
 23600 }
 23601 }
 23602 <?php
 23603 
 23604 
 23605 
 23606 
 23607 
 23608 
 23609 
 23610 
 23611 
 23612 
 23613 
 23614 namespace Composer\Downloader;
 23615 
 23616 use Composer\Package\PackageInterface;
 23617 use Composer\Util\ProcessExecutor;
 23618 use Composer\Util\Hg as HgUtils;
 23619 
 23620 
 23621 
 23622 
 23623 class HgDownloader extends VcsDownloader
 23624 {
 23625 
 23626 
 23627 
 23628 protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
 23629 {
 23630 if (null === HgUtils::getVersion($this->process)) {
 23631 throw new \RuntimeException('hg was not found in your PATH, skipping source download');
 23632 }
 23633 
 23634 return \React\Promise\resolve();
 23635 }
 23636 
 23637 
 23638 
 23639 
 23640 protected function doInstall(PackageInterface $package, $path, $url)
 23641 {
 23642 $hgUtils = new HgUtils($this->io, $this->config, $this->process);
 23643 
 23644 $cloneCommand = function ($url) use ($path) {
 23645 return sprintf('hg clone -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($path));
 23646 };
 23647 
 23648 $hgUtils->runCommand($cloneCommand, $url, $path);
 23649 
 23650 $ref = ProcessExecutor::escape($package->getSourceReference());
 23651 $command = sprintf('hg up -- %s', $ref);
 23652 if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) {
 23653 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23654 }
 23655 
 23656 return \React\Promise\resolve();
 23657 }
 23658 
 23659 
 23660 
 23661 
 23662 protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
 23663 {
 23664 $hgUtils = new HgUtils($this->io, $this->config, $this->process);
 23665 
 23666 $ref = $target->getSourceReference();
 23667 $this->io->writeError(" Updating to ".$target->getSourceReference());
 23668 
 23669 if (!$this->hasMetadataRepository($path)) {
 23670 throw new \RuntimeException('The .hg directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
 23671 }
 23672 
 23673 $command = function ($url) use ($ref) {
 23674 return sprintf('hg pull -- %s && hg up -- %s', ProcessExecutor::escape($url), ProcessExecutor::escape($ref));
 23675 };
 23676 
 23677 $hgUtils->runCommand($command, $url, $path);
 23678 
 23679 return \React\Promise\resolve();
 23680 }
 23681 
 23682 
 23683 
 23684 
 23685 public function getLocalChanges(PackageInterface $package, $path)
 23686 {
 23687 if (!is_dir($path.'/.hg')) {
 23688 return null;
 23689 }
 23690 
 23691 $this->process->execute('hg st', $output, realpath($path));
 23692 
 23693 return trim($output) ?: null;
 23694 }
 23695 
 23696 
 23697 
 23698 
 23699 protected function getCommitLogs($fromReference, $toReference, $path)
 23700 {
 23701 $command = sprintf('hg log -r %s:%s --style compact', ProcessExecutor::escape($fromReference), ProcessExecutor::escape($toReference));
 23702 
 23703 if (0 !== $this->process->execute($command, $output, realpath($path))) {
 23704 throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());
 23705 }
 23706 
 23707 return $output;
 23708 }
 23709 
 23710 
 23711 
 23712 
 23713 protected function hasMetadataRepository($path)
 23714 {
 23715 return is_dir($path . '/.hg');
 23716 }
 23717 }
 23718 <?php
 23719 
 23720 
 23721 
 23722 
 23723 
 23724 
 23725 
 23726 
 23727 
 23728 
 23729 
 23730 namespace Composer\Downloader;
 23731 
 23732 class MaxFileSizeExceededException extends TransportException
 23733 {
 23734 }
 23735 <?php
 23736 
 23737 
 23738 
 23739 
 23740 
 23741 
 23742 
 23743 
 23744 
 23745 
 23746 
 23747 namespace Composer\Downloader;
 23748 
 23749 use Composer\Package\Archiver\ArchivableFilesFinder;
 23750 use Composer\Package\Dumper\ArrayDumper;
 23751 use Composer\Package\PackageInterface;
 23752 use Composer\Package\Version\VersionGuesser;
 23753 use Composer\Package\Version\VersionParser;
 23754 use Composer\Util\Platform;
 23755 use Composer\Util\Filesystem;
 23756 use Symfony\Component\Filesystem\Exception\IOException;
 23757 use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
 23758 use Composer\DependencyResolver\Operation\InstallOperation;
 23759 use Composer\DependencyResolver\Operation\UninstallOperation;
 23760 
 23761 
 23762 
 23763 
 23764 
 23765 
 23766 
 23767 class PathDownloader extends FileDownloader implements VcsCapableDownloaderInterface
 23768 {
 23769 const STRATEGY_SYMLINK = 10;
 23770 const STRATEGY_MIRROR = 20;
 23771 
 23772 
 23773 
 23774 
 23775 public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
 23776 {
 23777 $path = Filesystem::trimTrailingSlash($path);
 23778 $url = $package->getDistUrl();
 23779 $realUrl = realpath($url);
 23780 if (false === $realUrl || !file_exists($realUrl) || !is_dir($realUrl)) {
 23781 throw new \RuntimeException(sprintf(
 23782 'Source path "%s" is not found for package %s',
 23783 $url,
 23784 $package->getName()
 23785 ));
 23786 }
 23787 
 23788 if (realpath($path) === $realUrl) {
 23789 return \React\Promise\resolve();
 23790 }
 23791 
 23792 if (strpos(realpath($path) . DIRECTORY_SEPARATOR, $realUrl . DIRECTORY_SEPARATOR) === 0) {
 23793 
 23794 
 23795 
 23796 
 23797 throw new \RuntimeException(sprintf(
 23798 'Package %s cannot install to "%s" inside its source at "%s"',
 23799 $package->getName(),
 23800 realpath($path),
 23801 $realUrl
 23802 ));
 23803 }
 23804 
 23805 return \React\Promise\resolve();
 23806 }
 23807 
 23808 
 23809 
 23810 
 23811 public function install(PackageInterface $package, $path, $output = true)
 23812 {
 23813 $path = Filesystem::trimTrailingSlash($path);
 23814 $url = $package->getDistUrl();
 23815 $realUrl = realpath($url);
 23816 
 23817 if (realpath($path) === $realUrl) {
 23818 if ($output) {
 23819 $this->io->writeError("  - " . InstallOperation::format($package) . $this->getInstallOperationAppendix($package, $path));
 23820 }
 23821 
 23822 return \React\Promise\resolve();
 23823 }
 23824 
 23825 
 23826 $transportOptions = $package->getTransportOptions() + array('relative' => true);
 23827 
 23828 list($currentStrategy, $allowedStrategies) = $this->computeAllowedStrategies($transportOptions);
 23829 
 23830 $symfonyFilesystem = new SymfonyFilesystem();
 23831 $this->filesystem->removeDirectory($path);
 23832 
 23833 if ($output) {
 23834 $this->io->writeError("  - " . InstallOperation::format($package).': ', false);
 23835 }
 23836 
 23837 $isFallback = false;
 23838 if (self::STRATEGY_SYMLINK === $currentStrategy) {
 23839 try {
 23840 if (Platform::isWindows()) {
 23841 
 23842 if ($output) {
 23843 $this->io->writeError(sprintf('Junctioning from %s', $url), false);
 23844 }
 23845 $this->filesystem->junction($realUrl, $path);
 23846 } else {
 23847 $absolutePath = $path;
 23848 if (!$this->filesystem->isAbsolutePath($absolutePath)) {
 23849 $absolutePath = getcwd() . DIRECTORY_SEPARATOR . $path;
 23850 }
 23851 $shortestPath = $this->filesystem->findShortestPath($absolutePath, $realUrl);
 23852 $path = rtrim($path, "/");
 23853 if ($output) {
 23854 $this->io->writeError(sprintf('Symlinking from %s', $url), false);
 23855 }
 23856 if ($transportOptions['relative']) {
 23857 $symfonyFilesystem->symlink($shortestPath, $path);
 23858 } else {
 23859 $symfonyFilesystem->symlink($realUrl, $path);
 23860 }
 23861 }
 23862 } catch (IOException $e) {
 23863 if (in_array(self::STRATEGY_MIRROR, $allowedStrategies, true)) {
 23864 if ($output) {
 23865 $this->io->writeError('');
 23866 $this->io->writeError('    <error>Symlink failed, fallback to use mirroring!</error>');
 23867 }
 23868 $currentStrategy = self::STRATEGY_MIRROR;
 23869 $isFallback = true;
 23870 } else {
 23871 throw new \RuntimeException(sprintf('Symlink from "%s" to "%s" failed!', $realUrl, $path));
 23872 }
 23873 }
 23874 }
 23875 
 23876 
 23877 if (self::STRATEGY_MIRROR === $currentStrategy) {
 23878 $realUrl = $this->filesystem->normalizePath($realUrl);
 23879 
 23880 if ($output) {
 23881 $this->io->writeError(sprintf('%sMirroring from %s', $isFallback ? '    ' : '', $url), false);
 23882 }
 23883 $iterator = new ArchivableFilesFinder($realUrl, array());
 23884 $symfonyFilesystem->mirror($realUrl, $path, $iterator);
 23885 }
 23886 
 23887 if ($output) {
 23888 $this->io->writeError('');
 23889 }
 23890 
 23891 return \React\Promise\resolve();
 23892 }
 23893 
 23894 
 23895 
 23896 
 23897 public function remove(PackageInterface $package, $path, $output = true)
 23898 {
 23899 $path = Filesystem::trimTrailingSlash($path);
 23900 
 23901 
 23902 
 23903 
 23904 
 23905 
 23906 
 23907 
 23908 
 23909 if (Platform::isWindows() && $this->filesystem->isJunction($path)) {
 23910 if ($output) {
 23911 $this->io->writeError("  - " . UninstallOperation::format($package).", source is still present in $path");
 23912 }
 23913 if (!$this->filesystem->removeJunction($path)) {
 23914 $this->io->writeError("    <warning>Could not remove junction at " . $path . " - is another process locking it?</warning>");
 23915 throw new \RuntimeException('Could not reliably remove junction for package ' . $package->getName());
 23916 }
 23917 
 23918 return \React\Promise\resolve();
 23919 }
 23920 
 23921 
 23922 
 23923 
 23924 
 23925 $fs = new Filesystem;
 23926 $absPath = $fs->isAbsolutePath($path) ? $path : getcwd() . '/' . $path;
 23927 $absDistUrl = $fs->isAbsolutePath($package->getDistUrl()) ? $package->getDistUrl() : getcwd() . '/' . $package->getDistUrl();
 23928 if ($fs->normalizePath($absPath) === $fs->normalizePath($absDistUrl)) {
 23929 if ($output) {
 23930 $this->io->writeError("  - " . UninstallOperation::format($package).", source is still present in $path");
 23931 }
 23932 
 23933 return \React\Promise\resolve();
 23934 }
 23935 
 23936 return parent::remove($package, $path, $output);
 23937 }
 23938 
 23939 
 23940 
 23941 
 23942 public function getVcsReference(PackageInterface $package, $path)
 23943 {
 23944 $path = Filesystem::trimTrailingSlash($path);
 23945 $parser = new VersionParser;
 23946 $guesser = new VersionGuesser($this->config, $this->process, $parser);
 23947 $dumper = new ArrayDumper;
 23948 
 23949 $packageConfig = $dumper->dump($package);
 23950 if ($packageVersion = $guesser->guessVersion($packageConfig, $path)) {
 23951 return $packageVersion['commit'];
 23952 }
 23953 
 23954 return null;
 23955 }
 23956 
 23957 
 23958 
 23959 
 23960 protected function getInstallOperationAppendix(PackageInterface $package, $path)
 23961 {
 23962 $realUrl = realpath($package->getDistUrl());
 23963 
 23964 if (realpath($path) === $realUrl) {
 23965 return ': Source already present';
 23966 }
 23967 
 23968 list($currentStrategy) = $this->computeAllowedStrategies($package->getTransportOptions());
 23969 
 23970 if ($currentStrategy === self::STRATEGY_SYMLINK) {
 23971 if (Platform::isWindows()) {
 23972 return ': Junctioning from '.$package->getDistUrl();
 23973 }
 23974 
 23975 return ': Symlinking from '.$package->getDistUrl();
 23976 }
 23977 
 23978 return ': Mirroring from '.$package->getDistUrl();
 23979 }
 23980 
 23981 
 23982 
 23983 
 23984 
 23985 
 23986 private function computeAllowedStrategies(array $transportOptions)
 23987 {
 23988 
 23989 $currentStrategy = self::STRATEGY_SYMLINK;
 23990 $allowedStrategies = array(self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR);
 23991 
 23992 $mirrorPathRepos = Platform::getEnv('COMPOSER_MIRROR_PATH_REPOS');
 23993 if ($mirrorPathRepos) {
 23994 $currentStrategy = self::STRATEGY_MIRROR;
 23995 }
 23996 
 23997 $symlinkOption = isset($transportOptions['symlink']) ? $transportOptions['symlink'] : null;
 23998 
 23999 if (true === $symlinkOption) {
 24000 $currentStrategy = self::STRATEGY_SYMLINK;
 24001 $allowedStrategies = array(self::STRATEGY_SYMLINK);
 24002 } elseif (false === $symlinkOption) {
 24003 $currentStrategy = self::STRATEGY_MIRROR;
 24004 $allowedStrategies = array(self::STRATEGY_MIRROR);
 24005 }
 24006 
 24007 
 24008 if (Platform::isWindows() && self::STRATEGY_SYMLINK === $currentStrategy && !$this->safeJunctions()) {
 24009 if (!in_array(self::STRATEGY_MIRROR, $allowedStrategies, true)) {
 24010 throw new \RuntimeException('You are on an old Windows / old PHP combo which does not allow Composer to use junctions/symlinks and this path repository has symlink:true in its options so copying is not allowed');
 24011 }
 24012 $currentStrategy = self::STRATEGY_MIRROR;
 24013 $allowedStrategies = array(self::STRATEGY_MIRROR);
 24014 }
 24015 
 24016 return array($currentStrategy, $allowedStrategies);
 24017 }
 24018 
 24019 
 24020 
 24021 
 24022 
 24023 
 24024 
 24025 
 24026 
 24027 
 24028 
 24029 
 24030 
 24031 
 24032 private function safeJunctions()
 24033 {
 24034 
 24035 return function_exists('proc_open') &&
 24036 (PHP_WINDOWS_VERSION_MAJOR > 6 ||
 24037 (PHP_WINDOWS_VERSION_MAJOR === 6 && PHP_WINDOWS_VERSION_MINOR >= 1));
 24038 }
 24039 }
 24040 <?php
 24041 
 24042 
 24043 
 24044 
 24045 
 24046 
 24047 
 24048 
 24049 
 24050 
 24051 
 24052 namespace Composer\Downloader;
 24053 
 24054 use Composer\Package\PackageInterface;
 24055 use Composer\Repository\VcsRepository;
 24056 use Composer\Util\Perforce;
 24057 
 24058 
 24059 
 24060 
 24061 class PerforceDownloader extends VcsDownloader
 24062 {
 24063 
 24064 protected $perforce;
 24065 
 24066 
 24067 
 24068 
 24069 protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
 24070 {
 24071 return \React\Promise\resolve();
 24072 }
 24073 
 24074 
 24075 
 24076 
 24077 public function doInstall(PackageInterface $package, $path, $url)
 24078 {
 24079 $ref = $package->getSourceReference();
 24080 $label = $this->getLabelFromSourceReference((string) $ref);
 24081 
 24082 $this->io->writeError('Cloning ' . $ref);
 24083 $this->initPerforce($package, $path, $url);
 24084 $this->perforce->setStream($ref);
 24085 $this->perforce->p4Login();
 24086 $this->perforce->writeP4ClientSpec();
 24087 $this->perforce->connectClient();
 24088 $this->perforce->syncCodeBase($label);
 24089 $this->perforce->cleanupClientSpec();
 24090 
 24091 return \React\Promise\resolve();
 24092 }
 24093 
 24094 
 24095 
 24096 
 24097 
 24098 
 24099 private function getLabelFromSourceReference($ref)
 24100 {
 24101 $pos = strpos($ref, '@');
 24102 if (false !== $pos) {
 24103 return substr($ref, $pos + 1);
 24104 }
 24105 
 24106 return null;
 24107 }
 24108 
 24109 
 24110 
 24111 
 24112 
 24113 
 24114 
 24115 public function initPerforce(PackageInterface $package, $path, $url)
 24116 {
 24117 if (!empty($this->perforce)) {
 24118 $this->perforce->initializePath($path);
 24119 
 24120 return;
 24121 }
 24122 
 24123 $repository = $package->getRepository();
 24124 $repoConfig = null;
 24125 if ($repository instanceof VcsRepository) {
 24126 $repoConfig = $this->getRepoConfig($repository);
 24127 }
 24128 $this->perforce = Perforce::create($repoConfig, $url, $path, $this->process, $this->io);
 24129 }
 24130 
 24131 
 24132 
 24133 
 24134 private function getRepoConfig(VcsRepository $repository)
 24135 {
 24136 return $repository->getRepoConfig();
 24137 }
 24138 
 24139 
 24140 
 24141 
 24142 protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
 24143 {
 24144 return $this->doInstall($target, $path, $url);
 24145 }
 24146 
 24147 
 24148 
 24149 
 24150 public function getLocalChanges(PackageInterface $package, $path)
 24151 {
 24152 $this->io->writeError('Perforce driver does not check for local changes before overriding');
 24153 
 24154 return null;
 24155 }
 24156 
 24157 
 24158 
 24159 
 24160 protected function getCommitLogs($fromReference, $toReference, $path)
 24161 {
 24162 return $this->perforce->getCommitLogs($fromReference, $toReference);
 24163 }
 24164 
 24165 
 24166 
 24167 
 24168 public function setPerforce(Perforce $perforce)
 24169 {
 24170 $this->perforce = $perforce;
 24171 }
 24172 
 24173 
 24174 
 24175 
 24176 protected function hasMetadataRepository($path)
 24177 {
 24178 return true;
 24179 }
 24180 }
 24181 <?php
 24182 
 24183 
 24184 
 24185 
 24186 
 24187 
 24188 
 24189 
 24190 
 24191 
 24192 
 24193 namespace Composer\Downloader;
 24194 
 24195 use Composer\Package\PackageInterface;
 24196 
 24197 
 24198 
 24199 
 24200 
 24201 
 24202 class PharDownloader extends ArchiveDownloader
 24203 {
 24204 
 24205 
 24206 
 24207 protected function extract(PackageInterface $package, $file, $path)
 24208 {
 24209 
 24210 $archive = new \Phar($file);
 24211 $archive->extractTo($path, null, true);
 24212 
 24213 
 24214 
 24215 
 24216 
 24217 
 24218 return \React\Promise\resolve();
 24219 }
 24220 }
 24221 <?php
 24222 
 24223 
 24224 
 24225 
 24226 
 24227 
 24228 
 24229 
 24230 
 24231 
 24232 
 24233 namespace Composer\Downloader;
 24234 
 24235 use Composer\Util\IniHelper;
 24236 use Composer\Util\Platform;
 24237 use Composer\Util\ProcessExecutor;
 24238 use Composer\Package\PackageInterface;
 24239 use RarArchive;
 24240 
 24241 
 24242 
 24243 
 24244 
 24245 
 24246 
 24247 
 24248 class RarDownloader extends ArchiveDownloader
 24249 {
 24250 protected function extract(PackageInterface $package, $file, $path)
 24251 {
 24252 $processError = null;
 24253 
 24254 
 24255 if (!Platform::isWindows()) {
 24256 $command = 'unrar x -- ' . ProcessExecutor::escape($file) . ' ' . ProcessExecutor::escape($path) . ' >/dev/null && chmod -R u+w ' . ProcessExecutor::escape($path);
 24257 
 24258 if (0 === $this->process->execute($command, $ignoredOutput)) {
 24259 return \React\Promise\resolve();
 24260 }
 24261 
 24262 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
 24263 }
 24264 
 24265 if (!class_exists('RarArchive')) {
 24266 
 24267 $iniMessage = IniHelper::getMessage();
 24268 
 24269 $error = "Could not decompress the archive, enable the PHP rar extension or install unrar.\n"
 24270 . $iniMessage . "\n" . $processError;
 24271 
 24272 if (!Platform::isWindows()) {
 24273 $error = "Could not decompress the archive, enable the PHP rar extension.\n" . $iniMessage;
 24274 }
 24275 
 24276 throw new \RuntimeException($error);
 24277 }
 24278 
 24279 $rarArchive = RarArchive::open($file);
 24280 
 24281 if (false === $rarArchive) {
 24282 throw new \UnexpectedValueException('Could not open RAR archive: ' . $file);
 24283 }
 24284 
 24285 $entries = $rarArchive->getEntries();
 24286 
 24287 if (false === $entries) {
 24288 throw new \RuntimeException('Could not retrieve RAR archive entries');
 24289 }
 24290 
 24291 foreach ($entries as $entry) {
 24292 if (false === $entry->extract($path)) {
 24293 throw new \RuntimeException('Could not extract entry');
 24294 }
 24295 }
 24296 
 24297 $rarArchive->close();
 24298 
 24299 return \React\Promise\resolve();
 24300 }
 24301 }
 24302 <?php
 24303 
 24304 
 24305 
 24306 
 24307 
 24308 
 24309 
 24310 
 24311 
 24312 
 24313 
 24314 namespace Composer\Downloader;
 24315 
 24316 use Composer\Package\PackageInterface;
 24317 use Composer\Pcre\Preg;
 24318 use Composer\Util\Svn as SvnUtil;
 24319 use Composer\Repository\VcsRepository;
 24320 use Composer\Util\ProcessExecutor;
 24321 use React\Promise\PromiseInterface;
 24322 
 24323 
 24324 
 24325 
 24326 
 24327 class SvnDownloader extends VcsDownloader
 24328 {
 24329 
 24330 protected $cacheCredentials = true;
 24331 
 24332 
 24333 
 24334 
 24335 protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
 24336 {
 24337 SvnUtil::cleanEnv();
 24338 $util = new SvnUtil($url, $this->io, $this->config, $this->process);
 24339 if (null === $util->binaryVersion()) {
 24340 throw new \RuntimeException('svn was not found in your PATH, skipping source download');
 24341 }
 24342 
 24343 return \React\Promise\resolve();
 24344 }
 24345 
 24346 
 24347 
 24348 
 24349 protected function doInstall(PackageInterface $package, $path, $url)
 24350 {
 24351 SvnUtil::cleanEnv();
 24352 $ref = $package->getSourceReference();
 24353 
 24354 $repo = $package->getRepository();
 24355 if ($repo instanceof VcsRepository) {
 24356 $repoConfig = $repo->getRepoConfig();
 24357 if (array_key_exists('svn-cache-credentials', $repoConfig)) {
 24358 $this->cacheCredentials = (bool) $repoConfig['svn-cache-credentials'];
 24359 }
 24360 }
 24361 
 24362 $this->io->writeError(" Checking out ".$package->getSourceReference());
 24363 $this->execute($package, $url, "svn co", sprintf("%s/%s", $url, $ref), null, $path);
 24364 
 24365 return \React\Promise\resolve();
 24366 }
 24367 
 24368 
 24369 
 24370 
 24371 protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
 24372 {
 24373 SvnUtil::cleanEnv();
 24374 $ref = $target->getSourceReference();
 24375 
 24376 if (!$this->hasMetadataRepository($path)) {
 24377 throw new \RuntimeException('The .svn directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
 24378 }
 24379 
 24380 $util = new SvnUtil($url, $this->io, $this->config, $this->process);
 24381 $flags = "";
 24382 if (version_compare($util->binaryVersion(), '1.7.0', '>=')) {
 24383 $flags .= ' --ignore-ancestry';
 24384 }
 24385 
 24386 $this->io->writeError(" Checking out " . $ref);
 24387 $this->execute($target, $url, "svn switch" . $flags, sprintf("%s/%s", $url, $ref), $path);
 24388 
 24389 return \React\Promise\resolve();
 24390 }
 24391 
 24392 
 24393 
 24394 
 24395 public function getLocalChanges(PackageInterface $package, $path)
 24396 {
 24397 if (!$this->hasMetadataRepository($path)) {
 24398 return null;
 24399 }
 24400 
 24401 $this->process->execute('svn status --ignore-externals', $output, $path);
 24402 
 24403 return Preg::isMatch('{^ *[^X ] +}m', $output) ? $output : null;
 24404 }
 24405 
 24406 
 24407 
 24408 
 24409 
 24410 
 24411 
 24412 
 24413 
 24414 
 24415 
 24416 
 24417 
 24418 protected function execute(PackageInterface $package, $baseUrl, $command, $url, $cwd = null, $path = null)
 24419 {
 24420 $util = new SvnUtil($baseUrl, $this->io, $this->config, $this->process);
 24421 $util->setCacheCredentials($this->cacheCredentials);
 24422 try {
 24423 return $util->execute($command, $url, $cwd, $path, $this->io->isVerbose());
 24424 } catch (\RuntimeException $e) {
 24425 throw new \RuntimeException(
 24426 $package->getPrettyName().' could not be downloaded, '.$e->getMessage()
 24427 );
 24428 }
 24429 }
 24430 
 24431 
 24432 
 24433 
 24434 protected function cleanChanges(PackageInterface $package, $path, $update)
 24435 {
 24436 if (!$changes = $this->getLocalChanges($package, $path)) {
 24437 return \React\Promise\resolve();
 24438 }
 24439 
 24440 if (!$this->io->isInteractive()) {
 24441 if (true === $this->config->get('discard-changes')) {
 24442 return $this->discardChanges($path);
 24443 }
 24444 
 24445 return parent::cleanChanges($package, $path, $update);
 24446 }
 24447 
 24448 $changes = array_map(function ($elem) {
 24449 return '    '.$elem;
 24450 }, Preg::split('{\s*\r?\n\s*}', $changes));
 24451 $countChanges = count($changes);
 24452 $this->io->writeError(sprintf('    <error>'.$package->getPrettyName().' has modified file%s:</error>', $countChanges === 1 ? '' : 's'));
 24453 $this->io->writeError(array_slice($changes, 0, 10));
 24454 if ($countChanges > 10) {
 24455 $remainingChanges = $countChanges - 10;
 24456 $this->io->writeError(
 24457 sprintf(
 24458 '    <info>'.$remainingChanges.' more file%s modified, choose "v" to view the full list</info>',
 24459 $remainingChanges === 1 ? '' : 's'
 24460 )
 24461 );
 24462 }
 24463 
 24464 while (true) {
 24465 switch ($this->io->ask('    <info>Discard changes [y,n,v,?]?</info> ', '?')) {
 24466 case 'y':
 24467 $this->discardChanges($path);
 24468 break 2;
 24469 
 24470 case 'n':
 24471 throw new \RuntimeException('Update aborted');
 24472 
 24473 case 'v':
 24474 $this->io->writeError($changes);
 24475 break;
 24476 
 24477 case '?':
 24478 default:
 24479 $this->io->writeError(array(
 24480 '    y - discard changes and apply the '.($update ? 'update' : 'uninstall'),
 24481 '    n - abort the '.($update ? 'update' : 'uninstall').' and let you manually clean things up',
 24482 '    v - view modified files',
 24483 '    ? - print help',
 24484 ));
 24485 break;
 24486 }
 24487 }
 24488 
 24489 return \React\Promise\resolve();
 24490 }
 24491 
 24492 
 24493 
 24494 
 24495 protected function getCommitLogs($fromReference, $toReference, $path)
 24496 {
 24497 if (Preg::isMatch('{@(\d+)$}', $fromReference) && Preg::isMatch('{@(\d+)$}', $toReference)) {
 24498 
 24499 $command = sprintf('svn info --non-interactive --xml -- %s', ProcessExecutor::escape($path));
 24500 if (0 !== $this->process->execute($command, $output, $path)) {
 24501 throw new \RuntimeException(
 24502 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()
 24503 );
 24504 }
 24505 
 24506 $urlPattern = '#<url>(.*)</url>#';
 24507 if (Preg::isMatch($urlPattern, $output, $matches)) {
 24508 $baseUrl = $matches[1];
 24509 } else {
 24510 throw new \RuntimeException(
 24511 'Unable to determine svn url for path '. $path
 24512 );
 24513 }
 24514 
 24515 
 24516 $fromRevision = Preg::replace('{.*@(\d+)$}', '$1', $fromReference);
 24517 $toRevision = Preg::replace('{.*@(\d+)$}', '$1', $toReference);
 24518 
 24519 $command = sprintf('svn log -r%s:%s --incremental', ProcessExecutor::escape($fromRevision), ProcessExecutor::escape($toRevision));
 24520 
 24521 $util = new SvnUtil($baseUrl, $this->io, $this->config, $this->process);
 24522 $util->setCacheCredentials($this->cacheCredentials);
 24523 try {
 24524 return $util->executeLocal($command, $path, null, $this->io->isVerbose());
 24525 } catch (\RuntimeException $e) {
 24526 throw new \RuntimeException(
 24527 'Failed to execute ' . $command . "\n\n".$e->getMessage()
 24528 );
 24529 }
 24530 }
 24531 
 24532 return "Could not retrieve changes between $fromReference and $toReference due to missing revision information";
 24533 }
 24534 
 24535 
 24536 
 24537 
 24538 
 24539 
 24540 protected function discardChanges($path)
 24541 {
 24542 if (0 !== $this->process->execute('svn revert -R .', $output, $path)) {
 24543 throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
 24544 }
 24545 
 24546 return \React\Promise\resolve();
 24547 }
 24548 
 24549 
 24550 
 24551 
 24552 protected function hasMetadataRepository($path)
 24553 {
 24554 return is_dir($path.'/.svn');
 24555 }
 24556 }
 24557 <?php
 24558 
 24559 
 24560 
 24561 
 24562 
 24563 
 24564 
 24565 
 24566 
 24567 
 24568 
 24569 namespace Composer\Downloader;
 24570 
 24571 use Composer\Package\PackageInterface;
 24572 
 24573 
 24574 
 24575 
 24576 
 24577 
 24578 class TarDownloader extends ArchiveDownloader
 24579 {
 24580 
 24581 
 24582 
 24583 protected function extract(PackageInterface $package, $file, $path)
 24584 {
 24585 
 24586 $archive = new \PharData($file);
 24587 $archive->extractTo($path, null, true);
 24588 
 24589 return \React\Promise\resolve();
 24590 }
 24591 }
 24592 <?php
 24593 
 24594 
 24595 
 24596 
 24597 
 24598 
 24599 
 24600 
 24601 
 24602 
 24603 
 24604 namespace Composer\Downloader;
 24605 
 24606 
 24607 
 24608 
 24609 class TransportException extends \RuntimeException
 24610 {
 24611 
 24612 protected $headers;
 24613 
 24614 protected $response;
 24615 
 24616 protected $statusCode;
 24617 
 24618 protected $responseInfo = array();
 24619 
 24620 
 24621 
 24622 
 24623 
 24624 
 24625 public function setHeaders($headers)
 24626 {
 24627 $this->headers = $headers;
 24628 }
 24629 
 24630 
 24631 
 24632 
 24633 public function getHeaders()
 24634 {
 24635 return $this->headers;
 24636 }
 24637 
 24638 
 24639 
 24640 
 24641 
 24642 
 24643 public function setResponse($response)
 24644 {
 24645 $this->response = $response;
 24646 }
 24647 
 24648 
 24649 
 24650 
 24651 public function getResponse()
 24652 {
 24653 return $this->response;
 24654 }
 24655 
 24656 
 24657 
 24658 
 24659 
 24660 
 24661 public function setStatusCode($statusCode)
 24662 {
 24663 $this->statusCode = $statusCode;
 24664 }
 24665 
 24666 
 24667 
 24668 
 24669 public function getStatusCode()
 24670 {
 24671 return $this->statusCode;
 24672 }
 24673 
 24674 
 24675 
 24676 
 24677 public function getResponseInfo()
 24678 {
 24679 return $this->responseInfo;
 24680 }
 24681 
 24682 
 24683 
 24684 
 24685 
 24686 
 24687 public function setResponseInfo(array $responseInfo)
 24688 {
 24689 $this->responseInfo = $responseInfo;
 24690 }
 24691 }
 24692 <?php
 24693 
 24694 
 24695 
 24696 
 24697 
 24698 
 24699 
 24700 
 24701 
 24702 
 24703 
 24704 namespace Composer\Downloader;
 24705 
 24706 use Composer\Package\PackageInterface;
 24707 
 24708 
 24709 
 24710 
 24711 
 24712 
 24713 interface VcsCapableDownloaderInterface
 24714 {
 24715 
 24716 
 24717 
 24718 
 24719 
 24720 
 24721 
 24722 public function getVcsReference(PackageInterface $package, $path);
 24723 }
 24724 <?php
 24725 
 24726 
 24727 
 24728 
 24729 
 24730 
 24731 
 24732 
 24733 
 24734 
 24735 
 24736 namespace Composer\Downloader;
 24737 
 24738 use Composer\Config;
 24739 use Composer\Package\Dumper\ArrayDumper;
 24740 use Composer\Package\PackageInterface;
 24741 use Composer\Package\Version\VersionGuesser;
 24742 use Composer\Package\Version\VersionParser;
 24743 use Composer\Util\ProcessExecutor;
 24744 use Composer\IO\IOInterface;
 24745 use Composer\Util\Filesystem;
 24746 use React\Promise\PromiseInterface;
 24747 use Composer\DependencyResolver\Operation\UpdateOperation;
 24748 use Composer\DependencyResolver\Operation\InstallOperation;
 24749 use Composer\DependencyResolver\Operation\UninstallOperation;
 24750 
 24751 
 24752 
 24753 
 24754 abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterface, VcsCapableDownloaderInterface
 24755 {
 24756 
 24757 protected $io;
 24758 
 24759 protected $config;
 24760 
 24761 protected $process;
 24762 
 24763 protected $filesystem;
 24764 
 24765 protected $hasCleanedChanges = array();
 24766 
 24767 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
 24768 {
 24769 $this->io = $io;
 24770 $this->config = $config;
 24771 $this->process = $process ?: new ProcessExecutor($io);
 24772 $this->filesystem = $fs ?: new Filesystem($this->process);
 24773 }
 24774 
 24775 
 24776 
 24777 
 24778 public function getInstallationSource()
 24779 {
 24780 return 'source';
 24781 }
 24782 
 24783 
 24784 
 24785 
 24786 public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null)
 24787 {
 24788 if (!$package->getSourceReference()) {
 24789 throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
 24790 }
 24791 
 24792 $urls = $this->prepareUrls($package->getSourceUrls());
 24793 
 24794 while ($url = array_shift($urls)) {
 24795 try {
 24796 return $this->doDownload($package, $path, $url, $prevPackage);
 24797 } catch (\Exception $e) {
 24798 
 24799 if ($e instanceof \PHPUnit\Framework\Exception) {
 24800 throw $e;
 24801 }
 24802 if ($this->io->isDebug()) {
 24803 $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
 24804 } elseif (count($urls)) {
 24805 $this->io->writeError('    Failed, trying the next URL');
 24806 }
 24807 if (!count($urls)) {
 24808 throw $e;
 24809 }
 24810 }
 24811 }
 24812 
 24813 return \React\Promise\resolve();
 24814 }
 24815 
 24816 
 24817 
 24818 
 24819 public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
 24820 {
 24821 if ($type === 'update') {
 24822 $this->cleanChanges($prevPackage, $path, true);
 24823 $this->hasCleanedChanges[$prevPackage->getUniqueName()] = true;
 24824 } elseif ($type === 'install') {
 24825 $this->filesystem->emptyDirectory($path);
 24826 } elseif ($type === 'uninstall') {
 24827 $this->cleanChanges($package, $path, false);
 24828 }
 24829 
 24830 return \React\Promise\resolve();
 24831 }
 24832 
 24833 
 24834 
 24835 
 24836 public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
 24837 {
 24838 if ($type === 'update' && isset($this->hasCleanedChanges[$prevPackage->getUniqueName()])) {
 24839 $this->reapplyChanges($path);
 24840 unset($this->hasCleanedChanges[$prevPackage->getUniqueName()]);
 24841 }
 24842 
 24843 return \React\Promise\resolve();
 24844 }
 24845 
 24846 
 24847 
 24848 
 24849 public function install(PackageInterface $package, $path)
 24850 {
 24851 if (!$package->getSourceReference()) {
 24852 throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
 24853 }
 24854 
 24855 $this->io->writeError("  - " . InstallOperation::format($package).': ', false);
 24856 
 24857 $urls = $this->prepareUrls($package->getSourceUrls());
 24858 while ($url = array_shift($urls)) {
 24859 try {
 24860 $this->doInstall($package, $path, $url);
 24861 break;
 24862 } catch (\Exception $e) {
 24863 
 24864 if ($e instanceof \PHPUnit\Framework\Exception) {
 24865 throw $e;
 24866 }
 24867 if ($this->io->isDebug()) {
 24868 $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
 24869 } elseif (count($urls)) {
 24870 $this->io->writeError('    Failed, trying the next URL');
 24871 }
 24872 if (!count($urls)) {
 24873 throw $e;
 24874 }
 24875 }
 24876 }
 24877 
 24878 return \React\Promise\resolve();
 24879 }
 24880 
 24881 
 24882 
 24883 
 24884 public function update(PackageInterface $initial, PackageInterface $target, $path)
 24885 {
 24886 if (!$target->getSourceReference()) {
 24887 throw new \InvalidArgumentException('Package '.$target->getPrettyName().' is missing reference information');
 24888 }
 24889 
 24890 $this->io->writeError("  - " . UpdateOperation::format($initial, $target).': ', false);
 24891 
 24892 $urls = $this->prepareUrls($target->getSourceUrls());
 24893 
 24894 $exception = null;
 24895 while ($url = array_shift($urls)) {
 24896 try {
 24897 $this->doUpdate($initial, $target, $path, $url);
 24898 
 24899 $exception = null;
 24900 break;
 24901 } catch (\Exception $exception) {
 24902 
 24903 if ($exception instanceof \PHPUnit\Framework\Exception) {
 24904 throw $exception;
 24905 }
 24906 if ($this->io->isDebug()) {
 24907 $this->io->writeError('Failed: ['.get_class($exception).'] '.$exception->getMessage());
 24908 } elseif (count($urls)) {
 24909 $this->io->writeError('    Failed, trying the next URL');
 24910 }
 24911 }
 24912 }
 24913 
 24914 
 24915 
 24916 if (!$exception && $this->io->isVerbose() && $this->hasMetadataRepository($path)) {
 24917 $message = 'Pulling in changes:';
 24918 $logs = $this->getCommitLogs($initial->getSourceReference(), $target->getSourceReference(), $path);
 24919 
 24920 if (!trim($logs)) {
 24921 $message = 'Rolling back changes:';
 24922 $logs = $this->getCommitLogs($target->getSourceReference(), $initial->getSourceReference(), $path);
 24923 }
 24924 
 24925 if (trim($logs)) {
 24926 $logs = implode("\n", array_map(function ($line) {
 24927 return '      ' . $line;
 24928 }, explode("\n", $logs)));
 24929 
 24930 
 24931 $logs = str_replace('<', '\<', $logs);
 24932 
 24933 $this->io->writeError('    '.$message);
 24934 $this->io->writeError($logs);
 24935 }
 24936 }
 24937 
 24938 if (!$urls && $exception) {
 24939 throw $exception;
 24940 }
 24941 
 24942 return \React\Promise\resolve();
 24943 }
 24944 
 24945 
 24946 
 24947 
 24948 public function remove(PackageInterface $package, $path)
 24949 {
 24950 $this->io->writeError("  - " . UninstallOperation::format($package));
 24951 
 24952 $promise = $this->filesystem->removeDirectoryAsync($path);
 24953 
 24954 return $promise->then(function ($result) use ($path) {
 24955 if (!$result) {
 24956 throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
 24957 }
 24958 });
 24959 }
 24960 
 24961 
 24962 
 24963 
 24964 public function getVcsReference(PackageInterface $package, $path)
 24965 {
 24966 $parser = new VersionParser;
 24967 $guesser = new VersionGuesser($this->config, $this->process, $parser);
 24968 $dumper = new ArrayDumper;
 24969 
 24970 $packageConfig = $dumper->dump($package);
 24971 if ($packageVersion = $guesser->guessVersion($packageConfig, $path)) {
 24972 return $packageVersion['commit'];
 24973 }
 24974 
 24975 return null;
 24976 }
 24977 
 24978 
 24979 
 24980 
 24981 
 24982 
 24983 
 24984 
 24985 
 24986 
 24987 
 24988 
 24989 
 24990 protected function cleanChanges(PackageInterface $package, $path, $update)
 24991 {
 24992 
 24993 if (null !== $this->getLocalChanges($package, $path)) {
 24994 throw new \RuntimeException('Source directory ' . $path . ' has uncommitted changes.');
 24995 }
 24996 
 24997 return \React\Promise\resolve();
 24998 }
 24999 
 25000 
 25001 
 25002 
 25003 
 25004 
 25005 
 25006 
 25007 
 25008 
 25009 protected function reapplyChanges($path)
 25010 {
 25011 }
 25012 
 25013 
 25014 
 25015 
 25016 
 25017 
 25018 
 25019 
 25020 
 25021 
 25022 
 25023 abstract protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null);
 25024 
 25025 
 25026 
 25027 
 25028 
 25029 
 25030 
 25031 
 25032 
 25033 
 25034 abstract protected function doInstall(PackageInterface $package, $path, $url);
 25035 
 25036 
 25037 
 25038 
 25039 
 25040 
 25041 
 25042 
 25043 
 25044 
 25045 
 25046 abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url);
 25047 
 25048 
 25049 
 25050 
 25051 
 25052 
 25053 
 25054 
 25055 
 25056 abstract protected function getCommitLogs($fromReference, $toReference, $path);
 25057 
 25058 
 25059 
 25060 
 25061 
 25062 
 25063 
 25064 
 25065 abstract protected function hasMetadataRepository($path);
 25066 
 25067 
 25068 
 25069 
 25070 
 25071 
 25072 private function prepareUrls(array $urls)
 25073 {
 25074 foreach ($urls as $index => $url) {
 25075 if (Filesystem::isLocalPath($url)) {
 25076 
 25077 
 25078 $fileProtocol = 'file://';
 25079 $isFileProtocol = false;
 25080 if (0 === strpos($url, $fileProtocol)) {
 25081 $url = substr($url, strlen($fileProtocol));
 25082 $isFileProtocol = true;
 25083 }
 25084 
 25085 
 25086 if (false !== strpos($url, '%')) {
 25087 $url = rawurldecode($url);
 25088 }
 25089 
 25090 $urls[$index] = realpath($url);
 25091 
 25092 if ($isFileProtocol) {
 25093 $urls[$index] = $fileProtocol . $urls[$index];
 25094 }
 25095 }
 25096 }
 25097 
 25098 return $urls;
 25099 }
 25100 }
 25101 <?php
 25102 
 25103 
 25104 
 25105 
 25106 
 25107 
 25108 
 25109 
 25110 
 25111 
 25112 
 25113 namespace Composer\Downloader;
 25114 
 25115 use Composer\Package\PackageInterface;
 25116 use Composer\Util\ProcessExecutor;
 25117 
 25118 
 25119 
 25120 
 25121 
 25122 
 25123 
 25124 class XzDownloader extends ArchiveDownloader
 25125 {
 25126 protected function extract(PackageInterface $package, $file, $path)
 25127 {
 25128 $command = 'tar -xJf ' . ProcessExecutor::escape($file) . ' -C ' . ProcessExecutor::escape($path);
 25129 
 25130 if (0 === $this->process->execute($command, $ignoredOutput)) {
 25131 return \React\Promise\resolve();
 25132 }
 25133 
 25134 $processError = 'Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput();
 25135 
 25136 throw new \RuntimeException($processError);
 25137 }
 25138 }
 25139 <?php
 25140 
 25141 
 25142 
 25143 
 25144 
 25145 
 25146 
 25147 
 25148 
 25149 
 25150 
 25151 namespace Composer\Downloader;
 25152 
 25153 use Composer\Package\PackageInterface;
 25154 use Composer\Util\IniHelper;
 25155 use Composer\Util\Platform;
 25156 use Composer\Util\ProcessExecutor;
 25157 use Symfony\Component\Process\ExecutableFinder;
 25158 use React\Promise\PromiseInterface;
 25159 use ZipArchive;
 25160 
 25161 
 25162 
 25163 
 25164 class ZipDownloader extends ArchiveDownloader
 25165 {
 25166 
 25167 private static $unzipCommands;
 25168 
 25169 private static $hasZipArchive;
 25170 
 25171 private static $isWindows;
 25172 
 25173 
 25174 private $zipArchiveObject; 
 25175 
 25176 
 25177 
 25178 
 25179 public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
 25180 {
 25181 if (null === self::$unzipCommands) {
 25182 self::$unzipCommands = array();
 25183 $finder = new ExecutableFinder;
 25184 if (Platform::isWindows() && ($cmd = $finder->find('7z', null, array('C:\Program Files\7-Zip')))) {
 25185 self::$unzipCommands[] = array('7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
 25186 }
 25187 if ($cmd = $finder->find('unzip')) {
 25188 self::$unzipCommands[] = array('unzip', ProcessExecutor::escape($cmd).' -qq %s -d %s');
 25189 }
 25190 if (!Platform::isWindows() && ($cmd = $finder->find('7z'))) { 
 25191 self::$unzipCommands[] = array('7z', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
 25192 }
 25193 if (!Platform::isWindows() && ($cmd = $finder->find('7zz'))) { 
 25194 self::$unzipCommands[] = array('7zz', ProcessExecutor::escape($cmd).' x -bb0 -y %s -o%s');
 25195 }
 25196 }
 25197 
 25198 $procOpenMissing = false;
 25199 if (!function_exists('proc_open')) {
 25200 self::$unzipCommands = array();
 25201 $procOpenMissing = true;
 25202 }
 25203 
 25204 if (null === self::$hasZipArchive) {
 25205 self::$hasZipArchive = class_exists('ZipArchive');
 25206 }
 25207 
 25208 if (!self::$hasZipArchive && !self::$unzipCommands) {
 25209 
 25210 $iniMessage = IniHelper::getMessage();
 25211 if ($procOpenMissing) {
 25212 $error = "The zip extension is missing and unzip/7z commands cannot be called as proc_open is disabled, skipping.\n" . $iniMessage;
 25213 } else {
 25214 $error = "The zip extension and unzip/7z commands are both missing, skipping.\n" . $iniMessage;
 25215 }
 25216 
 25217 throw new \RuntimeException($error);
 25218 }
 25219 
 25220 if (null === self::$isWindows) {
 25221 self::$isWindows = Platform::isWindows();
 25222 
 25223 if (!self::$isWindows && !self::$unzipCommands) {
 25224 if ($procOpenMissing) {
 25225 $this->io->writeError("<warning>proc_open is disabled so 'unzip' and '7z' commands cannot be used, zip files are being unpacked using the PHP zip extension.</warning>");
 25226 $this->io->writeError("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
 25227 $this->io->writeError("<warning>Enabling proc_open and installing 'unzip' or '7z' may remediate them.</warning>");
 25228 } else {
 25229 $this->io->writeError("<warning>As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.</warning>");
 25230 $this->io->writeError("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
 25231 $this->io->writeError("<warning>Installing 'unzip' or '7z' may remediate them.</warning>");
 25232 }
 25233 }
 25234 }
 25235 
 25236 return parent::download($package, $path, $prevPackage, $output);
 25237 }
 25238 
 25239 
 25240 
 25241 
 25242 
 25243 
 25244 
 25245 
 25246 private function extractWithSystemUnzip(PackageInterface $package, $file, $path)
 25247 {
 25248 
 25249 $isLastChance = !self::$hasZipArchive;
 25250 
 25251 if (!self::$unzipCommands) {
 25252 
 25253 
 25254 return $this->extractWithZipArchive($package, $file, $path);
 25255 }
 25256 
 25257 $commandSpec = reset(self::$unzipCommands);
 25258 $command = sprintf($commandSpec[1], ProcessExecutor::escape($file), ProcessExecutor::escape($path));
 25259 
 25260 
 25261 if (Platform::isWindows()) {
 25262 $command = sprintf($commandSpec[1], ProcessExecutor::escape(strtr($file, '/', '\\')), ProcessExecutor::escape(strtr($path, '/', '\\')));
 25263 }
 25264 
 25265 $executable = $commandSpec[0];
 25266 
 25267 $self = $this;
 25268 $io = $this->io;
 25269 $tryFallback = function ($processError) use ($isLastChance, $io, $self, $file, $path, $package, $executable) {
 25270 if ($isLastChance) {
 25271 throw $processError;
 25272 }
 25273 
 25274 if (!is_file($file)) {
 25275 $io->writeError('    <warning>'.$processError->getMessage().'</warning>');
 25276 $io->writeError('    <warning>This most likely is due to a custom installer plugin not handling the returned Promise from the downloader</warning>');
 25277 $io->writeError('    <warning>See https://github.com/composer/installers/commit/5006d0c28730ade233a8f42ec31ac68fb1c5c9bb for an example fix</warning>');
 25278 } else {
 25279 $io->writeError('    <warning>'.$processError->getMessage().'</warning>');
 25280 $io->writeError('    The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)');
 25281 $io->writeError('    Unzip with '.$executable.' command failed, falling back to ZipArchive class');
 25282 }
 25283 
 25284 return $self->extractWithZipArchive($package, $file, $path);
 25285 };
 25286 
 25287 try {
 25288 $promise = $this->process->executeAsync($command);
 25289 
 25290 return $promise->then(function ($process) use ($tryFallback, $command, $package, $file, $self) {
 25291 if (!$process->isSuccessful()) {
 25292 if (isset($self->cleanupExecuted[$package->getName()])) {
 25293 throw new \RuntimeException('Failed to extract '.$package->getName().' as the installation was aborted by another package operation.');
 25294 }
 25295 
 25296 $output = $process->getErrorOutput();
 25297 $output = str_replace(', '.$file.'.zip or '.$file.'.ZIP', '', $output);
 25298 
 25299 return $tryFallback(new \RuntimeException('Failed to extract '.$package->getName().': ('.$process->getExitCode().') '.$command."\n\n".$output));
 25300 }
 25301 });
 25302 } catch (\Exception $e) {
 25303 return $tryFallback($e);
 25304 } catch (\Throwable $e) {
 25305 return $tryFallback($e);
 25306 }
 25307 }
 25308 
 25309 
 25310 
 25311 
 25312 
 25313 
 25314 
 25315 
 25316 
 25317 
 25318 
 25319 public function extractWithZipArchive(PackageInterface $package, $file, $path)
 25320 {
 25321 $processError = null;
 25322 $zipArchive = $this->zipArchiveObject ?: new ZipArchive();
 25323 
 25324 try {
 25325 if (true === ($retval = $zipArchive->open($file))) {
 25326 $extractResult = $zipArchive->extractTo($path);
 25327 
 25328 if (true === $extractResult) {
 25329 $zipArchive->close();
 25330 
 25331 return \React\Promise\resolve();
 25332 }
 25333 
 25334 $processError = new \RuntimeException(rtrim("There was an error extracting the ZIP file, it is either corrupted or using an invalid format.\n"));
 25335 } else {
 25336 $processError = new \UnexpectedValueException(rtrim($this->getErrorMessage($retval, $file)."\n"), $retval);
 25337 }
 25338 } catch (\ErrorException $e) {
 25339 $processError = new \RuntimeException('The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems): '.$e->getMessage(), 0, $e);
 25340 } catch (\Exception $e) {
 25341 $processError = $e;
 25342 } catch (\Throwable $e) {
 25343 $processError = $e;
 25344 }
 25345 
 25346 throw $processError;
 25347 }
 25348 
 25349 
 25350 
 25351 
 25352 
 25353 
 25354 
 25355 
 25356 
 25357 
 25358 
 25359 public function extract(PackageInterface $package, $file, $path)
 25360 {
 25361 return $this->extractWithSystemUnzip($package, $file, $path);
 25362 }
 25363 
 25364 
 25365 
 25366 
 25367 
 25368 
 25369 
 25370 
 25371 protected function getErrorMessage($retval, $file)
 25372 {
 25373 switch ($retval) {
 25374 case ZipArchive::ER_EXISTS:
 25375 return sprintf("File '%s' already exists.", $file);
 25376 case ZipArchive::ER_INCONS:
 25377 return sprintf("Zip archive '%s' is inconsistent.", $file);
 25378 case ZipArchive::ER_INVAL:
 25379 return sprintf("Invalid argument (%s)", $file);
 25380 case ZipArchive::ER_MEMORY:
 25381 return sprintf("Malloc failure (%s)", $file);
 25382 case ZipArchive::ER_NOENT:
 25383 return sprintf("No such zip file: '%s'", $file);
 25384 case ZipArchive::ER_NOZIP:
 25385 return sprintf("'%s' is not a zip archive.", $file);
 25386 case ZipArchive::ER_OPEN:
 25387 return sprintf("Can't open zip file: %s", $file);
 25388 case ZipArchive::ER_READ:
 25389 return sprintf("Zip read error (%s)", $file);
 25390 case ZipArchive::ER_SEEK:
 25391 return sprintf("Zip seek error (%s)", $file);
 25392 default:
 25393 return sprintf("'%s' is not a valid zip archive, got error code: %s", $file, $retval);
 25394 }
 25395 }
 25396 }
 25397 <?php
 25398 
 25399 
 25400 
 25401 
 25402 
 25403 
 25404 
 25405 
 25406 
 25407 
 25408 
 25409 namespace Composer\EventDispatcher;
 25410 
 25411 
 25412 
 25413 
 25414 
 25415 
 25416 class Event
 25417 {
 25418 
 25419 
 25420 
 25421 protected $name;
 25422 
 25423 
 25424 
 25425 
 25426 protected $args;
 25427 
 25428 
 25429 
 25430 
 25431 protected $flags;
 25432 
 25433 
 25434 
 25435 
 25436 private $propagationStopped = false;
 25437 
 25438 
 25439 
 25440 
 25441 
 25442 
 25443 
 25444 
 25445 public function __construct($name, array $args = array(), array $flags = array())
 25446 {
 25447 $this->name = $name;
 25448 $this->args = $args;
 25449 $this->flags = $flags;
 25450 }
 25451 
 25452 
 25453 
 25454 
 25455 
 25456 
 25457 public function getName()
 25458 {
 25459 return $this->name;
 25460 }
 25461 
 25462 
 25463 
 25464 
 25465 
 25466 
 25467 public function getArguments()
 25468 {
 25469 return $this->args;
 25470 }
 25471 
 25472 
 25473 
 25474 
 25475 
 25476 
 25477 public function getFlags()
 25478 {
 25479 return $this->flags;
 25480 }
 25481 
 25482 
 25483 
 25484 
 25485 
 25486 
 25487 public function isPropagationStopped()
 25488 {
 25489 return $this->propagationStopped;
 25490 }
 25491 
 25492 
 25493 
 25494 
 25495 
 25496 
 25497 public function stopPropagation()
 25498 {
 25499 $this->propagationStopped = true;
 25500 }
 25501 }
 25502 <?php
 25503 
 25504 
 25505 
 25506 
 25507 
 25508 
 25509 
 25510 
 25511 
 25512 
 25513 
 25514 namespace Composer\EventDispatcher;
 25515 
 25516 use Composer\DependencyResolver\Transaction;
 25517 use Composer\Installer\InstallerEvent;
 25518 use Composer\IO\IOInterface;
 25519 use Composer\Composer;
 25520 use Composer\Pcre\Preg;
 25521 use Composer\Util\Platform;
 25522 use Composer\DependencyResolver\Operation\OperationInterface;
 25523 use Composer\Repository\RepositoryInterface;
 25524 use Composer\Script;
 25525 use Composer\Installer\PackageEvent;
 25526 use Composer\Installer\BinaryInstaller;
 25527 use Composer\Util\ProcessExecutor;
 25528 use Composer\Script\Event as ScriptEvent;
 25529 use Composer\Autoload\ClassLoader;
 25530 use Symfony\Component\Process\PhpExecutableFinder;
 25531 use Symfony\Component\Process\ExecutableFinder;
 25532 
 25533 
 25534 
 25535 
 25536 
 25537 
 25538 
 25539 
 25540 
 25541 
 25542 
 25543 
 25544 
 25545 
 25546 class EventDispatcher
 25547 {
 25548 
 25549 protected $composer;
 25550 
 25551 protected $io;
 25552 
 25553 protected $loader;
 25554 
 25555 protected $process;
 25556 
 25557 protected $listeners = array();
 25558 
 25559 protected $runScripts = true;
 25560 
 25561 private $eventStack;
 25562 
 25563 
 25564 
 25565 
 25566 
 25567 
 25568 
 25569 
 25570 public function __construct(Composer $composer, IOInterface $io, ProcessExecutor $process = null)
 25571 {
 25572 $this->composer = $composer;
 25573 $this->io = $io;
 25574 $this->process = $process ?: new ProcessExecutor($io);
 25575 $this->eventStack = array();
 25576 }
 25577 
 25578 
 25579 
 25580 
 25581 
 25582 
 25583 
 25584 public function setRunScripts($runScripts = true)
 25585 {
 25586 $this->runScripts = (bool) $runScripts;
 25587 
 25588 return $this;
 25589 }
 25590 
 25591 
 25592 
 25593 
 25594 
 25595 
 25596 
 25597 
 25598 
 25599 public function dispatch($eventName, Event $event = null)
 25600 {
 25601 if (null === $event) {
 25602 $event = new Event($eventName);
 25603 }
 25604 
 25605 return $this->doDispatch($event);
 25606 }
 25607 
 25608 
 25609 
 25610 
 25611 
 25612 
 25613 
 25614 
 25615 
 25616 
 25617 
 25618 public function dispatchScript($eventName, $devMode = false, $additionalArgs = array(), $flags = array())
 25619 {
 25620 return $this->doDispatch(new Script\Event($eventName, $this->composer, $this->io, $devMode, $additionalArgs, $flags));
 25621 }
 25622 
 25623 
 25624 
 25625 
 25626 
 25627 
 25628 
 25629 
 25630 
 25631 
 25632 
 25633 
 25634 
 25635 public function dispatchPackageEvent($eventName, $devMode, RepositoryInterface $localRepo, array $operations, OperationInterface $operation)
 25636 {
 25637 return $this->doDispatch(new PackageEvent($eventName, $this->composer, $this->io, $devMode, $localRepo, $operations, $operation));
 25638 }
 25639 
 25640 
 25641 
 25642 
 25643 
 25644 
 25645 
 25646 
 25647 
 25648 
 25649 
 25650 
 25651 public function dispatchInstallerEvent($eventName, $devMode, $executeOperations, Transaction $transaction)
 25652 {
 25653 return $this->doDispatch(new InstallerEvent($eventName, $this->composer, $this->io, $devMode, $executeOperations, $transaction));
 25654 }
 25655 
 25656 
 25657 
 25658 
 25659 
 25660 
 25661 
 25662 
 25663 
 25664 protected function doDispatch(Event $event)
 25665 {
 25666 if (Platform::getEnv('COMPOSER_DEBUG_EVENTS')) {
 25667 $details = null;
 25668 if ($event instanceof PackageEvent) {
 25669 $details = (string) $event->getOperation();
 25670 }
 25671 $this->io->writeError('Dispatching <info>'.$event->getName().'</info>'.($details ? ' ('.$details.')' : '').' event');
 25672 }
 25673 
 25674 $listeners = $this->getListeners($event);
 25675 
 25676 $this->pushEvent($event);
 25677 
 25678 try {
 25679 $returnMax = 0;
 25680 foreach ($listeners as $callable) {
 25681 $return = 0;
 25682 $this->ensureBinDirIsInPath();
 25683 
 25684 if (!is_string($callable)) {
 25685 if (!is_callable($callable)) {
 25686 $className = is_object($callable[0]) ? get_class($callable[0]) : $callable[0];
 25687 
 25688 throw new \RuntimeException('Subscriber '.$className.'::'.$callable[1].' for event '.$event->getName().' is not callable, make sure the function is defined and public');
 25689 }
 25690 if (is_array($callable) && (is_string($callable[0]) || is_object($callable[0])) && is_string($callable[1])) {
 25691 $this->io->writeError(sprintf('> %s: %s', $event->getName(), (is_object($callable[0]) ? get_class($callable[0]) : $callable[0]).'->'.$callable[1]), true, IOInterface::VERBOSE);
 25692 }
 25693 $return = false === call_user_func($callable, $event) ? 1 : 0;
 25694 } elseif ($this->isComposerScript($callable)) {
 25695 $this->io->writeError(sprintf('> %s: %s', $event->getName(), $callable), true, IOInterface::VERBOSE);
 25696 
 25697 $script = explode(' ', substr($callable, 1));
 25698 $scriptName = $script[0];
 25699 unset($script[0]);
 25700 
 25701 $args = array_merge($script, $event->getArguments());
 25702 $flags = $event->getFlags();
 25703 if (strpos($callable, '@composer ') === 0) {
 25704 $exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(Platform::getEnv('COMPOSER_BINARY')) . ' ' . implode(' ', $args);
 25705 if (0 !== ($exitCode = $this->executeTty($exec))) {
 25706 $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()), true, IOInterface::QUIET);
 25707 
 25708 throw new ScriptExecutionException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
 25709 }
 25710 } else {
 25711 if (!$this->getListeners(new Event($scriptName))) {
 25712 $this->io->writeError(sprintf('<warning>You made a reference to a non-existent script %s</warning>', $callable), true, IOInterface::QUIET);
 25713 }
 25714 
 25715 try {
 25716 
 25717 $scriptEvent = new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags);
 25718 $scriptEvent->setOriginatingEvent($event);
 25719 $return = $this->dispatch($scriptName, $scriptEvent);
 25720 } catch (ScriptExecutionException $e) {
 25721 $this->io->writeError(sprintf('<error>Script %s was called via %s</error>', $callable, $event->getName()), true, IOInterface::QUIET);
 25722 throw $e;
 25723 }
 25724 }
 25725 } elseif ($this->isPhpScript($callable)) {
 25726 $className = substr($callable, 0, strpos($callable, '::'));
 25727 $methodName = substr($callable, strpos($callable, '::') + 2);
 25728 
 25729 if (!class_exists($className)) {
 25730 $this->io->writeError('<warning>Class '.$className.' is not autoloadable, can not call '.$event->getName().' script</warning>', true, IOInterface::QUIET);
 25731 continue;
 25732 }
 25733 if (!is_callable($callable)) {
 25734 $this->io->writeError('<warning>Method '.$callable.' is not callable, can not call '.$event->getName().' script</warning>', true, IOInterface::QUIET);
 25735 continue;
 25736 }
 25737 
 25738 try {
 25739 $return = false === $this->executeEventPhpScript($className, $methodName, $event) ? 1 : 0;
 25740 } catch (\Exception $e) {
 25741 $message = "Script %s handling the %s event terminated with an exception";
 25742 $this->io->writeError('<error>'.sprintf($message, $callable, $event->getName()).'</error>', true, IOInterface::QUIET);
 25743 throw $e;
 25744 }
 25745 } else {
 25746 $args = implode(' ', array_map(array('Composer\Util\ProcessExecutor', 'escape'), $event->getArguments()));
 25747 $exec = $callable . ($args === '' ? '' : ' '.$args);
 25748 if ($this->io->isVerbose()) {
 25749 $this->io->writeError(sprintf('> %s: %s', $event->getName(), $exec));
 25750 } elseif ($event->getName() !== '__exec_command') {
 25751 
 25752 $this->io->writeError(sprintf('> %s', $exec));
 25753 }
 25754 
 25755 $possibleLocalBinaries = $this->composer->getPackage()->getBinaries();
 25756 if ($possibleLocalBinaries) {
 25757 foreach ($possibleLocalBinaries as $localExec) {
 25758 if (Preg::isMatch('{\b'.preg_quote($callable).'$}', $localExec)) {
 25759 $caller = BinaryInstaller::determineBinaryCaller($localExec);
 25760 $exec = Preg::replace('{^'.preg_quote($callable).'}', $caller . ' ' . $localExec, $exec);
 25761 break;
 25762 }
 25763 }
 25764 }
 25765 
 25766 if (strpos($exec, '@putenv ') === 0) {
 25767 if (false === strpos($exec, '=')) {
 25768 Platform::clearEnv(substr($exec, 8));
 25769 } else {
 25770 list($var, $value) = explode('=', substr($exec, 8), 2);
 25771 Platform::putEnv($var, $value);
 25772 }
 25773 
 25774 continue;
 25775 }
 25776 if (strpos($exec, '@php ') === 0) {
 25777 $pathAndArgs = substr($exec, 5);
 25778 if (Platform::isWindows()) {
 25779 $pathAndArgs = Preg::replaceCallback('{^\S+}', function ($path) {
 25780 return str_replace('/', '\\', $path[0]);
 25781 }, $pathAndArgs);
 25782 }
 25783 
 25784 
 25785 $matched = Preg::isMatch('{^[^\'"\s/\\\\]+}', $pathAndArgs, $match);
 25786 if ($matched && !file_exists($match[0])) {
 25787 $finder = new ExecutableFinder;
 25788 if ($pathToExec = $finder->find($match[0])) {
 25789 $pathAndArgs = $pathToExec . substr($pathAndArgs, strlen($match[0]));
 25790 }
 25791 }
 25792 $exec = $this->getPhpExecCommand() . ' ' . $pathAndArgs;
 25793 } else {
 25794 $finder = new PhpExecutableFinder();
 25795 $phpPath = $finder->find(false);
 25796 if ($phpPath) {
 25797 Platform::putEnv('PHP_BINARY', $phpPath);
 25798 }
 25799 
 25800 if (Platform::isWindows()) {
 25801 $exec = Preg::replaceCallback('{^\S+}', function ($path) {
 25802 return str_replace('/', '\\', $path[0]);
 25803 }, $exec);
 25804 }
 25805 }
 25806 
 25807 
 25808 
 25809 
 25810 if (strpos($exec, 'composer ') === 0) {
 25811 $exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(Platform::getEnv('COMPOSER_BINARY')) . substr($exec, 8);
 25812 }
 25813 
 25814 if (0 !== ($exitCode = $this->executeTty($exec))) {
 25815 $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()), true, IOInterface::QUIET);
 25816 
 25817 throw new ScriptExecutionException('Error Output: '.$this->process->getErrorOutput(), $exitCode);
 25818 }
 25819 }
 25820 
 25821 $returnMax = max($returnMax, $return);
 25822 
 25823 if ($event->isPropagationStopped()) {
 25824 break;
 25825 }
 25826 }
 25827 } catch (\Exception $e) { 
 25828 $this->popEvent();
 25829 
 25830 throw $e;
 25831 } catch (\Throwable $e) {
 25832 $this->popEvent();
 25833 
 25834 throw $e;
 25835 }
 25836 
 25837 $this->popEvent();
 25838 
 25839 return $returnMax;
 25840 }
 25841 
 25842 
 25843 
 25844 
 25845 
 25846 
 25847 protected function executeTty($exec)
 25848 {
 25849 if ($this->io->isInteractive()) {
 25850 return $this->process->executeTty($exec);
 25851 }
 25852 
 25853 return $this->process->execute($exec);
 25854 }
 25855 
 25856 
 25857 
 25858 
 25859 protected function getPhpExecCommand()
 25860 {
 25861 $finder = new PhpExecutableFinder();
 25862 $phpPath = $finder->find(false);
 25863 if (!$phpPath) {
 25864 throw new \RuntimeException('Failed to locate PHP binary to execute '.$phpPath);
 25865 }
 25866 $phpArgs = $finder->findArguments();
 25867 $phpArgs = $phpArgs ? ' ' . implode(' ', $phpArgs) : '';
 25868 $allowUrlFOpenFlag = ' -d allow_url_fopen=' . ProcessExecutor::escape(ini_get('allow_url_fopen'));
 25869 $disableFunctionsFlag = ' -d disable_functions=' . ProcessExecutor::escape(ini_get('disable_functions'));
 25870 $memoryLimitFlag = ' -d memory_limit=' . ProcessExecutor::escape(ini_get('memory_limit'));
 25871 
 25872 return ProcessExecutor::escape($phpPath) . $phpArgs . $allowUrlFOpenFlag . $disableFunctionsFlag . $memoryLimitFlag;
 25873 }
 25874 
 25875 
 25876 
 25877 
 25878 
 25879 
 25880 
 25881 
 25882 protected function executeEventPhpScript($className, $methodName, Event $event)
 25883 {
 25884 if ($this->io->isVerbose()) {
 25885 $this->io->writeError(sprintf('> %s: %s::%s', $event->getName(), $className, $methodName));
 25886 } else {
 25887 $this->io->writeError(sprintf('> %s::%s', $className, $methodName));
 25888 }
 25889 
 25890 return $className::$methodName($event);
 25891 }
 25892 
 25893 
 25894 
 25895 
 25896 
 25897 
 25898 
 25899 
 25900 
 25901 
 25902 public function addListener($eventName, $listener, $priority = 0)
 25903 {
 25904 $this->listeners[$eventName][$priority][] = $listener;
 25905 }
 25906 
 25907 
 25908 
 25909 
 25910 
 25911 
 25912 public function removeListener($listener)
 25913 {
 25914 foreach ($this->listeners as $eventName => $priorities) {
 25915 foreach ($priorities as $priority => $listeners) {
 25916 foreach ($listeners as $index => $candidate) {
 25917 if ($listener === $candidate || (is_array($candidate) && is_object($listener) && $candidate[0] === $listener)) {
 25918 unset($this->listeners[$eventName][$priority][$index]);
 25919 }
 25920 }
 25921 }
 25922 }
 25923 }
 25924 
 25925 
 25926 
 25927 
 25928 
 25929 
 25930 
 25931 
 25932 
 25933 
 25934 public function addSubscriber(EventSubscriberInterface $subscriber)
 25935 {
 25936 foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
 25937 if (is_string($params)) {
 25938 $this->addListener($eventName, array($subscriber, $params));
 25939 } elseif (is_string($params[0])) {
 25940 $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
 25941 } else {
 25942 foreach ($params as $listener) {
 25943 $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
 25944 }
 25945 }
 25946 }
 25947 }
 25948 
 25949 
 25950 
 25951 
 25952 
 25953 
 25954 
 25955 protected function getListeners(Event $event)
 25956 {
 25957 $scriptListeners = $this->runScripts ? $this->getScriptListeners($event) : array();
 25958 
 25959 if (!isset($this->listeners[$event->getName()][0])) {
 25960 $this->listeners[$event->getName()][0] = array();
 25961 }
 25962 krsort($this->listeners[$event->getName()]);
 25963 
 25964 $listeners = $this->listeners;
 25965 $listeners[$event->getName()][0] = array_merge($listeners[$event->getName()][0], $scriptListeners);
 25966 
 25967 return call_user_func_array('array_merge', $listeners[$event->getName()]);
 25968 }
 25969 
 25970 
 25971 
 25972 
 25973 
 25974 
 25975 
 25976 public function hasEventListeners(Event $event)
 25977 {
 25978 $listeners = $this->getListeners($event);
 25979 
 25980 return count($listeners) > 0;
 25981 }
 25982 
 25983 
 25984 
 25985 
 25986 
 25987 
 25988 
 25989 protected function getScriptListeners(Event $event)
 25990 {
 25991 $package = $this->composer->getPackage();
 25992 $scripts = $package->getScripts();
 25993 
 25994 if (empty($scripts[$event->getName()])) {
 25995 return array();
 25996 }
 25997 
 25998 if ($this->loader) {
 25999 $this->loader->unregister();
 26000 }
 26001 
 26002 $generator = $this->composer->getAutoloadGenerator();
 26003 if ($event instanceof ScriptEvent) {
 26004 $generator->setDevMode($event->isDevMode());
 26005 }
 26006 
 26007 $packages = $this->composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages();
 26008 $packageMap = $generator->buildPackageMap($this->composer->getInstallationManager(), $package, $packages);
 26009 $map = $generator->parseAutoloads($packageMap, $package);
 26010 $this->loader = $generator->createLoader($map, $this->composer->getConfig()->get('vendor-dir'));
 26011 $this->loader->register(false);
 26012 
 26013 return $scripts[$event->getName()];
 26014 }
 26015 
 26016 
 26017 
 26018 
 26019 
 26020 
 26021 
 26022 protected function isPhpScript($callable)
 26023 {
 26024 return false === strpos($callable, ' ') && false !== strpos($callable, '::');
 26025 }
 26026 
 26027 
 26028 
 26029 
 26030 
 26031 
 26032 
 26033 protected function isComposerScript($callable)
 26034 {
 26035 return strpos($callable, '@') === 0 && strpos($callable, '@php ') !== 0 && strpos($callable, '@putenv ') !== 0;
 26036 }
 26037 
 26038 
 26039 
 26040 
 26041 
 26042 
 26043 
 26044 
 26045 protected function pushEvent(Event $event)
 26046 {
 26047 $eventName = $event->getName();
 26048 if (in_array($eventName, $this->eventStack)) {
 26049 throw new \RuntimeException(sprintf("Circular call to script handler '%s' detected", $eventName));
 26050 }
 26051 
 26052 return array_push($this->eventStack, $eventName);
 26053 }
 26054 
 26055 
 26056 
 26057 
 26058 
 26059 
 26060 protected function popEvent()
 26061 {
 26062 return array_pop($this->eventStack);
 26063 }
 26064 
 26065 
 26066 
 26067 
 26068 private function ensureBinDirIsInPath()
 26069 {
 26070 $pathEnv = 'PATH';
 26071 if (false === Platform::getEnv('PATH') && false !== Platform::getEnv('Path')) {
 26072 $pathEnv = 'Path';
 26073 }
 26074 
 26075 
 26076 $binDir = $this->composer->getConfig()->get('bin-dir');
 26077 if (is_dir($binDir)) {
 26078 $binDir = realpath($binDir);
 26079 $pathValue = Platform::getEnv($pathEnv);
 26080 if (!Preg::isMatch('{(^|'.PATH_SEPARATOR.')'.preg_quote($binDir).'($|'.PATH_SEPARATOR.')}', $pathValue)) {
 26081 Platform::putEnv($pathEnv, $binDir.PATH_SEPARATOR.$pathValue);
 26082 }
 26083 }
 26084 }
 26085 }
 26086 <?php
 26087 
 26088 
 26089 
 26090 
 26091 
 26092 
 26093 
 26094 
 26095 
 26096 
 26097 
 26098 namespace Composer\EventDispatcher;
 26099 
 26100 
 26101 
 26102 
 26103 
 26104 
 26105 
 26106 
 26107 
 26108 
 26109 
 26110 
 26111 
 26112 interface EventSubscriberInterface
 26113 {
 26114 
 26115 
 26116 
 26117 
 26118 
 26119 
 26120 
 26121 
 26122 
 26123 
 26124 
 26125 
 26126 
 26127 
 26128 
 26129 
 26130 
 26131 
 26132 public static function getSubscribedEvents();
 26133 }
 26134 <?php
 26135 
 26136 
 26137 
 26138 
 26139 
 26140 
 26141 
 26142 
 26143 
 26144 
 26145 
 26146 namespace Composer\EventDispatcher;
 26147 
 26148 
 26149 
 26150 
 26151 class ScriptExecutionException extends \RuntimeException
 26152 {
 26153 }
 26154 <?php
 26155 
 26156 
 26157 
 26158 
 26159 
 26160 
 26161 
 26162 
 26163 
 26164 
 26165 
 26166 namespace Composer\Exception;
 26167 
 26168 
 26169 
 26170 
 26171 class IrrecoverableDownloadException extends \RuntimeException
 26172 {
 26173 }
 26174 <?php
 26175 
 26176 
 26177 
 26178 
 26179 
 26180 
 26181 
 26182 
 26183 
 26184 
 26185 
 26186 namespace Composer\Exception;
 26187 
 26188 
 26189 
 26190 
 26191 
 26192 
 26193 class NoSslException extends \RuntimeException
 26194 {
 26195 }
 26196 <?php
 26197 
 26198 
 26199 
 26200 
 26201 
 26202 
 26203 
 26204 
 26205 
 26206 
 26207 
 26208 namespace Composer;
 26209 
 26210 use Composer\Config\JsonConfigSource;
 26211 use Composer\Json\JsonFile;
 26212 use Composer\IO\IOInterface;
 26213 use Composer\Package\Archiver;
 26214 use Composer\Package\Version\VersionGuesser;
 26215 use Composer\Package\RootPackageInterface;
 26216 use Composer\Repository\RepositoryManager;
 26217 use Composer\Repository\RepositoryFactory;
 26218 use Composer\Util\Filesystem;
 26219 use Composer\Util\Platform;
 26220 use Composer\Util\ProcessExecutor;
 26221 use Composer\Util\HttpDownloader;
 26222 use Composer\Util\Loop;
 26223 use Composer\Util\Silencer;
 26224 use Composer\Plugin\PluginEvents;
 26225 use Composer\EventDispatcher\Event;
 26226 use Seld\JsonLint\DuplicateKeyException;
 26227 use Symfony\Component\Console\Formatter\OutputFormatter;
 26228 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
 26229 use Symfony\Component\Console\Output\ConsoleOutput;
 26230 use Composer\EventDispatcher\EventDispatcher;
 26231 use Composer\Autoload\AutoloadGenerator;
 26232 use Composer\Package\Version\VersionParser;
 26233 use Composer\Downloader\TransportException;
 26234 use Composer\Json\JsonValidationException;
 26235 use Composer\Repository\InstalledRepositoryInterface;
 26236 use Seld\JsonLint\JsonParser;
 26237 
 26238 
 26239 
 26240 
 26241 
 26242 
 26243 
 26244 
 26245 
 26246 class Factory
 26247 {
 26248 
 26249 
 26250 
 26251 
 26252 protected static function getHomeDir()
 26253 {
 26254 $home = Platform::getEnv('COMPOSER_HOME');
 26255 if ($home) {
 26256 return $home;
 26257 }
 26258 
 26259 if (Platform::isWindows()) {
 26260 if (!Platform::getEnv('APPDATA')) {
 26261 throw new \RuntimeException('The APPDATA or COMPOSER_HOME environment variable must be set for composer to run correctly');
 26262 }
 26263 
 26264 return rtrim(strtr(Platform::getEnv('APPDATA'), '\\', '/'), '/') . '/Composer';
 26265 }
 26266 
 26267 $userDir = self::getUserDir();
 26268 $dirs = array();
 26269 
 26270 if (self::useXdg()) {
 26271 
 26272 $xdgConfig = Platform::getEnv('XDG_CONFIG_HOME');
 26273 if (!$xdgConfig) {
 26274 $xdgConfig = $userDir . '/.config';
 26275 }
 26276 
 26277 $dirs[] = $xdgConfig . '/composer';
 26278 }
 26279 
 26280 $dirs[] = $userDir . '/.composer';
 26281 
 26282 
 26283 foreach ($dirs as $dir) {
 26284 if (Silencer::call('is_dir', $dir)) {
 26285 return $dir;
 26286 }
 26287 }
 26288 
 26289 
 26290 return $dirs[0];
 26291 }
 26292 
 26293 
 26294 
 26295 
 26296 
 26297 protected static function getCacheDir($home)
 26298 {
 26299 $cacheDir = Platform::getEnv('COMPOSER_CACHE_DIR');
 26300 if ($cacheDir) {
 26301 return $cacheDir;
 26302 }
 26303 
 26304 $homeEnv = Platform::getEnv('COMPOSER_HOME');
 26305 if ($homeEnv) {
 26306 return $homeEnv . '/cache';
 26307 }
 26308 
 26309 if (Platform::isWindows()) {
 26310 if ($cacheDir = Platform::getEnv('LOCALAPPDATA')) {
 26311 $cacheDir .= '/Composer';
 26312 } else {
 26313 $cacheDir = $home . '/cache';
 26314 }
 26315 
 26316 return rtrim(strtr($cacheDir, '\\', '/'), '/');
 26317 }
 26318 
 26319 $userDir = self::getUserDir();
 26320 if (PHP_OS === 'Darwin') {
 26321 
 26322 if (is_dir($home . '/cache') && !is_dir($userDir . '/Library/Caches/composer')) {
 26323 Silencer::call('rename', $home . '/cache', $userDir . '/Library/Caches/composer');
 26324 }
 26325 
 26326 return $userDir . '/Library/Caches/composer';
 26327 }
 26328 
 26329 if ($home === $userDir . '/.composer' && is_dir($home . '/cache')) {
 26330 return $home . '/cache';
 26331 }
 26332 
 26333 if (self::useXdg()) {
 26334 $xdgCache = Platform::getEnv('XDG_CACHE_HOME') ?: $userDir . '/.cache';
 26335 
 26336 return $xdgCache . '/composer';
 26337 }
 26338 
 26339 return $home . '/cache';
 26340 }
 26341 
 26342 
 26343 
 26344 
 26345 
 26346 protected static function getDataDir($home)
 26347 {
 26348 $homeEnv = Platform::getEnv('COMPOSER_HOME');
 26349 if ($homeEnv) {
 26350 return $homeEnv;
 26351 }
 26352 
 26353 if (Platform::isWindows()) {
 26354 return strtr($home, '\\', '/');
 26355 }
 26356 
 26357 $userDir = self::getUserDir();
 26358 if ($home !== $userDir . '/.composer' && self::useXdg()) {
 26359 $xdgData = Platform::getEnv('XDG_DATA_HOME') ?: $userDir . '/.local/share';
 26360 
 26361 return $xdgData . '/composer';
 26362 }
 26363 
 26364 return $home;
 26365 }
 26366 
 26367 
 26368 
 26369 
 26370 
 26371 
 26372 public static function createConfig(IOInterface $io = null, $cwd = null)
 26373 {
 26374 $cwd = $cwd ?: (string) getcwd();
 26375 
 26376 $config = new Config(true, $cwd);
 26377 
 26378 
 26379 $home = self::getHomeDir();
 26380 $config->merge(array('config' => array(
 26381 'home' => $home,
 26382 'cache-dir' => self::getCacheDir($home),
 26383 'data-dir' => self::getDataDir($home),
 26384 )), Config::SOURCE_DEFAULT);
 26385 
 26386 
 26387 $file = new JsonFile($config->get('home').'/config.json');
 26388 if ($file->exists()) {
 26389 if ($io && $io->isDebug()) {
 26390 $io->writeError('Loading config file ' . $file->getPath());
 26391 }
 26392 $config->merge($file->read(), $file->getPath());
 26393 }
 26394 $config->setConfigSource(new JsonConfigSource($file));
 26395 
 26396 $htaccessProtect = (bool) $config->get('htaccess-protect');
 26397 if ($htaccessProtect) {
 26398 
 26399 
 26400 
 26401 $dirs = array($config->get('home'), $config->get('cache-dir'), $config->get('data-dir'));
 26402 foreach ($dirs as $dir) {
 26403 if (!file_exists($dir . '/.htaccess')) {
 26404 if (!is_dir($dir)) {
 26405 Silencer::call('mkdir', $dir, 0777, true);
 26406 }
 26407 Silencer::call('file_put_contents', $dir . '/.htaccess', 'Deny from all');
 26408 }
 26409 }
 26410 }
 26411 
 26412 
 26413 $file = new JsonFile($config->get('home').'/auth.json');
 26414 if ($file->exists()) {
 26415 if ($io && $io->isDebug()) {
 26416 $io->writeError('Loading config file ' . $file->getPath());
 26417 }
 26418 $config->merge(array('config' => $file->read()), $file->getPath());
 26419 }
 26420 $config->setAuthConfigSource(new JsonConfigSource($file, true));
 26421 
 26422 
 26423 if ($composerAuthEnv = Platform::getEnv('COMPOSER_AUTH')) {
 26424 $authData = json_decode($composerAuthEnv, true);
 26425 
 26426 if (null === $authData) {
 26427 if ($io) {
 26428 $io->writeError('<error>COMPOSER_AUTH environment variable is malformed, should be a valid JSON object</error>');
 26429 }
 26430 } else {
 26431 if ($io && $io->isDebug()) {
 26432 $io->writeError('Loading auth config from COMPOSER_AUTH');
 26433 }
 26434 $config->merge(array('config' => $authData), 'COMPOSER_AUTH');
 26435 }
 26436 }
 26437 
 26438 return $config;
 26439 }
 26440 
 26441 
 26442 
 26443 
 26444 public static function getComposerFile()
 26445 {
 26446 return trim(Platform::getEnv('COMPOSER')) ?: './composer.json';
 26447 }
 26448 
 26449 
 26450 
 26451 
 26452 
 26453 
 26454 public static function getLockFile($composerFile)
 26455 {
 26456 return "json" === pathinfo($composerFile, PATHINFO_EXTENSION)
 26457 ? substr($composerFile, 0, -4).'lock'
 26458 : $composerFile . '.lock';
 26459 }
 26460 
 26461 
 26462 
 26463 
 26464 public static function createAdditionalStyles()
 26465 {
 26466 return array(
 26467 'highlight' => new OutputFormatterStyle('red'),
 26468 'warning' => new OutputFormatterStyle('black', 'yellow'),
 26469 );
 26470 }
 26471 
 26472 
 26473 
 26474 
 26475 
 26476 
 26477 public static function createOutput()
 26478 {
 26479 $styles = self::createAdditionalStyles();
 26480 $formatter = new OutputFormatter(false, $styles);
 26481 
 26482 return new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, null, $formatter);
 26483 }
 26484 
 26485 
 26486 
 26487 
 26488 
 26489 
 26490 
 26491 
 26492 
 26493 
 26494 
 26495 
 26496 
 26497 
 26498 
 26499 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true, $disableScripts = false)
 26500 {
 26501 $cwd = $cwd ?: (string) getcwd();
 26502 
 26503 
 26504 if (null === $localConfig) {
 26505 $localConfig = static::getComposerFile();
 26506 }
 26507 
 26508 $localConfigSource = Config::SOURCE_UNKNOWN;
 26509 if (is_string($localConfig)) {
 26510 $composerFile = $localConfig;
 26511 
 26512 $file = new JsonFile($localConfig, null, $io);
 26513 
 26514 if (!$file->exists()) {
 26515 if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
 26516 $message = 'Composer could not find a composer.json file in '.$cwd;
 26517 } else {
 26518 $message = 'Composer could not find the config file: '.$localConfig;
 26519 }
 26520 $instructions = $fullLoad ? 'To initialize a project, please create a composer.json file. See https://getcomposer.org/basic-usage' : '';
 26521 throw new \InvalidArgumentException($message.PHP_EOL.$instructions);
 26522 }
 26523 
 26524 try {
 26525 $file->validateSchema(JsonFile::LAX_SCHEMA);
 26526 } catch (JsonValidationException $e) {
 26527 $errors = ' - ' . implode(PHP_EOL . ' - ', $e->getErrors());
 26528 $message = $e->getMessage() . ':' . PHP_EOL . $errors;
 26529 throw new JsonValidationException($message);
 26530 }
 26531 $jsonParser = new JsonParser;
 26532 try {
 26533 $jsonParser->parse(file_get_contents($localConfig), JsonParser::DETECT_KEY_CONFLICTS);
 26534 } catch (DuplicateKeyException $e) {
 26535 $details = $e->getDetails();
 26536 $io->writeError('<warning>Key '.$details['key'].' is a duplicate in '.$localConfig.' at line '.$details['line'].'</warning>');
 26537 }
 26538 
 26539 $localConfig = $file->read();
 26540 $localConfigSource = $file->getPath();
 26541 }
 26542 
 26543 
 26544 $config = static::createConfig($io, $cwd);
 26545 $config->merge($localConfig, $localConfigSource);
 26546 if (isset($composerFile)) {
 26547 $io->writeError('Loading config file ' . $composerFile .' ('.realpath($composerFile).')', true, IOInterface::DEBUG);
 26548 $config->setConfigSource(new JsonConfigSource(new JsonFile(realpath($composerFile), null, $io)));
 26549 
 26550 $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json', null, $io);
 26551 if ($localAuthFile->exists()) {
 26552 $io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG);
 26553 $config->merge(array('config' => $localAuthFile->read()), $localAuthFile->getPath());
 26554 $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
 26555 }
 26556 }
 26557 
 26558 $vendorDir = $config->get('vendor-dir');
 26559 
 26560 
 26561 $composer = new Composer();
 26562 $composer->setConfig($config);
 26563 
 26564 if ($fullLoad) {
 26565 
 26566 $io->loadConfiguration($config);
 26567 
 26568 
 26569 if (!class_exists('Composer\InstalledVersions', false) && file_exists($installedVersionsPath = $config->get('vendor-dir').'/composer/InstalledVersions.php')) {
 26570 include $installedVersionsPath;
 26571 }
 26572 }
 26573 
 26574 $httpDownloader = self::createHttpDownloader($io, $config);
 26575 $process = new ProcessExecutor($io);
 26576 $loop = new Loop($httpDownloader, $process);
 26577 $composer->setLoop($loop);
 26578 
 26579 
 26580 $dispatcher = new EventDispatcher($composer, $io, $process);
 26581 $dispatcher->setRunScripts(!$disableScripts);
 26582 $composer->setEventDispatcher($dispatcher);
 26583 
 26584 
 26585 $rm = RepositoryFactory::manager($io, $config, $httpDownloader, $dispatcher, $process);
 26586 $composer->setRepositoryManager($rm);
 26587 
 26588 
 26589 
 26590 if (!$fullLoad && !isset($localConfig['version'])) {
 26591 $localConfig['version'] = '1.0.0';
 26592 }
 26593 
 26594 
 26595 $parser = new VersionParser;
 26596 $guesser = new VersionGuesser($config, $process, $parser);
 26597 $loader = $this->loadRootPackage($rm, $config, $parser, $guesser, $io);
 26598 $package = $loader->load($localConfig, 'Composer\Package\RootPackage', $cwd);
 26599 $composer->setPackage($package);
 26600 
 26601 
 26602 $this->addLocalRepository($io, $rm, $vendorDir, $package, $process);
 26603 
 26604 
 26605 $im = $this->createInstallationManager($loop, $io, $dispatcher);
 26606 $composer->setInstallationManager($im);
 26607 
 26608 if ($fullLoad) {
 26609 
 26610 $dm = $this->createDownloadManager($io, $config, $httpDownloader, $process, $dispatcher);
 26611 $composer->setDownloadManager($dm);
 26612 
 26613 
 26614 $generator = new AutoloadGenerator($dispatcher, $io);
 26615 $composer->setAutoloadGenerator($generator);
 26616 
 26617 
 26618 $am = $this->createArchiveManager($config, $dm, $loop);
 26619 $composer->setArchiveManager($am);
 26620 }
 26621 
 26622 
 26623 $this->createDefaultInstallers($im, $composer, $io, $process);
 26624 
 26625 if ($fullLoad) {
 26626 $globalComposer = null;
 26627 if (realpath($config->get('home')) !== $cwd) {
 26628 $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins, $disableScripts);
 26629 }
 26630 
 26631 $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins);
 26632 $composer->setPluginManager($pm);
 26633 
 26634 $pm->loadInstalledPlugins();
 26635 }
 26636 
 26637 
 26638 if ($fullLoad && isset($composerFile)) {
 26639 $lockFile = self::getLockFile($composerFile);
 26640 
 26641 $locker = new Package\Locker($io, new JsonFile($lockFile, null, $io), $im, file_get_contents($composerFile), $process);
 26642 $composer->setLocker($locker);
 26643 }
 26644 
 26645 if ($fullLoad) {
 26646 $initEvent = new Event(PluginEvents::INIT);
 26647 $composer->getEventDispatcher()->dispatch($initEvent->getName(), $initEvent);
 26648 
 26649 
 26650 
 26651 $this->purgePackages($rm->getLocalRepository(), $im);
 26652 }
 26653 
 26654 return $composer;
 26655 }
 26656 
 26657 
 26658 
 26659 
 26660 
 26661 
 26662 
 26663 public static function createGlobal(IOInterface $io, $disablePlugins = false, $disableScripts = false)
 26664 {
 26665 $factory = new static();
 26666 
 26667 return $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, $disableScripts, true);
 26668 }
 26669 
 26670 
 26671 
 26672 
 26673 
 26674 
 26675 
 26676 protected function addLocalRepository(IOInterface $io, RepositoryManager $rm, $vendorDir, RootPackageInterface $rootPackage, ProcessExecutor $process = null)
 26677 {
 26678 $fs = null;
 26679 if ($process) {
 26680 $fs = new Filesystem($process);
 26681 }
 26682 
 26683 $rm->setLocalRepository(new Repository\InstalledFilesystemRepository(new JsonFile($vendorDir.'/composer/installed.json', null, $io), true, $rootPackage, $fs));
 26684 }
 26685 
 26686 
 26687 
 26688 
 26689 
 26690 
 26691 
 26692 
 26693 protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins, $disableScripts, $fullLoad = false)
 26694 {
 26695 $composer = null;
 26696 try {
 26697 $composer = $this->createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), $fullLoad, $disableScripts);
 26698 } catch (\Exception $e) {
 26699 $io->writeError('Failed to initialize global composer: '.$e->getMessage(), true, IOInterface::DEBUG);
 26700 }
 26701 
 26702 return $composer;
 26703 }
 26704 
 26705 
 26706 
 26707 
 26708 
 26709 
 26710 
 26711 public function createDownloadManager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process, EventDispatcher $eventDispatcher = null)
 26712 {
 26713 $cache = null;
 26714 if ($config->get('cache-files-ttl') > 0) {
 26715 $cache = new Cache($io, $config->get('cache-files-dir'), 'a-z0-9_./');
 26716 $cache->setReadOnly($config->get('cache-read-only'));
 26717 }
 26718 
 26719 $fs = new Filesystem($process);
 26720 
 26721 $dm = new Downloader\DownloadManager($io, false, $fs);
 26722 switch ($preferred = $config->get('preferred-install')) {
 26723 case 'dist':
 26724 $dm->setPreferDist(true);
 26725 break;
 26726 case 'source':
 26727 $dm->setPreferSource(true);
 26728 break;
 26729 case 'auto':
 26730 default:
 26731 
 26732 break;
 26733 }
 26734 
 26735 if (is_array($preferred)) {
 26736 $dm->setPreferences($preferred);
 26737 }
 26738 
 26739 $dm->setDownloader('git', new Downloader\GitDownloader($io, $config, $process, $fs));
 26740 $dm->setDownloader('svn', new Downloader\SvnDownloader($io, $config, $process, $fs));
 26741 $dm->setDownloader('fossil', new Downloader\FossilDownloader($io, $config, $process, $fs));
 26742 $dm->setDownloader('hg', new Downloader\HgDownloader($io, $config, $process, $fs));
 26743 $dm->setDownloader('perforce', new Downloader\PerforceDownloader($io, $config, $process, $fs));
 26744 $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26745 $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26746 $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26747 $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26748 $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26749 $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26750 $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26751 $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $fs, $process));
 26752 
 26753 return $dm;
 26754 }
 26755 
 26756 
 26757 
 26758 
 26759 
 26760 
 26761 public function createArchiveManager(Config $config, Downloader\DownloadManager $dm, Loop $loop)
 26762 {
 26763 $am = new Archiver\ArchiveManager($dm, $loop);
 26764 $am->addArchiver(new Archiver\ZipArchiver);
 26765 $am->addArchiver(new Archiver\PharArchiver);
 26766 
 26767 return $am;
 26768 }
 26769 
 26770 
 26771 
 26772 
 26773 
 26774 
 26775 
 26776 
 26777 protected function createPluginManager(IOInterface $io, Composer $composer, Composer $globalComposer = null, $disablePlugins = false)
 26778 {
 26779 return new Plugin\PluginManager($io, $composer, $globalComposer, $disablePlugins);
 26780 }
 26781 
 26782 
 26783 
 26784 
 26785 public function createInstallationManager(Loop $loop, IOInterface $io, EventDispatcher $eventDispatcher = null)
 26786 {
 26787 return new Installer\InstallationManager($loop, $io, $eventDispatcher);
 26788 }
 26789 
 26790 
 26791 
 26792 
 26793 protected function createDefaultInstallers(Installer\InstallationManager $im, Composer $composer, IOInterface $io, ProcessExecutor $process = null)
 26794 {
 26795 $fs = new Filesystem($process);
 26796 $binaryInstaller = new Installer\BinaryInstaller($io, rtrim($composer->getConfig()->get('bin-dir'), '/'), $composer->getConfig()->get('bin-compat'), $fs, rtrim($composer->getConfig()->get('vendor-dir'), '/'));
 26797 
 26798 $im->addInstaller(new Installer\LibraryInstaller($io, $composer, null, $fs, $binaryInstaller));
 26799 $im->addInstaller(new Installer\PluginInstaller($io, $composer, $fs, $binaryInstaller));
 26800 $im->addInstaller(new Installer\MetapackageInstaller($io));
 26801 }
 26802 
 26803 
 26804 
 26805 
 26806 
 26807 
 26808 
 26809 protected function purgePackages(InstalledRepositoryInterface $repo, Installer\InstallationManager $im)
 26810 {
 26811 foreach ($repo->getPackages() as $package) {
 26812 if (!$im->isPackageInstalled($repo, $package)) {
 26813 $repo->removePackage($package);
 26814 }
 26815 }
 26816 }
 26817 
 26818 
 26819 
 26820 
 26821 protected function loadRootPackage(RepositoryManager $rm, Config $config, VersionParser $parser, VersionGuesser $guesser, IOInterface $io)
 26822 {
 26823 return new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser, $io);
 26824 }
 26825 
 26826 
 26827 
 26828 
 26829 
 26830 
 26831 
 26832 
 26833 
 26834 public static function create(IOInterface $io, $config = null, $disablePlugins = false, $disableScripts = false)
 26835 {
 26836 $factory = new static();
 26837 
 26838 return $factory->createComposer($io, $config, $disablePlugins, null, true, $disableScripts);
 26839 }
 26840 
 26841 
 26842 
 26843 
 26844 
 26845 
 26846 
 26847 
 26848 
 26849 public static function createHttpDownloader(IOInterface $io, Config $config, $options = array())
 26850 {
 26851 static $warned = false;
 26852 $disableTls = false;
 26853 
 26854 if (isset($_SERVER['argv']) && in_array('disable-tls', $_SERVER['argv']) && (in_array('conf', $_SERVER['argv']) || in_array('config', $_SERVER['argv']))) {
 26855 $warned = true;
 26856 $disableTls = !extension_loaded('openssl');
 26857 } elseif ($config->get('disable-tls') === true) {
 26858 if (!$warned) {
 26859 $io->writeError('<warning>You are running Composer with SSL/TLS protection disabled.</warning>');
 26860 }
 26861 $warned = true;
 26862 $disableTls = true;
 26863 } elseif (!extension_loaded('openssl')) {
 26864 throw new Exception\NoSslException('The openssl extension is required for SSL/TLS protection but is not available. '
 26865 . 'If you can not enable the openssl extension, you can disable this error, at your own risk, by setting the \'disable-tls\' option to true.');
 26866 }
 26867 $httpDownloaderOptions = array();
 26868 if ($disableTls === false) {
 26869 if ($config->get('cafile')) {
 26870 $httpDownloaderOptions['ssl']['cafile'] = $config->get('cafile');
 26871 }
 26872 if ($config->get('capath')) {
 26873 $httpDownloaderOptions['ssl']['capath'] = $config->get('capath');
 26874 }
 26875 $httpDownloaderOptions = array_replace_recursive($httpDownloaderOptions, $options);
 26876 }
 26877 try {
 26878 $httpDownloader = new HttpDownloader($io, $config, $httpDownloaderOptions, $disableTls);
 26879 } catch (TransportException $e) {
 26880 if (false !== strpos($e->getMessage(), 'cafile')) {
 26881 $io->write('<error>Unable to locate a valid CA certificate file. You must set a valid \'cafile\' option.</error>');
 26882 $io->write('<error>A valid CA certificate file is required for SSL/TLS protection.</error>');
 26883 if (PHP_VERSION_ID < 50600) {
 26884 $io->write('<error>It is recommended you upgrade to PHP 5.6+ which can detect your system CA file automatically.</error>');
 26885 }
 26886 $io->write('<error>You can disable this error, at your own risk, by setting the \'disable-tls\' option to true.</error>');
 26887 }
 26888 throw $e;
 26889 }
 26890 
 26891 return $httpDownloader;
 26892 }
 26893 
 26894 
 26895 
 26896 
 26897 private static function useXdg()
 26898 {
 26899 foreach (array_keys($_SERVER) as $key) {
 26900 if (strpos($key, 'XDG_') === 0) {
 26901 return true;
 26902 }
 26903 }
 26904 
 26905 if (Silencer::call('is_dir', '/etc/xdg')) {
 26906 return true;
 26907 }
 26908 
 26909 return false;
 26910 }
 26911 
 26912 
 26913 
 26914 
 26915 
 26916 private static function getUserDir()
 26917 {
 26918 $home = Platform::getEnv('HOME');
 26919 if (!$home) {
 26920 throw new \RuntimeException('The HOME or COMPOSER_HOME environment variable must be set for composer to run correctly');
 26921 }
 26922 
 26923 return rtrim(strtr($home, '\\', '/'), '/');
 26924 }
 26925 }
 26926 <?php
 26927 
 26928 namespace Composer\Filter\PlatformRequirementFilter;
 26929 
 26930 use Composer\Repository\PlatformRepository;
 26931 
 26932 final class IgnoreAllPlatformRequirementFilter implements PlatformRequirementFilterInterface
 26933 {
 26934 
 26935 
 26936 
 26937 
 26938 public function isIgnored($req)
 26939 {
 26940 return PlatformRepository::isPlatformPackage($req);
 26941 }
 26942 }
 26943 <?php
 26944 
 26945 namespace Composer\Filter\PlatformRequirementFilter;
 26946 
 26947 use Composer\Package\BasePackage;
 26948 use Composer\Pcre\Preg;
 26949 use Composer\Repository\PlatformRepository;
 26950 use Composer\Semver\Constraint\Constraint;
 26951 use Composer\Semver\Constraint\ConstraintInterface;
 26952 use Composer\Semver\Constraint\MatchAllConstraint;
 26953 use Composer\Semver\Constraint\MultiConstraint;
 26954 use Composer\Semver\Interval;
 26955 use Composer\Semver\Intervals;
 26956 
 26957 final class IgnoreListPlatformRequirementFilter implements PlatformRequirementFilterInterface
 26958 {
 26959 
 26960 
 26961 
 26962 private $ignoreRegex;
 26963 
 26964 
 26965 
 26966 
 26967 private $ignoreUpperBoundRegex;
 26968 
 26969 
 26970 
 26971 
 26972 public function __construct(array $reqList)
 26973 {
 26974 $ignoreAll = $ignoreUpperBound = array();
 26975 foreach ($reqList as $req) {
 26976 if (substr($req, -1) === '+') {
 26977 $ignoreUpperBound[] = substr($req, 0, -1);
 26978 } else {
 26979 $ignoreAll[] = $req;
 26980 }
 26981 }
 26982 $this->ignoreRegex = BasePackage::packageNamesToRegexp($ignoreAll);
 26983 $this->ignoreUpperBoundRegex = BasePackage::packageNamesToRegexp($ignoreUpperBound);
 26984 }
 26985 
 26986 
 26987 
 26988 
 26989 
 26990 public function isIgnored($req)
 26991 {
 26992 if (!PlatformRepository::isPlatformPackage($req)) {
 26993 return false;
 26994 }
 26995 
 26996 return Preg::isMatch($this->ignoreRegex, $req);
 26997 }
 26998 
 26999 
 27000 
 27001 
 27002 
 27003 public function filterConstraint($req, ConstraintInterface $constraint)
 27004 {
 27005 if (!PlatformRepository::isPlatformPackage($req)) {
 27006 return $constraint;
 27007 }
 27008 
 27009 if (!Preg::isMatch($this->ignoreUpperBoundRegex, $req)) {
 27010 return $constraint;
 27011 }
 27012 
 27013 if (Preg::isMatch($this->ignoreRegex, $req)) {
 27014 return new MatchAllConstraint;
 27015 }
 27016 
 27017 $intervals = Intervals::get($constraint);
 27018 $last = end($intervals['numeric']);
 27019 if ($last !== false && (string) $last->getEnd() !== (string) Interval::untilPositiveInfinity()) {
 27020 $constraint = new MultiConstraint(array($constraint, new Constraint('>=', $last->getEnd()->getVersion())), false);
 27021 }
 27022 
 27023 return $constraint;
 27024 }
 27025 }
 27026 <?php
 27027 
 27028 namespace Composer\Filter\PlatformRequirementFilter;
 27029 
 27030 final class IgnoreNothingPlatformRequirementFilter implements PlatformRequirementFilterInterface
 27031 {
 27032 
 27033 
 27034 
 27035 
 27036 public function isIgnored($req)
 27037 {
 27038 return false;
 27039 }
 27040 }
 27041 <?php
 27042 
 27043 namespace Composer\Filter\PlatformRequirementFilter;
 27044 
 27045 final class PlatformRequirementFilterFactory
 27046 {
 27047 
 27048 
 27049 
 27050 
 27051 
 27052 public static function fromBoolOrList($boolOrList)
 27053 {
 27054 if (is_bool($boolOrList)) {
 27055 return $boolOrList ? self::ignoreAll() : self::ignoreNothing();
 27056 }
 27057 
 27058 if (is_array($boolOrList)) {
 27059 return new IgnoreListPlatformRequirementFilter($boolOrList);
 27060 }
 27061 
 27062 throw new \InvalidArgumentException(
 27063 sprintf(
 27064 'PlatformRequirementFilter: Unknown $boolOrList parameter %s. Please report at https://github.com/composer/composer/issues/new.',
 27065 gettype($boolOrList)
 27066 )
 27067 );
 27068 }
 27069 
 27070 
 27071 
 27072 
 27073 public static function ignoreAll()
 27074 {
 27075 return new IgnoreAllPlatformRequirementFilter();
 27076 }
 27077 
 27078 
 27079 
 27080 
 27081 public static function ignoreNothing()
 27082 {
 27083 return new IgnoreNothingPlatformRequirementFilter();
 27084 }
 27085 }
 27086 <?php
 27087 
 27088 namespace Composer\Filter\PlatformRequirementFilter;
 27089 
 27090 interface PlatformRequirementFilterInterface
 27091 {
 27092 
 27093 
 27094 
 27095 
 27096 public function isIgnored($req);
 27097 }
 27098 <?php
 27099 
 27100 
 27101 
 27102 
 27103 
 27104 
 27105 
 27106 
 27107 
 27108 
 27109 
 27110 namespace Composer\IO;
 27111 
 27112 use Composer\Config;
 27113 use Composer\Pcre\Preg;
 27114 use Composer\Util\ProcessExecutor;
 27115 use Psr\Log\LogLevel;
 27116 
 27117 abstract class BaseIO implements IOInterface
 27118 {
 27119 
 27120 protected $authentications = array();
 27121 
 27122 
 27123 
 27124 
 27125 public function getAuthentications()
 27126 {
 27127 return $this->authentications;
 27128 }
 27129 
 27130 
 27131 
 27132 
 27133 public function resetAuthentications()
 27134 {
 27135 $this->authentications = array();
 27136 }
 27137 
 27138 
 27139 
 27140 
 27141 public function hasAuthentication($repositoryName)
 27142 {
 27143 return isset($this->authentications[$repositoryName]);
 27144 }
 27145 
 27146 
 27147 
 27148 
 27149 public function getAuthentication($repositoryName)
 27150 {
 27151 if (isset($this->authentications[$repositoryName])) {
 27152 return $this->authentications[$repositoryName];
 27153 }
 27154 
 27155 return array('username' => null, 'password' => null);
 27156 }
 27157 
 27158 
 27159 
 27160 
 27161 public function setAuthentication($repositoryName, $username, $password = null)
 27162 {
 27163 $this->authentications[$repositoryName] = array('username' => $username, 'password' => $password);
 27164 }
 27165 
 27166 
 27167 
 27168 
 27169 public function writeRaw($messages, $newline = true, $verbosity = self::NORMAL)
 27170 {
 27171 $this->write($messages, $newline, $verbosity);
 27172 }
 27173 
 27174 
 27175 
 27176 
 27177 public function writeErrorRaw($messages, $newline = true, $verbosity = self::NORMAL)
 27178 {
 27179 $this->writeError($messages, $newline, $verbosity);
 27180 }
 27181 
 27182 
 27183 
 27184 
 27185 
 27186 
 27187 
 27188 
 27189 
 27190 
 27191 protected function checkAndSetAuthentication($repositoryName, $username, $password = null)
 27192 {
 27193 if ($this->hasAuthentication($repositoryName)) {
 27194 $auth = $this->getAuthentication($repositoryName);
 27195 if ($auth['username'] === $username && $auth['password'] === $password) {
 27196 return;
 27197 }
 27198 
 27199 $this->writeError(
 27200 sprintf(
 27201 "<warning>Warning: You should avoid overwriting already defined auth settings for %s.</warning>",
 27202 $repositoryName
 27203 )
 27204 );
 27205 }
 27206 $this->setAuthentication($repositoryName, $username, $password);
 27207 }
 27208 
 27209 
 27210 
 27211 
 27212 public function loadConfiguration(Config $config)
 27213 {
 27214 $bitbucketOauth = $config->get('bitbucket-oauth') ?: array();
 27215 $githubOauth = $config->get('github-oauth') ?: array();
 27216 $gitlabOauth = $config->get('gitlab-oauth') ?: array();
 27217 $gitlabToken = $config->get('gitlab-token') ?: array();
 27218 $httpBasic = $config->get('http-basic') ?: array();
 27219 $bearerToken = $config->get('bearer') ?: array();
 27220 
 27221 
 27222 
 27223 foreach ($bitbucketOauth as $domain => $cred) {
 27224 $this->checkAndSetAuthentication($domain, $cred['consumer-key'], $cred['consumer-secret']);
 27225 }
 27226 
 27227 foreach ($githubOauth as $domain => $token) {
 27228 
 27229 
 27230 if (!Preg::isMatch('{^[.A-Za-z0-9_]+$}', $token)) {
 27231 throw new \UnexpectedValueException('Your github oauth token for '.$domain.' contains invalid characters: "'.$token.'"');
 27232 }
 27233 $this->checkAndSetAuthentication($domain, $token, 'x-oauth-basic');
 27234 }
 27235 
 27236 foreach ($gitlabOauth as $domain => $token) {
 27237 $this->checkAndSetAuthentication($domain, $token, 'oauth2');
 27238 }
 27239 
 27240 foreach ($gitlabToken as $domain => $token) {
 27241 $username = is_array($token) && array_key_exists("username", $token) ? $token["username"] : $token;
 27242 $password = is_array($token) && array_key_exists("token", $token) ? $token["token"] : 'private-token';
 27243 $this->checkAndSetAuthentication($domain, $username, $password);
 27244 }
 27245 
 27246 
 27247 foreach ($httpBasic as $domain => $cred) {
 27248 $this->checkAndSetAuthentication($domain, $cred['username'], $cred['password']);
 27249 }
 27250 
 27251 foreach ($bearerToken as $domain => $token) {
 27252 $this->checkAndSetAuthentication($domain, $token, 'bearer');
 27253 }
 27254 
 27255 
 27256 ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
 27257 }
 27258 
 27259 
 27260 
 27261 
 27262 public function emergency($message, array $context = array())
 27263 {
 27264 $this->log(LogLevel::EMERGENCY, $message, $context);
 27265 }
 27266 
 27267 
 27268 
 27269 
 27270 public function alert($message, array $context = array())
 27271 {
 27272 $this->log(LogLevel::ALERT, $message, $context);
 27273 }
 27274 
 27275 
 27276 
 27277 
 27278 public function critical($message, array $context = array())
 27279 {
 27280 $this->log(LogLevel::CRITICAL, $message, $context);
 27281 }
 27282 
 27283 
 27284 
 27285 
 27286 public function error($message, array $context = array())
 27287 {
 27288 $this->log(LogLevel::ERROR, $message, $context);
 27289 }
 27290 
 27291 
 27292 
 27293 
 27294 public function warning($message, array $context = array())
 27295 {
 27296 $this->log(LogLevel::WARNING, $message, $context);
 27297 }
 27298 
 27299 
 27300 
 27301 
 27302 public function notice($message, array $context = array())
 27303 {
 27304 $this->log(LogLevel::NOTICE, $message, $context);
 27305 }
 27306 
 27307 
 27308 
 27309 
 27310 public function info($message, array $context = array())
 27311 {
 27312 $this->log(LogLevel::INFO, $message, $context);
 27313 }
 27314 
 27315 
 27316 
 27317 
 27318 public function debug($message, array $context = array())
 27319 {
 27320 $this->log(LogLevel::DEBUG, $message, $context);
 27321 }
 27322 
 27323 
 27324 
 27325 
 27326 public function log($level, $message, array $context = array())
 27327 {
 27328 if (in_array($level, array(LogLevel::EMERGENCY, LogLevel::ALERT, LogLevel::CRITICAL, LogLevel::ERROR))) {
 27329 $this->writeError('<error>'.$message.'</error>');
 27330 } elseif ($level === LogLevel::WARNING) {
 27331 $this->writeError('<warning>'.$message.'</warning>');
 27332 } elseif ($level === LogLevel::NOTICE) {
 27333 $this->writeError('<info>'.$message.'</info>', true, self::VERBOSE);
 27334 } elseif ($level === LogLevel::INFO) {
 27335 $this->writeError('<info>'.$message.'</info>', true, self::VERY_VERBOSE);
 27336 } else {
 27337 $this->writeError($message, true, self::DEBUG);
 27338 }
 27339 }
 27340 }
 27341 <?php
 27342 
 27343 
 27344 
 27345 
 27346 
 27347 
 27348 
 27349 
 27350 
 27351 
 27352 
 27353 namespace Composer\IO;
 27354 
 27355 use Composer\Pcre\Preg;
 27356 use Symfony\Component\Console\Helper\QuestionHelper;
 27357 use Symfony\Component\Console\Output\StreamOutput;
 27358 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 27359 use Symfony\Component\Console\Input\StreamableInputInterface;
 27360 use Symfony\Component\Console\Input\StringInput;
 27361 use Symfony\Component\Console\Helper\HelperSet;
 27362 
 27363 
 27364 
 27365 
 27366 class BufferIO extends ConsoleIO
 27367 {
 27368 
 27369 protected $input;
 27370 
 27371 protected $output;
 27372 
 27373 
 27374 
 27375 
 27376 
 27377 
 27378 public function __construct($input = '', $verbosity = StreamOutput::VERBOSITY_NORMAL, OutputFormatterInterface $formatter = null)
 27379 {
 27380 $input = new StringInput($input);
 27381 $input->setInteractive(false);
 27382 
 27383 $output = new StreamOutput(fopen('php://memory', 'rw'), $verbosity, $formatter ? $formatter->isDecorated() : false, $formatter);
 27384 
 27385 parent::__construct($input, $output, new HelperSet(array(
 27386 new QuestionHelper(),
 27387 )));
 27388 }
 27389 
 27390 
 27391 
 27392 
 27393 public function getOutput()
 27394 {
 27395 fseek($this->output->getStream(), 0);
 27396 
 27397 $output = stream_get_contents($this->output->getStream());
 27398 
 27399 $output = Preg::replaceCallback("{(?<=^|\n|\x08)(.+?)(\x08+)}", function ($matches) {
 27400 $pre = strip_tags($matches[1]);
 27401 
 27402 if (strlen($pre) === strlen($matches[2])) {
 27403 return '';
 27404 }
 27405 
 27406 
 27407 return rtrim($matches[1])."\n";
 27408 }, $output);
 27409 
 27410 return $output;
 27411 }
 27412 
 27413 
 27414 
 27415 
 27416 
 27417 
 27418 
 27419 
 27420 public function setUserInputs(array $inputs)
 27421 {
 27422 if (!$this->input instanceof StreamableInputInterface) {
 27423 throw new \RuntimeException('Setting the user inputs requires at least the version 3.2 of the symfony/console component.');
 27424 }
 27425 
 27426 $this->input->setStream($this->createStream($inputs));
 27427 $this->input->setInteractive(true);
 27428 }
 27429 
 27430 
 27431 
 27432 
 27433 
 27434 
 27435 private function createStream(array $inputs)
 27436 {
 27437 $stream = fopen('php://memory', 'r+');
 27438 
 27439 foreach ($inputs as $input) {
 27440 fwrite($stream, $input.PHP_EOL);
 27441 }
 27442 
 27443 rewind($stream);
 27444 
 27445 return $stream;
 27446 }
 27447 }
 27448 <?php
 27449 
 27450 
 27451 
 27452 
 27453 
 27454 
 27455 
 27456 
 27457 
 27458 
 27459 
 27460 namespace Composer\IO;
 27461 
 27462 use Composer\Question\StrictConfirmationQuestion;
 27463 use Symfony\Component\Console\Helper\HelperSet;
 27464 use Symfony\Component\Console\Helper\ProgressBar;
 27465 use Symfony\Component\Console\Input\InputInterface;
 27466 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 27467 use Symfony\Component\Console\Output\OutputInterface;
 27468 use Symfony\Component\Console\Question\ChoiceQuestion;
 27469 use Symfony\Component\Console\Question\Question;
 27470 
 27471 
 27472 
 27473 
 27474 
 27475 
 27476 
 27477 class ConsoleIO extends BaseIO
 27478 {
 27479 
 27480 protected $input;
 27481 
 27482 protected $output;
 27483 
 27484 protected $helperSet;
 27485 
 27486 protected $lastMessage = '';
 27487 
 27488 protected $lastMessageErr = '';
 27489 
 27490 
 27491 private $startTime;
 27492 
 27493 private $verbosityMap;
 27494 
 27495 
 27496 
 27497 
 27498 
 27499 
 27500 
 27501 
 27502 public function __construct(InputInterface $input, OutputInterface $output, HelperSet $helperSet)
 27503 {
 27504 $this->input = $input;
 27505 $this->output = $output;
 27506 $this->helperSet = $helperSet;
 27507 $this->verbosityMap = array(
 27508 self::QUIET => OutputInterface::VERBOSITY_QUIET,
 27509 self::NORMAL => OutputInterface::VERBOSITY_NORMAL,
 27510 self::VERBOSE => OutputInterface::VERBOSITY_VERBOSE,
 27511 self::VERY_VERBOSE => OutputInterface::VERBOSITY_VERY_VERBOSE,
 27512 self::DEBUG => OutputInterface::VERBOSITY_DEBUG,
 27513 );
 27514 }
 27515 
 27516 
 27517 
 27518 
 27519 
 27520 
 27521 public function enableDebugging($startTime)
 27522 {
 27523 $this->startTime = $startTime;
 27524 }
 27525 
 27526 
 27527 
 27528 
 27529 public function isInteractive()
 27530 {
 27531 return $this->input->isInteractive();
 27532 }
 27533 
 27534 
 27535 
 27536 
 27537 public function isDecorated()
 27538 {
 27539 return $this->output->isDecorated();
 27540 }
 27541 
 27542 
 27543 
 27544 
 27545 public function isVerbose()
 27546 {
 27547 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE;
 27548 }
 27549 
 27550 
 27551 
 27552 
 27553 public function isVeryVerbose()
 27554 {
 27555 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE;
 27556 }
 27557 
 27558 
 27559 
 27560 
 27561 public function isDebug()
 27562 {
 27563 return $this->output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG;
 27564 }
 27565 
 27566 
 27567 
 27568 
 27569 public function write($messages, $newline = true, $verbosity = self::NORMAL)
 27570 {
 27571 $this->doWrite($messages, $newline, false, $verbosity);
 27572 }
 27573 
 27574 
 27575 
 27576 
 27577 public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
 27578 {
 27579 $this->doWrite($messages, $newline, true, $verbosity);
 27580 }
 27581 
 27582 
 27583 
 27584 
 27585 public function writeRaw($messages, $newline = true, $verbosity = self::NORMAL)
 27586 {
 27587 $this->doWrite($messages, $newline, false, $verbosity, true);
 27588 }
 27589 
 27590 
 27591 
 27592 
 27593 public function writeErrorRaw($messages, $newline = true, $verbosity = self::NORMAL)
 27594 {
 27595 $this->doWrite($messages, $newline, true, $verbosity, true);
 27596 }
 27597 
 27598 
 27599 
 27600 
 27601 
 27602 
 27603 
 27604 
 27605 
 27606 
 27607 private function doWrite($messages, $newline, $stderr, $verbosity, $raw = false)
 27608 {
 27609 $sfVerbosity = $this->verbosityMap[$verbosity];
 27610 if ($sfVerbosity > $this->output->getVerbosity()) {
 27611 return;
 27612 }
 27613 
 27614 if ($raw) {
 27615 if ($sfVerbosity === OutputInterface::OUTPUT_NORMAL) {
 27616 $sfVerbosity = OutputInterface::OUTPUT_RAW;
 27617 } else {
 27618 $sfVerbosity |= OutputInterface::OUTPUT_RAW;
 27619 }
 27620 }
 27621 
 27622 if (null !== $this->startTime) {
 27623 $memoryUsage = memory_get_usage() / 1024 / 1024;
 27624 $timeSpent = microtime(true) - $this->startTime;
 27625 $messages = array_map(function ($message) use ($memoryUsage, $timeSpent) {
 27626 return sprintf('[%.1fMiB/%.2fs] %s', $memoryUsage, $timeSpent, $message);
 27627 }, (array) $messages);
 27628 }
 27629 
 27630 if (true === $stderr && $this->output instanceof ConsoleOutputInterface) {
 27631 $this->output->getErrorOutput()->write($messages, $newline, $sfVerbosity);
 27632 $this->lastMessageErr = implode($newline ? "\n" : '', (array) $messages);
 27633 
 27634 return;
 27635 }
 27636 
 27637 $this->output->write($messages, $newline, $sfVerbosity);
 27638 $this->lastMessage = implode($newline ? "\n" : '', (array) $messages);
 27639 }
 27640 
 27641 
 27642 
 27643 
 27644 public function overwrite($messages, $newline = true, $size = null, $verbosity = self::NORMAL)
 27645 {
 27646 $this->doOverwrite($messages, $newline, $size, false, $verbosity);
 27647 }
 27648 
 27649 
 27650 
 27651 
 27652 public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL)
 27653 {
 27654 $this->doOverwrite($messages, $newline, $size, true, $verbosity);
 27655 }
 27656 
 27657 
 27658 
 27659 
 27660 
 27661 
 27662 
 27663 
 27664 
 27665 
 27666 private function doOverwrite($messages, $newline, $size, $stderr, $verbosity)
 27667 {
 27668 
 27669 $messages = implode($newline ? "\n" : '', (array) $messages);
 27670 
 27671 
 27672 if (!isset($size)) {
 27673 
 27674 $size = strlen(strip_tags($stderr ? $this->lastMessageErr : $this->lastMessage));
 27675 }
 27676 
 27677 $this->doWrite(str_repeat("\x08", $size), false, $stderr, $verbosity);
 27678 
 27679 
 27680 $this->doWrite($messages, false, $stderr, $verbosity);
 27681 
 27682 
 27683 
 27684 
 27685 $fill = $size - strlen(strip_tags($messages));
 27686 if ($fill > 0) {
 27687 
 27688 $this->doWrite(str_repeat(' ', $fill), false, $stderr, $verbosity);
 27689 
 27690 $this->doWrite(str_repeat("\x08", $fill), false, $stderr, $verbosity);
 27691 }
 27692 
 27693 if ($newline) {
 27694 $this->doWrite('', true, $stderr, $verbosity);
 27695 }
 27696 
 27697 if ($stderr) {
 27698 $this->lastMessageErr = $messages;
 27699 } else {
 27700 $this->lastMessage = $messages;
 27701 }
 27702 }
 27703 
 27704 
 27705 
 27706 
 27707 
 27708 public function getProgressBar($max = 0)
 27709 {
 27710 return new ProgressBar($this->getErrorOutput(), $max);
 27711 }
 27712 
 27713 
 27714 
 27715 
 27716 public function ask($question, $default = null)
 27717 {
 27718 
 27719 $helper = $this->helperSet->get('question');
 27720 $question = new Question($question, $default);
 27721 
 27722 return $helper->ask($this->input, $this->getErrorOutput(), $question);
 27723 }
 27724 
 27725 
 27726 
 27727 
 27728 public function askConfirmation($question, $default = true)
 27729 {
 27730 
 27731 $helper = $this->helperSet->get('question');
 27732 $question = new StrictConfirmationQuestion($question, $default);
 27733 
 27734 return $helper->ask($this->input, $this->getErrorOutput(), $question);
 27735 }
 27736 
 27737 
 27738 
 27739 
 27740 public function askAndValidate($question, $validator, $attempts = null, $default = null)
 27741 {
 27742 
 27743 $helper = $this->helperSet->get('question');
 27744 $question = new Question($question, $default);
 27745 $question->setValidator($validator);
 27746 $question->setMaxAttempts($attempts);
 27747 
 27748 return $helper->ask($this->input, $this->getErrorOutput(), $question);
 27749 }
 27750 
 27751 
 27752 
 27753 
 27754 public function askAndHideAnswer($question)
 27755 {
 27756 
 27757 $helper = $this->helperSet->get('question');
 27758 $question = new Question($question);
 27759 $question->setHidden(true);
 27760 
 27761 return $helper->ask($this->input, $this->getErrorOutput(), $question);
 27762 }
 27763 
 27764 
 27765 
 27766 
 27767 public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
 27768 {
 27769 
 27770 $helper = $this->helperSet->get('question');
 27771 $question = new ChoiceQuestion($question, $choices, $default);
 27772 $question->setMaxAttempts($attempts ?: null); 
 27773 $question->setErrorMessage($errorMessage);
 27774 $question->setMultiselect($multiselect);
 27775 
 27776 $result = $helper->ask($this->input, $this->getErrorOutput(), $question);
 27777 
 27778 if (!is_array($result)) {
 27779 return (string) array_search($result, $choices, true);
 27780 }
 27781 
 27782 $results = array();
 27783 foreach ($choices as $index => $choice) {
 27784 if (in_array($choice, $result, true)) {
 27785 $results[] = (string) $index;
 27786 }
 27787 }
 27788 
 27789 return $results;
 27790 }
 27791 
 27792 
 27793 
 27794 
 27795 private function getErrorOutput()
 27796 {
 27797 if ($this->output instanceof ConsoleOutputInterface) {
 27798 return $this->output->getErrorOutput();
 27799 }
 27800 
 27801 return $this->output;
 27802 }
 27803 }
 27804 <?php
 27805 
 27806 
 27807 
 27808 
 27809 
 27810 
 27811 
 27812 
 27813 
 27814 
 27815 
 27816 namespace Composer\IO;
 27817 
 27818 use Composer\Config;
 27819 use Psr\Log\LoggerInterface;
 27820 
 27821 
 27822 
 27823 
 27824 
 27825 
 27826 interface IOInterface extends LoggerInterface
 27827 {
 27828 const QUIET = 1;
 27829 const NORMAL = 2;
 27830 const VERBOSE = 4;
 27831 const VERY_VERBOSE = 8;
 27832 const DEBUG = 16;
 27833 
 27834 
 27835 
 27836 
 27837 
 27838 
 27839 public function isInteractive();
 27840 
 27841 
 27842 
 27843 
 27844 
 27845 
 27846 public function isVerbose();
 27847 
 27848 
 27849 
 27850 
 27851 
 27852 
 27853 public function isVeryVerbose();
 27854 
 27855 
 27856 
 27857 
 27858 
 27859 
 27860 public function isDebug();
 27861 
 27862 
 27863 
 27864 
 27865 
 27866 
 27867 public function isDecorated();
 27868 
 27869 
 27870 
 27871 
 27872 
 27873 
 27874 
 27875 
 27876 
 27877 
 27878 public function write($messages, $newline = true, $verbosity = self::NORMAL);
 27879 
 27880 
 27881 
 27882 
 27883 
 27884 
 27885 
 27886 
 27887 
 27888 
 27889 public function writeError($messages, $newline = true, $verbosity = self::NORMAL);
 27890 
 27891 
 27892 
 27893 
 27894 
 27895 
 27896 
 27897 
 27898 
 27899 
 27900 public function writeRaw($messages, $newline = true, $verbosity = self::NORMAL);
 27901 
 27902 
 27903 
 27904 
 27905 
 27906 
 27907 
 27908 
 27909 
 27910 
 27911 public function writeErrorRaw($messages, $newline = true, $verbosity = self::NORMAL);
 27912 
 27913 
 27914 
 27915 
 27916 
 27917 
 27918 
 27919 
 27920 
 27921 
 27922 
 27923 public function overwrite($messages, $newline = true, $size = null, $verbosity = self::NORMAL);
 27924 
 27925 
 27926 
 27927 
 27928 
 27929 
 27930 
 27931 
 27932 
 27933 
 27934 
 27935 public function overwriteError($messages, $newline = true, $size = null, $verbosity = self::NORMAL);
 27936 
 27937 
 27938 
 27939 
 27940 
 27941 
 27942 
 27943 
 27944 
 27945 
 27946 public function ask($question, $default = null);
 27947 
 27948 
 27949 
 27950 
 27951 
 27952 
 27953 
 27954 
 27955 
 27956 
 27957 
 27958 public function askConfirmation($question, $default = true);
 27959 
 27960 
 27961 
 27962 
 27963 
 27964 
 27965 
 27966 
 27967 
 27968 
 27969 
 27970 
 27971 
 27972 
 27973 
 27974 
 27975 public function askAndValidate($question, $validator, $attempts = null, $default = null);
 27976 
 27977 
 27978 
 27979 
 27980 
 27981 
 27982 
 27983 
 27984 public function askAndHideAnswer($question);
 27985 
 27986 
 27987 
 27988 
 27989 
 27990 
 27991 
 27992 
 27993 
 27994 
 27995 
 27996 
 27997 
 27998 
 27999 public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false);
 28000 
 28001 
 28002 
 28003 
 28004 
 28005 
 28006 public function getAuthentications();
 28007 
 28008 
 28009 
 28010 
 28011 
 28012 
 28013 
 28014 
 28015 public function hasAuthentication($repositoryName);
 28016 
 28017 
 28018 
 28019 
 28020 
 28021 
 28022 
 28023 
 28024 public function getAuthentication($repositoryName);
 28025 
 28026 
 28027 
 28028 
 28029 
 28030 
 28031 
 28032 
 28033 
 28034 
 28035 public function setAuthentication($repositoryName, $username, $password = null);
 28036 
 28037 
 28038 
 28039 
 28040 
 28041 
 28042 
 28043 
 28044 public function loadConfiguration(Config $config);
 28045 }
 28046 <?php
 28047 
 28048 
 28049 
 28050 
 28051 
 28052 
 28053 
 28054 
 28055 
 28056 
 28057 
 28058 namespace Composer\IO;
 28059 
 28060 
 28061 
 28062 
 28063 
 28064 
 28065 class NullIO extends BaseIO
 28066 {
 28067 
 28068 
 28069 
 28070 public function isInteractive()
 28071 {
 28072 return false;
 28073 }
 28074 
 28075 
 28076 
 28077 
 28078 public function isVerbose()
 28079 {
 28080 return false;
 28081 }
 28082 
 28083 
 28084 
 28085 
 28086 public function isVeryVerbose()
 28087 {
 28088 return false;
 28089 }
 28090 
 28091 
 28092 
 28093 
 28094 public function isDebug()
 28095 {
 28096 return false;
 28097 }
 28098 
 28099 
 28100 
 28101 
 28102 public function isDecorated()
 28103 {
 28104 return false;
 28105 }
 28106 
 28107 
 28108 
 28109 
 28110 public function write($messages, $newline = true, $verbosity = self::NORMAL)
 28111 {
 28112 }
 28113 
 28114 
 28115 
 28116 
 28117 public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
 28118 {
 28119 }
 28120 
 28121 
 28122 
 28123 
 28124 public function overwrite($messages, $newline = true, $size = 80, $verbosity = self::NORMAL)
 28125 {
 28126 }
 28127 
 28128 
 28129 
 28130 
 28131 public function overwriteError($messages, $newline = true, $size = 80, $verbosity = self::NORMAL)
 28132 {
 28133 }
 28134 
 28135 
 28136 
 28137 
 28138 public function ask($question, $default = null)
 28139 {
 28140 return $default;
 28141 }
 28142 
 28143 
 28144 
 28145 
 28146 public function askConfirmation($question, $default = true)
 28147 {
 28148 return $default;
 28149 }
 28150 
 28151 
 28152 
 28153 
 28154 public function askAndValidate($question, $validator, $attempts = null, $default = null)
 28155 {
 28156 return $default;
 28157 }
 28158 
 28159 
 28160 
 28161 
 28162 public function askAndHideAnswer($question)
 28163 {
 28164 return null;
 28165 }
 28166 
 28167 
 28168 
 28169 
 28170 public function select($question, $choices, $default, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
 28171 {
 28172 return $default;
 28173 }
 28174 }
 28175 <?php
 28176 
 28177 
 28178 
 28179 
 28180 
 28181 
 28182 
 28183 
 28184 
 28185 
 28186 
 28187 namespace Composer;
 28188 
 28189 use Composer\Autoload\AutoloadGenerator;
 28190 use Composer\Console\GithubActionError;
 28191 use Composer\DependencyResolver\DefaultPolicy;
 28192 use Composer\DependencyResolver\LocalRepoTransaction;
 28193 use Composer\DependencyResolver\LockTransaction;
 28194 use Composer\DependencyResolver\Operation\UpdateOperation;
 28195 use Composer\DependencyResolver\Operation\InstallOperation;
 28196 use Composer\DependencyResolver\Operation\UninstallOperation;
 28197 use Composer\DependencyResolver\PoolOptimizer;
 28198 use Composer\DependencyResolver\Pool;
 28199 use Composer\DependencyResolver\Request;
 28200 use Composer\DependencyResolver\Solver;
 28201 use Composer\DependencyResolver\SolverProblemsException;
 28202 use Composer\DependencyResolver\PolicyInterface;
 28203 use Composer\Downloader\DownloadManager;
 28204 use Composer\EventDispatcher\EventDispatcher;
 28205 use Composer\Filter\PlatformRequirementFilter\IgnoreListPlatformRequirementFilter;
 28206 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
 28207 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterInterface;
 28208 use Composer\Installer\InstallationManager;
 28209 use Composer\Installer\InstallerEvents;
 28210 use Composer\Installer\SuggestedPackagesReporter;
 28211 use Composer\IO\IOInterface;
 28212 use Composer\Package\AliasPackage;
 28213 use Composer\Package\RootAliasPackage;
 28214 use Composer\Package\BasePackage;
 28215 use Composer\Package\CompletePackage;
 28216 use Composer\Package\CompletePackageInterface;
 28217 use Composer\Package\Link;
 28218 use Composer\Package\Loader\ArrayLoader;
 28219 use Composer\Package\Dumper\ArrayDumper;
 28220 use Composer\Package\Version\VersionParser;
 28221 use Composer\Package\Package;
 28222 use Composer\Repository\ArrayRepository;
 28223 use Composer\Repository\RepositorySet;
 28224 use Composer\Repository\CompositeRepository;
 28225 use Composer\Semver\Constraint\Constraint;
 28226 use Composer\Package\Locker;
 28227 use Composer\Package\RootPackageInterface;
 28228 use Composer\Repository\InstalledArrayRepository;
 28229 use Composer\Repository\InstalledRepositoryInterface;
 28230 use Composer\Repository\InstalledRepository;
 28231 use Composer\Repository\RootPackageRepository;
 28232 use Composer\Repository\PlatformRepository;
 28233 use Composer\Repository\RepositoryInterface;
 28234 use Composer\Repository\RepositoryManager;
 28235 use Composer\Repository\LockArrayRepository;
 28236 use Composer\Script\ScriptEvents;
 28237 use Composer\Util\Platform;
 28238 
 28239 
 28240 
 28241 
 28242 
 28243 
 28244 
 28245 class Installer
 28246 {
 28247 const ERROR_NONE = 0; 
 28248 const ERROR_GENERIC_FAILURE = 1;
 28249 const ERROR_NO_LOCK_FILE_FOR_PARTIAL_UPDATE = 3;
 28250 const ERROR_LOCK_FILE_INVALID = 4;
 28251 
 28252 const ERROR_DEPENDENCY_RESOLUTION_FAILED = 2;
 28253 
 28254 
 28255 
 28256 
 28257 protected $io;
 28258 
 28259 
 28260 
 28261 
 28262 protected $config;
 28263 
 28264 
 28265 
 28266 
 28267 protected $package;
 28268 
 28269 
 28270 
 28271 
 28272 
 28273 protected $fixedRootPackage;
 28274 
 28275 
 28276 
 28277 
 28278 protected $downloadManager;
 28279 
 28280 
 28281 
 28282 
 28283 protected $repositoryManager;
 28284 
 28285 
 28286 
 28287 
 28288 protected $locker;
 28289 
 28290 
 28291 
 28292 
 28293 protected $installationManager;
 28294 
 28295 
 28296 
 28297 
 28298 protected $eventDispatcher;
 28299 
 28300 
 28301 
 28302 
 28303 protected $autoloadGenerator;
 28304 
 28305 
 28306 protected $preferSource = false;
 28307 
 28308 protected $preferDist = false;
 28309 
 28310 protected $optimizeAutoloader = false;
 28311 
 28312 protected $classMapAuthoritative = false;
 28313 
 28314 protected $apcuAutoloader = false;
 28315 
 28316 protected $apcuAutoloaderPrefix = null;
 28317 
 28318 protected $devMode = false;
 28319 
 28320 protected $dryRun = false;
 28321 
 28322 protected $verbose = false;
 28323 
 28324 protected $update = false;
 28325 
 28326 protected $install = true;
 28327 
 28328 protected $dumpAutoloader = true;
 28329 
 28330 protected $runScripts = true;
 28331 
 28332 protected $preferStable = false;
 28333 
 28334 protected $preferLowest = false;
 28335 
 28336 protected $writeLock;
 28337 
 28338 protected $executeOperations = true;
 28339 
 28340 
 28341 protected $updateMirrors = false;
 28342 
 28343 
 28344 
 28345 
 28346 
 28347 protected $updateAllowList = null;
 28348 
 28349 protected $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED;
 28350 
 28351 
 28352 
 28353 
 28354 protected $suggestedPackagesReporter;
 28355 
 28356 
 28357 
 28358 
 28359 protected $platformRequirementFilter;
 28360 
 28361 
 28362 
 28363 
 28364 protected $additionalFixedRepository;
 28365 
 28366 
 28367 
 28368 
 28369 
 28370 
 28371 
 28372 
 28373 
 28374 
 28375 
 28376 
 28377 
 28378 
 28379 public function __construct(IOInterface $io, Config $config, RootPackageInterface $package, DownloadManager $downloadManager, RepositoryManager $repositoryManager, Locker $locker, InstallationManager $installationManager, EventDispatcher $eventDispatcher, AutoloadGenerator $autoloadGenerator)
 28380 {
 28381 $this->io = $io;
 28382 $this->config = $config;
 28383 $this->package = $package;
 28384 $this->downloadManager = $downloadManager;
 28385 $this->repositoryManager = $repositoryManager;
 28386 $this->locker = $locker;
 28387 $this->installationManager = $installationManager;
 28388 $this->eventDispatcher = $eventDispatcher;
 28389 $this->autoloadGenerator = $autoloadGenerator;
 28390 $this->suggestedPackagesReporter = new SuggestedPackagesReporter($this->io);
 28391 $this->platformRequirementFilter = PlatformRequirementFilterFactory::ignoreNothing();
 28392 
 28393 $this->writeLock = $config->get('lock');
 28394 }
 28395 
 28396 
 28397 
 28398 
 28399 
 28400 
 28401 
 28402 
 28403 public function run()
 28404 {
 28405 
 28406 
 28407 
 28408 
 28409 gc_collect_cycles();
 28410 gc_disable();
 28411 
 28412 if ($this->updateAllowList && $this->updateMirrors) {
 28413 throw new \RuntimeException("The installer options updateMirrors and updateAllowList are mutually exclusive.");
 28414 }
 28415 
 28416 $isFreshInstall = $this->repositoryManager->getLocalRepository()->isFresh();
 28417 
 28418 
 28419 if (!$this->update && !$this->locker->isLocked()) {
 28420 $this->io->writeError('<warning>No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.</warning>');
 28421 $this->update = true;
 28422 }
 28423 
 28424 if ($this->dryRun) {
 28425 $this->verbose = true;
 28426 $this->runScripts = false;
 28427 $this->executeOperations = false;
 28428 $this->writeLock = false;
 28429 $this->dumpAutoloader = false;
 28430 $this->mockLocalRepositories($this->repositoryManager);
 28431 }
 28432 
 28433 if ($this->update && !$this->install) {
 28434 $this->dumpAutoloader = false;
 28435 }
 28436 
 28437 if ($this->runScripts) {
 28438 Platform::putEnv('COMPOSER_DEV_MODE', $this->devMode ? '1' : '0');
 28439 
 28440 
 28441 
 28442 $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD;
 28443 $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
 28444 }
 28445 
 28446 $this->downloadManager->setPreferSource($this->preferSource);
 28447 $this->downloadManager->setPreferDist($this->preferDist);
 28448 
 28449 $localRepo = $this->repositoryManager->getLocalRepository();
 28450 
 28451 try {
 28452 if ($this->update) {
 28453 $res = $this->doUpdate($localRepo, $this->install);
 28454 } else {
 28455 $res = $this->doInstall($localRepo);
 28456 }
 28457 if ($res !== 0) {
 28458 return $res;
 28459 }
 28460 } catch (\Exception $e) {
 28461 if ($this->executeOperations && $this->install && $this->config->get('notify-on-install')) {
 28462 $this->installationManager->notifyInstalls($this->io);
 28463 }
 28464 
 28465 throw $e;
 28466 }
 28467 if ($this->executeOperations && $this->install && $this->config->get('notify-on-install')) {
 28468 $this->installationManager->notifyInstalls($this->io);
 28469 }
 28470 
 28471 if ($this->update) {
 28472 $installedRepo = new InstalledRepository(array(
 28473 $this->locker->getLockedRepository($this->devMode),
 28474 $this->createPlatformRepo(false),
 28475 new RootPackageRepository(clone $this->package),
 28476 ));
 28477 if ($isFreshInstall) {
 28478 $this->suggestedPackagesReporter->addSuggestionsFromPackage($this->package);
 28479 }
 28480 $this->suggestedPackagesReporter->outputMinimalistic($installedRepo);
 28481 }
 28482 
 28483 
 28484 $lockedRepository = $this->locker->getLockedRepository(true);
 28485 foreach ($lockedRepository->getPackages() as $package) {
 28486 if (!$package instanceof CompletePackage || !$package->isAbandoned()) {
 28487 continue;
 28488 }
 28489 
 28490 $replacement = is_string($package->getReplacementPackage())
 28491 ? 'Use ' . $package->getReplacementPackage() . ' instead'
 28492 : 'No replacement was suggested';
 28493 
 28494 $this->io->writeError(
 28495 sprintf(
 28496 "<warning>Package %s is abandoned, you should avoid using it. %s.</warning>",
 28497 $package->getPrettyName(),
 28498 $replacement
 28499 )
 28500 );
 28501 }
 28502 
 28503 if ($this->dumpAutoloader) {
 28504 
 28505 if ($this->optimizeAutoloader) {
 28506 $this->io->writeError('<info>Generating optimized autoload files</info>');
 28507 } else {
 28508 $this->io->writeError('<info>Generating autoload files</info>');
 28509 }
 28510 
 28511 $this->autoloadGenerator->setClassMapAuthoritative($this->classMapAuthoritative);
 28512 $this->autoloadGenerator->setApcu($this->apcuAutoloader, $this->apcuAutoloaderPrefix);
 28513 $this->autoloadGenerator->setRunScripts($this->runScripts);
 28514 $this->autoloadGenerator->setPlatformRequirementFilter($this->platformRequirementFilter);
 28515 $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader);
 28516 }
 28517 
 28518 if ($this->install && $this->executeOperations) {
 28519 
 28520 foreach ($localRepo->getPackages() as $package) {
 28521 $this->installationManager->ensureBinariesPresence($package);
 28522 }
 28523 }
 28524 
 28525 $fundingCount = 0;
 28526 foreach ($localRepo->getPackages() as $package) {
 28527 if ($package instanceof CompletePackageInterface && !$package instanceof AliasPackage && $package->getFunding()) {
 28528 $fundingCount++;
 28529 }
 28530 }
 28531 if ($fundingCount > 0) {
 28532 $this->io->writeError(array(
 28533 sprintf(
 28534 "<info>%d package%s you are using %s looking for funding.</info>",
 28535 $fundingCount,
 28536 1 === $fundingCount ? '' : 's',
 28537 1 === $fundingCount ? 'is' : 'are'
 28538 ),
 28539 '<info>Use the `composer fund` command to find out more!</info>',
 28540 ));
 28541 }
 28542 
 28543 if ($this->runScripts) {
 28544 
 28545 $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
 28546 $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
 28547 }
 28548 
 28549 
 28550 if (!defined('HHVM_VERSION')) {
 28551 gc_enable();
 28552 }
 28553 
 28554 return 0;
 28555 }
 28556 
 28557 
 28558 
 28559 
 28560 
 28561 
 28562 
 28563 protected function doUpdate(InstalledRepositoryInterface $localRepo, $doInstall)
 28564 {
 28565 $platformRepo = $this->createPlatformRepo(true);
 28566 $aliases = $this->getRootAliases(true);
 28567 
 28568 $lockedRepository = null;
 28569 
 28570 try {
 28571 if ($this->locker->isLocked()) {
 28572 $lockedRepository = $this->locker->getLockedRepository(true);
 28573 }
 28574 } catch (\Seld\JsonLint\ParsingException $e) {
 28575 if ($this->updateAllowList || $this->updateMirrors) {
 28576 
 28577 throw $e;
 28578 }
 28579 
 28580 
 28581 }
 28582 
 28583 if (($this->updateAllowList || $this->updateMirrors) && !$lockedRepository) {
 28584 $this->io->writeError('<error>Cannot update ' . ($this->updateMirrors ? 'lock file information' : 'only a partial set of packages') . ' without a lock file present. Run `composer update` to generate a lock file.</error>', true, IOInterface::QUIET);
 28585 
 28586 return self::ERROR_NO_LOCK_FILE_FOR_PARTIAL_UPDATE;
 28587 }
 28588 
 28589 $this->io->writeError('<info>Loading composer repositories with package information</info>');
 28590 
 28591 
 28592 $policy = $this->createPolicy(true);
 28593 $repositorySet = $this->createRepositorySet(true, $platformRepo, $aliases);
 28594 $repositories = $this->repositoryManager->getRepositories();
 28595 foreach ($repositories as $repository) {
 28596 $repositorySet->addRepository($repository);
 28597 }
 28598 if ($lockedRepository) {
 28599 $repositorySet->addRepository($lockedRepository);
 28600 }
 28601 
 28602 $request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
 28603 $this->requirePackagesForUpdate($request, $lockedRepository, true);
 28604 
 28605 
 28606 if ($this->updateAllowList) {
 28607 $request->setUpdateAllowList($this->updateAllowList, $this->updateAllowTransitiveDependencies);
 28608 }
 28609 
 28610 $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher, $this->createPoolOptimizer($policy));
 28611 
 28612 $this->io->writeError('<info>Updating dependencies</info>');
 28613 
 28614 
 28615 $solver = new Solver($policy, $pool, $this->io);
 28616 try {
 28617 $lockTransaction = $solver->solve($request, $this->platformRequirementFilter);
 28618 $ruleSetSize = $solver->getRuleSetSize();
 28619 $solver = null;
 28620 } catch (SolverProblemsException $e) {
 28621 $err = 'Your requirements could not be resolved to an installable set of packages.';
 28622 $prettyProblem = $e->getPrettyString($repositorySet, $request, $pool, $this->io->isVerbose());
 28623 
 28624 $this->io->writeError('<error>'. $err .'</error>', true, IOInterface::QUIET);
 28625 $this->io->writeError($prettyProblem);
 28626 if (!$this->devMode) {
 28627 $this->io->writeError('<warning>Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.</warning>', true, IOInterface::QUIET);
 28628 }
 28629 
 28630 $ghe = new GithubActionError($this->io);
 28631 $ghe->emit($err."\n".$prettyProblem);
 28632 
 28633 return max(self::ERROR_GENERIC_FAILURE, $e->getCode());
 28634 }
 28635 
 28636 $this->io->writeError("Analyzed ".count($pool)." packages to resolve dependencies", true, IOInterface::VERBOSE);
 28637 $this->io->writeError("Analyzed ".$ruleSetSize." rules to resolve dependencies", true, IOInterface::VERBOSE);
 28638 
 28639 $pool = null;
 28640 
 28641 if (!$lockTransaction->getOperations()) {
 28642 $this->io->writeError('Nothing to modify in lock file');
 28643 }
 28644 
 28645 $exitCode = $this->extractDevPackages($lockTransaction, $platformRepo, $aliases, $policy, $lockedRepository);
 28646 if ($exitCode !== 0) {
 28647 return $exitCode;
 28648 }
 28649 
 28650 
 28651 if (method_exists('Composer\Semver\CompilingMatcher', 'clear')) { 
 28652 \Composer\Semver\CompilingMatcher::clear();
 28653 }
 28654 
 28655 
 28656 $platformReqs = $this->extractPlatformRequirements($this->package->getRequires());
 28657 $platformDevReqs = $this->extractPlatformRequirements($this->package->getDevRequires());
 28658 
 28659 $installsUpdates = $uninstalls = array();
 28660 if ($lockTransaction->getOperations()) {
 28661 $installNames = $updateNames = $uninstallNames = array();
 28662 foreach ($lockTransaction->getOperations() as $operation) {
 28663 if ($operation instanceof InstallOperation) {
 28664 $installsUpdates[] = $operation;
 28665 $installNames[] = $operation->getPackage()->getPrettyName().':'.$operation->getPackage()->getFullPrettyVersion();
 28666 } elseif ($operation instanceof UpdateOperation) {
 28667 
 28668 
 28669 if ($this->updateMirrors
 28670 && $operation->getInitialPackage()->getName() == $operation->getTargetPackage()->getName()
 28671 && $operation->getInitialPackage()->getVersion() == $operation->getTargetPackage()->getVersion()
 28672 ) {
 28673 continue;
 28674 }
 28675 
 28676 $installsUpdates[] = $operation;
 28677 $updateNames[] = $operation->getTargetPackage()->getPrettyName().':'.$operation->getTargetPackage()->getFullPrettyVersion();
 28678 } elseif ($operation instanceof UninstallOperation) {
 28679 $uninstalls[] = $operation;
 28680 $uninstallNames[] = $operation->getPackage()->getPrettyName();
 28681 }
 28682 }
 28683 
 28684 $this->io->writeError(sprintf(
 28685 "<info>Lock file operations: %d install%s, %d update%s, %d removal%s</info>",
 28686 count($installNames),
 28687 1 === count($installNames) ? '' : 's',
 28688 count($updateNames),
 28689 1 === count($updateNames) ? '' : 's',
 28690 count($uninstalls),
 28691 1 === count($uninstalls) ? '' : 's'
 28692 ));
 28693 if ($installNames) {
 28694 $this->io->writeError("Installs: ".implode(', ', $installNames), true, IOInterface::VERBOSE);
 28695 }
 28696 if ($updateNames) {
 28697 $this->io->writeError("Updates: ".implode(', ', $updateNames), true, IOInterface::VERBOSE);
 28698 }
 28699 if ($uninstalls) {
 28700 $this->io->writeError("Removals: ".implode(', ', $uninstallNames), true, IOInterface::VERBOSE);
 28701 }
 28702 }
 28703 
 28704 $sortByName = function ($a, $b) {
 28705 if ($a instanceof UpdateOperation) {
 28706 $a = $a->getTargetPackage()->getName();
 28707 } else {
 28708 $a = $a->getPackage()->getName();
 28709 }
 28710 if ($b instanceof UpdateOperation) {
 28711 $b = $b->getTargetPackage()->getName();
 28712 } else {
 28713 $b = $b->getPackage()->getName();
 28714 }
 28715 
 28716 return strcmp($a, $b);
 28717 };
 28718 usort($uninstalls, $sortByName);
 28719 usort($installsUpdates, $sortByName);
 28720 
 28721 foreach (array_merge($uninstalls, $installsUpdates) as $operation) {
 28722 
 28723 if ($operation instanceof InstallOperation) {
 28724 $this->suggestedPackagesReporter->addSuggestionsFromPackage($operation->getPackage());
 28725 }
 28726 
 28727 
 28728 if (false === strpos($operation->getOperationType(), 'Alias') || $this->io->isDebug()) {
 28729 $this->io->writeError('  - ' . $operation->show(true));
 28730 }
 28731 }
 28732 
 28733 $updatedLock = $this->locker->setLockData(
 28734 $lockTransaction->getNewLockPackages(false, $this->updateMirrors),
 28735 $lockTransaction->getNewLockPackages(true, $this->updateMirrors),
 28736 $platformReqs,
 28737 $platformDevReqs,
 28738 $lockTransaction->getAliases($aliases),
 28739 $this->package->getMinimumStability(),
 28740 $this->package->getStabilityFlags(),
 28741 $this->preferStable || $this->package->getPreferStable(),
 28742 $this->preferLowest,
 28743 $this->config->get('platform') ?: array(),
 28744 $this->writeLock && $this->executeOperations
 28745 );
 28746 if ($updatedLock && $this->writeLock && $this->executeOperations) {
 28747 $this->io->writeError('<info>Writing lock file</info>');
 28748 }
 28749 
 28750 
 28751 if ($this->executeOperations && count($lockTransaction->getOperations()) > 0) {
 28752 $vendorDir = $this->config->get('vendor-dir');
 28753 if (is_dir($vendorDir)) {
 28754 
 28755 
 28756 @touch($vendorDir);
 28757 }
 28758 }
 28759 
 28760 if ($doInstall) {
 28761 
 28762 return $this->doInstall($localRepo, true);
 28763 }
 28764 
 28765 return 0;
 28766 }
 28767 
 28768 
 28769 
 28770 
 28771 
 28772 
 28773 
 28774 
 28775 
 28776 
 28777 
 28778 
 28779 protected function extractDevPackages(LockTransaction $lockTransaction, PlatformRepository $platformRepo, array $aliases, PolicyInterface $policy, LockArrayRepository $lockedRepository = null)
 28780 {
 28781 if (!$this->package->getDevRequires()) {
 28782 return 0;
 28783 }
 28784 
 28785 $resultRepo = new ArrayRepository(array());
 28786 $loader = new ArrayLoader(null, true);
 28787 $dumper = new ArrayDumper();
 28788 foreach ($lockTransaction->getNewLockPackages(false) as $pkg) {
 28789 $resultRepo->addPackage($loader->load($dumper->dump($pkg)));
 28790 }
 28791 
 28792 $repositorySet = $this->createRepositorySet(true, $platformRepo, $aliases);
 28793 $repositorySet->addRepository($resultRepo);
 28794 
 28795 $request = $this->createRequest($this->fixedRootPackage, $platformRepo);
 28796 $this->requirePackagesForUpdate($request, $lockedRepository, false);
 28797 
 28798 $pool = $repositorySet->createPoolWithAllPackages();
 28799 
 28800 $solver = new Solver($policy, $pool, $this->io);
 28801 try {
 28802 $nonDevLockTransaction = $solver->solve($request, $this->platformRequirementFilter);
 28803 $solver = null;
 28804 } catch (SolverProblemsException $e) {
 28805 $err = 'Unable to find a compatible set of packages based on your non-dev requirements alone.';
 28806 $prettyProblem = $e->getPrettyString($repositorySet, $request, $pool, $this->io->isVerbose(), true);
 28807 
 28808 $this->io->writeError('<error>'. $err .'</error>', true, IOInterface::QUIET);
 28809 $this->io->writeError('Your requirements can be resolved successfully when require-dev packages are present.');
 28810 $this->io->writeError('You may need to move packages from require-dev or some of their dependencies to require.');
 28811 $this->io->writeError($prettyProblem);
 28812 
 28813 $ghe = new GithubActionError($this->io);
 28814 $ghe->emit($err."\n".$prettyProblem);
 28815 
 28816 return $e->getCode();
 28817 }
 28818 
 28819 $lockTransaction->setNonDevPackages($nonDevLockTransaction);
 28820 
 28821 return 0;
 28822 }
 28823 
 28824 
 28825 
 28826 
 28827 
 28828 
 28829 
 28830 protected function doInstall(InstalledRepositoryInterface $localRepo, $alreadySolved = false)
 28831 {
 28832 $this->io->writeError('<info>Installing dependencies from lock file'.($this->devMode ? ' (including require-dev)' : '').'</info>');
 28833 
 28834 $lockedRepository = $this->locker->getLockedRepository($this->devMode);
 28835 
 28836 
 28837 
 28838 if (!$alreadySolved) {
 28839 $this->io->writeError('<info>Verifying lock file contents can be installed on current platform.</info>');
 28840 
 28841 $platformRepo = $this->createPlatformRepo(false);
 28842 
 28843 $policy = $this->createPolicy(false);
 28844 
 28845 $repositorySet = $this->createRepositorySet(false, $platformRepo, array(), $lockedRepository);
 28846 $repositorySet->addRepository($lockedRepository);
 28847 
 28848 
 28849 $request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
 28850 
 28851 if (!$this->locker->isFresh()) {
 28852 $this->io->writeError('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`.</warning>', true, IOInterface::QUIET);
 28853 }
 28854 
 28855 foreach ($lockedRepository->getPackages() as $package) {
 28856 $request->fixLockedPackage($package);
 28857 }
 28858 
 28859 foreach ($this->locker->getPlatformRequirements($this->devMode) as $link) {
 28860 $request->requireName($link->getTarget(), $link->getConstraint());
 28861 }
 28862 
 28863 $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher);
 28864 
 28865 
 28866 $solver = new Solver($policy, $pool, $this->io);
 28867 try {
 28868 $lockTransaction = $solver->solve($request, $this->platformRequirementFilter);
 28869 $solver = null;
 28870 
 28871 
 28872 if (0 !== count($lockTransaction->getOperations())) {
 28873 $this->io->writeError('<error>Your lock file cannot be installed on this system without changes. Please run composer update.</error>', true, IOInterface::QUIET);
 28874 
 28875 return self::ERROR_LOCK_FILE_INVALID;
 28876 }
 28877 } catch (SolverProblemsException $e) {
 28878 $err = 'Your lock file does not contain a compatible set of packages. Please run composer update.';
 28879 $prettyProblem = $e->getPrettyString($repositorySet, $request, $pool, $this->io->isVerbose());
 28880 
 28881 $this->io->writeError('<error>'. $err .'</error>', true, IOInterface::QUIET);
 28882 $this->io->writeError($prettyProblem);
 28883 
 28884 $ghe = new GithubActionError($this->io);
 28885 $ghe->emit($err."\n".$prettyProblem);
 28886 
 28887 return max(self::ERROR_GENERIC_FAILURE, $e->getCode());
 28888 }
 28889 }
 28890 
 28891 
 28892 $localRepoTransaction = new LocalRepoTransaction($lockedRepository, $localRepo);
 28893 $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_OPERATIONS_EXEC, $this->devMode, $this->executeOperations, $localRepoTransaction);
 28894 
 28895 if (!$localRepoTransaction->getOperations()) {
 28896 $this->io->writeError('Nothing to install, update or remove');
 28897 }
 28898 
 28899 if ($localRepoTransaction->getOperations()) {
 28900 $installs = $updates = $uninstalls = array();
 28901 foreach ($localRepoTransaction->getOperations() as $operation) {
 28902 if ($operation instanceof InstallOperation) {
 28903 $installs[] = $operation->getPackage()->getPrettyName().':'.$operation->getPackage()->getFullPrettyVersion();
 28904 } elseif ($operation instanceof UpdateOperation) {
 28905 $updates[] = $operation->getTargetPackage()->getPrettyName().':'.$operation->getTargetPackage()->getFullPrettyVersion();
 28906 } elseif ($operation instanceof UninstallOperation) {
 28907 $uninstalls[] = $operation->getPackage()->getPrettyName();
 28908 }
 28909 }
 28910 
 28911 $this->io->writeError(sprintf(
 28912 "<info>Package operations: %d install%s, %d update%s, %d removal%s</info>",
 28913 count($installs),
 28914 1 === count($installs) ? '' : 's',
 28915 count($updates),
 28916 1 === count($updates) ? '' : 's',
 28917 count($uninstalls),
 28918 1 === count($uninstalls) ? '' : 's'
 28919 ));
 28920 if ($installs) {
 28921 $this->io->writeError("Installs: ".implode(', ', $installs), true, IOInterface::VERBOSE);
 28922 }
 28923 if ($updates) {
 28924 $this->io->writeError("Updates: ".implode(', ', $updates), true, IOInterface::VERBOSE);
 28925 }
 28926 if ($uninstalls) {
 28927 $this->io->writeError("Removals: ".implode(', ', $uninstalls), true, IOInterface::VERBOSE);
 28928 }
 28929 }
 28930 
 28931 if ($this->executeOperations) {
 28932 $localRepo->setDevPackageNames($this->locker->getDevPackageNames());
 28933 $this->installationManager->execute($localRepo, $localRepoTransaction->getOperations(), $this->devMode, $this->runScripts);
 28934 } else {
 28935 foreach ($localRepoTransaction->getOperations() as $operation) {
 28936 
 28937 if (false === strpos($operation->getOperationType(), 'Alias') || $this->io->isDebug()) {
 28938 $this->io->writeError('  - ' . $operation->show(false));
 28939 }
 28940 }
 28941 }
 28942 
 28943 return 0;
 28944 }
 28945 
 28946 
 28947 
 28948 
 28949 
 28950 
 28951 protected function createPlatformRepo($forUpdate)
 28952 {
 28953 if ($forUpdate) {
 28954 $platformOverrides = $this->config->get('platform') ?: array();
 28955 } else {
 28956 $platformOverrides = $this->locker->getPlatformOverrides();
 28957 }
 28958 
 28959 return new PlatformRepository(array(), $platformOverrides);
 28960 }
 28961 
 28962 
 28963 
 28964 
 28965 
 28966 
 28967 
 28968 
 28969 
 28970 
 28971 private function createRepositorySet($forUpdate, PlatformRepository $platformRepo, array $rootAliases = array(), $lockedRepository = null)
 28972 {
 28973 if ($forUpdate) {
 28974 $minimumStability = $this->package->getMinimumStability();
 28975 $stabilityFlags = $this->package->getStabilityFlags();
 28976 
 28977 $requires = array_merge($this->package->getRequires(), $this->package->getDevRequires());
 28978 } else {
 28979 $minimumStability = $this->locker->getMinimumStability();
 28980 $stabilityFlags = $this->locker->getStabilityFlags();
 28981 
 28982 $requires = array();
 28983 foreach ($lockedRepository->getPackages() as $package) {
 28984 $constraint = new Constraint('=', $package->getVersion());
 28985 $constraint->setPrettyString($package->getPrettyVersion());
 28986 $requires[$package->getName()] = $constraint;
 28987 }
 28988 }
 28989 
 28990 $rootRequires = array();
 28991 foreach ($requires as $req => $constraint) {
 28992 if ($constraint instanceof Link) {
 28993 $constraint = $constraint->getConstraint();
 28994 }
 28995 
 28996 if ($this->platformRequirementFilter->isIgnored($req)) {
 28997 continue;
 28998 } elseif ($this->platformRequirementFilter instanceof IgnoreListPlatformRequirementFilter) {
 28999 $constraint = $this->platformRequirementFilter->filterConstraint($req, $constraint);
 29000 }
 29001 $rootRequires[$req] = $constraint;
 29002 }
 29003 
 29004 $this->fixedRootPackage = clone $this->package;
 29005 $this->fixedRootPackage->setRequires(array());
 29006 $this->fixedRootPackage->setDevRequires(array());
 29007 
 29008 $stabilityFlags[$this->package->getName()] = BasePackage::$stabilities[VersionParser::parseStability($this->package->getVersion())];
 29009 
 29010 $repositorySet = new RepositorySet($minimumStability, $stabilityFlags, $rootAliases, $this->package->getReferences(), $rootRequires);
 29011 $repositorySet->addRepository(new RootPackageRepository($this->fixedRootPackage));
 29012 $repositorySet->addRepository($platformRepo);
 29013 if ($this->additionalFixedRepository) {
 29014 
 29015 
 29016 $additionalFixedRepositories = $this->additionalFixedRepository;
 29017 if ($additionalFixedRepositories instanceof CompositeRepository) {
 29018 $additionalFixedRepositories = $additionalFixedRepositories->getRepositories();
 29019 } else {
 29020 $additionalFixedRepositories = array($additionalFixedRepositories);
 29021 }
 29022 foreach ($additionalFixedRepositories as $additionalFixedRepository) {
 29023 if ($additionalFixedRepository instanceof InstalledRepository || $additionalFixedRepository instanceof InstalledRepositoryInterface) {
 29024 $repositorySet->allowInstalledRepositories();
 29025 break;
 29026 }
 29027 }
 29028 
 29029 $repositorySet->addRepository($this->additionalFixedRepository);
 29030 }
 29031 
 29032 return $repositorySet;
 29033 }
 29034 
 29035 
 29036 
 29037 
 29038 
 29039 
 29040 private function createPolicy($forUpdate)
 29041 {
 29042 $preferStable = null;
 29043 $preferLowest = null;
 29044 if (!$forUpdate) {
 29045 $preferStable = $this->locker->getPreferStable();
 29046 $preferLowest = $this->locker->getPreferLowest();
 29047 }
 29048 
 29049 
 29050 if (null === $preferStable) {
 29051 $preferStable = $this->preferStable || $this->package->getPreferStable();
 29052 }
 29053 if (null === $preferLowest) {
 29054 $preferLowest = $this->preferLowest;
 29055 }
 29056 
 29057 return new DefaultPolicy($preferStable, $preferLowest);
 29058 }
 29059 
 29060 
 29061 
 29062 
 29063 
 29064 private function createRequest(RootPackageInterface $rootPackage, PlatformRepository $platformRepo, LockArrayRepository $lockedRepository = null)
 29065 {
 29066 $request = new Request($lockedRepository);
 29067 
 29068 $request->fixPackage($rootPackage);
 29069 if ($rootPackage instanceof RootAliasPackage) {
 29070 $request->fixPackage($rootPackage->getAliasOf());
 29071 }
 29072 
 29073 $fixedPackages = $platformRepo->getPackages();
 29074 if ($this->additionalFixedRepository) {
 29075 $fixedPackages = array_merge($fixedPackages, $this->additionalFixedRepository->getPackages());
 29076 }
 29077 
 29078 
 29079 
 29080 
 29081 $provided = $rootPackage->getProvides();
 29082 foreach ($fixedPackages as $package) {
 29083 
 29084 if ($package->getRepository() !== $platformRepo
 29085 || !isset($provided[$package->getName()])
 29086 || !$provided[$package->getName()]->getConstraint()->matches(new Constraint('=', $package->getVersion()))
 29087 ) {
 29088 $request->fixPackage($package);
 29089 }
 29090 }
 29091 
 29092 return $request;
 29093 }
 29094 
 29095 
 29096 
 29097 
 29098 
 29099 
 29100 
 29101 private function requirePackagesForUpdate(Request $request, LockArrayRepository $lockedRepository = null, $includeDevRequires = true)
 29102 {
 29103 
 29104 if ($this->updateMirrors) {
 29105 $excludedPackages = array();
 29106 if (!$includeDevRequires) {
 29107 $excludedPackages = array_flip($this->locker->getDevPackageNames());
 29108 }
 29109 
 29110 foreach ($lockedRepository->getPackages() as $lockedPackage) {
 29111 
 29112 
 29113 if (!$lockedPackage instanceof AliasPackage && !isset($excludedPackages[$lockedPackage->getName()])) {
 29114 $request->requireName($lockedPackage->getName(), new Constraint('==', $lockedPackage->getVersion()));
 29115 }
 29116 }
 29117 } else {
 29118 $links = $this->package->getRequires();
 29119 if ($includeDevRequires) {
 29120 $links = array_merge($links, $this->package->getDevRequires());
 29121 }
 29122 foreach ($links as $link) {
 29123 $request->requireName($link->getTarget(), $link->getConstraint());
 29124 }
 29125 }
 29126 }
 29127 
 29128 
 29129 
 29130 
 29131 
 29132 
 29133 
 29134 
 29135 private function getRootAliases($forUpdate)
 29136 {
 29137 if ($forUpdate) {
 29138 $aliases = $this->package->getAliases();
 29139 } else {
 29140 $aliases = $this->locker->getAliases();
 29141 }
 29142 
 29143 return $aliases;
 29144 }
 29145 
 29146 
 29147 
 29148 
 29149 
 29150 
 29151 private function extractPlatformRequirements(array $links)
 29152 {
 29153 $platformReqs = array();
 29154 foreach ($links as $link) {
 29155 if (PlatformRepository::isPlatformPackage($link->getTarget())) {
 29156 $platformReqs[$link->getTarget()] = $link->getPrettyConstraint();
 29157 }
 29158 }
 29159 
 29160 return $platformReqs;
 29161 }
 29162 
 29163 
 29164 
 29165 
 29166 
 29167 
 29168 
 29169 
 29170 private function mockLocalRepositories(RepositoryManager $rm)
 29171 {
 29172 $packages = array();
 29173 foreach ($rm->getLocalRepository()->getPackages() as $package) {
 29174 $packages[(string) $package] = clone $package;
 29175 }
 29176 foreach ($packages as $key => $package) {
 29177 if ($package instanceof AliasPackage) {
 29178 $alias = (string) $package->getAliasOf();
 29179 $className = get_class($package);
 29180 $packages[$key] = new $className($packages[$alias], $package->getVersion(), $package->getPrettyVersion());
 29181 }
 29182 }
 29183 $rm->setLocalRepository(
 29184 new InstalledArrayRepository($packages)
 29185 );
 29186 }
 29187 
 29188 
 29189 
 29190 
 29191 private function createPoolOptimizer(PolicyInterface $policy)
 29192 {
 29193 
 29194 
 29195 
 29196 if ('0' === Platform::getEnv('COMPOSER_POOL_OPTIMIZER')) {
 29197 $this->io->write('Pool Optimizer was disabled for debugging purposes.', true, IOInterface::DEBUG);
 29198 
 29199 return null;
 29200 }
 29201 
 29202 return new PoolOptimizer($policy);
 29203 }
 29204 
 29205 
 29206 
 29207 
 29208 
 29209 
 29210 
 29211 
 29212 public static function create(IOInterface $io, Composer $composer)
 29213 {
 29214 return new static(
 29215 $io,
 29216 $composer->getConfig(),
 29217 $composer->getPackage(),
 29218 $composer->getDownloadManager(),
 29219 $composer->getRepositoryManager(),
 29220 $composer->getLocker(),
 29221 $composer->getInstallationManager(),
 29222 $composer->getEventDispatcher(),
 29223 $composer->getAutoloadGenerator()
 29224 );
 29225 }
 29226 
 29227 
 29228 
 29229 
 29230 
 29231 public function setAdditionalFixedRepository(RepositoryInterface $additionalFixedRepository)
 29232 {
 29233 $this->additionalFixedRepository = $additionalFixedRepository;
 29234 
 29235 return $this;
 29236 }
 29237 
 29238 
 29239 
 29240 
 29241 
 29242 
 29243 
 29244 public function setDryRun($dryRun = true)
 29245 {
 29246 $this->dryRun = (bool) $dryRun;
 29247 
 29248 return $this;
 29249 }
 29250 
 29251 
 29252 
 29253 
 29254 
 29255 
 29256 public function isDryRun()
 29257 {
 29258 return $this->dryRun;
 29259 }
 29260 
 29261 
 29262 
 29263 
 29264 
 29265 
 29266 
 29267 public function setPreferSource($preferSource = true)
 29268 {
 29269 $this->preferSource = (bool) $preferSource;
 29270 
 29271 return $this;
 29272 }
 29273 
 29274 
 29275 
 29276 
 29277 
 29278 
 29279 
 29280 public function setPreferDist($preferDist = true)
 29281 {
 29282 $this->preferDist = (bool) $preferDist;
 29283 
 29284 return $this;
 29285 }
 29286 
 29287 
 29288 
 29289 
 29290 
 29291 
 29292 
 29293 public function setOptimizeAutoloader($optimizeAutoloader)
 29294 {
 29295 $this->optimizeAutoloader = (bool) $optimizeAutoloader;
 29296 if (!$this->optimizeAutoloader) {
 29297 
 29298 
 29299 $this->setClassMapAuthoritative(false);
 29300 }
 29301 
 29302 return $this;
 29303 }
 29304 
 29305 
 29306 
 29307 
 29308 
 29309 
 29310 
 29311 
 29312 public function setClassMapAuthoritative($classMapAuthoritative)
 29313 {
 29314 $this->classMapAuthoritative = (bool) $classMapAuthoritative;
 29315 if ($this->classMapAuthoritative) {
 29316 
 29317 $this->setOptimizeAutoloader(true);
 29318 }
 29319 
 29320 return $this;
 29321 }
 29322 
 29323 
 29324 
 29325 
 29326 
 29327 
 29328 
 29329 
 29330 public function setApcuAutoloader($apcuAutoloader, $apcuAutoloaderPrefix = null)
 29331 {
 29332 $this->apcuAutoloader = $apcuAutoloader;
 29333 $this->apcuAutoloaderPrefix = $apcuAutoloaderPrefix;
 29334 
 29335 return $this;
 29336 }
 29337 
 29338 
 29339 
 29340 
 29341 
 29342 
 29343 
 29344 public function setUpdate($update)
 29345 {
 29346 $this->update = (bool) $update;
 29347 
 29348 return $this;
 29349 }
 29350 
 29351 
 29352 
 29353 
 29354 
 29355 
 29356 
 29357 public function setInstall($install)
 29358 {
 29359 $this->install = (bool) $install;
 29360 
 29361 return $this;
 29362 }
 29363 
 29364 
 29365 
 29366 
 29367 
 29368 
 29369 
 29370 public function setDevMode($devMode = true)
 29371 {
 29372 $this->devMode = (bool) $devMode;
 29373 
 29374 return $this;
 29375 }
 29376 
 29377 
 29378 
 29379 
 29380 
 29381 
 29382 
 29383 
 29384 
 29385 public function setDumpAutoloader($dumpAutoloader = true)
 29386 {
 29387 $this->dumpAutoloader = (bool) $dumpAutoloader;
 29388 
 29389 return $this;
 29390 }
 29391 
 29392 
 29393 
 29394 
 29395 
 29396 
 29397 
 29398 
 29399 
 29400 
 29401 public function setRunScripts($runScripts = true)
 29402 {
 29403 $this->runScripts = (bool) $runScripts;
 29404 
 29405 return $this;
 29406 }
 29407 
 29408 
 29409 
 29410 
 29411 
 29412 
 29413 
 29414 public function setConfig(Config $config)
 29415 {
 29416 $this->config = $config;
 29417 
 29418 return $this;
 29419 }
 29420 
 29421 
 29422 
 29423 
 29424 
 29425 
 29426 
 29427 public function setVerbose($verbose = true)
 29428 {
 29429 $this->verbose = (bool) $verbose;
 29430 
 29431 return $this;
 29432 }
 29433 
 29434 
 29435 
 29436 
 29437 
 29438 
 29439 public function isVerbose()
 29440 {
 29441 return $this->verbose;
 29442 }
 29443 
 29444 
 29445 
 29446 
 29447 
 29448 
 29449 
 29450 
 29451 
 29452 
 29453 
 29454 
 29455 
 29456 
 29457 public function setIgnorePlatformRequirements($ignorePlatformReqs)
 29458 {
 29459 trigger_error('Installer::setIgnorePlatformRequirements is deprecated since Composer 2.2, use setPlatformRequirementFilter instead.', E_USER_DEPRECATED);
 29460 
 29461 return $this->setPlatformRequirementFilter(PlatformRequirementFilterFactory::fromBoolOrList($ignorePlatformReqs));
 29462 }
 29463 
 29464 
 29465 
 29466 
 29467 
 29468 public function setPlatformRequirementFilter(PlatformRequirementFilterInterface $platformRequirementFilter)
 29469 {
 29470 $this->platformRequirementFilter = $platformRequirementFilter;
 29471 
 29472 return $this;
 29473 }
 29474 
 29475 
 29476 
 29477 
 29478 
 29479 
 29480 
 29481 public function setUpdateMirrors($updateMirrors)
 29482 {
 29483 $this->updateMirrors = $updateMirrors;
 29484 
 29485 return $this;
 29486 }
 29487 
 29488 
 29489 
 29490 
 29491 
 29492 
 29493 
 29494 
 29495 
 29496 public function setUpdateAllowList(array $packages)
 29497 {
 29498 $this->updateAllowList = array_flip(array_map('strtolower', $packages));
 29499 
 29500 return $this;
 29501 }
 29502 
 29503 
 29504 
 29505 
 29506 
 29507 
 29508 
 29509 
 29510 
 29511 
 29512 public function setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies)
 29513 {
 29514 if (!in_array($updateAllowTransitiveDependencies, array(Request::UPDATE_ONLY_LISTED, Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE, Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS), true)) {
 29515 throw new \RuntimeException("Invalid value for updateAllowTransitiveDependencies supplied");
 29516 }
 29517 
 29518 $this->updateAllowTransitiveDependencies = $updateAllowTransitiveDependencies;
 29519 
 29520 return $this;
 29521 }
 29522 
 29523 
 29524 
 29525 
 29526 
 29527 
 29528 
 29529 public function setPreferStable($preferStable = true)
 29530 {
 29531 $this->preferStable = (bool) $preferStable;
 29532 
 29533 return $this;
 29534 }
 29535 
 29536 
 29537 
 29538 
 29539 
 29540 
 29541 
 29542 public function setPreferLowest($preferLowest = true)
 29543 {
 29544 $this->preferLowest = (bool) $preferLowest;
 29545 
 29546 return $this;
 29547 }
 29548 
 29549 
 29550 
 29551 
 29552 
 29553 
 29554 
 29555 
 29556 
 29557 public function setWriteLock($writeLock = true)
 29558 {
 29559 $this->writeLock = (bool) $writeLock;
 29560 
 29561 return $this;
 29562 }
 29563 
 29564 
 29565 
 29566 
 29567 
 29568 
 29569 
 29570 
 29571 
 29572 public function setExecuteOperations($executeOperations = true)
 29573 {
 29574 $this->executeOperations = (bool) $executeOperations;
 29575 
 29576 return $this;
 29577 }
 29578 
 29579 
 29580 
 29581 
 29582 
 29583 
 29584 
 29585 
 29586 
 29587 
 29588 public function disablePlugins()
 29589 {
 29590 $this->installationManager->disablePlugins();
 29591 
 29592 return $this;
 29593 }
 29594 
 29595 
 29596 
 29597 
 29598 
 29599 public function setSuggestedPackagesReporter(SuggestedPackagesReporter $suggestedPackagesReporter)
 29600 {
 29601 $this->suggestedPackagesReporter = $suggestedPackagesReporter;
 29602 
 29603 return $this;
 29604 }
 29605 }
 29606 <?php
 29607 
 29608 
 29609 
 29610 
 29611 
 29612 
 29613 
 29614 
 29615 
 29616 
 29617 
 29618 namespace Composer\Installer;
 29619 
 29620 use Composer\IO\IOInterface;
 29621 use Composer\Package\PackageInterface;
 29622 use Composer\Pcre\Preg;
 29623 use Composer\Util\Filesystem;
 29624 use Composer\Util\Platform;
 29625 use Composer\Util\ProcessExecutor;
 29626 use Composer\Util\Silencer;
 29627 
 29628 
 29629 
 29630 
 29631 
 29632 
 29633 
 29634 
 29635 class BinaryInstaller
 29636 {
 29637 
 29638 protected $binDir;
 29639 
 29640 protected $binCompat;
 29641 
 29642 protected $io;
 29643 
 29644 protected $filesystem;
 29645 
 29646 private $vendorDir;
 29647 
 29648 
 29649 
 29650 
 29651 
 29652 
 29653 
 29654 
 29655 public function __construct(IOInterface $io, $binDir, $binCompat, Filesystem $filesystem = null, $vendorDir = null)
 29656 {
 29657 $this->binDir = $binDir;
 29658 $this->binCompat = $binCompat;
 29659 $this->io = $io;
 29660 $this->filesystem = $filesystem ?: new Filesystem();
 29661 $this->vendorDir = $vendorDir;
 29662 }
 29663 
 29664 
 29665 
 29666 
 29667 
 29668 
 29669 
 29670 public function installBinaries(PackageInterface $package, $installPath, $warnOnOverwrite = true)
 29671 {
 29672 $binaries = $this->getBinaries($package);
 29673 if (!$binaries) {
 29674 return;
 29675 }
 29676 
 29677 Platform::workaroundFilesystemIssues();
 29678 
 29679 foreach ($binaries as $bin) {
 29680 $binPath = $installPath.'/'.$bin;
 29681 if (!file_exists($binPath)) {
 29682 $this->io->writeError('    <warning>Skipped installation of bin '.$bin.' for package '.$package->getName().': file not found in package</warning>');
 29683 continue;
 29684 }
 29685 if (is_dir($binPath)) {
 29686 $this->io->writeError('    <warning>Skipped installation of bin '.$bin.' for package '.$package->getName().': found a directory at that path</warning>');
 29687 continue;
 29688 }
 29689 if (!$this->filesystem->isAbsolutePath($binPath)) {
 29690 
 29691 
 29692 
 29693 
 29694 $binPath = realpath($binPath);
 29695 }
 29696 $this->initializeBinDir();
 29697 $link = $this->binDir.'/'.basename($bin);
 29698 if (file_exists($link)) {
 29699 if (!is_link($link)) {
 29700 if ($warnOnOverwrite) {
 29701 $this->io->writeError('    Skipped installation of bin '.$bin.' for package '.$package->getName().': name conflicts with an existing file');
 29702 }
 29703 continue;
 29704 }
 29705 if (realpath($link) === realpath($binPath)) {
 29706 
 29707 $this->filesystem->unlink($link);
 29708 }
 29709 }
 29710 
 29711 $binCompat = $this->binCompat;
 29712 if ($binCompat === "auto" && (Platform::isWindows() || Platform::isWindowsSubsystemForLinux())) {
 29713 $binCompat = 'full';
 29714 }
 29715 
 29716 if ($binCompat === "full") {
 29717 $this->installFullBinaries($binPath, $link, $bin, $package);
 29718 } else {
 29719 $this->installUnixyProxyBinaries($binPath, $link);
 29720 }
 29721 Silencer::call('chmod', $binPath, 0777 & ~umask());
 29722 }
 29723 }
 29724 
 29725 
 29726 
 29727 
 29728 public function removeBinaries(PackageInterface $package)
 29729 {
 29730 $this->initializeBinDir();
 29731 
 29732 $binaries = $this->getBinaries($package);
 29733 if (!$binaries) {
 29734 return;
 29735 }
 29736 foreach ($binaries as $bin) {
 29737 $link = $this->binDir.'/'.basename($bin);
 29738 if (is_link($link) || file_exists($link)) { 
 29739 $this->filesystem->unlink($link);
 29740 }
 29741 if (is_file($link.'.bat')) {
 29742 $this->filesystem->unlink($link.'.bat');
 29743 }
 29744 }
 29745 
 29746 
 29747 if (is_dir($this->binDir) && $this->filesystem->isDirEmpty($this->binDir)) {
 29748 Silencer::call('rmdir', $this->binDir);
 29749 }
 29750 }
 29751 
 29752 
 29753 
 29754 
 29755 
 29756 
 29757 public static function determineBinaryCaller($bin)
 29758 {
 29759 if ('.bat' === substr($bin, -4) || '.exe' === substr($bin, -4)) {
 29760 return 'call';
 29761 }
 29762 
 29763 $handle = fopen($bin, 'r');
 29764 $line = fgets($handle);
 29765 fclose($handle);
 29766 if (Preg::isMatch('{^#!/(?:usr/bin/env )?(?:[^/]+/)*(.+)$}m', $line, $match)) {
 29767 return trim($match[1]);
 29768 }
 29769 
 29770 return 'php';
 29771 }
 29772 
 29773 
 29774 
 29775 
 29776 protected function getBinaries(PackageInterface $package)
 29777 {
 29778 return $package->getBinaries();
 29779 }
 29780 
 29781 
 29782 
 29783 
 29784 
 29785 
 29786 
 29787 
 29788 protected function installFullBinaries($binPath, $link, $bin, PackageInterface $package)
 29789 {
 29790 
 29791 if ('.bat' !== substr($binPath, -4)) {
 29792 $this->installUnixyProxyBinaries($binPath, $link);
 29793 $link .= '.bat';
 29794 if (file_exists($link)) {
 29795 $this->io->writeError('    Skipped installation of bin '.$bin.'.bat proxy for package '.$package->getName().': a .bat proxy was already installed');
 29796 }
 29797 }
 29798 if (!file_exists($link)) {
 29799 file_put_contents($link, $this->generateWindowsProxyCode($binPath, $link));
 29800 Silencer::call('chmod', $link, 0777 & ~umask());
 29801 }
 29802 }
 29803 
 29804 
 29805 
 29806 
 29807 
 29808 
 29809 
 29810 protected function installUnixyProxyBinaries($binPath, $link)
 29811 {
 29812 file_put_contents($link, $this->generateUnixyProxyCode($binPath, $link));
 29813 Silencer::call('chmod', $link, 0777 & ~umask());
 29814 }
 29815 
 29816 
 29817 
 29818 
 29819 protected function initializeBinDir()
 29820 {
 29821 $this->filesystem->ensureDirectoryExists($this->binDir);
 29822 $this->binDir = realpath($this->binDir);
 29823 }
 29824 
 29825 
 29826 
 29827 
 29828 
 29829 
 29830 
 29831 protected function generateWindowsProxyCode($bin, $link)
 29832 {
 29833 $binPath = $this->filesystem->findShortestPath($link, $bin);
 29834 $caller = self::determineBinaryCaller($bin);
 29835 
 29836 
 29837 
 29838 
 29839 if ($caller === 'php') {
 29840 return "@ECHO OFF\r\n".
 29841 "setlocal DISABLEDELAYEDEXPANSION\r\n".
 29842 "SET BIN_TARGET=%~dp0/".trim(ProcessExecutor::escape(basename($link, '.bat')), '"\'')."\r\n".
 29843 "SET COMPOSER_RUNTIME_BIN_DIR=%~dp0\r\n".
 29844 "{$caller} \"%BIN_TARGET%\" %*\r\n";
 29845 }
 29846 
 29847 return "@ECHO OFF\r\n".
 29848 "setlocal DISABLEDELAYEDEXPANSION\r\n".
 29849 "SET BIN_TARGET=%~dp0/".trim(ProcessExecutor::escape($binPath), '"\'')."\r\n".
 29850 "SET COMPOSER_RUNTIME_BIN_DIR=%~dp0\r\n".
 29851 "{$caller} \"%BIN_TARGET%\" %*\r\n";
 29852 }
 29853 
 29854 
 29855 
 29856 
 29857 
 29858 
 29859 
 29860 protected function generateUnixyProxyCode($bin, $link)
 29861 {
 29862 $binPath = $this->filesystem->findShortestPath($link, $bin);
 29863 
 29864 $binDir = ProcessExecutor::escape(dirname($binPath));
 29865 $binFile = basename($binPath);
 29866 
 29867 $binContents = file_get_contents($bin);
 29868 
 29869 
 29870 if (Preg::isMatch('{^(#!.*\r?\n)?[\r\n\t ]*<\?php}', $binContents, $match)) {
 29871 
 29872 $proxyCode = empty($match[1]) ? '#!/usr/bin/env php' : trim($match[1]);
 29873 $binPathExported = $this->filesystem->findShortestPathCode($link, $bin, false, true);
 29874 $streamProxyCode = $streamHint = '';
 29875 $globalsCode = '$GLOBALS[\'_composer_bin_dir\'] = __DIR__;'."\n";
 29876 $phpunitHack1 = $phpunitHack2 = '';
 29877 
 29878 if ($this->vendorDir) {
 29879 $globalsCode .= '$GLOBALS[\'_composer_autoload_path\'] = ' . $this->filesystem->findShortestPathCode($link, $this->vendorDir . '/autoload.php', false, true).";\n";
 29880 }
 29881 
 29882 if ($this->filesystem->normalizePath($bin) === $this->filesystem->normalizePath($this->vendorDir.'/phpunit/phpunit/phpunit')) {
 29883 
 29884 $globalsCode .= '$GLOBALS[\'__PHPUNIT_ISOLATION_EXCLUDE_LIST\'] = $GLOBALS[\'__PHPUNIT_ISOLATION_BLACKLIST\'] = array(realpath('.$binPathExported.'));'."\n";
 29885 
 29886 $phpunitHack1 = "'phpvfscomposer://'.";
 29887 $phpunitHack2 = '
 29888                 $data = str_replace(\'__DIR__\', var_export(dirname($this->realpath), true), $data);
 29889                 $data = str_replace(\'__FILE__\', var_export($this->realpath, true), $data);';
 29890 }
 29891 if (trim($match[0]) !== '<?php') {
 29892 $streamHint = ' using a stream wrapper to prevent the shebang from being output on PHP<8'."\n *";
 29893 $streamProxyCode = <<<STREAMPROXY
 29894 if (PHP_VERSION_ID < 80000) {
 29895     if (!class_exists('Composer\BinProxyWrapper')) {
 29896         /**
 29897          * @internal
 29898          */
 29899         final class BinProxyWrapper
 29900         {
 29901             private \$handle;
 29902             private \$position;
 29903             private \$realpath;
 29904 
 29905             public function stream_open(\$path, \$mode, \$options, &\$opened_path)
 29906             {
 29907                 // get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
 29908                 \$opened_path = substr(\$path, 17);
 29909                 \$this->realpath = realpath(\$opened_path) ?: \$opened_path;
 29910                 \$opened_path = $phpunitHack1\$this->realpath;
 29911                 \$this->handle = fopen(\$this->realpath, \$mode);
 29912                 \$this->position = 0;
 29913 
 29914                 return (bool) \$this->handle;
 29915             }
 29916 
 29917             public function stream_read(\$count)
 29918             {
 29919                 \$data = fread(\$this->handle, \$count);
 29920 
 29921                 if (\$this->position === 0) {
 29922                     \$data = preg_replace('{^#!.*\\r?\\n}', '', \$data);
 29923                 }$phpunitHack2
 29924 
 29925                 \$this->position += strlen(\$data);
 29926 
 29927                 return \$data;
 29928             }
 29929 
 29930             public function stream_cast(\$castAs)
 29931             {
 29932                 return \$this->handle;
 29933             }
 29934 
 29935             public function stream_close()
 29936             {
 29937                 fclose(\$this->handle);
 29938             }
 29939 
 29940             public function stream_lock(\$operation)
 29941             {
 29942                 return \$operation ? flock(\$this->handle, \$operation) : true;
 29943             }
 29944 
 29945             public function stream_seek(\$offset, \$whence)
 29946             {
 29947                 if (0 === fseek(\$this->handle, \$offset, \$whence)) {
 29948                     \$this->position = ftell(\$this->handle);
 29949                     return true;
 29950                 }
 29951 
 29952                 return false;
 29953             }
 29954 
 29955             public function stream_tell()
 29956             {
 29957                 return \$this->position;
 29958             }
 29959 
 29960             public function stream_eof()
 29961             {
 29962                 return feof(\$this->handle);
 29963             }
 29964 
 29965             public function stream_stat()
 29966             {
 29967                 return array();
 29968             }
 29969 
 29970             public function stream_set_option(\$option, \$arg1, \$arg2)
 29971             {
 29972                 return true;
 29973             }
 29974 
 29975             public function url_stat(\$path, \$flags)
 29976             {
 29977                 \$path = substr(\$path, 17);
 29978                 if (file_exists(\$path)) {
 29979                     return stat(\$path);
 29980                 }
 29981 
 29982                 return false;
 29983             }
 29984         }
 29985     }
 29986 
 29987     if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
 29988         include("phpvfscomposer://" . $binPathExported);
 29989         exit(0);
 29990     }
 29991 }
 29992 
 29993 STREAMPROXY;
 29994 }
 29995 
 29996 return $proxyCode . "\n" . <<<PROXY
 29997 <?php
 29998 
 29999 /**
 30000  * Proxy PHP file generated by Composer
 30001  *
 30002  * This file includes the referenced bin path ($binPath)
 30003  *$streamHint
 30004  * @generated
 30005  */
 30006 
 30007 namespace Composer;
 30008 
 30009 $globalsCode
 30010 $streamProxyCode
 30011 include $binPathExported;
 30012 
 30013 PROXY;
 30014 }
 30015 
 30016 return <<<PROXY
 30017 #!/usr/bin/env sh
 30018 
 30019 # Support bash to support `source` with fallback on $0 if this does not run with bash
 30020 # https://stackoverflow.com/a/35006505/6512
 30021 selfArg="\$BASH_SOURCE"
 30022 if [ -z "\$selfArg" ]; then
 30023     selfArg="\$0"
 30024 fi
 30025 
 30026 self=\$(realpath \$selfArg 2> /dev/null)
 30027 if [ -z "\$self" ]; then
 30028     self="\$selfArg"
 30029 fi
 30030 
 30031 dir=\$(cd "\${self%[/\\\\]*}" > /dev/null; cd $binDir && pwd)
 30032 
 30033 if [ -d /proc/cygdrive ]; then
 30034     case \$(which php) in
 30035         \$(readlink -n /proc/cygdrive)/*)
 30036             # We are in Cygwin using Windows php, so the path must be translated
 30037             dir=\$(cygpath -m "\$dir");
 30038             ;;
 30039     esac
 30040 fi
 30041 
 30042 export COMPOSER_RUNTIME_BIN_DIR=\$(cd "\${self%[/\\\\]*}" > /dev/null; pwd)
 30043 
 30044 # If bash is sourcing this file, we have to source the target as well
 30045 bashSource="\$BASH_SOURCE"
 30046 if [ -n "\$bashSource" ]; then
 30047     if [ "\$bashSource" != "\$0" ]; then
 30048         source "\${dir}/$binFile" "\$@"
 30049         return
 30050     fi
 30051 fi
 30052 
 30053 "\${dir}/$binFile" "\$@"
 30054 
 30055 PROXY;
 30056 }
 30057 }
 30058 <?php
 30059 
 30060 
 30061 
 30062 
 30063 
 30064 
 30065 
 30066 
 30067 
 30068 
 30069 
 30070 namespace Composer\Installer;
 30071 
 30072 use Composer\Package\PackageInterface;
 30073 
 30074 
 30075 
 30076 
 30077 
 30078 
 30079 interface BinaryPresenceInterface
 30080 {
 30081 
 30082 
 30083 
 30084 
 30085 
 30086 
 30087 
 30088 public function ensureBinariesPresence(PackageInterface $package);
 30089 }
 30090 <?php
 30091 
 30092 
 30093 
 30094 
 30095 
 30096 
 30097 
 30098 
 30099 
 30100 
 30101 
 30102 namespace Composer\Installer;
 30103 
 30104 use Composer\IO\IOInterface;
 30105 use Composer\IO\ConsoleIO;
 30106 use Composer\Package\PackageInterface;
 30107 use Composer\Package\AliasPackage;
 30108 use Composer\Repository\InstalledRepositoryInterface;
 30109 use Composer\DependencyResolver\Operation\OperationInterface;
 30110 use Composer\DependencyResolver\Operation\InstallOperation;
 30111 use Composer\DependencyResolver\Operation\UpdateOperation;
 30112 use Composer\DependencyResolver\Operation\UninstallOperation;
 30113 use Composer\DependencyResolver\Operation\MarkAliasInstalledOperation;
 30114 use Composer\DependencyResolver\Operation\MarkAliasUninstalledOperation;
 30115 use Composer\Downloader\FileDownloader;
 30116 use Composer\EventDispatcher\EventDispatcher;
 30117 use Composer\Util\Loop;
 30118 use Composer\Util\Platform;
 30119 use React\Promise\PromiseInterface;
 30120 
 30121 
 30122 
 30123 
 30124 
 30125 
 30126 
 30127 
 30128 class InstallationManager
 30129 {
 30130 
 30131 private $installers = array();
 30132 
 30133 private $cache = array();
 30134 
 30135 private $notifiablePackages = array();
 30136 
 30137 private $loop;
 30138 
 30139 private $io;
 30140 
 30141 private $eventDispatcher;
 30142 
 30143 private $outputProgress;
 30144 
 30145 public function __construct(Loop $loop, IOInterface $io, EventDispatcher $eventDispatcher = null)
 30146 {
 30147 $this->loop = $loop;
 30148 $this->io = $io;
 30149 $this->eventDispatcher = $eventDispatcher;
 30150 }
 30151 
 30152 
 30153 
 30154 
 30155 public function reset()
 30156 {
 30157 $this->notifiablePackages = array();
 30158 FileDownloader::$downloadMetadata = array();
 30159 }
 30160 
 30161 
 30162 
 30163 
 30164 
 30165 
 30166 
 30167 
 30168 public function addInstaller(InstallerInterface $installer)
 30169 {
 30170 array_unshift($this->installers, $installer);
 30171 $this->cache = array();
 30172 }
 30173 
 30174 
 30175 
 30176 
 30177 
 30178 
 30179 
 30180 
 30181 public function removeInstaller(InstallerInterface $installer)
 30182 {
 30183 if (false !== ($key = array_search($installer, $this->installers, true))) {
 30184 array_splice($this->installers, $key, 1);
 30185 $this->cache = array();
 30186 }
 30187 }
 30188 
 30189 
 30190 
 30191 
 30192 
 30193 
 30194 
 30195 
 30196 
 30197 
 30198 public function disablePlugins()
 30199 {
 30200 foreach ($this->installers as $i => $installer) {
 30201 if (!$installer instanceof PluginInstaller) {
 30202 continue;
 30203 }
 30204 
 30205 unset($this->installers[$i]);
 30206 }
 30207 }
 30208 
 30209 
 30210 
 30211 
 30212 
 30213 
 30214 
 30215 
 30216 
 30217 public function getInstaller($type)
 30218 {
 30219 $type = strtolower($type);
 30220 
 30221 if (isset($this->cache[$type])) {
 30222 return $this->cache[$type];
 30223 }
 30224 
 30225 foreach ($this->installers as $installer) {
 30226 if ($installer->supports($type)) {
 30227 return $this->cache[$type] = $installer;
 30228 }
 30229 }
 30230 
 30231 throw new \InvalidArgumentException('Unknown installer type: '.$type);
 30232 }
 30233 
 30234 
 30235 
 30236 
 30237 
 30238 
 30239 
 30240 
 30241 
 30242 public function isPackageInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
 30243 {
 30244 if ($package instanceof AliasPackage) {
 30245 return $repo->hasPackage($package) && $this->isPackageInstalled($repo, $package->getAliasOf());
 30246 }
 30247 
 30248 return $this->getInstaller($package->getType())->isInstalled($repo, $package);
 30249 }
 30250 
 30251 
 30252 
 30253 
 30254 
 30255 
 30256 
 30257 
 30258 
 30259 public function ensureBinariesPresence(PackageInterface $package)
 30260 {
 30261 try {
 30262 $installer = $this->getInstaller($package->getType());
 30263 } catch (\InvalidArgumentException $e) {
 30264 
 30265 return;
 30266 }
 30267 
 30268 
 30269 if ($installer instanceof BinaryPresenceInterface) {
 30270 $installer->ensureBinariesPresence($package);
 30271 }
 30272 }
 30273 
 30274 
 30275 
 30276 
 30277 
 30278 
 30279 
 30280 
 30281 
 30282 
 30283 
 30284 public function execute(InstalledRepositoryInterface $repo, array $operations, $devMode = true, $runScripts = true)
 30285 {
 30286 
 30287 $cleanupPromises = array();
 30288 
 30289 $loop = $this->loop;
 30290 $io = $this->io;
 30291 $runCleanup = function () use (&$cleanupPromises, $loop) {
 30292 $promises = array();
 30293 
 30294 $loop->abortJobs();
 30295 
 30296 foreach ($cleanupPromises as $cleanup) {
 30297 $promises[] = new \React\Promise\Promise(function ($resolve, $reject) use ($cleanup) {
 30298 $promise = $cleanup();
 30299 if (!$promise instanceof PromiseInterface) {
 30300 $resolve();
 30301 } else {
 30302 $promise->then(function () use ($resolve) {
 30303 $resolve();
 30304 });
 30305 }
 30306 });
 30307 }
 30308 
 30309 if (!empty($promises)) {
 30310 $loop->wait($promises);
 30311 }
 30312 };
 30313 
 30314 $handleInterruptsUnix = function_exists('pcntl_async_signals') && function_exists('pcntl_signal');
 30315 $handleInterruptsWindows = function_exists('sapi_windows_set_ctrl_handler') && PHP_SAPI === 'cli';
 30316 $prevHandler = null;
 30317 $windowsHandler = null;
 30318 if ($handleInterruptsUnix) {
 30319 pcntl_async_signals(true);
 30320 $prevHandler = pcntl_signal_get_handler(SIGINT);
 30321 pcntl_signal(SIGINT, function ($sig) use ($runCleanup, $prevHandler, $io) {
 30322 $io->writeError('Received SIGINT, aborting', true, IOInterface::DEBUG);
 30323 $runCleanup();
 30324 
 30325 if (!in_array($prevHandler, array(SIG_DFL, SIG_IGN), true)) {
 30326 call_user_func($prevHandler, $sig);
 30327 }
 30328 
 30329 exit(130);
 30330 });
 30331 }
 30332 if ($handleInterruptsWindows) {
 30333 $windowsHandler = function ($event) use ($runCleanup, $io) {
 30334 if ($event !== PHP_WINDOWS_EVENT_CTRL_C) {
 30335 return;
 30336 }
 30337 $io->writeError('Received CTRL+C, aborting', true, IOInterface::DEBUG);
 30338 $runCleanup();
 30339 
 30340 exit(130);
 30341 };
 30342 sapi_windows_set_ctrl_handler($windowsHandler);
 30343 }
 30344 
 30345 try {
 30346 
 30347 
 30348 $batches = array();
 30349 $batch = array();
 30350 foreach ($operations as $index => $operation) {
 30351 if ($operation instanceof UpdateOperation || $operation instanceof InstallOperation) {
 30352 $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage();
 30353 if ($package->getType() === 'composer-plugin' && ($extra = $package->getExtra()) && isset($extra['plugin-modifies-downloads']) && $extra['plugin-modifies-downloads'] === true) {
 30354 if ($batch) {
 30355 $batches[] = $batch;
 30356 }
 30357 $batches[] = array($index => $operation);
 30358 $batch = array();
 30359 
 30360 continue;
 30361 }
 30362 }
 30363 $batch[$index] = $operation;
 30364 }
 30365 
 30366 if ($batch) {
 30367 $batches[] = $batch;
 30368 }
 30369 
 30370 foreach ($batches as $batch) {
 30371 $this->downloadAndExecuteBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $operations);
 30372 }
 30373 } catch (\Exception $e) {
 30374 $runCleanup();
 30375 
 30376 if ($handleInterruptsUnix) {
 30377 pcntl_signal(SIGINT, $prevHandler);
 30378 }
 30379 if ($handleInterruptsWindows) {
 30380 sapi_windows_set_ctrl_handler($windowsHandler, false);
 30381 }
 30382 
 30383 throw $e;
 30384 }
 30385 
 30386 if ($handleInterruptsUnix) {
 30387 pcntl_signal(SIGINT, $prevHandler);
 30388 }
 30389 if ($handleInterruptsWindows) {
 30390 sapi_windows_set_ctrl_handler($windowsHandler, false);
 30391 }
 30392 
 30393 
 30394 
 30395 
 30396 $repo->write($devMode, $this);
 30397 }
 30398 
 30399 
 30400 
 30401 
 30402 
 30403 
 30404 
 30405 
 30406 
 30407 
 30408 private function downloadAndExecuteBatch(InstalledRepositoryInterface $repo, array $operations, array &$cleanupPromises, $devMode, $runScripts, array $allOperations)
 30409 {
 30410 $promises = array();
 30411 
 30412 foreach ($operations as $index => $operation) {
 30413 $opType = $operation->getOperationType();
 30414 
 30415 
 30416 if (!in_array($opType, array('update', 'install', 'uninstall'))) {
 30417 continue;
 30418 }
 30419 
 30420 if ($opType === 'update') {
 30421 
 30422 $package = $operation->getTargetPackage();
 30423 $initialPackage = $operation->getInitialPackage();
 30424 } else {
 30425 
 30426 $package = $operation->getPackage();
 30427 $initialPackage = null;
 30428 }
 30429 $installer = $this->getInstaller($package->getType());
 30430 
 30431 $cleanupPromises[$index] = function () use ($opType, $installer, $package, $initialPackage) {
 30432 
 30433 
 30434 if (!$package->getInstallationSource()) {
 30435 return;
 30436 }
 30437 
 30438 return $installer->cleanup($opType, $package, $initialPackage);
 30439 };
 30440 
 30441 if ($opType !== 'uninstall') {
 30442 $promise = $installer->download($package, $initialPackage);
 30443 if ($promise) {
 30444 $promises[] = $promise;
 30445 }
 30446 }
 30447 }
 30448 
 30449 
 30450 if (count($promises)) {
 30451 $this->waitOnPromises($promises);
 30452 }
 30453 
 30454 
 30455 
 30456 $batches = array();
 30457 $batch = array();
 30458 foreach ($operations as $index => $operation) {
 30459 if ($operation instanceof InstallOperation || $operation instanceof UpdateOperation) {
 30460 $package = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage();
 30461 if ($package->getType() === 'composer-plugin' || $package->getType() === 'composer-installer') {
 30462 if ($batch) {
 30463 $batches[] = $batch;
 30464 }
 30465 $batches[] = array($index => $operation);
 30466 $batch = array();
 30467 
 30468 continue;
 30469 }
 30470 }
 30471 $batch[$index] = $operation;
 30472 }
 30473 
 30474 if ($batch) {
 30475 $batches[] = $batch;
 30476 }
 30477 
 30478 foreach ($batches as $batch) {
 30479 $this->executeBatch($repo, $batch, $cleanupPromises, $devMode, $runScripts, $allOperations);
 30480 }
 30481 }
 30482 
 30483 
 30484 
 30485 
 30486 
 30487 
 30488 
 30489 
 30490 
 30491 
 30492 private function executeBatch(InstalledRepositoryInterface $repo, array $operations, array $cleanupPromises, $devMode, $runScripts, array $allOperations)
 30493 {
 30494 $promises = array();
 30495 $postExecCallbacks = array();
 30496 
 30497 foreach ($operations as $index => $operation) {
 30498 $opType = $operation->getOperationType();
 30499 
 30500 
 30501 if (!in_array($opType, array('update', 'install', 'uninstall'))) {
 30502 
 30503 if ($this->io->isDebug()) {
 30504 $this->io->writeError('  - ' . $operation->show(false));
 30505 }
 30506 $this->$opType($repo, $operation);
 30507 
 30508 continue;
 30509 }
 30510 
 30511 if ($opType === 'update') {
 30512 
 30513 $package = $operation->getTargetPackage();
 30514 $initialPackage = $operation->getInitialPackage();
 30515 } else {
 30516 
 30517 $package = $operation->getPackage();
 30518 $initialPackage = null;
 30519 }
 30520 $installer = $this->getInstaller($package->getType());
 30521 
 30522 $event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($opType);
 30523 if (defined($event) && $runScripts && $this->eventDispatcher) {
 30524 $this->eventDispatcher->dispatchPackageEvent(constant($event), $devMode, $repo, $allOperations, $operation);
 30525 }
 30526 
 30527 $dispatcher = $this->eventDispatcher;
 30528 $installManager = $this;
 30529 $io = $this->io;
 30530 
 30531 $promise = $installer->prepare($opType, $package, $initialPackage);
 30532 if (!$promise instanceof PromiseInterface) {
 30533 $promise = \React\Promise\resolve();
 30534 }
 30535 
 30536 $promise = $promise->then(function () use ($opType, $installManager, $repo, $operation) {
 30537 return $installManager->$opType($repo, $operation);
 30538 })->then($cleanupPromises[$index])
 30539 ->then(function () use ($installManager, $devMode, $repo) {
 30540 $repo->write($devMode, $installManager);
 30541 }, function ($e) use ($opType, $package, $io) {
 30542 $io->writeError('    <error>' . ucfirst($opType) .' of '.$package->getPrettyName().' failed</error>');
 30543 
 30544 throw $e;
 30545 });
 30546 
 30547 $postExecCallbacks[] = function () use ($opType, $runScripts, $dispatcher, $devMode, $repo, $allOperations, $operation) {
 30548 $event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($opType);
 30549 if (defined($event) && $runScripts && $dispatcher) {
 30550 $dispatcher->dispatchPackageEvent(constant($event), $devMode, $repo, $allOperations, $operation);
 30551 }
 30552 };
 30553 
 30554 $promises[] = $promise;
 30555 }
 30556 
 30557 
 30558 if (count($promises)) {
 30559 $this->waitOnPromises($promises);
 30560 }
 30561 
 30562 Platform::workaroundFilesystemIssues();
 30563 
 30564 foreach ($postExecCallbacks as $cb) {
 30565 $cb();
 30566 }
 30567 }
 30568 
 30569 
 30570 
 30571 
 30572 
 30573 
 30574 private function waitOnPromises(array $promises)
 30575 {
 30576 $progress = null;
 30577 if (
 30578 $this->outputProgress
 30579 && $this->io instanceof ConsoleIO
 30580 && !Platform::getEnv('CI')
 30581 && !$this->io->isDebug()
 30582 && count($promises) > 1
 30583 ) {
 30584 $progress = $this->io->getProgressBar();
 30585 }
 30586 $this->loop->wait($promises, $progress);
 30587 if ($progress) {
 30588 $progress->clear();
 30589 
 30590 if (!$this->io->isDecorated()) {
 30591 $this->io->writeError('');
 30592 }
 30593 }
 30594 }
 30595 
 30596 
 30597 
 30598 
 30599 
 30600 
 30601 
 30602 
 30603 
 30604 public function install(InstalledRepositoryInterface $repo, InstallOperation $operation)
 30605 {
 30606 $package = $operation->getPackage();
 30607 $installer = $this->getInstaller($package->getType());
 30608 $promise = $installer->install($repo, $package);
 30609 $this->markForNotification($package);
 30610 
 30611 return $promise;
 30612 }
 30613 
 30614 
 30615 
 30616 
 30617 
 30618 
 30619 
 30620 
 30621 
 30622 public function update(InstalledRepositoryInterface $repo, UpdateOperation $operation)
 30623 {
 30624 $initial = $operation->getInitialPackage();
 30625 $target = $operation->getTargetPackage();
 30626 
 30627 $initialType = $initial->getType();
 30628 $targetType = $target->getType();
 30629 
 30630 if ($initialType === $targetType) {
 30631 $installer = $this->getInstaller($initialType);
 30632 $promise = $installer->update($repo, $initial, $target);
 30633 $this->markForNotification($target);
 30634 } else {
 30635 $promise = $this->getInstaller($initialType)->uninstall($repo, $initial);
 30636 if (!$promise instanceof PromiseInterface) {
 30637 $promise = \React\Promise\resolve();
 30638 }
 30639 
 30640 $installer = $this->getInstaller($targetType);
 30641 $promise = $promise->then(function () use ($installer, $repo, $target) {
 30642 return $installer->install($repo, $target);
 30643 });
 30644 }
 30645 
 30646 return $promise;
 30647 }
 30648 
 30649 
 30650 
 30651 
 30652 
 30653 
 30654 
 30655 
 30656 
 30657 public function uninstall(InstalledRepositoryInterface $repo, UninstallOperation $operation)
 30658 {
 30659 $package = $operation->getPackage();
 30660 $installer = $this->getInstaller($package->getType());
 30661 
 30662 return $installer->uninstall($repo, $package);
 30663 }
 30664 
 30665 
 30666 
 30667 
 30668 
 30669 
 30670 
 30671 
 30672 
 30673 public function markAliasInstalled(InstalledRepositoryInterface $repo, MarkAliasInstalledOperation $operation)
 30674 {
 30675 $package = $operation->getPackage();
 30676 
 30677 if (!$repo->hasPackage($package)) {
 30678 $repo->addPackage(clone $package);
 30679 }
 30680 }
 30681 
 30682 
 30683 
 30684 
 30685 
 30686 
 30687 
 30688 
 30689 
 30690 public function markAliasUninstalled(InstalledRepositoryInterface $repo, MarkAliasUninstalledOperation $operation)
 30691 {
 30692 $package = $operation->getPackage();
 30693 
 30694 $repo->removePackage($package);
 30695 }
 30696 
 30697 
 30698 
 30699 
 30700 
 30701 
 30702 
 30703 public function getInstallPath(PackageInterface $package)
 30704 {
 30705 $installer = $this->getInstaller($package->getType());
 30706 
 30707 return $installer->getInstallPath($package);
 30708 }
 30709 
 30710 
 30711 
 30712 
 30713 
 30714 
 30715 public function setOutputProgress($outputProgress)
 30716 {
 30717 $this->outputProgress = $outputProgress;
 30718 }
 30719 
 30720 
 30721 
 30722 
 30723 public function notifyInstalls(IOInterface $io)
 30724 {
 30725 $promises = array();
 30726 
 30727 try {
 30728 foreach ($this->notifiablePackages as $repoUrl => $packages) {
 30729 
 30730 if (strpos($repoUrl, '%package%')) {
 30731 foreach ($packages as $package) {
 30732 $url = str_replace('%package%', $package->getPrettyName(), $repoUrl);
 30733 
 30734 $params = array(
 30735 'version' => $package->getPrettyVersion(),
 30736 'version_normalized' => $package->getVersion(),
 30737 );
 30738 $opts = array(
 30739 'retry-auth-failure' => false,
 30740 'http' => array(
 30741 'method' => 'POST',
 30742 'header' => array('Content-type: application/x-www-form-urlencoded'),
 30743 'content' => http_build_query($params, '', '&'),
 30744 'timeout' => 3,
 30745 ),
 30746 );
 30747 
 30748 $promises[] = $this->loop->getHttpDownloader()->add($url, $opts);
 30749 }
 30750 
 30751 continue;
 30752 }
 30753 
 30754 $postData = array('downloads' => array());
 30755 foreach ($packages as $package) {
 30756 $packageNotification = array(
 30757 'name' => $package->getPrettyName(),
 30758 'version' => $package->getVersion(),
 30759 );
 30760 if (strpos($repoUrl, 'packagist.org/') !== false) {
 30761 if (isset(FileDownloader::$downloadMetadata[$package->getName()])) {
 30762 $packageNotification['downloaded'] = FileDownloader::$downloadMetadata[$package->getName()];
 30763 } else {
 30764 $packageNotification['downloaded'] = false;
 30765 }
 30766 }
 30767 $postData['downloads'][] = $packageNotification;
 30768 }
 30769 
 30770 $opts = array(
 30771 'retry-auth-failure' => false,
 30772 'http' => array(
 30773 'method' => 'POST',
 30774 'header' => array('Content-Type: application/json'),
 30775 'content' => json_encode($postData),
 30776 'timeout' => 6,
 30777 ),
 30778 );
 30779 
 30780 $promises[] = $this->loop->getHttpDownloader()->add($repoUrl, $opts);
 30781 }
 30782 
 30783 $this->loop->wait($promises);
 30784 } catch (\Exception $e) {
 30785 }
 30786 
 30787 $this->reset();
 30788 }
 30789 
 30790 
 30791 
 30792 
 30793 private function markForNotification(PackageInterface $package)
 30794 {
 30795 if ($package->getNotificationUrl()) {
 30796 $this->notifiablePackages[$package->getNotificationUrl()][$package->getName()] = $package;
 30797 }
 30798 }
 30799 }
 30800 <?php
 30801 
 30802 
 30803 
 30804 
 30805 
 30806 
 30807 
 30808 
 30809 
 30810 
 30811 
 30812 namespace Composer\Installer;
 30813 
 30814 use Composer\Composer;
 30815 use Composer\DependencyResolver\Transaction;
 30816 use Composer\EventDispatcher\Event;
 30817 use Composer\IO\IOInterface;
 30818 
 30819 class InstallerEvent extends Event
 30820 {
 30821 
 30822 
 30823 
 30824 private $composer;
 30825 
 30826 
 30827 
 30828 
 30829 private $io;
 30830 
 30831 
 30832 
 30833 
 30834 private $devMode;
 30835 
 30836 
 30837 
 30838 
 30839 private $executeOperations;
 30840 
 30841 
 30842 
 30843 
 30844 private $transaction;
 30845 
 30846 
 30847 
 30848 
 30849 
 30850 
 30851 
 30852 
 30853 
 30854 
 30855 
 30856 public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, $executeOperations, Transaction $transaction)
 30857 {
 30858 parent::__construct($eventName);
 30859 
 30860 $this->composer = $composer;
 30861 $this->io = $io;
 30862 $this->devMode = $devMode;
 30863 $this->executeOperations = $executeOperations;
 30864 $this->transaction = $transaction;
 30865 }
 30866 
 30867 
 30868 
 30869 
 30870 public function getComposer()
 30871 {
 30872 return $this->composer;
 30873 }
 30874 
 30875 
 30876 
 30877 
 30878 public function getIO()
 30879 {
 30880 return $this->io;
 30881 }
 30882 
 30883 
 30884 
 30885 
 30886 public function isDevMode()
 30887 {
 30888 return $this->devMode;
 30889 }
 30890 
 30891 
 30892 
 30893 
 30894 public function isExecutingOperations()
 30895 {
 30896 return $this->executeOperations;
 30897 }
 30898 
 30899 
 30900 
 30901 
 30902 public function getTransaction()
 30903 {
 30904 return $this->transaction;
 30905 }
 30906 }
 30907 <?php
 30908 
 30909 
 30910 
 30911 
 30912 
 30913 
 30914 
 30915 
 30916 
 30917 
 30918 
 30919 namespace Composer\Installer;
 30920 
 30921 class InstallerEvents
 30922 {
 30923 
 30924 
 30925 
 30926 
 30927 
 30928 
 30929 
 30930 
 30931 const PRE_OPERATIONS_EXEC = 'pre-operations-exec';
 30932 }
 30933 <?php
 30934 
 30935 
 30936 
 30937 
 30938 
 30939 
 30940 
 30941 
 30942 
 30943 
 30944 
 30945 namespace Composer\Installer;
 30946 
 30947 use Composer\Package\PackageInterface;
 30948 use Composer\Repository\InstalledRepositoryInterface;
 30949 use InvalidArgumentException;
 30950 use React\Promise\PromiseInterface;
 30951 
 30952 
 30953 
 30954 
 30955 
 30956 
 30957 
 30958 interface InstallerInterface
 30959 {
 30960 
 30961 
 30962 
 30963 
 30964 
 30965 
 30966 public function supports($packageType);
 30967 
 30968 
 30969 
 30970 
 30971 
 30972 
 30973 
 30974 
 30975 
 30976 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package);
 30977 
 30978 
 30979 
 30980 
 30981 
 30982 
 30983 
 30984 
 30985 public function download(PackageInterface $package, PackageInterface $prevPackage = null);
 30986 
 30987 
 30988 
 30989 
 30990 
 30991 
 30992 
 30993 
 30994 
 30995 
 30996 
 30997 
 30998 
 30999 
 31000 public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null);
 31001 
 31002 
 31003 
 31004 
 31005 
 31006 
 31007 
 31008 
 31009 public function install(InstalledRepositoryInterface $repo, PackageInterface $package);
 31010 
 31011 
 31012 
 31013 
 31014 
 31015 
 31016 
 31017 
 31018 
 31019 
 31020 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target);
 31021 
 31022 
 31023 
 31024 
 31025 
 31026 
 31027 
 31028 
 31029 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package);
 31030 
 31031 
 31032 
 31033 
 31034 
 31035 
 31036 
 31037 
 31038 
 31039 
 31040 
 31041 
 31042 
 31043 public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null);
 31044 
 31045 
 31046 
 31047 
 31048 
 31049 
 31050 
 31051 public function getInstallPath(PackageInterface $package);
 31052 }
 31053 <?php
 31054 
 31055 
 31056 
 31057 
 31058 
 31059 
 31060 
 31061 
 31062 
 31063 
 31064 
 31065 namespace Composer\Installer;
 31066 
 31067 use Composer\Composer;
 31068 use Composer\IO\IOInterface;
 31069 use Composer\Pcre\Preg;
 31070 use Composer\Repository\InstalledRepositoryInterface;
 31071 use Composer\Package\PackageInterface;
 31072 use Composer\Util\Filesystem;
 31073 use Composer\Util\Silencer;
 31074 use Composer\Util\Platform;
 31075 use React\Promise\PromiseInterface;
 31076 use Composer\Downloader\DownloadManager;
 31077 
 31078 
 31079 
 31080 
 31081 
 31082 
 31083 
 31084 class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
 31085 {
 31086 
 31087 protected $composer;
 31088 
 31089 protected $vendorDir;
 31090 
 31091 protected $downloadManager;
 31092 
 31093 protected $io;
 31094 
 31095 protected $type;
 31096 
 31097 protected $filesystem;
 31098 
 31099 protected $binaryInstaller;
 31100 
 31101 
 31102 
 31103 
 31104 
 31105 
 31106 
 31107 
 31108 
 31109 
 31110 public function __construct(IOInterface $io, Composer $composer, $type = 'library', Filesystem $filesystem = null, BinaryInstaller $binaryInstaller = null)
 31111 {
 31112 $this->composer = $composer;
 31113 $this->downloadManager = $composer->getDownloadManager();
 31114 $this->io = $io;
 31115 $this->type = $type;
 31116 
 31117 $this->filesystem = $filesystem ?: new Filesystem();
 31118 $this->vendorDir = rtrim($composer->getConfig()->get('vendor-dir'), '/');
 31119 $this->binaryInstaller = $binaryInstaller ?: new BinaryInstaller($this->io, rtrim($composer->getConfig()->get('bin-dir'), '/'), $composer->getConfig()->get('bin-compat'), $this->filesystem, $this->vendorDir);
 31120 }
 31121 
 31122 
 31123 
 31124 
 31125 public function supports($packageType)
 31126 {
 31127 return $packageType === $this->type || null === $this->type;
 31128 }
 31129 
 31130 
 31131 
 31132 
 31133 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
 31134 {
 31135 if (!$repo->hasPackage($package)) {
 31136 return false;
 31137 }
 31138 
 31139 $installPath = $this->getInstallPath($package);
 31140 
 31141 if (Filesystem::isReadable($installPath)) {
 31142 return true;
 31143 }
 31144 
 31145 return (Platform::isWindows() && $this->filesystem->isJunction($installPath)) || is_link($installPath);
 31146 }
 31147 
 31148 
 31149 
 31150 
 31151 public function download(PackageInterface $package, PackageInterface $prevPackage = null)
 31152 {
 31153 $this->initializeVendorDir();
 31154 $downloadPath = $this->getInstallPath($package);
 31155 
 31156 return $this->downloadManager->download($package, $downloadPath, $prevPackage);
 31157 }
 31158 
 31159 
 31160 
 31161 
 31162 public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
 31163 {
 31164 $this->initializeVendorDir();
 31165 $downloadPath = $this->getInstallPath($package);
 31166 
 31167 return $this->downloadManager->prepare($type, $package, $downloadPath, $prevPackage);
 31168 }
 31169 
 31170 
 31171 
 31172 
 31173 public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
 31174 {
 31175 $this->initializeVendorDir();
 31176 $downloadPath = $this->getInstallPath($package);
 31177 
 31178 return $this->downloadManager->cleanup($type, $package, $downloadPath, $prevPackage);
 31179 }
 31180 
 31181 
 31182 
 31183 
 31184 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
 31185 {
 31186 $this->initializeVendorDir();
 31187 $downloadPath = $this->getInstallPath($package);
 31188 
 31189 
 31190 if (!Filesystem::isReadable($downloadPath) && $repo->hasPackage($package)) {
 31191 $this->binaryInstaller->removeBinaries($package);
 31192 }
 31193 
 31194 $promise = $this->installCode($package);
 31195 if (!$promise instanceof PromiseInterface) {
 31196 $promise = \React\Promise\resolve();
 31197 }
 31198 
 31199 $binaryInstaller = $this->binaryInstaller;
 31200 $installPath = $this->getInstallPath($package);
 31201 
 31202 return $promise->then(function () use ($binaryInstaller, $installPath, $package, $repo) {
 31203 $binaryInstaller->installBinaries($package, $installPath);
 31204 if (!$repo->hasPackage($package)) {
 31205 $repo->addPackage(clone $package);
 31206 }
 31207 });
 31208 }
 31209 
 31210 
 31211 
 31212 
 31213 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
 31214 {
 31215 if (!$repo->hasPackage($initial)) {
 31216 throw new \InvalidArgumentException('Package is not installed: '.$initial);
 31217 }
 31218 
 31219 $this->initializeVendorDir();
 31220 
 31221 $this->binaryInstaller->removeBinaries($initial);
 31222 $promise = $this->updateCode($initial, $target);
 31223 if (!$promise instanceof PromiseInterface) {
 31224 $promise = \React\Promise\resolve();
 31225 }
 31226 
 31227 $binaryInstaller = $this->binaryInstaller;
 31228 $installPath = $this->getInstallPath($target);
 31229 
 31230 return $promise->then(function () use ($binaryInstaller, $installPath, $target, $initial, $repo) {
 31231 $binaryInstaller->installBinaries($target, $installPath);
 31232 $repo->removePackage($initial);
 31233 if (!$repo->hasPackage($target)) {
 31234 $repo->addPackage(clone $target);
 31235 }
 31236 });
 31237 }
 31238 
 31239 
 31240 
 31241 
 31242 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
 31243 {
 31244 if (!$repo->hasPackage($package)) {
 31245 throw new \InvalidArgumentException('Package is not installed: '.$package);
 31246 }
 31247 
 31248 $promise = $this->removeCode($package);
 31249 if (!$promise instanceof PromiseInterface) {
 31250 $promise = \React\Promise\resolve();
 31251 }
 31252 
 31253 $binaryInstaller = $this->binaryInstaller;
 31254 $downloadPath = $this->getPackageBasePath($package);
 31255 $filesystem = $this->filesystem;
 31256 
 31257 return $promise->then(function () use ($binaryInstaller, $filesystem, $downloadPath, $package, $repo) {
 31258 $binaryInstaller->removeBinaries($package);
 31259 $repo->removePackage($package);
 31260 
 31261 if (strpos($package->getName(), '/')) {
 31262 $packageVendorDir = dirname($downloadPath);
 31263 if (is_dir($packageVendorDir) && $filesystem->isDirEmpty($packageVendorDir)) {
 31264 Silencer::call('rmdir', $packageVendorDir);
 31265 }
 31266 }
 31267 });
 31268 }
 31269 
 31270 
 31271 
 31272 
 31273 public function getInstallPath(PackageInterface $package)
 31274 {
 31275 $this->initializeVendorDir();
 31276 
 31277 $basePath = ($this->vendorDir ? $this->vendorDir.'/' : '') . $package->getPrettyName();
 31278 $targetDir = $package->getTargetDir();
 31279 
 31280 return $basePath . ($targetDir ? '/'.$targetDir : '');
 31281 }
 31282 
 31283 
 31284 
 31285 
 31286 
 31287 
 31288 public function ensureBinariesPresence(PackageInterface $package)
 31289 {
 31290 $this->binaryInstaller->installBinaries($package, $this->getInstallPath($package), false);
 31291 }
 31292 
 31293 
 31294 
 31295 
 31296 
 31297 
 31298 
 31299 
 31300 
 31301 
 31302 protected function getPackageBasePath(PackageInterface $package)
 31303 {
 31304 $installPath = $this->getInstallPath($package);
 31305 $targetDir = $package->getTargetDir();
 31306 
 31307 if ($targetDir) {
 31308 return Preg::replace('{/*'.str_replace('/', '/+', preg_quote($targetDir)).'/?$}', '', $installPath);
 31309 }
 31310 
 31311 return $installPath;
 31312 }
 31313 
 31314 
 31315 
 31316 
 31317 protected function installCode(PackageInterface $package)
 31318 {
 31319 $downloadPath = $this->getInstallPath($package);
 31320 
 31321 return $this->downloadManager->install($package, $downloadPath);
 31322 }
 31323 
 31324 
 31325 
 31326 
 31327 protected function updateCode(PackageInterface $initial, PackageInterface $target)
 31328 {
 31329 $initialDownloadPath = $this->getInstallPath($initial);
 31330 $targetDownloadPath = $this->getInstallPath($target);
 31331 if ($targetDownloadPath !== $initialDownloadPath) {
 31332 
 31333 
 31334 if (strpos($initialDownloadPath, $targetDownloadPath) === 0
 31335 || strpos($targetDownloadPath, $initialDownloadPath) === 0
 31336 ) {
 31337 $promise = $this->removeCode($initial);
 31338 if (!$promise instanceof PromiseInterface) {
 31339 $promise = \React\Promise\resolve();
 31340 }
 31341 
 31342 $self = $this;
 31343 
 31344 return $promise->then(function () use ($self, $target) {
 31345 $reflMethod = new \ReflectionMethod($self, 'installCode');
 31346 $reflMethod->setAccessible(true);
 31347 
 31348 
 31349 
 31350 return $reflMethod->invoke($self, $target);
 31351 });
 31352 }
 31353 
 31354 $this->filesystem->rename($initialDownloadPath, $targetDownloadPath);
 31355 }
 31356 
 31357 return $this->downloadManager->update($initial, $target, $targetDownloadPath);
 31358 }
 31359 
 31360 
 31361 
 31362 
 31363 protected function removeCode(PackageInterface $package)
 31364 {
 31365 $downloadPath = $this->getPackageBasePath($package);
 31366 
 31367 return $this->downloadManager->remove($package, $downloadPath);
 31368 }
 31369 
 31370 
 31371 
 31372 
 31373 protected function initializeVendorDir()
 31374 {
 31375 $this->filesystem->ensureDirectoryExists($this->vendorDir);
 31376 $this->vendorDir = realpath($this->vendorDir);
 31377 }
 31378 }
 31379 <?php
 31380 
 31381 
 31382 
 31383 
 31384 
 31385 
 31386 
 31387 
 31388 
 31389 
 31390 
 31391 namespace Composer\Installer;
 31392 
 31393 use Composer\Repository\InstalledRepositoryInterface;
 31394 use Composer\Package\PackageInterface;
 31395 use Composer\IO\IOInterface;
 31396 use Composer\DependencyResolver\Operation\UpdateOperation;
 31397 use Composer\DependencyResolver\Operation\InstallOperation;
 31398 use Composer\DependencyResolver\Operation\UninstallOperation;
 31399 
 31400 
 31401 
 31402 
 31403 
 31404 
 31405 class MetapackageInstaller implements InstallerInterface
 31406 {
 31407 
 31408 private $io;
 31409 
 31410 public function __construct(IOInterface $io)
 31411 {
 31412 $this->io = $io;
 31413 }
 31414 
 31415 
 31416 
 31417 
 31418 public function supports($packageType)
 31419 {
 31420 return $packageType === 'metapackage';
 31421 }
 31422 
 31423 
 31424 
 31425 
 31426 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
 31427 {
 31428 return $repo->hasPackage($package);
 31429 }
 31430 
 31431 
 31432 
 31433 
 31434 public function download(PackageInterface $package, PackageInterface $prevPackage = null)
 31435 {
 31436 
 31437 return \React\Promise\resolve();
 31438 }
 31439 
 31440 
 31441 
 31442 
 31443 public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
 31444 {
 31445 
 31446 return \React\Promise\resolve();
 31447 }
 31448 
 31449 
 31450 
 31451 
 31452 public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
 31453 {
 31454 
 31455 return \React\Promise\resolve();
 31456 }
 31457 
 31458 
 31459 
 31460 
 31461 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
 31462 {
 31463 $this->io->writeError("  - " . InstallOperation::format($package));
 31464 
 31465 $repo->addPackage(clone $package);
 31466 
 31467 return \React\Promise\resolve();
 31468 }
 31469 
 31470 
 31471 
 31472 
 31473 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
 31474 {
 31475 if (!$repo->hasPackage($initial)) {
 31476 throw new \InvalidArgumentException('Package is not installed: '.$initial);
 31477 }
 31478 
 31479 $this->io->writeError("  - " . UpdateOperation::format($initial, $target));
 31480 
 31481 $repo->removePackage($initial);
 31482 $repo->addPackage(clone $target);
 31483 
 31484 return \React\Promise\resolve();
 31485 }
 31486 
 31487 
 31488 
 31489 
 31490 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
 31491 {
 31492 if (!$repo->hasPackage($package)) {
 31493 throw new \InvalidArgumentException('Package is not installed: '.$package);
 31494 }
 31495 
 31496 $this->io->writeError("  - " . UninstallOperation::format($package));
 31497 
 31498 $repo->removePackage($package);
 31499 
 31500 return \React\Promise\resolve();
 31501 }
 31502 
 31503 
 31504 
 31505 
 31506 public function getInstallPath(PackageInterface $package)
 31507 {
 31508 return '';
 31509 }
 31510 }
 31511 <?php
 31512 
 31513 
 31514 
 31515 
 31516 
 31517 
 31518 
 31519 
 31520 
 31521 
 31522 
 31523 namespace Composer\Installer;
 31524 
 31525 use Composer\Repository\InstalledRepositoryInterface;
 31526 use Composer\Package\PackageInterface;
 31527 
 31528 
 31529 
 31530 
 31531 
 31532 
 31533 
 31534 
 31535 class NoopInstaller implements InstallerInterface
 31536 {
 31537 
 31538 
 31539 
 31540 public function supports($packageType)
 31541 {
 31542 return true;
 31543 }
 31544 
 31545 
 31546 
 31547 
 31548 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
 31549 {
 31550 return $repo->hasPackage($package);
 31551 }
 31552 
 31553 
 31554 
 31555 
 31556 public function download(PackageInterface $package, PackageInterface $prevPackage = null)
 31557 {
 31558 return \React\Promise\resolve();
 31559 }
 31560 
 31561 
 31562 
 31563 
 31564 public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
 31565 {
 31566 return \React\Promise\resolve();
 31567 }
 31568 
 31569 
 31570 
 31571 
 31572 public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
 31573 {
 31574 return \React\Promise\resolve();
 31575 }
 31576 
 31577 
 31578 
 31579 
 31580 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
 31581 {
 31582 if (!$repo->hasPackage($package)) {
 31583 $repo->addPackage(clone $package);
 31584 }
 31585 
 31586 return \React\Promise\resolve();
 31587 }
 31588 
 31589 
 31590 
 31591 
 31592 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
 31593 {
 31594 if (!$repo->hasPackage($initial)) {
 31595 throw new \InvalidArgumentException('Package is not installed: '.$initial);
 31596 }
 31597 
 31598 $repo->removePackage($initial);
 31599 if (!$repo->hasPackage($target)) {
 31600 $repo->addPackage(clone $target);
 31601 }
 31602 
 31603 return \React\Promise\resolve();
 31604 }
 31605 
 31606 
 31607 
 31608 
 31609 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
 31610 {
 31611 if (!$repo->hasPackage($package)) {
 31612 throw new \InvalidArgumentException('Package is not installed: '.$package);
 31613 }
 31614 $repo->removePackage($package);
 31615 
 31616 return \React\Promise\resolve();
 31617 }
 31618 
 31619 
 31620 
 31621 
 31622 public function getInstallPath(PackageInterface $package)
 31623 {
 31624 $targetDir = $package->getTargetDir();
 31625 
 31626 return $package->getPrettyName() . ($targetDir ? '/'.$targetDir : '');
 31627 }
 31628 }
 31629 <?php
 31630 
 31631 
 31632 
 31633 
 31634 
 31635 
 31636 
 31637 
 31638 
 31639 
 31640 
 31641 namespace Composer\Installer;
 31642 
 31643 use Composer\Composer;
 31644 use Composer\IO\IOInterface;
 31645 use Composer\DependencyResolver\Operation\OperationInterface;
 31646 use Composer\Repository\RepositoryInterface;
 31647 use Composer\EventDispatcher\Event;
 31648 
 31649 
 31650 
 31651 
 31652 
 31653 
 31654 class PackageEvent extends Event
 31655 {
 31656 
 31657 
 31658 
 31659 private $composer;
 31660 
 31661 
 31662 
 31663 
 31664 private $io;
 31665 
 31666 
 31667 
 31668 
 31669 private $devMode;
 31670 
 31671 
 31672 
 31673 
 31674 private $localRepo;
 31675 
 31676 
 31677 
 31678 
 31679 private $operations;
 31680 
 31681 
 31682 
 31683 
 31684 private $operation;
 31685 
 31686 
 31687 
 31688 
 31689 
 31690 
 31691 
 31692 
 31693 
 31694 
 31695 
 31696 
 31697 public function __construct($eventName, Composer $composer, IOInterface $io, $devMode, RepositoryInterface $localRepo, array $operations, OperationInterface $operation)
 31698 {
 31699 parent::__construct($eventName);
 31700 
 31701 $this->composer = $composer;
 31702 $this->io = $io;
 31703 $this->devMode = $devMode;
 31704 $this->localRepo = $localRepo;
 31705 $this->operations = $operations;
 31706 $this->operation = $operation;
 31707 }
 31708 
 31709 
 31710 
 31711 
 31712 public function getComposer()
 31713 {
 31714 return $this->composer;
 31715 }
 31716 
 31717 
 31718 
 31719 
 31720 public function getIO()
 31721 {
 31722 return $this->io;
 31723 }
 31724 
 31725 
 31726 
 31727 
 31728 public function isDevMode()
 31729 {
 31730 return $this->devMode;
 31731 }
 31732 
 31733 
 31734 
 31735 
 31736 public function getLocalRepo()
 31737 {
 31738 return $this->localRepo;
 31739 }
 31740 
 31741 
 31742 
 31743 
 31744 public function getOperations()
 31745 {
 31746 return $this->operations;
 31747 }
 31748 
 31749 
 31750 
 31751 
 31752 
 31753 
 31754 public function getOperation()
 31755 {
 31756 return $this->operation;
 31757 }
 31758 }
 31759 <?php
 31760 
 31761 
 31762 
 31763 
 31764 
 31765 
 31766 
 31767 
 31768 
 31769 
 31770 
 31771 namespace Composer\Installer;
 31772 
 31773 
 31774 
 31775 
 31776 
 31777 
 31778 class PackageEvents
 31779 {
 31780 
 31781 
 31782 
 31783 
 31784 
 31785 
 31786 
 31787 const PRE_PACKAGE_INSTALL = 'pre-package-install';
 31788 
 31789 
 31790 
 31791 
 31792 
 31793 
 31794 
 31795 
 31796 const POST_PACKAGE_INSTALL = 'post-package-install';
 31797 
 31798 
 31799 
 31800 
 31801 
 31802 
 31803 
 31804 
 31805 const PRE_PACKAGE_UPDATE = 'pre-package-update';
 31806 
 31807 
 31808 
 31809 
 31810 
 31811 
 31812 
 31813 
 31814 const POST_PACKAGE_UPDATE = 'post-package-update';
 31815 
 31816 
 31817 
 31818 
 31819 
 31820 
 31821 
 31822 
 31823 const PRE_PACKAGE_UNINSTALL = 'pre-package-uninstall';
 31824 
 31825 
 31826 
 31827 
 31828 
 31829 
 31830 
 31831 
 31832 const POST_PACKAGE_UNINSTALL = 'post-package-uninstall';
 31833 }
 31834 <?php
 31835 
 31836 
 31837 
 31838 
 31839 
 31840 
 31841 
 31842 
 31843 
 31844 
 31845 
 31846 namespace Composer\Installer;
 31847 
 31848 use Composer\Composer;
 31849 use Composer\IO\IOInterface;
 31850 use Composer\Repository\InstalledRepositoryInterface;
 31851 use Composer\Package\PackageInterface;
 31852 use Composer\Util\Filesystem;
 31853 use Composer\Util\Platform;
 31854 use React\Promise\PromiseInterface;
 31855 
 31856 
 31857 
 31858 
 31859 
 31860 
 31861 
 31862 class PluginInstaller extends LibraryInstaller
 31863 {
 31864 
 31865 
 31866 
 31867 
 31868 
 31869 
 31870 public function __construct(IOInterface $io, Composer $composer, Filesystem $fs = null, BinaryInstaller $binaryInstaller = null)
 31871 {
 31872 parent::__construct($io, $composer, 'composer-plugin', $fs, $binaryInstaller);
 31873 }
 31874 
 31875 
 31876 
 31877 
 31878 public function supports($packageType)
 31879 {
 31880 return $packageType === 'composer-plugin' || $packageType === 'composer-installer';
 31881 }
 31882 
 31883 
 31884 
 31885 
 31886 public function download(PackageInterface $package, PackageInterface $prevPackage = null)
 31887 {
 31888 $extra = $package->getExtra();
 31889 if (empty($extra['class'])) {
 31890 throw new \UnexpectedValueException('Error while installing '.$package->getPrettyName().', composer-plugin packages should have a class defined in their extra key to be usable.');
 31891 }
 31892 
 31893 return parent::download($package, $prevPackage);
 31894 }
 31895 
 31896 
 31897 
 31898 
 31899 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
 31900 {
 31901 $promise = parent::install($repo, $package);
 31902 if (!$promise instanceof PromiseInterface) {
 31903 $promise = \React\Promise\resolve();
 31904 }
 31905 
 31906 $pluginManager = $this->composer->getPluginManager();
 31907 $self = $this;
 31908 
 31909 return $promise->then(function () use ($self, $pluginManager, $package, $repo) {
 31910 try {
 31911 Platform::workaroundFilesystemIssues();
 31912 $pluginManager->registerPackage($package, true);
 31913 } catch (\Exception $e) {
 31914 $self->rollbackInstall($e, $repo, $package);
 31915 }
 31916 });
 31917 }
 31918 
 31919 
 31920 
 31921 
 31922 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
 31923 {
 31924 $promise = parent::update($repo, $initial, $target);
 31925 if (!$promise instanceof PromiseInterface) {
 31926 $promise = \React\Promise\resolve();
 31927 }
 31928 
 31929 $pluginManager = $this->composer->getPluginManager();
 31930 $self = $this;
 31931 
 31932 return $promise->then(function () use ($self, $pluginManager, $initial, $target, $repo) {
 31933 try {
 31934 Platform::workaroundFilesystemIssues();
 31935 $pluginManager->deactivatePackage($initial);
 31936 $pluginManager->registerPackage($target, true);
 31937 } catch (\Exception $e) {
 31938 $self->rollbackInstall($e, $repo, $target);
 31939 }
 31940 });
 31941 }
 31942 
 31943 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
 31944 {
 31945 $this->composer->getPluginManager()->uninstallPackage($package);
 31946 
 31947 return parent::uninstall($repo, $package);
 31948 }
 31949 
 31950 
 31951 
 31952 
 31953 
 31954 
 31955 
 31956 public function rollbackInstall(\Exception $e, InstalledRepositoryInterface $repo, PackageInterface $package)
 31957 {
 31958 $this->io->writeError('Plugin initialization failed ('.$e->getMessage().'), uninstalling plugin');
 31959 parent::uninstall($repo, $package);
 31960 throw $e;
 31961 }
 31962 }
 31963 <?php
 31964 
 31965 
 31966 
 31967 
 31968 
 31969 
 31970 
 31971 
 31972 
 31973 
 31974 
 31975 namespace Composer\Installer;
 31976 
 31977 use Composer\Package\PackageInterface;
 31978 use Composer\Downloader\DownloadManager;
 31979 use Composer\Repository\InstalledRepositoryInterface;
 31980 use Composer\Util\Filesystem;
 31981 
 31982 
 31983 
 31984 
 31985 
 31986 
 31987 
 31988 class ProjectInstaller implements InstallerInterface
 31989 {
 31990 
 31991 private $installPath;
 31992 
 31993 private $downloadManager;
 31994 
 31995 private $filesystem;
 31996 
 31997 
 31998 
 31999 
 32000 public function __construct($installPath, DownloadManager $dm, Filesystem $fs)
 32001 {
 32002 $this->installPath = rtrim(strtr($installPath, '\\', '/'), '/').'/';
 32003 $this->downloadManager = $dm;
 32004 $this->filesystem = $fs;
 32005 }
 32006 
 32007 
 32008 
 32009 
 32010 
 32011 
 32012 
 32013 public function supports($packageType)
 32014 {
 32015 return true;
 32016 }
 32017 
 32018 
 32019 
 32020 
 32021 public function isInstalled(InstalledRepositoryInterface $repo, PackageInterface $package)
 32022 {
 32023 return false;
 32024 }
 32025 
 32026 
 32027 
 32028 
 32029 public function download(PackageInterface $package, PackageInterface $prevPackage = null)
 32030 {
 32031 $installPath = $this->installPath;
 32032 if (file_exists($installPath) && !$this->filesystem->isDirEmpty($installPath)) {
 32033 throw new \InvalidArgumentException("Project directory $installPath is not empty.");
 32034 }
 32035 if (!is_dir($installPath)) {
 32036 mkdir($installPath, 0777, true);
 32037 }
 32038 
 32039 return $this->downloadManager->download($package, $installPath, $prevPackage);
 32040 }
 32041 
 32042 
 32043 
 32044 
 32045 public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
 32046 {
 32047 return $this->downloadManager->prepare($type, $package, $this->installPath, $prevPackage);
 32048 }
 32049 
 32050 
 32051 
 32052 
 32053 public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
 32054 {
 32055 return $this->downloadManager->cleanup($type, $package, $this->installPath, $prevPackage);
 32056 }
 32057 
 32058 
 32059 
 32060 
 32061 public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
 32062 {
 32063 return $this->downloadManager->install($package, $this->installPath);
 32064 }
 32065 
 32066 
 32067 
 32068 
 32069 public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
 32070 {
 32071 throw new \InvalidArgumentException("not supported");
 32072 }
 32073 
 32074 
 32075 
 32076 
 32077 public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
 32078 {
 32079 throw new \InvalidArgumentException("not supported");
 32080 }
 32081 
 32082 
 32083 
 32084 
 32085 
 32086 
 32087 
 32088 public function getInstallPath(PackageInterface $package)
 32089 {
 32090 return $this->installPath;
 32091 }
 32092 }
 32093 <?php
 32094 
 32095 
 32096 
 32097 
 32098 
 32099 
 32100 
 32101 
 32102 
 32103 
 32104 
 32105 namespace Composer\Installer;
 32106 
 32107 use Composer\IO\IOInterface;
 32108 use Composer\Package\PackageInterface;
 32109 use Composer\Pcre\Preg;
 32110 use Composer\Repository\InstalledRepository;
 32111 use Symfony\Component\Console\Formatter\OutputFormatter;
 32112 
 32113 
 32114 
 32115 
 32116 
 32117 
 32118 class SuggestedPackagesReporter
 32119 {
 32120 const MODE_LIST = 1;
 32121 const MODE_BY_PACKAGE = 2;
 32122 const MODE_BY_SUGGESTION = 4;
 32123 
 32124 
 32125 
 32126 
 32127 protected $suggestedPackages = array();
 32128 
 32129 
 32130 
 32131 
 32132 private $io;
 32133 
 32134 public function __construct(IOInterface $io)
 32135 {
 32136 $this->io = $io;
 32137 }
 32138 
 32139 
 32140 
 32141 
 32142 public function getPackages()
 32143 {
 32144 return $this->suggestedPackages;
 32145 }
 32146 
 32147 
 32148 
 32149 
 32150 
 32151 
 32152 
 32153 
 32154 
 32155 
 32156 
 32157 
 32158 public function addPackage($source, $target, $reason)
 32159 {
 32160 $this->suggestedPackages[] = array(
 32161 'source' => $source,
 32162 'target' => $target,
 32163 'reason' => $reason,
 32164 );
 32165 
 32166 return $this;
 32167 }
 32168 
 32169 
 32170 
 32171 
 32172 
 32173 
 32174 
 32175 public function addSuggestionsFromPackage(PackageInterface $package)
 32176 {
 32177 $source = $package->getPrettyName();
 32178 foreach ($package->getSuggests() as $target => $reason) {
 32179 $this->addPackage(
 32180 $source,
 32181 $target,
 32182 $reason
 32183 );
 32184 }
 32185 
 32186 return $this;
 32187 }
 32188 
 32189 
 32190 
 32191 
 32192 
 32193 
 32194 
 32195 
 32196 
 32197 
 32198 
 32199 public function output($mode, InstalledRepository $installedRepo = null, PackageInterface $onlyDependentsOf = null)
 32200 {
 32201 $suggestedPackages = $this->getFilteredSuggestions($installedRepo, $onlyDependentsOf);
 32202 
 32203 $suggesters = array();
 32204 $suggested = array();
 32205 foreach ($suggestedPackages as $suggestion) {
 32206 $suggesters[$suggestion['source']][$suggestion['target']] = $suggestion['reason'];
 32207 $suggested[$suggestion['target']][$suggestion['source']] = $suggestion['reason'];
 32208 }
 32209 ksort($suggesters);
 32210 ksort($suggested);
 32211 
 32212 
 32213 if ($mode & self::MODE_LIST) {
 32214 foreach (array_keys($suggested) as $name) {
 32215 $this->io->write(sprintf('<info>%s</info>', $name));
 32216 }
 32217 
 32218 return;
 32219 }
 32220 
 32221 
 32222 if ($mode & self::MODE_BY_PACKAGE) {
 32223 foreach ($suggesters as $suggester => $suggestions) {
 32224 $this->io->write(sprintf('<comment>%s</comment> suggests:', $suggester));
 32225 
 32226 foreach ($suggestions as $suggestion => $reason) {
 32227 $this->io->write(sprintf(' - <info>%s</info>' . ($reason ? ': %s' : ''), $suggestion, $this->escapeOutput($reason)));
 32228 }
 32229 $this->io->write('');
 32230 }
 32231 }
 32232 
 32233 
 32234 if ($mode & self::MODE_BY_SUGGESTION) {
 32235 
 32236 if ($mode & self::MODE_BY_PACKAGE) {
 32237 $this->io->write(str_repeat('-', 78));
 32238 }
 32239 foreach ($suggested as $suggestion => $suggesters) {
 32240 $this->io->write(sprintf('<comment>%s</comment> is suggested by:', $suggestion));
 32241 
 32242 foreach ($suggesters as $suggester => $reason) {
 32243 $this->io->write(sprintf(' - <info>%s</info>' . ($reason ? ': %s' : ''), $suggester, $this->escapeOutput($reason)));
 32244 }
 32245 $this->io->write('');
 32246 }
 32247 }
 32248 
 32249 if ($onlyDependentsOf) {
 32250 $allSuggestedPackages = $this->getFilteredSuggestions($installedRepo);
 32251 $diff = count($allSuggestedPackages) - count($suggestedPackages);
 32252 if ($diff) {
 32253 $this->io->write('<info>'.$diff.' additional suggestions</info> by transitive dependencies can be shown with <info>--all</info>');
 32254 }
 32255 }
 32256 }
 32257 
 32258 
 32259 
 32260 
 32261 
 32262 
 32263 
 32264 
 32265 public function outputMinimalistic(InstalledRepository $installedRepo = null, PackageInterface $onlyDependentsOf = null)
 32266 {
 32267 $suggestedPackages = $this->getFilteredSuggestions($installedRepo, $onlyDependentsOf);
 32268 if ($suggestedPackages) {
 32269 $this->io->writeError('<info>'.count($suggestedPackages).' package suggestions were added by new dependencies, use `composer suggest` to see details.</info>');
 32270 }
 32271 }
 32272 
 32273 
 32274 
 32275 
 32276 
 32277 
 32278 private function getFilteredSuggestions(InstalledRepository $installedRepo = null, PackageInterface $onlyDependentsOf = null)
 32279 {
 32280 $suggestedPackages = $this->getPackages();
 32281 $installedNames = array();
 32282 if (null !== $installedRepo && !empty($suggestedPackages)) {
 32283 foreach ($installedRepo->getPackages() as $package) {
 32284 $installedNames = array_merge(
 32285 $installedNames,
 32286 $package->getNames()
 32287 );
 32288 }
 32289 }
 32290 
 32291 $sourceFilter = array();
 32292 if ($onlyDependentsOf) {
 32293 $sourceFilter = array_map(function ($link) {
 32294 return $link->getTarget();
 32295 }, array_merge($onlyDependentsOf->getRequires(), $onlyDependentsOf->getDevRequires()));
 32296 $sourceFilter[] = $onlyDependentsOf->getName();
 32297 }
 32298 
 32299 $suggestions = array();
 32300 foreach ($suggestedPackages as $suggestion) {
 32301 if (in_array($suggestion['target'], $installedNames) || ($sourceFilter && !in_array($suggestion['source'], $sourceFilter))) {
 32302 continue;
 32303 }
 32304 
 32305 $suggestions[] = $suggestion;
 32306 }
 32307 
 32308 return $suggestions;
 32309 }
 32310 
 32311 
 32312 
 32313 
 32314 
 32315 private function escapeOutput($string)
 32316 {
 32317 return OutputFormatter::escape(
 32318 $this->removeControlCharacters($string)
 32319 );
 32320 }
 32321 
 32322 
 32323 
 32324 
 32325 
 32326 private function removeControlCharacters($string)
 32327 {
 32328 return Preg::replace(
 32329 '/[[:cntrl:]]/',
 32330 '',
 32331 str_replace("\n", ' ', $string)
 32332 );
 32333 }
 32334 }
 32335 <?php
 32336 
 32337 
 32338 
 32339 
 32340 
 32341 
 32342 
 32343 
 32344 
 32345 
 32346 
 32347 namespace Composer\Json;
 32348 
 32349 use Composer\Pcre\Preg;
 32350 use JsonSchema\Validator;
 32351 use Seld\JsonLint\JsonParser;
 32352 use Seld\JsonLint\ParsingException;
 32353 use Composer\Util\HttpDownloader;
 32354 use Composer\IO\IOInterface;
 32355 use Composer\Downloader\TransportException;
 32356 
 32357 
 32358 
 32359 
 32360 
 32361 
 32362 
 32363 class JsonFile
 32364 {
 32365 const LAX_SCHEMA = 1;
 32366 const STRICT_SCHEMA = 2;
 32367 
 32368 const JSON_UNESCAPED_SLASHES = 64;
 32369 const JSON_PRETTY_PRINT = 128;
 32370 const JSON_UNESCAPED_UNICODE = 256;
 32371 
 32372 const COMPOSER_SCHEMA_PATH = '/../../../res/composer-schema.json';
 32373 
 32374 
 32375 private $path;
 32376 
 32377 private $httpDownloader;
 32378 
 32379 private $io;
 32380 
 32381 
 32382 
 32383 
 32384 
 32385 
 32386 
 32387 
 32388 
 32389 public function __construct($path, HttpDownloader $httpDownloader = null, IOInterface $io = null)
 32390 {
 32391 $this->path = $path;
 32392 
 32393 if (null === $httpDownloader && Preg::isMatch('{^https?://}i', $path)) {
 32394 throw new \InvalidArgumentException('http urls require a HttpDownloader instance to be passed');
 32395 }
 32396 $this->httpDownloader = $httpDownloader;
 32397 $this->io = $io;
 32398 }
 32399 
 32400 
 32401 
 32402 
 32403 public function getPath()
 32404 {
 32405 return $this->path;
 32406 }
 32407 
 32408 
 32409 
 32410 
 32411 
 32412 
 32413 public function exists()
 32414 {
 32415 return is_file($this->path);
 32416 }
 32417 
 32418 
 32419 
 32420 
 32421 
 32422 
 32423 
 32424 
 32425 public function read()
 32426 {
 32427 try {
 32428 if ($this->httpDownloader) {
 32429 $json = $this->httpDownloader->get($this->path)->getBody();
 32430 } else {
 32431 if ($this->io && $this->io->isDebug()) {
 32432 $realpathInfo = '';
 32433 $realpath = realpath($this->path);
 32434 if (false !== $realpath && $realpath !== $this->path) {
 32435 $realpathInfo = ' (' . $realpath . ')';
 32436 }
 32437 $this->io->writeError('Reading ' . $this->path . $realpathInfo);
 32438 }
 32439 $json = file_get_contents($this->path);
 32440 }
 32441 } catch (TransportException $e) {
 32442 throw new \RuntimeException($e->getMessage(), 0, $e);
 32443 } catch (\Exception $e) {
 32444 throw new \RuntimeException('Could not read '.$this->path."\n\n".$e->getMessage());
 32445 }
 32446 
 32447 return static::parseJson($json, $this->path);
 32448 }
 32449 
 32450 
 32451 
 32452 
 32453 
 32454 
 32455 
 32456 
 32457 
 32458 public function write(array $hash, $options = 448)
 32459 {
 32460 if ($this->path === 'php://memory') {
 32461 file_put_contents($this->path, static::encode($hash, $options));
 32462 
 32463 return;
 32464 }
 32465 
 32466 $dir = dirname($this->path);
 32467 if (!is_dir($dir)) {
 32468 if (file_exists($dir)) {
 32469 throw new \UnexpectedValueException(
 32470 realpath($dir).' exists and is not a directory.'
 32471 );
 32472 }
 32473 if (!@mkdir($dir, 0777, true)) {
 32474 throw new \UnexpectedValueException(
 32475 $dir.' does not exist and could not be created.'
 32476 );
 32477 }
 32478 }
 32479 
 32480 $retries = 3;
 32481 while ($retries--) {
 32482 try {
 32483 $this->filePutContentsIfModified($this->path, static::encode($hash, $options). ($options & self::JSON_PRETTY_PRINT ? "\n" : ''));
 32484 break;
 32485 } catch (\Exception $e) {
 32486 if ($retries > 0) {
 32487 usleep(500000);
 32488 continue;
 32489 }
 32490 
 32491 throw $e;
 32492 }
 32493 }
 32494 }
 32495 
 32496 
 32497 
 32498 
 32499 
 32500 
 32501 
 32502 
 32503 private function filePutContentsIfModified($path, $content)
 32504 {
 32505 $currentContent = @file_get_contents($path);
 32506 if (!$currentContent || ($currentContent != $content)) {
 32507 return file_put_contents($path, $content);
 32508 }
 32509 
 32510 return 0;
 32511 }
 32512 
 32513 
 32514 
 32515 
 32516 
 32517 
 32518 
 32519 
 32520 
 32521 
 32522 public function validateSchema($schema = self::STRICT_SCHEMA, $schemaFile = null)
 32523 {
 32524 $content = file_get_contents($this->path);
 32525 $data = json_decode($content);
 32526 
 32527 if (null === $data && 'null' !== $content) {
 32528 self::validateSyntax($content, $this->path);
 32529 }
 32530 
 32531 $isComposerSchemaFile = false;
 32532 if (null === $schemaFile) {
 32533 $isComposerSchemaFile = true;
 32534 $schemaFile = __DIR__ . self::COMPOSER_SCHEMA_PATH;
 32535 }
 32536 
 32537 
 32538 if (false === strpos($schemaFile, '://')) {
 32539 $schemaFile = 'file://' . $schemaFile;
 32540 }
 32541 
 32542 $schemaData = (object) array('$ref' => $schemaFile);
 32543 
 32544 if ($schema === self::LAX_SCHEMA) {
 32545 $schemaData->additionalProperties = true;
 32546 $schemaData->required = array();
 32547 } elseif ($schema === self::STRICT_SCHEMA && $isComposerSchemaFile) {
 32548 $schemaData->additionalProperties = false;
 32549 $schemaData->required = array('name', 'description');
 32550 }
 32551 
 32552 $validator = new Validator();
 32553 $validator->check($data, $schemaData);
 32554 
 32555 if (!$validator->isValid()) {
 32556 $errors = array();
 32557 foreach ((array) $validator->getErrors() as $error) {
 32558 $errors[] = ($error['property'] ? $error['property'].' : ' : '').$error['message'];
 32559 }
 32560 throw new JsonValidationException('"'.$this->path.'" does not match the expected JSON schema', $errors);
 32561 }
 32562 
 32563 return true;
 32564 }
 32565 
 32566 
 32567 
 32568 
 32569 
 32570 
 32571 
 32572 
 32573 public static function encode($data, $options = 448)
 32574 {
 32575 if (PHP_VERSION_ID >= 50400) {
 32576 $json = json_encode($data, $options);
 32577 if (false === $json) {
 32578 self::throwEncodeError(json_last_error());
 32579 }
 32580 
 32581 
 32582 if (PHP_VERSION_ID < 50428 || (PHP_VERSION_ID >= 50500 && PHP_VERSION_ID < 50512) || (defined('JSON_C_VERSION') && version_compare(phpversion('json'), '1.3.6', '<'))) {
 32583 $json = Preg::replace('/\[\s+\]/', '[]', $json);
 32584 $json = Preg::replace('/\{\s+\}/', '{}', $json);
 32585 }
 32586 
 32587 return $json;
 32588 }
 32589 
 32590 $json = json_encode($data);
 32591 if (false === $json) {
 32592 self::throwEncodeError(json_last_error());
 32593 }
 32594 
 32595 $prettyPrint = (bool) ($options & self::JSON_PRETTY_PRINT);
 32596 $unescapeUnicode = (bool) ($options & self::JSON_UNESCAPED_UNICODE);
 32597 $unescapeSlashes = (bool) ($options & self::JSON_UNESCAPED_SLASHES);
 32598 
 32599 if (!$prettyPrint && !$unescapeUnicode && !$unescapeSlashes) {
 32600 return $json;
 32601 }
 32602 
 32603 return JsonFormatter::format($json, $unescapeUnicode, $unescapeSlashes);
 32604 }
 32605 
 32606 
 32607 
 32608 
 32609 
 32610 
 32611 
 32612 
 32613 private static function throwEncodeError($code)
 32614 {
 32615 switch ($code) {
 32616 case JSON_ERROR_DEPTH:
 32617 $msg = 'Maximum stack depth exceeded';
 32618 break;
 32619 case JSON_ERROR_STATE_MISMATCH:
 32620 $msg = 'Underflow or the modes mismatch';
 32621 break;
 32622 case JSON_ERROR_CTRL_CHAR:
 32623 $msg = 'Unexpected control character found';
 32624 break;
 32625 case JSON_ERROR_UTF8:
 32626 $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
 32627 break;
 32628 default:
 32629 $msg = 'Unknown error';
 32630 }
 32631 
 32632 throw new \RuntimeException('JSON encoding failed: '.$msg);
 32633 }
 32634 
 32635 
 32636 
 32637 
 32638 
 32639 
 32640 
 32641 
 32642 
 32643 
 32644 public static function parseJson($json, $file = null)
 32645 {
 32646 if (null === $json) {
 32647 return null;
 32648 }
 32649 $data = json_decode($json, true);
 32650 if (null === $data && JSON_ERROR_NONE !== json_last_error()) {
 32651 self::validateSyntax($json, $file);
 32652 }
 32653 
 32654 return $data;
 32655 }
 32656 
 32657 
 32658 
 32659 
 32660 
 32661 
 32662 
 32663 
 32664 
 32665 
 32666 protected static function validateSyntax($json, $file = null)
 32667 {
 32668 $parser = new JsonParser();
 32669 $result = $parser->lint($json);
 32670 if (null === $result) {
 32671 if (defined('JSON_ERROR_UTF8') && JSON_ERROR_UTF8 === json_last_error()) {
 32672 throw new \UnexpectedValueException('"'.$file.'" is not UTF-8, could not parse as JSON');
 32673 }
 32674 
 32675 return true;
 32676 }
 32677 
 32678 throw new ParsingException('"'.$file.'" does not contain valid JSON'."\n".$result->getMessage(), $result->getDetails());
 32679 }
 32680 }
 32681 <?php
 32682 
 32683 
 32684 
 32685 
 32686 
 32687 
 32688 
 32689 
 32690 
 32691 
 32692 
 32693 namespace Composer\Json;
 32694 
 32695 use Composer\Pcre\Preg;
 32696 
 32697 
 32698 
 32699 
 32700 
 32701 
 32702 
 32703 
 32704 
 32705 class JsonFormatter
 32706 {
 32707 
 32708 
 32709 
 32710 
 32711 
 32712 
 32713 
 32714 
 32715 
 32716 
 32717 
 32718 
 32719 public static function format($json, $unescapeUnicode, $unescapeSlashes)
 32720 {
 32721 $result = '';
 32722 $pos = 0;
 32723 $strLen = strlen($json);
 32724 $indentStr = '    ';
 32725 $newLine = "\n";
 32726 $outOfQuotes = true;
 32727 $buffer = '';
 32728 $noescape = true;
 32729 
 32730 for ($i = 0; $i < $strLen; $i++) {
 32731 
 32732 $char = substr($json, $i, 1);
 32733 
 32734 
 32735 if ('"' === $char && $noescape) {
 32736 $outOfQuotes = !$outOfQuotes;
 32737 }
 32738 
 32739 if (!$outOfQuotes) {
 32740 $buffer .= $char;
 32741 $noescape = '\\' === $char ? !$noescape : true;
 32742 continue;
 32743 }
 32744 if ('' !== $buffer) {
 32745 if ($unescapeSlashes) {
 32746 $buffer = str_replace('\\/', '/', $buffer);
 32747 }
 32748 
 32749 if ($unescapeUnicode && function_exists('mb_convert_encoding')) {
 32750 
 32751 $buffer = Preg::replaceCallback('/(\\\\+)u([0-9a-f]{4})/i', function ($match) {
 32752 $l = strlen($match[1]);
 32753 
 32754 if ($l % 2) {
 32755 $code = hexdec($match[2]);
 32756 
 32757 
 32758 if (0xD800 <= $code && 0xDFFF >= $code) {
 32759 return $match[0];
 32760 }
 32761 
 32762 return str_repeat('\\', $l - 1) . mb_convert_encoding(
 32763 pack('H*', $match[2]),
 32764 'UTF-8',
 32765 'UCS-2BE'
 32766 );
 32767 }
 32768 
 32769 return $match[0];
 32770 }, $buffer);
 32771 }
 32772 
 32773 $result .= $buffer.$char;
 32774 $buffer = '';
 32775 continue;
 32776 }
 32777 
 32778 if (':' === $char) {
 32779 
 32780 $char .= ' ';
 32781 } elseif ('}' === $char || ']' === $char) {
 32782 $pos--;
 32783 $prevChar = substr($json, $i - 1, 1);
 32784 
 32785 if ('{' !== $prevChar && '[' !== $prevChar) {
 32786 
 32787 
 32788 $result .= $newLine;
 32789 for ($j = 0; $j < $pos; $j++) {
 32790 $result .= $indentStr;
 32791 }
 32792 } else {
 32793 
 32794 $result = rtrim($result);
 32795 }
 32796 }
 32797 
 32798 $result .= $char;
 32799 
 32800 
 32801 
 32802 if (',' === $char || '{' === $char || '[' === $char) {
 32803 $result .= $newLine;
 32804 
 32805 if ('{' === $char || '[' === $char) {
 32806 $pos++;
 32807 }
 32808 
 32809 for ($j = 0; $j < $pos; $j++) {
 32810 $result .= $indentStr;
 32811 }
 32812 }
 32813 }
 32814 
 32815 return $result;
 32816 }
 32817 }
 32818 <?php
 32819 
 32820 
 32821 
 32822 
 32823 
 32824 
 32825 
 32826 
 32827 
 32828 
 32829 
 32830 namespace Composer\Json;
 32831 
 32832 use Composer\Pcre\Preg;
 32833 use Composer\Repository\PlatformRepository;
 32834 
 32835 
 32836 
 32837 
 32838 class JsonManipulator
 32839 {
 32840 
 32841 private static $DEFINES = '(?(DEFINE)
 32842        (?<number>    -? (?= [1-9]|0(?!\d) ) \d++ (\.\d++)? ([eE] [+-]?+ \d++)? )
 32843        (?<boolean>   true | false | null )
 32844        (?<string>    " ([^"\\\\]*+ | \\\\ ["\\\\bfnrt\/] | \\\\ u [0-9A-Fa-f]{4} )* " )
 32845        (?<array>     \[  (?:  (?&json) \s*+ (?: , (?&json) \s*+ )*+  )?+  \s*+ \] )
 32846        (?<pair>      \s*+ (?&string) \s*+ : (?&json) \s*+ )
 32847        (?<object>    \{  (?:  (?&pair)  (?: , (?&pair)  )*+  )?+  \s*+ \} )
 32848        (?<json>      \s*+ (?: (?&number) | (?&boolean) | (?&string) | (?&array) | (?&object) ) )
 32849     )';
 32850 
 32851 
 32852 private $contents;
 32853 
 32854 private $newline;
 32855 
 32856 private $indent;
 32857 
 32858 
 32859 
 32860 
 32861 public function __construct($contents)
 32862 {
 32863 $contents = trim($contents);
 32864 if ($contents === '') {
 32865 $contents = '{}';
 32866 }
 32867 if (!Preg::isMatch('#^\{(.*)\}$#s', $contents)) {
 32868 throw new \InvalidArgumentException('The json file must be an object ({})');
 32869 }
 32870 $this->newline = false !== strpos($contents, "\r\n") ? "\r\n" : "\n";
 32871 $this->contents = $contents === '{}' ? '{' . $this->newline . '}' : $contents;
 32872 $this->detectIndenting();
 32873 }
 32874 
 32875 
 32876 
 32877 
 32878 public function getContents()
 32879 {
 32880 return $this->contents . $this->newline;
 32881 }
 32882 
 32883 
 32884 
 32885 
 32886 
 32887 
 32888 
 32889 
 32890 public function addLink($type, $package, $constraint, $sortPackages = false)
 32891 {
 32892 $decoded = JsonFile::parseJson($this->contents);
 32893 
 32894 
 32895 if (!isset($decoded[$type])) {
 32896 return $this->addMainKey($type, array($package => $constraint));
 32897 }
 32898 
 32899 $regex = '{'.self::$DEFINES.'^(?P<start>\s*\{\s*(?:(?&string)\s*:\s*(?&json)\s*,\s*)*?)'.
 32900 '(?P<property>'.preg_quote(JsonFile::encode($type)).'\s*:\s*)(?P<value>(?&json))(?P<end>.*)}sx';
 32901 if (!Preg::isMatch($regex, $this->contents, $matches)) {
 32902 return false;
 32903 }
 32904 
 32905 $links = $matches['value'];
 32906 
 32907 
 32908 $packageRegex = str_replace('/', '\\\\?/', preg_quote($package));
 32909 $regex = '{'.self::$DEFINES.'"(?P<package>'.$packageRegex.')"(\s*:\s*)(?&string)}ix';
 32910 if (Preg::isMatch($regex, $links, $packageMatches)) {
 32911 
 32912 $existingPackage = $packageMatches['package'];
 32913 $packageRegex = str_replace('/', '\\\\?/', preg_quote($existingPackage));
 32914 $links = Preg::replaceCallback('{'.self::$DEFINES.'"'.$packageRegex.'"(?P<separator>\s*:\s*)(?&string)}ix', function ($m) use ($existingPackage, $constraint) {
 32915 return JsonFile::encode(str_replace('\\/', '/', $existingPackage)) . $m['separator'] . '"' . $constraint . '"';
 32916 }, $links);
 32917 } else {
 32918 if (Preg::isMatch('#^\s*\{\s*\S+.*?(\s*\}\s*)$#s', $links, $match)) {
 32919 
 32920 $links = Preg::replace(
 32921 '{'.preg_quote($match[1]).'$}',
 32922 
 32923 addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $match[1], '\\$'),
 32924 $links
 32925 );
 32926 } else {
 32927 
 32928 $links = '{' . $this->newline .
 32929 $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $this->newline .
 32930 $this->indent . '}';
 32931 }
 32932 }
 32933 
 32934 if (true === $sortPackages) {
 32935 $requirements = json_decode($links, true);
 32936 $this->sortPackages($requirements);
 32937 $links = $this->format($requirements);
 32938 }
 32939 
 32940 $this->contents = $matches['start'] . $matches['property'] . $links . $matches['end'];
 32941 
 32942 return true;
 32943 }
 32944 
 32945 
 32946 
 32947 
 32948 
 32949 
 32950 
 32951 
 32952 
 32953 private function sortPackages(array &$packages = array())
 32954 {
 32955 $prefix = function ($requirement) {
 32956 if (PlatformRepository::isPlatformPackage($requirement)) {
 32957 return Preg::replace(
 32958 array(
 32959 '/^php/',
 32960 '/^hhvm/',
 32961 '/^ext/',
 32962 '/^lib/',
 32963 '/^\D/',
 32964 ),
 32965 array(
 32966 '0-$0',
 32967 '1-$0',
 32968 '2-$0',
 32969 '3-$0',
 32970 '4-$0',
 32971 ),
 32972 $requirement
 32973 );
 32974 }
 32975 
 32976 return '5-'.$requirement;
 32977 };
 32978 
 32979 uksort($packages, function ($a, $b) use ($prefix) {
 32980 return strnatcmp($prefix($a), $prefix($b));
 32981 });
 32982 }
 32983 
 32984 
 32985 
 32986 
 32987 
 32988 
 32989 
 32990 public function addRepository($name, $config, $append = true)
 32991 {
 32992 return $this->addSubNode('repositories', $name, $config, $append);
 32993 }
 32994 
 32995 
 32996 
 32997 
 32998 
 32999 public function removeRepository($name)
 33000 {
 33001 return $this->removeSubNode('repositories', $name);
 33002 }
 33003 
 33004 
 33005 
 33006 
 33007 
 33008 
 33009 public function addConfigSetting($name, $value)
 33010 {
 33011 return $this->addSubNode('config', $name, $value);
 33012 }
 33013 
 33014 
 33015 
 33016 
 33017 
 33018 public function removeConfigSetting($name)
 33019 {
 33020 return $this->removeSubNode('config', $name);
 33021 }
 33022 
 33023 
 33024 
 33025 
 33026 
 33027 
 33028 public function addProperty($name, $value)
 33029 {
 33030 if (strpos($name, 'suggest.') === 0) {
 33031 return $this->addSubNode('suggest', substr($name, 8), $value);
 33032 }
 33033 
 33034 if (strpos($name, 'extra.') === 0) {
 33035 return $this->addSubNode('extra', substr($name, 6), $value);
 33036 }
 33037 
 33038 if (strpos($name, 'scripts.') === 0) {
 33039 return $this->addSubNode('scripts', substr($name, 8), $value);
 33040 }
 33041 
 33042 return $this->addMainKey($name, $value);
 33043 }
 33044 
 33045 
 33046 
 33047 
 33048 
 33049 public function removeProperty($name)
 33050 {
 33051 if (strpos($name, 'suggest.') === 0) {
 33052 return $this->removeSubNode('suggest', substr($name, 8));
 33053 }
 33054 
 33055 if (strpos($name, 'extra.') === 0) {
 33056 return $this->removeSubNode('extra', substr($name, 6));
 33057 }
 33058 
 33059 if (strpos($name, 'scripts.') === 0) {
 33060 return $this->removeSubNode('scripts', substr($name, 8));
 33061 }
 33062 
 33063 return $this->removeMainKey($name);
 33064 }
 33065 
 33066 
 33067 
 33068 
 33069 
 33070 
 33071 
 33072 
 33073 public function addSubNode($mainNode, $name, $value, $append = true)
 33074 {
 33075 $decoded = JsonFile::parseJson($this->contents);
 33076 
 33077 $subName = null;
 33078 if (in_array($mainNode, array('config', 'extra', 'scripts')) && false !== strpos($name, '.')) {
 33079 list($name, $subName) = explode('.', $name, 2);
 33080 }
 33081 
 33082 
 33083 if (!isset($decoded[$mainNode])) {
 33084 if ($subName !== null) {
 33085 $this->addMainKey($mainNode, array($name => array($subName => $value)));
 33086 } else {
 33087 $this->addMainKey($mainNode, array($name => $value));
 33088 }
 33089 
 33090 return true;
 33091 }
 33092 
 33093 
 33094 $nodeRegex = '{'.self::$DEFINES.'^(?P<start> \s* \{ \s* (?: (?&string) \s* : (?&json) \s* , \s* )*?'.
 33095 preg_quote(JsonFile::encode($mainNode)).'\s*:\s*)(?P<content>(?&object))(?P<end>.*)}sx';
 33096 
 33097 try {
 33098 if (!Preg::isMatch($nodeRegex, $this->contents, $match)) {
 33099 return false;
 33100 }
 33101 } catch (\RuntimeException $e) {
 33102 if ($e->getCode() === PREG_BACKTRACK_LIMIT_ERROR) {
 33103 return false;
 33104 }
 33105 throw $e;
 33106 }
 33107 
 33108 $children = $match['content'];
 33109 
 33110 if (!@json_decode($children)) {
 33111 return false;
 33112 }
 33113 
 33114 $that = $this;
 33115 
 33116 
 33117 $childRegex = '{'.self::$DEFINES.'(?P<start>"'.preg_quote($name).'"\s*:\s*)(?P<content>(?&json))(?P<end>,?)}x';
 33118 if (Preg::isMatch($childRegex, $children, $matches)) {
 33119 $children = Preg::replaceCallback($childRegex, function ($matches) use ($subName, $value, $that) {
 33120 if ($subName !== null) {
 33121 $curVal = json_decode($matches['content'], true);
 33122 if (!is_array($curVal)) {
 33123 $curVal = array();
 33124 }
 33125 $curVal[$subName] = $value;
 33126 $value = $curVal;
 33127 }
 33128 
 33129 return $matches['start'] . $that->format($value, 1) . $matches['end'];
 33130 }, $children);
 33131 } else {
 33132 Preg::match('#^{ (?P<leadingspace>\s*?) (?P<content>\S+.*?)? (?P<trailingspace>\s*) }$#sx', $children, $match);
 33133 
 33134 $whitespace = '';
 33135 if (!empty($match['trailingspace'])) {
 33136 $whitespace = $match['trailingspace'];
 33137 }
 33138 
 33139 if (!empty($match['content'])) {
 33140 if ($subName !== null) {
 33141 $value = array($subName => $value);
 33142 }
 33143 
 33144 
 33145 if ($append) {
 33146 $children = Preg::replace(
 33147 '#'.$whitespace.'}$#',
 33148 addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $whitespace . '}', '\\$'),
 33149 $children
 33150 );
 33151 } else {
 33152 $whitespace = '';
 33153 if (!empty($match['leadingspace'])) {
 33154 $whitespace = $match['leadingspace'];
 33155 }
 33156 
 33157 $children = Preg::replace(
 33158 '#^{'.$whitespace.'#',
 33159 addcslashes('{' . $whitespace . JsonFile::encode($name).': '.$this->format($value, 1) . ',' . $this->newline . $this->indent . $this->indent, '\\$'),
 33160 $children
 33161 );
 33162 }
 33163 } else {
 33164 if ($subName !== null) {
 33165 $value = array($subName => $value);
 33166 }
 33167 
 33168 
 33169 $children = '{' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $whitespace . '}';
 33170 }
 33171 }
 33172 
 33173 $this->contents = Preg::replaceCallback($nodeRegex, function ($m) use ($children) {
 33174 return $m['start'] . $children . $m['end'];
 33175 }, $this->contents);
 33176 
 33177 return true;
 33178 }
 33179 
 33180 
 33181 
 33182 
 33183 
 33184 
 33185 public function removeSubNode($mainNode, $name)
 33186 {
 33187 $decoded = JsonFile::parseJson($this->contents);
 33188 
 33189 
 33190 if (empty($decoded[$mainNode])) {
 33191 return true;
 33192 }
 33193 
 33194 
 33195 $nodeRegex = '{'.self::$DEFINES.'^(?P<start> \s* \{ \s* (?: (?&string) \s* : (?&json) \s* , \s* )*?'.
 33196 preg_quote(JsonFile::encode($mainNode)).'\s*:\s*)(?P<content>(?&object))(?P<end>.*)}sx';
 33197 try {
 33198 if (!Preg::isMatch($nodeRegex, $this->contents, $match)) {
 33199 return false;
 33200 }
 33201 } catch (\RuntimeException $e) {
 33202 if ($e->getCode() === PREG_BACKTRACK_LIMIT_ERROR) {
 33203 return false;
 33204 }
 33205 throw $e;
 33206 }
 33207 
 33208 $children = $match['content'];
 33209 
 33210 
 33211 if (!@json_decode($children, true)) {
 33212 return false;
 33213 }
 33214 
 33215 $subName = null;
 33216 if (in_array($mainNode, array('config', 'extra', 'scripts')) && false !== strpos($name, '.')) {
 33217 list($name, $subName) = explode('.', $name, 2);
 33218 }
 33219 
 33220 
 33221 if (!isset($decoded[$mainNode][$name]) || ($subName && !isset($decoded[$mainNode][$name][$subName]))) {
 33222 return true;
 33223 }
 33224 
 33225 
 33226 $keyRegex = str_replace('/', '\\\\?/', preg_quote($name));
 33227 if (Preg::isMatch('{"'.$keyRegex.'"\s*:}i', $children)) {
 33228 
 33229 if (Preg::isMatchAll('{'.self::$DEFINES.'"'.$keyRegex.'"\s*:\s*(?:(?&json))}x', $children, $matches)) {
 33230 $bestMatch = '';
 33231 foreach ($matches[0] as $match) {
 33232 if (strlen($bestMatch) < strlen($match)) {
 33233 $bestMatch = $match;
 33234 }
 33235 }
 33236 $childrenClean = Preg::replace('{,\s*'.preg_quote($bestMatch).'}i', '', $children, -1, $count);
 33237 if (1 !== $count) {
 33238 $childrenClean = Preg::replace('{'.preg_quote($bestMatch).'\s*,?\s*}i', '', $childrenClean, -1, $count);
 33239 if (1 !== $count) {
 33240 return false;
 33241 }
 33242 }
 33243 }
 33244 } else {
 33245 $childrenClean = $children;
 33246 }
 33247 
 33248 if (!isset($childrenClean)) {
 33249 throw new \InvalidArgumentException("JsonManipulator: \$childrenClean is not defined. Please report at https://github.com/composer/composer/issues/new.");
 33250 }
 33251 
 33252 
 33253 Preg::match('#^{ \s*? (?P<content>\S+.*?)? (?P<trailingspace>\s*) }$#sx', $childrenClean, $match);
 33254 if (empty($match['content'])) {
 33255 $newline = $this->newline;
 33256 $indent = $this->indent;
 33257 
 33258 $this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($indent, $newline) {
 33259 return $matches['start'] . '{' . $newline . $indent . '}' . $matches['end'];
 33260 }, $this->contents);
 33261 
 33262 
 33263 if ($subName !== null) {
 33264 $curVal = json_decode($children, true);
 33265 unset($curVal[$name][$subName]);
 33266 $this->addSubNode($mainNode, $name, $curVal[$name]);
 33267 }
 33268 
 33269 return true;
 33270 }
 33271 
 33272 $that = $this;
 33273 $this->contents = Preg::replaceCallback($nodeRegex, function ($matches) use ($that, $name, $subName, $childrenClean) {
 33274 if ($subName !== null) {
 33275 $curVal = json_decode($matches['content'], true);
 33276 unset($curVal[$name][$subName]);
 33277 $childrenClean = $that->format($curVal);
 33278 }
 33279 
 33280 return $matches['start'] . $childrenClean . $matches['end'];
 33281 }, $this->contents);
 33282 
 33283 return true;
 33284 }
 33285 
 33286 
 33287 
 33288 
 33289 
 33290 
 33291 public function addMainKey($key, $content)
 33292 {
 33293 $decoded = JsonFile::parseJson($this->contents);
 33294 $content = $this->format($content);
 33295 
 33296 
 33297 $regex = '{'.self::$DEFINES.'^(?P<start>\s*\{\s*(?:(?&string)\s*:\s*(?&json)\s*,\s*)*?)'.
 33298 '(?P<key>'.preg_quote(JsonFile::encode($key)).'\s*:\s*(?&json))(?P<end>.*)}sx';
 33299 if (isset($decoded[$key]) && Preg::isMatch($regex, $this->contents, $matches)) {
 33300 
 33301 if (!@json_decode('{'.$matches['key'].'}')) {
 33302 return false;
 33303 }
 33304 
 33305 $this->contents = $matches['start'] . JsonFile::encode($key).': '.$content . $matches['end'];
 33306 
 33307 return true;
 33308 }
 33309 
 33310 
 33311 if (Preg::isMatch('#[^{\s](\s*)\}$#', $this->contents, $match)) {
 33312 $this->contents = Preg::replace(
 33313 '#'.$match[1].'\}$#',
 33314 addcslashes(',' . $this->newline . $this->indent . JsonFile::encode($key). ': '. $content . $this->newline . '}', '\\$'),
 33315 $this->contents
 33316 );
 33317 
 33318 return true;
 33319 }
 33320 
 33321 
 33322 $this->contents = Preg::replace(
 33323 '#\}$#',
 33324 addcslashes($this->indent . JsonFile::encode($key). ': '.$content . $this->newline . '}', '\\$'),
 33325 $this->contents
 33326 );
 33327 
 33328 return true;
 33329 }
 33330 
 33331 
 33332 
 33333 
 33334 
 33335 public function removeMainKey($key)
 33336 {
 33337 $decoded = JsonFile::parseJson($this->contents);
 33338 
 33339 if (!array_key_exists($key, $decoded)) {
 33340 return true;
 33341 }
 33342 
 33343 
 33344 $regex = '{'.self::$DEFINES.'^(?P<start>\s*\{\s*(?:(?&string)\s*:\s*(?&json)\s*,\s*)*?)'.
 33345 '(?P<removal>'.preg_quote(JsonFile::encode($key)).'\s*:\s*(?&json))\s*,?\s*(?P<end>.*)}sx';
 33346 if (Preg::isMatch($regex, $this->contents, $matches)) {
 33347 
 33348 if (!@json_decode('{'.$matches['removal'].'}')) {
 33349 return false;
 33350 }
 33351 
 33352 
 33353 if (Preg::isMatch('#,\s*$#', $matches['start']) && Preg::isMatch('#^\}$#', $matches['end'])) {
 33354 $matches['start'] = rtrim(Preg::replace('#,(\s*)$#', '$1', $matches['start']), $this->indent);
 33355 }
 33356 
 33357 $this->contents = $matches['start'] . $matches['end'];
 33358 if (Preg::isMatch('#^\{\s*\}\s*$#', $this->contents)) {
 33359 $this->contents = "{\n}";
 33360 }
 33361 
 33362 return true;
 33363 }
 33364 
 33365 return false;
 33366 }
 33367 
 33368 
 33369 
 33370 
 33371 
 33372 public function removeMainKeyIfEmpty($key)
 33373 {
 33374 $decoded = JsonFile::parseJson($this->contents);
 33375 
 33376 if (!array_key_exists($key, $decoded)) {
 33377 return true;
 33378 }
 33379 
 33380 if (is_array($decoded[$key]) && count($decoded[$key]) === 0) {
 33381 return $this->removeMainKey($key);
 33382 }
 33383 
 33384 return true;
 33385 }
 33386 
 33387 
 33388 
 33389 
 33390 
 33391 
 33392 public function format($data, $depth = 0)
 33393 {
 33394 if (is_array($data)) {
 33395 reset($data);
 33396 
 33397 if (is_numeric(key($data))) {
 33398 foreach ($data as $key => $val) {
 33399 $data[$key] = $this->format($val, $depth + 1);
 33400 }
 33401 
 33402 return '['.implode(', ', $data).']';
 33403 }
 33404 
 33405 $out = '{' . $this->newline;
 33406 $elems = array();
 33407 foreach ($data as $key => $val) {
 33408 $elems[] = str_repeat($this->indent, $depth + 2) . JsonFile::encode($key). ': '.$this->format($val, $depth + 1);
 33409 }
 33410 
 33411 return $out . implode(','.$this->newline, $elems) . $this->newline . str_repeat($this->indent, $depth + 1) . '}';
 33412 }
 33413 
 33414 return JsonFile::encode($data);
 33415 }
 33416 
 33417 
 33418 
 33419 
 33420 protected function detectIndenting()
 33421 {
 33422 if (Preg::isMatch('{^([ \t]+)"}m', $this->contents, $match)) {
 33423 $this->indent = $match[1];
 33424 } else {
 33425 $this->indent = '    ';
 33426 }
 33427 }
 33428 }
 33429 <?php
 33430 
 33431 
 33432 
 33433 
 33434 
 33435 
 33436 
 33437 
 33438 
 33439 
 33440 
 33441 namespace Composer\Json;
 33442 
 33443 use Exception;
 33444 
 33445 
 33446 
 33447 
 33448 class JsonValidationException extends Exception
 33449 {
 33450 
 33451 
 33452 
 33453 protected $errors;
 33454 
 33455 
 33456 
 33457 
 33458 
 33459 public function __construct($message, $errors = array(), Exception $previous = null)
 33460 {
 33461 $this->errors = $errors;
 33462 parent::__construct((string) $message, 0, $previous);
 33463 }
 33464 
 33465 
 33466 
 33467 
 33468 public function getErrors()
 33469 {
 33470 return $this->errors;
 33471 }
 33472 }
 33473 <?php
 33474 
 33475 
 33476 
 33477 
 33478 
 33479 
 33480 
 33481 
 33482 
 33483 
 33484 
 33485 namespace Composer\Package;
 33486 
 33487 use Composer\Semver\Constraint\Constraint;
 33488 use Composer\Package\Version\VersionParser;
 33489 
 33490 
 33491 
 33492 
 33493 class AliasPackage extends BasePackage
 33494 {
 33495 
 33496 protected $version;
 33497 
 33498 protected $prettyVersion;
 33499 
 33500 protected $dev;
 33501 
 33502 protected $rootPackageAlias = false;
 33503 
 33504 
 33505 
 33506 
 33507 protected $stability;
 33508 
 33509 protected $hasSelfVersionRequires = false;
 33510 
 33511 
 33512 protected $aliasOf;
 33513 
 33514 protected $requires;
 33515 
 33516 protected $devRequires;
 33517 
 33518 protected $conflicts;
 33519 
 33520 protected $provides;
 33521 
 33522 protected $replaces;
 33523 
 33524 
 33525 
 33526 
 33527 
 33528 
 33529 
 33530 
 33531 public function __construct(BasePackage $aliasOf, $version, $prettyVersion)
 33532 {
 33533 parent::__construct($aliasOf->getName());
 33534 
 33535 $this->version = $version;
 33536 $this->prettyVersion = $prettyVersion;
 33537 $this->aliasOf = $aliasOf;
 33538 $this->stability = VersionParser::parseStability($version);
 33539 $this->dev = $this->stability === 'dev';
 33540 
 33541 foreach (Link::$TYPES as $type) {
 33542 $links = $aliasOf->{'get' . ucfirst($type)}();
 33543 $this->$type = $this->replaceSelfVersionDependencies($links, $type);
 33544 }
 33545 }
 33546 
 33547 
 33548 
 33549 
 33550 public function getAliasOf()
 33551 {
 33552 return $this->aliasOf;
 33553 }
 33554 
 33555 
 33556 
 33557 
 33558 public function getVersion()
 33559 {
 33560 return $this->version;
 33561 }
 33562 
 33563 
 33564 
 33565 
 33566 public function getStability()
 33567 {
 33568 return $this->stability;
 33569 }
 33570 
 33571 
 33572 
 33573 
 33574 public function getPrettyVersion()
 33575 {
 33576 return $this->prettyVersion;
 33577 }
 33578 
 33579 
 33580 
 33581 
 33582 public function isDev()
 33583 {
 33584 return $this->dev;
 33585 }
 33586 
 33587 
 33588 
 33589 
 33590 public function getRequires()
 33591 {
 33592 return $this->requires;
 33593 }
 33594 
 33595 
 33596 
 33597 
 33598 
 33599 public function getConflicts()
 33600 {
 33601 return $this->conflicts;
 33602 }
 33603 
 33604 
 33605 
 33606 
 33607 
 33608 public function getProvides()
 33609 {
 33610 return $this->provides;
 33611 }
 33612 
 33613 
 33614 
 33615 
 33616 
 33617 public function getReplaces()
 33618 {
 33619 return $this->replaces;
 33620 }
 33621 
 33622 
 33623 
 33624 
 33625 public function getDevRequires()
 33626 {
 33627 return $this->devRequires;
 33628 }
 33629 
 33630 
 33631 
 33632 
 33633 
 33634 
 33635 
 33636 
 33637 
 33638 
 33639 public function setRootPackageAlias($value)
 33640 {
 33641 return $this->rootPackageAlias = $value;
 33642 }
 33643 
 33644 
 33645 
 33646 
 33647 
 33648 public function isRootPackageAlias()
 33649 {
 33650 return $this->rootPackageAlias;
 33651 }
 33652 
 33653 
 33654 
 33655 
 33656 
 33657 
 33658 
 33659 protected function replaceSelfVersionDependencies(array $links, $linkType)
 33660 {
 33661 
 33662 $prettyVersion = $this->prettyVersion;
 33663 if ($prettyVersion === VersionParser::DEFAULT_BRANCH_ALIAS) {
 33664 $prettyVersion = $this->aliasOf->getPrettyVersion();
 33665 }
 33666 
 33667 if (\in_array($linkType, array(Link::TYPE_CONFLICT, Link::TYPE_PROVIDE, Link::TYPE_REPLACE), true)) {
 33668 $newLinks = array();
 33669 foreach ($links as $link) {
 33670 
 33671 if ('self.version' === $link->getPrettyConstraint()) {
 33672 $newLinks[] = new Link($link->getSource(), $link->getTarget(), $constraint = new Constraint('=', $this->version), $linkType, $prettyVersion);
 33673 $constraint->setPrettyString($prettyVersion);
 33674 }
 33675 }
 33676 $links = array_merge($links, $newLinks);
 33677 } else {
 33678 foreach ($links as $index => $link) {
 33679 if ('self.version' === $link->getPrettyConstraint()) {
 33680 if ($linkType === Link::TYPE_REQUIRE) {
 33681 $this->hasSelfVersionRequires = true;
 33682 }
 33683 $links[$index] = new Link($link->getSource(), $link->getTarget(), $constraint = new Constraint('=', $this->version), $linkType, $prettyVersion);
 33684 $constraint->setPrettyString($prettyVersion);
 33685 }
 33686 }
 33687 }
 33688 
 33689 return $links;
 33690 }
 33691 
 33692 
 33693 
 33694 
 33695 public function hasSelfVersionRequires()
 33696 {
 33697 return $this->hasSelfVersionRequires;
 33698 }
 33699 
 33700 public function __toString()
 33701 {
 33702 return parent::__toString().' ('.($this->rootPackageAlias ? 'root ' : ''). 'alias of '.$this->aliasOf->getVersion().')';
 33703 }
 33704 
 33705 
 33706 
 33707 
 33708 
 33709 public function getType()
 33710 {
 33711 return $this->aliasOf->getType();
 33712 }
 33713 
 33714 public function getTargetDir()
 33715 {
 33716 return $this->aliasOf->getTargetDir();
 33717 }
 33718 
 33719 public function getExtra()
 33720 {
 33721 return $this->aliasOf->getExtra();
 33722 }
 33723 
 33724 public function setInstallationSource($type)
 33725 {
 33726 $this->aliasOf->setInstallationSource($type);
 33727 }
 33728 
 33729 public function getInstallationSource()
 33730 {
 33731 return $this->aliasOf->getInstallationSource();
 33732 }
 33733 
 33734 public function getSourceType()
 33735 {
 33736 return $this->aliasOf->getSourceType();
 33737 }
 33738 
 33739 public function getSourceUrl()
 33740 {
 33741 return $this->aliasOf->getSourceUrl();
 33742 }
 33743 
 33744 public function getSourceUrls()
 33745 {
 33746 return $this->aliasOf->getSourceUrls();
 33747 }
 33748 
 33749 public function getSourceReference()
 33750 {
 33751 return $this->aliasOf->getSourceReference();
 33752 }
 33753 
 33754 public function setSourceReference($reference)
 33755 {
 33756 $this->aliasOf->setSourceReference($reference);
 33757 }
 33758 
 33759 public function setSourceMirrors($mirrors)
 33760 {
 33761 $this->aliasOf->setSourceMirrors($mirrors);
 33762 }
 33763 
 33764 public function getSourceMirrors()
 33765 {
 33766 return $this->aliasOf->getSourceMirrors();
 33767 }
 33768 
 33769 public function getDistType()
 33770 {
 33771 return $this->aliasOf->getDistType();
 33772 }
 33773 
 33774 public function getDistUrl()
 33775 {
 33776 return $this->aliasOf->getDistUrl();
 33777 }
 33778 
 33779 public function getDistUrls()
 33780 {
 33781 return $this->aliasOf->getDistUrls();
 33782 }
 33783 
 33784 public function getDistReference()
 33785 {
 33786 return $this->aliasOf->getDistReference();
 33787 }
 33788 
 33789 public function setDistReference($reference)
 33790 {
 33791 $this->aliasOf->setDistReference($reference);
 33792 }
 33793 
 33794 public function getDistSha1Checksum()
 33795 {
 33796 return $this->aliasOf->getDistSha1Checksum();
 33797 }
 33798 
 33799 public function setTransportOptions(array $options)
 33800 {
 33801 $this->aliasOf->setTransportOptions($options);
 33802 }
 33803 
 33804 public function getTransportOptions()
 33805 {
 33806 return $this->aliasOf->getTransportOptions();
 33807 }
 33808 
 33809 public function setDistMirrors($mirrors)
 33810 {
 33811 $this->aliasOf->setDistMirrors($mirrors);
 33812 }
 33813 
 33814 public function getDistMirrors()
 33815 {
 33816 return $this->aliasOf->getDistMirrors();
 33817 }
 33818 
 33819 public function getAutoload()
 33820 {
 33821 return $this->aliasOf->getAutoload();
 33822 }
 33823 
 33824 public function getDevAutoload()
 33825 {
 33826 return $this->aliasOf->getDevAutoload();
 33827 }
 33828 
 33829 public function getIncludePaths()
 33830 {
 33831 return $this->aliasOf->getIncludePaths();
 33832 }
 33833 
 33834 public function getReleaseDate()
 33835 {
 33836 return $this->aliasOf->getReleaseDate();
 33837 }
 33838 
 33839 public function getBinaries()
 33840 {
 33841 return $this->aliasOf->getBinaries();
 33842 }
 33843 
 33844 public function getSuggests()
 33845 {
 33846 return $this->aliasOf->getSuggests();
 33847 }
 33848 
 33849 public function getNotificationUrl()
 33850 {
 33851 return $this->aliasOf->getNotificationUrl();
 33852 }
 33853 
 33854 public function isDefaultBranch()
 33855 {
 33856 return $this->aliasOf->isDefaultBranch();
 33857 }
 33858 
 33859 public function setDistUrl($url)
 33860 {
 33861 $this->aliasOf->setDistUrl($url);
 33862 }
 33863 
 33864 public function setDistType($type)
 33865 {
 33866 $this->aliasOf->setDistType($type);
 33867 }
 33868 
 33869 public function setSourceDistReferences($reference)
 33870 {
 33871 $this->aliasOf->setSourceDistReferences($reference);
 33872 }
 33873 }
 33874 <?php
 33875 
 33876 
 33877 
 33878 
 33879 
 33880 
 33881 
 33882 
 33883 
 33884 
 33885 
 33886 namespace Composer\Package\Archiver;
 33887 
 33888 use FilterIterator;
 33889 use PharData;
 33890 
 33891 class ArchivableFilesFilter extends FilterIterator
 33892 {
 33893 
 33894 private $dirs = array();
 33895 
 33896 
 33897 
 33898 
 33899 #[\ReturnTypeWillChange]
 33900 public function accept()
 33901 {
 33902 $file = $this->getInnerIterator()->current();
 33903 if ($file->isDir()) {
 33904 $this->dirs[] = (string) $file;
 33905 
 33906 return false;
 33907 }
 33908 
 33909 return true;
 33910 }
 33911 
 33912 
 33913 
 33914 
 33915 
 33916 
 33917 public function addEmptyDir(PharData $phar, $sources)
 33918 {
 33919 foreach ($this->dirs as $filepath) {
 33920 $localname = str_replace($sources . "/", '', $filepath);
 33921 $phar->addEmptyDir($localname);
 33922 }
 33923 }
 33924 }
 33925 <?php
 33926 
 33927 
 33928 
 33929 
 33930 
 33931 
 33932 
 33933 
 33934 
 33935 
 33936 
 33937 namespace Composer\Package\Archiver;
 33938 
 33939 use Composer\Pcre\Preg;
 33940 use Composer\Util\Filesystem;
 33941 use FilesystemIterator;
 33942 use Symfony\Component\Finder\Finder;
 33943 use Symfony\Component\Finder\SplFileInfo;
 33944 
 33945 
 33946 
 33947 
 33948 
 33949 
 33950 
 33951 
 33952 
 33953 class ArchivableFilesFinder extends \FilterIterator
 33954 {
 33955 
 33956 
 33957 
 33958 protected $finder;
 33959 
 33960 
 33961 
 33962 
 33963 
 33964 
 33965 
 33966 
 33967 public function __construct($sources, array $excludes, $ignoreFilters = false)
 33968 {
 33969 $fs = new Filesystem();
 33970 
 33971 $sources = $fs->normalizePath(realpath($sources));
 33972 
 33973 if ($ignoreFilters) {
 33974 $filters = array();
 33975 } else {
 33976 $filters = array(
 33977 new GitExcludeFilter($sources),
 33978 new ComposerExcludeFilter($sources, $excludes),
 33979 );
 33980 }
 33981 
 33982 $this->finder = new Finder();
 33983 
 33984 $filter = function (\SplFileInfo $file) use ($sources, $filters, $fs) {
 33985 if ($file->isLink() && strpos($file->getRealPath(), $sources) !== 0) {
 33986 return false;
 33987 }
 33988 
 33989 $relativePath = Preg::replace(
 33990 '#^'.preg_quote($sources, '#').'#',
 33991 '',
 33992 $fs->normalizePath($file->getRealPath())
 33993 );
 33994 
 33995 $exclude = false;
 33996 foreach ($filters as $filter) {
 33997 $exclude = $filter->filter($relativePath, $exclude);
 33998 }
 33999 
 34000 return !$exclude;
 34001 };
 34002 
 34003 if (method_exists($filter, 'bindTo')) {
 34004 $filter = $filter->bindTo(null);
 34005 }
 34006 
 34007 $this->finder
 34008 ->in($sources)
 34009 ->filter($filter)
 34010 ->ignoreVCS(true)
 34011 ->ignoreDotFiles(false)
 34012 ->sortByName();
 34013 
 34014 parent::__construct($this->finder->getIterator());
 34015 }
 34016 
 34017 #[\ReturnTypeWillChange]
 34018 public function accept()
 34019 {
 34020 
 34021 $current = $this->getInnerIterator()->current();
 34022 
 34023 if (!$current->isDir()) {
 34024 return true;
 34025 }
 34026 
 34027 $iterator = new FilesystemIterator($current, FilesystemIterator::SKIP_DOTS);
 34028 
 34029 return !$iterator->valid();
 34030 }
 34031 }
 34032 <?php
 34033 
 34034 
 34035 
 34036 
 34037 
 34038 
 34039 
 34040 
 34041 
 34042 
 34043 
 34044 namespace Composer\Package\Archiver;
 34045 
 34046 use Composer\Downloader\DownloadManager;
 34047 use Composer\Package\RootPackageInterface;
 34048 use Composer\Pcre\Preg;
 34049 use Composer\Util\Filesystem;
 34050 use Composer\Util\Loop;
 34051 use Composer\Util\SyncHelper;
 34052 use Composer\Json\JsonFile;
 34053 use Composer\Package\CompletePackageInterface;
 34054 
 34055 
 34056 
 34057 
 34058 
 34059 class ArchiveManager
 34060 {
 34061 
 34062 protected $downloadManager;
 34063 
 34064 protected $loop;
 34065 
 34066 
 34067 
 34068 
 34069 protected $archivers = array();
 34070 
 34071 
 34072 
 34073 
 34074 protected $overwriteFiles = true;
 34075 
 34076 
 34077 
 34078 
 34079 public function __construct(DownloadManager $downloadManager, Loop $loop)
 34080 {
 34081 $this->downloadManager = $downloadManager;
 34082 $this->loop = $loop;
 34083 }
 34084 
 34085 
 34086 
 34087 
 34088 
 34089 
 34090 public function addArchiver(ArchiverInterface $archiver)
 34091 {
 34092 $this->archivers[] = $archiver;
 34093 }
 34094 
 34095 
 34096 
 34097 
 34098 
 34099 
 34100 
 34101 
 34102 public function setOverwriteFiles($overwriteFiles)
 34103 {
 34104 $this->overwriteFiles = $overwriteFiles;
 34105 
 34106 return $this;
 34107 }
 34108 
 34109 
 34110 
 34111 
 34112 
 34113 
 34114 
 34115 
 34116 public function getPackageFilename(CompletePackageInterface $package)
 34117 {
 34118 if ($package->getArchiveName()) {
 34119 $baseName = $package->getArchiveName();
 34120 } else {
 34121 $baseName = Preg::replace('#[^a-z0-9-_]#i', '-', $package->getName());
 34122 }
 34123 $nameParts = array($baseName);
 34124 
 34125 if (null !== $package->getDistReference() && Preg::isMatch('{^[a-f0-9]{40}$}', $package->getDistReference())) {
 34126 array_push($nameParts, $package->getDistReference(), $package->getDistType());
 34127 } else {
 34128 array_push($nameParts, $package->getPrettyVersion(), $package->getDistReference());
 34129 }
 34130 
 34131 if ($package->getSourceReference()) {
 34132 $nameParts[] = substr(sha1($package->getSourceReference()), 0, 6);
 34133 }
 34134 
 34135 $name = implode('-', array_filter($nameParts, function ($p) {
 34136 return !empty($p);
 34137 }));
 34138 
 34139 return str_replace('/', '-', $name);
 34140 }
 34141 
 34142 
 34143 
 34144 
 34145 
 34146 
 34147 
 34148 
 34149 
 34150 
 34151 
 34152 
 34153 
 34154 
 34155 public function archive(CompletePackageInterface $package, $format, $targetDir, $fileName = null, $ignoreFilters = false)
 34156 {
 34157 if (empty($format)) {
 34158 throw new \InvalidArgumentException('Format must be specified');
 34159 }
 34160 
 34161 
 34162 $usableArchiver = null;
 34163 foreach ($this->archivers as $archiver) {
 34164 if ($archiver->supports($format, $package->getSourceType())) {
 34165 $usableArchiver = $archiver;
 34166 break;
 34167 }
 34168 }
 34169 
 34170 
 34171 if (null === $usableArchiver) {
 34172 throw new \RuntimeException(sprintf('No archiver found to support %s format', $format));
 34173 }
 34174 
 34175 $filesystem = new Filesystem();
 34176 
 34177 if ($package instanceof RootPackageInterface) {
 34178 $sourcePath = realpath('.');
 34179 } else {
 34180 
 34181 $sourcePath = sys_get_temp_dir().'/composer_archive'.uniqid();
 34182 $filesystem->ensureDirectoryExists($sourcePath);
 34183 
 34184 try {
 34185 
 34186 $promise = $this->downloadManager->download($package, $sourcePath);
 34187 SyncHelper::await($this->loop, $promise);
 34188 $promise = $this->downloadManager->install($package, $sourcePath);
 34189 SyncHelper::await($this->loop, $promise);
 34190 } catch (\Exception $e) {
 34191 $filesystem->removeDirectory($sourcePath);
 34192 throw $e;
 34193 }
 34194 
 34195 
 34196 if (file_exists($composerJsonPath = $sourcePath.'/composer.json')) {
 34197 $jsonFile = new JsonFile($composerJsonPath);
 34198 $jsonData = $jsonFile->read();
 34199 if (!empty($jsonData['archive']['name'])) {
 34200 $package->setArchiveName($jsonData['archive']['name']);
 34201 }
 34202 if (!empty($jsonData['archive']['exclude'])) {
 34203 $package->setArchiveExcludes($jsonData['archive']['exclude']);
 34204 }
 34205 }
 34206 }
 34207 
 34208 if (null === $fileName) {
 34209 $packageName = $this->getPackageFilename($package);
 34210 } else {
 34211 $packageName = $fileName;
 34212 }
 34213 
 34214 
 34215 $filesystem->ensureDirectoryExists($targetDir);
 34216 $target = realpath($targetDir).'/'.$packageName.'.'.$format;
 34217 $filesystem->ensureDirectoryExists(dirname($target));
 34218 
 34219 if (!$this->overwriteFiles && file_exists($target)) {
 34220 return $target;
 34221 }
 34222 
 34223 
 34224 $tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format;
 34225 $filesystem->ensureDirectoryExists(dirname($tempTarget));
 34226 
 34227 $archivePath = $usableArchiver->archive($sourcePath, $tempTarget, $format, $package->getArchiveExcludes(), $ignoreFilters);
 34228 $filesystem->rename($archivePath, $target);
 34229 
 34230 
 34231 if (!$package instanceof RootPackageInterface) {
 34232 $filesystem->removeDirectory($sourcePath);
 34233 }
 34234 $filesystem->remove($tempTarget);
 34235 
 34236 return $target;
 34237 }
 34238 }
 34239 <?php
 34240 
 34241 
 34242 
 34243 
 34244 
 34245 
 34246 
 34247 
 34248 
 34249 
 34250 
 34251 namespace Composer\Package\Archiver;
 34252 
 34253 
 34254 
 34255 
 34256 
 34257 
 34258 interface ArchiverInterface
 34259 {
 34260 
 34261 
 34262 
 34263 
 34264 
 34265 
 34266 
 34267 
 34268 
 34269 
 34270 
 34271 public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false);
 34272 
 34273 
 34274 
 34275 
 34276 
 34277 
 34278 
 34279 
 34280 
 34281 public function supports($format, $sourceType);
 34282 }
 34283 <?php
 34284 
 34285 
 34286 
 34287 
 34288 
 34289 
 34290 
 34291 
 34292 
 34293 
 34294 
 34295 namespace Composer\Package\Archiver;
 34296 
 34297 use Composer\Pcre\Preg;
 34298 use Symfony\Component\Finder;
 34299 
 34300 
 34301 
 34302 
 34303 abstract class BaseExcludeFilter
 34304 {
 34305 
 34306 
 34307 
 34308 protected $sourcePath;
 34309 
 34310 
 34311 
 34312 
 34313 protected $excludePatterns;
 34314 
 34315 
 34316 
 34317 
 34318 public function __construct($sourcePath)
 34319 {
 34320 $this->sourcePath = $sourcePath;
 34321 $this->excludePatterns = array();
 34322 }
 34323 
 34324 
 34325 
 34326 
 34327 
 34328 
 34329 
 34330 
 34331 
 34332 
 34333 
 34334 public function filter($relativePath, $exclude)
 34335 {
 34336 foreach ($this->excludePatterns as $patternData) {
 34337 list($pattern, $negate, $stripLeadingSlash) = $patternData;
 34338 
 34339 if ($stripLeadingSlash) {
 34340 $path = substr($relativePath, 1);
 34341 } else {
 34342 $path = $relativePath;
 34343 }
 34344 
 34345 try {
 34346 if (Preg::isMatch($pattern, $path)) {
 34347 $exclude = !$negate;
 34348 }
 34349 } catch (\RuntimeException $e) {
 34350 
 34351 }
 34352 }
 34353 
 34354 return $exclude;
 34355 }
 34356 
 34357 
 34358 
 34359 
 34360 
 34361 
 34362 
 34363 
 34364 
 34365 protected function parseLines(array $lines, $lineParser)
 34366 {
 34367 return array_filter(
 34368 array_map(
 34369 function ($line) use ($lineParser) {
 34370 $line = trim($line);
 34371 
 34372 if (!$line || 0 === strpos($line, '#')) {
 34373 return null;
 34374 }
 34375 
 34376 return call_user_func($lineParser, $line);
 34377 },
 34378 $lines
 34379 ),
 34380 function ($pattern) {
 34381 return $pattern !== null;
 34382 }
 34383 );
 34384 }
 34385 
 34386 
 34387 
 34388 
 34389 
 34390 
 34391 
 34392 
 34393 protected function generatePatterns($rules)
 34394 {
 34395 $patterns = array();
 34396 foreach ($rules as $rule) {
 34397 $patterns[] = $this->generatePattern($rule);
 34398 }
 34399 
 34400 return $patterns;
 34401 }
 34402 
 34403 
 34404 
 34405 
 34406 
 34407 
 34408 
 34409 
 34410 protected function generatePattern($rule)
 34411 {
 34412 $negate = false;
 34413 $pattern = '';
 34414 
 34415 if ($rule !== '' && $rule[0] === '!') {
 34416 $negate = true;
 34417 $rule = ltrim($rule, '!');
 34418 }
 34419 
 34420 $firstSlashPosition = strpos($rule, '/');
 34421 if (0 === $firstSlashPosition) {
 34422 $pattern = '^/';
 34423 } elseif (false === $firstSlashPosition || strlen($rule) - 1 === $firstSlashPosition) {
 34424 $pattern = '/';
 34425 }
 34426 
 34427 $rule = trim($rule, '/');
 34428 
 34429 
 34430 $rule = substr(Finder\Glob::toRegex($rule), 2, -2);
 34431 
 34432 return array('{'.$pattern.$rule.'(?=$|/)}', $negate, false);
 34433 }
 34434 }
 34435 <?php
 34436 
 34437 
 34438 
 34439 
 34440 
 34441 
 34442 
 34443 
 34444 
 34445 
 34446 
 34447 namespace Composer\Package\Archiver;
 34448 
 34449 
 34450 
 34451 
 34452 
 34453 
 34454 class ComposerExcludeFilter extends BaseExcludeFilter
 34455 {
 34456 
 34457 
 34458 
 34459 
 34460 public function __construct($sourcePath, array $excludeRules)
 34461 {
 34462 parent::__construct($sourcePath);
 34463 $this->excludePatterns = $this->generatePatterns($excludeRules);
 34464 }
 34465 }
 34466 <?php
 34467 
 34468 
 34469 
 34470 
 34471 
 34472 
 34473 
 34474 
 34475 
 34476 
 34477 
 34478 namespace Composer\Package\Archiver;
 34479 
 34480 use Composer\Pcre\Preg;
 34481 
 34482 
 34483 
 34484 
 34485 
 34486 
 34487 
 34488 
 34489 class GitExcludeFilter extends BaseExcludeFilter
 34490 {
 34491 
 34492 
 34493 
 34494 
 34495 
 34496 public function __construct($sourcePath)
 34497 {
 34498 parent::__construct($sourcePath);
 34499 
 34500 if (file_exists($sourcePath.'/.gitattributes')) {
 34501 $this->excludePatterns = array_merge(
 34502 $this->excludePatterns,
 34503 $this->parseLines(
 34504 file($sourcePath.'/.gitattributes'),
 34505 array($this, 'parseGitAttributesLine')
 34506 )
 34507 );
 34508 }
 34509 }
 34510 
 34511 
 34512 
 34513 
 34514 
 34515 
 34516 
 34517 
 34518 public function parseGitAttributesLine($line)
 34519 {
 34520 $parts = Preg::split('#\s+#', $line);
 34521 
 34522 if (count($parts) == 2 && $parts[1] === 'export-ignore') {
 34523 return $this->generatePattern($parts[0]);
 34524 }
 34525 
 34526 if (count($parts) == 2 && $parts[1] === '-export-ignore') {
 34527 return $this->generatePattern('!'.$parts[0]);
 34528 }
 34529 
 34530 return null;
 34531 }
 34532 }
 34533 <?php
 34534 
 34535 
 34536 
 34537 
 34538 
 34539 
 34540 
 34541 
 34542 
 34543 
 34544 
 34545 namespace Composer\Package\Archiver;
 34546 
 34547 
 34548 
 34549 
 34550 
 34551 
 34552 class PharArchiver implements ArchiverInterface
 34553 {
 34554 
 34555 protected static $formats = array(
 34556 'zip' => \Phar::ZIP,
 34557 'tar' => \Phar::TAR,
 34558 'tar.gz' => \Phar::TAR,
 34559 'tar.bz2' => \Phar::TAR,
 34560 );
 34561 
 34562 
 34563 protected static $compressFormats = array(
 34564 'tar.gz' => \Phar::GZ,
 34565 'tar.bz2' => \Phar::BZ2,
 34566 );
 34567 
 34568 
 34569 
 34570 
 34571 public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
 34572 {
 34573 $sources = realpath($sources);
 34574 
 34575 
 34576 if (file_exists($target)) {
 34577 unlink($target);
 34578 }
 34579 
 34580 try {
 34581 $filename = substr($target, 0, strrpos($target, $format) - 1);
 34582 
 34583 
 34584 if (isset(static::$compressFormats[$format])) {
 34585 
 34586 $target = $filename . '.tar';
 34587 }
 34588 
 34589 $phar = new \PharData(
 34590 $target,
 34591 \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO,
 34592 '',
 34593 static::$formats[$format]
 34594 );
 34595 $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
 34596 $filesOnly = new ArchivableFilesFilter($files);
 34597 $phar->buildFromIterator($filesOnly, $sources);
 34598 $filesOnly->addEmptyDir($phar, $sources);
 34599 
 34600 if (isset(static::$compressFormats[$format])) {
 34601 
 34602 if (!$phar->canCompress(static::$compressFormats[$format])) {
 34603 throw new \RuntimeException(sprintf('Can not compress to %s format', $format));
 34604 }
 34605 
 34606 
 34607 unlink($target);
 34608 
 34609 
 34610 $phar->compress(static::$compressFormats[$format]);
 34611 
 34612 
 34613 $target = $filename . '.' . $format;
 34614 }
 34615 
 34616 return $target;
 34617 } catch (\UnexpectedValueException $e) {
 34618 $message = sprintf(
 34619 "Could not create archive '%s' from '%s': %s",
 34620 $target,
 34621 $sources,
 34622 $e->getMessage()
 34623 );
 34624 
 34625 throw new \RuntimeException($message, $e->getCode(), $e);
 34626 }
 34627 }
 34628 
 34629 
 34630 
 34631 
 34632 public function supports($format, $sourceType)
 34633 {
 34634 return isset(static::$formats[$format]);
 34635 }
 34636 }
 34637 <?php
 34638 
 34639 
 34640 
 34641 
 34642 
 34643 
 34644 
 34645 
 34646 
 34647 
 34648 
 34649 namespace Composer\Package\Archiver;
 34650 
 34651 use ZipArchive;
 34652 use Composer\Util\Filesystem;
 34653 
 34654 
 34655 
 34656 
 34657 class ZipArchiver implements ArchiverInterface
 34658 {
 34659 
 34660 protected static $formats = array(
 34661 'zip' => true,
 34662 );
 34663 
 34664 
 34665 
 34666 
 34667 public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
 34668 {
 34669 $fs = new Filesystem();
 34670 $sources = $fs->normalizePath($sources);
 34671 
 34672 $zip = new ZipArchive();
 34673 $res = $zip->open($target, ZipArchive::CREATE);
 34674 if ($res === true) {
 34675 $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
 34676 foreach ($files as $file) {
 34677 
 34678 $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/');
 34679 $localname = $filepath;
 34680 if (strpos($localname, $sources . '/') === 0) {
 34681 $localname = substr($localname, strlen($sources . '/'));
 34682 }
 34683 if ($file->isDir()) {
 34684 $zip->addEmptyDir($localname);
 34685 } else {
 34686 $zip->addFile($filepath, $localname);
 34687 }
 34688 
 34689 
 34690 
 34691 
 34692 
 34693 if (PHP_VERSION_ID >= 50600 && method_exists($zip, 'setExternalAttributesName')) {
 34694 $perms = fileperms($filepath);
 34695 
 34696 
 34697 
 34698 
 34699 $zip->setExternalAttributesName($localname, ZipArchive::OPSYS_UNIX, $perms << 16);
 34700 }
 34701 }
 34702 if ($zip->close()) {
 34703 return $target;
 34704 }
 34705 }
 34706 $message = sprintf(
 34707 "Could not create archive '%s' from '%s': %s",
 34708 $target,
 34709 $sources,
 34710 $zip->getStatusString()
 34711 );
 34712 throw new \RuntimeException($message);
 34713 }
 34714 
 34715 
 34716 
 34717 
 34718 public function supports($format, $sourceType)
 34719 {
 34720 return isset(static::$formats[$format]) && $this->compressionAvailable();
 34721 }
 34722 
 34723 
 34724 
 34725 
 34726 private function compressionAvailable()
 34727 {
 34728 return class_exists('ZipArchive');
 34729 }
 34730 }
 34731 <?php
 34732 
 34733 
 34734 
 34735 
 34736 
 34737 
 34738 
 34739 
 34740 
 34741 
 34742 
 34743 namespace Composer\Package;
 34744 
 34745 use Composer\Repository\RepositoryInterface;
 34746 use Composer\Repository\PlatformRepository;
 34747 
 34748 
 34749 
 34750 
 34751 
 34752 
 34753 abstract class BasePackage implements PackageInterface
 34754 {
 34755 
 34756 
 34757 
 34758 
 34759 public static $supportedLinkTypes = array(
 34760 'require' => array('description' => 'requires', 'method' => Link::TYPE_REQUIRE),
 34761 'conflict' => array('description' => 'conflicts', 'method' => Link::TYPE_CONFLICT),
 34762 'provide' => array('description' => 'provides', 'method' => Link::TYPE_PROVIDE),
 34763 'replace' => array('description' => 'replaces', 'method' => Link::TYPE_REPLACE),
 34764 'require-dev' => array('description' => 'requires (for development)', 'method' => Link::TYPE_DEV_REQUIRE),
 34765 );
 34766 
 34767 const STABILITY_STABLE = 0;
 34768 const STABILITY_RC = 5;
 34769 const STABILITY_BETA = 10;
 34770 const STABILITY_ALPHA = 15;
 34771 const STABILITY_DEV = 20;
 34772 
 34773 
 34774 public static $stabilities = array(
 34775 'stable' => self::STABILITY_STABLE,
 34776 'RC' => self::STABILITY_RC,
 34777 'beta' => self::STABILITY_BETA,
 34778 'alpha' => self::STABILITY_ALPHA,
 34779 'dev' => self::STABILITY_DEV,
 34780 );
 34781 
 34782 
 34783 
 34784 
 34785 
 34786 
 34787 
 34788 public $id;
 34789 
 34790 protected $name;
 34791 
 34792 protected $prettyName;
 34793 
 34794 protected $repository = null;
 34795 
 34796 
 34797 
 34798 
 34799 
 34800 
 34801 public function __construct($name)
 34802 {
 34803 $this->prettyName = $name;
 34804 $this->name = strtolower($name);
 34805 $this->id = -1;
 34806 }
 34807 
 34808 
 34809 
 34810 
 34811 public function getName()
 34812 {
 34813 return $this->name;
 34814 }
 34815 
 34816 
 34817 
 34818 
 34819 public function getPrettyName()
 34820 {
 34821 return $this->prettyName;
 34822 }
 34823 
 34824 
 34825 
 34826 
 34827 public function getNames($provides = true)
 34828 {
 34829 $names = array(
 34830 $this->getName() => true,
 34831 );
 34832 
 34833 if ($provides) {
 34834 foreach ($this->getProvides() as $link) {
 34835 $names[$link->getTarget()] = true;
 34836 }
 34837 }
 34838 
 34839 foreach ($this->getReplaces() as $link) {
 34840 $names[$link->getTarget()] = true;
 34841 }
 34842 
 34843 return array_keys($names);
 34844 }
 34845 
 34846 
 34847 
 34848 
 34849 public function setId($id)
 34850 {
 34851 $this->id = $id;
 34852 }
 34853 
 34854 
 34855 
 34856 
 34857 public function getId()
 34858 {
 34859 return $this->id;
 34860 }
 34861 
 34862 
 34863 
 34864 
 34865 public function setRepository(RepositoryInterface $repository)
 34866 {
 34867 if ($this->repository && $repository !== $this->repository) {
 34868 throw new \LogicException('A package can only be added to one repository');
 34869 }
 34870 $this->repository = $repository;
 34871 }
 34872 
 34873 
 34874 
 34875 
 34876 public function getRepository()
 34877 {
 34878 return $this->repository;
 34879 }
 34880 
 34881 
 34882 
 34883 
 34884 
 34885 
 34886 public function isPlatform()
 34887 {
 34888 return $this->getRepository() instanceof PlatformRepository;
 34889 }
 34890 
 34891 
 34892 
 34893 
 34894 
 34895 
 34896 public function getUniqueName()
 34897 {
 34898 return $this->getName().'-'.$this->getVersion();
 34899 }
 34900 
 34901 
 34902 
 34903 
 34904 public function equals(PackageInterface $package)
 34905 {
 34906 $self = $this;
 34907 if ($this instanceof AliasPackage) {
 34908 $self = $this->getAliasOf();
 34909 }
 34910 if ($package instanceof AliasPackage) {
 34911 $package = $package->getAliasOf();
 34912 }
 34913 
 34914 return $package === $self;
 34915 }
 34916 
 34917 
 34918 
 34919 
 34920 
 34921 
 34922 public function __toString()
 34923 {
 34924 return $this->getUniqueName();
 34925 }
 34926 
 34927 public function getPrettyString()
 34928 {
 34929 return $this->getPrettyName().' '.$this->getPrettyVersion();
 34930 }
 34931 
 34932 
 34933 
 34934 
 34935 public function getFullPrettyVersion($truncate = true, $displayMode = PackageInterface::DISPLAY_SOURCE_REF_IF_DEV)
 34936 {
 34937 if ($displayMode === PackageInterface::DISPLAY_SOURCE_REF_IF_DEV &&
 34938 (!$this->isDev() || !\in_array($this->getSourceType(), array('hg', 'git')))
 34939 ) {
 34940 return $this->getPrettyVersion();
 34941 }
 34942 
 34943 switch ($displayMode) {
 34944 case PackageInterface::DISPLAY_SOURCE_REF_IF_DEV:
 34945 case PackageInterface::DISPLAY_SOURCE_REF:
 34946 $reference = $this->getSourceReference();
 34947 break;
 34948 case PackageInterface::DISPLAY_DIST_REF:
 34949 $reference = $this->getDistReference();
 34950 break;
 34951 default:
 34952 throw new \UnexpectedValueException('Display mode '.$displayMode.' is not supported');
 34953 }
 34954 
 34955 if (null === $reference) {
 34956 return $this->getPrettyVersion();
 34957 }
 34958 
 34959 
 34960 if ($truncate && \strlen($reference) === 40 && $this->getSourceType() !== 'svn') {
 34961 return $this->getPrettyVersion() . ' ' . substr($reference, 0, 7);
 34962 }
 34963 
 34964 return $this->getPrettyVersion() . ' ' . $reference;
 34965 }
 34966 
 34967 
 34968 
 34969 
 34970 
 34971 
 34972 public function getStabilityPriority()
 34973 {
 34974 return self::$stabilities[$this->getStability()];
 34975 }
 34976 
 34977 public function __clone()
 34978 {
 34979 $this->repository = null;
 34980 $this->id = -1;
 34981 }
 34982 
 34983 
 34984 
 34985 
 34986 
 34987 
 34988 
 34989 
 34990 public static function packageNameToRegexp($allowPattern, $wrap = '{^%s$}i')
 34991 {
 34992 $cleanedAllowPattern = str_replace('\\*', '.*', preg_quote($allowPattern));
 34993 
 34994 return sprintf($wrap, $cleanedAllowPattern);
 34995 }
 34996 
 34997 
 34998 
 34999 
 35000 
 35001 
 35002 
 35003 
 35004 public static function packageNamesToRegexp(array $packageNames, $wrap = '{^(?:%s)$}iD')
 35005 {
 35006 $packageNames = array_map(
 35007 function ($packageName) {
 35008 return BasePackage::packageNameToRegexp($packageName, '%s');
 35009 },
 35010 $packageNames
 35011 );
 35012 
 35013 return sprintf($wrap, implode('|', $packageNames));
 35014 }
 35015 }
 35016 <?php
 35017 
 35018 
 35019 
 35020 
 35021 
 35022 
 35023 
 35024 
 35025 
 35026 
 35027 
 35028 namespace Composer\Package\Comparer;
 35029 
 35030 
 35031 
 35032 
 35033 
 35034 
 35035 class Comparer
 35036 {
 35037 
 35038 private $source;
 35039 
 35040 private $update;
 35041 
 35042 private $changed;
 35043 
 35044 
 35045 
 35046 
 35047 
 35048 
 35049 public function setSource($source)
 35050 {
 35051 $this->source = $source;
 35052 }
 35053 
 35054 
 35055 
 35056 
 35057 
 35058 
 35059 public function setUpdate($update)
 35060 {
 35061 $this->update = $update;
 35062 }
 35063 
 35064 
 35065 
 35066 
 35067 
 35068 
 35069 
 35070 public function getChanged($toString = false, $explicated = false)
 35071 {
 35072 $changed = $this->changed;
 35073 if (!count($changed)) {
 35074 return false;
 35075 }
 35076 if ($explicated) {
 35077 foreach ($changed as $sectionKey => $itemSection) {
 35078 foreach ($itemSection as $itemKey => $item) {
 35079 $changed[$sectionKey][$itemKey] = $item.' ('.$sectionKey.')';
 35080 }
 35081 }
 35082 }
 35083 
 35084 if ($toString) {
 35085 $strings = array();
 35086 foreach ($changed as $sectionKey => $itemSection) {
 35087 foreach ($itemSection as $itemKey => $item) {
 35088 $strings[] = $item."\r\n";
 35089 }
 35090 }
 35091 $changed = implode("\r\n", $strings);
 35092 }
 35093 
 35094 return $changed;
 35095 }
 35096 
 35097 
 35098 
 35099 
 35100 public function doCompare()
 35101 {
 35102 $source = array();
 35103 $destination = array();
 35104 $this->changed = array();
 35105 $currentDirectory = getcwd();
 35106 chdir($this->source);
 35107 $source = $this->doTree('.', $source);
 35108 if (!is_array($source)) {
 35109 return;
 35110 }
 35111 chdir($currentDirectory);
 35112 chdir($this->update);
 35113 $destination = $this->doTree('.', $destination);
 35114 if (!is_array($destination)) {
 35115 exit;
 35116 }
 35117 chdir($currentDirectory);
 35118 foreach ($source as $dir => $value) {
 35119 foreach ($value as $file => $hash) {
 35120 if (isset($destination[$dir][$file])) {
 35121 if ($hash !== $destination[$dir][$file]) {
 35122 $this->changed['changed'][] = $dir.'/'.$file;
 35123 }
 35124 } else {
 35125 $this->changed['removed'][] = $dir.'/'.$file;
 35126 }
 35127 }
 35128 }
 35129 foreach ($destination as $dir => $value) {
 35130 foreach ($value as $file => $hash) {
 35131 if (!isset($source[$dir][$file])) {
 35132 $this->changed['added'][] = $dir.'/'.$file;
 35133 }
 35134 }
 35135 }
 35136 }
 35137 
 35138 
 35139 
 35140 
 35141 
 35142 
 35143 
 35144 private function doTree($dir, &$array)
 35145 {
 35146 if ($dh = opendir($dir)) {
 35147 while ($file = readdir($dh)) {
 35148 if ($file !== '.' && $file !== '..') {
 35149 if (is_link($dir.'/'.$file)) {
 35150 $array[$dir][$file] = readlink($dir.'/'.$file);
 35151 } elseif (is_dir($dir.'/'.$file)) {
 35152 if (!count($array)) {
 35153 $array[0] = 'Temp';
 35154 }
 35155 if (!$this->doTree($dir.'/'.$file, $array)) {
 35156 return false;
 35157 }
 35158 } elseif (is_file($dir.'/'.$file) && filesize($dir.'/'.$file)) {
 35159 $array[$dir][$file] = md5_file($dir.'/'.$file);
 35160 }
 35161 }
 35162 }
 35163 if (count($array) > 1 && isset($array['0'])) {
 35164 unset($array['0']);
 35165 }
 35166 
 35167 return $array;
 35168 }
 35169 
 35170 return false;
 35171 }
 35172 }
 35173 <?php
 35174 
 35175 
 35176 
 35177 
 35178 
 35179 
 35180 
 35181 
 35182 
 35183 
 35184 
 35185 namespace Composer\Package;
 35186 
 35187 
 35188 
 35189 
 35190 class CompleteAliasPackage extends AliasPackage implements CompletePackageInterface
 35191 {
 35192 
 35193 protected $aliasOf;
 35194 
 35195 
 35196 
 35197 
 35198 
 35199 
 35200 
 35201 
 35202 public function __construct(CompletePackage $aliasOf, $version, $prettyVersion)
 35203 {
 35204 parent::__construct($aliasOf, $version, $prettyVersion);
 35205 }
 35206 
 35207 
 35208 
 35209 
 35210 public function getAliasOf()
 35211 {
 35212 return $this->aliasOf;
 35213 }
 35214 
 35215 public function getScripts()
 35216 {
 35217 return $this->aliasOf->getScripts();
 35218 }
 35219 
 35220 public function setScripts(array $scripts)
 35221 {
 35222 $this->aliasOf->setScripts($scripts);
 35223 }
 35224 
 35225 public function getRepositories()
 35226 {
 35227 return $this->aliasOf->getRepositories();
 35228 }
 35229 
 35230 public function setRepositories(array $repositories)
 35231 {
 35232 $this->aliasOf->setRepositories($repositories);
 35233 }
 35234 
 35235 public function getLicense()
 35236 {
 35237 return $this->aliasOf->getLicense();
 35238 }
 35239 
 35240 public function setLicense(array $license)
 35241 {
 35242 $this->aliasOf->setLicense($license);
 35243 }
 35244 
 35245 public function getKeywords()
 35246 {
 35247 return $this->aliasOf->getKeywords();
 35248 }
 35249 
 35250 public function setKeywords(array $keywords)
 35251 {
 35252 $this->aliasOf->setKeywords($keywords);
 35253 }
 35254 
 35255 public function getDescription()
 35256 {
 35257 return $this->aliasOf->getDescription();
 35258 }
 35259 
 35260 public function setDescription($description)
 35261 {
 35262 $this->aliasOf->setDescription($description);
 35263 }
 35264 
 35265 public function getHomepage()
 35266 {
 35267 return $this->aliasOf->getHomepage();
 35268 }
 35269 
 35270 public function setHomepage($homepage)
 35271 {
 35272 $this->aliasOf->setHomepage($homepage);
 35273 }
 35274 
 35275 public function getAuthors()
 35276 {
 35277 return $this->aliasOf->getAuthors();
 35278 }
 35279 
 35280 public function setAuthors(array $authors)
 35281 {
 35282 $this->aliasOf->setAuthors($authors);
 35283 }
 35284 
 35285 public function getSupport()
 35286 {
 35287 return $this->aliasOf->getSupport();
 35288 }
 35289 
 35290 public function setSupport(array $support)
 35291 {
 35292 $this->aliasOf->setSupport($support);
 35293 }
 35294 
 35295 public function getFunding()
 35296 {
 35297 return $this->aliasOf->getFunding();
 35298 }
 35299 
 35300 public function setFunding(array $funding)
 35301 {
 35302 $this->aliasOf->setFunding($funding);
 35303 }
 35304 
 35305 public function isAbandoned()
 35306 {
 35307 return $this->aliasOf->isAbandoned();
 35308 }
 35309 
 35310 public function getReplacementPackage()
 35311 {
 35312 return $this->aliasOf->getReplacementPackage();
 35313 }
 35314 
 35315 public function setAbandoned($abandoned)
 35316 {
 35317 $this->aliasOf->setAbandoned($abandoned);
 35318 }
 35319 
 35320 public function getArchiveName()
 35321 {
 35322 return $this->aliasOf->getArchiveName();
 35323 }
 35324 
 35325 public function setArchiveName($name)
 35326 {
 35327 $this->aliasOf->setArchiveName($name);
 35328 }
 35329 
 35330 public function getArchiveExcludes()
 35331 {
 35332 return $this->aliasOf->getArchiveExcludes();
 35333 }
 35334 
 35335 public function setArchiveExcludes(array $excludes)
 35336 {
 35337 $this->aliasOf->setArchiveExcludes($excludes);
 35338 }
 35339 }
 35340 <?php
 35341 
 35342 
 35343 
 35344 
 35345 
 35346 
 35347 
 35348 
 35349 
 35350 
 35351 
 35352 namespace Composer\Package;
 35353 
 35354 
 35355 
 35356 
 35357 
 35358 
 35359 class CompletePackage extends Package implements CompletePackageInterface
 35360 {
 35361 
 35362 protected $repositories = array();
 35363 
 35364 protected $license = array();
 35365 
 35366 protected $keywords = array();
 35367 
 35368 protected $authors = array();
 35369 
 35370 protected $description = null;
 35371 
 35372 protected $homepage = null;
 35373 
 35374 protected $scripts = array();
 35375 
 35376 protected $support = array();
 35377 
 35378 protected $funding = array();
 35379 
 35380 protected $abandoned = false;
 35381 
 35382 protected $archiveName = null;
 35383 
 35384 protected $archiveExcludes = array();
 35385 
 35386 
 35387 
 35388 
 35389 public function setScripts(array $scripts)
 35390 {
 35391 $this->scripts = $scripts;
 35392 }
 35393 
 35394 
 35395 
 35396 
 35397 public function getScripts()
 35398 {
 35399 return $this->scripts;
 35400 }
 35401 
 35402 
 35403 
 35404 
 35405 public function setRepositories(array $repositories)
 35406 {
 35407 $this->repositories = $repositories;
 35408 }
 35409 
 35410 
 35411 
 35412 
 35413 public function getRepositories()
 35414 {
 35415 return $this->repositories;
 35416 }
 35417 
 35418 
 35419 
 35420 
 35421 public function setLicense(array $license)
 35422 {
 35423 $this->license = $license;
 35424 }
 35425 
 35426 
 35427 
 35428 
 35429 public function getLicense()
 35430 {
 35431 return $this->license;
 35432 }
 35433 
 35434 
 35435 
 35436 
 35437 public function setKeywords(array $keywords)
 35438 {
 35439 $this->keywords = $keywords;
 35440 }
 35441 
 35442 
 35443 
 35444 
 35445 public function getKeywords()
 35446 {
 35447 return $this->keywords;
 35448 }
 35449 
 35450 
 35451 
 35452 
 35453 public function setAuthors(array $authors)
 35454 {
 35455 $this->authors = $authors;
 35456 }
 35457 
 35458 
 35459 
 35460 
 35461 public function getAuthors()
 35462 {
 35463 return $this->authors;
 35464 }
 35465 
 35466 
 35467 
 35468 
 35469 public function setDescription($description)
 35470 {
 35471 $this->description = $description;
 35472 }
 35473 
 35474 
 35475 
 35476 
 35477 public function getDescription()
 35478 {
 35479 return $this->description;
 35480 }
 35481 
 35482 
 35483 
 35484 
 35485 public function setHomepage($homepage)
 35486 {
 35487 $this->homepage = $homepage;
 35488 }
 35489 
 35490 
 35491 
 35492 
 35493 public function getHomepage()
 35494 {
 35495 return $this->homepage;
 35496 }
 35497 
 35498 
 35499 
 35500 
 35501 public function setSupport(array $support)
 35502 {
 35503 $this->support = $support;
 35504 }
 35505 
 35506 
 35507 
 35508 
 35509 public function getSupport()
 35510 {
 35511 return $this->support;
 35512 }
 35513 
 35514 
 35515 
 35516 
 35517 public function setFunding(array $funding)
 35518 {
 35519 $this->funding = $funding;
 35520 }
 35521 
 35522 
 35523 
 35524 
 35525 public function getFunding()
 35526 {
 35527 return $this->funding;
 35528 }
 35529 
 35530 
 35531 
 35532 
 35533 public function isAbandoned()
 35534 {
 35535 return (bool) $this->abandoned;
 35536 }
 35537 
 35538 
 35539 
 35540 
 35541 public function setAbandoned($abandoned)
 35542 {
 35543 $this->abandoned = $abandoned;
 35544 }
 35545 
 35546 
 35547 
 35548 
 35549 public function getReplacementPackage()
 35550 {
 35551 return \is_string($this->abandoned) ? $this->abandoned : null;
 35552 }
 35553 
 35554 
 35555 
 35556 
 35557 public function setArchiveName($name)
 35558 {
 35559 $this->archiveName = $name;
 35560 }
 35561 
 35562 
 35563 
 35564 
 35565 public function getArchiveName()
 35566 {
 35567 return $this->archiveName;
 35568 }
 35569 
 35570 
 35571 
 35572 
 35573 public function setArchiveExcludes(array $excludes)
 35574 {
 35575 $this->archiveExcludes = $excludes;
 35576 }
 35577 
 35578 
 35579 
 35580 
 35581 public function getArchiveExcludes()
 35582 {
 35583 return $this->archiveExcludes;
 35584 }
 35585 }
 35586 <?php
 35587 
 35588 
 35589 
 35590 
 35591 
 35592 
 35593 
 35594 
 35595 
 35596 
 35597 
 35598 namespace Composer\Package;
 35599 
 35600 
 35601 
 35602 
 35603 
 35604 
 35605 interface CompletePackageInterface extends PackageInterface
 35606 {
 35607 
 35608 
 35609 
 35610 
 35611 
 35612 public function getScripts();
 35613 
 35614 
 35615 
 35616 
 35617 
 35618 public function setScripts(array $scripts);
 35619 
 35620 
 35621 
 35622 
 35623 
 35624 
 35625 public function getRepositories();
 35626 
 35627 
 35628 
 35629 
 35630 
 35631 
 35632 
 35633 public function setRepositories(array $repositories);
 35634 
 35635 
 35636 
 35637 
 35638 
 35639 
 35640 public function getLicense();
 35641 
 35642 
 35643 
 35644 
 35645 
 35646 
 35647 
 35648 public function setLicense(array $license);
 35649 
 35650 
 35651 
 35652 
 35653 
 35654 
 35655 public function getKeywords();
 35656 
 35657 
 35658 
 35659 
 35660 
 35661 
 35662 
 35663 public function setKeywords(array $keywords);
 35664 
 35665 
 35666 
 35667 
 35668 
 35669 
 35670 public function getDescription();
 35671 
 35672 
 35673 
 35674 
 35675 
 35676 
 35677 
 35678 public function setDescription($description);
 35679 
 35680 
 35681 
 35682 
 35683 
 35684 
 35685 public function getHomepage();
 35686 
 35687 
 35688 
 35689 
 35690 
 35691 
 35692 
 35693 public function setHomepage($homepage);
 35694 
 35695 
 35696 
 35697 
 35698 
 35699 
 35700 
 35701 
 35702 public function getAuthors();
 35703 
 35704 
 35705 
 35706 
 35707 
 35708 
 35709 
 35710 public function setAuthors(array $authors);
 35711 
 35712 
 35713 
 35714 
 35715 
 35716 
 35717 public function getSupport();
 35718 
 35719 
 35720 
 35721 
 35722 
 35723 
 35724 
 35725 public function setSupport(array $support);
 35726 
 35727 
 35728 
 35729 
 35730 
 35731 
 35732 
 35733 
 35734 public function getFunding();
 35735 
 35736 
 35737 
 35738 
 35739 
 35740 
 35741 
 35742 public function setFunding(array $funding);
 35743 
 35744 
 35745 
 35746 
 35747 
 35748 
 35749 public function isAbandoned();
 35750 
 35751 
 35752 
 35753 
 35754 
 35755 
 35756 public function getReplacementPackage();
 35757 
 35758 
 35759 
 35760 
 35761 
 35762 public function setAbandoned($abandoned);
 35763 
 35764 
 35765 
 35766 
 35767 
 35768 
 35769 public function getArchiveName();
 35770 
 35771 
 35772 
 35773 
 35774 
 35775 
 35776 
 35777 public function setArchiveName($name);
 35778 
 35779 
 35780 
 35781 
 35782 
 35783 
 35784 public function getArchiveExcludes();
 35785 
 35786 
 35787 
 35788 
 35789 
 35790 
 35791 
 35792 public function setArchiveExcludes(array $excludes);
 35793 }
 35794 <?php
 35795 
 35796 
 35797 
 35798 
 35799 
 35800 
 35801 
 35802 
 35803 
 35804 
 35805 
 35806 namespace Composer\Package\Dumper;
 35807 
 35808 use Composer\Package\BasePackage;
 35809 use Composer\Package\PackageInterface;
 35810 use Composer\Package\CompletePackageInterface;
 35811 use Composer\Package\RootPackageInterface;
 35812 
 35813 
 35814 
 35815 
 35816 
 35817 class ArrayDumper
 35818 {
 35819 
 35820 
 35821 
 35822 public function dump(PackageInterface $package)
 35823 {
 35824 $keys = array(
 35825 'binaries' => 'bin',
 35826 'type',
 35827 'extra',
 35828 'installationSource' => 'installation-source',
 35829 'autoload',
 35830 'devAutoload' => 'autoload-dev',
 35831 'notificationUrl' => 'notification-url',
 35832 'includePaths' => 'include-path',
 35833 );
 35834 
 35835 $data = array();
 35836 $data['name'] = $package->getPrettyName();
 35837 $data['version'] = $package->getPrettyVersion();
 35838 $data['version_normalized'] = $package->getVersion();
 35839 
 35840 if ($package->getTargetDir()) {
 35841 $data['target-dir'] = $package->getTargetDir();
 35842 }
 35843 
 35844 if ($package->getSourceType()) {
 35845 $data['source']['type'] = $package->getSourceType();
 35846 $data['source']['url'] = $package->getSourceUrl();
 35847 if (null !== ($value = $package->getSourceReference())) {
 35848 $data['source']['reference'] = $value;
 35849 }
 35850 if ($mirrors = $package->getSourceMirrors()) {
 35851 $data['source']['mirrors'] = $mirrors;
 35852 }
 35853 }
 35854 
 35855 if ($package->getDistType()) {
 35856 $data['dist']['type'] = $package->getDistType();
 35857 $data['dist']['url'] = $package->getDistUrl();
 35858 if (null !== ($value = $package->getDistReference())) {
 35859 $data['dist']['reference'] = $value;
 35860 }
 35861 if (null !== ($value = $package->getDistSha1Checksum())) {
 35862 $data['dist']['shasum'] = $value;
 35863 }
 35864 if ($mirrors = $package->getDistMirrors()) {
 35865 $data['dist']['mirrors'] = $mirrors;
 35866 }
 35867 }
 35868 
 35869 foreach (BasePackage::$supportedLinkTypes as $type => $opts) {
 35870 if ($links = $package->{'get'.ucfirst($opts['method'])}()) {
 35871 foreach ($links as $link) {
 35872 $data[$type][$link->getTarget()] = $link->getPrettyConstraint();
 35873 }
 35874 ksort($data[$type]);
 35875 }
 35876 }
 35877 
 35878 if ($packages = $package->getSuggests()) {
 35879 ksort($packages);
 35880 $data['suggest'] = $packages;
 35881 }
 35882 
 35883 if ($package->getReleaseDate()) {
 35884 $data['time'] = $package->getReleaseDate()->format(DATE_RFC3339);
 35885 }
 35886 
 35887 if ($package->isDefaultBranch()) {
 35888 $data['default-branch'] = true;
 35889 }
 35890 
 35891 $data = $this->dumpValues($package, $keys, $data);
 35892 
 35893 if ($package instanceof CompletePackageInterface) {
 35894 if ($package->getArchiveName()) {
 35895 $data['archive']['name'] = $package->getArchiveName();
 35896 }
 35897 if ($package->getArchiveExcludes()) {
 35898 $data['archive']['exclude'] = $package->getArchiveExcludes();
 35899 }
 35900 
 35901 $keys = array(
 35902 'scripts',
 35903 'license',
 35904 'authors',
 35905 'description',
 35906 'homepage',
 35907 'keywords',
 35908 'repositories',
 35909 'support',
 35910 'funding',
 35911 );
 35912 
 35913 $data = $this->dumpValues($package, $keys, $data);
 35914 
 35915 if (isset($data['keywords']) && \is_array($data['keywords'])) {
 35916 sort($data['keywords']);
 35917 }
 35918 
 35919 if ($package->isAbandoned()) {
 35920 $data['abandoned'] = $package->getReplacementPackage() ?: true;
 35921 }
 35922 }
 35923 
 35924 if ($package instanceof RootPackageInterface) {
 35925 $minimumStability = $package->getMinimumStability();
 35926 if ($minimumStability) {
 35927 $data['minimum-stability'] = $minimumStability;
 35928 }
 35929 }
 35930 
 35931 if (\count($package->getTransportOptions()) > 0) {
 35932 $data['transport-options'] = $package->getTransportOptions();
 35933 }
 35934 
 35935 return $data;
 35936 }
 35937 
 35938 
 35939 
 35940 
 35941 
 35942 
 35943 
 35944 private function dumpValues(PackageInterface $package, array $keys, array $data)
 35945 {
 35946 foreach ($keys as $method => $key) {
 35947 if (is_numeric($method)) {
 35948 $method = $key;
 35949 }
 35950 
 35951 $getter = 'get'.ucfirst($method);
 35952 $value = $package->$getter();
 35953 
 35954 if (null !== $value && !(\is_array($value) && 0 === \count($value))) {
 35955 $data[$key] = $value;
 35956 }
 35957 }
 35958 
 35959 return $data;
 35960 }
 35961 }
 35962 <?php
 35963 
 35964 
 35965 
 35966 
 35967 
 35968 
 35969 
 35970 
 35971 
 35972 
 35973 
 35974 namespace Composer\Package;
 35975 
 35976 use Composer\Semver\Constraint\ConstraintInterface;
 35977 
 35978 
 35979 
 35980 
 35981 
 35982 
 35983 class Link
 35984 {
 35985 const TYPE_REQUIRE = 'requires';
 35986 const TYPE_DEV_REQUIRE = 'devRequires';
 35987 const TYPE_PROVIDE = 'provides';
 35988 const TYPE_CONFLICT = 'conflicts';
 35989 const TYPE_REPLACE = 'replaces';
 35990 
 35991 
 35992 
 35993 
 35994 
 35995 const TYPE_DOES_NOT_REQUIRE = 'does not require';
 35996 
 35997 
 35998 
 35999 
 36000 const TYPE_UNKNOWN = 'relates to';
 36001 
 36002 
 36003 
 36004 
 36005 
 36006 
 36007 
 36008 
 36009 public static $TYPES = array(
 36010 self::TYPE_REQUIRE,
 36011 self::TYPE_DEV_REQUIRE,
 36012 self::TYPE_PROVIDE,
 36013 self::TYPE_CONFLICT,
 36014 self::TYPE_REPLACE,
 36015 );
 36016 
 36017 
 36018 
 36019 
 36020 protected $source;
 36021 
 36022 
 36023 
 36024 
 36025 protected $target;
 36026 
 36027 
 36028 
 36029 
 36030 protected $constraint;
 36031 
 36032 
 36033 
 36034 
 36035 
 36036 protected $description;
 36037 
 36038 
 36039 
 36040 
 36041 protected $prettyConstraint;
 36042 
 36043 
 36044 
 36045 
 36046 
 36047 
 36048 
 36049 
 36050 
 36051 
 36052 public function __construct(
 36053 $source,
 36054 $target,
 36055 ConstraintInterface $constraint,
 36056 $description = self::TYPE_UNKNOWN,
 36057 $prettyConstraint = null
 36058 ) {
 36059 $this->source = strtolower($source);
 36060 $this->target = strtolower($target);
 36061 $this->constraint = $constraint;
 36062 $this->description = self::TYPE_DEV_REQUIRE === $description ? 'requires (for development)' : $description;
 36063 $this->prettyConstraint = $prettyConstraint;
 36064 }
 36065 
 36066 
 36067 
 36068 
 36069 public function getDescription()
 36070 {
 36071 return $this->description;
 36072 }
 36073 
 36074 
 36075 
 36076 
 36077 public function getSource()
 36078 {
 36079 return $this->source;
 36080 }
 36081 
 36082 
 36083 
 36084 
 36085 public function getTarget()
 36086 {
 36087 return $this->target;
 36088 }
 36089 
 36090 
 36091 
 36092 
 36093 public function getConstraint()
 36094 {
 36095 return $this->constraint;
 36096 }
 36097 
 36098 
 36099 
 36100 
 36101 
 36102 public function getPrettyConstraint()
 36103 {
 36104 if (null === $this->prettyConstraint) {
 36105 throw new \UnexpectedValueException(sprintf('Link %s has been misconfigured and had no prettyConstraint given.', $this));
 36106 }
 36107 
 36108 return $this->prettyConstraint;
 36109 }
 36110 
 36111 
 36112 
 36113 
 36114 public function __toString()
 36115 {
 36116 return $this->source.' '.$this->description.' '.$this->target.' ('.$this->constraint.')';
 36117 }
 36118 
 36119 
 36120 
 36121 
 36122 
 36123 public function getPrettyString(PackageInterface $sourcePackage)
 36124 {
 36125 return $sourcePackage->getPrettyString().' '.$this->description.' '.$this->target.' '.$this->constraint->getPrettyString();
 36126 }
 36127 }
 36128 <?php
 36129 
 36130 
 36131 
 36132 
 36133 
 36134 
 36135 
 36136 
 36137 
 36138 
 36139 
 36140 namespace Composer\Package\Loader;
 36141 
 36142 use Composer\Package\BasePackage;
 36143 use Composer\Package\CompleteAliasPackage;
 36144 use Composer\Package\CompletePackage;
 36145 use Composer\Package\RootPackage;
 36146 use Composer\Package\PackageInterface;
 36147 use Composer\Package\CompletePackageInterface;
 36148 use Composer\Package\Link;
 36149 use Composer\Package\RootAliasPackage;
 36150 use Composer\Package\Version\VersionParser;
 36151 use Composer\Pcre\Preg;
 36152 
 36153 
 36154 
 36155 
 36156 
 36157 class ArrayLoader implements LoaderInterface
 36158 {
 36159 
 36160 protected $versionParser;
 36161 
 36162 protected $loadOptions;
 36163 
 36164 
 36165 
 36166 
 36167 public function __construct(VersionParser $parser = null, $loadOptions = false)
 36168 {
 36169 if (!$parser) {
 36170 $parser = new VersionParser;
 36171 }
 36172 $this->versionParser = $parser;
 36173 $this->loadOptions = $loadOptions;
 36174 }
 36175 
 36176 
 36177 
 36178 
 36179 public function load(array $config, $class = 'Composer\Package\CompletePackage')
 36180 {
 36181 if ($class !== 'Composer\Package\CompletePackage' && $class !== 'Composer\Package\RootPackage') {
 36182 trigger_error('The $class arg is deprecated, please reach out to Composer maintainers ASAP if you still need this.', E_USER_DEPRECATED);
 36183 }
 36184 
 36185 $package = $this->createObject($config, $class);
 36186 
 36187 foreach (BasePackage::$supportedLinkTypes as $type => $opts) {
 36188 if (isset($config[$type])) {
 36189 $method = 'set'.ucfirst($opts['method']);
 36190 $package->{$method}(
 36191 $this->parseLinks(
 36192 $package->getName(),
 36193 $package->getPrettyVersion(),
 36194 $opts['method'],
 36195 $config[$type]
 36196 )
 36197 );
 36198 }
 36199 }
 36200 
 36201 $package = $this->configureObject($package, $config);
 36202 
 36203 return $package;
 36204 }
 36205 
 36206 
 36207 
 36208 
 36209 
 36210 
 36211 public function loadPackages(array $versions)
 36212 {
 36213 $packages = array();
 36214 $linkCache = array();
 36215 
 36216 foreach ($versions as $version) {
 36217 $package = $this->createObject($version, 'Composer\Package\CompletePackage');
 36218 
 36219 $this->configureCachedLinks($linkCache, $package, $version);
 36220 $package = $this->configureObject($package, $version);
 36221 
 36222 $packages[] = $package;
 36223 }
 36224 
 36225 return $packages;
 36226 }
 36227 
 36228 
 36229 
 36230 
 36231 
 36232 
 36233 
 36234 
 36235 
 36236 
 36237 
 36238 private function createObject(array $config, $class)
 36239 {
 36240 if (!isset($config['name'])) {
 36241 throw new \UnexpectedValueException('Unknown package has no name defined ('.json_encode($config).').');
 36242 }
 36243 if (!isset($config['version']) || !is_scalar($config['version'])) {
 36244 throw new \UnexpectedValueException('Package '.$config['name'].' has no version defined.');
 36245 }
 36246 if (!is_string($config['version'])) {
 36247 $config['version'] = (string) $config['version'];
 36248 }
 36249 
 36250 
 36251 if (isset($config['version_normalized']) && is_string($config['version_normalized'])) {
 36252 $version = $config['version_normalized'];
 36253 
 36254 
 36255 if ($version === VersionParser::DEFAULT_BRANCH_ALIAS) {
 36256 $version = $this->versionParser->normalize($config['version']);
 36257 }
 36258 } else {
 36259 $version = $this->versionParser->normalize($config['version']);
 36260 }
 36261 
 36262 return new $class($config['name'], $version, $config['version']);
 36263 }
 36264 
 36265 
 36266 
 36267 
 36268 
 36269 
 36270 
 36271 private function configureObject(PackageInterface $package, array $config)
 36272 {
 36273 if (!$package instanceof CompletePackage) {
 36274 throw new \LogicException('ArrayLoader expects instances of the Composer\Package\CompletePackage class to function correctly');
 36275 }
 36276 
 36277 $package->setType(isset($config['type']) ? strtolower($config['type']) : 'library');
 36278 
 36279 if (isset($config['target-dir'])) {
 36280 $package->setTargetDir($config['target-dir']);
 36281 }
 36282 
 36283 if (isset($config['extra']) && \is_array($config['extra'])) {
 36284 $package->setExtra($config['extra']);
 36285 }
 36286 
 36287 if (isset($config['bin'])) {
 36288 if (!\is_array($config['bin'])) {
 36289 $config['bin'] = array($config['bin']);
 36290 }
 36291 foreach ($config['bin'] as $key => $bin) {
 36292 $config['bin'][$key] = ltrim($bin, '/');
 36293 }
 36294 $package->setBinaries($config['bin']);
 36295 }
 36296 
 36297 if (isset($config['installation-source'])) {
 36298 $package->setInstallationSource($config['installation-source']);
 36299 }
 36300 
 36301 if (isset($config['default-branch']) && $config['default-branch'] === true) {
 36302 $package->setIsDefaultBranch(true);
 36303 }
 36304 
 36305 if (isset($config['source'])) {
 36306 if (!isset($config['source']['type'], $config['source']['url'], $config['source']['reference'])) {
 36307 throw new \UnexpectedValueException(sprintf(
 36308 "Package %s's source key should be specified as {\"type\": ..., \"url\": ..., \"reference\": ...},\n%s given.",
 36309 $config['name'],
 36310 json_encode($config['source'])
 36311 ));
 36312 }
 36313 $package->setSourceType($config['source']['type']);
 36314 $package->setSourceUrl($config['source']['url']);
 36315 $package->setSourceReference(isset($config['source']['reference']) ? $config['source']['reference'] : null);
 36316 if (isset($config['source']['mirrors'])) {
 36317 $package->setSourceMirrors($config['source']['mirrors']);
 36318 }
 36319 }
 36320 
 36321 if (isset($config['dist'])) {
 36322 if (!isset($config['dist']['type'], $config['dist']['url'])) {
 36323 throw new \UnexpectedValueException(sprintf(
 36324 "Package %s's dist key should be specified as ".
 36325 "{\"type\": ..., \"url\": ..., \"reference\": ..., \"shasum\": ...},\n%s given.",
 36326 $config['name'],
 36327 json_encode($config['dist'])
 36328 ));
 36329 }
 36330 $package->setDistType($config['dist']['type']);
 36331 $package->setDistUrl($config['dist']['url']);
 36332 $package->setDistReference(isset($config['dist']['reference']) ? $config['dist']['reference'] : null);
 36333 $package->setDistSha1Checksum(isset($config['dist']['shasum']) ? $config['dist']['shasum'] : null);
 36334 if (isset($config['dist']['mirrors'])) {
 36335 $package->setDistMirrors($config['dist']['mirrors']);
 36336 }
 36337 }
 36338 
 36339 if (isset($config['suggest']) && \is_array($config['suggest'])) {
 36340 foreach ($config['suggest'] as $target => $reason) {
 36341 if ('self.version' === trim($reason)) {
 36342 $config['suggest'][$target] = $package->getPrettyVersion();
 36343 }
 36344 }
 36345 $package->setSuggests($config['suggest']);
 36346 }
 36347 
 36348 if (isset($config['autoload'])) {
 36349 $package->setAutoload($config['autoload']);
 36350 }
 36351 
 36352 if (isset($config['autoload-dev'])) {
 36353 $package->setDevAutoload($config['autoload-dev']);
 36354 }
 36355 
 36356 if (isset($config['include-path'])) {
 36357 $package->setIncludePaths($config['include-path']);
 36358 }
 36359 
 36360 if (!empty($config['time'])) {
 36361 $time = Preg::isMatch('/^\d++$/D', $config['time']) ? '@'.$config['time'] : $config['time'];
 36362 
 36363 try {
 36364 $date = new \DateTime($time, new \DateTimeZone('UTC'));
 36365 $package->setReleaseDate($date);
 36366 } catch (\Exception $e) {
 36367 }
 36368 }
 36369 
 36370 if (!empty($config['notification-url'])) {
 36371 $package->setNotificationUrl($config['notification-url']);
 36372 }
 36373 
 36374 if ($package instanceof CompletePackageInterface) {
 36375 if (!empty($config['archive']['name'])) {
 36376 $package->setArchiveName($config['archive']['name']);
 36377 }
 36378 if (!empty($config['archive']['exclude'])) {
 36379 $package->setArchiveExcludes($config['archive']['exclude']);
 36380 }
 36381 
 36382 if (isset($config['scripts']) && \is_array($config['scripts'])) {
 36383 foreach ($config['scripts'] as $event => $listeners) {
 36384 $config['scripts'][$event] = (array) $listeners;
 36385 }
 36386 foreach (array('composer', 'php', 'putenv') as $reserved) {
 36387 if (isset($config['scripts'][$reserved])) {
 36388 trigger_error('The `'.$reserved.'` script name is reserved for internal use, please avoid defining it', E_USER_DEPRECATED);
 36389 }
 36390 }
 36391 $package->setScripts($config['scripts']);
 36392 }
 36393 
 36394 if (!empty($config['description']) && \is_string($config['description'])) {
 36395 $package->setDescription($config['description']);
 36396 }
 36397 
 36398 if (!empty($config['homepage']) && \is_string($config['homepage'])) {
 36399 $package->setHomepage($config['homepage']);
 36400 }
 36401 
 36402 if (!empty($config['keywords']) && \is_array($config['keywords'])) {
 36403 $package->setKeywords($config['keywords']);
 36404 }
 36405 
 36406 if (!empty($config['license'])) {
 36407 $package->setLicense(\is_array($config['license']) ? $config['license'] : array($config['license']));
 36408 }
 36409 
 36410 if (!empty($config['authors']) && \is_array($config['authors'])) {
 36411 $package->setAuthors($config['authors']);
 36412 }
 36413 
 36414 if (isset($config['support'])) {
 36415 $package->setSupport($config['support']);
 36416 }
 36417 
 36418 if (!empty($config['funding']) && \is_array($config['funding'])) {
 36419 $package->setFunding($config['funding']);
 36420 }
 36421 
 36422 if (isset($config['abandoned'])) {
 36423 $package->setAbandoned($config['abandoned']);
 36424 }
 36425 }
 36426 
 36427 if ($this->loadOptions && isset($config['transport-options'])) {
 36428 $package->setTransportOptions($config['transport-options']);
 36429 }
 36430 
 36431 if ($aliasNormalized = $this->getBranchAlias($config)) {
 36432 $prettyAlias = Preg::replace('{(\.9{7})+}', '.x', $aliasNormalized);
 36433 
 36434 if ($package instanceof RootPackage) {
 36435 return new RootAliasPackage($package, $aliasNormalized, $prettyAlias);
 36436 }
 36437 
 36438 return new CompleteAliasPackage($package, $aliasNormalized, $prettyAlias);
 36439 }
 36440 
 36441 return $package;
 36442 }
 36443 
 36444 
 36445 
 36446 
 36447 
 36448 
 36449 
 36450 
 36451 private function configureCachedLinks(&$linkCache, $package, array $config)
 36452 {
 36453 $name = $package->getName();
 36454 $prettyVersion = $package->getPrettyVersion();
 36455 
 36456 foreach (BasePackage::$supportedLinkTypes as $type => $opts) {
 36457 if (isset($config[$type])) {
 36458 $method = 'set'.ucfirst($opts['method']);
 36459 
 36460 $links = array();
 36461 foreach ($config[$type] as $prettyTarget => $constraint) {
 36462 $target = strtolower($prettyTarget);
 36463 
 36464 
 36465 if ($target === $name) {
 36466 continue;
 36467 }
 36468 
 36469 if ($constraint === 'self.version') {
 36470 $links[$target] = $this->createLink($name, $prettyVersion, $opts['method'], $target, $constraint);
 36471 } else {
 36472 if (!isset($linkCache[$name][$type][$target][$constraint])) {
 36473 $linkCache[$name][$type][$target][$constraint] = array($target, $this->createLink($name, $prettyVersion, $opts['method'], $target, $constraint));
 36474 }
 36475 
 36476 list($target, $link) = $linkCache[$name][$type][$target][$constraint];
 36477 $links[$target] = $link;
 36478 }
 36479 }
 36480 
 36481 $package->{$method}($links);
 36482 }
 36483 }
 36484 }
 36485 
 36486 
 36487 
 36488 
 36489 
 36490 
 36491 
 36492 
 36493 
 36494 
 36495 
 36496 public function parseLinks($source, $sourceVersion, $description, $links)
 36497 {
 36498 $res = array();
 36499 foreach ($links as $target => $constraint) {
 36500 $target = strtolower($target);
 36501 $res[$target] = $this->createLink($source, $sourceVersion, $description, $target, $constraint);
 36502 }
 36503 
 36504 return $res;
 36505 }
 36506 
 36507 
 36508 
 36509 
 36510 
 36511 
 36512 
 36513 
 36514 
 36515 private function createLink($source, $sourceVersion, $description, $target, $prettyConstraint)
 36516 {
 36517 if (!\is_string($prettyConstraint)) {
 36518 throw new \UnexpectedValueException('Link constraint in '.$source.' '.$description.' > '.$target.' should be a string, got '.\gettype($prettyConstraint) . ' (' . var_export($prettyConstraint, true) . ')');
 36519 }
 36520 if ('self.version' === $prettyConstraint) {
 36521 $parsedConstraint = $this->versionParser->parseConstraints($sourceVersion);
 36522 } else {
 36523 $parsedConstraint = $this->versionParser->parseConstraints($prettyConstraint);
 36524 }
 36525 
 36526 return new Link($source, $target, $parsedConstraint, $description, $prettyConstraint);
 36527 }
 36528 
 36529 
 36530 
 36531 
 36532 
 36533 
 36534 
 36535 
 36536 public function getBranchAlias(array $config)
 36537 {
 36538 if (strpos($config['version'], 'dev-') !== 0 && '-dev' !== substr($config['version'], -4)) {
 36539 return null;
 36540 }
 36541 
 36542 if (isset($config['extra']['branch-alias']) && \is_array($config['extra']['branch-alias'])) {
 36543 foreach ($config['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
 36544 
 36545 if ('-dev' !== substr($targetBranch, -4)) {
 36546 continue;
 36547 }
 36548 
 36549 
 36550 if ($targetBranch === VersionParser::DEFAULT_BRANCH_ALIAS) {
 36551 $validatedTargetBranch = VersionParser::DEFAULT_BRANCH_ALIAS;
 36552 } else {
 36553 $validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
 36554 }
 36555 if ('-dev' !== substr($validatedTargetBranch, -4)) {
 36556 continue;
 36557 }
 36558 
 36559 
 36560 if (strtolower($config['version']) !== strtolower($sourceBranch)) {
 36561 continue;
 36562 }
 36563 
 36564 
 36565 if (($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
 36566 && ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
 36567 && (stripos($targetPrefix, $sourcePrefix) !== 0)
 36568 ) {
 36569 continue;
 36570 }
 36571 
 36572 return $validatedTargetBranch;
 36573 }
 36574 }
 36575 
 36576 if (
 36577 isset($config['default-branch'])
 36578 && $config['default-branch'] === true
 36579 && false === $this->versionParser->parseNumericAliasPrefix($config['version'])
 36580 ) {
 36581 return VersionParser::DEFAULT_BRANCH_ALIAS;
 36582 }
 36583 
 36584 return null;
 36585 }
 36586 }
 36587 <?php
 36588 
 36589 
 36590 
 36591 
 36592 
 36593 
 36594 
 36595 
 36596 
 36597 
 36598 
 36599 namespace Composer\Package\Loader;
 36600 
 36601 
 36602 
 36603 
 36604 class InvalidPackageException extends \Exception
 36605 {
 36606 
 36607 private $errors;
 36608 
 36609 private $warnings;
 36610 
 36611 private $data;
 36612 
 36613 
 36614 
 36615 
 36616 
 36617 
 36618 public function __construct(array $errors, array $warnings, array $data)
 36619 {
 36620 $this->errors = $errors;
 36621 $this->warnings = $warnings;
 36622 $this->data = $data;
 36623 parent::__construct("Invalid package information: \n".implode("\n", array_merge($errors, $warnings)));
 36624 }
 36625 
 36626 
 36627 
 36628 
 36629 public function getData()
 36630 {
 36631 return $this->data;
 36632 }
 36633 
 36634 
 36635 
 36636 
 36637 public function getErrors()
 36638 {
 36639 return $this->errors;
 36640 }
 36641 
 36642 
 36643 
 36644 
 36645 public function getWarnings()
 36646 {
 36647 return $this->warnings;
 36648 }
 36649 }
 36650 <?php
 36651 
 36652 
 36653 
 36654 
 36655 
 36656 
 36657 
 36658 
 36659 
 36660 
 36661 
 36662 namespace Composer\Package\Loader;
 36663 
 36664 use Composer\Json\JsonFile;
 36665 use Composer\Package\CompletePackage;
 36666 use Composer\Package\CompleteAliasPackage;
 36667 
 36668 
 36669 
 36670 
 36671 class JsonLoader
 36672 {
 36673 
 36674 private $loader;
 36675 
 36676 public function __construct(LoaderInterface $loader)
 36677 {
 36678 $this->loader = $loader;
 36679 }
 36680 
 36681 
 36682 
 36683 
 36684 
 36685 public function load($json)
 36686 {
 36687 if ($json instanceof JsonFile) {
 36688 $config = $json->read();
 36689 } elseif (file_exists($json)) {
 36690 $config = JsonFile::parseJson(file_get_contents($json), $json);
 36691 } elseif (is_string($json)) {
 36692 $config = JsonFile::parseJson($json);
 36693 } else {
 36694 throw new \InvalidArgumentException(sprintf(
 36695 "JsonLoader: Unknown \$json parameter %s. Please report at https://github.com/composer/composer/issues/new.",
 36696 gettype($json)
 36697 ));
 36698 }
 36699 
 36700 return $this->loader->load($config);
 36701 }
 36702 }
 36703 <?php
 36704 
 36705 
 36706 
 36707 
 36708 
 36709 
 36710 
 36711 
 36712 
 36713 
 36714 
 36715 namespace Composer\Package\Loader;
 36716 
 36717 use Composer\Package\CompletePackageInterface;
 36718 use Composer\Package\CompletePackage;
 36719 use Composer\Package\CompleteAliasPackage;
 36720 use Composer\Package\RootAliasPackage;
 36721 use Composer\Package\RootPackage;
 36722 
 36723 
 36724 
 36725 
 36726 
 36727 
 36728 interface LoaderInterface
 36729 {
 36730 
 36731 
 36732 
 36733 
 36734 
 36735 
 36736 
 36737 
 36738 
 36739 
 36740 
 36741 
 36742 public function load(array $config, $class = 'Composer\Package\CompletePackage');
 36743 }
 36744 <?php
 36745 
 36746 
 36747 
 36748 
 36749 
 36750 
 36751 
 36752 
 36753 
 36754 
 36755 
 36756 namespace Composer\Package\Loader;
 36757 
 36758 use Composer\Package\BasePackage;
 36759 use Composer\Config;
 36760 use Composer\IO\IOInterface;
 36761 use Composer\Package\RootAliasPackage;
 36762 use Composer\Pcre\Preg;
 36763 use Composer\Repository\RepositoryFactory;
 36764 use Composer\Package\Version\VersionGuesser;
 36765 use Composer\Package\Version\VersionParser;
 36766 use Composer\Package\RootPackage;
 36767 use Composer\Repository\RepositoryManager;
 36768 use Composer\Util\Platform;
 36769 use Composer\Util\ProcessExecutor;
 36770 
 36771 
 36772 
 36773 
 36774 
 36775 
 36776 
 36777 
 36778 class RootPackageLoader extends ArrayLoader
 36779 {
 36780 
 36781 
 36782 
 36783 private $manager;
 36784 
 36785 
 36786 
 36787 
 36788 private $config;
 36789 
 36790 
 36791 
 36792 
 36793 private $versionGuesser;
 36794 
 36795 public function __construct(RepositoryManager $manager, Config $config, VersionParser $parser = null, VersionGuesser $versionGuesser = null, IOInterface $io = null)
 36796 {
 36797 parent::__construct($parser);
 36798 
 36799 $this->manager = $manager;
 36800 $this->config = $config;
 36801 $this->versionGuesser = $versionGuesser ?: new VersionGuesser($config, new ProcessExecutor($io), $this->versionParser);
 36802 }
 36803 
 36804 
 36805 
 36806 
 36807 
 36808 
 36809 
 36810 
 36811 
 36812 
 36813 
 36814 
 36815 public function load(array $config, $class = 'Composer\Package\RootPackage', $cwd = null)
 36816 {
 36817 if ($class !== 'Composer\Package\RootPackage') {
 36818 trigger_error('The $class arg is deprecated, please reach out to Composer maintainers ASAP if you still need this.', E_USER_DEPRECATED);
 36819 }
 36820 
 36821 if (!isset($config['name'])) {
 36822 $config['name'] = '__root__';
 36823 } elseif ($err = ValidatingArrayLoader::hasPackageNamingError($config['name'])) {
 36824 throw new \RuntimeException('Your package name '.$err);
 36825 }
 36826 $autoVersioned = false;
 36827 if (!isset($config['version'])) {
 36828 $commit = null;
 36829 
 36830 
 36831 if (Platform::getEnv('COMPOSER_ROOT_VERSION')) {
 36832 $config['version'] = Platform::getEnv('COMPOSER_ROOT_VERSION');
 36833 } else {
 36834 $versionData = $this->versionGuesser->guessVersion($config, $cwd ?: getcwd());
 36835 if ($versionData) {
 36836 $config['version'] = $versionData['pretty_version'];
 36837 $config['version_normalized'] = $versionData['version'];
 36838 $commit = $versionData['commit'];
 36839 }
 36840 }
 36841 
 36842 if (!isset($config['version'])) {
 36843 $config['version'] = '1.0.0';
 36844 $autoVersioned = true;
 36845 }
 36846 
 36847 if ($commit) {
 36848 $config['source'] = array(
 36849 'type' => '',
 36850 'url' => '',
 36851 'reference' => $commit,
 36852 );
 36853 $config['dist'] = array(
 36854 'type' => '',
 36855 'url' => '',
 36856 'reference' => $commit,
 36857 );
 36858 }
 36859 }
 36860 
 36861 
 36862 $package = parent::load($config, $class);
 36863 if ($package instanceof RootAliasPackage) {
 36864 $realPackage = $package->getAliasOf();
 36865 } else {
 36866 $realPackage = $package;
 36867 }
 36868 
 36869 if (!$realPackage instanceof RootPackage) {
 36870 throw new \LogicException('Expecting a Composer\Package\RootPackage at this point');
 36871 }
 36872 
 36873 if ($autoVersioned) {
 36874 $realPackage->replaceVersion($realPackage->getVersion(), RootPackage::DEFAULT_PRETTY_VERSION);
 36875 }
 36876 
 36877 if (isset($config['minimum-stability'])) {
 36878 $realPackage->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability']));
 36879 }
 36880 
 36881 $aliases = array();
 36882 $stabilityFlags = array();
 36883 $references = array();
 36884 foreach (array('require', 'require-dev') as $linkType) {
 36885 if (isset($config[$linkType])) {
 36886 $linkInfo = BasePackage::$supportedLinkTypes[$linkType];
 36887 $method = 'get'.ucfirst($linkInfo['method']);
 36888 $links = array();
 36889 foreach ($realPackage->$method() as $link) {
 36890 $links[$link->getTarget()] = $link->getConstraint()->getPrettyString();
 36891 }
 36892 $aliases = $this->extractAliases($links, $aliases);
 36893 $stabilityFlags = self::extractStabilityFlags($links, $realPackage->getMinimumStability(), $stabilityFlags);
 36894 $references = self::extractReferences($links, $references);
 36895 
 36896 if (isset($links[$config['name']])) {
 36897 throw new \RuntimeException(sprintf('Root package \'%s\' cannot require itself in its composer.json' . PHP_EOL .
 36898 'Did you accidentally name your root package after an external package?', $config['name']));
 36899 }
 36900 }
 36901 }
 36902 
 36903 foreach (array_keys(BasePackage::$supportedLinkTypes) as $linkType) {
 36904 if (isset($config[$linkType])) {
 36905 foreach ($config[$linkType] as $linkName => $constraint) {
 36906 if ($err = ValidatingArrayLoader::hasPackageNamingError($linkName, true)) {
 36907 throw new \RuntimeException($linkType.'.'.$err);
 36908 }
 36909 }
 36910 }
 36911 }
 36912 
 36913 $realPackage->setAliases($aliases);
 36914 $realPackage->setStabilityFlags($stabilityFlags);
 36915 $realPackage->setReferences($references);
 36916 
 36917 if (isset($config['prefer-stable'])) {
 36918 $realPackage->setPreferStable((bool) $config['prefer-stable']);
 36919 }
 36920 
 36921 if (isset($config['config'])) {
 36922 $realPackage->setConfig($config['config']);
 36923 }
 36924 
 36925 $repos = RepositoryFactory::defaultRepos(null, $this->config, $this->manager);
 36926 foreach ($repos as $repo) {
 36927 $this->manager->addRepository($repo);
 36928 }
 36929 $realPackage->setRepositories($this->config->getRepositories());
 36930 
 36931 return $package;
 36932 }
 36933 
 36934 
 36935 
 36936 
 36937 
 36938 
 36939 
 36940 private function extractAliases(array $requires, array $aliases)
 36941 {
 36942 foreach ($requires as $reqName => $reqVersion) {
 36943 if (Preg::isMatch('{^([^,\s#]+)(?:#[^ ]+)? +as +([^,\s]+)$}', $reqVersion, $match)) {
 36944 $aliases[] = array(
 36945 'package' => strtolower($reqName),
 36946 'version' => $this->versionParser->normalize($match[1], $reqVersion),
 36947 'alias' => $match[2],
 36948 'alias_normalized' => $this->versionParser->normalize($match[2], $reqVersion),
 36949 );
 36950 } elseif (strpos($reqVersion, ' as ') !== false) {
 36951 throw new \UnexpectedValueException('Invalid alias definition in "'.$reqName.'": "'.$reqVersion.'". Aliases should be in the form "exact-version as other-exact-version".');
 36952 }
 36953 }
 36954 
 36955 return $aliases;
 36956 }
 36957 
 36958 
 36959 
 36960 
 36961 
 36962 
 36963 
 36964 
 36965 
 36966 
 36967 
 36968 
 36969 
 36970 public static function extractStabilityFlags(array $requires, $minimumStability, array $stabilityFlags)
 36971 {
 36972 $stabilities = BasePackage::$stabilities;
 36973 
 36974 $minimumStability = $stabilities[$minimumStability];
 36975 foreach ($requires as $reqName => $reqVersion) {
 36976 $constraints = array();
 36977 
 36978 
 36979 $orSplit = Preg::split('{\s*\|\|?\s*}', trim($reqVersion));
 36980 foreach ($orSplit as $orConstraint) {
 36981 $andSplit = Preg::split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $orConstraint);
 36982 foreach ($andSplit as $andConstraint) {
 36983 $constraints[] = $andConstraint;
 36984 }
 36985 }
 36986 
 36987 
 36988 $match = false;
 36989 foreach ($constraints as $constraint) {
 36990 if (Preg::isMatch('{^[^@]*?@('.implode('|', array_keys($stabilities)).')$}i', $constraint, $match)) {
 36991 $name = strtolower($reqName);
 36992 $stability = $stabilities[VersionParser::normalizeStability($match[1])];
 36993 
 36994 if (isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) {
 36995 continue;
 36996 }
 36997 $stabilityFlags[$name] = $stability;
 36998 $match = true;
 36999 }
 37000 }
 37001 
 37002 if ($match) {
 37003 continue;
 37004 }
 37005 
 37006 foreach ($constraints as $constraint) {
 37007 
 37008 
 37009 $reqVersion = Preg::replace('{^([^,\s@]+) as .+$}', '$1', $constraint);
 37010 if (Preg::isMatch('{^[^,\s@]+$}', $reqVersion) && 'stable' !== ($stabilityName = VersionParser::parseStability($reqVersion))) {
 37011 $name = strtolower($reqName);
 37012 $stability = $stabilities[$stabilityName];
 37013 if ((isset($stabilityFlags[$name]) && $stabilityFlags[$name] > $stability) || ($minimumStability > $stability)) {
 37014 continue;
 37015 }
 37016 $stabilityFlags[$name] = $stability;
 37017 }
 37018 }
 37019 }
 37020 
 37021 return $stabilityFlags;
 37022 }
 37023 
 37024 
 37025 
 37026 
 37027 
 37028 
 37029 
 37030 
 37031 
 37032 public static function extractReferences(array $requires, array $references)
 37033 {
 37034 foreach ($requires as $reqName => $reqVersion) {
 37035 $reqVersion = Preg::replace('{^([^,\s@]+) as .+$}', '$1', $reqVersion);
 37036 if (Preg::isMatch('{^[^,\s@]+?#([a-f0-9]+)$}', $reqVersion, $match) && 'dev' === VersionParser::parseStability($reqVersion)) {
 37037 $name = strtolower($reqName);
 37038 $references[$name] = $match[1];
 37039 }
 37040 }
 37041 
 37042 return $references;
 37043 }
 37044 }
 37045 <?php
 37046 
 37047 
 37048 
 37049 
 37050 
 37051 
 37052 
 37053 
 37054 
 37055 
 37056 
 37057 namespace Composer\Package\Loader;
 37058 
 37059 use Composer\Package\BasePackage;
 37060 use Composer\Pcre\Preg;
 37061 use Composer\Semver\Constraint\Constraint;
 37062 use Composer\Package\Version\VersionParser;
 37063 use Composer\Repository\PlatformRepository;
 37064 use Composer\Spdx\SpdxLicenses;
 37065 
 37066 
 37067 
 37068 
 37069 class ValidatingArrayLoader implements LoaderInterface
 37070 {
 37071 const CHECK_ALL = 3;
 37072 const CHECK_UNBOUND_CONSTRAINTS = 1;
 37073 const CHECK_STRICT_CONSTRAINTS = 2;
 37074 
 37075 
 37076 private $loader;
 37077 
 37078 private $versionParser;
 37079 
 37080 private $errors;
 37081 
 37082 private $warnings;
 37083 
 37084 private $config;
 37085 
 37086 private $flags;
 37087 
 37088 
 37089 
 37090 
 37091 
 37092 public function __construct(LoaderInterface $loader, $strictName = true, VersionParser $parser = null, $flags = 0)
 37093 {
 37094 $this->loader = $loader;
 37095 $this->versionParser = $parser ?: new VersionParser();
 37096 $this->flags = $flags;
 37097 
 37098 if ($strictName !== true) { 
 37099 trigger_error('$strictName must be set to true in ValidatingArrayLoader\'s constructor as of 2.2, and it will be removed in 3.0', E_USER_DEPRECATED);
 37100 }
 37101 }
 37102 
 37103 
 37104 
 37105 
 37106 public function load(array $config, $class = 'Composer\Package\CompletePackage')
 37107 {
 37108 $this->errors = array();
 37109 $this->warnings = array();
 37110 $this->config = $config;
 37111 
 37112 $this->validateString('name', true);
 37113 if ($err = self::hasPackageNamingError($config['name'])) {
 37114 $this->errors[] = 'name : '.$err;
 37115 }
 37116 
 37117 if (!empty($this->config['version'])) {
 37118 if (!is_scalar($this->config['version'])) {
 37119 $this->validateString('version');
 37120 } else {
 37121 if (!is_string($this->config['version'])) {
 37122 $this->config['version'] = (string) $this->config['version'];
 37123 }
 37124 try {
 37125 $this->versionParser->normalize($this->config['version']);
 37126 } catch (\Exception $e) {
 37127 $this->errors[] = 'version : invalid value ('.$this->config['version'].'): '.$e->getMessage();
 37128 unset($this->config['version']);
 37129 }
 37130 }
 37131 }
 37132 
 37133 if (!empty($this->config['config']['platform'])) {
 37134 foreach ((array) $this->config['config']['platform'] as $key => $platform) {
 37135 if (false === $platform) {
 37136 continue;
 37137 }
 37138 if (!is_string($platform)) {
 37139 $this->errors[] = 'config.platform.' . $key . ' : invalid value ('.gettype($platform).' '.var_export($platform, true).'): expected string or false';
 37140 continue;
 37141 }
 37142 try {
 37143 $this->versionParser->normalize($platform);
 37144 } catch (\Exception $e) {
 37145 $this->errors[] = 'config.platform.' . $key . ' : invalid value ('.$platform.'): '.$e->getMessage();
 37146 }
 37147 }
 37148 }
 37149 
 37150 $this->validateRegex('type', '[A-Za-z0-9-]+');
 37151 $this->validateString('target-dir');
 37152 $this->validateArray('extra');
 37153 
 37154 if (isset($this->config['bin'])) {
 37155 if (is_string($this->config['bin'])) {
 37156 $this->validateString('bin');
 37157 } else {
 37158 $this->validateFlatArray('bin');
 37159 }
 37160 }
 37161 
 37162 $this->validateArray('scripts'); 
 37163 $this->validateString('description');
 37164 $this->validateUrl('homepage');
 37165 $this->validateFlatArray('keywords', '[\p{N}\p{L} ._-]+');
 37166 
 37167 $releaseDate = null;
 37168 $this->validateString('time');
 37169 if (!empty($this->config['time'])) {
 37170 try {
 37171 $releaseDate = new \DateTime($this->config['time'], new \DateTimeZone('UTC'));
 37172 } catch (\Exception $e) {
 37173 $this->errors[] = 'time : invalid value ('.$this->config['time'].'): '.$e->getMessage();
 37174 unset($this->config['time']);
 37175 }
 37176 }
 37177 
 37178 
 37179 if (isset($this->config['license']) && (!$releaseDate || $releaseDate->getTimestamp() >= strtotime('-8days'))) {
 37180 if (is_array($this->config['license']) || is_string($this->config['license'])) {
 37181 $licenses = (array) $this->config['license'];
 37182 
 37183 $licenseValidator = new SpdxLicenses();
 37184 foreach ($licenses as $license) {
 37185 
 37186 if ('proprietary' === $license) {
 37187 continue;
 37188 }
 37189 $licenseToValidate = str_replace('proprietary', 'MIT', $license);
 37190 if (!$licenseValidator->validate($licenseToValidate)) {
 37191 if ($licenseValidator->validate(trim($licenseToValidate))) {
 37192 $this->warnings[] = sprintf(
 37193 'License %s must not contain extra spaces, make sure to trim it.',
 37194 json_encode($license)
 37195 );
 37196 } else {
 37197 $this->warnings[] = sprintf(
 37198 'License %s is not a valid SPDX license identifier, see https://spdx.org/licenses/ if you use an open license.' . PHP_EOL .
 37199 'If the software is closed-source, you may use "proprietary" as license.',
 37200 json_encode($license)
 37201 );
 37202 }
 37203 }
 37204 }
 37205 }
 37206 }
 37207 
 37208 if ($this->validateArray('authors') && !empty($this->config['authors'])) {
 37209 foreach ($this->config['authors'] as $key => $author) {
 37210 if (!is_array($author)) {
 37211 $this->errors[] = 'authors.'.$key.' : should be an array, '.gettype($author).' given';
 37212 unset($this->config['authors'][$key]);
 37213 continue;
 37214 }
 37215 foreach (array('homepage', 'email', 'name', 'role') as $authorData) {
 37216 if (isset($author[$authorData]) && !is_string($author[$authorData])) {
 37217 $this->errors[] = 'authors.'.$key.'.'.$authorData.' : invalid value, must be a string';
 37218 unset($this->config['authors'][$key][$authorData]);
 37219 }
 37220 }
 37221 if (isset($author['homepage']) && !$this->filterUrl($author['homepage'])) {
 37222 $this->warnings[] = 'authors.'.$key.'.homepage : invalid value ('.$author['homepage'].'), must be an http/https URL';
 37223 unset($this->config['authors'][$key]['homepage']);
 37224 }
 37225 if (isset($author['email']) && !filter_var($author['email'], FILTER_VALIDATE_EMAIL)) {
 37226 $this->warnings[] = 'authors.'.$key.'.email : invalid value ('.$author['email'].'), must be a valid email address';
 37227 unset($this->config['authors'][$key]['email']);
 37228 }
 37229 if (empty($this->config['authors'][$key])) {
 37230 unset($this->config['authors'][$key]);
 37231 }
 37232 }
 37233 if (empty($this->config['authors'])) {
 37234 unset($this->config['authors']);
 37235 }
 37236 }
 37237 
 37238 if ($this->validateArray('support') && !empty($this->config['support'])) {
 37239 foreach (array('issues', 'forum', 'wiki', 'source', 'email', 'irc', 'docs', 'rss', 'chat') as $key) {
 37240 if (isset($this->config['support'][$key]) && !is_string($this->config['support'][$key])) {
 37241 $this->errors[] = 'support.'.$key.' : invalid value, must be a string';
 37242 unset($this->config['support'][$key]);
 37243 }
 37244 }
 37245 
 37246 if (isset($this->config['support']['email']) && !filter_var($this->config['support']['email'], FILTER_VALIDATE_EMAIL)) {
 37247 $this->warnings[] = 'support.email : invalid value ('.$this->config['support']['email'].'), must be a valid email address';
 37248 unset($this->config['support']['email']);
 37249 }
 37250 
 37251 if (isset($this->config['support']['irc']) && !$this->filterUrl($this->config['support']['irc'], array('irc', 'ircs'))) {
 37252 $this->warnings[] = 'support.irc : invalid value ('.$this->config['support']['irc'].'), must be a irc://<server>/<channel> or ircs:// URL';
 37253 unset($this->config['support']['irc']);
 37254 }
 37255 
 37256 foreach (array('issues', 'forum', 'wiki', 'source', 'docs', 'chat') as $key) {
 37257 if (isset($this->config['support'][$key]) && !$this->filterUrl($this->config['support'][$key])) {
 37258 $this->warnings[] = 'support.'.$key.' : invalid value ('.$this->config['support'][$key].'), must be an http/https URL';
 37259 unset($this->config['support'][$key]);
 37260 }
 37261 }
 37262 if (empty($this->config['support'])) {
 37263 unset($this->config['support']);
 37264 }
 37265 }
 37266 
 37267 if ($this->validateArray('funding') && !empty($this->config['funding'])) {
 37268 foreach ($this->config['funding'] as $key => $fundingOption) {
 37269 if (!is_array($fundingOption)) {
 37270 $this->errors[] = 'funding.'.$key.' : should be an array, '.gettype($fundingOption).' given';
 37271 unset($this->config['funding'][$key]);
 37272 continue;
 37273 }
 37274 foreach (array('type', 'url') as $fundingData) {
 37275 if (isset($fundingOption[$fundingData]) && !is_string($fundingOption[$fundingData])) {
 37276 $this->errors[] = 'funding.'.$key.'.'.$fundingData.' : invalid value, must be a string';
 37277 unset($this->config['funding'][$key][$fundingData]);
 37278 }
 37279 }
 37280 if (isset($fundingOption['url']) && !$this->filterUrl($fundingOption['url'])) {
 37281 $this->warnings[] = 'funding.'.$key.'.url : invalid value ('.$fundingOption['url'].'), must be an http/https URL';
 37282 unset($this->config['funding'][$key]['url']);
 37283 }
 37284 if (empty($this->config['funding'][$key])) {
 37285 unset($this->config['funding'][$key]);
 37286 }
 37287 }
 37288 if (empty($this->config['funding'])) {
 37289 unset($this->config['funding']);
 37290 }
 37291 }
 37292 
 37293 $unboundConstraint = new Constraint('=', '10000000-dev');
 37294 $stableConstraint = new Constraint('=', '1.0.0');
 37295 
 37296 foreach (array_keys(BasePackage::$supportedLinkTypes) as $linkType) {
 37297 if ($this->validateArray($linkType) && isset($this->config[$linkType])) {
 37298 foreach ($this->config[$linkType] as $package => $constraint) {
 37299 if (0 === strcasecmp($package, $this->config['name'])) {
 37300 $this->errors[] = $linkType.'.'.$package.' : a package cannot set a '.$linkType.' on itself';
 37301 unset($this->config[$linkType][$package]);
 37302 continue;
 37303 }
 37304 if ($err = self::hasPackageNamingError($package, true)) {
 37305 $this->errors[] = $linkType.'.'.$err;
 37306 } elseif (!Preg::isMatch('{^[A-Za-z0-9_./-]+$}', $package)) {
 37307 $this->warnings[] = $linkType.'.'.$package.' : invalid key, package names must be strings containing only [A-Za-z0-9_./-]';
 37308 }
 37309 if (!is_string($constraint)) {
 37310 $this->errors[] = $linkType.'.'.$package.' : invalid value, must be a string containing a version constraint';
 37311 unset($this->config[$linkType][$package]);
 37312 } elseif ('self.version' !== $constraint) {
 37313 try {
 37314 $linkConstraint = $this->versionParser->parseConstraints($constraint);
 37315 } catch (\Exception $e) {
 37316 $this->errors[] = $linkType.'.'.$package.' : invalid version constraint ('.$e->getMessage().')';
 37317 unset($this->config[$linkType][$package]);
 37318 continue;
 37319 }
 37320 
 37321 
 37322 if (
 37323 ($this->flags & self::CHECK_UNBOUND_CONSTRAINTS)
 37324 && 'require' === $linkType
 37325 && $linkConstraint->matches($unboundConstraint)
 37326 && !PlatformRepository::isPlatformPackage($package)
 37327 ) {
 37328 $this->warnings[] = $linkType.'.'.$package.' : unbound version constraints ('.$constraint.') should be avoided';
 37329 } elseif (
 37330 
 37331 ($this->flags & self::CHECK_STRICT_CONSTRAINTS)
 37332 && 'require' === $linkType
 37333 && strpos($linkConstraint, '=') === 0
 37334 && $stableConstraint->versionCompare($stableConstraint, $linkConstraint, '<=')
 37335 ) {
 37336 $this->warnings[] = $linkType.'.'.$package.' : exact version constraints ('.$constraint.') should be avoided if the package follows semantic versioning';
 37337 }
 37338 }
 37339 
 37340 if ($linkType === 'conflict' && isset($this->config['replace']) && $keys = array_intersect_key($this->config['replace'], $this->config['conflict'])) {
 37341 $this->errors[] = $linkType.'.'.$package.' : you cannot conflict with a package that is also replaced, as replace already creates an implicit conflict rule';
 37342 unset($this->config[$linkType][$package]);
 37343 }
 37344 }
 37345 }
 37346 }
 37347 
 37348 if ($this->validateArray('suggest') && !empty($this->config['suggest'])) {
 37349 foreach ($this->config['suggest'] as $package => $description) {
 37350 if (!is_string($description)) {
 37351 $this->errors[] = 'suggest.'.$package.' : invalid value, must be a string describing why the package is suggested';
 37352 unset($this->config['suggest'][$package]);
 37353 }
 37354 }
 37355 }
 37356 
 37357 if ($this->validateString('minimum-stability') && !empty($this->config['minimum-stability'])) {
 37358 if (!isset(BasePackage::$stabilities[strtolower($this->config['minimum-stability'])]) && $this->config['minimum-stability'] !== 'RC') {
 37359 $this->errors[] = 'minimum-stability : invalid value ('.$this->config['minimum-stability'].'), must be one of '.implode(', ', array_keys(BasePackage::$stabilities));
 37360 unset($this->config['minimum-stability']);
 37361 }
 37362 }
 37363 
 37364 if ($this->validateArray('autoload') && !empty($this->config['autoload'])) {
 37365 $types = array('psr-0', 'psr-4', 'classmap', 'files', 'exclude-from-classmap');
 37366 foreach ($this->config['autoload'] as $type => $typeConfig) {
 37367 if (!in_array($type, $types)) {
 37368 $this->errors[] = 'autoload : invalid value ('.$type.'), must be one of '.implode(', ', $types);
 37369 unset($this->config['autoload'][$type]);
 37370 }
 37371 if ($type === 'psr-4') {
 37372 foreach ($typeConfig as $namespace => $dirs) {
 37373 if ($namespace !== '' && '\\' !== substr($namespace, -1)) {
 37374 $this->errors[] = 'autoload.psr-4 : invalid value ('.$namespace.'), namespaces must end with a namespace separator, should be '.$namespace.'\\\\';
 37375 }
 37376 }
 37377 }
 37378 }
 37379 }
 37380 
 37381 if (!empty($this->config['autoload']['psr-4']) && !empty($this->config['target-dir'])) {
 37382 $this->errors[] = 'target-dir : this can not be used together with the autoload.psr-4 setting, remove target-dir to upgrade to psr-4';
 37383 
 37384 
 37385 unset($this->config['autoload']['psr-4']);
 37386 }
 37387 
 37388 foreach (array('source', 'dist') as $srcType) {
 37389 if ($this->validateArray($srcType) && !empty($this->config[$srcType])) {
 37390 if (!isset($this->config[$srcType]['type'])) {
 37391 $this->errors[] = $srcType . '.type : must be present';
 37392 }
 37393 if (!isset($this->config[$srcType]['url'])) {
 37394 $this->errors[] = $srcType . '.url : must be present';
 37395 }
 37396 if ($srcType === 'source' && !isset($this->config[$srcType]['reference'])) {
 37397 $this->errors[] = $srcType . '.reference : must be present';
 37398 }
 37399 if (!is_string($this->config[$srcType]['type'])) {
 37400 $this->errors[] = $srcType . '.type : should be a string, '.gettype($this->config[$srcType]['type']).' given';
 37401 }
 37402 if (!is_string($this->config[$srcType]['url'])) {
 37403 $this->errors[] = $srcType . '.url : should be a string, '.gettype($this->config[$srcType]['url']).' given';
 37404 }
 37405 if (isset($this->config[$srcType]['reference']) && !is_string($this->config[$srcType]['reference']) && !is_int($this->config[$srcType]['reference'])) {
 37406 $this->errors[] = $srcType . '.reference : should be a string or int, '.gettype($this->config[$srcType]['reference']).' given';
 37407 }
 37408 if (isset($this->config[$srcType]['reference']) && Preg::isMatch('{^\s*-}', (string) $this->config[$srcType]['reference'])) {
 37409 $this->errors[] = $srcType . '.reference : must not start with a "-", "'.$this->config[$srcType]['reference'].'" given';
 37410 }
 37411 if (Preg::isMatch('{^\s*-}', $this->config[$srcType]['url'])) {
 37412 $this->errors[] = $srcType . '.url : must not start with a "-", "'.$this->config[$srcType]['url'].'" given';
 37413 }
 37414 }
 37415 }
 37416 
 37417 
 37418 
 37419 
 37420 $this->validateFlatArray('include-path');
 37421 $this->validateArray('transport-options');
 37422 
 37423 
 37424 if (isset($this->config['extra']['branch-alias'])) {
 37425 if (!is_array($this->config['extra']['branch-alias'])) {
 37426 $this->errors[] = 'extra.branch-alias : must be an array of versions => aliases';
 37427 } else {
 37428 foreach ($this->config['extra']['branch-alias'] as $sourceBranch => $targetBranch) {
 37429 if (!is_string($targetBranch)) {
 37430 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.json_encode($targetBranch).') must be a string, "'.gettype($targetBranch).'" received.';
 37431 unset($this->config['extra']['branch-alias'][$sourceBranch]);
 37432 
 37433 continue;
 37434 }
 37435 
 37436 
 37437 if ('-dev' !== substr($targetBranch, -4)) {
 37438 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') must end in -dev';
 37439 unset($this->config['extra']['branch-alias'][$sourceBranch]);
 37440 
 37441 continue;
 37442 }
 37443 
 37444 
 37445 $validatedTargetBranch = $this->versionParser->normalizeBranch(substr($targetBranch, 0, -4));
 37446 if ('-dev' !== substr($validatedTargetBranch, -4)) {
 37447 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') must be a parseable number like 2.0-dev';
 37448 unset($this->config['extra']['branch-alias'][$sourceBranch]);
 37449 
 37450 continue;
 37451 }
 37452 
 37453 
 37454 if (($sourcePrefix = $this->versionParser->parseNumericAliasPrefix($sourceBranch))
 37455 && ($targetPrefix = $this->versionParser->parseNumericAliasPrefix($targetBranch))
 37456 && (stripos($targetPrefix, $sourcePrefix) !== 0)
 37457 ) {
 37458 $this->warnings[] = 'extra.branch-alias.'.$sourceBranch.' : the target branch ('.$targetBranch.') is not a valid numeric alias for this version';
 37459 unset($this->config['extra']['branch-alias'][$sourceBranch]);
 37460 }
 37461 }
 37462 }
 37463 }
 37464 
 37465 if ($this->errors) {
 37466 throw new InvalidPackageException($this->errors, $this->warnings, $config);
 37467 }
 37468 
 37469 $package = $this->loader->load($this->config, $class);
 37470 $this->config = array();
 37471 
 37472 return $package;
 37473 }
 37474 
 37475 
 37476 
 37477 
 37478 public function getWarnings()
 37479 {
 37480 return $this->warnings;
 37481 }
 37482 
 37483 
 37484 
 37485 
 37486 public function getErrors()
 37487 {
 37488 return $this->errors;
 37489 }
 37490 
 37491 
 37492 
 37493 
 37494 
 37495 
 37496 
 37497 public static function hasPackageNamingError($name, $isLink = false)
 37498 {
 37499 if (PlatformRepository::isPlatformPackage($name)) {
 37500 return null;
 37501 }
 37502 
 37503 if (!Preg::isMatch('{^[a-z0-9](?:[_.-]?[a-z0-9]+)*/[a-z0-9](?:(?:[_.]?|-{0,2})[a-z0-9]+)*$}iD', $name)) {
 37504 return $name.' is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name should match "^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$".';
 37505 }
 37506 
 37507 $reservedNames = array('nul', 'con', 'prn', 'aux', 'com1', 'com2', 'com3', 'com4', 'com5', 'com6', 'com7', 'com8', 'com9', 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', 'lpt8', 'lpt9');
 37508 $bits = explode('/', strtolower($name));
 37509 if (in_array($bits[0], $reservedNames, true) || in_array($bits[1], $reservedNames, true)) {
 37510 return $name.' is reserved, package and vendor names can not match any of: '.implode(', ', $reservedNames).'.';
 37511 }
 37512 
 37513 if (Preg::isMatch('{\.json$}', $name)) {
 37514 return $name.' is invalid, package names can not end in .json, consider renaming it or perhaps using a -json suffix instead.';
 37515 }
 37516 
 37517 if (Preg::isMatch('{[A-Z]}', $name)) {
 37518 if ($isLink) {
 37519 return $name.' is invalid, it should not contain uppercase characters. Please use '.strtolower($name).' instead.';
 37520 }
 37521 
 37522 $suggestName = Preg::replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $name);
 37523 $suggestName = strtolower($suggestName);
 37524 
 37525 return $name.' is invalid, it should not contain uppercase characters. We suggest using '.$suggestName.' instead.';
 37526 }
 37527 
 37528 return null;
 37529 }
 37530 
 37531 
 37532 
 37533 
 37534 
 37535 
 37536 
 37537 
 37538 
 37539 
 37540 
 37541 private function validateRegex($property, $regex, $mandatory = false)
 37542 {
 37543 if (!$this->validateString($property, $mandatory)) {
 37544 return false;
 37545 }
 37546 
 37547 if (!Preg::isMatch('{^'.$regex.'$}u', $this->config[$property])) {
 37548 $message = $property.' : invalid value ('.$this->config[$property].'), must match '.$regex;
 37549 if ($mandatory) {
 37550 $this->errors[] = $message;
 37551 } else {
 37552 $this->warnings[] = $message;
 37553 }
 37554 unset($this->config[$property]);
 37555 
 37556 return false;
 37557 }
 37558 
 37559 return true;
 37560 }
 37561 
 37562 
 37563 
 37564 
 37565 
 37566 
 37567 
 37568 
 37569 
 37570 private function validateString($property, $mandatory = false)
 37571 {
 37572 if (isset($this->config[$property]) && !is_string($this->config[$property])) {
 37573 $this->errors[] = $property.' : should be a string, '.gettype($this->config[$property]).' given';
 37574 unset($this->config[$property]);
 37575 
 37576 return false;
 37577 }
 37578 
 37579 if (!isset($this->config[$property]) || trim($this->config[$property]) === '') {
 37580 if ($mandatory) {
 37581 $this->errors[] = $property.' : must be present';
 37582 }
 37583 unset($this->config[$property]);
 37584 
 37585 return false;
 37586 }
 37587 
 37588 return true;
 37589 }
 37590 
 37591 
 37592 
 37593 
 37594 
 37595 
 37596 
 37597 
 37598 
 37599 private function validateArray($property, $mandatory = false)
 37600 {
 37601 if (isset($this->config[$property]) && !is_array($this->config[$property])) {
 37602 $this->errors[] = $property.' : should be an array, '.gettype($this->config[$property]).' given';
 37603 unset($this->config[$property]);
 37604 
 37605 return false;
 37606 }
 37607 
 37608 if (!isset($this->config[$property]) || !count($this->config[$property])) {
 37609 if ($mandatory) {
 37610 $this->errors[] = $property.' : must be present and contain at least one element';
 37611 }
 37612 unset($this->config[$property]);
 37613 
 37614 return false;
 37615 }
 37616 
 37617 return true;
 37618 }
 37619 
 37620 
 37621 
 37622 
 37623 
 37624 
 37625 
 37626 
 37627 
 37628 
 37629 
 37630 private function validateFlatArray($property, $regex = null, $mandatory = false)
 37631 {
 37632 if (!$this->validateArray($property, $mandatory)) {
 37633 return false;
 37634 }
 37635 
 37636 $pass = true;
 37637 foreach ($this->config[$property] as $key => $value) {
 37638 if (!is_string($value) && !is_numeric($value)) {
 37639 $this->errors[] = $property.'.'.$key.' : must be a string or int, '.gettype($value).' given';
 37640 unset($this->config[$property][$key]);
 37641 $pass = false;
 37642 
 37643 continue;
 37644 }
 37645 
 37646 if ($regex && !Preg::isMatch('{^'.$regex.'$}u', $value)) {
 37647 $this->warnings[] = $property.'.'.$key.' : invalid value ('.$value.'), must match '.$regex;
 37648 unset($this->config[$property][$key]);
 37649 $pass = false;
 37650 }
 37651 }
 37652 
 37653 return $pass;
 37654 }
 37655 
 37656 
 37657 
 37658 
 37659 
 37660 
 37661 
 37662 
 37663 
 37664 private function validateUrl($property, $mandatory = false)
 37665 {
 37666 if (!$this->validateString($property, $mandatory)) {
 37667 return false;
 37668 }
 37669 
 37670 if (!$this->filterUrl($this->config[$property])) {
 37671 $this->warnings[] = $property.' : invalid value ('.$this->config[$property].'), must be an http/https URL';
 37672 unset($this->config[$property]);
 37673 
 37674 return false;
 37675 }
 37676 
 37677 return true;
 37678 }
 37679 
 37680 
 37681 
 37682 
 37683 
 37684 
 37685 
 37686 private function filterUrl($value, array $schemes = array('http', 'https'))
 37687 {
 37688 if ($value === '') {
 37689 return true;
 37690 }
 37691 
 37692 $bits = parse_url($value);
 37693 if (empty($bits['scheme']) || empty($bits['host'])) {
 37694 return false;
 37695 }
 37696 
 37697 if (!in_array($bits['scheme'], $schemes, true)) {
 37698 return false;
 37699 }
 37700 
 37701 return true;
 37702 }
 37703 }
 37704 <?php
 37705 
 37706 
 37707 
 37708 
 37709 
 37710 
 37711 
 37712 
 37713 
 37714 
 37715 
 37716 namespace Composer\Package;
 37717 
 37718 use Composer\Json\JsonFile;
 37719 use Composer\Installer\InstallationManager;
 37720 use Composer\Pcre\Preg;
 37721 use Composer\Repository\LockArrayRepository;
 37722 use Composer\Util\ProcessExecutor;
 37723 use Composer\Package\Dumper\ArrayDumper;
 37724 use Composer\Package\Loader\ArrayLoader;
 37725 use Composer\Package\Version\VersionParser;
 37726 use Composer\Plugin\PluginInterface;
 37727 use Composer\Util\Git as GitUtil;
 37728 use Composer\IO\IOInterface;
 37729 use Seld\JsonLint\ParsingException;
 37730 
 37731 
 37732 
 37733 
 37734 
 37735 
 37736 
 37737 class Locker
 37738 {
 37739 
 37740 private $lockFile;
 37741 
 37742 private $installationManager;
 37743 
 37744 private $hash;
 37745 
 37746 private $contentHash;
 37747 
 37748 private $loader;
 37749 
 37750 private $dumper;
 37751 
 37752 private $process;
 37753 
 37754 private $lockDataCache = null;
 37755 
 37756 private $virtualFileWritten = false;
 37757 
 37758 
 37759 
 37760 
 37761 
 37762 
 37763 
 37764 
 37765 
 37766 public function __construct(IOInterface $io, JsonFile $lockFile, InstallationManager $installationManager, $composerFileContents, ProcessExecutor $process = null)
 37767 {
 37768 $this->lockFile = $lockFile;
 37769 $this->installationManager = $installationManager;
 37770 $this->hash = md5($composerFileContents);
 37771 $this->contentHash = self::getContentHash($composerFileContents);
 37772 $this->loader = new ArrayLoader(null, true);
 37773 $this->dumper = new ArrayDumper();
 37774 $this->process = $process ?: new ProcessExecutor($io);
 37775 }
 37776 
 37777 
 37778 
 37779 
 37780 
 37781 
 37782 
 37783 
 37784 public static function getContentHash($composerFileContents)
 37785 {
 37786 $content = json_decode($composerFileContents, true);
 37787 
 37788 $relevantKeys = array(
 37789 'name',
 37790 'version',
 37791 'require',
 37792 'require-dev',
 37793 'conflict',
 37794 'replace',
 37795 'provide',
 37796 'minimum-stability',
 37797 'prefer-stable',
 37798 'repositories',
 37799 'extra',
 37800 );
 37801 
 37802 $relevantContent = array();
 37803 
 37804 foreach (array_intersect($relevantKeys, array_keys($content)) as $key) {
 37805 $relevantContent[$key] = $content[$key];
 37806 }
 37807 if (isset($content['config']['platform'])) {
 37808 $relevantContent['config']['platform'] = $content['config']['platform'];
 37809 }
 37810 
 37811 ksort($relevantContent);
 37812 
 37813 return md5(json_encode($relevantContent));
 37814 }
 37815 
 37816 
 37817 
 37818 
 37819 
 37820 
 37821 public function isLocked()
 37822 {
 37823 if (!$this->virtualFileWritten && !$this->lockFile->exists()) {
 37824 return false;
 37825 }
 37826 
 37827 $data = $this->getLockData();
 37828 
 37829 return isset($data['packages']);
 37830 }
 37831 
 37832 
 37833 
 37834 
 37835 
 37836 
 37837 public function isFresh()
 37838 {
 37839 $lock = $this->lockFile->read();
 37840 
 37841 if (!empty($lock['content-hash'])) {
 37842 
 37843 return $this->contentHash === $lock['content-hash'];
 37844 }
 37845 
 37846 
 37847 if (!empty($lock['hash'])) {
 37848 return $this->hash === $lock['hash'];
 37849 }
 37850 
 37851 
 37852 return false;
 37853 }
 37854 
 37855 
 37856 
 37857 
 37858 
 37859 
 37860 
 37861 
 37862 public function getLockedRepository($withDevReqs = false)
 37863 {
 37864 $lockData = $this->getLockData();
 37865 $packages = new LockArrayRepository();
 37866 
 37867 $lockedPackages = $lockData['packages'];
 37868 if ($withDevReqs) {
 37869 if (isset($lockData['packages-dev'])) {
 37870 $lockedPackages = array_merge($lockedPackages, $lockData['packages-dev']);
 37871 } else {
 37872 throw new \RuntimeException('The lock file does not contain require-dev information, run install with the --no-dev option or delete it and run composer update to generate a new lock file.');
 37873 }
 37874 }
 37875 
 37876 if (empty($lockedPackages)) {
 37877 return $packages;
 37878 }
 37879 
 37880 if (isset($lockedPackages[0]['name'])) {
 37881 $packageByName = array();
 37882 foreach ($lockedPackages as $info) {
 37883 $package = $this->loader->load($info);
 37884 $packages->addPackage($package);
 37885 $packageByName[$package->getName()] = $package;
 37886 
 37887 if ($package instanceof AliasPackage) {
 37888 $packageByName[$package->getAliasOf()->getName()] = $package->getAliasOf();
 37889 }
 37890 }
 37891 
 37892 if (isset($lockData['aliases'])) {
 37893 foreach ($lockData['aliases'] as $alias) {
 37894 if (isset($packageByName[$alias['package']])) {
 37895 $aliasPkg = new CompleteAliasPackage($packageByName[$alias['package']], $alias['alias_normalized'], $alias['alias']);
 37896 $aliasPkg->setRootPackageAlias(true);
 37897 $packages->addPackage($aliasPkg);
 37898 }
 37899 }
 37900 }
 37901 
 37902 return $packages;
 37903 }
 37904 
 37905 throw new \RuntimeException('Your composer.lock is invalid. Run "composer update" to generate a new one.');
 37906 }
 37907 
 37908 
 37909 
 37910 
 37911 public function getDevPackageNames()
 37912 {
 37913 $names = array();
 37914 $lockData = $this->getLockData();
 37915 if (isset($lockData['packages-dev'])) {
 37916 foreach ($lockData['packages-dev'] as $package) {
 37917 $names[] = strtolower($package['name']);
 37918 }
 37919 }
 37920 
 37921 return $names;
 37922 }
 37923 
 37924 
 37925 
 37926 
 37927 
 37928 
 37929 
 37930 public function getPlatformRequirements($withDevReqs = false)
 37931 {
 37932 $lockData = $this->getLockData();
 37933 $requirements = array();
 37934 
 37935 if (!empty($lockData['platform'])) {
 37936 $requirements = $this->loader->parseLinks(
 37937 '__root__',
 37938 '1.0.0',
 37939 Link::TYPE_REQUIRE,
 37940 isset($lockData['platform']) ? $lockData['platform'] : array()
 37941 );
 37942 }
 37943 
 37944 if ($withDevReqs && !empty($lockData['platform-dev'])) {
 37945 $devRequirements = $this->loader->parseLinks(
 37946 '__root__',
 37947 '1.0.0',
 37948 Link::TYPE_REQUIRE,
 37949 isset($lockData['platform-dev']) ? $lockData['platform-dev'] : array()
 37950 );
 37951 
 37952 $requirements = array_merge($requirements, $devRequirements);
 37953 }
 37954 
 37955 return $requirements;
 37956 }
 37957 
 37958 
 37959 
 37960 
 37961 public function getMinimumStability()
 37962 {
 37963 $lockData = $this->getLockData();
 37964 
 37965 return isset($lockData['minimum-stability']) ? $lockData['minimum-stability'] : 'stable';
 37966 }
 37967 
 37968 
 37969 
 37970 
 37971 public function getStabilityFlags()
 37972 {
 37973 $lockData = $this->getLockData();
 37974 
 37975 return isset($lockData['stability-flags']) ? $lockData['stability-flags'] : array();
 37976 }
 37977 
 37978 
 37979 
 37980 
 37981 public function getPreferStable()
 37982 {
 37983 $lockData = $this->getLockData();
 37984 
 37985 
 37986 
 37987 return isset($lockData['prefer-stable']) ? $lockData['prefer-stable'] : null;
 37988 }
 37989 
 37990 
 37991 
 37992 
 37993 public function getPreferLowest()
 37994 {
 37995 $lockData = $this->getLockData();
 37996 
 37997 
 37998 
 37999 return isset($lockData['prefer-lowest']) ? $lockData['prefer-lowest'] : null;
 38000 }
 38001 
 38002 
 38003 
 38004 
 38005 public function getPlatformOverrides()
 38006 {
 38007 $lockData = $this->getLockData();
 38008 
 38009 return isset($lockData['platform-overrides']) ? $lockData['platform-overrides'] : array();
 38010 }
 38011 
 38012 
 38013 
 38014 
 38015 
 38016 
 38017 public function getAliases()
 38018 {
 38019 $lockData = $this->getLockData();
 38020 
 38021 return isset($lockData['aliases']) ? $lockData['aliases'] : array();
 38022 }
 38023 
 38024 
 38025 
 38026 
 38027 public function getLockData()
 38028 {
 38029 if (null !== $this->lockDataCache) {
 38030 return $this->lockDataCache;
 38031 }
 38032 
 38033 if (!$this->lockFile->exists()) {
 38034 throw new \LogicException('No lockfile found. Unable to read locked packages');
 38035 }
 38036 
 38037 return $this->lockDataCache = $this->lockFile->read();
 38038 }
 38039 
 38040 
 38041 
 38042 
 38043 
 38044 
 38045 
 38046 
 38047 
 38048 
 38049 
 38050 
 38051 
 38052 
 38053 
 38054 
 38055 
 38056 
 38057 
 38058 
 38059 public function setLockData(array $packages, $devPackages, array $platformReqs, $platformDevReqs, array $aliases, $minimumStability, array $stabilityFlags, $preferStable, $preferLowest, array $platformOverrides, $write = true)
 38060 {
 38061 
 38062 
 38063 $aliases = array_map(function ($alias) {
 38064 if (in_array($alias['version'], array('dev-master', 'dev-trunk', 'dev-default'), true)) {
 38065 $alias['version'] = VersionParser::DEFAULT_BRANCH_ALIAS;
 38066 }
 38067 
 38068 return $alias;
 38069 }, $aliases);
 38070 
 38071 $lock = array(
 38072 '_readme' => array('This file locks the dependencies of your project to a known state',
 38073 'Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies',
 38074 'This file is @gener'.'ated automatically', ),
 38075 'content-hash' => $this->contentHash,
 38076 'packages' => null,
 38077 'packages-dev' => null,
 38078 'aliases' => $aliases,
 38079 'minimum-stability' => $minimumStability,
 38080 'stability-flags' => $stabilityFlags,
 38081 'prefer-stable' => $preferStable,
 38082 'prefer-lowest' => $preferLowest,
 38083 );
 38084 
 38085 $lock['packages'] = $this->lockPackages($packages);
 38086 if (null !== $devPackages) {
 38087 $lock['packages-dev'] = $this->lockPackages($devPackages);
 38088 }
 38089 
 38090 $lock['platform'] = $platformReqs;
 38091 $lock['platform-dev'] = $platformDevReqs;
 38092 if ($platformOverrides) {
 38093 $lock['platform-overrides'] = $platformOverrides;
 38094 }
 38095 $lock['plugin-api-version'] = PluginInterface::PLUGIN_API_VERSION;
 38096 
 38097 try {
 38098 $isLocked = $this->isLocked();
 38099 } catch (ParsingException $e) {
 38100 $isLocked = false;
 38101 }
 38102 if (!$isLocked || $lock !== $this->getLockData()) {
 38103 if ($write) {
 38104 $this->lockFile->write($lock);
 38105 $this->lockDataCache = null;
 38106 $this->virtualFileWritten = false;
 38107 } else {
 38108 $this->virtualFileWritten = true;
 38109 $this->lockDataCache = JsonFile::parseJson(JsonFile::encode($lock, 448 & JsonFile::JSON_PRETTY_PRINT));
 38110 }
 38111 
 38112 return true;
 38113 }
 38114 
 38115 return false;
 38116 }
 38117 
 38118 
 38119 
 38120 
 38121 
 38122 
 38123 
 38124 
 38125 private function lockPackages(array $packages)
 38126 {
 38127 $locked = array();
 38128 
 38129 foreach ($packages as $package) {
 38130 if ($package instanceof AliasPackage) {
 38131 continue;
 38132 }
 38133 
 38134 $name = $package->getPrettyName();
 38135 $version = $package->getPrettyVersion();
 38136 
 38137 if (!$name || !$version) {
 38138 throw new \LogicException(sprintf(
 38139 'Package "%s" has no version or name and can not be locked',
 38140 $package
 38141 ));
 38142 }
 38143 
 38144 $spec = $this->dumper->dump($package);
 38145 unset($spec['version_normalized']);
 38146 
 38147 
 38148 $time = isset($spec['time']) ? $spec['time'] : null;
 38149 unset($spec['time']);
 38150 if ($package->isDev() && $package->getInstallationSource() === 'source') {
 38151 
 38152 $time = $this->getPackageTime($package) ?: $time;
 38153 }
 38154 if (null !== $time) {
 38155 $spec['time'] = $time;
 38156 }
 38157 
 38158 unset($spec['installation-source']);
 38159 
 38160 $locked[] = $spec;
 38161 }
 38162 
 38163 usort($locked, function ($a, $b) {
 38164 $comparison = strcmp($a['name'], $b['name']);
 38165 
 38166 if (0 !== $comparison) {
 38167 return $comparison;
 38168 }
 38169 
 38170 
 38171 return strcmp($a['version'], $b['version']);
 38172 });
 38173 
 38174 return $locked;
 38175 }
 38176 
 38177 
 38178 
 38179 
 38180 
 38181 
 38182 
 38183 private function getPackageTime(PackageInterface $package)
 38184 {
 38185 if (!function_exists('proc_open')) {
 38186 return null;
 38187 }
 38188 
 38189 $path = realpath($this->installationManager->getInstallPath($package));
 38190 $sourceType = $package->getSourceType();
 38191 $datetime = null;
 38192 
 38193 if ($path && in_array($sourceType, array('git', 'hg'))) {
 38194 $sourceRef = $package->getSourceReference() ?: $package->getDistReference();
 38195 switch ($sourceType) {
 38196 case 'git':
 38197 GitUtil::cleanEnv();
 38198 
 38199 if (0 === $this->process->execute('git log -n1 --pretty=%ct '.ProcessExecutor::escape($sourceRef).GitUtil::getNoShowSignatureFlag($this->process), $output, $path) && Preg::isMatch('{^\s*\d+\s*$}', $output)) {
 38200 $datetime = new \DateTime('@'.trim($output), new \DateTimeZone('UTC'));
 38201 }
 38202 break;
 38203 
 38204 case 'hg':
 38205 if (0 === $this->process->execute('hg log --template "{date|hgdate}" -r '.ProcessExecutor::escape($sourceRef), $output, $path) && Preg::isMatch('{^\s*(\d+)\s*}', $output, $match)) {
 38206 $datetime = new \DateTime('@'.$match[1], new \DateTimeZone('UTC'));
 38207 }
 38208 break;
 38209 }
 38210 }
 38211 
 38212 return $datetime ? $datetime->format(DATE_RFC3339) : null;
 38213 }
 38214 }
 38215 <?php
 38216 
 38217 
 38218 
 38219 
 38220 
 38221 
 38222 
 38223 
 38224 
 38225 
 38226 
 38227 namespace Composer\Package;
 38228 
 38229 use Composer\Package\Version\VersionParser;
 38230 use Composer\Pcre\Preg;
 38231 use Composer\Util\ComposerMirror;
 38232 
 38233 
 38234 
 38235 
 38236 
 38237 
 38238 
 38239 
 38240 
 38241 class Package extends BasePackage
 38242 {
 38243 
 38244 protected $type;
 38245 
 38246 protected $targetDir;
 38247 
 38248 protected $installationSource;
 38249 
 38250 protected $sourceType;
 38251 
 38252 protected $sourceUrl;
 38253 
 38254 protected $sourceReference;
 38255 
 38256 protected $sourceMirrors;
 38257 
 38258 protected $distType;
 38259 
 38260 protected $distUrl;
 38261 
 38262 protected $distReference;
 38263 
 38264 protected $distSha1Checksum;
 38265 
 38266 protected $distMirrors;
 38267 
 38268 protected $version;
 38269 
 38270 protected $prettyVersion;
 38271 
 38272 protected $releaseDate;
 38273 
 38274 protected $extra = array();
 38275 
 38276 protected $binaries = array();
 38277 
 38278 protected $dev;
 38279 
 38280 
 38281 
 38282 
 38283 protected $stability;
 38284 
 38285 protected $notificationUrl;
 38286 
 38287 
 38288 protected $requires = array();
 38289 
 38290 protected $conflicts = array();
 38291 
 38292 protected $provides = array();
 38293 
 38294 protected $replaces = array();
 38295 
 38296 protected $devRequires = array();
 38297 
 38298 protected $suggests = array();
 38299 
 38300 
 38301 
 38302 
 38303 protected $autoload = array();
 38304 
 38305 
 38306 
 38307 
 38308 protected $devAutoload = array();
 38309 
 38310 protected $includePaths = array();
 38311 
 38312 protected $isDefaultBranch = false;
 38313 
 38314 protected $transportOptions = array();
 38315 
 38316 
 38317 
 38318 
 38319 
 38320 
 38321 
 38322 
 38323 public function __construct($name, $version, $prettyVersion)
 38324 {
 38325 parent::__construct($name);
 38326 
 38327 $this->version = $version;
 38328 $this->prettyVersion = $prettyVersion;
 38329 
 38330 $this->stability = VersionParser::parseStability($version);
 38331 $this->dev = $this->stability === 'dev';
 38332 }
 38333 
 38334 
 38335 
 38336 
 38337 public function isDev()
 38338 {
 38339 return $this->dev;
 38340 }
 38341 
 38342 
 38343 
 38344 
 38345 
 38346 
 38347 public function setType($type)
 38348 {
 38349 $this->type = $type;
 38350 }
 38351 
 38352 
 38353 
 38354 
 38355 public function getType()
 38356 {
 38357 return $this->type ?: 'library';
 38358 }
 38359 
 38360 
 38361 
 38362 
 38363 public function getStability()
 38364 {
 38365 return $this->stability;
 38366 }
 38367 
 38368 
 38369 
 38370 
 38371 
 38372 
 38373 public function setTargetDir($targetDir)
 38374 {
 38375 $this->targetDir = $targetDir;
 38376 }
 38377 
 38378 
 38379 
 38380 
 38381 public function getTargetDir()
 38382 {
 38383 if (null === $this->targetDir) {
 38384 return null;
 38385 }
 38386 
 38387 return ltrim(Preg::replace('{ (?:^|[\\\\/]+) \.\.? (?:[\\\\/]+|$) (?:\.\.? (?:[\\\\/]+|$) )*}x', '/', $this->targetDir), '/');
 38388 }
 38389 
 38390 
 38391 
 38392 
 38393 
 38394 
 38395 public function setExtra(array $extra)
 38396 {
 38397 $this->extra = $extra;
 38398 }
 38399 
 38400 
 38401 
 38402 
 38403 public function getExtra()
 38404 {
 38405 return $this->extra;
 38406 }
 38407 
 38408 
 38409 
 38410 
 38411 
 38412 
 38413 public function setBinaries(array $binaries)
 38414 {
 38415 $this->binaries = $binaries;
 38416 }
 38417 
 38418 
 38419 
 38420 
 38421 public function getBinaries()
 38422 {
 38423 return $this->binaries;
 38424 }
 38425 
 38426 
 38427 
 38428 
 38429 
 38430 
 38431 public function setInstallationSource($type)
 38432 {
 38433 $this->installationSource = $type;
 38434 }
 38435 
 38436 
 38437 
 38438 
 38439 public function getInstallationSource()
 38440 {
 38441 return $this->installationSource;
 38442 }
 38443 
 38444 
 38445 
 38446 
 38447 
 38448 
 38449 public function setSourceType($type)
 38450 {
 38451 $this->sourceType = $type;
 38452 }
 38453 
 38454 
 38455 
 38456 
 38457 public function getSourceType()
 38458 {
 38459 return $this->sourceType;
 38460 }
 38461 
 38462 
 38463 
 38464 
 38465 
 38466 
 38467 public function setSourceUrl($url)
 38468 {
 38469 $this->sourceUrl = $url;
 38470 }
 38471 
 38472 
 38473 
 38474 
 38475 public function getSourceUrl()
 38476 {
 38477 return $this->sourceUrl;
 38478 }
 38479 
 38480 
 38481 
 38482 
 38483 
 38484 
 38485 public function setSourceReference($reference)
 38486 {
 38487 $this->sourceReference = $reference;
 38488 }
 38489 
 38490 
 38491 
 38492 
 38493 public function getSourceReference()
 38494 {
 38495 return $this->sourceReference;
 38496 }
 38497 
 38498 
 38499 
 38500 
 38501 
 38502 
 38503 public function setSourceMirrors($mirrors)
 38504 {
 38505 $this->sourceMirrors = $mirrors;
 38506 }
 38507 
 38508 
 38509 
 38510 
 38511 public function getSourceMirrors()
 38512 {
 38513 return $this->sourceMirrors;
 38514 }
 38515 
 38516 
 38517 
 38518 
 38519 public function getSourceUrls()
 38520 {
 38521 return $this->getUrls($this->sourceUrl, $this->sourceMirrors, $this->sourceReference, $this->sourceType, 'source');
 38522 }
 38523 
 38524 
 38525 
 38526 
 38527 
 38528 
 38529 public function setDistType($type)
 38530 {
 38531 $this->distType = $type;
 38532 }
 38533 
 38534 
 38535 
 38536 
 38537 public function getDistType()
 38538 {
 38539 return $this->distType;
 38540 }
 38541 
 38542 
 38543 
 38544 
 38545 
 38546 
 38547 public function setDistUrl($url)
 38548 {
 38549 $this->distUrl = $url;
 38550 }
 38551 
 38552 
 38553 
 38554 
 38555 public function getDistUrl()
 38556 {
 38557 return $this->distUrl;
 38558 }
 38559 
 38560 
 38561 
 38562 
 38563 
 38564 
 38565 public function setDistReference($reference)
 38566 {
 38567 $this->distReference = $reference;
 38568 }
 38569 
 38570 
 38571 
 38572 
 38573 public function getDistReference()
 38574 {
 38575 return $this->distReference;
 38576 }
 38577 
 38578 
 38579 
 38580 
 38581 
 38582 
 38583 public function setDistSha1Checksum($sha1checksum)
 38584 {
 38585 $this->distSha1Checksum = $sha1checksum;
 38586 }
 38587 
 38588 
 38589 
 38590 
 38591 public function getDistSha1Checksum()
 38592 {
 38593 return $this->distSha1Checksum;
 38594 }
 38595 
 38596 
 38597 
 38598 
 38599 
 38600 
 38601 public function setDistMirrors($mirrors)
 38602 {
 38603 $this->distMirrors = $mirrors;
 38604 }
 38605 
 38606 
 38607 
 38608 
 38609 public function getDistMirrors()
 38610 {
 38611 return $this->distMirrors;
 38612 }
 38613 
 38614 
 38615 
 38616 
 38617 public function getDistUrls()
 38618 {
 38619 return $this->getUrls($this->distUrl, $this->distMirrors, $this->distReference, $this->distType, 'dist');
 38620 }
 38621 
 38622 
 38623 
 38624 
 38625 public function getTransportOptions()
 38626 {
 38627 return $this->transportOptions;
 38628 }
 38629 
 38630 
 38631 
 38632 
 38633 public function setTransportOptions(array $options)
 38634 {
 38635 $this->transportOptions = $options;
 38636 }
 38637 
 38638 
 38639 
 38640 
 38641 public function getVersion()
 38642 {
 38643 return $this->version;
 38644 }
 38645 
 38646 
 38647 
 38648 
 38649 public function getPrettyVersion()
 38650 {
 38651 return $this->prettyVersion;
 38652 }
 38653 
 38654 
 38655 
 38656 
 38657 
 38658 
 38659 
 38660 
 38661 public function setReleaseDate(\DateTime $releaseDate)
 38662 {
 38663 $this->releaseDate = $releaseDate;
 38664 }
 38665 
 38666 
 38667 
 38668 
 38669 public function getReleaseDate()
 38670 {
 38671 return $this->releaseDate;
 38672 }
 38673 
 38674 
 38675 
 38676 
 38677 
 38678 
 38679 
 38680 
 38681 public function setRequires(array $requires)
 38682 {
 38683 if (isset($requires[0])) { 
 38684 $requires = $this->convertLinksToMap($requires, 'setRequires');
 38685 }
 38686 
 38687 $this->requires = $requires;
 38688 }
 38689 
 38690 
 38691 
 38692 
 38693 public function getRequires()
 38694 {
 38695 return $this->requires;
 38696 }
 38697 
 38698 
 38699 
 38700 
 38701 
 38702 
 38703 
 38704 
 38705 public function setConflicts(array $conflicts)
 38706 {
 38707 if (isset($conflicts[0])) { 
 38708 $conflicts = $this->convertLinksToMap($conflicts, 'setConflicts');
 38709 }
 38710 
 38711 $this->conflicts = $conflicts;
 38712 }
 38713 
 38714 
 38715 
 38716 
 38717 
 38718 public function getConflicts()
 38719 {
 38720 return $this->conflicts;
 38721 }
 38722 
 38723 
 38724 
 38725 
 38726 
 38727 
 38728 
 38729 
 38730 public function setProvides(array $provides)
 38731 {
 38732 if (isset($provides[0])) { 
 38733 $provides = $this->convertLinksToMap($provides, 'setProvides');
 38734 }
 38735 
 38736 $this->provides = $provides;
 38737 }
 38738 
 38739 
 38740 
 38741 
 38742 
 38743 public function getProvides()
 38744 {
 38745 return $this->provides;
 38746 }
 38747 
 38748 
 38749 
 38750 
 38751 
 38752 
 38753 
 38754 
 38755 public function setReplaces(array $replaces)
 38756 {
 38757 if (isset($replaces[0])) { 
 38758 $replaces = $this->convertLinksToMap($replaces, 'setReplaces');
 38759 }
 38760 
 38761 $this->replaces = $replaces;
 38762 }
 38763 
 38764 
 38765 
 38766 
 38767 
 38768 public function getReplaces()
 38769 {
 38770 return $this->replaces;
 38771 }
 38772 
 38773 
 38774 
 38775 
 38776 
 38777 
 38778 
 38779 
 38780 public function setDevRequires(array $devRequires)
 38781 {
 38782 if (isset($devRequires[0])) { 
 38783 $devRequires = $this->convertLinksToMap($devRequires, 'setDevRequires');
 38784 }
 38785 
 38786 $this->devRequires = $devRequires;
 38787 }
 38788 
 38789 
 38790 
 38791 
 38792 public function getDevRequires()
 38793 {
 38794 return $this->devRequires;
 38795 }
 38796 
 38797 
 38798 
 38799 
 38800 
 38801 
 38802 
 38803 
 38804 public function setSuggests(array $suggests)
 38805 {
 38806 $this->suggests = $suggests;
 38807 }
 38808 
 38809 
 38810 
 38811 
 38812 public function getSuggests()
 38813 {
 38814 return $this->suggests;
 38815 }
 38816 
 38817 
 38818 
 38819 
 38820 
 38821 
 38822 
 38823 
 38824 
 38825 
 38826 public function setAutoload(array $autoload)
 38827 {
 38828 $this->autoload = $autoload;
 38829 }
 38830 
 38831 
 38832 
 38833 
 38834 public function getAutoload()
 38835 {
 38836 return $this->autoload;
 38837 }
 38838 
 38839 
 38840 
 38841 
 38842 
 38843 
 38844 
 38845 
 38846 
 38847 
 38848 public function setDevAutoload(array $devAutoload)
 38849 {
 38850 $this->devAutoload = $devAutoload;
 38851 }
 38852 
 38853 
 38854 
 38855 
 38856 public function getDevAutoload()
 38857 {
 38858 return $this->devAutoload;
 38859 }
 38860 
 38861 
 38862 
 38863 
 38864 
 38865 
 38866 
 38867 
 38868 public function setIncludePaths(array $includePaths)
 38869 {
 38870 $this->includePaths = $includePaths;
 38871 }
 38872 
 38873 
 38874 
 38875 
 38876 public function getIncludePaths()
 38877 {
 38878 return $this->includePaths;
 38879 }
 38880 
 38881 
 38882 
 38883 
 38884 
 38885 
 38886 
 38887 
 38888 public function setNotificationUrl($notificationUrl)
 38889 {
 38890 $this->notificationUrl = $notificationUrl;
 38891 }
 38892 
 38893 
 38894 
 38895 
 38896 public function getNotificationUrl()
 38897 {
 38898 return $this->notificationUrl;
 38899 }
 38900 
 38901 
 38902 
 38903 
 38904 
 38905 
 38906 public function setIsDefaultBranch($defaultBranch)
 38907 {
 38908 $this->isDefaultBranch = $defaultBranch;
 38909 }
 38910 
 38911 
 38912 
 38913 
 38914 public function isDefaultBranch()
 38915 {
 38916 return $this->isDefaultBranch;
 38917 }
 38918 
 38919 
 38920 
 38921 
 38922 public function setSourceDistReferences($reference)
 38923 {
 38924 $this->setSourceReference($reference);
 38925 
 38926 
 38927 
 38928 if (
 38929 $this->getDistUrl() !== null
 38930 && Preg::isMatch('{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com|(?:www\.)?gitlab\.com)/}i', $this->getDistUrl())
 38931 ) {
 38932 $this->setDistReference($reference);
 38933 $this->setDistUrl(Preg::replace('{(?<=/|sha=)[a-f0-9]{40}(?=/|$)}i', $reference, $this->getDistUrl()));
 38934 } elseif ($this->getDistReference()) { 
 38935 $this->setDistReference($reference);
 38936 }
 38937 }
 38938 
 38939 
 38940 
 38941 
 38942 
 38943 
 38944 
 38945 
 38946 
 38947 
 38948 public function replaceVersion($version, $prettyVersion)
 38949 {
 38950 $this->version = $version;
 38951 $this->prettyVersion = $prettyVersion;
 38952 
 38953 $this->stability = VersionParser::parseStability($version);
 38954 $this->dev = $this->stability === 'dev';
 38955 }
 38956 
 38957 
 38958 
 38959 
 38960 
 38961 
 38962 
 38963 
 38964 
 38965 
 38966 
 38967 
 38968 protected function getUrls($url, $mirrors, $ref, $type, $urlType)
 38969 {
 38970 if (!$url) {
 38971 return array();
 38972 }
 38973 
 38974 if ($urlType === 'dist' && false !== strpos($url, '%')) {
 38975 $url = ComposerMirror::processUrl($url, $this->name, $this->version, $ref, $type, $this->prettyVersion);
 38976 }
 38977 
 38978 $urls = array($url);
 38979 if ($mirrors) {
 38980 foreach ($mirrors as $mirror) {
 38981 if ($urlType === 'dist') {
 38982 $mirrorUrl = ComposerMirror::processUrl($mirror['url'], $this->name, $this->version, $ref, $type, $this->prettyVersion);
 38983 } elseif ($urlType === 'source' && $type === 'git') {
 38984 $mirrorUrl = ComposerMirror::processGitUrl($mirror['url'], $this->name, $url, $type);
 38985 } elseif ($urlType === 'source' && $type === 'hg') {
 38986 $mirrorUrl = ComposerMirror::processHgUrl($mirror['url'], $this->name, $url, $type);
 38987 } else {
 38988 continue;
 38989 }
 38990 if (!\in_array($mirrorUrl, $urls)) {
 38991 $func = $mirror['preferred'] ? 'array_unshift' : 'array_push';
 38992 $func($urls, $mirrorUrl);
 38993 }
 38994 }
 38995 }
 38996 
 38997 return $urls;
 38998 }
 38999 
 39000 
 39001 
 39002 
 39003 
 39004 
 39005 private function convertLinksToMap(array $links, $source)
 39006 {
 39007 trigger_error('Package::'.$source.' must be called with a map of lowercased package name => Link object, got a indexed array, this is deprecated and you should fix your usage.');
 39008 $newLinks = array();
 39009 foreach ($links as $link) {
 39010 $newLinks[$link->getTarget()] = $link;
 39011 }
 39012 
 39013 return $newLinks;
 39014 }
 39015 }
 39016 <?php
 39017 
 39018 
 39019 
 39020 
 39021 
 39022 
 39023 
 39024 
 39025 
 39026 
 39027 
 39028 namespace Composer\Package;
 39029 
 39030 use Composer\Repository\RepositoryInterface;
 39031 
 39032 
 39033 
 39034 
 39035 
 39036 
 39037 
 39038 
 39039 
 39040 interface PackageInterface
 39041 {
 39042 const DISPLAY_SOURCE_REF_IF_DEV = 0;
 39043 const DISPLAY_SOURCE_REF = 1;
 39044 const DISPLAY_DIST_REF = 2;
 39045 
 39046 
 39047 
 39048 
 39049 
 39050 
 39051 public function getName();
 39052 
 39053 
 39054 
 39055 
 39056 
 39057 
 39058 public function getPrettyName();
 39059 
 39060 
 39061 
 39062 
 39063 
 39064 
 39065 
 39066 
 39067 
 39068 
 39069 
 39070 public function getNames($provides = true);
 39071 
 39072 
 39073 
 39074 
 39075 
 39076 
 39077 
 39078 
 39079 public function setId($id);
 39080 
 39081 
 39082 
 39083 
 39084 
 39085 
 39086 public function getId();
 39087 
 39088 
 39089 
 39090 
 39091 
 39092 
 39093 public function isDev();
 39094 
 39095 
 39096 
 39097 
 39098 
 39099 
 39100 public function getType();
 39101 
 39102 
 39103 
 39104 
 39105 
 39106 
 39107 public function getTargetDir();
 39108 
 39109 
 39110 
 39111 
 39112 
 39113 
 39114 public function getExtra();
 39115 
 39116 
 39117 
 39118 
 39119 
 39120 
 39121 
 39122 
 39123 
 39124 public function setInstallationSource($type);
 39125 
 39126 
 39127 
 39128 
 39129 
 39130 
 39131 
 39132 public function getInstallationSource();
 39133 
 39134 
 39135 
 39136 
 39137 
 39138 
 39139 public function getSourceType();
 39140 
 39141 
 39142 
 39143 
 39144 
 39145 
 39146 public function getSourceUrl();
 39147 
 39148 
 39149 
 39150 
 39151 
 39152 
 39153 public function getSourceUrls();
 39154 
 39155 
 39156 
 39157 
 39158 
 39159 
 39160 public function getSourceReference();
 39161 
 39162 
 39163 
 39164 
 39165 
 39166 
 39167 public function getSourceMirrors();
 39168 
 39169 
 39170 
 39171 
 39172 
 39173 public function setSourceMirrors($mirrors);
 39174 
 39175 
 39176 
 39177 
 39178 
 39179 
 39180 public function getDistType();
 39181 
 39182 
 39183 
 39184 
 39185 
 39186 
 39187 public function getDistUrl();
 39188 
 39189 
 39190 
 39191 
 39192 
 39193 
 39194 public function getDistUrls();
 39195 
 39196 
 39197 
 39198 
 39199 
 39200 
 39201 public function getDistReference();
 39202 
 39203 
 39204 
 39205 
 39206 
 39207 
 39208 public function getDistSha1Checksum();
 39209 
 39210 
 39211 
 39212 
 39213 
 39214 
 39215 public function getDistMirrors();
 39216 
 39217 
 39218 
 39219 
 39220 
 39221 public function setDistMirrors($mirrors);
 39222 
 39223 
 39224 
 39225 
 39226 
 39227 
 39228 public function getVersion();
 39229 
 39230 
 39231 
 39232 
 39233 
 39234 
 39235 public function getPrettyVersion();
 39236 
 39237 
 39238 
 39239 
 39240 
 39241 
 39242 
 39243 
 39244 
 39245 
 39246 
 39247 
 39248 public function getFullPrettyVersion($truncate = true, $displayMode = self::DISPLAY_SOURCE_REF_IF_DEV);
 39249 
 39250 
 39251 
 39252 
 39253 
 39254 
 39255 public function getReleaseDate();
 39256 
 39257 
 39258 
 39259 
 39260 
 39261 
 39262 
 39263 
 39264 public function getStability();
 39265 
 39266 
 39267 
 39268 
 39269 
 39270 
 39271 
 39272 public function getRequires();
 39273 
 39274 
 39275 
 39276 
 39277 
 39278 
 39279 
 39280 public function getConflicts();
 39281 
 39282 
 39283 
 39284 
 39285 
 39286 
 39287 
 39288 public function getProvides();
 39289 
 39290 
 39291 
 39292 
 39293 
 39294 
 39295 
 39296 public function getReplaces();
 39297 
 39298 
 39299 
 39300 
 39301 
 39302 
 39303 
 39304 public function getDevRequires();
 39305 
 39306 
 39307 
 39308 
 39309 
 39310 
 39311 
 39312 
 39313 public function getSuggests();
 39314 
 39315 
 39316 
 39317 
 39318 
 39319 
 39320 
 39321 
 39322 
 39323 
 39324 
 39325 
 39326 public function getAutoload();
 39327 
 39328 
 39329 
 39330 
 39331 
 39332 
 39333 
 39334 
 39335 
 39336 
 39337 
 39338 
 39339 public function getDevAutoload();
 39340 
 39341 
 39342 
 39343 
 39344 
 39345 
 39346 
 39347 public function getIncludePaths();
 39348 
 39349 
 39350 
 39351 
 39352 
 39353 
 39354 
 39355 
 39356 public function setRepository(RepositoryInterface $repository);
 39357 
 39358 
 39359 
 39360 
 39361 
 39362 
 39363 public function getRepository();
 39364 
 39365 
 39366 
 39367 
 39368 
 39369 
 39370 public function getBinaries();
 39371 
 39372 
 39373 
 39374 
 39375 
 39376 
 39377 public function getUniqueName();
 39378 
 39379 
 39380 
 39381 
 39382 
 39383 
 39384 public function getNotificationUrl();
 39385 
 39386 
 39387 
 39388 
 39389 
 39390 
 39391 public function __toString();
 39392 
 39393 
 39394 
 39395 
 39396 
 39397 
 39398 public function getPrettyString();
 39399 
 39400 
 39401 
 39402 
 39403 public function isDefaultBranch();
 39404 
 39405 
 39406 
 39407 
 39408 
 39409 
 39410 public function getTransportOptions();
 39411 
 39412 
 39413 
 39414 
 39415 
 39416 
 39417 
 39418 
 39419 public function setTransportOptions(array $options);
 39420 
 39421 
 39422 
 39423 
 39424 
 39425 
 39426 public function setSourceReference($reference);
 39427 
 39428 
 39429 
 39430 
 39431 
 39432 
 39433 public function setDistUrl($url);
 39434 
 39435 
 39436 
 39437 
 39438 
 39439 
 39440 public function setDistType($type);
 39441 
 39442 
 39443 
 39444 
 39445 
 39446 
 39447 public function setDistReference($reference);
 39448 
 39449 
 39450 
 39451 
 39452 
 39453 
 39454 
 39455 
 39456 public function setSourceDistReferences($reference);
 39457 }
 39458 <?php
 39459 
 39460 
 39461 
 39462 
 39463 
 39464 
 39465 
 39466 
 39467 
 39468 
 39469 
 39470 namespace Composer\Package;
 39471 
 39472 
 39473 
 39474 
 39475 class RootAliasPackage extends CompleteAliasPackage implements RootPackageInterface
 39476 {
 39477 
 39478 protected $aliasOf;
 39479 
 39480 
 39481 
 39482 
 39483 
 39484 
 39485 
 39486 
 39487 public function __construct(RootPackage $aliasOf, $version, $prettyVersion)
 39488 {
 39489 parent::__construct($aliasOf, $version, $prettyVersion);
 39490 }
 39491 
 39492 
 39493 
 39494 
 39495 public function getAliasOf()
 39496 {
 39497 return $this->aliasOf;
 39498 }
 39499 
 39500 
 39501 
 39502 
 39503 public function getAliases()
 39504 {
 39505 return $this->aliasOf->getAliases();
 39506 }
 39507 
 39508 
 39509 
 39510 
 39511 public function getMinimumStability()
 39512 {
 39513 return $this->aliasOf->getMinimumStability();
 39514 }
 39515 
 39516 
 39517 
 39518 
 39519 public function getStabilityFlags()
 39520 {
 39521 return $this->aliasOf->getStabilityFlags();
 39522 }
 39523 
 39524 
 39525 
 39526 
 39527 public function getReferences()
 39528 {
 39529 return $this->aliasOf->getReferences();
 39530 }
 39531 
 39532 
 39533 
 39534 
 39535 public function getPreferStable()
 39536 {
 39537 return $this->aliasOf->getPreferStable();
 39538 }
 39539 
 39540 
 39541 
 39542 
 39543 public function getConfig()
 39544 {
 39545 return $this->aliasOf->getConfig();
 39546 }
 39547 
 39548 
 39549 
 39550 
 39551 public function setRequires(array $require)
 39552 {
 39553 $this->requires = $this->replaceSelfVersionDependencies($require, Link::TYPE_REQUIRE);
 39554 
 39555 $this->aliasOf->setRequires($require);
 39556 }
 39557 
 39558 
 39559 
 39560 
 39561 public function setDevRequires(array $devRequire)
 39562 {
 39563 $this->devRequires = $this->replaceSelfVersionDependencies($devRequire, Link::TYPE_DEV_REQUIRE);
 39564 
 39565 $this->aliasOf->setDevRequires($devRequire);
 39566 }
 39567 
 39568 
 39569 
 39570 
 39571 public function setConflicts(array $conflicts)
 39572 {
 39573 $this->conflicts = $this->replaceSelfVersionDependencies($conflicts, Link::TYPE_CONFLICT);
 39574 $this->aliasOf->setConflicts($conflicts);
 39575 }
 39576 
 39577 
 39578 
 39579 
 39580 public function setProvides(array $provides)
 39581 {
 39582 $this->provides = $this->replaceSelfVersionDependencies($provides, Link::TYPE_PROVIDE);
 39583 $this->aliasOf->setProvides($provides);
 39584 }
 39585 
 39586 
 39587 
 39588 
 39589 public function setReplaces(array $replaces)
 39590 {
 39591 $this->replaces = $this->replaceSelfVersionDependencies($replaces, Link::TYPE_REPLACE);
 39592 $this->aliasOf->setReplaces($replaces);
 39593 }
 39594 
 39595 
 39596 
 39597 
 39598 public function setAutoload(array $autoload)
 39599 {
 39600 $this->aliasOf->setAutoload($autoload);
 39601 }
 39602 
 39603 
 39604 
 39605 
 39606 public function setDevAutoload(array $devAutoload)
 39607 {
 39608 $this->aliasOf->setDevAutoload($devAutoload);
 39609 }
 39610 
 39611 
 39612 
 39613 
 39614 public function setStabilityFlags(array $stabilityFlags)
 39615 {
 39616 $this->aliasOf->setStabilityFlags($stabilityFlags);
 39617 }
 39618 
 39619 
 39620 
 39621 
 39622 public function setMinimumStability($minimumStability)
 39623 {
 39624 $this->aliasOf->setMinimumStability($minimumStability);
 39625 }
 39626 
 39627 
 39628 
 39629 
 39630 public function setPreferStable($preferStable)
 39631 {
 39632 $this->aliasOf->setPreferStable($preferStable);
 39633 }
 39634 
 39635 
 39636 
 39637 
 39638 public function setConfig(array $config)
 39639 {
 39640 $this->aliasOf->setConfig($config);
 39641 }
 39642 
 39643 
 39644 
 39645 
 39646 public function setReferences(array $references)
 39647 {
 39648 $this->aliasOf->setReferences($references);
 39649 }
 39650 
 39651 
 39652 
 39653 
 39654 public function setAliases(array $aliases)
 39655 {
 39656 $this->aliasOf->setAliases($aliases);
 39657 }
 39658 
 39659 
 39660 
 39661 
 39662 public function setSuggests(array $suggests)
 39663 {
 39664 $this->aliasOf->setSuggests($suggests);
 39665 }
 39666 
 39667 
 39668 
 39669 
 39670 public function setExtra(array $extra)
 39671 {
 39672 $this->aliasOf->setExtra($extra);
 39673 }
 39674 
 39675 public function __clone()
 39676 {
 39677 parent::__clone();
 39678 $this->aliasOf = clone $this->aliasOf;
 39679 }
 39680 }
 39681 <?php
 39682 
 39683 
 39684 
 39685 
 39686 
 39687 
 39688 
 39689 
 39690 
 39691 
 39692 
 39693 namespace Composer\Package;
 39694 
 39695 
 39696 
 39697 
 39698 
 39699 
 39700 class RootPackage extends CompletePackage implements RootPackageInterface
 39701 {
 39702 const DEFAULT_PRETTY_VERSION = '1.0.0+no-version-set';
 39703 
 39704 
 39705 protected $minimumStability = 'stable';
 39706 
 39707 protected $preferStable = false;
 39708 
 39709 protected $stabilityFlags = array();
 39710 
 39711 protected $config = array();
 39712 
 39713 protected $references = array();
 39714 
 39715 protected $aliases = array();
 39716 
 39717 
 39718 
 39719 
 39720 public function setMinimumStability($minimumStability)
 39721 {
 39722 $this->minimumStability = $minimumStability;
 39723 }
 39724 
 39725 
 39726 
 39727 
 39728 public function getMinimumStability()
 39729 {
 39730 return $this->minimumStability;
 39731 }
 39732 
 39733 
 39734 
 39735 
 39736 public function setStabilityFlags(array $stabilityFlags)
 39737 {
 39738 $this->stabilityFlags = $stabilityFlags;
 39739 }
 39740 
 39741 
 39742 
 39743 
 39744 public function getStabilityFlags()
 39745 {
 39746 return $this->stabilityFlags;
 39747 }
 39748 
 39749 
 39750 
 39751 
 39752 public function setPreferStable($preferStable)
 39753 {
 39754 $this->preferStable = $preferStable;
 39755 }
 39756 
 39757 
 39758 
 39759 
 39760 public function getPreferStable()
 39761 {
 39762 return $this->preferStable;
 39763 }
 39764 
 39765 
 39766 
 39767 
 39768 public function setConfig(array $config)
 39769 {
 39770 $this->config = $config;
 39771 }
 39772 
 39773 
 39774 
 39775 
 39776 public function getConfig()
 39777 {
 39778 return $this->config;
 39779 }
 39780 
 39781 
 39782 
 39783 
 39784 public function setReferences(array $references)
 39785 {
 39786 $this->references = $references;
 39787 }
 39788 
 39789 
 39790 
 39791 
 39792 public function getReferences()
 39793 {
 39794 return $this->references;
 39795 }
 39796 
 39797 
 39798 
 39799 
 39800 public function setAliases(array $aliases)
 39801 {
 39802 $this->aliases = $aliases;
 39803 }
 39804 
 39805 
 39806 
 39807 
 39808 public function getAliases()
 39809 {
 39810 return $this->aliases;
 39811 }
 39812 }
 39813 <?php
 39814 
 39815 
 39816 
 39817 
 39818 
 39819 
 39820 
 39821 
 39822 
 39823 
 39824 
 39825 namespace Composer\Package;
 39826 
 39827 
 39828 
 39829 
 39830 
 39831 
 39832 
 39833 
 39834 
 39835 interface RootPackageInterface extends CompletePackageInterface
 39836 {
 39837 
 39838 
 39839 
 39840 
 39841 
 39842 public function getAliases();
 39843 
 39844 
 39845 
 39846 
 39847 
 39848 
 39849 public function getMinimumStability();
 39850 
 39851 
 39852 
 39853 
 39854 
 39855 
 39856 
 39857 
 39858 public function getStabilityFlags();
 39859 
 39860 
 39861 
 39862 
 39863 
 39864 
 39865 
 39866 
 39867 public function getReferences();
 39868 
 39869 
 39870 
 39871 
 39872 
 39873 
 39874 public function getPreferStable();
 39875 
 39876 
 39877 
 39878 
 39879 
 39880 
 39881 public function getConfig();
 39882 
 39883 
 39884 
 39885 
 39886 
 39887 
 39888 
 39889 
 39890 public function setRequires(array $requires);
 39891 
 39892 
 39893 
 39894 
 39895 
 39896 
 39897 
 39898 
 39899 public function setDevRequires(array $devRequires);
 39900 
 39901 
 39902 
 39903 
 39904 
 39905 
 39906 
 39907 
 39908 public function setConflicts(array $conflicts);
 39909 
 39910 
 39911 
 39912 
 39913 
 39914 
 39915 
 39916 
 39917 public function setProvides(array $provides);
 39918 
 39919 
 39920 
 39921 
 39922 
 39923 
 39924 
 39925 
 39926 public function setReplaces(array $replaces);
 39927 
 39928 
 39929 
 39930 
 39931 
 39932 
 39933 
 39934 
 39935 public function setRepositories(array $repositories);
 39936 
 39937 
 39938 
 39939 
 39940 
 39941 
 39942 
 39943 
 39944 
 39945 public function setAutoload(array $autoload);
 39946 
 39947 
 39948 
 39949 
 39950 
 39951 
 39952 
 39953 
 39954 
 39955 public function setDevAutoload(array $devAutoload);
 39956 
 39957 
 39958 
 39959 
 39960 
 39961 
 39962 
 39963 
 39964 public function setStabilityFlags(array $stabilityFlags);
 39965 
 39966 
 39967 
 39968 
 39969 
 39970 
 39971 
 39972 
 39973 public function setMinimumStability($minimumStability);
 39974 
 39975 
 39976 
 39977 
 39978 
 39979 
 39980 
 39981 
 39982 public function setPreferStable($preferStable);
 39983 
 39984 
 39985 
 39986 
 39987 
 39988 
 39989 
 39990 
 39991 public function setConfig(array $config);
 39992 
 39993 
 39994 
 39995 
 39996 
 39997 
 39998 
 39999 
 40000 public function setReferences(array $references);
 40001 
 40002 
 40003 
 40004 
 40005 
 40006 
 40007 
 40008 
 40009 public function setAliases(array $aliases);
 40010 
 40011 
 40012 
 40013 
 40014 
 40015 
 40016 
 40017 
 40018 public function setSuggests(array $suggests);
 40019 
 40020 
 40021 
 40022 
 40023 
 40024 
 40025 public function setExtra(array $extra);
 40026 }
 40027 <?php
 40028 
 40029 
 40030 
 40031 
 40032 
 40033 
 40034 
 40035 
 40036 
 40037 
 40038 
 40039 namespace Composer\Package\Version;
 40040 
 40041 use Composer\Package\BasePackage;
 40042 
 40043 
 40044 
 40045 
 40046 class StabilityFilter
 40047 {
 40048 
 40049 
 40050 
 40051 
 40052 
 40053 
 40054 
 40055 
 40056 
 40057 
 40058 
 40059 public static function isPackageAcceptable(array $acceptableStabilities, array $stabilityFlags, array $names, $stability)
 40060 {
 40061 foreach ($names as $name) {
 40062 
 40063 if (isset($stabilityFlags[$name])) {
 40064 if (BasePackage::$stabilities[$stability] <= $stabilityFlags[$name]) {
 40065 return true;
 40066 }
 40067 } elseif (isset($acceptableStabilities[$stability])) {
 40068 
 40069 return true;
 40070 }
 40071 }
 40072 
 40073 return false;
 40074 }
 40075 }
 40076 <?php
 40077 
 40078 
 40079 
 40080 
 40081 
 40082 
 40083 
 40084 
 40085 
 40086 
 40087 
 40088 namespace Composer\Package\Version;
 40089 
 40090 use Composer\Config;
 40091 use Composer\Pcre\Preg;
 40092 use Composer\Repository\Vcs\HgDriver;
 40093 use Composer\IO\NullIO;
 40094 use Composer\Semver\VersionParser as SemverVersionParser;
 40095 use Composer\Util\Git as GitUtil;
 40096 use Composer\Util\HttpDownloader;
 40097 use Composer\Util\ProcessExecutor;
 40098 use Composer\Util\Svn as SvnUtil;
 40099 
 40100 
 40101 
 40102 
 40103 
 40104 
 40105 
 40106 
 40107 
 40108 class VersionGuesser
 40109 {
 40110 
 40111 
 40112 
 40113 private $config;
 40114 
 40115 
 40116 
 40117 
 40118 private $process;
 40119 
 40120 
 40121 
 40122 
 40123 private $versionParser;
 40124 
 40125 
 40126 
 40127 
 40128 
 40129 
 40130 public function __construct(Config $config, ProcessExecutor $process, SemverVersionParser $versionParser)
 40131 {
 40132 $this->config = $config;
 40133 $this->process = $process;
 40134 $this->versionParser = $versionParser;
 40135 }
 40136 
 40137 
 40138 
 40139 
 40140 
 40141 
 40142 
 40143 
 40144 public function guessVersion(array $packageConfig, $path)
 40145 {
 40146 if (!function_exists('proc_open')) {
 40147 return null;
 40148 }
 40149 
 40150 $versionData = $this->guessGitVersion($packageConfig, $path);
 40151 if (null !== $versionData && null !== $versionData['version']) {
 40152 return $this->postprocess($versionData);
 40153 }
 40154 
 40155 $versionData = $this->guessHgVersion($packageConfig, $path);
 40156 if (null !== $versionData && null !== $versionData['version']) {
 40157 return $this->postprocess($versionData);
 40158 }
 40159 
 40160 $versionData = $this->guessFossilVersion($path);
 40161 if (null !== $versionData && null !== $versionData['version']) {
 40162 return $this->postprocess($versionData);
 40163 }
 40164 
 40165 $versionData = $this->guessSvnVersion($packageConfig, $path);
 40166 if (null !== $versionData && null !== $versionData['version']) {
 40167 return $this->postprocess($versionData);
 40168 }
 40169 
 40170 return null;
 40171 }
 40172 
 40173 
 40174 
 40175 
 40176 
 40177 
 40178 
 40179 
 40180 
 40181 private function postprocess(array $versionData)
 40182 {
 40183 if (!empty($versionData['feature_version']) && $versionData['feature_version'] === $versionData['version'] && $versionData['feature_pretty_version'] === $versionData['pretty_version']) {
 40184 unset($versionData['feature_version'], $versionData['feature_pretty_version']);
 40185 }
 40186 
 40187 if ('-dev' === substr($versionData['version'], -4) && Preg::isMatch('{\.9{7}}', $versionData['version'])) {
 40188 $versionData['pretty_version'] = Preg::replace('{(\.9{7})+}', '.x', $versionData['version']);
 40189 }
 40190 
 40191 if (!empty($versionData['feature_version']) && '-dev' === substr($versionData['feature_version'], -4) && Preg::isMatch('{\.9{7}}', $versionData['feature_version'])) {
 40192 $versionData['feature_pretty_version'] = Preg::replace('{(\.9{7})+}', '.x', $versionData['feature_version']);
 40193 }
 40194 
 40195 return $versionData;
 40196 }
 40197 
 40198 
 40199 
 40200 
 40201 
 40202 
 40203 
 40204 private function guessGitVersion(array $packageConfig, $path)
 40205 {
 40206 GitUtil::cleanEnv();
 40207 $commit = null;
 40208 $version = null;
 40209 $prettyVersion = null;
 40210 $featureVersion = null;
 40211 $featurePrettyVersion = null;
 40212 $isDetached = false;
 40213 
 40214 
 40215 if (0 === $this->process->execute('git branch -a --no-color --no-abbrev -v', $output, $path)) {
 40216 $branches = array();
 40217 $isFeatureBranch = false;
 40218 
 40219 
 40220 foreach ($this->process->splitLines($output) as $branch) {
 40221 if ($branch && Preg::isMatch('{^(?:\* ) *(\(no branch\)|\(detached from \S+\)|\(HEAD detached at \S+\)|\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
 40222 if (
 40223 $match[1] === '(no branch)'
 40224 || strpos($match[1], '(detached ') === 0
 40225 || strpos($match[1], '(HEAD detached at') === 0
 40226 ) {
 40227 $version = 'dev-' . $match[2];
 40228 $prettyVersion = $version;
 40229 $isFeatureBranch = true;
 40230 $isDetached = true;
 40231 } else {
 40232 $version = $this->versionParser->normalizeBranch($match[1]);
 40233 $prettyVersion = 'dev-' . $match[1];
 40234 $isFeatureBranch = $this->isFeatureBranch($packageConfig, $match[1]);
 40235 }
 40236 
 40237 if ($match[2]) {
 40238 $commit = $match[2];
 40239 }
 40240 }
 40241 
 40242 if ($branch && !Preg::isMatch('{^ *.+/HEAD }', $branch)) {
 40243 if (Preg::isMatch('{^(?:\* )? *((?:remotes/(?:origin|upstream)/)?[^\s/]+) *([a-f0-9]+) .*$}', $branch, $match)) {
 40244 $branches[] = $match[1];
 40245 }
 40246 }
 40247 }
 40248 
 40249 if ($isFeatureBranch) {
 40250 $featureVersion = $version;
 40251 $featurePrettyVersion = $prettyVersion;
 40252 
 40253 
 40254 $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
 40255 $version = $result['version'];
 40256 $prettyVersion = $result['pretty_version'];
 40257 }
 40258 }
 40259 
 40260 if (!$version || $isDetached) {
 40261 $result = $this->versionFromGitTags($path);
 40262 if ($result) {
 40263 $version = $result['version'];
 40264 $prettyVersion = $result['pretty_version'];
 40265 $featureVersion = null;
 40266 $featurePrettyVersion = null;
 40267 }
 40268 }
 40269 
 40270 if (!$commit) {
 40271 $command = 'git log --pretty="%H" -n1 HEAD'.GitUtil::getNoShowSignatureFlag($this->process);
 40272 if (0 === $this->process->execute($command, $output, $path)) {
 40273 $commit = trim($output) ?: null;
 40274 }
 40275 }
 40276 
 40277 if ($featureVersion) {
 40278 return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion, 'feature_version' => $featureVersion, 'feature_pretty_version' => $featurePrettyVersion);
 40279 }
 40280 
 40281 return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion);
 40282 }
 40283 
 40284 
 40285 
 40286 
 40287 
 40288 
 40289 private function versionFromGitTags($path)
 40290 {
 40291 
 40292 if (0 === $this->process->execute('git describe --exact-match --tags', $output, $path)) {
 40293 try {
 40294 $version = $this->versionParser->normalize(trim($output));
 40295 
 40296 return array('version' => $version, 'pretty_version' => trim($output));
 40297 } catch (\Exception $e) {
 40298 }
 40299 }
 40300 
 40301 return null;
 40302 }
 40303 
 40304 
 40305 
 40306 
 40307 
 40308 
 40309 
 40310 private function guessHgVersion(array $packageConfig, $path)
 40311 {
 40312 
 40313 if (0 === $this->process->execute('hg branch', $output, $path)) {
 40314 $branch = trim($output);
 40315 $version = $this->versionParser->normalizeBranch($branch);
 40316 $isFeatureBranch = 0 === strpos($version, 'dev-');
 40317 
 40318 if (VersionParser::DEFAULT_BRANCH_ALIAS === $version) {
 40319 return array('version' => $version, 'commit' => null, 'pretty_version' => 'dev-'.$branch);
 40320 }
 40321 
 40322 if (!$isFeatureBranch) {
 40323 return array('version' => $version, 'commit' => null, 'pretty_version' => $version);
 40324 }
 40325 
 40326 
 40327 $io = new NullIO();
 40328 $driver = new HgDriver(array('url' => $path), $io, $this->config, new HttpDownloader($io, $this->config), $this->process);
 40329 $branches = array_map('strval', array_keys($driver->getBranches()));
 40330 
 40331 
 40332 $result = $this->guessFeatureVersion($packageConfig, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"', $path);
 40333 $result['commit'] = '';
 40334 $result['feature_version'] = $version;
 40335 $result['feature_pretty_version'] = $version;
 40336 
 40337 return $result;
 40338 }
 40339 
 40340 return null;
 40341 }
 40342 
 40343 
 40344 
 40345 
 40346 
 40347 
 40348 
 40349 
 40350 
 40351 
 40352 
 40353 
 40354 private function guessFeatureVersion(array $packageConfig, $version, array $branches, $scmCmdline, $path)
 40355 {
 40356 $prettyVersion = $version;
 40357 
 40358 
 40359 
 40360 if (!isset($packageConfig['extra']['branch-alias'][$version])
 40361 || strpos(json_encode($packageConfig), '"self.version"')
 40362 ) {
 40363 $branch = Preg::replace('{^dev-}', '', $version);
 40364 $length = PHP_INT_MAX;
 40365 
 40366 
 40367 if (!$this->isFeatureBranch($packageConfig, $branch)) {
 40368 return array('version' => $version, 'pretty_version' => $prettyVersion);
 40369 }
 40370 
 40371 
 40372 
 40373 
 40374 usort($branches, function ($a, $b) {
 40375 $aRemote = 0 === strpos($a, 'remotes/');
 40376 $bRemote = 0 === strpos($b, 'remotes/');
 40377 
 40378 if ($aRemote !== $bRemote) {
 40379 return $aRemote ? 1 : -1;
 40380 }
 40381 
 40382 return strnatcasecmp($b, $a);
 40383 });
 40384 
 40385 foreach ($branches as $candidate) {
 40386 $candidateVersion = Preg::replace('{^remotes/\S+/}', '', $candidate);
 40387 
 40388 
 40389 if ($candidate === $branch || $this->isFeatureBranch($packageConfig, $candidateVersion)) {
 40390 continue;
 40391 }
 40392 
 40393 $cmdLine = str_replace(array('%candidate%', '%branch%'), array($candidate, $branch), $scmCmdline);
 40394 if (0 !== $this->process->execute($cmdLine, $output, $path)) {
 40395 continue;
 40396 }
 40397 
 40398 if (strlen($output) < $length) {
 40399 $length = strlen($output);
 40400 $version = $this->versionParser->normalizeBranch($candidateVersion);
 40401 $prettyVersion = 'dev-' . $candidateVersion;
 40402 if ($length === 0) {
 40403 break;
 40404 }
 40405 }
 40406 }
 40407 }
 40408 
 40409 return array('version' => $version, 'pretty_version' => $prettyVersion);
 40410 }
 40411 
 40412 
 40413 
 40414 
 40415 
 40416 
 40417 
 40418 private function isFeatureBranch(array $packageConfig, $branchName)
 40419 {
 40420 $nonFeatureBranches = '';
 40421 if (!empty($packageConfig['non-feature-branches'])) {
 40422 $nonFeatureBranches = implode('|', $packageConfig['non-feature-branches']);
 40423 }
 40424 
 40425 return !Preg::isMatch('{^(' . $nonFeatureBranches . '|master|main|latest|next|current|support|tip|trunk|default|develop|\d+\..+)$}', $branchName, $match);
 40426 }
 40427 
 40428 
 40429 
 40430 
 40431 
 40432 
 40433 private function guessFossilVersion($path)
 40434 {
 40435 $version = null;
 40436 $prettyVersion = null;
 40437 
 40438 
 40439 if (0 === $this->process->execute('fossil branch list', $output, $path)) {
 40440 $branch = trim($output);
 40441 $version = $this->versionParser->normalizeBranch($branch);
 40442 $prettyVersion = 'dev-' . $branch;
 40443 }
 40444 
 40445 
 40446 if (0 === $this->process->execute('fossil tag list', $output, $path)) {
 40447 try {
 40448 $version = $this->versionParser->normalize(trim($output));
 40449 $prettyVersion = trim($output);
 40450 } catch (\Exception $e) {
 40451 }
 40452 }
 40453 
 40454 return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion);
 40455 }
 40456 
 40457 
 40458 
 40459 
 40460 
 40461 
 40462 
 40463 private function guessSvnVersion(array $packageConfig, $path)
 40464 {
 40465 SvnUtil::cleanEnv();
 40466 
 40467 
 40468 if (0 === $this->process->execute('svn info --xml', $output, $path)) {
 40469 $trunkPath = isset($packageConfig['trunk-path']) ? preg_quote($packageConfig['trunk-path'], '#') : 'trunk';
 40470 $branchesPath = isset($packageConfig['branches-path']) ? preg_quote($packageConfig['branches-path'], '#') : 'branches';
 40471 $tagsPath = isset($packageConfig['tags-path']) ? preg_quote($packageConfig['tags-path'], '#') : 'tags';
 40472 
 40473 $urlPattern = '#<url>.*/(' . $trunkPath . '|(' . $branchesPath . '|' . $tagsPath . ')/(.*))</url>#';
 40474 
 40475 if (Preg::isMatch($urlPattern, $output, $matches)) {
 40476 if (isset($matches[2]) && ($branchesPath === $matches[2] || $tagsPath === $matches[2])) {
 40477 
 40478 $version = $this->versionParser->normalizeBranch($matches[3]);
 40479 $prettyVersion = 'dev-' . $matches[3];
 40480 
 40481 return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion);
 40482 }
 40483 
 40484 $prettyVersion = trim($matches[1]);
 40485 if ($prettyVersion === 'trunk') {
 40486 $version = 'dev-trunk';
 40487 } else {
 40488 $version = $this->versionParser->normalize($prettyVersion);
 40489 }
 40490 
 40491 return array('version' => $version, 'commit' => '', 'pretty_version' => $prettyVersion);
 40492 }
 40493 }
 40494 
 40495 return null;
 40496 }
 40497 }
 40498 <?php
 40499 
 40500 
 40501 
 40502 
 40503 
 40504 
 40505 
 40506 
 40507 
 40508 
 40509 
 40510 namespace Composer\Package\Version;
 40511 
 40512 use Composer\Pcre\Preg;
 40513 use Composer\Repository\PlatformRepository;
 40514 use Composer\Semver\VersionParser as SemverVersionParser;
 40515 use Composer\Semver\Semver;
 40516 use Composer\Semver\Constraint\ConstraintInterface;
 40517 
 40518 class VersionParser extends SemverVersionParser
 40519 {
 40520 const DEFAULT_BRANCH_ALIAS = '9999999-dev';
 40521 
 40522 
 40523 private static $constraints = array();
 40524 
 40525 
 40526 
 40527 
 40528 public function parseConstraints($constraints)
 40529 {
 40530 if (!isset(self::$constraints[$constraints])) {
 40531 self::$constraints[$constraints] = parent::parseConstraints($constraints);
 40532 }
 40533 
 40534 return self::$constraints[$constraints];
 40535 }
 40536 
 40537 
 40538 
 40539 
 40540 
 40541 
 40542 
 40543 
 40544 
 40545 
 40546 
 40547 public function parseNameVersionPairs(array $pairs)
 40548 {
 40549 $pairs = array_values($pairs);
 40550 $result = array();
 40551 
 40552 for ($i = 0, $count = count($pairs); $i < $count; $i++) {
 40553 $pair = Preg::replace('{^([^=: ]+)[=: ](.*)$}', '$1 $2', trim($pairs[$i]));
 40554 if (false === strpos($pair, ' ') && isset($pairs[$i + 1]) && false === strpos($pairs[$i + 1], '/') && !Preg::isMatch('{(?<=[a-z0-9_/-])\*|\*(?=[a-z0-9_/-])}i', $pairs[$i + 1]) && !PlatformRepository::isPlatformPackage($pairs[$i + 1])) {
 40555 $pair .= ' '.$pairs[$i + 1];
 40556 $i++;
 40557 }
 40558 
 40559 if (strpos($pair, ' ')) {
 40560 list($name, $version) = explode(' ', $pair, 2);
 40561 $result[] = array('name' => $name, 'version' => $version);
 40562 } else {
 40563 $result[] = array('name' => $pair);
 40564 }
 40565 }
 40566 
 40567 return $result;
 40568 }
 40569 
 40570 
 40571 
 40572 
 40573 
 40574 
 40575 
 40576 public static function isUpgrade($normalizedFrom, $normalizedTo)
 40577 {
 40578 if ($normalizedFrom === $normalizedTo) {
 40579 return true;
 40580 }
 40581 
 40582 if (in_array($normalizedFrom, array('dev-master', 'dev-trunk', 'dev-default'), true)) {
 40583 $normalizedFrom = VersionParser::DEFAULT_BRANCH_ALIAS;
 40584 }
 40585 if (in_array($normalizedTo, array('dev-master', 'dev-trunk', 'dev-default'), true)) {
 40586 $normalizedTo = VersionParser::DEFAULT_BRANCH_ALIAS;
 40587 }
 40588 
 40589 if (strpos($normalizedFrom, 'dev-') === 0 || strpos($normalizedTo, 'dev-') === 0) {
 40590 return true;
 40591 }
 40592 
 40593 $sorted = Semver::sort(array($normalizedTo, $normalizedFrom));
 40594 
 40595 return $sorted[0] === $normalizedFrom;
 40596 }
 40597 }
 40598 <?php
 40599 
 40600 
 40601 
 40602 
 40603 
 40604 
 40605 
 40606 
 40607 
 40608 
 40609 
 40610 namespace Composer\Package\Version;
 40611 
 40612 use Composer\Filter\PlatformRequirementFilter\IgnoreAllPlatformRequirementFilter;
 40613 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterFactory;
 40614 use Composer\Filter\PlatformRequirementFilter\PlatformRequirementFilterInterface;
 40615 use Composer\Package\BasePackage;
 40616 use Composer\Package\AliasPackage;
 40617 use Composer\Package\PackageInterface;
 40618 use Composer\Composer;
 40619 use Composer\Package\Loader\ArrayLoader;
 40620 use Composer\Package\Dumper\ArrayDumper;
 40621 use Composer\Pcre\Preg;
 40622 use Composer\Repository\RepositorySet;
 40623 use Composer\Repository\PlatformRepository;
 40624 use Composer\Semver\Constraint\Constraint;
 40625 use Composer\Semver\Constraint\ConstraintInterface;
 40626 
 40627 
 40628 
 40629 
 40630 
 40631 
 40632 
 40633 class VersionSelector
 40634 {
 40635 
 40636 private $repositorySet;
 40637 
 40638 
 40639 private $platformConstraints = array();
 40640 
 40641 
 40642 private $parser;
 40643 
 40644 
 40645 
 40646 
 40647 public function __construct(RepositorySet $repositorySet, PlatformRepository $platformRepo = null)
 40648 {
 40649 $this->repositorySet = $repositorySet;
 40650 if ($platformRepo) {
 40651 foreach ($platformRepo->getPackages() as $package) {
 40652 $this->platformConstraints[$package->getName()][] = new Constraint('==', $package->getVersion());
 40653 }
 40654 }
 40655 }
 40656 
 40657 
 40658 
 40659 
 40660 
 40661 
 40662 
 40663 
 40664 
 40665 
 40666 
 40667 
 40668 public function findBestCandidate($packageName, $targetPackageVersion = null, $preferredStability = 'stable', $platformRequirementFilter = null, $repoSetFlags = 0)
 40669 {
 40670 if (!isset(BasePackage::$stabilities[$preferredStability])) {
 40671 
 40672 throw new \UnexpectedValueException('Expected a valid stability name as 3rd argument, got '.$preferredStability);
 40673 }
 40674 
 40675 if (null === $platformRequirementFilter) {
 40676 $platformRequirementFilter = PlatformRequirementFilterFactory::ignoreNothing();
 40677 } elseif (!($platformRequirementFilter instanceof PlatformRequirementFilterInterface)) {
 40678 trigger_error('VersionSelector::findBestCandidate with ignored platform reqs as bool|array is deprecated since Composer 2.2, use an instance of PlatformRequirementFilterInterface instead.', E_USER_DEPRECATED);
 40679 $platformRequirementFilter = PlatformRequirementFilterFactory::fromBoolOrList($platformRequirementFilter);
 40680 }
 40681 
 40682 $constraint = $targetPackageVersion ? $this->getParser()->parseConstraints($targetPackageVersion) : null;
 40683 $candidates = $this->repositorySet->findPackages(strtolower($packageName), $constraint, $repoSetFlags);
 40684 
 40685 if ($this->platformConstraints && !($platformRequirementFilter instanceof IgnoreAllPlatformRequirementFilter)) {
 40686 $platformConstraints = $this->platformConstraints;
 40687 $candidates = array_filter($candidates, function ($pkg) use ($platformConstraints, $platformRequirementFilter) {
 40688 $reqs = $pkg->getRequires();
 40689 
 40690 foreach ($reqs as $name => $link) {
 40691 if (!$platformRequirementFilter->isIgnored($name)) {
 40692 if (isset($platformConstraints[$name])) {
 40693 foreach ($platformConstraints[$name] as $constraint) {
 40694 if ($link->getConstraint()->matches($constraint)) {
 40695 continue 2;
 40696 }
 40697 }
 40698 
 40699 return false;
 40700 } elseif (PlatformRepository::isPlatformPackage($name)) {
 40701 
 40702 
 40703 return false;
 40704 }
 40705 }
 40706 }
 40707 
 40708 return true;
 40709 });
 40710 }
 40711 
 40712 if (!$candidates) {
 40713 return false;
 40714 }
 40715 
 40716 
 40717 $package = reset($candidates);
 40718 $minPriority = BasePackage::$stabilities[$preferredStability];
 40719 foreach ($candidates as $candidate) {
 40720 $candidatePriority = $candidate->getStabilityPriority();
 40721 $currentPriority = $package->getStabilityPriority();
 40722 
 40723 
 40724 
 40725 if ($minPriority < $candidatePriority && $currentPriority < $candidatePriority) {
 40726 continue;
 40727 }
 40728 
 40729 
 40730 
 40731 if ($minPriority < $candidatePriority && $candidatePriority < $currentPriority) {
 40732 $package = $candidate;
 40733 continue;
 40734 }
 40735 
 40736 
 40737 
 40738 if ($minPriority >= $candidatePriority && $minPriority < $currentPriority) {
 40739 $package = $candidate;
 40740 continue;
 40741 }
 40742 
 40743 
 40744 if (version_compare($package->getVersion(), $candidate->getVersion(), '<')) {
 40745 $package = $candidate;
 40746 }
 40747 }
 40748 
 40749 
 40750 if ($package instanceof AliasPackage && $package->getVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {
 40751 $package = $package->getAliasOf();
 40752 }
 40753 
 40754 return $package;
 40755 }
 40756 
 40757 
 40758 
 40759 
 40760 
 40761 
 40762 
 40763 
 40764 
 40765 
 40766 
 40767 
 40768 
 40769 
 40770 
 40771 
 40772 public function findRecommendedRequireVersion(PackageInterface $package)
 40773 {
 40774 
 40775 
 40776 if (0 === strpos($package->getName(), 'ext-')) {
 40777 $phpVersion = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
 40778 $extVersion = implode('.', array_slice(explode('.', $package->getVersion()), 0, 3));
 40779 if ($phpVersion === $extVersion) {
 40780 return '*';
 40781 }
 40782 }
 40783 
 40784 $version = $package->getVersion();
 40785 if (!$package->isDev()) {
 40786 return $this->transformVersion($version, $package->getPrettyVersion(), $package->getStability());
 40787 }
 40788 
 40789 $loader = new ArrayLoader($this->getParser());
 40790 $dumper = new ArrayDumper();
 40791 $extra = $loader->getBranchAlias($dumper->dump($package));
 40792 if ($extra && $extra !== VersionParser::DEFAULT_BRANCH_ALIAS) {
 40793 $extra = Preg::replace('{^(\d+\.\d+\.\d+)(\.9999999)-dev$}', '$1.0', $extra, -1, $count);
 40794 if ($count) {
 40795 $extra = str_replace('.9999999', '.0', $extra);
 40796 
 40797 return $this->transformVersion($extra, $extra, 'dev');
 40798 }
 40799 }
 40800 
 40801 return $package->getPrettyVersion();
 40802 }
 40803 
 40804 
 40805 
 40806 
 40807 
 40808 
 40809 
 40810 
 40811 private function transformVersion($version, $prettyVersion, $stability)
 40812 {
 40813 
 40814 
 40815 $semanticVersionParts = explode('.', $version);
 40816 
 40817 
 40818 if (count($semanticVersionParts) == 4 && Preg::isMatch('{^0\D?}', $semanticVersionParts[3])) {
 40819 
 40820 if ($semanticVersionParts[0] === '0') {
 40821 unset($semanticVersionParts[3]);
 40822 } else {
 40823 unset($semanticVersionParts[2], $semanticVersionParts[3]);
 40824 }
 40825 $version = implode('.', $semanticVersionParts);
 40826 } else {
 40827 return $prettyVersion;
 40828 }
 40829 
 40830 
 40831 if ($stability != 'stable') {
 40832 $version .= '@'.$stability;
 40833 }
 40834 
 40835 
 40836 return '^' . $version;
 40837 }
 40838 
 40839 
 40840 
 40841 
 40842 private function getParser()
 40843 {
 40844 if ($this->parser === null) {
 40845 $this->parser = new VersionParser();
 40846 }
 40847 
 40848 return $this->parser;
 40849 }
 40850 }
 40851 <?php
 40852 
 40853 
 40854 
 40855 
 40856 
 40857 
 40858 
 40859 
 40860 
 40861 
 40862 
 40863 namespace Composer\Platform;
 40864 
 40865 use Composer\Util\Platform;
 40866 use Composer\Util\ProcessExecutor;
 40867 use Symfony\Component\Process\ExecutableFinder;
 40868 
 40869 class HhvmDetector
 40870 {
 40871 
 40872 private static $hhvmVersion = null;
 40873 
 40874 private $executableFinder;
 40875 
 40876 private $processExecutor;
 40877 
 40878 public function __construct(ExecutableFinder $executableFinder = null, ProcessExecutor $processExecutor = null)
 40879 {
 40880 $this->executableFinder = $executableFinder;
 40881 $this->processExecutor = $processExecutor;
 40882 }
 40883 
 40884 
 40885 
 40886 
 40887 public function reset()
 40888 {
 40889 self::$hhvmVersion = null;
 40890 }
 40891 
 40892 
 40893 
 40894 
 40895 public function getVersion()
 40896 {
 40897 if (null !== self::$hhvmVersion) {
 40898 return self::$hhvmVersion ?: null;
 40899 }
 40900 
 40901 self::$hhvmVersion = defined('HHVM_VERSION') ? HHVM_VERSION : null;
 40902 if (self::$hhvmVersion === null && !Platform::isWindows()) {
 40903 self::$hhvmVersion = false;
 40904 $this->executableFinder = $this->executableFinder ?: new ExecutableFinder();
 40905 $hhvmPath = $this->executableFinder->find('hhvm');
 40906 if ($hhvmPath !== null) {
 40907 $this->processExecutor = $this->processExecutor ?: new ProcessExecutor();
 40908 $exitCode = $this->processExecutor->execute(
 40909 ProcessExecutor::escape($hhvmPath).
 40910 ' --php -d hhvm.jit=0 -r "echo HHVM_VERSION;" 2>/dev/null',
 40911 self::$hhvmVersion
 40912 );
 40913 if ($exitCode !== 0) {
 40914 self::$hhvmVersion = false;
 40915 }
 40916 }
 40917 }
 40918 
 40919 return self::$hhvmVersion ?: null;
 40920 }
 40921 }
 40922 <?php
 40923 
 40924 
 40925 
 40926 
 40927 
 40928 
 40929 
 40930 
 40931 
 40932 
 40933 
 40934 namespace Composer\Platform;
 40935 
 40936 class Runtime
 40937 {
 40938 
 40939 
 40940 
 40941 
 40942 
 40943 
 40944 public function hasConstant($constant, $class = null)
 40945 {
 40946 return defined(ltrim($class.'::'.$constant, ':'));
 40947 }
 40948 
 40949 
 40950 
 40951 
 40952 
 40953 
 40954 
 40955 public function getConstant($constant, $class = null)
 40956 {
 40957 return constant(ltrim($class.'::'.$constant, ':'));
 40958 }
 40959 
 40960 
 40961 
 40962 
 40963 
 40964 
 40965 public function hasFunction($fn)
 40966 {
 40967 return function_exists($fn);
 40968 }
 40969 
 40970 
 40971 
 40972 
 40973 
 40974 
 40975 
 40976 public function invoke($callable, array $arguments = array())
 40977 {
 40978 return call_user_func_array($callable, $arguments);
 40979 }
 40980 
 40981 
 40982 
 40983 
 40984 
 40985 
 40986 public function hasClass($class)
 40987 {
 40988 return class_exists($class, false);
 40989 }
 40990 
 40991 
 40992 
 40993 
 40994 
 40995 
 40996 
 40997 
 40998 public function construct($class, array $arguments = array())
 40999 {
 41000 if (empty($arguments)) {
 41001 return new $class;
 41002 }
 41003 
 41004 $refl = new \ReflectionClass($class);
 41005 
 41006 return $refl->newInstanceArgs($arguments);
 41007 }
 41008 
 41009 
 41010 public function getExtensions()
 41011 {
 41012 return get_loaded_extensions();
 41013 }
 41014 
 41015 
 41016 
 41017 
 41018 
 41019 
 41020 public function getExtensionVersion($extension)
 41021 {
 41022 return phpversion($extension);
 41023 }
 41024 
 41025 
 41026 
 41027 
 41028 
 41029 
 41030 
 41031 public function getExtensionInfo($extension)
 41032 {
 41033 $reflector = new \ReflectionExtension($extension);
 41034 
 41035 ob_start();
 41036 $reflector->info();
 41037 
 41038 return ob_get_clean();
 41039 }
 41040 }
 41041 <?php
 41042 
 41043 
 41044 
 41045 
 41046 
 41047 
 41048 
 41049 
 41050 
 41051 
 41052 
 41053 namespace Composer\Platform;
 41054 
 41055 use Composer\Pcre\Preg;
 41056 
 41057 
 41058 
 41059 
 41060 class Version
 41061 {
 41062 
 41063 
 41064 
 41065 
 41066 
 41067 public static function parseOpenssl($opensslVersion, &$isFips)
 41068 {
 41069 $isFips = false;
 41070 
 41071 if (!Preg::isMatch('/^(?<version>[0-9.]+)(?<patch>[a-z]{0,2})?(?<suffix>(?:-?(?:dev|pre|alpha|beta|rc|fips)[\d]*)*)?(?<garbage>-\w+)?$/', $opensslVersion, $matches)) {
 41072 return null;
 41073 }
 41074 
 41075 $isFips = strpos($matches['suffix'], 'fips') !== false;
 41076 $suffix = strtr('-'.ltrim($matches['suffix'], '-'), array('-fips' => '', '-pre' => '-alpha'));
 41077 $patch = self::convertAlphaVersionToIntVersion($matches['patch']);
 41078 
 41079 return rtrim($matches['version'].'.'.$patch.$suffix, '-');
 41080 }
 41081 
 41082 
 41083 
 41084 
 41085 
 41086 public static function parseLibjpeg($libjpegVersion)
 41087 {
 41088 if (!Preg::isMatch('/^(?<major>\d+)(?<minor>[a-z]*)$/', $libjpegVersion, $matches)) {
 41089 return null;
 41090 }
 41091 
 41092 return $matches['major'].'.'.self::convertAlphaVersionToIntVersion($matches['minor']);
 41093 }
 41094 
 41095 
 41096 
 41097 
 41098 
 41099 public static function parseZoneinfoVersion($zoneinfoVersion)
 41100 {
 41101 if (!Preg::isMatch('/^(?<year>\d{4})(?<revision>[a-z]*)$/', $zoneinfoVersion, $matches)) {
 41102 return null;
 41103 }
 41104 
 41105 return $matches['year'].'.'.self::convertAlphaVersionToIntVersion($matches['revision']);
 41106 }
 41107 
 41108 
 41109 
 41110 
 41111 
 41112 
 41113 
 41114 private static function convertAlphaVersionToIntVersion($alpha)
 41115 {
 41116 return strlen($alpha) * (-ord('a') + 1) + array_sum(array_map('ord', str_split($alpha)));
 41117 }
 41118 
 41119 
 41120 
 41121 
 41122 
 41123 public static function convertLibxpmVersionId($versionId)
 41124 {
 41125 return self::convertVersionId($versionId, 100);
 41126 }
 41127 
 41128 
 41129 
 41130 
 41131 
 41132 public static function convertOpenldapVersionId($versionId)
 41133 {
 41134 return self::convertVersionId($versionId, 100);
 41135 }
 41136 
 41137 
 41138 
 41139 
 41140 
 41141 
 41142 
 41143 private static function convertVersionId($versionId, $base)
 41144 {
 41145 return sprintf(
 41146 '%d.%d.%d',
 41147 $versionId / ($base * $base),
 41148 (int) ($versionId / $base) % $base,
 41149 $versionId % $base
 41150 );
 41151 }
 41152 }
 41153 <?php
 41154 
 41155 
 41156 
 41157 
 41158 
 41159 
 41160 
 41161 
 41162 
 41163 
 41164 
 41165 namespace Composer\Plugin\Capability;
 41166 
 41167 
 41168 
 41169 
 41170 
 41171 
 41172 
 41173 interface Capability
 41174 {
 41175 }
 41176 <?php
 41177 
 41178 
 41179 
 41180 
 41181 
 41182 
 41183 
 41184 
 41185 
 41186 
 41187 
 41188 namespace Composer\Plugin\Capability;
 41189 
 41190 
 41191 
 41192 
 41193 
 41194 
 41195 
 41196 
 41197 
 41198 
 41199 
 41200 interface CommandProvider extends Capability
 41201 {
 41202 
 41203 
 41204 
 41205 
 41206 
 41207 public function getCommands();
 41208 }
 41209 <?php
 41210 
 41211 
 41212 
 41213 
 41214 
 41215 
 41216 
 41217 
 41218 
 41219 
 41220 
 41221 namespace Composer\Plugin;
 41222 
 41223 
 41224 
 41225 
 41226 
 41227 
 41228 
 41229 
 41230 interface Capable
 41231 {
 41232 
 41233 
 41234 
 41235 
 41236 
 41237 
 41238 
 41239 
 41240 
 41241 
 41242 
 41243 
 41244 
 41245 
 41246 
 41247 
 41248 
 41249 
 41250 public function getCapabilities();
 41251 }
 41252 <?php
 41253 
 41254 
 41255 
 41256 
 41257 
 41258 
 41259 
 41260 
 41261 
 41262 
 41263 
 41264 namespace Composer\Plugin;
 41265 
 41266 use Composer\EventDispatcher\Event;
 41267 use Symfony\Component\Console\Input\InputInterface;
 41268 use Symfony\Component\Console\Output\OutputInterface;
 41269 
 41270 
 41271 
 41272 
 41273 
 41274 
 41275 class CommandEvent extends Event
 41276 {
 41277 
 41278 
 41279 
 41280 private $commandName;
 41281 
 41282 
 41283 
 41284 
 41285 private $input;
 41286 
 41287 
 41288 
 41289 
 41290 private $output;
 41291 
 41292 
 41293 
 41294 
 41295 
 41296 
 41297 
 41298 
 41299 
 41300 
 41301 
 41302 public function __construct($name, $commandName, $input, $output, array $args = array(), array $flags = array())
 41303 {
 41304 parent::__construct($name, $args, $flags);
 41305 $this->commandName = $commandName;
 41306 $this->input = $input;
 41307 $this->output = $output;
 41308 }
 41309 
 41310 
 41311 
 41312 
 41313 
 41314 
 41315 public function getInput()
 41316 {
 41317 return $this->input;
 41318 }
 41319 
 41320 
 41321 
 41322 
 41323 
 41324 
 41325 public function getOutput()
 41326 {
 41327 return $this->output;
 41328 }
 41329 
 41330 
 41331 
 41332 
 41333 
 41334 
 41335 public function getCommandName()
 41336 {
 41337 return $this->commandName;
 41338 }
 41339 }
 41340 <?php
 41341 
 41342 
 41343 
 41344 
 41345 
 41346 
 41347 
 41348 
 41349 
 41350 
 41351 
 41352 namespace Composer\Plugin;
 41353 
 41354 
 41355 
 41356 
 41357 
 41358 
 41359 class PluginEvents
 41360 {
 41361 
 41362 
 41363 
 41364 
 41365 
 41366 
 41367 
 41368 
 41369 const INIT = 'init';
 41370 
 41371 
 41372 
 41373 
 41374 
 41375 
 41376 
 41377 
 41378 
 41379 const COMMAND = 'command';
 41380 
 41381 
 41382 
 41383 
 41384 
 41385 
 41386 
 41387 
 41388 
 41389 const PRE_FILE_DOWNLOAD = 'pre-file-download';
 41390 
 41391 
 41392 
 41393 
 41394 
 41395 
 41396 
 41397 
 41398 
 41399 const POST_FILE_DOWNLOAD = 'post-file-download';
 41400 
 41401 
 41402 
 41403 
 41404 
 41405 
 41406 
 41407 
 41408 
 41409 const PRE_COMMAND_RUN = 'pre-command-run';
 41410 
 41411 
 41412 
 41413 
 41414 
 41415 
 41416 
 41417 
 41418 
 41419 
 41420 const PRE_POOL_CREATE = 'pre-pool-create';
 41421 }
 41422 <?php
 41423 
 41424 
 41425 
 41426 
 41427 
 41428 
 41429 
 41430 
 41431 
 41432 
 41433 
 41434 namespace Composer\Plugin;
 41435 
 41436 use Composer\Composer;
 41437 use Composer\IO\IOInterface;
 41438 
 41439 
 41440 
 41441 
 41442 
 41443 
 41444 interface PluginInterface
 41445 {
 41446 
 41447 
 41448 
 41449 
 41450 
 41451 
 41452 
 41453 
 41454 
 41455 
 41456 const PLUGIN_API_VERSION = '2.2.0';
 41457 
 41458 
 41459 
 41460 
 41461 
 41462 
 41463 
 41464 
 41465 
 41466 public function activate(Composer $composer, IOInterface $io);
 41467 
 41468 
 41469 
 41470 
 41471 
 41472 
 41473 
 41474 
 41475 
 41476 
 41477 
 41478 
 41479 
 41480 public function deactivate(Composer $composer, IOInterface $io);
 41481 
 41482 
 41483 
 41484 
 41485 
 41486 
 41487 
 41488 
 41489 
 41490 
 41491 
 41492 public function uninstall(Composer $composer, IOInterface $io);
 41493 }
 41494 <?php
 41495 
 41496 
 41497 
 41498 
 41499 
 41500 
 41501 
 41502 
 41503 
 41504 
 41505 
 41506 namespace Composer\Plugin;
 41507 
 41508 use Composer\Composer;
 41509 use Composer\EventDispatcher\EventSubscriberInterface;
 41510 use Composer\Installer\InstallerInterface;
 41511 use Composer\IO\IOInterface;
 41512 use Composer\Package\BasePackage;
 41513 use Composer\Package\CompletePackage;
 41514 use Composer\Package\Package;
 41515 use Composer\Package\Version\VersionParser;
 41516 use Composer\Pcre\Preg;
 41517 use Composer\Repository\RepositoryInterface;
 41518 use Composer\Repository\InstalledRepository;
 41519 use Composer\Repository\RootPackageRepository;
 41520 use Composer\Package\PackageInterface;
 41521 use Composer\Package\Link;
 41522 use Composer\Semver\Constraint\Constraint;
 41523 use Composer\Plugin\Capability\Capability;
 41524 use Composer\Util\PackageSorter;
 41525 
 41526 
 41527 
 41528 
 41529 
 41530 
 41531 
 41532 class PluginManager
 41533 {
 41534 
 41535 protected $composer;
 41536 
 41537 protected $io;
 41538 
 41539 protected $globalComposer;
 41540 
 41541 protected $versionParser;
 41542 
 41543 protected $disablePlugins = false;
 41544 
 41545 
 41546 protected $plugins = array();
 41547 
 41548 protected $registeredPlugins = array();
 41549 
 41550 
 41551 
 41552 
 41553 private $allowPluginRules;
 41554 
 41555 
 41556 
 41557 
 41558 private $allowGlobalPluginRules;
 41559 
 41560 
 41561 private static $classCounter = 0;
 41562 
 41563 
 41564 
 41565 
 41566 
 41567 
 41568 
 41569 
 41570 
 41571 public function __construct(IOInterface $io, Composer $composer, Composer $globalComposer = null, $disablePlugins = false)
 41572 {
 41573 $this->io = $io;
 41574 $this->composer = $composer;
 41575 $this->globalComposer = $globalComposer;
 41576 $this->versionParser = new VersionParser();
 41577 $this->disablePlugins = $disablePlugins;
 41578 
 41579 $this->allowPluginRules = $this->parseAllowedPlugins($composer->getConfig()->get('allow-plugins'));
 41580 $this->allowGlobalPluginRules = $this->parseAllowedPlugins($globalComposer !== null ? $globalComposer->getConfig()->get('allow-plugins') : false);
 41581 }
 41582 
 41583 
 41584 
 41585 
 41586 
 41587 
 41588 public function loadInstalledPlugins()
 41589 {
 41590 if ($this->disablePlugins) {
 41591 return;
 41592 }
 41593 
 41594 $repo = $this->composer->getRepositoryManager()->getLocalRepository();
 41595 $globalRepo = $this->globalComposer !== null ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
 41596 $this->loadRepository($repo, false);
 41597 if ($globalRepo) {
 41598 $this->loadRepository($globalRepo, true);
 41599 }
 41600 }
 41601 
 41602 
 41603 
 41604 
 41605 
 41606 
 41607 public function deactivateInstalledPlugins()
 41608 {
 41609 if ($this->disablePlugins) {
 41610 return;
 41611 }
 41612 
 41613 $repo = $this->composer->getRepositoryManager()->getLocalRepository();
 41614 $globalRepo = $this->globalComposer ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
 41615 $this->deactivateRepository($repo, false);
 41616 if ($globalRepo) {
 41617 $this->deactivateRepository($globalRepo, true);
 41618 }
 41619 }
 41620 
 41621 
 41622 
 41623 
 41624 
 41625 
 41626 public function getPlugins()
 41627 {
 41628 return $this->plugins;
 41629 }
 41630 
 41631 
 41632 
 41633 
 41634 
 41635 
 41636 public function getGlobalComposer()
 41637 {
 41638 return $this->globalComposer;
 41639 }
 41640 
 41641 
 41642 
 41643 
 41644 
 41645 
 41646 
 41647 
 41648 
 41649 
 41650 
 41651 
 41652 
 41653 
 41654 
 41655 public function registerPackage(PackageInterface $package, $failOnMissingClasses = false, $isGlobalPlugin = false)
 41656 {
 41657 if ($this->disablePlugins) {
 41658 return;
 41659 }
 41660 
 41661 if (!$this->isPluginAllowed($package->getName(), $isGlobalPlugin)) {
 41662 $this->io->writeError('Skipped loading "'.$package->getName() . '" '.($isGlobalPlugin ? '(installed globally) ' : '').'as it is not in config.allow-plugins', true, IOInterface::DEBUG);
 41663 return;
 41664 }
 41665 
 41666 if ($package->getType() === 'composer-plugin') {
 41667 $requiresComposer = null;
 41668 foreach ($package->getRequires() as $link) { 
 41669 if ('composer-plugin-api' === $link->getTarget()) {
 41670 $requiresComposer = $link->getConstraint();
 41671 break;
 41672 }
 41673 }
 41674 
 41675 if (!$requiresComposer) {
 41676 throw new \RuntimeException("Plugin ".$package->getName()." is missing a require statement for a version of the composer-plugin-api package.");
 41677 }
 41678 
 41679 $currentPluginApiVersion = $this->getPluginApiVersion();
 41680 $currentPluginApiConstraint = new Constraint('==', $this->versionParser->normalize($currentPluginApiVersion));
 41681 
 41682 if ($requiresComposer->getPrettyString() === $this->getPluginApiVersion()) {
 41683 $this->io->writeError('<warning>The "' . $package->getName() . '" plugin requires composer-plugin-api '.$this->getPluginApiVersion().', this *WILL* break in the future and it should be fixed ASAP (require ^'.$this->getPluginApiVersion().' instead for example).</warning>');
 41684 } elseif (!$requiresComposer->matches($currentPluginApiConstraint)) {
 41685 $this->io->writeError('<warning>The "' . $package->getName() . '" plugin '.($isGlobalPlugin ? '(installed globally) ' : '').'was skipped because it requires a Plugin API version ("' . $requiresComposer->getPrettyString() . '") that does not match your Composer installation ("' . $currentPluginApiVersion . '"). You may need to run composer update with the "--no-plugins" option.</warning>');
 41686 
 41687 return;
 41688 }
 41689 
 41690 if ($package->getName() === 'symfony/flex' && Preg::isMatch('{^[0-9.]+$}', $package->getVersion()) && version_compare($package->getVersion(), '1.9.8', '<')) {
 41691 $this->io->writeError('<warning>The "' . $package->getName() . '" plugin '.($isGlobalPlugin ? '(installed globally) ' : '').'was skipped because it is not compatible with Composer 2+. Make sure to update it to version 1.9.8 or greater.</warning>');
 41692 
 41693 return;
 41694 }
 41695 }
 41696 
 41697 $oldInstallerPlugin = ($package->getType() === 'composer-installer');
 41698 
 41699 if (isset($this->registeredPlugins[$package->getName()])) {
 41700 return;
 41701 }
 41702 
 41703 $extra = $package->getExtra();
 41704 if (empty($extra['class'])) {
 41705 throw new \UnexpectedValueException('Error while installing '.$package->getPrettyName().', composer-plugin packages should have a class defined in their extra key to be usable.');
 41706 }
 41707 $classes = is_array($extra['class']) ? $extra['class'] : array($extra['class']);
 41708 
 41709 $localRepo = $this->composer->getRepositoryManager()->getLocalRepository();
 41710 $globalRepo = $this->globalComposer !== null ? $this->globalComposer->getRepositoryManager()->getLocalRepository() : null;
 41711 
 41712 $rootPackage = clone $this->composer->getPackage();
 41713 
 41714 
 41715 
 41716 $rootPackageAutoloads = $rootPackage->getAutoload();
 41717 $rootPackageAutoloads['files'] = array();
 41718 $rootPackage->setAutoload($rootPackageAutoloads);
 41719 $rootPackageAutoloads = $rootPackage->getDevAutoload();
 41720 $rootPackageAutoloads['files'] = array();
 41721 $rootPackage->setDevAutoload($rootPackageAutoloads);
 41722 unset($rootPackageAutoloads);
 41723 
 41724 $rootPackageRepo = new RootPackageRepository($rootPackage);
 41725 $installedRepo = new InstalledRepository(array($localRepo, $rootPackageRepo));
 41726 if ($globalRepo) {
 41727 $installedRepo->addRepository($globalRepo);
 41728 }
 41729 
 41730 $autoloadPackages = array($package->getName() => $package);
 41731 $autoloadPackages = $this->collectDependencies($installedRepo, $autoloadPackages, $package);
 41732 
 41733 $generator = $this->composer->getAutoloadGenerator();
 41734 $autoloads = array(array($rootPackage, ''));
 41735 foreach ($autoloadPackages as $autoloadPackage) {
 41736 if ($autoloadPackage === $rootPackage) {
 41737 continue;
 41738 }
 41739 
 41740 $downloadPath = $this->getInstallPath($autoloadPackage, $globalRepo && $globalRepo->hasPackage($autoloadPackage));
 41741 $autoloads[] = array($autoloadPackage, $downloadPath);
 41742 }
 41743 
 41744 $map = $generator->parseAutoloads($autoloads, $rootPackage);
 41745 $classLoader = $generator->createLoader($map, $this->composer->getConfig()->get('vendor-dir'));
 41746 $classLoader->register(false);
 41747 
 41748 foreach ($map['files'] as $fileIdentifier => $file) {
 41749 
 41750 
 41751 
 41752 if ($fileIdentifier === '7e9bd612cc444b3eed788ebbe46263a0') {
 41753 continue;
 41754 }
 41755 \Composer\Autoload\composerRequire($fileIdentifier, $file);
 41756 }
 41757 
 41758 foreach ($classes as $class) {
 41759 if (class_exists($class, false)) {
 41760 $class = trim($class, '\\');
 41761 $path = $classLoader->findFile($class);
 41762 $code = file_get_contents($path);
 41763 $separatorPos = strrpos($class, '\\');
 41764 $className = $class;
 41765 if ($separatorPos) {
 41766 $className = substr($class, $separatorPos + 1);
 41767 }
 41768 $code = Preg::replace('{^((?:final\s+)?(?:\s*))class\s+('.preg_quote($className).')}mi', '$1class $2_composer_tmp'.self::$classCounter, $code, 1);
 41769 $code = strtr($code, array(
 41770 '__FILE__' => var_export($path, true),
 41771 '__DIR__' => var_export(dirname($path), true),
 41772 '__CLASS__' => var_export($class, true),
 41773 ));
 41774 $code = Preg::replace('/^\s*<\?(php)?/i', '', $code, 1);
 41775 eval($code);
 41776 $class .= '_composer_tmp'.self::$classCounter;
 41777 self::$classCounter++;
 41778 }
 41779 
 41780 if ($oldInstallerPlugin) {
 41781 if (!is_a($class, 'Composer\Installer\InstallerInterface', true)) {
 41782 throw new \RuntimeException('Could not activate plugin "'.$package->getName().'" as "'.$class.'" does not implement Composer\Installer\InstallerInterface');
 41783 }
 41784 $this->io->writeError('<warning>Loading "'.$package->getName() . '" '.($isGlobalPlugin ? '(installed globally) ' : '').'which is a legacy composer-installer built for Composer 1.x, it is likely to cause issues as you are running Composer 2.x.</warning>');
 41785 $installer = new $class($this->io, $this->composer);
 41786 $this->composer->getInstallationManager()->addInstaller($installer);
 41787 $this->registeredPlugins[$package->getName()] = $installer;
 41788 } elseif (class_exists($class)) {
 41789 if (!is_a($class, 'Composer\Plugin\PluginInterface', true)) {
 41790 throw new \RuntimeException('Could not activate plugin "'.$package->getName().'" as "'.$class.'" does not implement Composer\Plugin\PluginInterface');
 41791 }
 41792 $plugin = new $class();
 41793 $this->addPlugin($plugin, $isGlobalPlugin, $package);
 41794 $this->registeredPlugins[$package->getName()] = $plugin;
 41795 } elseif ($failOnMissingClasses) {
 41796 throw new \UnexpectedValueException('Plugin '.$package->getName().' could not be initialized, class not found: '.$class);
 41797 }
 41798 }
 41799 }
 41800 
 41801 
 41802 
 41803 
 41804 
 41805 
 41806 
 41807 
 41808 
 41809 
 41810 
 41811 
 41812 
 41813 public function deactivatePackage(PackageInterface $package)
 41814 {
 41815 if ($this->disablePlugins) {
 41816 return;
 41817 }
 41818 
 41819 if (!isset($this->registeredPlugins[$package->getName()])) {
 41820 return;
 41821 }
 41822 
 41823 $plugin = $this->registeredPlugins[$package->getName()];
 41824 unset($this->registeredPlugins[$package->getName()]);
 41825 if ($plugin instanceof InstallerInterface) {
 41826 $this->composer->getInstallationManager()->removeInstaller($plugin);
 41827 } else {
 41828 $this->removePlugin($plugin);
 41829 }
 41830 }
 41831 
 41832 
 41833 
 41834 
 41835 
 41836 
 41837 
 41838 
 41839 
 41840 
 41841 
 41842 
 41843 
 41844 public function uninstallPackage(PackageInterface $package)
 41845 {
 41846 if ($this->disablePlugins) {
 41847 return;
 41848 }
 41849 
 41850 if (!isset($this->registeredPlugins[$package->getName()])) {
 41851 return;
 41852 }
 41853 
 41854 $plugin = $this->registeredPlugins[$package->getName()];
 41855 if ($plugin instanceof InstallerInterface) {
 41856 $this->deactivatePackage($package);
 41857 } else {
 41858 unset($this->registeredPlugins[$package->getName()]);
 41859 $this->removePlugin($plugin);
 41860 $this->uninstallPlugin($plugin);
 41861 }
 41862 }
 41863 
 41864 
 41865 
 41866 
 41867 
 41868 
 41869 protected function getPluginApiVersion()
 41870 {
 41871 return PluginInterface::PLUGIN_API_VERSION;
 41872 }
 41873 
 41874 
 41875 
 41876 
 41877 
 41878 
 41879 
 41880 
 41881 
 41882 
 41883 
 41884 
 41885 
 41886 
 41887 public function addPlugin(PluginInterface $plugin, $isGlobalPlugin = false, PackageInterface $sourcePackage = null)
 41888 {
 41889 if ($sourcePackage === null) {
 41890 trigger_error('Calling PluginManager::addPlugin without $sourcePackage is deprecated, if you are using this please get in touch with us to explain the use case', E_USER_DEPRECATED);
 41891 } elseif (!$this->isPluginAllowed($sourcePackage->getName(), $isGlobalPlugin)) {
 41892 $this->io->writeError('Skipped loading "'.get_class($plugin).' from '.$sourcePackage->getName() . '" '.($isGlobalPlugin ? '(installed globally) ' : '').' as it is not in config.allow-plugins', true, IOInterface::DEBUG);
 41893 return;
 41894 }
 41895 
 41896 $details = array();
 41897 if ($sourcePackage) {
 41898 $details[] = 'from '.$sourcePackage->getName();
 41899 }
 41900 if ($isGlobalPlugin) {
 41901 $details[] = 'installed globally';
 41902 }
 41903 $this->io->writeError('Loading plugin '.get_class($plugin).($details ? ' ('.implode(', ', $details).')' : ''), true, IOInterface::DEBUG);
 41904 $this->plugins[] = $plugin;
 41905 $plugin->activate($this->composer, $this->io);
 41906 
 41907 if ($plugin instanceof EventSubscriberInterface) {
 41908 $this->composer->getEventDispatcher()->addSubscriber($plugin);
 41909 }
 41910 }
 41911 
 41912 
 41913 
 41914 
 41915 
 41916 
 41917 
 41918 
 41919 
 41920 
 41921 
 41922 
 41923 public function removePlugin(PluginInterface $plugin)
 41924 {
 41925 $index = array_search($plugin, $this->plugins, true);
 41926 if ($index === false) {
 41927 return;
 41928 }
 41929 
 41930 $this->io->writeError('Unloading plugin '.get_class($plugin), true, IOInterface::DEBUG);
 41931 unset($this->plugins[$index]);
 41932 $plugin->deactivate($this->composer, $this->io);
 41933 
 41934 $this->composer->getEventDispatcher()->removeListener($plugin);
 41935 }
 41936 
 41937 
 41938 
 41939 
 41940 
 41941 
 41942 
 41943 
 41944 
 41945 
 41946 
 41947 
 41948 public function uninstallPlugin(PluginInterface $plugin)
 41949 {
 41950 $this->io->writeError('Uninstalling plugin '.get_class($plugin), true, IOInterface::DEBUG);
 41951 $plugin->uninstall($this->composer, $this->io);
 41952 }
 41953 
 41954 
 41955 
 41956 
 41957 
 41958 
 41959 
 41960 
 41961 
 41962 
 41963 
 41964 
 41965 
 41966 
 41967 
 41968 
 41969 
 41970 private function loadRepository(RepositoryInterface $repo, $isGlobalRepo)
 41971 {
 41972 $packages = $repo->getPackages();
 41973 
 41974 $weights = array();
 41975 foreach ($packages as $package) {
 41976 if ($package->getType() === 'composer-plugin') {
 41977 $extra = $package->getExtra();
 41978 if ($package->getName() === 'composer/installers' || (isset($extra['plugin-modifies-install-path']) && $extra['plugin-modifies-install-path'] === true)) {
 41979 $weights[$package->getName()] = -10000;
 41980 }
 41981 }
 41982 }
 41983 
 41984 $sortedPackages = PackageSorter::sortPackages($packages, $weights);
 41985 foreach ($sortedPackages as $package) {
 41986 if (!($package instanceof CompletePackage)) {
 41987 continue;
 41988 }
 41989 if ('composer-plugin' === $package->getType()) {
 41990 $this->registerPackage($package, false, $isGlobalRepo);
 41991 
 41992 } elseif ('composer-installer' === $package->getType()) {
 41993 $this->registerPackage($package, false, $isGlobalRepo);
 41994 }
 41995 }
 41996 }
 41997 
 41998 
 41999 
 42000 
 42001 
 42002 
 42003 
 42004 
 42005 
 42006 
 42007 
 42008 private function deactivateRepository(RepositoryInterface $repo, $isGlobalRepo)
 42009 {
 42010 $packages = $repo->getPackages();
 42011 $sortedPackages = array_reverse(PackageSorter::sortPackages($packages));
 42012 
 42013 foreach ($sortedPackages as $package) {
 42014 if (!($package instanceof CompletePackage)) {
 42015 continue;
 42016 }
 42017 if ('composer-plugin' === $package->getType()) {
 42018 $this->deactivatePackage($package);
 42019 
 42020 } elseif ('composer-installer' === $package->getType()) {
 42021 $this->deactivatePackage($package);
 42022 }
 42023 }
 42024 }
 42025 
 42026 
 42027 
 42028 
 42029 
 42030 
 42031 
 42032 
 42033 
 42034 
 42035 private function collectDependencies(InstalledRepository $installedRepo, array $collected, PackageInterface $package)
 42036 {
 42037 foreach ($package->getRequires() as $requireLink) {
 42038 foreach ($installedRepo->findPackagesWithReplacersAndProviders($requireLink->getTarget()) as $requiredPackage) {
 42039 if (!isset($collected[$requiredPackage->getName()])) {
 42040 $collected[$requiredPackage->getName()] = $requiredPackage;
 42041 $collected = $this->collectDependencies($installedRepo, $collected, $requiredPackage);
 42042 }
 42043 }
 42044 }
 42045 
 42046 return $collected;
 42047 }
 42048 
 42049 
 42050 
 42051 
 42052 
 42053 
 42054 
 42055 
 42056 
 42057 private function getInstallPath(PackageInterface $package, $global = false)
 42058 {
 42059 if (!$global) {
 42060 return $this->composer->getInstallationManager()->getInstallPath($package);
 42061 }
 42062 
 42063 return $this->globalComposer->getInstallationManager()->getInstallPath($package);
 42064 }
 42065 
 42066 
 42067 
 42068 
 42069 
 42070 
 42071 
 42072 protected function getCapabilityImplementationClassName(PluginInterface $plugin, $capability)
 42073 {
 42074 if (!($plugin instanceof Capable)) {
 42075 return null;
 42076 }
 42077 
 42078 $capabilities = (array) $plugin->getCapabilities();
 42079 
 42080 if (!empty($capabilities[$capability]) && is_string($capabilities[$capability]) && trim($capabilities[$capability])) {
 42081 return trim($capabilities[$capability]);
 42082 }
 42083 
 42084 if (
 42085 array_key_exists($capability, $capabilities)
 42086 && (empty($capabilities[$capability]) || !is_string($capabilities[$capability]) || !trim($capabilities[$capability]))
 42087 ) {
 42088 throw new \UnexpectedValueException('Plugin '.get_class($plugin).' provided invalid capability class name(s), got '.var_export($capabilities[$capability], true));
 42089 }
 42090 
 42091 return null;
 42092 }
 42093 
 42094 
 42095 
 42096 
 42097 
 42098 
 42099 
 42100 
 42101 
 42102 
 42103 
 42104 
 42105 public function getPluginCapability(PluginInterface $plugin, $capabilityClassName, array $ctorArgs = array())
 42106 {
 42107 if ($capabilityClass = $this->getCapabilityImplementationClassName($plugin, $capabilityClassName)) {
 42108 if (!class_exists($capabilityClass)) {
 42109 throw new \RuntimeException("Cannot instantiate Capability, as class $capabilityClass from plugin ".get_class($plugin)." does not exist.");
 42110 }
 42111 
 42112 $ctorArgs['plugin'] = $plugin;
 42113 $capabilityObj = new $capabilityClass($ctorArgs);
 42114 
 42115 
 42116 if (!$capabilityObj instanceof Capability || !$capabilityObj instanceof $capabilityClassName) {
 42117 throw new \RuntimeException(
 42118 'Class ' . $capabilityClass . ' must implement both Composer\Plugin\Capability\Capability and '. $capabilityClassName . '.'
 42119 );
 42120 }
 42121 
 42122 return $capabilityObj;
 42123 }
 42124 
 42125 return null;
 42126 }
 42127 
 42128 
 42129 
 42130 
 42131 
 42132 
 42133 
 42134 
 42135 
 42136 public function getPluginCapabilities($capabilityClassName, array $ctorArgs = array())
 42137 {
 42138 $capabilities = array();
 42139 foreach ($this->getPlugins() as $plugin) {
 42140 if ($capability = $this->getPluginCapability($plugin, $capabilityClassName, $ctorArgs)) {
 42141 $capabilities[] = $capability;
 42142 }
 42143 }
 42144 
 42145 return $capabilities;
 42146 }
 42147 
 42148 
 42149 
 42150 
 42151 
 42152 private function parseAllowedPlugins($allowPluginsConfig)
 42153 {
 42154 if (null === $allowPluginsConfig) {
 42155 return null;
 42156 }
 42157 
 42158 if (true === $allowPluginsConfig) {
 42159 return array('{}' => true);
 42160 }
 42161 
 42162 if (false === $allowPluginsConfig) {
 42163 return array('{}' => false);
 42164 }
 42165 
 42166 $rules = array();
 42167 foreach ($allowPluginsConfig as $pattern => $allow) {
 42168 $rules[BasePackage::packageNameToRegexp($pattern)] = $allow;
 42169 }
 42170 
 42171 return $rules;
 42172 }
 42173 
 42174 
 42175 
 42176 
 42177 
 42178 
 42179 private function isPluginAllowed($package, $isGlobalPlugin)
 42180 {
 42181 static $warned = array();
 42182 $rules = $isGlobalPlugin ? $this->allowGlobalPluginRules : $this->allowPluginRules;
 42183 
 42184 if ($rules === null) {
 42185 if (!$this->io->isInteractive()) {
 42186 if (!isset($warned['all'])) {
 42187 $this->io->writeError('<warning>For additional security you should declare the allow-plugins config with a list of packages names that are allowed to run code. See https://getcomposer.org/allow-plugins</warning>');
 42188 $this->io->writeError('<warning>You have until July 2022 to add the setting. Composer will then switch the default behavior to disallow all plugins.</warning>');
 42189 $warned['all'] = true;
 42190 }
 42191 
 42192 
 42193 return true;
 42194 }
 42195 
 42196 
 42197 $rules = array();
 42198 }
 42199 
 42200 foreach ($rules as $pattern => $allow) {
 42201 if (Preg::isMatch($pattern, $package)) {
 42202 return $allow === true;
 42203 }
 42204 }
 42205 
 42206 if ($package === 'composer/package-versions-deprecated') {
 42207 return false;
 42208 }
 42209 
 42210 if (!isset($warned[$package])) {
 42211 if ($this->io->isInteractive()) {
 42212 $composer = $isGlobalPlugin && $this->globalComposer !== null ? $this->globalComposer : $this->composer;
 42213 
 42214 $this->io->writeError('<warning>'.$package.($isGlobalPlugin ? ' (installed globally)' : '').' contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins</warning>');
 42215 while (true) {
 42216 switch ($answer = $this->io->ask('Do you trust "<info>'.$package.'</info>" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [<comment>y,n,d,?</comment>] ', '?')) {
 42217 case 'y':
 42218 case 'n':
 42219 case 'd':
 42220 $allow = $answer === 'y';
 42221 
 42222 
 42223 if ($isGlobalPlugin) {
 42224 $this->allowGlobalPluginRules[BasePackage::packageNameToRegexp($package)] = $allow;
 42225 } else {
 42226 $this->allowPluginRules[BasePackage::packageNameToRegexp($package)] = $allow;
 42227 }
 42228 
 42229 
 42230 if ($answer === 'y' || $answer === 'n') {
 42231 $composer->getConfig()->getConfigSource()->addConfigSetting('allow-plugins.'.$package, $allow);
 42232 }
 42233 
 42234 return $allow;
 42235 
 42236 case '?':
 42237 default:
 42238 $this->io->writeError(array(
 42239 'y - add package to allow-plugins in composer.json and let it run immediately',
 42240 'n - add package (as disallowed) to allow-plugins in composer.json to suppress further prompts',
 42241 'd - discard this, do not change composer.json and do not allow the plugin to run',
 42242 '? - print help'
 42243 ));
 42244 break;
 42245 }
 42246 }
 42247 } else {
 42248 $this->io->writeError('<warning>'.$package.($isGlobalPlugin ? ' (installed globally)' : '').' contains a Composer plugin which is blocked by your allow-plugins config. You may add it to the list if you consider it safe. See https://getcomposer.org/allow-plugins</warning>');
 42249 $this->io->writeError('<warning>You can run "composer '.($isGlobalPlugin ? 'global ' : '').'config --no-plugins allow-plugins.'.$package.' [true|false]" to enable it (true) or keep it disabled and suppress this warning (false)</warning>');
 42250 }
 42251 $warned[$package] = true;
 42252 }
 42253 
 42254 return false;
 42255 }
 42256 }
 42257 <?php
 42258 
 42259 
 42260 
 42261 
 42262 
 42263 
 42264 
 42265 
 42266 
 42267 
 42268 
 42269 namespace Composer\Plugin;
 42270 
 42271 use Composer\EventDispatcher\Event;
 42272 use Composer\Package\PackageInterface;
 42273 
 42274 
 42275 
 42276 
 42277 
 42278 
 42279 class PostFileDownloadEvent extends Event
 42280 {
 42281 
 42282 
 42283 
 42284 private $fileName;
 42285 
 42286 
 42287 
 42288 
 42289 private $checksum;
 42290 
 42291 
 42292 
 42293 
 42294 private $url;
 42295 
 42296 
 42297 
 42298 
 42299 private $context;
 42300 
 42301 
 42302 
 42303 
 42304 private $type;
 42305 
 42306 
 42307 
 42308 
 42309 
 42310 
 42311 
 42312 
 42313 
 42314 
 42315 
 42316 public function __construct($name, $fileName, $checksum, $url, $type, $context = null)
 42317 {
 42318 
 42319 if ($context === null && $type instanceof PackageInterface) {
 42320 $context = $type;
 42321 $type = 'package';
 42322 trigger_error('PostFileDownloadEvent::__construct should receive a $type=package and the package object in $context since Composer 2.1.', E_USER_DEPRECATED);
 42323 }
 42324 
 42325 parent::__construct($name);
 42326 $this->fileName = $fileName;
 42327 $this->checksum = $checksum;
 42328 $this->url = $url;
 42329 $this->context = $context;
 42330 $this->type = $type;
 42331 }
 42332 
 42333 
 42334 
 42335 
 42336 
 42337 
 42338 
 42339 
 42340 public function getFileName()
 42341 {
 42342 return $this->fileName;
 42343 }
 42344 
 42345 
 42346 
 42347 
 42348 
 42349 
 42350 public function getChecksum()
 42351 {
 42352 return $this->checksum;
 42353 }
 42354 
 42355 
 42356 
 42357 
 42358 
 42359 
 42360 public function getUrl()
 42361 {
 42362 return $this->url;
 42363 }
 42364 
 42365 
 42366 
 42367 
 42368 
 42369 
 42370 
 42371 
 42372 
 42373 public function getContext()
 42374 {
 42375 return $this->context;
 42376 }
 42377 
 42378 
 42379 
 42380 
 42381 
 42382 
 42383 
 42384 
 42385 
 42386 public function getPackage()
 42387 {
 42388 trigger_error('PostFileDownloadEvent::getPackage is deprecated since Composer 2.1, use getContext instead.', E_USER_DEPRECATED);
 42389 $context = $this->getContext();
 42390 
 42391 return $context instanceof PackageInterface ? $context : null;
 42392 }
 42393 
 42394 
 42395 
 42396 
 42397 
 42398 
 42399 public function getType()
 42400 {
 42401 return $this->type;
 42402 }
 42403 }
 42404 <?php
 42405 
 42406 
 42407 
 42408 
 42409 
 42410 
 42411 
 42412 
 42413 
 42414 
 42415 
 42416 namespace Composer\Plugin;
 42417 
 42418 use Composer\EventDispatcher\Event;
 42419 use Symfony\Component\Console\Input\InputInterface;
 42420 
 42421 
 42422 
 42423 
 42424 
 42425 
 42426 class PreCommandRunEvent extends Event
 42427 {
 42428 
 42429 
 42430 
 42431 private $input;
 42432 
 42433 
 42434 
 42435 
 42436 private $command;
 42437 
 42438 
 42439 
 42440 
 42441 
 42442 
 42443 
 42444 
 42445 public function __construct($name, InputInterface $input, $command)
 42446 {
 42447 parent::__construct($name);
 42448 $this->input = $input;
 42449 $this->command = $command;
 42450 }
 42451 
 42452 
 42453 
 42454 
 42455 
 42456 
 42457 public function getInput()
 42458 {
 42459 return $this->input;
 42460 }
 42461 
 42462 
 42463 
 42464 
 42465 
 42466 
 42467 public function getCommand()
 42468 {
 42469 return $this->command;
 42470 }
 42471 }
 42472 <?php
 42473 
 42474 
 42475 
 42476 
 42477 
 42478 
 42479 
 42480 
 42481 
 42482 
 42483 
 42484 namespace Composer\Plugin;
 42485 
 42486 use Composer\EventDispatcher\Event;
 42487 use Composer\Util\HttpDownloader;
 42488 
 42489 
 42490 
 42491 
 42492 
 42493 
 42494 class PreFileDownloadEvent extends Event
 42495 {
 42496 
 42497 
 42498 
 42499 private $httpDownloader;
 42500 
 42501 
 42502 
 42503 
 42504 private $processedUrl;
 42505 
 42506 
 42507 
 42508 
 42509 private $customCacheKey;
 42510 
 42511 
 42512 
 42513 
 42514 private $type;
 42515 
 42516 
 42517 
 42518 
 42519 private $context;
 42520 
 42521 
 42522 
 42523 
 42524 private $transportOptions = array();
 42525 
 42526 
 42527 
 42528 
 42529 
 42530 
 42531 
 42532 
 42533 
 42534 
 42535 public function __construct($name, HttpDownloader $httpDownloader, $processedUrl, $type, $context = null)
 42536 {
 42537 parent::__construct($name);
 42538 $this->httpDownloader = $httpDownloader;
 42539 $this->processedUrl = $processedUrl;
 42540 $this->type = $type;
 42541 $this->context = $context;
 42542 }
 42543 
 42544 
 42545 
 42546 
 42547 public function getHttpDownloader()
 42548 {
 42549 return $this->httpDownloader;
 42550 }
 42551 
 42552 
 42553 
 42554 
 42555 
 42556 
 42557 public function getProcessedUrl()
 42558 {
 42559 return $this->processedUrl;
 42560 }
 42561 
 42562 
 42563 
 42564 
 42565 
 42566 
 42567 
 42568 
 42569 public function setProcessedUrl($processedUrl)
 42570 {
 42571 $this->processedUrl = $processedUrl;
 42572 }
 42573 
 42574 
 42575 
 42576 
 42577 
 42578 
 42579 public function getCustomCacheKey()
 42580 {
 42581 return $this->customCacheKey;
 42582 }
 42583 
 42584 
 42585 
 42586 
 42587 
 42588 
 42589 
 42590 
 42591 public function setCustomCacheKey($customCacheKey)
 42592 {
 42593 $this->customCacheKey = $customCacheKey;
 42594 }
 42595 
 42596 
 42597 
 42598 
 42599 
 42600 
 42601 public function getType()
 42602 {
 42603 return $this->type;
 42604 }
 42605 
 42606 
 42607 
 42608 
 42609 
 42610 
 42611 
 42612 
 42613 
 42614 public function getContext()
 42615 {
 42616 return $this->context;
 42617 }
 42618 
 42619 
 42620 
 42621 
 42622 
 42623 
 42624 
 42625 
 42626 public function getTransportOptions()
 42627 {
 42628 return $this->transportOptions;
 42629 }
 42630 
 42631 
 42632 
 42633 
 42634 
 42635 
 42636 
 42637 
 42638 
 42639 
 42640 public function setTransportOptions(array $options)
 42641 {
 42642 $this->transportOptions = $options;
 42643 }
 42644 }
 42645 <?php
 42646 
 42647 
 42648 
 42649 
 42650 
 42651 
 42652 
 42653 
 42654 
 42655 
 42656 
 42657 namespace Composer\Plugin;
 42658 
 42659 use Composer\EventDispatcher\Event;
 42660 use Composer\Repository\RepositoryInterface;
 42661 use Composer\DependencyResolver\Request;
 42662 use Composer\Package\BasePackage;
 42663 
 42664 
 42665 
 42666 
 42667 
 42668 
 42669 class PrePoolCreateEvent extends Event
 42670 {
 42671 
 42672 
 42673 
 42674 private $repositories;
 42675 
 42676 
 42677 
 42678 private $request;
 42679 
 42680 
 42681 
 42682 
 42683 private $acceptableStabilities;
 42684 
 42685 
 42686 
 42687 
 42688 private $stabilityFlags;
 42689 
 42690 
 42691 
 42692 
 42693 private $rootAliases;
 42694 
 42695 
 42696 
 42697 
 42698 private $rootReferences;
 42699 
 42700 
 42701 
 42702 private $packages;
 42703 
 42704 
 42705 
 42706 private $unacceptableFixedPackages;
 42707 
 42708 
 42709 
 42710 
 42711 
 42712 
 42713 
 42714 
 42715 
 42716 
 42717 
 42718 
 42719 
 42720 
 42721 
 42722 
 42723 public function __construct($name, array $repositories, Request $request, array $acceptableStabilities, array $stabilityFlags, array $rootAliases, array $rootReferences, array $packages, array $unacceptableFixedPackages)
 42724 {
 42725 parent::__construct($name);
 42726 
 42727 $this->repositories = $repositories;
 42728 $this->request = $request;
 42729 $this->acceptableStabilities = $acceptableStabilities;
 42730 $this->stabilityFlags = $stabilityFlags;
 42731 $this->rootAliases = $rootAliases;
 42732 $this->rootReferences = $rootReferences;
 42733 $this->packages = $packages;
 42734 $this->unacceptableFixedPackages = $unacceptableFixedPackages;
 42735 }
 42736 
 42737 
 42738 
 42739 
 42740 public function getRepositories()
 42741 {
 42742 return $this->repositories;
 42743 }
 42744 
 42745 
 42746 
 42747 
 42748 public function getRequest()
 42749 {
 42750 return $this->request;
 42751 }
 42752 
 42753 
 42754 
 42755 
 42756 
 42757 public function getAcceptableStabilities()
 42758 {
 42759 return $this->acceptableStabilities;
 42760 }
 42761 
 42762 
 42763 
 42764 
 42765 
 42766 public function getStabilityFlags()
 42767 {
 42768 return $this->stabilityFlags;
 42769 }
 42770 
 42771 
 42772 
 42773 
 42774 
 42775 public function getRootAliases()
 42776 {
 42777 return $this->rootAliases;
 42778 }
 42779 
 42780 
 42781 
 42782 
 42783 
 42784 public function getRootReferences()
 42785 {
 42786 return $this->rootReferences;
 42787 }
 42788 
 42789 
 42790 
 42791 
 42792 public function getPackages()
 42793 {
 42794 return $this->packages;
 42795 }
 42796 
 42797 
 42798 
 42799 
 42800 public function getUnacceptableFixedPackages()
 42801 {
 42802 return $this->unacceptableFixedPackages;
 42803 }
 42804 
 42805 
 42806 
 42807 
 42808 
 42809 
 42810 public function setPackages(array $packages)
 42811 {
 42812 $this->packages = $packages;
 42813 }
 42814 
 42815 
 42816 
 42817 
 42818 
 42819 
 42820 public function setUnacceptableFixedPackages(array $packages)
 42821 {
 42822 $this->unacceptableFixedPackages = $packages;
 42823 }
 42824 }
 42825 <?php
 42826 
 42827 
 42828 
 42829 
 42830 
 42831 
 42832 
 42833 
 42834 
 42835 
 42836 
 42837 namespace Composer\Question;
 42838 
 42839 use Composer\Pcre\Preg;
 42840 use Symfony\Component\Console\Exception\InvalidArgumentException;
 42841 use Symfony\Component\Console\Question\Question;
 42842 
 42843 
 42844 
 42845 
 42846 
 42847 
 42848 
 42849 
 42850 class StrictConfirmationQuestion extends Question
 42851 {
 42852 
 42853 private $trueAnswerRegex;
 42854 
 42855 private $falseAnswerRegex;
 42856 
 42857 
 42858 
 42859 
 42860 
 42861 
 42862 
 42863 
 42864 
 42865 public function __construct($question, $default = true, $trueAnswerRegex = '/^y(?:es)?$/i', $falseAnswerRegex = '/^no?$/i')
 42866 {
 42867 parent::__construct($question, (bool) $default);
 42868 
 42869 $this->trueAnswerRegex = $trueAnswerRegex;
 42870 $this->falseAnswerRegex = $falseAnswerRegex;
 42871 $this->setNormalizer($this->getDefaultNormalizer());
 42872 $this->setValidator($this->getDefaultValidator());
 42873 }
 42874 
 42875 
 42876 
 42877 
 42878 
 42879 
 42880 private function getDefaultNormalizer()
 42881 {
 42882 $default = $this->getDefault();
 42883 $trueRegex = $this->trueAnswerRegex;
 42884 $falseRegex = $this->falseAnswerRegex;
 42885 
 42886 return function ($answer) use ($default, $trueRegex, $falseRegex) {
 42887 if (is_bool($answer)) {
 42888 return $answer;
 42889 }
 42890 if (empty($answer) && !empty($default)) {
 42891 return $default;
 42892 }
 42893 
 42894 if (Preg::isMatch($trueRegex, $answer)) {
 42895 return true;
 42896 }
 42897 
 42898 if (Preg::isMatch($falseRegex, $answer)) {
 42899 return false;
 42900 }
 42901 
 42902 return null;
 42903 };
 42904 }
 42905 
 42906 
 42907 
 42908 
 42909 
 42910 
 42911 private function getDefaultValidator()
 42912 {
 42913 return function ($answer) {
 42914 if (!is_bool($answer)) {
 42915 throw new InvalidArgumentException('Please answer yes, y, no, or n.');
 42916 }
 42917 
 42918 return $answer;
 42919 };
 42920 }
 42921 }
 42922 <?php
 42923 
 42924 
 42925 
 42926 
 42927 
 42928 
 42929 
 42930 
 42931 
 42932 
 42933 
 42934 namespace Composer\Repository;
 42935 
 42936 use Composer\Package\AliasPackage;
 42937 use Composer\Package\BasePackage;
 42938 use Composer\Package\CompleteAliasPackage;
 42939 use Composer\Package\CompletePackage;
 42940 use Composer\Package\PackageInterface;
 42941 use Composer\Package\CompletePackageInterface;
 42942 use Composer\Package\Version\VersionParser;
 42943 use Composer\Package\Version\StabilityFilter;
 42944 use Composer\Pcre\Preg;
 42945 use Composer\Semver\Constraint\ConstraintInterface;
 42946 use Composer\Semver\Constraint\Constraint;
 42947 
 42948 
 42949 
 42950 
 42951 
 42952 
 42953 class ArrayRepository implements RepositoryInterface
 42954 {
 42955 
 42956 protected $packages = null;
 42957 
 42958 
 42959 
 42960 
 42961 protected $packageMap = null;
 42962 
 42963 
 42964 
 42965 
 42966 public function __construct(array $packages = array())
 42967 {
 42968 foreach ($packages as $package) {
 42969 $this->addPackage($package);
 42970 }
 42971 }
 42972 
 42973 public function getRepoName()
 42974 {
 42975 return 'array repo (defining '.$this->count().' package'.($this->count() > 1 ? 's' : '').')';
 42976 }
 42977 
 42978 
 42979 
 42980 
 42981 public function loadPackages(array $packageMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array())
 42982 {
 42983 $packages = $this->getPackages();
 42984 
 42985 $result = array();
 42986 $namesFound = array();
 42987 foreach ($packages as $package) {
 42988 if (array_key_exists($package->getName(), $packageMap)) {
 42989 if (
 42990 (!$packageMap[$package->getName()] || $packageMap[$package->getName()]->matches(new Constraint('==', $package->getVersion())))
 42991 && StabilityFilter::isPackageAcceptable($acceptableStabilities, $stabilityFlags, $package->getNames(), $package->getStability())
 42992 && !isset($alreadyLoaded[$package->getName()][$package->getVersion()])
 42993 ) {
 42994 
 42995 $result[spl_object_hash($package)] = $package;
 42996 
 42997 if ($package instanceof AliasPackage && !isset($result[spl_object_hash($package->getAliasOf())])) {
 42998 $result[spl_object_hash($package->getAliasOf())] = $package->getAliasOf();
 42999 }
 43000 }
 43001 
 43002 $namesFound[$package->getName()] = true;
 43003 }
 43004 }
 43005 
 43006 
 43007 foreach ($packages as $package) {
 43008 if ($package instanceof AliasPackage) {
 43009 if (isset($result[spl_object_hash($package->getAliasOf())])) {
 43010 $result[spl_object_hash($package)] = $package;
 43011 }
 43012 }
 43013 }
 43014 
 43015 return array('namesFound' => array_keys($namesFound), 'packages' => $result);
 43016 }
 43017 
 43018 
 43019 
 43020 
 43021 public function findPackage($name, $constraint)
 43022 {
 43023 $name = strtolower($name);
 43024 
 43025 if (!$constraint instanceof ConstraintInterface) {
 43026 $versionParser = new VersionParser();
 43027 $constraint = $versionParser->parseConstraints($constraint);
 43028 }
 43029 
 43030 foreach ($this->getPackages() as $package) {
 43031 if ($name === $package->getName()) {
 43032 $pkgConstraint = new Constraint('==', $package->getVersion());
 43033 if ($constraint->matches($pkgConstraint)) {
 43034 return $package;
 43035 }
 43036 }
 43037 }
 43038 
 43039 return null;
 43040 }
 43041 
 43042 
 43043 
 43044 
 43045 public function findPackages($name, $constraint = null)
 43046 {
 43047 
 43048 $name = strtolower($name);
 43049 $packages = array();
 43050 
 43051 if (null !== $constraint && !$constraint instanceof ConstraintInterface) {
 43052 $versionParser = new VersionParser();
 43053 $constraint = $versionParser->parseConstraints($constraint);
 43054 }
 43055 
 43056 foreach ($this->getPackages() as $package) {
 43057 if ($name === $package->getName()) {
 43058 if (null === $constraint || $constraint->matches(new Constraint('==', $package->getVersion()))) {
 43059 $packages[] = $package;
 43060 }
 43061 }
 43062 }
 43063 
 43064 return $packages;
 43065 }
 43066 
 43067 
 43068 
 43069 
 43070 public function search($query, $mode = 0, $type = null)
 43071 {
 43072 if ($mode === self::SEARCH_FULLTEXT) {
 43073 $regex = '{(?:'.implode('|', Preg::split('{\s+}', preg_quote($query))).')}i';
 43074 } else {
 43075 
 43076 $regex = '{(?:'.implode('|', Preg::split('{\s+}', $query)).')}i';
 43077 }
 43078 
 43079 $matches = array();
 43080 foreach ($this->getPackages() as $package) {
 43081 $name = $package->getName();
 43082 if ($mode === self::SEARCH_VENDOR) {
 43083 list($name) = explode('/', $name);
 43084 }
 43085 if (isset($matches[$name])) {
 43086 continue;
 43087 }
 43088 if (null !== $type && $package->getType() !== $type) {
 43089 continue;
 43090 }
 43091 
 43092 if (Preg::isMatch($regex, $name)
 43093 || ($mode === self::SEARCH_FULLTEXT && $package instanceof CompletePackageInterface && Preg::isMatch($regex, implode(' ', (array) $package->getKeywords()) . ' ' . $package->getDescription()))
 43094 ) {
 43095 if ($mode === self::SEARCH_VENDOR) {
 43096 $matches[$name] = array(
 43097 'name' => $name,
 43098 'description' => null,
 43099 );
 43100 } else {
 43101 $matches[$name] = array(
 43102 'name' => $package->getPrettyName(),
 43103 'description' => $package instanceof CompletePackageInterface ? $package->getDescription() : null,
 43104 );
 43105 
 43106 if ($package instanceof CompletePackageInterface && $package->isAbandoned()) {
 43107 $matches[$name]['abandoned'] = $package->getReplacementPackage() ?: true;
 43108 }
 43109 }
 43110 }
 43111 }
 43112 
 43113 return array_values($matches);
 43114 }
 43115 
 43116 
 43117 
 43118 
 43119 public function hasPackage(PackageInterface $package)
 43120 {
 43121 if ($this->packageMap === null) {
 43122 $this->packageMap = array();
 43123 foreach ($this->getPackages() as $repoPackage) {
 43124 $this->packageMap[$repoPackage->getUniqueName()] = $repoPackage;
 43125 }
 43126 }
 43127 
 43128 return isset($this->packageMap[$package->getUniqueName()]);
 43129 }
 43130 
 43131 
 43132 
 43133 
 43134 
 43135 
 43136 public function addPackage(PackageInterface $package)
 43137 {
 43138 if (!$package instanceof BasePackage) {
 43139 throw new \InvalidArgumentException('Only subclasses of BasePackage are supported');
 43140 }
 43141 if (null === $this->packages) {
 43142 $this->initialize();
 43143 }
 43144 $package->setRepository($this);
 43145 $this->packages[] = $package;
 43146 
 43147 if ($package instanceof AliasPackage) {
 43148 $aliasedPackage = $package->getAliasOf();
 43149 if (null === $aliasedPackage->getRepository()) {
 43150 $this->addPackage($aliasedPackage);
 43151 }
 43152 }
 43153 
 43154 
 43155 $this->packageMap = null;
 43156 }
 43157 
 43158 
 43159 
 43160 
 43161 public function getProviders($packageName)
 43162 {
 43163 $result = array();
 43164 
 43165 foreach ($this->getPackages() as $candidate) {
 43166 if (isset($result[$candidate->getName()])) {
 43167 continue;
 43168 }
 43169 foreach ($candidate->getProvides() as $link) {
 43170 if ($packageName === $link->getTarget()) {
 43171 $result[$candidate->getName()] = array(
 43172 'name' => $candidate->getName(),
 43173 'description' => $candidate instanceof CompletePackageInterface ? $candidate->getDescription() : null,
 43174 'type' => $candidate->getType(),
 43175 );
 43176 continue 2;
 43177 }
 43178 }
 43179 }
 43180 
 43181 return $result;
 43182 }
 43183 
 43184 
 43185 
 43186 
 43187 
 43188 
 43189 
 43190 protected function createAliasPackage(BasePackage $package, $alias, $prettyAlias)
 43191 {
 43192 while ($package instanceof AliasPackage) {
 43193 $package = $package->getAliasOf();
 43194 }
 43195 
 43196 if ($package instanceof CompletePackage) {
 43197 return new CompleteAliasPackage($package, $alias, $prettyAlias);
 43198 }
 43199 
 43200 return new AliasPackage($package, $alias, $prettyAlias);
 43201 }
 43202 
 43203 
 43204 
 43205 
 43206 
 43207 
 43208 
 43209 
 43210 public function removePackage(PackageInterface $package)
 43211 {
 43212 $packageId = $package->getUniqueName();
 43213 
 43214 foreach ($this->getPackages() as $key => $repoPackage) {
 43215 if ($packageId === $repoPackage->getUniqueName()) {
 43216 array_splice($this->packages, $key, 1);
 43217 
 43218 
 43219 $this->packageMap = null;
 43220 
 43221 return;
 43222 }
 43223 }
 43224 }
 43225 
 43226 
 43227 
 43228 
 43229 public function getPackages()
 43230 {
 43231 if (null === $this->packages) {
 43232 $this->initialize();
 43233 }
 43234 
 43235 if (null === $this->packages) {
 43236 throw new \LogicException('initialize failed to initialize the packages array');
 43237 }
 43238 
 43239 return $this->packages;
 43240 }
 43241 
 43242 
 43243 
 43244 
 43245 
 43246 
 43247 #[\ReturnTypeWillChange]
 43248 public function count()
 43249 {
 43250 if (null === $this->packages) {
 43251 $this->initialize();
 43252 }
 43253 
 43254 return count($this->packages);
 43255 }
 43256 
 43257 
 43258 
 43259 
 43260 
 43261 
 43262 protected function initialize()
 43263 {
 43264 $this->packages = array();
 43265 }
 43266 }
 43267 <?php
 43268 
 43269 
 43270 
 43271 
 43272 
 43273 
 43274 
 43275 
 43276 
 43277 
 43278 
 43279 namespace Composer\Repository;
 43280 
 43281 use Composer\IO\IOInterface;
 43282 use Composer\Json\JsonFile;
 43283 use Composer\Package\BasePackage;
 43284 use Composer\Package\Loader\ArrayLoader;
 43285 use Composer\Package\Loader\LoaderInterface;
 43286 use Composer\Util\Tar;
 43287 use Composer\Util\Zip;
 43288 
 43289 
 43290 
 43291 
 43292 class ArtifactRepository extends ArrayRepository implements ConfigurableRepositoryInterface
 43293 {
 43294 
 43295 protected $loader;
 43296 
 43297 
 43298 protected $lookup;
 43299 
 43300 protected $repoConfig;
 43301 
 43302 private $io;
 43303 
 43304 
 43305 
 43306 
 43307 public function __construct(array $repoConfig, IOInterface $io)
 43308 {
 43309 parent::__construct();
 43310 if (!extension_loaded('zip')) {
 43311 throw new \RuntimeException('The artifact repository requires PHP\'s zip extension');
 43312 }
 43313 
 43314 $this->loader = new ArrayLoader();
 43315 $this->lookup = $repoConfig['url'];
 43316 $this->io = $io;
 43317 $this->repoConfig = $repoConfig;
 43318 }
 43319 
 43320 public function getRepoName()
 43321 {
 43322 return 'artifact repo ('.$this->lookup.')';
 43323 }
 43324 
 43325 public function getRepoConfig()
 43326 {
 43327 return $this->repoConfig;
 43328 }
 43329 
 43330 protected function initialize()
 43331 {
 43332 parent::initialize();
 43333 
 43334 $this->scanDirectory($this->lookup);
 43335 }
 43336 
 43337 
 43338 
 43339 
 43340 
 43341 
 43342 private function scanDirectory($path)
 43343 {
 43344 $io = $this->io;
 43345 
 43346 $directory = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
 43347 $iterator = new \RecursiveIteratorIterator($directory);
 43348 $regex = new \RegexIterator($iterator, '/^.+\.(zip|tar|gz|tgz)$/i');
 43349 foreach ($regex as $file) {
 43350 
 43351 if (!$file->isFile()) {
 43352 continue;
 43353 }
 43354 
 43355 $package = $this->getComposerInformation($file);
 43356 if (!$package) {
 43357 $io->writeError("File <comment>{$file->getBasename()}</comment> doesn't seem to hold a package", true, IOInterface::VERBOSE);
 43358 continue;
 43359 }
 43360 
 43361 $template = 'Found package <info>%s</info> (<comment>%s</comment>) in file <info>%s</info>';
 43362 $io->writeError(sprintf($template, $package->getName(), $package->getPrettyVersion(), $file->getBasename()), true, IOInterface::VERBOSE);
 43363 
 43364 $this->addPackage($package);
 43365 }
 43366 }
 43367 
 43368 
 43369 
 43370 
 43371 private function getComposerInformation(\SplFileInfo $file)
 43372 {
 43373 $json = null;
 43374 $fileType = null;
 43375 $fileExtension = pathinfo($file->getPathname(), PATHINFO_EXTENSION);
 43376 if (in_array($fileExtension, array('gz', 'tar', 'tgz'), true)) {
 43377 $fileType = 'tar';
 43378 } elseif ($fileExtension === 'zip') {
 43379 $fileType = 'zip';
 43380 } else {
 43381 throw new \RuntimeException('Files with "'.$fileExtension.'" extensions aren\'t supported. Only ZIP and TAR/TAR.GZ/TGZ archives are supported.');
 43382 }
 43383 
 43384 try {
 43385 if ($fileType === 'tar') {
 43386 $json = Tar::getComposerJson($file->getPathname());
 43387 } else {
 43388 $json = Zip::getComposerJson($file->getPathname());
 43389 }
 43390 } catch (\Exception $exception) {
 43391 $this->io->write('Failed loading package '.$file->getPathname().': '.$exception->getMessage(), false, IOInterface::VERBOSE);
 43392 }
 43393 
 43394 if (null === $json) {
 43395 return null;
 43396 }
 43397 
 43398 $package = JsonFile::parseJson($json, $file->getPathname().'#composer.json');
 43399 $package['dist'] = array(
 43400 'type' => $fileType,
 43401 'url' => strtr($file->getPathname(), '\\', '/'),
 43402 'shasum' => sha1_file($file->getRealPath()),
 43403 );
 43404 
 43405 try {
 43406 $package = $this->loader->load($package);
 43407 } catch (\UnexpectedValueException $e) {
 43408 throw new \UnexpectedValueException('Failed loading package in '.$file.': '.$e->getMessage(), 0, $e);
 43409 }
 43410 
 43411 return $package;
 43412 }
 43413 }
 43414 <?php
 43415 
 43416 
 43417 
 43418 
 43419 
 43420 
 43421 
 43422 
 43423 
 43424 
 43425 
 43426 namespace Composer\Repository;
 43427 
 43428 use Composer\Package\BasePackage;
 43429 use Composer\Package\Loader\ArrayLoader;
 43430 use Composer\Package\PackageInterface;
 43431 use Composer\Package\AliasPackage;
 43432 use Composer\Package\CompletePackage;
 43433 use Composer\Package\CompleteAliasPackage;
 43434 use Composer\Package\Version\VersionParser;
 43435 use Composer\Package\Version\StabilityFilter;
 43436 use Composer\Json\JsonFile;
 43437 use Composer\Cache;
 43438 use Composer\Config;
 43439 use Composer\IO\IOInterface;
 43440 use Composer\Pcre\Preg;
 43441 use Composer\Plugin\PostFileDownloadEvent;
 43442 use Composer\Semver\CompilingMatcher;
 43443 use Composer\Util\HttpDownloader;
 43444 use Composer\Util\Loop;
 43445 use Composer\Plugin\PluginEvents;
 43446 use Composer\Plugin\PreFileDownloadEvent;
 43447 use Composer\EventDispatcher\EventDispatcher;
 43448 use Composer\Downloader\TransportException;
 43449 use Composer\Semver\Constraint\ConstraintInterface;
 43450 use Composer\Semver\Constraint\Constraint;
 43451 use Composer\Semver\Constraint\MatchAllConstraint;
 43452 use Composer\Util\Http\Response;
 43453 use Composer\MetadataMinifier\MetadataMinifier;
 43454 use Composer\Util\Url;
 43455 
 43456 
 43457 
 43458 
 43459 class ComposerRepository extends ArrayRepository implements ConfigurableRepositoryInterface
 43460 {
 43461 
 43462 
 43463 
 43464 
 43465 private $repoConfig;
 43466 
 43467 private $options;
 43468 
 43469 private $url;
 43470 
 43471 private $baseUrl;
 43472 
 43473 private $io;
 43474 
 43475 private $httpDownloader;
 43476 
 43477 private $loop;
 43478 
 43479 protected $cache;
 43480 
 43481 protected $notifyUrl = null;
 43482 
 43483 protected $searchUrl = null;
 43484 
 43485 protected $providersApiUrl = null;
 43486 
 43487 protected $hasProviders = false;
 43488 
 43489 protected $providersUrl = null;
 43490 
 43491 protected $listUrl = null;
 43492 
 43493 protected $hasAvailablePackageList = false;
 43494 
 43495 protected $availablePackages = null;
 43496 
 43497 protected $availablePackagePatterns = null;
 43498 
 43499 protected $lazyProvidersUrl = null;
 43500 
 43501 protected $providerListing;
 43502 
 43503 protected $loader;
 43504 
 43505 private $allowSslDowngrade = false;
 43506 
 43507 private $eventDispatcher;
 43508 
 43509 private $sourceMirrors;
 43510 
 43511 private $distMirrors;
 43512 
 43513 private $degradedMode = false;
 43514 
 43515 private $rootData;
 43516 
 43517 private $hasPartialPackages = false;
 43518 
 43519 private $partialPackagesByName = null;
 43520 
 43521 
 43522 
 43523 
 43524 
 43525 
 43526 
 43527 
 43528 public $freshMetadataUrls = array();
 43529 
 43530 
 43531 
 43532 
 43533 
 43534 
 43535 
 43536 
 43537 public $packagesNotFoundCache = array();
 43538 
 43539 
 43540 
 43541 
 43542 
 43543 public $versionParser;
 43544 
 43545 
 43546 
 43547 
 43548 
 43549 public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
 43550 {
 43551 parent::__construct();
 43552 if (!Preg::isMatch('{^[\w.]+\??://}', $repoConfig['url'])) {
 43553 
 43554 $repoConfig['url'] = 'http://'.$repoConfig['url'];
 43555 }
 43556 $repoConfig['url'] = rtrim($repoConfig['url'], '/');
 43557 
 43558 if (strpos($repoConfig['url'], 'https?') === 0) {
 43559 $repoConfig['url'] = (extension_loaded('openssl') ? 'https' : 'http') . substr($repoConfig['url'], 6);
 43560 }
 43561 
 43562 $urlBits = parse_url($repoConfig['url']);
 43563 if ($urlBits === false || empty($urlBits['scheme'])) {
 43564 throw new \UnexpectedValueException('Invalid url given for Composer repository: '.$repoConfig['url']);
 43565 }
 43566 
 43567 if (!isset($repoConfig['options'])) {
 43568 $repoConfig['options'] = array();
 43569 }
 43570 if (isset($repoConfig['allow_ssl_downgrade']) && true === $repoConfig['allow_ssl_downgrade']) {
 43571 $this->allowSslDowngrade = true;
 43572 }
 43573 
 43574 $this->options = $repoConfig['options'];
 43575 $this->url = $repoConfig['url'];
 43576 
 43577 
 43578 if (Preg::isMatch('{^(?P<proto>https?)://packagist\.org/?$}i', $this->url, $match)) {
 43579 $this->url = $match['proto'].'://repo.packagist.org';
 43580 }
 43581 
 43582 $this->baseUrl = rtrim(Preg::replace('{(?:/[^/\\\\]+\.json)?(?:[?#].*)?$}', '', $this->url), '/');
 43583 $this->io = $io;
 43584 $this->cache = new Cache($io, $config->get('cache-repo-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($this->url)), 'a-z0-9.$~');
 43585 $this->cache->setReadOnly($config->get('cache-read-only'));
 43586 $this->versionParser = new VersionParser();
 43587 $this->loader = new ArrayLoader($this->versionParser);
 43588 $this->httpDownloader = $httpDownloader;
 43589 $this->eventDispatcher = $eventDispatcher;
 43590 $this->repoConfig = $repoConfig;
 43591 $this->loop = new Loop($this->httpDownloader);
 43592 }
 43593 
 43594 public function getRepoName()
 43595 {
 43596 return 'composer repo ('.Url::sanitize($this->url).')';
 43597 }
 43598 
 43599 public function getRepoConfig()
 43600 {
 43601 return $this->repoConfig;
 43602 }
 43603 
 43604 
 43605 
 43606 
 43607 public function findPackage($name, $constraint)
 43608 {
 43609 
 43610 $hasProviders = $this->hasProviders();
 43611 
 43612 $name = strtolower($name);
 43613 if (!$constraint instanceof ConstraintInterface) {
 43614 $constraint = $this->versionParser->parseConstraints($constraint);
 43615 }
 43616 
 43617 if ($this->lazyProvidersUrl) {
 43618 if ($this->hasPartialPackages() && isset($this->partialPackagesByName[$name])) {
 43619 return $this->filterPackages($this->whatProvides($name), $constraint, true);
 43620 }
 43621 
 43622 if ($this->hasAvailablePackageList && !$this->lazyProvidersRepoContains($name)) {
 43623 return null;
 43624 }
 43625 
 43626 $packages = $this->loadAsyncPackages(array($name => $constraint));
 43627 
 43628 return reset($packages['packages']);
 43629 }
 43630 
 43631 if ($hasProviders) {
 43632 foreach ($this->getProviderNames() as $providerName) {
 43633 if ($name === $providerName) {
 43634 return $this->filterPackages($this->whatProvides($providerName), $constraint, true);
 43635 }
 43636 }
 43637 
 43638 return null;
 43639 }
 43640 
 43641 return parent::findPackage($name, $constraint);
 43642 }
 43643 
 43644 
 43645 
 43646 
 43647 public function findPackages($name, $constraint = null)
 43648 {
 43649 
 43650 $hasProviders = $this->hasProviders();
 43651 
 43652 $name = strtolower($name);
 43653 if (null !== $constraint && !$constraint instanceof ConstraintInterface) {
 43654 $constraint = $this->versionParser->parseConstraints($constraint);
 43655 }
 43656 
 43657 if ($this->lazyProvidersUrl) {
 43658 if ($this->hasPartialPackages() && isset($this->partialPackagesByName[$name])) {
 43659 return $this->filterPackages($this->whatProvides($name), $constraint);
 43660 }
 43661 
 43662 if ($this->hasAvailablePackageList && !$this->lazyProvidersRepoContains($name)) {
 43663 return array();
 43664 }
 43665 
 43666 $result = $this->loadAsyncPackages(array($name => $constraint));
 43667 
 43668 return $result['packages'];
 43669 }
 43670 
 43671 if ($hasProviders) {
 43672 foreach ($this->getProviderNames() as $providerName) {
 43673 if ($name === $providerName) {
 43674 return $this->filterPackages($this->whatProvides($providerName), $constraint);
 43675 }
 43676 }
 43677 
 43678 return array();
 43679 }
 43680 
 43681 return parent::findPackages($name, $constraint);
 43682 }
 43683 
 43684 
 43685 
 43686 
 43687 
 43688 
 43689 
 43690 
 43691 private function filterPackages(array $packages, $constraint = null, $returnFirstMatch = false)
 43692 {
 43693 if (null === $constraint) {
 43694 if ($returnFirstMatch) {
 43695 return reset($packages);
 43696 }
 43697 
 43698 return $packages;
 43699 }
 43700 
 43701 $filteredPackages = array();
 43702 
 43703 foreach ($packages as $package) {
 43704 $pkgConstraint = new Constraint('==', $package->getVersion());
 43705 
 43706 if ($constraint->matches($pkgConstraint)) {
 43707 if ($returnFirstMatch) {
 43708 return $package;
 43709 }
 43710 
 43711 $filteredPackages[] = $package;
 43712 }
 43713 }
 43714 
 43715 if ($returnFirstMatch) {
 43716 return null;
 43717 }
 43718 
 43719 return $filteredPackages;
 43720 }
 43721 
 43722 public function getPackages()
 43723 {
 43724 $hasProviders = $this->hasProviders();
 43725 
 43726 if ($this->lazyProvidersUrl) {
 43727 if (is_array($this->availablePackages) && !$this->availablePackagePatterns) {
 43728 $packageMap = array();
 43729 foreach ($this->availablePackages as $name) {
 43730 $packageMap[$name] = new MatchAllConstraint();
 43731 }
 43732 
 43733 $result = $this->loadAsyncPackages($packageMap);
 43734 
 43735 return array_values($result['packages']);
 43736 }
 43737 
 43738 if ($this->hasPartialPackages()) {
 43739 if (!is_array($this->partialPackagesByName)) {
 43740 throw new \LogicException('hasPartialPackages failed to initialize $this->partialPackagesByName');
 43741 }
 43742 return $this->createPackages($this->partialPackagesByName, 'packages.json inline packages');
 43743 }
 43744 
 43745 throw new \LogicException('Composer repositories that have lazy providers and no available-packages list can not load the complete list of packages, use getPackageNames instead.');
 43746 }
 43747 
 43748 if ($hasProviders) {
 43749 throw new \LogicException('Composer repositories that have providers can not load the complete list of packages, use getPackageNames instead.');
 43750 }
 43751 
 43752 return parent::getPackages();
 43753 }
 43754 
 43755 
 43756 
 43757 
 43758 
 43759 
 43760 public function getPackageNames($packageFilter = null)
 43761 {
 43762 $hasProviders = $this->hasProviders();
 43763 
 43764 $filterResults =
 43765 
 43766 
 43767 
 43768 
 43769 function (array $results) {
 43770 return $results;
 43771 }
 43772 ;
 43773 if (null !== $packageFilter && '' !== $packageFilter) {
 43774 $packageFilterRegex = BasePackage::packageNameToRegexp($packageFilter);
 43775 $filterResults =
 43776 
 43777 
 43778 
 43779 
 43780 function (array $results) use ($packageFilterRegex) {
 43781 
 43782 return Preg::grep($packageFilterRegex, $results);
 43783 }
 43784 ;
 43785 }
 43786 
 43787 if ($this->lazyProvidersUrl) {
 43788 if (is_array($this->availablePackages)) {
 43789 return $filterResults(array_keys($this->availablePackages));
 43790 }
 43791 
 43792 if ($this->listUrl) {
 43793 
 43794 return $this->loadPackageList($packageFilter);
 43795 }
 43796 
 43797 if ($this->hasPartialPackages() && $this->partialPackagesByName !== null) {
 43798 return $filterResults(array_keys($this->partialPackagesByName));
 43799 }
 43800 
 43801 return array();
 43802 }
 43803 
 43804 if ($hasProviders) {
 43805 return $filterResults($this->getProviderNames());
 43806 }
 43807 
 43808 $names = array();
 43809 foreach ($this->getPackages() as $package) {
 43810 $names[] = $package->getPrettyName();
 43811 }
 43812 
 43813 return $filterResults($names);
 43814 }
 43815 
 43816 
 43817 
 43818 
 43819 private function getVendorNames()
 43820 {
 43821 $cacheKey = 'vendor-list.txt';
 43822 $cacheAge = $this->cache->getAge($cacheKey);
 43823 if (false !== $cacheAge && $cacheAge < 600 && ($cachedData = $this->cache->read($cacheKey)) !== false) {
 43824 $cachedData = explode("\n", $cachedData);
 43825 
 43826 return $cachedData;
 43827 }
 43828 
 43829 $names = $this->getPackageNames();
 43830 
 43831 $uniques = array();
 43832 foreach ($names as $name) {
 43833 
 43834 $uniques[substr($name, 0, strpos($name, '/'))] = true;
 43835 }
 43836 
 43837 $vendors = array_keys($uniques);
 43838 
 43839 if (!$this->cache->isReadOnly()) {
 43840 $this->cache->write($cacheKey, implode("\n", $vendors));
 43841 }
 43842 
 43843 return $vendors;
 43844 }
 43845 
 43846 
 43847 
 43848 
 43849 
 43850 private function loadPackageList($packageFilter = null)
 43851 {
 43852 if (null === $this->listUrl) {
 43853 throw new \LogicException('Make sure to call loadRootServerFile before loadPackageList');
 43854 }
 43855 
 43856 $url = $this->listUrl;
 43857 if (is_string($packageFilter) && $packageFilter !== '') {
 43858 $url .= '?filter='.urlencode($packageFilter);
 43859 $result = $this->httpDownloader->get($url, $this->options)->decodeJson();
 43860 
 43861 return $result['packageNames'];
 43862 }
 43863 
 43864 $cacheKey = 'package-list.txt';
 43865 $cacheAge = $this->cache->getAge($cacheKey);
 43866 if (false !== $cacheAge && $cacheAge < 600 && ($cachedData = $this->cache->read($cacheKey)) !== false) {
 43867 $cachedData = explode("\n", $cachedData);
 43868 
 43869 return $cachedData;
 43870 }
 43871 
 43872 $result = $this->httpDownloader->get($url, $this->options)->decodeJson();
 43873 if (!$this->cache->isReadOnly()) {
 43874 $this->cache->write($cacheKey, implode("\n", $result['packageNames']));
 43875 }
 43876 
 43877 return $result['packageNames'];
 43878 }
 43879 
 43880 public function loadPackages(array $packageNameMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array())
 43881 {
 43882 
 43883 $hasProviders = $this->hasProviders();
 43884 
 43885 if (!$hasProviders && !$this->hasPartialPackages() && !$this->lazyProvidersUrl) {
 43886 return parent::loadPackages($packageNameMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded);
 43887 }
 43888 
 43889 $packages = array();
 43890 $namesFound = array();
 43891 
 43892 if ($hasProviders || $this->hasPartialPackages()) {
 43893 foreach ($packageNameMap as $name => $constraint) {
 43894 $matches = array();
 43895 
 43896 
 43897 
 43898 if (!$hasProviders && !isset($this->partialPackagesByName[$name])) {
 43899 continue;
 43900 }
 43901 
 43902 $candidates = $this->whatProvides($name, $acceptableStabilities, $stabilityFlags, $alreadyLoaded);
 43903 foreach ($candidates as $candidate) {
 43904 if ($candidate->getName() !== $name) {
 43905 throw new \LogicException('whatProvides should never return a package with a different name than the requested one');
 43906 }
 43907 $namesFound[$name] = true;
 43908 
 43909 if (!$constraint || $constraint->matches(new Constraint('==', $candidate->getVersion()))) {
 43910 $matches[spl_object_hash($candidate)] = $candidate;
 43911 if ($candidate instanceof AliasPackage && !isset($matches[spl_object_hash($candidate->getAliasOf())])) {
 43912 $matches[spl_object_hash($candidate->getAliasOf())] = $candidate->getAliasOf();
 43913 }
 43914 }
 43915 }
 43916 
 43917 
 43918 foreach ($candidates as $candidate) {
 43919 if ($candidate instanceof AliasPackage) {
 43920 if (isset($matches[spl_object_hash($candidate->getAliasOf())])) {
 43921 $matches[spl_object_hash($candidate)] = $candidate;
 43922 }
 43923 }
 43924 }
 43925 $packages = array_merge($packages, $matches);
 43926 
 43927 unset($packageNameMap[$name]);
 43928 }
 43929 }
 43930 
 43931 if ($this->lazyProvidersUrl && count($packageNameMap)) {
 43932 if ($this->hasAvailablePackageList) {
 43933 foreach ($packageNameMap as $name => $constraint) {
 43934 if (!$this->lazyProvidersRepoContains(strtolower($name))) {
 43935 unset($packageNameMap[$name]);
 43936 }
 43937 }
 43938 }
 43939 
 43940 $result = $this->loadAsyncPackages($packageNameMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded);
 43941 $packages = array_merge($packages, $result['packages']);
 43942 $namesFound = array_merge($namesFound, $result['namesFound']);
 43943 }
 43944 
 43945 return array('namesFound' => array_keys($namesFound), 'packages' => $packages);
 43946 }
 43947 
 43948 
 43949 
 43950 
 43951 public function search($query, $mode = 0, $type = null)
 43952 {
 43953 $this->loadRootServerFile(600);
 43954 
 43955 if ($this->searchUrl && $mode === self::SEARCH_FULLTEXT) {
 43956 $url = str_replace(array('%query%', '%type%'), array(urlencode($query), $type), $this->searchUrl);
 43957 
 43958 $search = $this->httpDownloader->get($url, $this->options)->decodeJson();
 43959 
 43960 if (empty($search['results'])) {
 43961 return array();
 43962 }
 43963 
 43964 $results = array();
 43965 foreach ($search['results'] as $result) {
 43966 
 43967 if (!empty($result['virtual'])) {
 43968 continue;
 43969 }
 43970 
 43971 $results[] = $result;
 43972 }
 43973 
 43974 return $results;
 43975 }
 43976 
 43977 if ($mode === self::SEARCH_VENDOR) {
 43978 $results = array();
 43979 $regex = '{(?:'.implode('|', Preg::split('{\s+}', $query)).')}i';
 43980 
 43981 $vendorNames = $this->getVendorNames();
 43982 foreach (Preg::grep($regex, $vendorNames) as $name) {
 43983 $results[] = array('name' => $name, 'description' => '');
 43984 }
 43985 
 43986 return $results;
 43987 }
 43988 
 43989 if ($this->hasProviders() || $this->lazyProvidersUrl) {
 43990 
 43991 if (Preg::isMatch('{^\^(?P<query>(?P<vendor>[a-z0-9_.-]+)/[a-z0-9_.-]*)\*?$}i', $query, $match) && $this->listUrl !== null) {
 43992 $url = $this->listUrl . '?vendor='.urlencode($match['vendor']).'&filter='.urlencode($match['query'].'*');
 43993 $result = $this->httpDownloader->get($url, $this->options)->decodeJson();
 43994 
 43995 $results = array();
 43996 foreach ($result['packageNames'] as $name) {
 43997 $results[] = array('name' => $name, 'description' => '');
 43998 }
 43999 
 44000 return $results;
 44001 }
 44002 
 44003 $results = array();
 44004 $regex = '{(?:'.implode('|', Preg::split('{\s+}', $query)).')}i';
 44005 
 44006 $packageNames = $this->getPackageNames();
 44007 foreach (Preg::grep($regex, $packageNames) as $name) {
 44008 $results[] = array('name' => $name, 'description' => '');
 44009 }
 44010 
 44011 return $results;
 44012 }
 44013 
 44014 return parent::search($query, $mode);
 44015 }
 44016 
 44017 public function getProviders($packageName)
 44018 {
 44019 $this->loadRootServerFile();
 44020 $result = array();
 44021 
 44022 if ($this->providersApiUrl) {
 44023 $apiResult = $this->httpDownloader->get(str_replace('%package%', $packageName, $this->providersApiUrl), $this->options)->decodeJson();
 44024 
 44025 foreach ($apiResult['providers'] as $provider) {
 44026 $result[$provider['name']] = $provider;
 44027 }
 44028 
 44029 return $result;
 44030 }
 44031 
 44032 if ($this->hasPartialPackages()) {
 44033 if (!is_array($this->partialPackagesByName)) {
 44034 throw new \LogicException('hasPartialPackages failed to initialize $this->partialPackagesByName');
 44035 }
 44036 foreach ($this->partialPackagesByName as $versions) {
 44037 foreach ($versions as $candidate) {
 44038 if (isset($result[$candidate['name']]) || !isset($candidate['provide'][$packageName])) {
 44039 continue;
 44040 }
 44041 $result[$candidate['name']] = array(
 44042 'name' => $candidate['name'],
 44043 'description' => isset($candidate['description']) ? $candidate['description'] : '',
 44044 'type' => isset($candidate['type']) ? $candidate['type'] : '',
 44045 );
 44046 }
 44047 }
 44048 }
 44049 
 44050 if ($this->packages) {
 44051 $result = array_merge($result, parent::getProviders($packageName));
 44052 }
 44053 
 44054 return $result;
 44055 }
 44056 
 44057 
 44058 
 44059 
 44060 private function getProviderNames()
 44061 {
 44062 $this->loadRootServerFile();
 44063 
 44064 if (null === $this->providerListing) {
 44065 $this->loadProviderListings($this->loadRootServerFile());
 44066 }
 44067 
 44068 if ($this->lazyProvidersUrl) {
 44069 
 44070 return array();
 44071 }
 44072 
 44073 if (null !== $this->providersUrl && null !== $this->providerListing) {
 44074 return array_keys($this->providerListing);
 44075 }
 44076 
 44077 return array();
 44078 }
 44079 
 44080 
 44081 
 44082 
 44083 protected function configurePackageTransportOptions(PackageInterface $package)
 44084 {
 44085 foreach ($package->getDistUrls() as $url) {
 44086 if (strpos($url, $this->baseUrl) === 0) {
 44087 $package->setTransportOptions($this->options);
 44088 
 44089 return;
 44090 }
 44091 }
 44092 }
 44093 
 44094 
 44095 
 44096 
 44097 private function hasProviders()
 44098 {
 44099 $this->loadRootServerFile();
 44100 
 44101 return $this->hasProviders;
 44102 }
 44103 
 44104 
 44105 
 44106 
 44107 
 44108 
 44109 
 44110 
 44111 
 44112 
 44113 
 44114 private function whatProvides($name, array $acceptableStabilities = null, array $stabilityFlags = null, array $alreadyLoaded = array())
 44115 {
 44116 $packagesSource = null;
 44117 if (!$this->hasPartialPackages() || !isset($this->partialPackagesByName[$name])) {
 44118 
 44119 if (PlatformRepository::isPlatformPackage($name) || '__root__' === $name) {
 44120 return array();
 44121 }
 44122 
 44123 if (null === $this->providerListing) {
 44124 $this->loadProviderListings($this->loadRootServerFile());
 44125 }
 44126 
 44127 $useLastModifiedCheck = false;
 44128 if ($this->lazyProvidersUrl && !isset($this->providerListing[$name])) {
 44129 $hash = null;
 44130 $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
 44131 $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
 44132 $useLastModifiedCheck = true;
 44133 } elseif ($this->providersUrl) {
 44134 
 44135 if (!isset($this->providerListing[$name])) {
 44136 return array();
 44137 }
 44138 
 44139 $hash = $this->providerListing[$name]['sha256'];
 44140 $url = str_replace(array('%package%', '%hash%'), array($name, $hash), $this->providersUrl);
 44141 $cacheKey = 'provider-'.strtr($name, '/', '$').'.json';
 44142 } else {
 44143 return array();
 44144 }
 44145 
 44146 $packages = null;
 44147 if (!$useLastModifiedCheck && $hash && $this->cache->sha256($cacheKey) === $hash) {
 44148 $packages = json_decode($this->cache->read($cacheKey), true);
 44149 $packagesSource = 'cached file ('.$cacheKey.' originating from '.Url::sanitize($url).')';
 44150 } elseif ($useLastModifiedCheck) {
 44151 if ($contents = $this->cache->read($cacheKey)) {
 44152 $contents = json_decode($contents, true);
 44153 
 44154 if (isset($alreadyLoaded[$name])) {
 44155 $packages = $contents;
 44156 $packagesSource = 'cached file ('.$cacheKey.' originating from '.Url::sanitize($url).')';
 44157 } elseif (isset($contents['last-modified'])) {
 44158 $response = $this->fetchFileIfLastModified($url, $cacheKey, $contents['last-modified']);
 44159 $packages = true === $response ? $contents : $response;
 44160 $packagesSource = true === $response ? 'cached file ('.$cacheKey.' originating from '.Url::sanitize($url).')' : 'downloaded file ('.Url::sanitize($url).')';
 44161 }
 44162 }
 44163 }
 44164 
 44165 if (!$packages) {
 44166 try {
 44167 $packages = $this->fetchFile($url, $cacheKey, $hash, $useLastModifiedCheck);
 44168 $packagesSource = 'downloaded file ('.Url::sanitize($url).')';
 44169 } catch (TransportException $e) {
 44170 
 44171 if ($this->lazyProvidersUrl && in_array($e->getStatusCode(), array(404, 499), true)) {
 44172 $packages = array('packages' => array());
 44173 $packagesSource = 'not-found file ('.Url::sanitize($url).')';
 44174 if ($e->getStatusCode() === 499) {
 44175 $this->io->error('<warning>' . $e->getMessage() . '</warning>');
 44176 }
 44177 } else {
 44178 throw $e;
 44179 }
 44180 }
 44181 }
 44182 
 44183 $loadingPartialPackage = false;
 44184 } else {
 44185 $packages = array('packages' => array('versions' => $this->partialPackagesByName[$name]));
 44186 $packagesSource = 'root file ('.Url::sanitize($this->getPackagesJsonUrl()).')';
 44187 $loadingPartialPackage = true;
 44188 }
 44189 
 44190 $result = array();
 44191 $versionsToLoad = array();
 44192 foreach ($packages['packages'] as $versions) {
 44193 foreach ($versions as $version) {
 44194 $normalizedName = strtolower($version['name']);
 44195 
 44196 
 44197 if ($normalizedName !== $name) {
 44198 continue;
 44199 }
 44200 
 44201 if (!$loadingPartialPackage && $this->hasPartialPackages() && isset($this->partialPackagesByName[$normalizedName])) {
 44202 continue;
 44203 }
 44204 
 44205 if (!isset($versionsToLoad[$version['uid']])) {
 44206 if (!isset($version['version_normalized'])) {
 44207 $version['version_normalized'] = $this->versionParser->normalize($version['version']);
 44208 } elseif ($version['version_normalized'] === VersionParser::DEFAULT_BRANCH_ALIAS) {
 44209 
 44210 $version['version_normalized'] = $this->versionParser->normalize($version['version']);
 44211 }
 44212 
 44213 
 44214 if (isset($alreadyLoaded[$name][$version['version_normalized']])) {
 44215 continue;
 44216 }
 44217 
 44218 if ($this->isVersionAcceptable(null, $normalizedName, $version, $acceptableStabilities, $stabilityFlags)) {
 44219 $versionsToLoad[$version['uid']] = $version;
 44220 }
 44221 }
 44222 }
 44223 }
 44224 
 44225 
 44226 $loadedPackages = $this->createPackages($versionsToLoad, $packagesSource);
 44227 $uids = array_keys($versionsToLoad);
 44228 
 44229 foreach ($loadedPackages as $index => $package) {
 44230 $package->setRepository($this);
 44231 $uid = $uids[$index];
 44232 
 44233 if ($package instanceof AliasPackage) {
 44234 $aliased = $package->getAliasOf();
 44235 $aliased->setRepository($this);
 44236 
 44237 $result[$uid] = $aliased;
 44238 $result[$uid.'-alias'] = $package;
 44239 } else {
 44240 $result[$uid] = $package;
 44241 }
 44242 }
 44243 
 44244 return $result;
 44245 }
 44246 
 44247 
 44248 
 44249 
 44250 protected function initialize()
 44251 {
 44252 parent::initialize();
 44253 
 44254 $repoData = $this->loadDataFromServer();
 44255 
 44256 foreach ($this->createPackages($repoData, 'root file ('.Url::sanitize($this->getPackagesJsonUrl()).')') as $package) {
 44257 $this->addPackage($package);
 44258 }
 44259 }
 44260 
 44261 
 44262 
 44263 
 44264 
 44265 
 44266 public function addPackage(PackageInterface $package)
 44267 {
 44268 parent::addPackage($package);
 44269 $this->configurePackageTransportOptions($package);
 44270 }
 44271 
 44272 
 44273 
 44274 
 44275 
 44276 
 44277 
 44278 
 44279 
 44280 
 44281 
 44282 private function loadAsyncPackages(array $packageNames, array $acceptableStabilities = null, array $stabilityFlags = null, array $alreadyLoaded = array())
 44283 {
 44284 $this->loadRootServerFile();
 44285 
 44286 $packages = array();
 44287 $namesFound = array();
 44288 $promises = array();
 44289 $repo = $this;
 44290 
 44291 if (!$this->lazyProvidersUrl) {
 44292 throw new \LogicException('loadAsyncPackages only supports v2 protocol composer repos with a metadata-url');
 44293 }
 44294 
 44295 
 44296 foreach ($packageNames as $name => $constraint) {
 44297 if ($acceptableStabilities === null || $stabilityFlags === null || StabilityFilter::isPackageAcceptable($acceptableStabilities, $stabilityFlags, array($name), 'dev')) {
 44298 $packageNames[$name.'~dev'] = $constraint;
 44299 }
 44300 
 44301 if (isset($acceptableStabilities['dev']) && count($acceptableStabilities) === 1 && count($stabilityFlags) === 0) {
 44302 unset($packageNames[$name]);
 44303 }
 44304 }
 44305 
 44306 foreach ($packageNames as $name => $constraint) {
 44307 $name = strtolower($name);
 44308 
 44309 $realName = Preg::replace('{~dev$}', '', $name);
 44310 
 44311 if (PlatformRepository::isPlatformPackage($realName) || '__root__' === $realName) {
 44312 continue;
 44313 }
 44314 
 44315 $url = str_replace('%package%', $name, $this->lazyProvidersUrl);
 44316 $cacheKey = 'provider-'.strtr($name, '/', '~').'.json';
 44317 
 44318 $lastModified = null;
 44319 if ($contents = $this->cache->read($cacheKey)) {
 44320 $contents = json_decode($contents, true);
 44321 $lastModified = isset($contents['last-modified']) ? $contents['last-modified'] : null;
 44322 }
 44323 
 44324 $promises[] = $this->asyncFetchFile($url, $cacheKey, $lastModified)
 44325 ->then(function ($response) use (&$packages, &$namesFound, $url, $cacheKey, $contents, $realName, $constraint, $repo, $acceptableStabilities, $stabilityFlags, $alreadyLoaded) {
 44326 $packagesSource = 'downloaded file ('.Url::sanitize($url).')';
 44327 
 44328 if (true === $response) {
 44329 $packagesSource = 'cached file ('.$cacheKey.' originating from '.Url::sanitize($url).')';
 44330 $response = $contents;
 44331 }
 44332 
 44333 if (!isset($response['packages'][$realName])) {
 44334 return;
 44335 }
 44336 
 44337 $versions = $response['packages'][$realName];
 44338 
 44339 if (isset($response['minified']) && $response['minified'] === 'composer/2.0') {
 44340 $versions = MetadataMinifier::expand($versions);
 44341 }
 44342 
 44343 $namesFound[$realName] = true;
 44344 $versionsToLoad = array();
 44345 foreach ($versions as $version) {
 44346 if (!isset($version['version_normalized'])) {
 44347 $version['version_normalized'] = $repo->versionParser->normalize($version['version']);
 44348 } elseif ($version['version_normalized'] === VersionParser::DEFAULT_BRANCH_ALIAS) {
 44349 
 44350 $version['version_normalized'] = $repo->versionParser->normalize($version['version']);
 44351 }
 44352 
 44353 
 44354 if (isset($alreadyLoaded[$realName][$version['version_normalized']])) {
 44355 continue;
 44356 }
 44357 
 44358 if ($repo->isVersionAcceptable($constraint, $realName, $version, $acceptableStabilities, $stabilityFlags)) {
 44359 $versionsToLoad[] = $version;
 44360 }
 44361 }
 44362 
 44363 $loadedPackages = $repo->createPackages($versionsToLoad, $packagesSource);
 44364 foreach ($loadedPackages as $package) {
 44365 $package->setRepository($repo);
 44366 $packages[spl_object_hash($package)] = $package;
 44367 
 44368 if ($package instanceof AliasPackage && !isset($packages[spl_object_hash($package->getAliasOf())])) {
 44369 $package->getAliasOf()->setRepository($repo);
 44370 $packages[spl_object_hash($package->getAliasOf())] = $package->getAliasOf();
 44371 }
 44372 }
 44373 });
 44374 }
 44375 
 44376 $this->loop->wait($promises);
 44377 
 44378 return array('namesFound' => $namesFound, 'packages' => $packages);
 44379 
 44380 }
 44381 
 44382 
 44383 
 44384 
 44385 
 44386 
 44387 
 44388 
 44389 
 44390 
 44391 
 44392 
 44393 
 44394 
 44395 
 44396 
 44397 public function isVersionAcceptable($constraint, $name, $versionData, array $acceptableStabilities = null, array $stabilityFlags = null)
 44398 {
 44399 $versions = array($versionData['version_normalized']);
 44400 
 44401 if ($alias = $this->loader->getBranchAlias($versionData)) {
 44402 $versions[] = $alias;
 44403 }
 44404 
 44405 foreach ($versions as $version) {
 44406 if (null !== $acceptableStabilities && null !== $stabilityFlags && !StabilityFilter::isPackageAcceptable($acceptableStabilities, $stabilityFlags, array($name), VersionParser::parseStability($version))) {
 44407 continue;
 44408 }
 44409 
 44410 if ($constraint && !CompilingMatcher::match($constraint, Constraint::OP_EQ, $version)) {
 44411 continue;
 44412 }
 44413 
 44414 return true;
 44415 }
 44416 
 44417 return false;
 44418 }
 44419 
 44420 
 44421 
 44422 
 44423 private function getPackagesJsonUrl()
 44424 {
 44425 $jsonUrlParts = parse_url($this->url);
 44426 
 44427 if (isset($jsonUrlParts['path']) && false !== strpos($jsonUrlParts['path'], '.json')) {
 44428 return $this->url;
 44429 }
 44430 
 44431 return $this->url . '/packages.json';
 44432 }
 44433 
 44434 
 44435 
 44436 
 44437 
 44438 protected function loadRootServerFile($rootMaxAge = null)
 44439 {
 44440 if (null !== $this->rootData) {
 44441 return $this->rootData;
 44442 }
 44443 
 44444 if (!extension_loaded('openssl') && strpos($this->url, 'https') === 0) {
 44445 throw new \RuntimeException('You must enable the openssl extension in your php.ini to load information from '.$this->url);
 44446 }
 44447 
 44448 if ($cachedData = $this->cache->read('packages.json')) {
 44449 $cachedData = json_decode($cachedData, true);
 44450 if ($rootMaxAge !== null && ($age = $this->cache->getAge('packages.json')) !== false && $age <= $rootMaxAge) {
 44451 $data = $cachedData;
 44452 } elseif (isset($cachedData['last-modified'])) {
 44453 $response = $this->fetchFileIfLastModified($this->getPackagesJsonUrl(), 'packages.json', $cachedData['last-modified']);
 44454 $data = true === $response ? $cachedData : $response;
 44455 }
 44456 }
 44457 
 44458 if (!isset($data)) {
 44459 $data = $this->fetchFile($this->getPackagesJsonUrl(), 'packages.json', null, true);
 44460 }
 44461 
 44462 if (!empty($data['notify-batch'])) {
 44463 $this->notifyUrl = $this->canonicalizeUrl($data['notify-batch']);
 44464 } elseif (!empty($data['notify'])) {
 44465 $this->notifyUrl = $this->canonicalizeUrl($data['notify']);
 44466 }
 44467 
 44468 if (!empty($data['search'])) {
 44469 $this->searchUrl = $this->canonicalizeUrl($data['search']);
 44470 }
 44471 
 44472 if (!empty($data['mirrors'])) {
 44473 foreach ($data['mirrors'] as $mirror) {
 44474 if (!empty($mirror['git-url'])) {
 44475 $this->sourceMirrors['git'][] = array('url' => $mirror['git-url'], 'preferred' => !empty($mirror['preferred']));
 44476 }
 44477 if (!empty($mirror['hg-url'])) {
 44478 $this->sourceMirrors['hg'][] = array('url' => $mirror['hg-url'], 'preferred' => !empty($mirror['preferred']));
 44479 }
 44480 if (!empty($mirror['dist-url'])) {
 44481 $this->distMirrors[] = array(
 44482 'url' => $this->canonicalizeUrl($mirror['dist-url']),
 44483 'preferred' => !empty($mirror['preferred']),
 44484 );
 44485 }
 44486 }
 44487 }
 44488 
 44489 if (!empty($data['providers-lazy-url'])) {
 44490 $this->lazyProvidersUrl = $this->canonicalizeUrl($data['providers-lazy-url']);
 44491 $this->hasProviders = true;
 44492 
 44493 $this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
 44494 }
 44495 
 44496 
 44497 
 44498 
 44499 if (!empty($data['metadata-url'])) {
 44500 $this->lazyProvidersUrl = $this->canonicalizeUrl($data['metadata-url']);
 44501 $this->providersUrl = null;
 44502 $this->hasProviders = false;
 44503 $this->hasPartialPackages = !empty($data['packages']) && is_array($data['packages']);
 44504 $this->allowSslDowngrade = false;
 44505 
 44506 
 44507 
 44508 
 44509 if (!empty($data['available-packages'])) {
 44510 $availPackages = array_map('strtolower', $data['available-packages']);
 44511 $this->availablePackages = array_combine($availPackages, $availPackages);
 44512 $this->hasAvailablePackageList = true;
 44513 }
 44514 
 44515 
 44516 
 44517 
 44518 if (!empty($data['available-package-patterns'])) {
 44519 $this->availablePackagePatterns = array_map(function ($pattern) {
 44520 return BasePackage::packageNameToRegexp($pattern);
 44521 }, $data['available-package-patterns']);
 44522 $this->hasAvailablePackageList = true;
 44523 }
 44524 
 44525 
 44526 
 44527 unset($data['providers-url'], $data['providers'], $data['providers-includes']);
 44528 }
 44529 
 44530 if ($this->allowSslDowngrade) {
 44531 $this->url = str_replace('https://', 'http://', $this->url);
 44532 $this->baseUrl = str_replace('https://', 'http://', $this->baseUrl);
 44533 }
 44534 
 44535 if (!empty($data['providers-url'])) {
 44536 $this->providersUrl = $this->canonicalizeUrl($data['providers-url']);
 44537 $this->hasProviders = true;
 44538 }
 44539 
 44540 if (!empty($data['list'])) {
 44541 $this->listUrl = $this->canonicalizeUrl($data['list']);
 44542 }
 44543 
 44544 if (!empty($data['providers']) || !empty($data['providers-includes'])) {
 44545 $this->hasProviders = true;
 44546 }
 44547 
 44548 if (!empty($data['providers-api'])) {
 44549 $this->providersApiUrl = $this->canonicalizeUrl($data['providers-api']);
 44550 }
 44551 
 44552 return $this->rootData = $data;
 44553 }
 44554 
 44555 
 44556 
 44557 
 44558 
 44559 
 44560 private function canonicalizeUrl($url)
 44561 {
 44562 if ('/' === $url[0]) {
 44563 if (Preg::isMatch('{^[^:]++://[^/]*+}', $this->url, $matches)) {
 44564 return $matches[0] . $url;
 44565 }
 44566 
 44567 return $this->url;
 44568 }
 44569 
 44570 return $url;
 44571 }
 44572 
 44573 
 44574 
 44575 
 44576 private function loadDataFromServer()
 44577 {
 44578 $data = $this->loadRootServerFile();
 44579 
 44580 return $this->loadIncludes($data);
 44581 }
 44582 
 44583 
 44584 
 44585 
 44586 private function hasPartialPackages()
 44587 {
 44588 if ($this->hasPartialPackages && null === $this->partialPackagesByName) {
 44589 $this->initializePartialPackages();
 44590 }
 44591 
 44592 return $this->hasPartialPackages;
 44593 }
 44594 
 44595 
 44596 
 44597 
 44598 
 44599 
 44600 private function loadProviderListings($data)
 44601 {
 44602 if (isset($data['providers'])) {
 44603 if (!is_array($this->providerListing)) {
 44604 $this->providerListing = array();
 44605 }
 44606 $this->providerListing = array_merge($this->providerListing, $data['providers']);
 44607 }
 44608 
 44609 if ($this->providersUrl && isset($data['provider-includes'])) {
 44610 $includes = $data['provider-includes'];
 44611 foreach ($includes as $include => $metadata) {
 44612 $url = $this->baseUrl . '/' . str_replace('%hash%', $metadata['sha256'], $include);
 44613 $cacheKey = str_replace(array('%hash%','$'), '', $include);
 44614 if ($this->cache->sha256($cacheKey) === $metadata['sha256']) {
 44615 $includedData = json_decode($this->cache->read($cacheKey), true);
 44616 } else {
 44617 $includedData = $this->fetchFile($url, $cacheKey, $metadata['sha256']);
 44618 }
 44619 
 44620 $this->loadProviderListings($includedData);
 44621 }
 44622 }
 44623 }
 44624 
 44625 
 44626 
 44627 
 44628 
 44629 
 44630 private function loadIncludes($data)
 44631 {
 44632 $packages = array();
 44633 
 44634 
 44635 if (!isset($data['packages']) && !isset($data['includes'])) {
 44636 foreach ($data as $pkg) {
 44637 if (isset($pkg['versions']) && is_array($pkg['versions'])) {
 44638 foreach ($pkg['versions'] as $metadata) {
 44639 $packages[] = $metadata;
 44640 }
 44641 }
 44642 }
 44643 
 44644 return $packages;
 44645 }
 44646 
 44647 if (isset($data['packages'])) {
 44648 foreach ($data['packages'] as $package => $versions) {
 44649 foreach ($versions as $version => $metadata) {
 44650 $packages[] = $metadata;
 44651 }
 44652 }
 44653 }
 44654 
 44655 if (isset($data['includes'])) {
 44656 foreach ($data['includes'] as $include => $metadata) {
 44657 if (isset($metadata['sha1']) && $this->cache->sha1((string) $include) === $metadata['sha1']) {
 44658 $includedData = json_decode($this->cache->read((string) $include), true);
 44659 } else {
 44660 $includedData = $this->fetchFile($include);
 44661 }
 44662 $packages = array_merge($packages, $this->loadIncludes($includedData));
 44663 }
 44664 }
 44665 
 44666 return $packages;
 44667 }
 44668 
 44669 
 44670 
 44671 
 44672 
 44673 
 44674 
 44675 
 44676 
 44677 
 44678 public function createPackages(array $packages, $source = null)
 44679 {
 44680 if (!$packages) {
 44681 return array();
 44682 }
 44683 
 44684 try {
 44685 foreach ($packages as &$data) {
 44686 if (!isset($data['notification-url'])) {
 44687 $data['notification-url'] = $this->notifyUrl;
 44688 }
 44689 }
 44690 
 44691 $packageInstances = $this->loader->loadPackages($packages);
 44692 
 44693 foreach ($packageInstances as $package) {
 44694 if (isset($this->sourceMirrors[$package->getSourceType()])) {
 44695 $package->setSourceMirrors($this->sourceMirrors[$package->getSourceType()]);
 44696 }
 44697 $package->setDistMirrors($this->distMirrors);
 44698 $this->configurePackageTransportOptions($package);
 44699 }
 44700 
 44701 return $packageInstances;
 44702 } catch (\Exception $e) {
 44703 throw new \RuntimeException('Could not load packages '.(isset($packages[0]['name']) ? $packages[0]['name'] : json_encode($packages)).' in '.$this->getRepoName().($source ? ' from '.$source : '').': ['.get_class($e).'] '.$e->getMessage(), 0, $e);
 44704 }
 44705 }
 44706 
 44707 
 44708 
 44709 
 44710 
 44711 
 44712 
 44713 
 44714 
 44715 protected function fetchFile($filename, $cacheKey = null, $sha256 = null, $storeLastModifiedTime = false)
 44716 {
 44717 if (null === $cacheKey) {
 44718 $cacheKey = $filename;
 44719 $filename = $this->baseUrl.'/'.$filename;
 44720 }
 44721 
 44722 
 44723 if (($pos = strpos($filename, '$')) && Preg::isMatch('{^https?://}i', $filename)) {
 44724 $filename = substr($filename, 0, $pos) . '%24' . substr($filename, $pos + 1);
 44725 }
 44726 
 44727 $retries = 3;
 44728 while ($retries--) {
 44729 try {
 44730 $options = $this->options;
 44731 if ($this->eventDispatcher) {
 44732 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this));
 44733 $preFileDownloadEvent->setTransportOptions($this->options);
 44734 $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
 44735 $filename = $preFileDownloadEvent->getProcessedUrl();
 44736 $options = $preFileDownloadEvent->getTransportOptions();
 44737 }
 44738 
 44739 $response = $this->httpDownloader->get($filename, $options);
 44740 $json = (string) $response->getBody();
 44741 if ($sha256 && $sha256 !== hash('sha256', $json)) {
 44742 
 44743 if ($this->allowSslDowngrade) {
 44744 $this->url = str_replace('http://', 'https://', $this->url);
 44745 $this->baseUrl = str_replace('http://', 'https://', $this->baseUrl);
 44746 $filename = str_replace('http://', 'https://', $filename);
 44747 }
 44748 
 44749 if ($retries > 0) {
 44750 usleep(100000);
 44751 
 44752 continue;
 44753 }
 44754 
 44755 
 44756 throw new RepositorySecurityException('The contents of '.$filename.' do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.');
 44757 }
 44758 
 44759 if ($this->eventDispatcher) {
 44760 $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, $sha256, $filename, 'metadata', array('response' => $response, 'repository' => $this));
 44761 $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
 44762 }
 44763 
 44764 $data = $response->decodeJson();
 44765 HttpDownloader::outputWarnings($this->io, $this->url, $data);
 44766 
 44767 if ($cacheKey && !$this->cache->isReadOnly()) {
 44768 if ($storeLastModifiedTime) {
 44769 $lastModifiedDate = $response->getHeader('last-modified');
 44770 if ($lastModifiedDate) {
 44771 $data['last-modified'] = $lastModifiedDate;
 44772 $json = JsonFile::encode($data, 0);
 44773 }
 44774 }
 44775 $this->cache->write($cacheKey, $json);
 44776 }
 44777 
 44778 $response->collect();
 44779 
 44780 break;
 44781 } catch (\Exception $e) {
 44782 if ($e instanceof \LogicException) {
 44783 throw $e;
 44784 }
 44785 
 44786 if ($e instanceof TransportException && $e->getStatusCode() === 404) {
 44787 throw $e;
 44788 }
 44789 
 44790 if ($e instanceof RepositorySecurityException) {
 44791 throw $e;
 44792 }
 44793 
 44794 if ($cacheKey && ($contents = $this->cache->read($cacheKey))) {
 44795 if (!$this->degradedMode) {
 44796 $this->io->writeError('<warning>'.$this->url.' could not be fully loaded ('.$e->getMessage().'), package information was loaded from the local cache and may be out of date</warning>');
 44797 }
 44798 $this->degradedMode = true;
 44799 $data = JsonFile::parseJson($contents, $this->cache->getRoot().$cacheKey);
 44800 
 44801 break;
 44802 }
 44803 
 44804 throw $e;
 44805 }
 44806 }
 44807 
 44808 if (!isset($data)) {
 44809 throw new \LogicException("ComposerRepository: Undefined \$data. Please report at https://github.com/composer/composer/issues/new.");
 44810 }
 44811 
 44812 return $data;
 44813 }
 44814 
 44815 
 44816 
 44817 
 44818 
 44819 
 44820 
 44821 
 44822 private function fetchFileIfLastModified($filename, $cacheKey, $lastModifiedTime)
 44823 {
 44824 try {
 44825 $options = $this->options;
 44826 if ($this->eventDispatcher) {
 44827 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this));
 44828 $preFileDownloadEvent->setTransportOptions($this->options);
 44829 $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
 44830 $filename = $preFileDownloadEvent->getProcessedUrl();
 44831 $options = $preFileDownloadEvent->getTransportOptions();
 44832 }
 44833 
 44834 if (isset($options['http']['header'])) {
 44835 $options['http']['header'] = (array) $options['http']['header'];
 44836 }
 44837 $options['http']['header'][] = 'If-Modified-Since: '.$lastModifiedTime;
 44838 $response = $this->httpDownloader->get($filename, $options);
 44839 $json = (string) $response->getBody();
 44840 if ($json === '' && $response->getStatusCode() === 304) {
 44841 return true;
 44842 }
 44843 
 44844 if ($this->eventDispatcher) {
 44845 $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', array('response' => $response, 'repository' => $this));
 44846 $this->eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
 44847 }
 44848 
 44849 $data = $response->decodeJson();
 44850 HttpDownloader::outputWarnings($this->io, $this->url, $data);
 44851 
 44852 $lastModifiedDate = $response->getHeader('last-modified');
 44853 $response->collect();
 44854 if ($lastModifiedDate) {
 44855 $data['last-modified'] = $lastModifiedDate;
 44856 $json = JsonFile::encode($data, 0);
 44857 }
 44858 if (!$this->cache->isReadOnly()) {
 44859 $this->cache->write($cacheKey, $json);
 44860 }
 44861 
 44862 return $data;
 44863 } catch (\Exception $e) {
 44864 if ($e instanceof \LogicException) {
 44865 throw $e;
 44866 }
 44867 
 44868 if ($e instanceof TransportException && $e->getStatusCode() === 404) {
 44869 throw $e;
 44870 }
 44871 
 44872 if (!$this->degradedMode) {
 44873 $this->io->writeError('<warning>'.$this->url.' could not be fully loaded ('.$e->getMessage().'), package information was loaded from the local cache and may be out of date</warning>');
 44874 }
 44875 $this->degradedMode = true;
 44876 
 44877 return true;
 44878 }
 44879 }
 44880 
 44881 
 44882 
 44883 
 44884 
 44885 
 44886 
 44887 
 44888 private function asyncFetchFile($filename, $cacheKey, $lastModifiedTime = null)
 44889 {
 44890 if (isset($this->packagesNotFoundCache[$filename])) {
 44891 return \React\Promise\resolve(array('packages' => array()));
 44892 }
 44893 
 44894 if (isset($this->freshMetadataUrls[$filename]) && $lastModifiedTime) {
 44895 
 44896 return \React\Promise\resolve(true);
 44897 }
 44898 
 44899 $httpDownloader = $this->httpDownloader;
 44900 $options = $this->options;
 44901 if ($this->eventDispatcher) {
 44902 $preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->httpDownloader, $filename, 'metadata', array('repository' => $this));
 44903 $preFileDownloadEvent->setTransportOptions($this->options);
 44904 $this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
 44905 $filename = $preFileDownloadEvent->getProcessedUrl();
 44906 $options = $preFileDownloadEvent->getTransportOptions();
 44907 }
 44908 
 44909 if ($lastModifiedTime) {
 44910 if (isset($options['http']['header'])) {
 44911 $options['http']['header'] = (array) $options['http']['header'];
 44912 }
 44913 $options['http']['header'][] = 'If-Modified-Since: '.$lastModifiedTime;
 44914 }
 44915 
 44916 $io = $this->io;
 44917 $url = $this->url;
 44918 $cache = $this->cache;
 44919 $degradedMode = &$this->degradedMode;
 44920 $eventDispatcher = $this->eventDispatcher;
 44921 $repo = $this;
 44922 
 44923 $accept = function ($response) use ($io, $url, $filename, $cache, $cacheKey, $eventDispatcher, $repo) {
 44924 
 44925 if ($response->getStatusCode() === 404) {
 44926 $repo->packagesNotFoundCache[$filename] = true;
 44927 
 44928 return array('packages' => array());
 44929 }
 44930 
 44931 $json = (string) $response->getBody();
 44932 if ($json === '' && $response->getStatusCode() === 304) {
 44933 $repo->freshMetadataUrls[$filename] = true;
 44934 
 44935 return true;
 44936 }
 44937 
 44938 if ($eventDispatcher) {
 44939 $postFileDownloadEvent = new PostFileDownloadEvent(PluginEvents::POST_FILE_DOWNLOAD, null, null, $filename, 'metadata', array('response' => $response, 'repository' => $repo));
 44940 $eventDispatcher->dispatch($postFileDownloadEvent->getName(), $postFileDownloadEvent);
 44941 }
 44942 
 44943 $data = $response->decodeJson();
 44944 HttpDownloader::outputWarnings($io, $url, $data);
 44945 
 44946 $lastModifiedDate = $response->getHeader('last-modified');
 44947 $response->collect();
 44948 if ($lastModifiedDate) {
 44949 $data['last-modified'] = $lastModifiedDate;
 44950 $json = JsonFile::encode($data, JsonFile::JSON_UNESCAPED_SLASHES | JsonFile::JSON_UNESCAPED_UNICODE);
 44951 }
 44952 if (!$cache->isReadOnly()) {
 44953 $cache->write($cacheKey, $json);
 44954 }
 44955 $repo->freshMetadataUrls[$filename] = true;
 44956 
 44957 return $data;
 44958 };
 44959 
 44960 $reject = function ($e) use ($filename, $accept, $io, $url, &$degradedMode, $repo, $lastModifiedTime) {
 44961 if ($e instanceof TransportException && $e->getStatusCode() === 404) {
 44962 $repo->packagesNotFoundCache[$filename] = true;
 44963 
 44964 return false;
 44965 }
 44966 
 44967 if (!$degradedMode) {
 44968 $io->writeError('<warning>'.$url.' could not be fully loaded ('.$e->getMessage().'), package information was loaded from the local cache and may be out of date</warning>');
 44969 }
 44970 $degradedMode = true;
 44971 
 44972 
 44973 if ($lastModifiedTime) {
 44974 return $accept(new Response(array('url' => $url), 304, array(), ''));
 44975 }
 44976 
 44977 
 44978 if ($e instanceof TransportException && $e->getStatusCode() === 499) {
 44979 return $accept(new Response(array('url' => $url), 404, array(), ''));
 44980 }
 44981 
 44982 throw $e;
 44983 };
 44984 
 44985 return $httpDownloader->add($filename, $options)->then($accept, $reject);
 44986 }
 44987 
 44988 
 44989 
 44990 
 44991 
 44992 
 44993 
 44994 
 44995 private function initializePartialPackages()
 44996 {
 44997 $rootData = $this->loadRootServerFile();
 44998 
 44999 $this->partialPackagesByName = array();
 45000 foreach ($rootData['packages'] as $package => $versions) {
 45001 foreach ($versions as $version) {
 45002 $this->partialPackagesByName[strtolower($version['name'])][] = $version;
 45003 }
 45004 }
 45005 
 45006 
 45007 $this->rootData = true;
 45008 }
 45009 
 45010 
 45011 
 45012 
 45013 
 45014 
 45015 
 45016 protected function lazyProvidersRepoContains($name)
 45017 {
 45018 if (!$this->hasAvailablePackageList) {
 45019 throw new \LogicException('lazyProvidersRepoContains should not be called unless hasAvailablePackageList is true');
 45020 }
 45021 
 45022 if (is_array($this->availablePackages) && isset($this->availablePackages[$name])) {
 45023 return true;
 45024 }
 45025 
 45026 if (is_array($this->availablePackagePatterns)) {
 45027 foreach ($this->availablePackagePatterns as $providerRegex) {
 45028 if (Preg::isMatch($providerRegex, $name)) {
 45029 return true;
 45030 }
 45031 }
 45032 }
 45033 
 45034 return false;
 45035 }
 45036 }
 45037 <?php
 45038 
 45039 
 45040 
 45041 
 45042 
 45043 
 45044 
 45045 
 45046 
 45047 
 45048 
 45049 namespace Composer\Repository;
 45050 
 45051 use Composer\Package\PackageInterface;
 45052 
 45053 
 45054 
 45055 
 45056 
 45057 
 45058 class CompositeRepository implements RepositoryInterface
 45059 {
 45060 
 45061 
 45062 
 45063 
 45064 private $repositories;
 45065 
 45066 
 45067 
 45068 
 45069 
 45070 public function __construct(array $repositories)
 45071 {
 45072 $this->repositories = array();
 45073 foreach ($repositories as $repo) {
 45074 $this->addRepository($repo);
 45075 }
 45076 }
 45077 
 45078 public function getRepoName()
 45079 {
 45080 return 'composite repo ('.implode(', ', array_map(function ($repo) {
 45081 return $repo->getRepoName();
 45082 }, $this->repositories)).')';
 45083 }
 45084 
 45085 
 45086 
 45087 
 45088 
 45089 
 45090 public function getRepositories()
 45091 {
 45092 return $this->repositories;
 45093 }
 45094 
 45095 
 45096 
 45097 
 45098 public function hasPackage(PackageInterface $package)
 45099 {
 45100 foreach ($this->repositories as $repository) {
 45101 
 45102 if ($repository->hasPackage($package)) {
 45103 return true;
 45104 }
 45105 }
 45106 
 45107 return false;
 45108 }
 45109 
 45110 
 45111 
 45112 
 45113 public function findPackage($name, $constraint)
 45114 {
 45115 foreach ($this->repositories as $repository) {
 45116 
 45117 $package = $repository->findPackage($name, $constraint);
 45118 if (null !== $package) {
 45119 return $package;
 45120 }
 45121 }
 45122 
 45123 return null;
 45124 }
 45125 
 45126 
 45127 
 45128 
 45129 public function findPackages($name, $constraint = null)
 45130 {
 45131 $packages = array();
 45132 foreach ($this->repositories as $repository) {
 45133 
 45134 $packages[] = $repository->findPackages($name, $constraint);
 45135 }
 45136 
 45137 return $packages ? call_user_func_array('array_merge', $packages) : array();
 45138 }
 45139 
 45140 
 45141 
 45142 
 45143 public function loadPackages(array $packageMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array())
 45144 {
 45145 $packages = array();
 45146 $namesFound = array();
 45147 foreach ($this->repositories as $repository) {
 45148 
 45149 $result = $repository->loadPackages($packageMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded);
 45150 $packages[] = $result['packages'];
 45151 $namesFound[] = $result['namesFound'];
 45152 }
 45153 
 45154 return array(
 45155 'packages' => $packages ? call_user_func_array('array_merge', $packages) : array(),
 45156 'namesFound' => $namesFound ? array_unique(call_user_func_array('array_merge', $namesFound)) : array(),
 45157 );
 45158 }
 45159 
 45160 
 45161 
 45162 
 45163 public function search($query, $mode = 0, $type = null)
 45164 {
 45165 $matches = array();
 45166 foreach ($this->repositories as $repository) {
 45167 
 45168 $matches[] = $repository->search($query, $mode, $type);
 45169 }
 45170 
 45171 return $matches ? call_user_func_array('array_merge', $matches) : array();
 45172 }
 45173 
 45174 
 45175 
 45176 
 45177 public function getPackages()
 45178 {
 45179 $packages = array();
 45180 foreach ($this->repositories as $repository) {
 45181 
 45182 $packages[] = $repository->getPackages();
 45183 }
 45184 
 45185 return $packages ? call_user_func_array('array_merge', $packages) : array();
 45186 }
 45187 
 45188 
 45189 
 45190 
 45191 public function getProviders($packageName)
 45192 {
 45193 $results = array();
 45194 foreach ($this->repositories as $repository) {
 45195 
 45196 $results[] = $repository->getProviders($packageName);
 45197 }
 45198 
 45199 return $results ? call_user_func_array('array_merge', $results) : array();
 45200 }
 45201 
 45202 
 45203 
 45204 
 45205 public function removePackage(PackageInterface $package)
 45206 {
 45207 foreach ($this->repositories as $repository) {
 45208 if ($repository instanceof WritableRepositoryInterface) {
 45209 $repository->removePackage($package);
 45210 }
 45211 }
 45212 }
 45213 
 45214 
 45215 
 45216 
 45217 #[\ReturnTypeWillChange]
 45218 public function count()
 45219 {
 45220 $total = 0;
 45221 foreach ($this->repositories as $repository) {
 45222 
 45223 $total += $repository->count();
 45224 }
 45225 
 45226 return $total;
 45227 }
 45228 
 45229 
 45230 
 45231 
 45232 
 45233 
 45234 
 45235 public function addRepository(RepositoryInterface $repository)
 45236 {
 45237 if ($repository instanceof self) {
 45238 foreach ($repository->getRepositories() as $repo) {
 45239 $this->addRepository($repo);
 45240 }
 45241 } else {
 45242 $this->repositories[] = $repository;
 45243 }
 45244 }
 45245 }
 45246 <?php
 45247 
 45248 
 45249 
 45250 
 45251 
 45252 
 45253 
 45254 
 45255 
 45256 
 45257 
 45258 namespace Composer\Repository;
 45259 
 45260 
 45261 
 45262 
 45263 
 45264 
 45265 interface ConfigurableRepositoryInterface
 45266 {
 45267 
 45268 
 45269 
 45270 public function getRepoConfig();
 45271 }
 45272 <?php
 45273 
 45274 
 45275 
 45276 
 45277 
 45278 
 45279 
 45280 
 45281 
 45282 
 45283 
 45284 namespace Composer\Repository;
 45285 
 45286 use Composer\Json\JsonFile;
 45287 use Composer\Package\Loader\ArrayLoader;
 45288 use Composer\Package\RootPackageInterface;
 45289 use Composer\Package\AliasPackage;
 45290 use Composer\Package\Dumper\ArrayDumper;
 45291 use Composer\Installer\InstallationManager;
 45292 use Composer\Util\Filesystem;
 45293 
 45294 
 45295 
 45296 
 45297 
 45298 
 45299 
 45300 class FilesystemRepository extends WritableArrayRepository
 45301 {
 45302 
 45303 protected $file;
 45304 
 45305 private $dumpVersions;
 45306 
 45307 private $rootPackage;
 45308 
 45309 private $filesystem;
 45310 
 45311 private $devMode = null;
 45312 
 45313 
 45314 
 45315 
 45316 
 45317 
 45318 
 45319 
 45320 public function __construct(JsonFile $repositoryFile, $dumpVersions = false, RootPackageInterface $rootPackage = null, Filesystem $filesystem = null)
 45321 {
 45322 parent::__construct();
 45323 $this->file = $repositoryFile;
 45324 $this->dumpVersions = $dumpVersions;
 45325 $this->rootPackage = $rootPackage;
 45326 $this->filesystem = $filesystem ?: new Filesystem;
 45327 if ($dumpVersions && !$rootPackage) {
 45328 throw new \InvalidArgumentException('Expected a root package instance if $dumpVersions is true');
 45329 }
 45330 }
 45331 
 45332 
 45333 
 45334 
 45335 public function getDevMode()
 45336 {
 45337 return $this->devMode;
 45338 }
 45339 
 45340 
 45341 
 45342 
 45343 protected function initialize()
 45344 {
 45345 parent::initialize();
 45346 
 45347 if (!$this->file->exists()) {
 45348 return;
 45349 }
 45350 
 45351 try {
 45352 $data = $this->file->read();
 45353 if (isset($data['packages'])) {
 45354 $packages = $data['packages'];
 45355 } else {
 45356 $packages = $data;
 45357 }
 45358 
 45359 if (isset($data['dev-package-names'])) {
 45360 $this->setDevPackageNames($data['dev-package-names']);
 45361 }
 45362 if (isset($data['dev'])) {
 45363 $this->devMode = $data['dev'];
 45364 }
 45365 
 45366 if (!is_array($packages)) {
 45367 throw new \UnexpectedValueException('Could not parse package list from the repository');
 45368 }
 45369 } catch (\Exception $e) {
 45370 throw new InvalidRepositoryException('Invalid repository data in '.$this->file->getPath().', packages could not be loaded: ['.get_class($e).'] '.$e->getMessage());
 45371 }
 45372 
 45373 $loader = new ArrayLoader(null, true);
 45374 foreach ($packages as $packageData) {
 45375 $package = $loader->load($packageData);
 45376 $this->addPackage($package);
 45377 }
 45378 }
 45379 
 45380 public function reload()
 45381 {
 45382 $this->packages = null;
 45383 $this->initialize();
 45384 }
 45385 
 45386 
 45387 
 45388 
 45389 public function write($devMode, InstallationManager $installationManager)
 45390 {
 45391 $data = array('packages' => array(), 'dev' => $devMode, 'dev-package-names' => array());
 45392 $dumper = new ArrayDumper();
 45393 
 45394 
 45395 
 45396 
 45397 $repoDir = dirname($this->file->getPath());
 45398 $this->filesystem->ensureDirectoryExists($repoDir);
 45399 
 45400 $repoDir = $this->filesystem->normalizePath(realpath($repoDir));
 45401 $installPaths = array();
 45402 
 45403 foreach ($this->getCanonicalPackages() as $package) {
 45404 $pkgArray = $dumper->dump($package);
 45405 $path = $installationManager->getInstallPath($package);
 45406 $installPath = null;
 45407 if ('' !== $path && null !== $path) {
 45408 $normalizedPath = $this->filesystem->normalizePath($this->filesystem->isAbsolutePath($path) ? $path : getcwd() . '/' . $path);
 45409 $installPath = $this->filesystem->findShortestPath($repoDir, $normalizedPath, true);
 45410 }
 45411 $installPaths[$package->getName()] = $installPath;
 45412 
 45413 $pkgArray['install-path'] = $installPath;
 45414 $data['packages'][] = $pkgArray;
 45415 
 45416 
 45417 
 45418 if (in_array($package->getName(), $this->devPackageNames, true)) {
 45419 $data['dev-package-names'][] = $package->getName();
 45420 }
 45421 }
 45422 
 45423 sort($data['dev-package-names']);
 45424 usort($data['packages'], function ($a, $b) {
 45425 return strcmp($a['name'], $b['name']);
 45426 });
 45427 
 45428 $this->file->write($data);
 45429 
 45430 if ($this->dumpVersions) {
 45431 $versions = $this->generateInstalledVersions($installationManager, $installPaths, $devMode, $repoDir);
 45432 
 45433 $this->filesystem->filePutContentsIfModified($repoDir.'/installed.php', '<?php return ' . $this->dumpToPhpCode($versions) . ';'."\n");
 45434 $installedVersionsClass = file_get_contents(__DIR__.'/../InstalledVersions.php');
 45435 $this->filesystem->filePutContentsIfModified($repoDir.'/InstalledVersions.php', $installedVersionsClass);
 45436 
 45437 \Composer\InstalledVersions::reload($versions);
 45438 }
 45439 }
 45440 
 45441 
 45442 
 45443 
 45444 
 45445 
 45446 
 45447 private function dumpToPhpCode(array $array = array(), $level = 0)
 45448 {
 45449 $lines = "array(\n";
 45450 $level++;
 45451 
 45452 foreach ($array as $key => $value) {
 45453 $lines .= str_repeat('    ', $level);
 45454 $lines .= is_int($key) ? $key . ' => ' : '\'' . $key . '\' => ';
 45455 
 45456 if (is_array($value)) {
 45457 if (!empty($value)) {
 45458 $lines .= $this->dumpToPhpCode($value, $level);
 45459 } else {
 45460 $lines .= "array(),\n";
 45461 }
 45462 } elseif ($key === 'install_path' && is_string($value)) {
 45463 if ($this->filesystem->isAbsolutePath($value)) {
 45464 $lines .= var_export($value, true) . ",\n";
 45465 } else {
 45466 $lines .= "__DIR__ . " . var_export('/' . $value, true) . ",\n";
 45467 }
 45468 } else {
 45469 $lines .= var_export($value, true) . ",\n";
 45470 }
 45471 }
 45472 
 45473 $lines .= str_repeat('    ', $level - 1) . ')' . ($level - 1 == 0 ? '' : ",\n");
 45474 
 45475 return $lines;
 45476 }
 45477 
 45478 
 45479 
 45480 
 45481 
 45482 
 45483 
 45484 
 45485 private function generateInstalledVersions(InstallationManager $installationManager, array $installPaths, $devMode, $repoDir)
 45486 {
 45487 if (!$this->dumpVersions) {
 45488 return null;
 45489 }
 45490 
 45491 $devPackages = array_flip($this->devPackageNames);
 45492 $versions = array('versions' => array());
 45493 $packages = $this->getPackages();
 45494 $packages[] = $rootPackage = $this->rootPackage;
 45495 while ($rootPackage instanceof AliasPackage) {
 45496 $rootPackage = $rootPackage->getAliasOf();
 45497 $packages[] = $rootPackage;
 45498 }
 45499 
 45500 
 45501 foreach ($packages as $package) {
 45502 if ($package instanceof AliasPackage) {
 45503 continue;
 45504 }
 45505 
 45506 $reference = null;
 45507 if ($package->getInstallationSource()) {
 45508 $reference = $package->getInstallationSource() === 'source' ? $package->getSourceReference() : $package->getDistReference();
 45509 }
 45510 if (null === $reference) {
 45511 $reference = ($package->getSourceReference() ?: $package->getDistReference()) ?: null;
 45512 }
 45513 
 45514 if ($package instanceof RootPackageInterface) {
 45515 $to = $this->filesystem->normalizePath(realpath(getcwd()));
 45516 $installPath = $this->filesystem->findShortestPath($repoDir, $to, true);
 45517 } else {
 45518 $installPath = $installPaths[$package->getName()];
 45519 }
 45520 
 45521 $versions['versions'][$package->getName()] = array(
 45522 'pretty_version' => $package->getPrettyVersion(),
 45523 'version' => $package->getVersion(),
 45524 'type' => $package->getType(),
 45525 'install_path' => $installPath,
 45526 'aliases' => array(),
 45527 'reference' => $reference,
 45528 'dev_requirement' => isset($devPackages[$package->getName()]),
 45529 );
 45530 if ($package instanceof RootPackageInterface) {
 45531 $versions['root'] = $versions['versions'][$package->getName()];
 45532 unset($versions['root']['dev_requirement']);
 45533 $versions['root']['name'] = $package->getName();
 45534 $versions['root']['dev'] = $devMode;
 45535 }
 45536 }
 45537 
 45538 
 45539 foreach ($packages as $package) {
 45540 $isDevPackage = isset($devPackages[$package->getName()]);
 45541 foreach ($package->getReplaces() as $replace) {
 45542 
 45543 if (PlatformRepository::isPlatformPackage($replace->getTarget())) {
 45544 continue;
 45545 }
 45546 if (!isset($versions['versions'][$replace->getTarget()]['dev_requirement'])) {
 45547 $versions['versions'][$replace->getTarget()]['dev_requirement'] = $isDevPackage;
 45548 } elseif (!$isDevPackage) {
 45549 $versions['versions'][$replace->getTarget()]['dev_requirement'] = false;
 45550 }
 45551 $replaced = $replace->getPrettyConstraint();
 45552 if ($replaced === 'self.version') {
 45553 $replaced = $package->getPrettyVersion();
 45554 }
 45555 if (!isset($versions['versions'][$replace->getTarget()]['replaced']) || !in_array($replaced, $versions['versions'][$replace->getTarget()]['replaced'], true)) {
 45556 $versions['versions'][$replace->getTarget()]['replaced'][] = $replaced;
 45557 }
 45558 }
 45559 foreach ($package->getProvides() as $provide) {
 45560 
 45561 if (PlatformRepository::isPlatformPackage($provide->getTarget())) {
 45562 continue;
 45563 }
 45564 if (!isset($versions['versions'][$provide->getTarget()]['dev_requirement'])) {
 45565 $versions['versions'][$provide->getTarget()]['dev_requirement'] = $isDevPackage;
 45566 } elseif (!$isDevPackage) {
 45567 $versions['versions'][$provide->getTarget()]['dev_requirement'] = false;
 45568 }
 45569 $provided = $provide->getPrettyConstraint();
 45570 if ($provided === 'self.version') {
 45571 $provided = $package->getPrettyVersion();
 45572 }
 45573 if (!isset($versions['versions'][$provide->getTarget()]['provided']) || !in_array($provided, $versions['versions'][$provide->getTarget()]['provided'], true)) {
 45574 $versions['versions'][$provide->getTarget()]['provided'][] = $provided;
 45575 }
 45576 }
 45577 }
 45578 
 45579 
 45580 foreach ($packages as $package) {
 45581 if (!$package instanceof AliasPackage) {
 45582 continue;
 45583 }
 45584 $versions['versions'][$package->getName()]['aliases'][] = $package->getPrettyVersion();
 45585 if ($package instanceof RootPackageInterface) {
 45586 $versions['root']['aliases'][] = $package->getPrettyVersion();
 45587 }
 45588 }
 45589 
 45590 ksort($versions['versions']);
 45591 ksort($versions);
 45592 
 45593 return $versions;
 45594 }
 45595 }
 45596 <?php
 45597 
 45598 
 45599 
 45600 
 45601 
 45602 
 45603 
 45604 
 45605 
 45606 
 45607 
 45608 namespace Composer\Repository;
 45609 
 45610 use Composer\Package\PackageInterface;
 45611 use Composer\Package\BasePackage;
 45612 use Composer\Pcre\Preg;
 45613 
 45614 
 45615 
 45616 
 45617 
 45618 
 45619 class FilterRepository implements RepositoryInterface
 45620 {
 45621 
 45622 private $only = null;
 45623 
 45624 private $exclude = null;
 45625 
 45626 private $canonical = true;
 45627 
 45628 private $repo;
 45629 
 45630 
 45631 
 45632 
 45633 public function __construct(RepositoryInterface $repo, array $options)
 45634 {
 45635 if (isset($options['only'])) {
 45636 if (!is_array($options['only'])) {
 45637 throw new \InvalidArgumentException('"only" key for repository '.$repo->getRepoName().' should be an array');
 45638 }
 45639 $this->only = BasePackage::packageNamesToRegexp($options['only']);
 45640 }
 45641 if (isset($options['exclude'])) {
 45642 if (!is_array($options['exclude'])) {
 45643 throw new \InvalidArgumentException('"exclude" key for repository '.$repo->getRepoName().' should be an array');
 45644 }
 45645 $this->exclude = BasePackage::packageNamesToRegexp($options['exclude']);
 45646 }
 45647 if ($this->exclude && $this->only) {
 45648 throw new \InvalidArgumentException('Only one of "only" and "exclude" can be specified for repository '.$repo->getRepoName());
 45649 }
 45650 if (isset($options['canonical'])) {
 45651 if (!is_bool($options['canonical'])) {
 45652 throw new \InvalidArgumentException('"canonical" key for repository '.$repo->getRepoName().' should be a boolean');
 45653 }
 45654 $this->canonical = $options['canonical'];
 45655 }
 45656 
 45657 $this->repo = $repo;
 45658 }
 45659 
 45660 public function getRepoName()
 45661 {
 45662 return $this->repo->getRepoName();
 45663 }
 45664 
 45665 
 45666 
 45667 
 45668 
 45669 
 45670 public function getRepository()
 45671 {
 45672 return $this->repo;
 45673 }
 45674 
 45675 
 45676 
 45677 
 45678 public function hasPackage(PackageInterface $package)
 45679 {
 45680 return $this->repo->hasPackage($package);
 45681 }
 45682 
 45683 
 45684 
 45685 
 45686 public function findPackage($name, $constraint)
 45687 {
 45688 if (!$this->isAllowed($name)) {
 45689 return null;
 45690 }
 45691 
 45692 return $this->repo->findPackage($name, $constraint);
 45693 }
 45694 
 45695 
 45696 
 45697 
 45698 public function findPackages($name, $constraint = null)
 45699 {
 45700 if (!$this->isAllowed($name)) {
 45701 return array();
 45702 }
 45703 
 45704 return $this->repo->findPackages($name, $constraint);
 45705 }
 45706 
 45707 
 45708 
 45709 
 45710 public function loadPackages(array $packageMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array())
 45711 {
 45712 foreach ($packageMap as $name => $constraint) {
 45713 if (!$this->isAllowed($name)) {
 45714 unset($packageMap[$name]);
 45715 }
 45716 }
 45717 
 45718 if (!$packageMap) {
 45719 return array('namesFound' => array(), 'packages' => array());
 45720 }
 45721 
 45722 $result = $this->repo->loadPackages($packageMap, $acceptableStabilities, $stabilityFlags, $alreadyLoaded);
 45723 if (!$this->canonical) {
 45724 $result['namesFound'] = array();
 45725 }
 45726 
 45727 return $result;
 45728 }
 45729 
 45730 
 45731 
 45732 
 45733 public function search($query, $mode = 0, $type = null)
 45734 {
 45735 $result = array();
 45736 
 45737 foreach ($this->repo->search($query, $mode, $type) as $package) {
 45738 if ($this->isAllowed($package['name'])) {
 45739 $result[] = $package;
 45740 }
 45741 }
 45742 
 45743 return $result;
 45744 }
 45745 
 45746 
 45747 
 45748 
 45749 public function getPackages()
 45750 {
 45751 $result = array();
 45752 foreach ($this->repo->getPackages() as $package) {
 45753 if ($this->isAllowed($package->getName())) {
 45754 $result[] = $package;
 45755 }
 45756 }
 45757 
 45758 return $result;
 45759 }
 45760 
 45761 
 45762 
 45763 
 45764 public function getProviders($packageName)
 45765 {
 45766 $result = array();
 45767 foreach ($this->repo->getProviders($packageName) as $name => $provider) {
 45768 if ($this->isAllowed($provider['name'])) {
 45769 $result[$name] = $provider;
 45770 }
 45771 }
 45772 
 45773 return $result;
 45774 }
 45775 
 45776 
 45777 
 45778 
 45779 #[\ReturnTypeWillChange]
 45780 public function count()
 45781 {
 45782 if ($this->repo->count() > 0) {
 45783 return count($this->getPackages());
 45784 }
 45785 
 45786 return 0;
 45787 }
 45788 
 45789 
 45790 
 45791 
 45792 
 45793 
 45794 private function isAllowed($name)
 45795 {
 45796 if (!$this->only && !$this->exclude) {
 45797 return true;
 45798 }
 45799 
 45800 if ($this->only) {
 45801 return Preg::isMatch($this->only, $name);
 45802 }
 45803 
 45804 if ($this->exclude === null) {
 45805 return true;
 45806 }
 45807 
 45808 return !Preg::isMatch($this->exclude, $name);
 45809 }
 45810 }
 45811 <?php
 45812 
 45813 
 45814 
 45815 
 45816 
 45817 
 45818 
 45819 
 45820 
 45821 
 45822 
 45823 namespace Composer\Repository;
 45824 
 45825 
 45826 
 45827 
 45828 
 45829 
 45830 
 45831 
 45832 class InstalledArrayRepository extends WritableArrayRepository implements InstalledRepositoryInterface
 45833 {
 45834 public function getRepoName()
 45835 {
 45836 return 'installed '.parent::getRepoName();
 45837 }
 45838 
 45839 
 45840 
 45841 
 45842 public function isFresh()
 45843 {
 45844 
 45845 
 45846 return $this->count() === 0;
 45847 }
 45848 }
 45849 <?php
 45850 
 45851 
 45852 
 45853 
 45854 
 45855 
 45856 
 45857 
 45858 
 45859 
 45860 
 45861 namespace Composer\Repository;
 45862 
 45863 
 45864 
 45865 
 45866 
 45867 
 45868 class InstalledFilesystemRepository extends FilesystemRepository implements InstalledRepositoryInterface
 45869 {
 45870 public function getRepoName()
 45871 {
 45872 return 'installed '.parent::getRepoName();
 45873 }
 45874 
 45875 
 45876 
 45877 
 45878 public function isFresh()
 45879 {
 45880 return !$this->file->exists();
 45881 }
 45882 }
 45883 <?php
 45884 
 45885 
 45886 
 45887 
 45888 
 45889 
 45890 
 45891 
 45892 
 45893 
 45894 
 45895 namespace Composer\Repository;
 45896 
 45897 use Composer\Package\BasePackage;
 45898 use Composer\Package\PackageInterface;
 45899 use Composer\Package\Version\VersionParser;
 45900 use Composer\Semver\Constraint\ConstraintInterface;
 45901 use Composer\Semver\Constraint\Constraint;
 45902 use Composer\Semver\Constraint\MatchAllConstraint;
 45903 use Composer\Package\RootPackageInterface;
 45904 use Composer\Package\Link;
 45905 
 45906 
 45907 
 45908 
 45909 
 45910 
 45911 
 45912 
 45913 
 45914 
 45915 class InstalledRepository extends CompositeRepository
 45916 {
 45917 
 45918 
 45919 
 45920 
 45921 
 45922 
 45923 public function findPackagesWithReplacersAndProviders($name, $constraint = null)
 45924 {
 45925 $name = strtolower($name);
 45926 
 45927 if (null !== $constraint && !$constraint instanceof ConstraintInterface) {
 45928 $versionParser = new VersionParser();
 45929 $constraint = $versionParser->parseConstraints($constraint);
 45930 }
 45931 
 45932 $matches = array();
 45933 foreach ($this->getRepositories() as $repo) {
 45934 foreach ($repo->getPackages() as $candidate) {
 45935 if ($name === $candidate->getName()) {
 45936 if (null === $constraint || $constraint->matches(new Constraint('==', $candidate->getVersion()))) {
 45937 $matches[] = $candidate;
 45938 }
 45939 continue;
 45940 }
 45941 
 45942 foreach (array_merge($candidate->getProvides(), $candidate->getReplaces()) as $link) {
 45943 if (
 45944 $name === $link->getTarget()
 45945 && ($constraint === null || $constraint->matches($link->getConstraint()))
 45946 ) {
 45947 $matches[] = $candidate;
 45948 continue 2;
 45949 }
 45950 }
 45951 }
 45952 }
 45953 
 45954 return $matches;
 45955 }
 45956 
 45957 
 45958 
 45959 
 45960 
 45961 
 45962 
 45963 
 45964 
 45965 
 45966 
 45967 
 45968 
 45969 
 45970 
 45971 
 45972 public function getDependents($needle, $constraint = null, $invert = false, $recurse = true, $packagesFound = null)
 45973 {
 45974 $needles = array_map('strtolower', (array) $needle);
 45975 $results = array();
 45976 
 45977 
 45978 if (null === $packagesFound) {
 45979 $packagesFound = $needles;
 45980 }
 45981 
 45982 
 45983 $rootPackage = null;
 45984 foreach ($this->getPackages() as $package) {
 45985 if ($package instanceof RootPackageInterface) {
 45986 $rootPackage = $package;
 45987 break;
 45988 }
 45989 }
 45990 
 45991 
 45992 foreach ($this->getPackages() as $package) {
 45993 $links = $package->getRequires();
 45994 
 45995 
 45996 
 45997 $packagesInTree = $packagesFound;
 45998 
 45999 
 46000 if (!$invert) {
 46001 $links += $package->getReplaces();
 46002 
 46003 
 46004 
 46005 
 46006 foreach ($package->getReplaces() as $link) {
 46007 foreach ($needles as $needle) {
 46008 if ($link->getSource() === $needle) {
 46009 if ($constraint === null || ($link->getConstraint()->matches($constraint) === true)) {
 46010 
 46011 if (in_array($link->getTarget(), $packagesInTree)) {
 46012 $results[] = array($package, $link, false);
 46013 continue;
 46014 }
 46015 $packagesInTree[] = $link->getTarget();
 46016 $dependents = $recurse ? $this->getDependents($link->getTarget(), null, false, true, $packagesInTree) : array();
 46017 $results[] = array($package, $link, $dependents);
 46018 $needles[] = $link->getTarget();
 46019 }
 46020 }
 46021 }
 46022 }
 46023 }
 46024 
 46025 
 46026 if ($package instanceof RootPackageInterface) {
 46027 $links += $package->getDevRequires();
 46028 }
 46029 
 46030 
 46031 foreach ($links as $link) {
 46032 foreach ($needles as $needle) {
 46033 if ($link->getTarget() === $needle) {
 46034 if ($constraint === null || ($link->getConstraint()->matches($constraint) === !$invert)) {
 46035 
 46036 if (in_array($link->getSource(), $packagesInTree)) {
 46037 $results[] = array($package, $link, false);
 46038 continue;
 46039 }
 46040 $packagesInTree[] = $link->getSource();
 46041 $dependents = $recurse ? $this->getDependents($link->getSource(), null, false, true, $packagesInTree) : array();
 46042 $results[] = array($package, $link, $dependents);
 46043 }
 46044 }
 46045 }
 46046 }
 46047 
 46048 
 46049 if ($invert && in_array($package->getName(), $needles)) {
 46050 foreach ($package->getConflicts() as $link) {
 46051 foreach ($this->findPackages($link->getTarget()) as $pkg) {
 46052 $version = new Constraint('=', $pkg->getVersion());
 46053 if ($link->getConstraint()->matches($version) === $invert) {
 46054 $results[] = array($package, $link, false);
 46055 }
 46056 }
 46057 }
 46058 }
 46059 
 46060 
 46061 foreach ($package->getConflicts() as $link) {
 46062 if (in_array($link->getTarget(), $needles)) {
 46063 foreach ($this->findPackages($link->getTarget()) as $pkg) {
 46064 $version = new Constraint('=', $pkg->getVersion());
 46065 if ($link->getConstraint()->matches($version) === $invert) {
 46066 $results[] = array($package, $link, false);
 46067 }
 46068 }
 46069 }
 46070 }
 46071 
 46072 
 46073 if ($invert && $constraint && in_array($package->getName(), $needles) && $constraint->matches(new Constraint('=', $package->getVersion()))) {
 46074 foreach ($package->getRequires() as $link) {
 46075 if (PlatformRepository::isPlatformPackage($link->getTarget())) {
 46076 if ($this->findPackage($link->getTarget(), $link->getConstraint())) {
 46077 continue;
 46078 }
 46079 
 46080 $platformPkg = $this->findPackage($link->getTarget(), '*');
 46081 $description = $platformPkg ? 'but '.$platformPkg->getPrettyVersion().' is installed' : 'but it is missing';
 46082 $results[] = array($package, new Link($package->getName(), $link->getTarget(), new MatchAllConstraint, Link::TYPE_REQUIRE, $link->getPrettyConstraint().' '.$description), false);
 46083 
 46084 continue;
 46085 }
 46086 
 46087 foreach ($this->getPackages() as $pkg) {
 46088 if (!in_array($link->getTarget(), $pkg->getNames())) {
 46089 continue;
 46090 }
 46091 
 46092 $version = new Constraint('=', $pkg->getVersion());
 46093 
 46094 if ($link->getTarget() !== $pkg->getName()) {
 46095 foreach (array_merge($pkg->getReplaces(), $pkg->getProvides()) as $prov) {
 46096 if ($link->getTarget() === $prov->getTarget()) {
 46097 $version = $prov->getConstraint();
 46098 break;
 46099 }
 46100 }
 46101 }
 46102 
 46103 if (!$link->getConstraint()->matches($version)) {
 46104 
 46105 
 46106 if ($rootPackage) {
 46107 foreach (array_merge($rootPackage->getRequires(), $rootPackage->getDevRequires()) as $rootReq) {
 46108 if (in_array($rootReq->getTarget(), $pkg->getNames()) && !$rootReq->getConstraint()->matches($link->getConstraint())) {
 46109 $results[] = array($package, $link, false);
 46110 $results[] = array($rootPackage, $rootReq, false);
 46111 continue 3;
 46112 }
 46113 }
 46114 
 46115 $results[] = array($package, $link, false);
 46116 $results[] = array($rootPackage, new Link($rootPackage->getName(), $link->getTarget(), new MatchAllConstraint, Link::TYPE_DOES_NOT_REQUIRE, 'but ' . $pkg->getPrettyVersion() . ' is installed'), false);
 46117 } else {
 46118 
 46119 $results[] = array($package, $link, false);
 46120 }
 46121 }
 46122 
 46123 continue 2;
 46124 }
 46125 }
 46126 }
 46127 }
 46128 
 46129 ksort($results);
 46130 
 46131 return $results;
 46132 }
 46133 
 46134 public function getRepoName()
 46135 {
 46136 return 'installed repo ('.implode(', ', array_map(function ($repo) {
 46137 return $repo->getRepoName();
 46138 }, $this->getRepositories())).')';
 46139 }
 46140 
 46141 
 46142 
 46143 
 46144 public function addRepository(RepositoryInterface $repository)
 46145 {
 46146 if (
 46147 $repository instanceof LockArrayRepository
 46148 || $repository instanceof InstalledRepositoryInterface
 46149 || $repository instanceof RootPackageRepository
 46150 || $repository instanceof PlatformRepository
 46151 ) {
 46152 parent::addRepository($repository);
 46153 
 46154 return;
 46155 }
 46156 
 46157 throw new \LogicException('An InstalledRepository can not contain a repository of type '.get_class($repository).' ('.$repository->getRepoName().')');
 46158 }
 46159 }
 46160 <?php
 46161 
 46162 
 46163 
 46164 
 46165 
 46166 
 46167 
 46168 
 46169 
 46170 
 46171 
 46172 namespace Composer\Repository;
 46173 
 46174 
 46175 
 46176 
 46177 
 46178 
 46179 
 46180 
 46181 interface InstalledRepositoryInterface extends WritableRepositoryInterface
 46182 {
 46183 
 46184 
 46185 
 46186 public function getDevMode();
 46187 
 46188 
 46189 
 46190 
 46191 public function isFresh();
 46192 }
 46193 <?php
 46194 
 46195 
 46196 
 46197 
 46198 
 46199 
 46200 
 46201 
 46202 
 46203 
 46204 
 46205 namespace Composer\Repository;
 46206 
 46207 
 46208 
 46209 
 46210 
 46211 
 46212 class InvalidRepositoryException extends \Exception
 46213 {
 46214 }
 46215 <?php
 46216 
 46217 
 46218 
 46219 
 46220 
 46221 
 46222 
 46223 
 46224 
 46225 
 46226 
 46227 namespace Composer\Repository;
 46228 
 46229 
 46230 
 46231 
 46232 
 46233 
 46234 
 46235 
 46236 class LockArrayRepository extends ArrayRepository
 46237 {
 46238 public function getRepoName()
 46239 {
 46240 return 'lock repo';
 46241 }
 46242 }
 46243 <?php
 46244 
 46245 
 46246 
 46247 
 46248 
 46249 
 46250 
 46251 
 46252 
 46253 
 46254 
 46255 namespace Composer\Repository;
 46256 
 46257 use Composer\Package\Loader\ArrayLoader;
 46258 use Composer\Package\Loader\ValidatingArrayLoader;
 46259 use Composer\Pcre\Preg;
 46260 
 46261 
 46262 
 46263 
 46264 
 46265 
 46266 class PackageRepository extends ArrayRepository
 46267 {
 46268 
 46269 private $config;
 46270 
 46271 
 46272 
 46273 
 46274 
 46275 
 46276 public function __construct(array $config)
 46277 {
 46278 parent::__construct();
 46279 $this->config = $config['package'];
 46280 
 46281 
 46282 if (!is_numeric(key($this->config))) {
 46283 $this->config = array($this->config);
 46284 }
 46285 }
 46286 
 46287 
 46288 
 46289 
 46290 protected function initialize()
 46291 {
 46292 parent::initialize();
 46293 
 46294 $loader = new ValidatingArrayLoader(new ArrayLoader(null, true), true);
 46295 foreach ($this->config as $package) {
 46296 try {
 46297 $package = $loader->load($package);
 46298 } catch (\Exception $e) {
 46299 throw new InvalidRepositoryException('A repository of type "package" contains an invalid package definition: '.$e->getMessage()."\n\nInvalid package definition:\n".json_encode($package));
 46300 }
 46301 
 46302 $this->addPackage($package);
 46303 }
 46304 }
 46305 
 46306 public function getRepoName()
 46307 {
 46308 return Preg::replace('{^array }', 'package ', parent::getRepoName());
 46309 }
 46310 }
 46311 <?php
 46312 
 46313 
 46314 
 46315 
 46316 
 46317 
 46318 
 46319 
 46320 
 46321 
 46322 
 46323 namespace Composer\Repository;
 46324 
 46325 use Composer\Config;
 46326 use Composer\IO\IOInterface;
 46327 use Composer\Json\JsonFile;
 46328 use Composer\Package\CompleteAliasPackage;
 46329 use Composer\Package\CompletePackage;
 46330 use Composer\Package\Loader\ArrayLoader;
 46331 use Composer\Package\Version\VersionGuesser;
 46332 use Composer\Package\Version\VersionParser;
 46333 use Composer\Pcre\Preg;
 46334 use Composer\Util\Platform;
 46335 use Composer\Util\ProcessExecutor;
 46336 use Composer\Util\Filesystem;
 46337 use Composer\Util\Url;
 46338 use Composer\Util\Git as GitUtil;
 46339 
 46340 
 46341 
 46342 
 46343 
 46344 
 46345 
 46346 
 46347 
 46348 
 46349 
 46350 
 46351 
 46352 
 46353 
 46354 
 46355 
 46356 
 46357 
 46358 
 46359 
 46360 
 46361 
 46362 
 46363 
 46364 
 46365 
 46366 
 46367 
 46368 
 46369 
 46370 
 46371 
 46372 
 46373 
 46374 
 46375 class PathRepository extends ArrayRepository implements ConfigurableRepositoryInterface
 46376 {
 46377 
 46378 
 46379 
 46380 private $loader;
 46381 
 46382 
 46383 
 46384 
 46385 private $versionGuesser;
 46386 
 46387 
 46388 
 46389 
 46390 private $url;
 46391 
 46392 
 46393 
 46394 
 46395 
 46396 private $repoConfig;
 46397 
 46398 
 46399 
 46400 
 46401 private $process;
 46402 
 46403 
 46404 
 46405 
 46406 private $options;
 46407 
 46408 
 46409 
 46410 
 46411 
 46412 
 46413 
 46414 
 46415 public function __construct(array $repoConfig, IOInterface $io, Config $config)
 46416 {
 46417 if (!isset($repoConfig['url'])) {
 46418 throw new \RuntimeException('You must specify the `url` configuration for the path repository');
 46419 }
 46420 
 46421 $this->loader = new ArrayLoader(null, true);
 46422 $this->url = Platform::expandPath($repoConfig['url']);
 46423 $this->process = new ProcessExecutor($io);
 46424 $this->versionGuesser = new VersionGuesser($config, $this->process, new VersionParser());
 46425 $this->repoConfig = $repoConfig;
 46426 $this->options = isset($repoConfig['options']) ? $repoConfig['options'] : array();
 46427 if (!isset($this->options['relative'])) {
 46428 $filesystem = new Filesystem();
 46429 $this->options['relative'] = !$filesystem->isAbsolutePath($this->url);
 46430 }
 46431 
 46432 parent::__construct();
 46433 }
 46434 
 46435 public function getRepoName()
 46436 {
 46437 return 'path repo ('.Url::sanitize($this->repoConfig['url']).')';
 46438 }
 46439 
 46440 public function getRepoConfig()
 46441 {
 46442 return $this->repoConfig;
 46443 }
 46444 
 46445 
 46446 
 46447 
 46448 
 46449 
 46450 protected function initialize()
 46451 {
 46452 parent::initialize();
 46453 
 46454 $urlMatches = $this->getUrlMatches();
 46455 
 46456 if (empty($urlMatches)) {
 46457 if (Preg::isMatch('{[*{}]}', $this->url)) {
 46458 $url = $this->url;
 46459 while (Preg::isMatch('{[*{}]}', $url)) {
 46460 $url = dirname($url);
 46461 }
 46462 
 46463 if (is_dir($url)) {
 46464 return;
 46465 }
 46466 }
 46467 
 46468 throw new \RuntimeException('The `url` supplied for the path (' . $this->url . ') repository does not exist');
 46469 }
 46470 
 46471 foreach ($urlMatches as $url) {
 46472 $path = realpath($url) . DIRECTORY_SEPARATOR;
 46473 $composerFilePath = $path.'composer.json';
 46474 
 46475 if (!file_exists($composerFilePath)) {
 46476 continue;
 46477 }
 46478 
 46479 $json = file_get_contents($composerFilePath);
 46480 $package = JsonFile::parseJson($json, $composerFilePath);
 46481 $package['dist'] = array(
 46482 'type' => 'path',
 46483 'url' => $url,
 46484 'reference' => sha1($json . serialize($this->options)),
 46485 );
 46486 
 46487 
 46488 $package['transport-options'] = array_intersect_key($this->options, array('symlink' => true, 'relative' => true));
 46489 
 46490 
 46491 if (isset($package['name'], $this->options['versions'][$package['name']])) {
 46492 $package['version'] = $this->options['versions'][$package['name']];
 46493 }
 46494 
 46495 
 46496 if (!isset($package['version']) && ($rootVersion = Platform::getEnv('COMPOSER_ROOT_VERSION'))) {
 46497 if (
 46498 0 === $this->process->execute('git rev-parse HEAD', $ref1, $path)
 46499 && 0 === $this->process->execute('git rev-parse HEAD', $ref2)
 46500 && $ref1 === $ref2
 46501 ) {
 46502 $package['version'] = $rootVersion;
 46503 }
 46504 }
 46505 
 46506 $output = '';
 46507 if (is_dir($path . DIRECTORY_SEPARATOR . '.git') && 0 === $this->process->execute('git log -n1 --pretty=%H'.GitUtil::getNoShowSignatureFlag($this->process), $output, $path)) {
 46508 $package['dist']['reference'] = trim($output);
 46509 }
 46510 
 46511 $needsAlias = false;
 46512 if (!isset($package['version'])) {
 46513 $versionData = $this->versionGuesser->guessVersion($package, $path);
 46514 if (is_array($versionData) && $versionData['pretty_version']) {
 46515 
 46516 if (!empty($versionData['feature_pretty_version'])) {
 46517 $package['version'] = $versionData['feature_pretty_version'];
 46518 $this->addPackage($this->loader->load($package));
 46519 }
 46520 
 46521 $package['version'] = $versionData['pretty_version'];
 46522 } else {
 46523 $package['version'] = 'dev-main';
 46524 $needsAlias = true;
 46525 }
 46526 }
 46527 
 46528 $package = $this->loader->load($package);
 46529 if ($needsAlias && $package instanceof CompletePackage) {
 46530 
 46531 $package = new CompleteAliasPackage($package, 'dev-master', 'dev-master');
 46532 }
 46533 $this->addPackage($package);
 46534 }
 46535 }
 46536 
 46537 
 46538 
 46539 
 46540 
 46541 
 46542 private function getUrlMatches()
 46543 {
 46544 $flags = GLOB_MARK | GLOB_ONLYDIR;
 46545 
 46546 if (defined('GLOB_BRACE')) {
 46547 $flags |= GLOB_BRACE;
 46548 } elseif (strpos($this->url, '{') !== false || strpos($this->url, '}') !== false) {
 46549 throw new \RuntimeException('The operating system does not support GLOB_BRACE which is required for the url '. $this->url);
 46550 }
 46551 
 46552 
 46553 return array_map(function ($val) {
 46554 return rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $val), '/');
 46555 }, glob($this->url, $flags));
 46556 }
 46557 }
 46558 <?php
 46559 
 46560 
 46561 
 46562 
 46563 
 46564 
 46565 
 46566 
 46567 
 46568 
 46569 
 46570 namespace Composer\Repository;
 46571 
 46572 
 46573 
 46574 
 46575 
 46576 
 46577 
 46578 
 46579 
 46580 
 46581 
 46582 
 46583 class PearRepository extends ArrayRepository
 46584 {
 46585 public function __construct()
 46586 {
 46587 throw new \InvalidArgumentException('The PEAR repository has been removed from Composer 2.x');
 46588 }
 46589 }
 46590 <?php
 46591 
 46592 
 46593 
 46594 
 46595 
 46596 
 46597 
 46598 
 46599 
 46600 
 46601 
 46602 namespace Composer\Repository;
 46603 
 46604 use Composer\Composer;
 46605 use Composer\Package\CompletePackage;
 46606 use Composer\Package\CompletePackageInterface;
 46607 use Composer\Package\Link;
 46608 use Composer\Package\PackageInterface;
 46609 use Composer\Package\Version\VersionParser;
 46610 use Composer\Pcre\Preg;
 46611 use Composer\Platform\HhvmDetector;
 46612 use Composer\Platform\Runtime;
 46613 use Composer\Platform\Version;
 46614 use Composer\Plugin\PluginInterface;
 46615 use Composer\Semver\Constraint\Constraint;
 46616 use Composer\Util\Silencer;
 46617 use Composer\XdebugHandler\XdebugHandler;
 46618 
 46619 
 46620 
 46621 
 46622 class PlatformRepository extends ArrayRepository
 46623 {
 46624 const PLATFORM_PACKAGE_REGEX = '{^(?:php(?:-64bit|-ipv6|-zts|-debug)?|hhvm|(?:ext|lib)-[a-z0-9](?:[_.-]?[a-z0-9]+)*|composer(?:-(?:plugin|runtime)-api)?)$}iD';
 46625 
 46626 
 46627 
 46628 
 46629 private static $lastSeenPlatformPhp = null;
 46630 
 46631 
 46632 
 46633 
 46634 private $versionParser;
 46635 
 46636 
 46637 
 46638 
 46639 
 46640 
 46641 
 46642 
 46643 private $overrides = array();
 46644 
 46645 
 46646 
 46647 
 46648 
 46649 
 46650 private $disabledPackages = array();
 46651 
 46652 
 46653 private $runtime;
 46654 
 46655 private $hhvmDetector;
 46656 
 46657 
 46658 
 46659 
 46660 public function __construct(array $packages = array(), array $overrides = array(), Runtime $runtime = null, HhvmDetector $hhvmDetector = null)
 46661 {
 46662 $this->runtime = $runtime ?: new Runtime();
 46663 $this->hhvmDetector = $hhvmDetector ?: new HhvmDetector();
 46664 foreach ($overrides as $name => $version) {
 46665 if (!is_string($version) && false !== $version) { 
 46666 throw new \UnexpectedValueException('config.platform.'.$name.' should be a string or false, but got '.gettype($version).' '.var_export($version, true));
 46667 }
 46668 if ($name === 'php' && $version === false) {
 46669 throw new \UnexpectedValueException('config.platform.'.$name.' cannot be set to false as you cannot disable php entirely.');
 46670 }
 46671 $this->overrides[strtolower($name)] = array('name' => $name, 'version' => $version);
 46672 }
 46673 parent::__construct($packages);
 46674 }
 46675 
 46676 public function getRepoName()
 46677 {
 46678 return 'platform repo';
 46679 }
 46680 
 46681 
 46682 
 46683 
 46684 
 46685 public function isPlatformPackageDisabled($name)
 46686 {
 46687 return isset($this->disabledPackages[$name]);
 46688 }
 46689 
 46690 
 46691 
 46692 
 46693 public function getDisabledPackages()
 46694 {
 46695 return $this->disabledPackages;
 46696 }
 46697 
 46698 protected function initialize()
 46699 {
 46700 parent::initialize();
 46701 
 46702 $this->versionParser = new VersionParser();
 46703 
 46704 
 46705 
 46706 foreach ($this->overrides as $override) {
 46707 
 46708 if (!self::isPlatformPackage($override['name'])) {
 46709 throw new \InvalidArgumentException('Invalid platform package name in config.platform: '.$override['name']);
 46710 }
 46711 
 46712 if ($override['version'] !== false) {
 46713 $this->addOverriddenPackage($override);
 46714 }
 46715 }
 46716 
 46717 $prettyVersion = Composer::getVersion();
 46718 $version = $this->versionParser->normalize($prettyVersion);
 46719 $composer = new CompletePackage('composer', $version, $prettyVersion);
 46720 $composer->setDescription('Composer package');
 46721 $this->addPackage($composer);
 46722 
 46723 $prettyVersion = PluginInterface::PLUGIN_API_VERSION;
 46724 $version = $this->versionParser->normalize($prettyVersion);
 46725 $composerPluginApi = new CompletePackage('composer-plugin-api', $version, $prettyVersion);
 46726 $composerPluginApi->setDescription('The Composer Plugin API');
 46727 $this->addPackage($composerPluginApi);
 46728 
 46729 $prettyVersion = Composer::RUNTIME_API_VERSION;
 46730 $version = $this->versionParser->normalize($prettyVersion);
 46731 $composerRuntimeApi = new CompletePackage('composer-runtime-api', $version, $prettyVersion);
 46732 $composerRuntimeApi->setDescription('The Composer Runtime API');
 46733 $this->addPackage($composerRuntimeApi);
 46734 
 46735 try {
 46736 $prettyVersion = $this->runtime->getConstant('PHP_VERSION');
 46737 $version = $this->versionParser->normalize($prettyVersion);
 46738 } catch (\UnexpectedValueException $e) {
 46739 $prettyVersion = Preg::replace('#^([^~+-]+).*$#', '$1', $this->runtime->getConstant('PHP_VERSION'));
 46740 $version = $this->versionParser->normalize($prettyVersion);
 46741 }
 46742 
 46743 $php = new CompletePackage('php', $version, $prettyVersion);
 46744 $php->setDescription('The PHP interpreter');
 46745 $this->addPackage($php);
 46746 
 46747 if ($this->runtime->getConstant('PHP_DEBUG')) {
 46748 $phpdebug = new CompletePackage('php-debug', $version, $prettyVersion);
 46749 $phpdebug->setDescription('The PHP interpreter, with debugging symbols');
 46750 $this->addPackage($phpdebug);
 46751 }
 46752 
 46753 if ($this->runtime->hasConstant('PHP_ZTS') && $this->runtime->getConstant('PHP_ZTS')) {
 46754 $phpzts = new CompletePackage('php-zts', $version, $prettyVersion);
 46755 $phpzts->setDescription('The PHP interpreter, with Zend Thread Safety');
 46756 $this->addPackage($phpzts);
 46757 }
 46758 
 46759 if ($this->runtime->getConstant('PHP_INT_SIZE') === 8) {
 46760 $php64 = new CompletePackage('php-64bit', $version, $prettyVersion);
 46761 $php64->setDescription('The PHP interpreter, 64bit');
 46762 $this->addPackage($php64);
 46763 }
 46764 
 46765 
 46766 
 46767 if ($this->runtime->hasConstant('AF_INET6') || Silencer::call(array($this->runtime, 'invoke'), 'inet_pton', array('::')) !== false) {
 46768 $phpIpv6 = new CompletePackage('php-ipv6', $version, $prettyVersion);
 46769 $phpIpv6->setDescription('The PHP interpreter, with IPv6 support');
 46770 $this->addPackage($phpIpv6);
 46771 }
 46772 
 46773 $loadedExtensions = $this->runtime->getExtensions();
 46774 
 46775 
 46776 foreach ($loadedExtensions as $name) {
 46777 if (in_array($name, array('standard', 'Core'))) {
 46778 continue;
 46779 }
 46780 
 46781 $this->addExtension($name, $this->runtime->getExtensionVersion($name));
 46782 }
 46783 
 46784 
 46785 if (!in_array('xdebug', $loadedExtensions, true) && ($prettyVersion = XdebugHandler::getSkippedVersion())) {
 46786 $this->addExtension('xdebug', $prettyVersion);
 46787 }
 46788 
 46789 
 46790 
 46791 
 46792 foreach ($loadedExtensions as $name) {
 46793 switch ($name) {
 46794 case 'amqp':
 46795 $info = $this->runtime->getExtensionInfo($name);
 46796 
 46797 
 46798 if (Preg::isMatch('/^librabbitmq version => (?<version>.+)$/im', $info, $librabbitmqMatches)) {
 46799 $this->addLibrary($name.'-librabbitmq', $librabbitmqMatches['version'], 'AMQP librabbitmq version');
 46800 }
 46801 
 46802 
 46803 if (Preg::isMatch('/^AMQP protocol version => (?<version>.+)$/im', $info, $protocolMatches)) {
 46804 $this->addLibrary($name.'-protocol', str_replace('-', '.', $protocolMatches['version']), 'AMQP protocol version');
 46805 }
 46806 break;
 46807 
 46808 case 'bz2':
 46809 $info = $this->runtime->getExtensionInfo($name);
 46810 
 46811 
 46812 if (Preg::isMatch('/^BZip2 Version => (?<version>.*),/im', $info, $matches)) {
 46813 $this->addLibrary($name, $matches['version']);
 46814 }
 46815 break;
 46816 
 46817 case 'curl':
 46818 $curlVersion = $this->runtime->invoke('curl_version');
 46819 $this->addLibrary($name, $curlVersion['version']);
 46820 
 46821 $info = $this->runtime->getExtensionInfo($name);
 46822 
 46823 
 46824 if (Preg::isMatch('{^SSL Version => (?<library>[^/]+)/(?<version>.+)$}im', $info, $sslMatches)) {
 46825 $library = strtolower($sslMatches['library']);
 46826 if ($library === 'openssl') {
 46827 $parsedVersion = Version::parseOpenssl($sslMatches['version'], $isFips);
 46828 $this->addLibrary($name.'-openssl'.($isFips ? '-fips' : ''), $parsedVersion, 'curl OpenSSL version ('.$parsedVersion.')', array(), $isFips ? array('curl-openssl') : array());
 46829 } else {
 46830 $this->addLibrary($name.'-'.$library, $sslMatches['version'], 'curl '.$library.' version ('.$sslMatches['version'].')', array('curl-openssl'));
 46831 }
 46832 }
 46833 
 46834 
 46835 if (Preg::isMatch('{^libSSH Version => (?<library>[^/]+)/(?<version>.+?)(?:/.*)?$}im', $info, $sshMatches)) {
 46836 $this->addLibrary($name.'-'.strtolower($sshMatches['library']), $sshMatches['version'], 'curl '.$sshMatches['library'].' version');
 46837 }
 46838 
 46839 
 46840 if (Preg::isMatch('{^ZLib Version => (?<version>.+)$}im', $info, $zlibMatches)) {
 46841 $this->addLibrary($name.'-zlib', $zlibMatches['version'], 'curl zlib version');
 46842 }
 46843 break;
 46844 
 46845 case 'date':
 46846 $info = $this->runtime->getExtensionInfo($name);
 46847 
 46848 
 46849 if (Preg::isMatch('/^timelib version => (?<version>.+)$/im', $info, $timelibMatches)) {
 46850 $this->addLibrary($name.'-timelib', $timelibMatches['version'], 'date timelib version');
 46851 }
 46852 
 46853 
 46854 if (Preg::isMatch('/^Timezone Database => (?<source>internal|external)$/im', $info, $zoneinfoSourceMatches)) {
 46855 $external = $zoneinfoSourceMatches['source'] === 'external';
 46856 if (Preg::isMatch('/^"Olson" Timezone Database Version => (?<version>.+?)(\.system)?$/im', $info, $zoneinfoMatches)) {
 46857 
 46858 if ($external && in_array('timezonedb', $loadedExtensions, true)) {
 46859 $this->addLibrary('timezonedb-zoneinfo', $zoneinfoMatches['version'], 'zoneinfo ("Olson") database for date (replaced by timezonedb)', array($name.'-zoneinfo'));
 46860 } else {
 46861 $this->addLibrary($name.'-zoneinfo', $zoneinfoMatches['version'], 'zoneinfo ("Olson") database for date');
 46862 }
 46863 }
 46864 }
 46865 break;
 46866 
 46867 case 'fileinfo':
 46868 $info = $this->runtime->getExtensionInfo($name);
 46869 
 46870 
 46871 if (Preg::isMatch('/^libmagic => (?<version>.+)$/im', $info, $magicMatches)) {
 46872 $this->addLibrary($name.'-libmagic', $magicMatches['version'], 'fileinfo libmagic version');
 46873 }
 46874 break;
 46875 
 46876 case 'gd':
 46877 $this->addLibrary($name, $this->runtime->getConstant('GD_VERSION'));
 46878 
 46879 $info = $this->runtime->getExtensionInfo($name);
 46880 
 46881 if (Preg::isMatch('/^libJPEG Version => (?<version>.+?)(?: compatible)?$/im', $info, $libjpegMatches)) {
 46882 $this->addLibrary($name.'-libjpeg', Version::parseLibjpeg($libjpegMatches['version']), 'libjpeg version for gd');
 46883 }
 46884 
 46885 if (Preg::isMatch('/^libPNG Version => (?<version>.+)$/im', $info, $libpngMatches)) {
 46886 $this->addLibrary($name.'-libpng', $libpngMatches['version'], 'libpng version for gd');
 46887 }
 46888 
 46889 if (Preg::isMatch('/^FreeType Version => (?<version>.+)$/im', $info, $freetypeMatches)) {
 46890 $this->addLibrary($name.'-freetype', $freetypeMatches['version'], 'freetype version for gd');
 46891 }
 46892 
 46893 if (Preg::isMatch('/^libXpm Version => (?<versionId>\d+)$/im', $info, $libxpmMatches)) {
 46894 $this->addLibrary($name.'-libxpm', Version::convertLibxpmVersionId($libxpmMatches['versionId']), 'libxpm version for gd');
 46895 }
 46896 
 46897 break;
 46898 
 46899 case 'gmp':
 46900 $this->addLibrary($name, $this->runtime->getConstant('GMP_VERSION'));
 46901 break;
 46902 
 46903 case 'iconv':
 46904 $this->addLibrary($name, $this->runtime->getConstant('ICONV_VERSION'));
 46905 break;
 46906 
 46907 case 'intl':
 46908 $info = $this->runtime->getExtensionInfo($name);
 46909 
 46910 $description = 'The ICU unicode and globalization support library';
 46911 
 46912 if ($this->runtime->hasConstant('INTL_ICU_VERSION')) {
 46913 $this->addLibrary('icu', $this->runtime->getConstant('INTL_ICU_VERSION'), $description);
 46914 } elseif (Preg::isMatch('/^ICU version => (?<version>.+)$/im', $info, $matches)) {
 46915 $this->addLibrary('icu', $matches['version'], $description);
 46916 }
 46917 
 46918 
 46919 if (Preg::isMatch('/^ICU TZData version => (?<version>.*)$/im', $info, $zoneinfoMatches)) {
 46920 $this->addLibrary('icu-zoneinfo', Version::parseZoneinfoVersion($zoneinfoMatches['version']), 'zoneinfo ("Olson") database for icu');
 46921 }
 46922 
 46923 
 46924 if ($this->runtime->hasClass('ResourceBundle')) {
 46925 $cldrVersion = $this->runtime->invoke(array('ResourceBundle', 'create'), array('root', 'ICUDATA', false))->get('Version');
 46926 $this->addLibrary('icu-cldr', $cldrVersion, 'ICU CLDR project version');
 46927 }
 46928 
 46929 if ($this->runtime->hasClass('IntlChar')) {
 46930 $this->addLibrary('icu-unicode', implode('.', array_slice($this->runtime->invoke(array('IntlChar', 'getUnicodeVersion')), 0, 3)), 'ICU unicode version');
 46931 }
 46932 break;
 46933 
 46934 case 'imagick':
 46935 $imageMagickVersion = $this->runtime->construct('Imagick')->getVersion();
 46936 
 46937 
 46938 Preg::match('/^ImageMagick (?<version>[\d.]+)(?:-(?<patch>\d+))?/', $imageMagickVersion['versionString'], $matches);
 46939 $version = $matches['version'];
 46940 if (isset($matches['patch'])) {
 46941 $version .= '.'.$matches['patch'];
 46942 }
 46943 
 46944 $this->addLibrary($name.'-imagemagick', $version, null, array('imagick'));
 46945 break;
 46946 
 46947 case 'ldap':
 46948 $info = $this->runtime->getExtensionInfo($name);
 46949 
 46950 if (Preg::isMatch('/^Vendor Version => (?<versionId>\d+)$/im', $info, $matches) && Preg::isMatch('/^Vendor Name => (?<vendor>.+)$/im', $info, $vendorMatches)) {
 46951 $this->addLibrary($name.'-'.strtolower($vendorMatches['vendor']), Version::convertOpenldapVersionId($matches['versionId']), $vendorMatches['vendor'].' version of ldap');
 46952 }
 46953 break;
 46954 
 46955 case 'libxml':
 46956 
 46957 $libxmlProvides = array_map(function ($extension) {
 46958 return $extension . '-libxml';
 46959 }, array_intersect($loadedExtensions, array('dom', 'simplexml', 'xml', 'xmlreader', 'xmlwriter')));
 46960 $this->addLibrary($name, $this->runtime->getConstant('LIBXML_DOTTED_VERSION'), 'libxml library version', array(), $libxmlProvides);
 46961 
 46962 break;
 46963 
 46964 case 'mbstring':
 46965 $info = $this->runtime->getExtensionInfo($name);
 46966 
 46967 
 46968 if (Preg::isMatch('/^libmbfl version => (?<version>.+)$/im', $info, $libmbflMatches)) {
 46969 $this->addLibrary($name.'-libmbfl', $libmbflMatches['version'], 'mbstring libmbfl version');
 46970 }
 46971 
 46972 if ($this->runtime->hasConstant('MB_ONIGURUMA_VERSION')) {
 46973 $this->addLibrary($name.'-oniguruma', $this->runtime->getConstant('MB_ONIGURUMA_VERSION'), 'mbstring oniguruma version');
 46974 
 46975 
 46976 
 46977 } elseif (Preg::isMatch('/^(?:oniguruma|Multibyte regex \(oniguruma\)) version => (?<version>.+)$/im', $info, $onigurumaMatches)) {
 46978 $this->addLibrary($name.'-oniguruma', $onigurumaMatches['version'], 'mbstring oniguruma version');
 46979 }
 46980 
 46981 break;
 46982 
 46983 case 'memcached':
 46984 $info = $this->runtime->getExtensionInfo($name);
 46985 
 46986 
 46987 if (Preg::isMatch('/^libmemcached version => (?<version>.+)$/im', $info, $matches)) {
 46988 $this->addLibrary($name.'-libmemcached', $matches['version'], 'libmemcached version');
 46989 }
 46990 break;
 46991 
 46992 case 'openssl':
 46993 
 46994 if (Preg::isMatch('{^(?:OpenSSL|LibreSSL)?\s*(?<version>\S+)}i', $this->runtime->getConstant('OPENSSL_VERSION_TEXT'), $matches)) {
 46995 $parsedVersion = Version::parseOpenssl($matches['version'], $isFips);
 46996 $this->addLibrary($name.($isFips ? '-fips' : ''), $parsedVersion, $this->runtime->getConstant('OPENSSL_VERSION_TEXT'), array(), $isFips ? array($name) : array());
 46997 }
 46998 break;
 46999 
 47000 case 'pcre':
 47001 $this->addLibrary($name, Preg::replace('{^(\S+).*}', '$1', $this->runtime->getConstant('PCRE_VERSION')));
 47002 
 47003 $info = $this->runtime->getExtensionInfo($name);
 47004 
 47005 
 47006 if (Preg::isMatch('/^PCRE Unicode Version => (?<version>.+)$/im', $info, $pcreUnicodeMatches)) {
 47007 $this->addLibrary($name.'-unicode', $pcreUnicodeMatches['version'], 'PCRE Unicode version support');
 47008 }
 47009 
 47010 break;
 47011 
 47012 case 'mysqlnd':
 47013 case 'pdo_mysql':
 47014 $info = $this->runtime->getExtensionInfo($name);
 47015 
 47016 if (Preg::isMatch('/^(?:Client API version|Version) => mysqlnd (?<version>.+?) /mi', $info, $matches)) {
 47017 $this->addLibrary($name.'-mysqlnd', $matches['version'], 'mysqlnd library version for '.$name);
 47018 }
 47019 break;
 47020 
 47021 case 'mongodb':
 47022 $info = $this->runtime->getExtensionInfo($name);
 47023 
 47024 if (Preg::isMatch('/^libmongoc bundled version => (?<version>.+)$/im', $info, $libmongocMatches)) {
 47025 $this->addLibrary($name.'-libmongoc', $libmongocMatches['version'], 'libmongoc version of mongodb');
 47026 }
 47027 
 47028 if (Preg::isMatch('/^libbson bundled version => (?<version>.+)$/im', $info, $libbsonMatches)) {
 47029 $this->addLibrary($name.'-libbson', $libbsonMatches['version'], 'libbson version of mongodb');
 47030 }
 47031 break;
 47032 
 47033 case 'pgsql':
 47034 case 'pdo_pgsql':
 47035 $info = $this->runtime->getExtensionInfo($name);
 47036 
 47037 if (Preg::isMatch('/^PostgreSQL\(libpq\) Version => (?<version>.*)$/im', $info, $matches)) {
 47038 $this->addLibrary($name.'-libpq', $matches['version'], 'libpq for '.$name);
 47039 }
 47040 break;
 47041 
 47042 case 'libsodium':
 47043 case 'sodium':
 47044 if ($this->runtime->hasConstant('SODIUM_LIBRARY_VERSION')) {
 47045 $this->addLibrary('libsodium', $this->runtime->getConstant('SODIUM_LIBRARY_VERSION'));
 47046 }
 47047 break;
 47048 
 47049 case 'sqlite3':
 47050 case 'pdo_sqlite':
 47051 $info = $this->runtime->getExtensionInfo($name);
 47052 
 47053 if (Preg::isMatch('/^SQLite Library => (?<version>.+)$/im', $info, $matches)) {
 47054 $this->addLibrary($name.'-sqlite', $matches['version']);
 47055 }
 47056 break;
 47057 
 47058 case 'ssh2':
 47059 $info = $this->runtime->getExtensionInfo($name);
 47060 
 47061 if (Preg::isMatch('/^libssh2 version => (?<version>.+)$/im', $info, $matches)) {
 47062 $this->addLibrary($name.'-libssh2', $matches['version']);
 47063 }
 47064 break;
 47065 
 47066 case 'xsl':
 47067 $this->addLibrary('libxslt', $this->runtime->getConstant('LIBXSLT_DOTTED_VERSION'), null, array('xsl'));
 47068 
 47069 $info = $this->runtime->getExtensionInfo('xsl');
 47070 if (Preg::isMatch('/^libxslt compiled against libxml Version => (?<version>.+)$/im', $info, $matches)) {
 47071 $this->addLibrary('libxslt-libxml', $matches['version'], 'libxml version libxslt is compiled against');
 47072 }
 47073 break;
 47074 
 47075 case 'yaml':
 47076 $info = $this->runtime->getExtensionInfo('yaml');
 47077 
 47078 if (Preg::isMatch('/^LibYAML Version => (?<version>.+)$/im', $info, $matches)) {
 47079 $this->addLibrary($name.'-libyaml', $matches['version'], 'libyaml version of yaml');
 47080 }
 47081 break;
 47082 
 47083 case 'zip':
 47084 if ($this->runtime->hasConstant('LIBZIP_VERSION', 'ZipArchive')) {
 47085 $this->addLibrary($name.'-libzip', $this->runtime->getConstant('LIBZIP_VERSION', 'ZipArchive'), null, array('zip'));
 47086 }
 47087 break;
 47088 
 47089 case 'zlib':
 47090 if ($this->runtime->hasConstant('ZLIB_VERSION')) {
 47091 $this->addLibrary($name, $this->runtime->getConstant('ZLIB_VERSION'));
 47092 
 47093 
 47094 } elseif (Preg::isMatch('/^Linked Version => (?<version>.+)$/im', $this->runtime->getExtensionInfo($name), $matches)) {
 47095 $this->addLibrary($name, $matches['version']);
 47096 }
 47097 break;
 47098 
 47099 default:
 47100 break;
 47101 }
 47102 }
 47103 
 47104 $hhvmVersion = $this->hhvmDetector->getVersion();
 47105 if ($hhvmVersion) {
 47106 try {
 47107 $prettyVersion = $hhvmVersion;
 47108 $version = $this->versionParser->normalize($prettyVersion);
 47109 } catch (\UnexpectedValueException $e) {
 47110 $prettyVersion = Preg::replace('#^([^~+-]+).*$#', '$1', $hhvmVersion);
 47111 $version = $this->versionParser->normalize($prettyVersion);
 47112 }
 47113 
 47114 $hhvm = new CompletePackage('hhvm', $version, $prettyVersion);
 47115 $hhvm->setDescription('The HHVM Runtime (64bit)');
 47116 $this->addPackage($hhvm);
 47117 }
 47118 }
 47119 
 47120 
 47121 
 47122 
 47123 public function addPackage(PackageInterface $package)
 47124 {
 47125 if (!$package instanceof CompletePackage) {
 47126 throw new \UnexpectedValueException('Expected CompletePackage but got '.get_class($package));
 47127 }
 47128 
 47129 
 47130 if (isset($this->overrides[$package->getName()])) {
 47131 if ($this->overrides[$package->getName()]['version'] === false) {
 47132 $this->addDisabledPackage($package);
 47133 return;
 47134 }
 47135 
 47136 $overrider = $this->findPackage($package->getName(), '*');
 47137 if ($package->getVersion() === $overrider->getVersion()) {
 47138 $actualText = 'same as actual';
 47139 } else {
 47140 $actualText = 'actual: '.$package->getPrettyVersion();
 47141 }
 47142 if ($overrider instanceof CompletePackageInterface) {
 47143 $overrider->setDescription($overrider->getDescription().', '.$actualText);
 47144 }
 47145 
 47146 return;
 47147 }
 47148 
 47149 
 47150 if (isset($this->overrides['php']) && 0 === strpos($package->getName(), 'php-')) {
 47151 if (isset($this->overrides[$package->getName()]) && $this->overrides[$package->getName()]['version'] === false) {
 47152 $this->addDisabledPackage($package);
 47153 return;
 47154 }
 47155 
 47156 $overrider = $this->addOverriddenPackage($this->overrides['php'], $package->getPrettyName());
 47157 if ($package->getVersion() === $overrider->getVersion()) {
 47158 $actualText = 'same as actual';
 47159 } else {
 47160 $actualText = 'actual: '.$package->getPrettyVersion();
 47161 }
 47162 $overrider->setDescription($overrider->getDescription().', '.$actualText);
 47163 
 47164 return;
 47165 }
 47166 
 47167 parent::addPackage($package);
 47168 }
 47169 
 47170 
 47171 
 47172 
 47173 
 47174 
 47175 
 47176 private function addOverriddenPackage(array $override, $name = null)
 47177 {
 47178 $version = $this->versionParser->normalize($override['version']);
 47179 $package = new CompletePackage($name ?: $override['name'], $version, $override['version']);
 47180 $package->setDescription('Package overridden via config.platform');
 47181 $package->setExtra(array('config.platform' => true));
 47182 parent::addPackage($package);
 47183 
 47184 if ($package->getName() === 'php') {
 47185 self::$lastSeenPlatformPhp = implode('.', array_slice(explode('.', $package->getVersion()), 0, 3));
 47186 }
 47187 
 47188 return $package;
 47189 }
 47190 
 47191 
 47192 
 47193 
 47194 private function addDisabledPackage(CompletePackage $package)
 47195 {
 47196 $package->setDescription($package->getDescription().'. <warning>Package disabled via config.platform</warning>');
 47197 $package->setExtra(array('config.platform' => true));
 47198 
 47199 $this->disabledPackages[$package->getName()] = $package;
 47200 }
 47201 
 47202 
 47203 
 47204 
 47205 
 47206 
 47207 
 47208 
 47209 
 47210 private function addExtension($name, $prettyVersion)
 47211 {
 47212 $extraDescription = null;
 47213 
 47214 try {
 47215 $version = $this->versionParser->normalize($prettyVersion);
 47216 } catch (\UnexpectedValueException $e) {
 47217 $extraDescription = ' (actual version: '.$prettyVersion.')';
 47218 if (Preg::isMatch('{^(\d+\.\d+\.\d+(?:\.\d+)?)}', $prettyVersion, $match)) {
 47219 $prettyVersion = $match[1];
 47220 } else {
 47221 $prettyVersion = '0';
 47222 }
 47223 $version = $this->versionParser->normalize($prettyVersion);
 47224 }
 47225 
 47226 $packageName = $this->buildPackageName($name);
 47227 $ext = new CompletePackage($packageName, $version, $prettyVersion);
 47228 $ext->setDescription('The '.$name.' PHP extension'.$extraDescription);
 47229 
 47230 if ($name === 'uuid') {
 47231 $ext->setReplaces(array(
 47232 'lib-uuid' => new Link('ext-uuid', 'lib-uuid', new Constraint('=', $version), Link::TYPE_REPLACE, $ext->getPrettyVersion()),
 47233 ));
 47234 }
 47235 
 47236 $this->addPackage($ext);
 47237 }
 47238 
 47239 
 47240 
 47241 
 47242 
 47243 private function buildPackageName($name)
 47244 {
 47245 return 'ext-' . str_replace(' ', '-', strtolower($name));
 47246 }
 47247 
 47248 
 47249 
 47250 
 47251 
 47252 
 47253 
 47254 
 47255 
 47256 
 47257 private function addLibrary($name, $prettyVersion, $description = null, array $replaces = array(), array $provides = array())
 47258 {
 47259 try {
 47260 $version = $this->versionParser->normalize($prettyVersion);
 47261 } catch (\UnexpectedValueException $e) {
 47262 return;
 47263 }
 47264 
 47265 if ($description === null) {
 47266 $description = 'The '.$name.' library';
 47267 }
 47268 
 47269 $lib = new CompletePackage('lib-'.$name, $version, $prettyVersion);
 47270 $lib->setDescription($description);
 47271 
 47272 $replaceLinks = array();
 47273 foreach ($replaces as $replace) {
 47274 $replace = strtolower($replace);
 47275 $replaceLinks[$replace] = new Link('lib-'.$name, 'lib-'.$replace, new Constraint('=', $version), Link::TYPE_REPLACE, $lib->getPrettyVersion());
 47276 }
 47277 $provideLinks = array();
 47278 foreach ($provides as $provide) {
 47279 $provide = strtolower($provide);
 47280 $provideLinks[$provide] = new Link('lib-'.$name, 'lib-'.$provide, new Constraint('=', $version), Link::TYPE_PROVIDE, $lib->getPrettyVersion());
 47281 }
 47282 $lib->setReplaces($replaceLinks);
 47283 $lib->setProvides($provideLinks);
 47284 
 47285 $this->addPackage($lib);
 47286 }
 47287 
 47288 
 47289 
 47290 
 47291 
 47292 
 47293 
 47294 public static function isPlatformPackage($name)
 47295 {
 47296 static $cache = array();
 47297 
 47298 if (isset($cache[$name])) {
 47299 return $cache[$name];
 47300 }
 47301 
 47302 return $cache[$name] = Preg::isMatch(PlatformRepository::PLATFORM_PACKAGE_REGEX, $name);
 47303 }
 47304 
 47305 
 47306 
 47307 
 47308 
 47309 
 47310 
 47311 
 47312 
 47313 
 47314 
 47315 public static function getPlatformPhpVersion()
 47316 {
 47317 return self::$lastSeenPlatformPhp;
 47318 }
 47319 
 47320 public function search($query, $mode = 0, $type = null)
 47321 {
 47322 
 47323 if ($mode === self::SEARCH_VENDOR) {
 47324 return array();
 47325 }
 47326 
 47327 return parent::search($query, $mode, $type);
 47328 }
 47329 }
 47330 <?php
 47331 
 47332 
 47333 
 47334 
 47335 
 47336 
 47337 
 47338 
 47339 
 47340 
 47341 
 47342 namespace Composer\Repository;
 47343 
 47344 use Composer\Factory;
 47345 use Composer\IO\IOInterface;
 47346 use Composer\Config;
 47347 use Composer\EventDispatcher\EventDispatcher;
 47348 use Composer\Pcre\Preg;
 47349 use Composer\Util\HttpDownloader;
 47350 use Composer\Util\ProcessExecutor;
 47351 use Composer\Json\JsonFile;
 47352 
 47353 
 47354 
 47355 
 47356 class RepositoryFactory
 47357 {
 47358 
 47359 
 47360 
 47361 
 47362 
 47363 
 47364 
 47365 public static function configFromString(IOInterface $io, Config $config, $repository, $allowFilesystem = false)
 47366 {
 47367 if (0 === strpos($repository, 'http')) {
 47368 $repoConfig = array('type' => 'composer', 'url' => $repository);
 47369 } elseif ("json" === pathinfo($repository, PATHINFO_EXTENSION)) {
 47370 $json = new JsonFile($repository, Factory::createHttpDownloader($io, $config));
 47371 $data = $json->read();
 47372 if (!empty($data['packages']) || !empty($data['includes']) || !empty($data['provider-includes'])) {
 47373 $repoConfig = array('type' => 'composer', 'url' => 'file://' . strtr(realpath($repository), '\\', '/'));
 47374 } elseif ($allowFilesystem) {
 47375 $repoConfig = array('type' => 'filesystem', 'json' => $json);
 47376 } else {
 47377 throw new \InvalidArgumentException("Invalid repository URL ($repository) given. This file does not contain a valid composer repository.");
 47378 }
 47379 } elseif (strpos($repository, '{') === 0) {
 47380 
 47381 $repoConfig = JsonFile::parseJson($repository);
 47382 } else {
 47383 throw new \InvalidArgumentException("Invalid repository url ($repository) given. Has to be a .json file, an http url or a JSON object.");
 47384 }
 47385 
 47386 return $repoConfig;
 47387 }
 47388 
 47389 
 47390 
 47391 
 47392 
 47393 
 47394 
 47395 
 47396 public static function fromString(IOInterface $io, Config $config, $repository, $allowFilesystem = false, RepositoryManager $rm = null)
 47397 {
 47398 $repoConfig = static::configFromString($io, $config, $repository, $allowFilesystem);
 47399 
 47400 return static::createRepo($io, $config, $repoConfig, $rm);
 47401 }
 47402 
 47403 
 47404 
 47405 
 47406 
 47407 
 47408 
 47409 public static function createRepo(IOInterface $io, Config $config, array $repoConfig, RepositoryManager $rm = null)
 47410 {
 47411 if (!$rm) {
 47412 $rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config));
 47413 }
 47414 $repos = self::createRepos($rm, array($repoConfig));
 47415 
 47416 return reset($repos);
 47417 }
 47418 
 47419 
 47420 
 47421 
 47422 
 47423 
 47424 
 47425 public static function defaultRepos(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null)
 47426 {
 47427 if (!$config) {
 47428 $config = Factory::createConfig($io);
 47429 }
 47430 if ($io) {
 47431 $io->loadConfiguration($config);
 47432 }
 47433 if (!$rm) {
 47434 if (!$io) {
 47435 throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager');
 47436 }
 47437 $rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config));
 47438 }
 47439 
 47440 return self::createRepos($rm, $config->getRepositories());
 47441 }
 47442 
 47443 
 47444 
 47445 
 47446 
 47447 
 47448 
 47449 
 47450 public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, ProcessExecutor $process = null)
 47451 {
 47452 $rm = new RepositoryManager($io, $config, $httpDownloader, $eventDispatcher, $process);
 47453 $rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
 47454 $rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
 47455 $rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository');
 47456 $rm->setRepositoryClass('pear', 'Composer\Repository\PearRepository');
 47457 $rm->setRepositoryClass('git', 'Composer\Repository\VcsRepository');
 47458 $rm->setRepositoryClass('bitbucket', 'Composer\Repository\VcsRepository');
 47459 $rm->setRepositoryClass('git-bitbucket', 'Composer\Repository\VcsRepository');
 47460 $rm->setRepositoryClass('github', 'Composer\Repository\VcsRepository');
 47461 $rm->setRepositoryClass('gitlab', 'Composer\Repository\VcsRepository');
 47462 $rm->setRepositoryClass('svn', 'Composer\Repository\VcsRepository');
 47463 $rm->setRepositoryClass('fossil', 'Composer\Repository\VcsRepository');
 47464 $rm->setRepositoryClass('perforce', 'Composer\Repository\VcsRepository');
 47465 $rm->setRepositoryClass('hg', 'Composer\Repository\VcsRepository');
 47466 $rm->setRepositoryClass('artifact', 'Composer\Repository\ArtifactRepository');
 47467 $rm->setRepositoryClass('path', 'Composer\Repository\PathRepository');
 47468 
 47469 return $rm;
 47470 }
 47471 
 47472 
 47473 
 47474 
 47475 
 47476 
 47477 private static function createRepos(RepositoryManager $rm, array $repoConfigs)
 47478 {
 47479 $repos = array();
 47480 
 47481 foreach ($repoConfigs as $index => $repo) {
 47482 if (is_string($repo)) {
 47483 throw new \UnexpectedValueException('"repositories" should be an array of repository definitions, only a single repository was given');
 47484 }
 47485 if (!is_array($repo)) {
 47486 throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') should be an array, '.gettype($repo).' given');
 47487 }
 47488 if (!isset($repo['type'])) {
 47489 throw new \UnexpectedValueException('Repository "'.$index.'" ('.json_encode($repo).') must have a type defined');
 47490 }
 47491 
 47492 $name = self::generateRepositoryName($index, $repo, $repos);
 47493 if ($repo['type'] === 'filesystem') {
 47494 $repos[$name] = new FilesystemRepository($repo['json']);
 47495 } else {
 47496 $repos[$name] = $rm->createRepository($repo['type'], $repo, $index);
 47497 }
 47498 }
 47499 
 47500 return $repos;
 47501 }
 47502 
 47503 
 47504 
 47505 
 47506 
 47507 
 47508 
 47509 
 47510 public static function generateRepositoryName($index, array $repo, array $existingRepos)
 47511 {
 47512 $name = is_int($index) && isset($repo['url']) ? Preg::replace('{^https?://}i', '', $repo['url']) : $index;
 47513 while (isset($existingRepos[$name])) {
 47514 $name .= '2';
 47515 }
 47516 
 47517 return $name;
 47518 }
 47519 }
 47520 <?php
 47521 
 47522 
 47523 
 47524 
 47525 
 47526 
 47527 
 47528 
 47529 
 47530 
 47531 
 47532 namespace Composer\Repository;
 47533 
 47534 use Composer\Package\PackageInterface;
 47535 use Composer\Package\BasePackage;
 47536 use Composer\Semver\Constraint\ConstraintInterface;
 47537 
 47538 
 47539 
 47540 
 47541 
 47542 
 47543 
 47544 
 47545 interface RepositoryInterface extends \Countable
 47546 {
 47547 const SEARCH_FULLTEXT = 0;
 47548 const SEARCH_NAME = 1;
 47549 const SEARCH_VENDOR = 2;
 47550 
 47551 
 47552 
 47553 
 47554 
 47555 
 47556 
 47557 
 47558 public function hasPackage(PackageInterface $package);
 47559 
 47560 
 47561 
 47562 
 47563 
 47564 
 47565 
 47566 
 47567 
 47568 public function findPackage($name, $constraint);
 47569 
 47570 
 47571 
 47572 
 47573 
 47574 
 47575 
 47576 
 47577 
 47578 public function findPackages($name, $constraint = null);
 47579 
 47580 
 47581 
 47582 
 47583 
 47584 
 47585 public function getPackages();
 47586 
 47587 
 47588 
 47589 
 47590 
 47591 
 47592 
 47593 
 47594 
 47595 
 47596 
 47597 
 47598 
 47599 
 47600 
 47601 
 47602 
 47603 public function loadPackages(array $packageNameMap, array $acceptableStabilities, array $stabilityFlags, array $alreadyLoaded = array());
 47604 
 47605 
 47606 
 47607 
 47608 
 47609 
 47610 
 47611 
 47612 
 47613 
 47614 
 47615 public function search($query, $mode = 0, $type = null);
 47616 
 47617 
 47618 
 47619 
 47620 
 47621 
 47622 
 47623 
 47624 
 47625 
 47626 
 47627 public function getProviders($packageName);
 47628 
 47629 
 47630 
 47631 
 47632 
 47633 
 47634 
 47635 
 47636 public function getRepoName();
 47637 }
 47638 <?php
 47639 
 47640 
 47641 
 47642 
 47643 
 47644 
 47645 
 47646 
 47647 
 47648 
 47649 
 47650 namespace Composer\Repository;
 47651 
 47652 use Composer\IO\IOInterface;
 47653 use Composer\Config;
 47654 use Composer\EventDispatcher\EventDispatcher;
 47655 use Composer\Package\PackageInterface;
 47656 use Composer\Util\HttpDownloader;
 47657 use Composer\Util\ProcessExecutor;
 47658 
 47659 
 47660 
 47661 
 47662 
 47663 
 47664 
 47665 
 47666 class RepositoryManager
 47667 {
 47668 
 47669 private $localRepository;
 47670 
 47671 private $repositories = array();
 47672 
 47673 private $repositoryClasses = array();
 47674 
 47675 private $io;
 47676 
 47677 private $config;
 47678 
 47679 private $httpDownloader;
 47680 
 47681 private $eventDispatcher;
 47682 
 47683 private $process;
 47684 
 47685 public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, ProcessExecutor $process = null)
 47686 {
 47687 $this->io = $io;
 47688 $this->config = $config;
 47689 $this->httpDownloader = $httpDownloader;
 47690 $this->eventDispatcher = $eventDispatcher;
 47691 $this->process = $process ?: new ProcessExecutor($io);
 47692 }
 47693 
 47694 
 47695 
 47696 
 47697 
 47698 
 47699 
 47700 
 47701 
 47702 public function findPackage($name, $constraint)
 47703 {
 47704 foreach ($this->repositories as $repository) {
 47705 
 47706 if ($package = $repository->findPackage($name, $constraint)) {
 47707 return $package;
 47708 }
 47709 }
 47710 
 47711 return null;
 47712 }
 47713 
 47714 
 47715 
 47716 
 47717 
 47718 
 47719 
 47720 
 47721 
 47722 public function findPackages($name, $constraint)
 47723 {
 47724 $packages = array();
 47725 
 47726 foreach ($this->getRepositories() as $repository) {
 47727 $packages = array_merge($packages, $repository->findPackages($name, $constraint));
 47728 }
 47729 
 47730 return $packages;
 47731 }
 47732 
 47733 
 47734 
 47735 
 47736 
 47737 
 47738 
 47739 
 47740 public function addRepository(RepositoryInterface $repository)
 47741 {
 47742 $this->repositories[] = $repository;
 47743 }
 47744 
 47745 
 47746 
 47747 
 47748 
 47749 
 47750 
 47751 
 47752 
 47753 
 47754 public function prependRepository(RepositoryInterface $repository)
 47755 {
 47756 array_unshift($this->repositories, $repository);
 47757 }
 47758 
 47759 
 47760 
 47761 
 47762 
 47763 
 47764 
 47765 
 47766 
 47767 
 47768 public function createRepository($type, $config, $name = null)
 47769 {
 47770 if (!isset($this->repositoryClasses[$type])) {
 47771 throw new \InvalidArgumentException('Repository type is not registered: '.$type);
 47772 }
 47773 
 47774 if (isset($config['packagist']) && false === $config['packagist']) {
 47775 $this->io->writeError('<warning>Repository "'.$name.'" ('.json_encode($config).') has a packagist key which should be in its own repository definition</warning>');
 47776 }
 47777 
 47778 $class = $this->repositoryClasses[$type];
 47779 
 47780 if (isset($config['only']) || isset($config['exclude']) || isset($config['canonical'])) {
 47781 $filterConfig = $config;
 47782 unset($config['only'], $config['exclude'], $config['canonical']);
 47783 }
 47784 
 47785 $repository = new $class($config, $this->io, $this->config, $this->httpDownloader, $this->eventDispatcher, $this->process);
 47786 
 47787 if (isset($filterConfig)) {
 47788 $repository = new FilterRepository($repository, $filterConfig);
 47789 }
 47790 
 47791 return $repository;
 47792 }
 47793 
 47794 
 47795 
 47796 
 47797 
 47798 
 47799 
 47800 
 47801 
 47802 public function setRepositoryClass($type, $class)
 47803 {
 47804 $this->repositoryClasses[$type] = $class;
 47805 }
 47806 
 47807 
 47808 
 47809 
 47810 
 47811 
 47812 public function getRepositories()
 47813 {
 47814 return $this->repositories;
 47815 }
 47816 
 47817 
 47818 
 47819 
 47820 
 47821 
 47822 
 47823 
 47824 public function setLocalRepository(InstalledRepositoryInterface $repository)
 47825 {
 47826 $this->localRepository = $repository;
 47827 }
 47828 
 47829 
 47830 
 47831 
 47832 
 47833 
 47834 public function getLocalRepository()
 47835 {
 47836 return $this->localRepository;
 47837 }
 47838 }
 47839 <?php
 47840 
 47841 
 47842 
 47843 
 47844 
 47845 
 47846 
 47847 
 47848 
 47849 
 47850 
 47851 namespace Composer\Repository;
 47852 
 47853 
 47854 
 47855 
 47856 
 47857 
 47858 class RepositorySecurityException extends \Exception
 47859 {
 47860 }
 47861 <?php
 47862 
 47863 
 47864 
 47865 
 47866 
 47867 
 47868 
 47869 
 47870 
 47871 
 47872 
 47873 namespace Composer\Repository;
 47874 
 47875 use Composer\DependencyResolver\PoolOptimizer;
 47876 use Composer\DependencyResolver\PolicyInterface;
 47877 use Composer\DependencyResolver\Pool;
 47878 use Composer\DependencyResolver\PoolBuilder;
 47879 use Composer\DependencyResolver\Request;
 47880 use Composer\EventDispatcher\EventDispatcher;
 47881 use Composer\IO\IOInterface;
 47882 use Composer\IO\NullIO;
 47883 use Composer\Package\BasePackage;
 47884 use Composer\Package\AliasPackage;
 47885 use Composer\Package\CompleteAliasPackage;
 47886 use Composer\Package\CompletePackage;
 47887 use Composer\Semver\Constraint\ConstraintInterface;
 47888 use Composer\Package\Version\StabilityFilter;
 47889 
 47890 
 47891 
 47892 
 47893 class RepositorySet
 47894 {
 47895 
 47896 
 47897 
 47898 const ALLOW_UNACCEPTABLE_STABILITIES = 1;
 47899 
 47900 
 47901 
 47902 const ALLOW_SHADOWED_REPOSITORIES = 2;
 47903 
 47904 
 47905 
 47906 
 47907 
 47908 private $rootAliases;
 47909 
 47910 
 47911 
 47912 
 47913 
 47914 private $rootReferences;
 47915 
 47916 
 47917 private $repositories = array();
 47918 
 47919 
 47920 
 47921 
 47922 
 47923 private $acceptableStabilities;
 47924 
 47925 
 47926 
 47927 
 47928 
 47929 private $stabilityFlags;
 47930 
 47931 
 47932 
 47933 
 47934 
 47935 private $rootRequires;
 47936 
 47937 
 47938 private $locked = false;
 47939 
 47940 private $allowInstalledRepositories = false;
 47941 
 47942 
 47943 
 47944 
 47945 
 47946 
 47947 
 47948 
 47949 
 47950 
 47951 
 47952 
 47953 
 47954 
 47955 
 47956 
 47957 public function __construct($minimumStability = 'stable', array $stabilityFlags = array(), array $rootAliases = array(), array $rootReferences = array(), array $rootRequires = array())
 47958 {
 47959 $this->rootAliases = self::getRootAliasesPerPackage($rootAliases);
 47960 $this->rootReferences = $rootReferences;
 47961 
 47962 $this->acceptableStabilities = array();
 47963 foreach (BasePackage::$stabilities as $stability => $value) {
 47964 if ($value <= BasePackage::$stabilities[$minimumStability]) {
 47965 $this->acceptableStabilities[$stability] = $value;
 47966 }
 47967 }
 47968 $this->stabilityFlags = $stabilityFlags;
 47969 $this->rootRequires = $rootRequires;
 47970 foreach ($rootRequires as $name => $constraint) {
 47971 if (PlatformRepository::isPlatformPackage($name)) {
 47972 unset($this->rootRequires[$name]);
 47973 }
 47974 }
 47975 }
 47976 
 47977 
 47978 
 47979 
 47980 
 47981 
 47982 public function allowInstalledRepositories($allow = true)
 47983 {
 47984 $this->allowInstalledRepositories = $allow;
 47985 }
 47986 
 47987 
 47988 
 47989 
 47990 
 47991 public function getRootRequires()
 47992 {
 47993 return $this->rootRequires;
 47994 }
 47995 
 47996 
 47997 
 47998 
 47999 
 48000 
 48001 
 48002 
 48003 
 48004 
 48005 
 48006 public function addRepository(RepositoryInterface $repo)
 48007 {
 48008 if ($this->locked) {
 48009 throw new \RuntimeException("Pool has already been created from this repository set, it cannot be modified anymore.");
 48010 }
 48011 
 48012 if ($repo instanceof CompositeRepository) {
 48013 $repos = $repo->getRepositories();
 48014 } else {
 48015 $repos = array($repo);
 48016 }
 48017 
 48018 foreach ($repos as $repo) {
 48019 $this->repositories[] = $repo;
 48020 }
 48021 }
 48022 
 48023 
 48024 
 48025 
 48026 
 48027 
 48028 
 48029 
 48030 
 48031 
 48032 
 48033 public function findPackages($name, ConstraintInterface $constraint = null, $flags = 0)
 48034 {
 48035 $ignoreStability = ($flags & self::ALLOW_UNACCEPTABLE_STABILITIES) !== 0;
 48036 $loadFromAllRepos = ($flags & self::ALLOW_SHADOWED_REPOSITORIES) !== 0;
 48037 
 48038 $packages = array();
 48039 if ($loadFromAllRepos) {
 48040 foreach ($this->repositories as $repository) {
 48041 $packages[] = $repository->findPackages($name, $constraint) ?: array();
 48042 }
 48043 } else {
 48044 foreach ($this->repositories as $repository) {
 48045 $result = $repository->loadPackages(array($name => $constraint), $ignoreStability ? BasePackage::$stabilities : $this->acceptableStabilities, $ignoreStability ? array() : $this->stabilityFlags);
 48046 
 48047 $packages[] = $result['packages'];
 48048 foreach ($result['namesFound'] as $nameFound) {
 48049 
 48050 if ($name === $nameFound) {
 48051 break 2;
 48052 }
 48053 }
 48054 }
 48055 }
 48056 
 48057 $candidates = $packages ? call_user_func_array('array_merge', $packages) : array();
 48058 
 48059 
 48060 if ($ignoreStability || !$loadFromAllRepos) {
 48061 return $candidates;
 48062 }
 48063 
 48064 $result = array();
 48065 foreach ($candidates as $candidate) {
 48066 if ($this->isPackageAcceptable($candidate->getNames(), $candidate->getStability())) {
 48067 $result[] = $candidate;
 48068 }
 48069 }
 48070 
 48071 return $result;
 48072 }
 48073 
 48074 
 48075 
 48076 
 48077 
 48078 
 48079 
 48080 public function getProviders($packageName)
 48081 {
 48082 $providers = array();
 48083 foreach ($this->repositories as $repository) {
 48084 if ($repoProviders = $repository->getProviders($packageName)) {
 48085 $providers = array_merge($providers, $repoProviders);
 48086 }
 48087 }
 48088 
 48089 return $providers;
 48090 }
 48091 
 48092 
 48093 
 48094 
 48095 
 48096 
 48097 
 48098 
 48099 public function isPackageAcceptable($names, $stability)
 48100 {
 48101 return StabilityFilter::isPackageAcceptable($this->acceptableStabilities, $this->stabilityFlags, $names, $stability);
 48102 }
 48103 
 48104 
 48105 
 48106 
 48107 
 48108 
 48109 public function createPool(Request $request, IOInterface $io, EventDispatcher $eventDispatcher = null, PoolOptimizer $poolOptimizer = null)
 48110 {
 48111 $poolBuilder = new PoolBuilder($this->acceptableStabilities, $this->stabilityFlags, $this->rootAliases, $this->rootReferences, $io, $eventDispatcher, $poolOptimizer);
 48112 
 48113 foreach ($this->repositories as $repo) {
 48114 if (($repo instanceof InstalledRepositoryInterface || $repo instanceof InstalledRepository) && !$this->allowInstalledRepositories) {
 48115 throw new \LogicException('The pool can not accept packages from an installed repository');
 48116 }
 48117 }
 48118 
 48119 $this->locked = true;
 48120 
 48121 return $poolBuilder->buildPool($this->repositories, $request);
 48122 }
 48123 
 48124 
 48125 
 48126 
 48127 
 48128 
 48129 public function createPoolWithAllPackages()
 48130 {
 48131 foreach ($this->repositories as $repo) {
 48132 if (($repo instanceof InstalledRepositoryInterface || $repo instanceof InstalledRepository) && !$this->allowInstalledRepositories) {
 48133 throw new \LogicException('The pool can not accept packages from an installed repository');
 48134 }
 48135 }
 48136 
 48137 $this->locked = true;
 48138 
 48139 $packages = array();
 48140 foreach ($this->repositories as $repository) {
 48141 foreach ($repository->getPackages() as $package) {
 48142 $packages[] = $package;
 48143 
 48144 if (isset($this->rootAliases[$package->getName()][$package->getVersion()])) {
 48145 $alias = $this->rootAliases[$package->getName()][$package->getVersion()];
 48146 while ($package instanceof AliasPackage) {
 48147 $package = $package->getAliasOf();
 48148 }
 48149 if ($package instanceof CompletePackage) {
 48150 $aliasPackage = new CompleteAliasPackage($package, $alias['alias_normalized'], $alias['alias']);
 48151 } else {
 48152 $aliasPackage = new AliasPackage($package, $alias['alias_normalized'], $alias['alias']);
 48153 }
 48154 $aliasPackage->setRootPackageAlias(true);
 48155 $packages[] = $aliasPackage;
 48156 }
 48157 }
 48158 }
 48159 
 48160 return new Pool($packages);
 48161 }
 48162 
 48163 
 48164 
 48165 
 48166 
 48167 
 48168 public function createPoolForPackage($packageName, LockArrayRepository $lockedRepo = null)
 48169 {
 48170 
 48171 return $this->createPoolForPackages(array($packageName), $lockedRepo);
 48172 }
 48173 
 48174 
 48175 
 48176 
 48177 
 48178 
 48179 public function createPoolForPackages($packageNames, LockArrayRepository $lockedRepo = null)
 48180 {
 48181 $request = new Request($lockedRepo);
 48182 
 48183 foreach ($packageNames as $packageName) {
 48184 if (PlatformRepository::isPlatformPackage($packageName)) {
 48185 throw new \LogicException('createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.');
 48186 }
 48187 
 48188 $request->requireName($packageName);
 48189 }
 48190 
 48191 return $this->createPool($request, new NullIO());
 48192 }
 48193 
 48194 
 48195 
 48196 
 48197 
 48198 
 48199 
 48200 private static function getRootAliasesPerPackage(array $aliases)
 48201 {
 48202 $normalizedAliases = array();
 48203 
 48204 foreach ($aliases as $alias) {
 48205 $normalizedAliases[$alias['package']][$alias['version']] = array(
 48206 'alias' => $alias['alias'],
 48207 'alias_normalized' => $alias['alias_normalized'],
 48208 );
 48209 }
 48210 
 48211 return $normalizedAliases;
 48212 }
 48213 }
 48214 <?php
 48215 
 48216 
 48217 
 48218 
 48219 
 48220 
 48221 
 48222 
 48223 
 48224 
 48225 
 48226 namespace Composer\Repository;
 48227 
 48228 use Composer\Package\RootPackageInterface;
 48229 
 48230 
 48231 
 48232 
 48233 
 48234 
 48235 
 48236 
 48237 class RootPackageRepository extends ArrayRepository
 48238 {
 48239 public function __construct(RootPackageInterface $package)
 48240 {
 48241 parent::__construct(array($package));
 48242 }
 48243 
 48244 public function getRepoName()
 48245 {
 48246 return 'root package repo';
 48247 }
 48248 }
 48249 <?php
 48250 
 48251 
 48252 
 48253 
 48254 
 48255 
 48256 
 48257 
 48258 
 48259 
 48260 
 48261 namespace Composer\Repository\Vcs;
 48262 
 48263 use Composer\Cache;
 48264 use Composer\Config;
 48265 use Composer\Pcre\Preg;
 48266 use Composer\Util\ProcessExecutor;
 48267 use Composer\Util\Filesystem;
 48268 use Composer\IO\IOInterface;
 48269 
 48270 
 48271 
 48272 
 48273 class FossilDriver extends VcsDriver
 48274 {
 48275 
 48276 protected $tags;
 48277 
 48278 protected $branches;
 48279 
 48280 protected $rootIdentifier = null;
 48281 
 48282 protected $repoFile = null;
 48283 
 48284 protected $checkoutDir;
 48285 
 48286 
 48287 
 48288 
 48289 public function initialize()
 48290 {
 48291 
 48292 $this->checkFossil();
 48293 
 48294 
 48295 $this->config->prohibitUrlByConfig($this->url, $this->io);
 48296 
 48297 
 48298 
 48299 if (Filesystem::isLocalPath($this->url) && is_dir($this->url)) {
 48300 $this->checkoutDir = $this->url;
 48301 } else {
 48302 if (!Cache::isUsable((string) $this->config->get('cache-repo-dir')) || !Cache::isUsable((string) $this->config->get('cache-vcs-dir'))) {
 48303 throw new \RuntimeException('FossilDriver requires a usable cache directory, and it looks like you set it to be disabled');
 48304 }
 48305 
 48306 $localName = Preg::replace('{[^a-z0-9]}i', '-', $this->url);
 48307 $this->repoFile = $this->config->get('cache-repo-dir') . '/' . $localName . '.fossil';
 48308 $this->checkoutDir = $this->config->get('cache-vcs-dir') . '/' . $localName . '/';
 48309 
 48310 $this->updateLocalRepo();
 48311 }
 48312 
 48313 $this->getTags();
 48314 $this->getBranches();
 48315 }
 48316 
 48317 
 48318 
 48319 
 48320 
 48321 
 48322 protected function checkFossil()
 48323 {
 48324 if (0 !== $this->process->execute('fossil version', $ignoredOutput)) {
 48325 throw new \RuntimeException("fossil was not found, check that it is installed and in your PATH env.\n\n" . $this->process->getErrorOutput());
 48326 }
 48327 }
 48328 
 48329 
 48330 
 48331 
 48332 
 48333 
 48334 protected function updateLocalRepo()
 48335 {
 48336 $fs = new Filesystem();
 48337 $fs->ensureDirectoryExists($this->checkoutDir);
 48338 
 48339 if (!is_writable(dirname($this->checkoutDir))) {
 48340 throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.$this->checkoutDir.'" directory is not writable by the current user.');
 48341 }
 48342 
 48343 
 48344 if (is_file($this->repoFile) && is_dir($this->checkoutDir) && 0 === $this->process->execute('fossil info', $output, $this->checkoutDir)) {
 48345 if (0 !== $this->process->execute('fossil pull', $output, $this->checkoutDir)) {
 48346 $this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
 48347 }
 48348 } else {
 48349 
 48350 $fs->removeDirectory($this->checkoutDir);
 48351 $fs->remove($this->repoFile);
 48352 
 48353 $fs->ensureDirectoryExists($this->checkoutDir);
 48354 
 48355 if (0 !== $this->process->execute(sprintf('fossil clone -- %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoFile)), $output)) {
 48356 $output = $this->process->getErrorOutput();
 48357 
 48358 throw new \RuntimeException('Failed to clone '.$this->url.' to repository ' . $this->repoFile . "\n\n" .$output);
 48359 }
 48360 
 48361 if (0 !== $this->process->execute(sprintf('fossil open --nested -- %s', ProcessExecutor::escape($this->repoFile)), $output, $this->checkoutDir)) {
 48362 $output = $this->process->getErrorOutput();
 48363 
 48364 throw new \RuntimeException('Failed to open repository '.$this->repoFile.' in ' . $this->checkoutDir . "\n\n" .$output);
 48365 }
 48366 }
 48367 }
 48368 
 48369 
 48370 
 48371 
 48372 public function getRootIdentifier()
 48373 {
 48374 if (null === $this->rootIdentifier) {
 48375 $this->rootIdentifier = 'trunk';
 48376 }
 48377 
 48378 return $this->rootIdentifier;
 48379 }
 48380 
 48381 
 48382 
 48383 
 48384 public function getUrl()
 48385 {
 48386 return $this->url;
 48387 }
 48388 
 48389 
 48390 
 48391 
 48392 public function getSource($identifier)
 48393 {
 48394 return array('type' => 'fossil', 'url' => $this->getUrl(), 'reference' => $identifier);
 48395 }
 48396 
 48397 
 48398 
 48399 
 48400 public function getDist($identifier)
 48401 {
 48402 return null;
 48403 }
 48404 
 48405 
 48406 
 48407 
 48408 public function getFileContent($file, $identifier)
 48409 {
 48410 $command = sprintf('fossil cat -r %s -- %s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
 48411 $this->process->execute($command, $content, $this->checkoutDir);
 48412 
 48413 if (!trim($content)) {
 48414 return null;
 48415 }
 48416 
 48417 return $content;
 48418 }
 48419 
 48420 
 48421 
 48422 
 48423 public function getChangeDate($identifier)
 48424 {
 48425 $this->process->execute('fossil finfo -b -n 1 composer.json', $output, $this->checkoutDir);
 48426 list(, $date) = explode(' ', trim($output), 3);
 48427 
 48428 return new \DateTime($date, new \DateTimeZone('UTC'));
 48429 }
 48430 
 48431 
 48432 
 48433 
 48434 public function getTags()
 48435 {
 48436 if (null === $this->tags) {
 48437 $tags = array();
 48438 
 48439 $this->process->execute('fossil tag list', $output, $this->checkoutDir);
 48440 foreach ($this->process->splitLines($output) as $tag) {
 48441 $tags[$tag] = $tag;
 48442 }
 48443 
 48444 $this->tags = $tags;
 48445 }
 48446 
 48447 return $this->tags;
 48448 }
 48449 
 48450 
 48451 
 48452 
 48453 public function getBranches()
 48454 {
 48455 if (null === $this->branches) {
 48456 $branches = array();
 48457 
 48458 $this->process->execute('fossil branch list', $output, $this->checkoutDir);
 48459 foreach ($this->process->splitLines($output) as $branch) {
 48460 $branch = trim(Preg::replace('/^\*/', '', trim($branch)));
 48461 $branches[$branch] = $branch;
 48462 }
 48463 
 48464 $this->branches = $branches;
 48465 }
 48466 
 48467 return $this->branches;
 48468 }
 48469 
 48470 
 48471 
 48472 
 48473 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 48474 {
 48475 if (Preg::isMatch('#(^(?:https?|ssh)://(?:[^@]@)?(?:chiselapp\.com|fossil\.))#i', $url)) {
 48476 return true;
 48477 }
 48478 
 48479 if (Preg::isMatch('!/fossil/|\.fossil!', $url)) {
 48480 return true;
 48481 }
 48482 
 48483 
 48484 if (Filesystem::isLocalPath($url)) {
 48485 $url = Filesystem::getPlatformPath($url);
 48486 if (!is_dir($url)) {
 48487 return false;
 48488 }
 48489 
 48490 $process = new ProcessExecutor($io);
 48491 
 48492 if ($process->execute('fossil info', $output, $url) === 0) {
 48493 return true;
 48494 }
 48495 }
 48496 
 48497 return false;
 48498 }
 48499 }
 48500 <?php
 48501 
 48502 
 48503 
 48504 
 48505 
 48506 
 48507 
 48508 
 48509 
 48510 
 48511 
 48512 namespace Composer\Repository\Vcs;
 48513 
 48514 use Composer\Config;
 48515 use Composer\IO\IOInterface;
 48516 use Composer\Cache;
 48517 use Composer\Downloader\TransportException;
 48518 use Composer\Json\JsonFile;
 48519 use Composer\Pcre\Preg;
 48520 use Composer\Util\Bitbucket;
 48521 use Composer\Util\Http\Response;
 48522 
 48523 
 48524 
 48525 
 48526 class GitBitbucketDriver extends VcsDriver
 48527 {
 48528 
 48529 protected $owner;
 48530 
 48531 protected $repository;
 48532 
 48533 private $hasIssues = false;
 48534 
 48535 private $rootIdentifier;
 48536 
 48537 private $tags;
 48538 
 48539 private $branches;
 48540 
 48541 private $branchesUrl = '';
 48542 
 48543 private $tagsUrl = '';
 48544 
 48545 private $homeUrl = '';
 48546 
 48547 private $website = '';
 48548 
 48549 private $cloneHttpsUrl = '';
 48550 
 48551 
 48552 
 48553 
 48554 protected $fallbackDriver = null;
 48555 
 48556 private $vcsType;
 48557 
 48558 
 48559 
 48560 
 48561 public function initialize()
 48562 {
 48563 if (!Preg::isMatch('#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i', $this->url, $match)) {
 48564 throw new \InvalidArgumentException(sprintf('The Bitbucket repository URL %s is invalid. It must be the HTTPS URL of a Bitbucket repository.', $this->url));
 48565 }
 48566 
 48567 $this->owner = $match[1];
 48568 $this->repository = $match[2];
 48569 $this->originUrl = 'bitbucket.org';
 48570 $this->cache = new Cache(
 48571 $this->io,
 48572 implode('/', array(
 48573 $this->config->get('cache-repo-dir'),
 48574 $this->originUrl,
 48575 $this->owner,
 48576 $this->repository,
 48577 ))
 48578 );
 48579 $this->cache->setReadOnly($this->config->get('cache-read-only'));
 48580 }
 48581 
 48582 
 48583 
 48584 
 48585 public function getUrl()
 48586 {
 48587 if ($this->fallbackDriver) {
 48588 return $this->fallbackDriver->getUrl();
 48589 }
 48590 
 48591 return $this->cloneHttpsUrl;
 48592 }
 48593 
 48594 
 48595 
 48596 
 48597 
 48598 
 48599 
 48600 
 48601 protected function getRepoData()
 48602 {
 48603 $resource = sprintf(
 48604 'https://api.bitbucket.org/2.0/repositories/%s/%s?%s',
 48605 $this->owner,
 48606 $this->repository,
 48607 http_build_query(
 48608 array('fields' => '-project,-owner'),
 48609 '',
 48610 '&'
 48611 )
 48612 );
 48613 
 48614 $repoData = $this->fetchWithOAuthCredentials($resource, true)->decodeJson();
 48615 if ($this->fallbackDriver) {
 48616 return false;
 48617 }
 48618 $this->parseCloneUrls($repoData['links']['clone']);
 48619 
 48620 $this->hasIssues = !empty($repoData['has_issues']);
 48621 $this->branchesUrl = $repoData['links']['branches']['href'];
 48622 $this->tagsUrl = $repoData['links']['tags']['href'];
 48623 $this->homeUrl = $repoData['links']['html']['href'];
 48624 $this->website = $repoData['website'];
 48625 $this->vcsType = $repoData['scm'];
 48626 
 48627 return true;
 48628 }
 48629 
 48630 
 48631 
 48632 
 48633 public function getComposerInformation($identifier)
 48634 {
 48635 if ($this->fallbackDriver) {
 48636 return $this->fallbackDriver->getComposerInformation($identifier);
 48637 }
 48638 
 48639 if (!isset($this->infoCache[$identifier])) {
 48640 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
 48641 $composer = JsonFile::parseJson($res);
 48642 } else {
 48643 $composer = $this->getBaseComposerInformation($identifier);
 48644 
 48645 if ($this->shouldCache($identifier)) {
 48646 $this->cache->write($identifier, json_encode($composer));
 48647 }
 48648 }
 48649 
 48650 if ($composer) {
 48651 
 48652 if (!isset($composer['support']['source'])) {
 48653 $label = array_search(
 48654 $identifier,
 48655 $this->getTags()
 48656 ) ?: array_search(
 48657 $identifier,
 48658 $this->getBranches()
 48659 ) ?: $identifier;
 48660 
 48661 if (array_key_exists($label, $tags = $this->getTags())) {
 48662 $hash = $tags[$label];
 48663 } elseif (array_key_exists($label, $branches = $this->getBranches())) {
 48664 $hash = $branches[$label];
 48665 }
 48666 
 48667 if (!isset($hash)) {
 48668 $composer['support']['source'] = sprintf(
 48669 'https://%s/%s/%s/src',
 48670 $this->originUrl,
 48671 $this->owner,
 48672 $this->repository
 48673 );
 48674 } else {
 48675 $composer['support']['source'] = sprintf(
 48676 'https://%s/%s/%s/src/%s/?at=%s',
 48677 $this->originUrl,
 48678 $this->owner,
 48679 $this->repository,
 48680 $hash,
 48681 $label
 48682 );
 48683 }
 48684 }
 48685 if (!isset($composer['support']['issues']) && $this->hasIssues) {
 48686 $composer['support']['issues'] = sprintf(
 48687 'https://%s/%s/%s/issues',
 48688 $this->originUrl,
 48689 $this->owner,
 48690 $this->repository
 48691 );
 48692 }
 48693 if (!isset($composer['homepage'])) {
 48694 $composer['homepage'] = empty($this->website) ? $this->homeUrl : $this->website;
 48695 }
 48696 }
 48697 
 48698 $this->infoCache[$identifier] = $composer;
 48699 }
 48700 
 48701 return $this->infoCache[$identifier];
 48702 }
 48703 
 48704 
 48705 
 48706 
 48707 public function getFileContent($file, $identifier)
 48708 {
 48709 if ($this->fallbackDriver) {
 48710 return $this->fallbackDriver->getFileContent($file, $identifier);
 48711 }
 48712 
 48713 if (strpos($identifier, '/') !== false) {
 48714 $branches = $this->getBranches();
 48715 if (isset($branches[$identifier])) {
 48716 $identifier = $branches[$identifier];
 48717 }
 48718 }
 48719 
 48720 $resource = sprintf(
 48721 'https://api.bitbucket.org/2.0/repositories/%s/%s/src/%s/%s',
 48722 $this->owner,
 48723 $this->repository,
 48724 $identifier,
 48725 $file
 48726 );
 48727 
 48728 return $this->fetchWithOAuthCredentials($resource)->getBody();
 48729 }
 48730 
 48731 
 48732 
 48733 
 48734 public function getChangeDate($identifier)
 48735 {
 48736 if ($this->fallbackDriver) {
 48737 return $this->fallbackDriver->getChangeDate($identifier);
 48738 }
 48739 
 48740 if (strpos($identifier, '/') !== false) {
 48741 $branches = $this->getBranches();
 48742 if (isset($branches[$identifier])) {
 48743 $identifier = $branches[$identifier];
 48744 }
 48745 }
 48746 
 48747 $resource = sprintf(
 48748 'https://api.bitbucket.org/2.0/repositories/%s/%s/commit/%s?fields=date',
 48749 $this->owner,
 48750 $this->repository,
 48751 $identifier
 48752 );
 48753 $commit = $this->fetchWithOAuthCredentials($resource)->decodeJson();
 48754 
 48755 return new \DateTime($commit['date']);
 48756 }
 48757 
 48758 
 48759 
 48760 
 48761 public function getSource($identifier)
 48762 {
 48763 if ($this->fallbackDriver) {
 48764 return $this->fallbackDriver->getSource($identifier);
 48765 }
 48766 
 48767 return array('type' => $this->vcsType, 'url' => $this->getUrl(), 'reference' => $identifier);
 48768 }
 48769 
 48770 
 48771 
 48772 
 48773 public function getDist($identifier)
 48774 {
 48775 if ($this->fallbackDriver) {
 48776 return $this->fallbackDriver->getDist($identifier);
 48777 }
 48778 
 48779 $url = sprintf(
 48780 'https://bitbucket.org/%s/%s/get/%s.zip',
 48781 $this->owner,
 48782 $this->repository,
 48783 $identifier
 48784 );
 48785 
 48786 return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');
 48787 }
 48788 
 48789 
 48790 
 48791 
 48792 public function getTags()
 48793 {
 48794 if ($this->fallbackDriver) {
 48795 return $this->fallbackDriver->getTags();
 48796 }
 48797 
 48798 if (null === $this->tags) {
 48799 $tags = array();
 48800 $resource = sprintf(
 48801 '%s?%s',
 48802 $this->tagsUrl,
 48803 http_build_query(
 48804 array(
 48805 'pagelen' => 100,
 48806 'fields' => 'values.name,values.target.hash,next',
 48807 'sort' => '-target.date',
 48808 ),
 48809 '',
 48810 '&'
 48811 )
 48812 );
 48813 $hasNext = true;
 48814 while ($hasNext) {
 48815 $tagsData = $this->fetchWithOAuthCredentials($resource)->decodeJson();
 48816 foreach ($tagsData['values'] as $data) {
 48817 $tags[$data['name']] = $data['target']['hash'];
 48818 }
 48819 if (empty($tagsData['next'])) {
 48820 $hasNext = false;
 48821 } else {
 48822 $resource = $tagsData['next'];
 48823 }
 48824 }
 48825 
 48826 $this->tags = $tags;
 48827 }
 48828 
 48829 return $this->tags;
 48830 }
 48831 
 48832 
 48833 
 48834 
 48835 public function getBranches()
 48836 {
 48837 if ($this->fallbackDriver) {
 48838 return $this->fallbackDriver->getBranches();
 48839 }
 48840 
 48841 if (null === $this->branches) {
 48842 $branches = array();
 48843 $resource = sprintf(
 48844 '%s?%s',
 48845 $this->branchesUrl,
 48846 http_build_query(
 48847 array(
 48848 'pagelen' => 100,
 48849 'fields' => 'values.name,values.target.hash,values.heads,next',
 48850 'sort' => '-target.date',
 48851 ),
 48852 '',
 48853 '&'
 48854 )
 48855 );
 48856 $hasNext = true;
 48857 while ($hasNext) {
 48858 $branchData = $this->fetchWithOAuthCredentials($resource)->decodeJson();
 48859 foreach ($branchData['values'] as $data) {
 48860 $branches[$data['name']] = $data['target']['hash'];
 48861 }
 48862 if (empty($branchData['next'])) {
 48863 $hasNext = false;
 48864 } else {
 48865 $resource = $branchData['next'];
 48866 }
 48867 }
 48868 
 48869 $this->branches = $branches;
 48870 }
 48871 
 48872 return $this->branches;
 48873 }
 48874 
 48875 
 48876 
 48877 
 48878 
 48879 
 48880 
 48881 
 48882 
 48883 
 48884 
 48885 protected function fetchWithOAuthCredentials($url, $fetchingRepoData = false)
 48886 {
 48887 try {
 48888 return parent::getContents($url);
 48889 } catch (TransportException $e) {
 48890 $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->httpDownloader);
 48891 
 48892 if (403 === $e->getCode() || (401 === $e->getCode() && strpos($e->getMessage(), 'Could not authenticate against') === 0)) {
 48893 if (!$this->io->hasAuthentication($this->originUrl)
 48894 && $bitbucketUtil->authorizeOAuth($this->originUrl)
 48895 ) {
 48896 return parent::getContents($url);
 48897 }
 48898 
 48899 if (!$this->io->isInteractive() && $fetchingRepoData) {
 48900 $this->attemptCloneFallback();
 48901 
 48902 return new Response(array('url' => 'dummy'), 200, array(), 'null');
 48903 }
 48904 }
 48905 
 48906 throw $e;
 48907 }
 48908 }
 48909 
 48910 
 48911 
 48912 
 48913 
 48914 
 48915 protected function generateSshUrl()
 48916 {
 48917 return 'git@' . $this->originUrl . ':' . $this->owner.'/'.$this->repository.'.git';
 48918 }
 48919 
 48920 
 48921 
 48922 
 48923 
 48924 
 48925 
 48926 protected function attemptCloneFallback()
 48927 {
 48928 try {
 48929 $this->setupFallbackDriver($this->generateSshUrl());
 48930 
 48931 return true;
 48932 } catch (\RuntimeException $e) {
 48933 $this->fallbackDriver = null;
 48934 
 48935 $this->io->writeError(
 48936 '<error>Failed to clone the ' . $this->generateSshUrl() . ' repository, try running in interactive mode'
 48937 . ' so that you can enter your Bitbucket OAuth consumer credentials</error>'
 48938 );
 48939 throw $e;
 48940 }
 48941 }
 48942 
 48943 
 48944 
 48945 
 48946 
 48947 protected function setupFallbackDriver($url)
 48948 {
 48949 $this->fallbackDriver = new GitDriver(
 48950 array('url' => $url),
 48951 $this->io,
 48952 $this->config,
 48953 $this->httpDownloader,
 48954 $this->process
 48955 );
 48956 $this->fallbackDriver->initialize();
 48957 }
 48958 
 48959 
 48960 
 48961 
 48962 
 48963 protected function parseCloneUrls(array $cloneLinks)
 48964 {
 48965 foreach ($cloneLinks as $cloneLink) {
 48966 if ($cloneLink['name'] === 'https') {
 48967 
 48968 
 48969 $this->cloneHttpsUrl = Preg::replace('/https:\/\/([^@]+@)?/', 'https://', $cloneLink['href']);
 48970 }
 48971 }
 48972 }
 48973 
 48974 
 48975 
 48976 
 48977 protected function getMainBranchData()
 48978 {
 48979 $resource = sprintf(
 48980 'https://api.bitbucket.org/2.0/repositories/%s/%s?fields=mainbranch',
 48981 $this->owner,
 48982 $this->repository
 48983 );
 48984 
 48985 $data = $this->fetchWithOAuthCredentials($resource)->decodeJson();
 48986 if (isset($data['mainbranch'])) {
 48987 return $data['mainbranch'];
 48988 }
 48989 
 48990 return null;
 48991 }
 48992 
 48993 
 48994 
 48995 
 48996 public function getRootIdentifier()
 48997 {
 48998 if ($this->fallbackDriver) {
 48999 return $this->fallbackDriver->getRootIdentifier();
 49000 }
 49001 
 49002 if (null === $this->rootIdentifier) {
 49003 if (!$this->getRepoData()) {
 49004 if (!$this->fallbackDriver) {
 49005 throw new \LogicException('A fallback driver should be setup if getRepoData returns false');
 49006 }
 49007 
 49008 return $this->fallbackDriver->getRootIdentifier();
 49009 }
 49010 
 49011 if ($this->vcsType !== 'git') {
 49012 throw new \RuntimeException(
 49013 $this->url.' does not appear to be a git repository, use '.
 49014 $this->cloneHttpsUrl.' but remember that Bitbucket no longer supports the mercurial repositories. '.
 49015 'https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket'
 49016 );
 49017 }
 49018 
 49019 $mainBranchData = $this->getMainBranchData();
 49020 $this->rootIdentifier = !empty($mainBranchData['name']) ? $mainBranchData['name'] : 'master';
 49021 }
 49022 
 49023 return $this->rootIdentifier;
 49024 }
 49025 
 49026 
 49027 
 49028 
 49029 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 49030 {
 49031 if (!Preg::isMatch('#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i', $url)) {
 49032 return false;
 49033 }
 49034 
 49035 if (!extension_loaded('openssl')) {
 49036 $io->writeError('Skipping Bitbucket git driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
 49037 
 49038 return false;
 49039 }
 49040 
 49041 return true;
 49042 }
 49043 }
 49044 <?php
 49045 
 49046 
 49047 
 49048 
 49049 
 49050 
 49051 
 49052 
 49053 
 49054 
 49055 
 49056 namespace Composer\Repository\Vcs;
 49057 
 49058 use Composer\Pcre\Preg;
 49059 use Composer\Util\ProcessExecutor;
 49060 use Composer\Util\Filesystem;
 49061 use Composer\Util\Url;
 49062 use Composer\Util\Git as GitUtil;
 49063 use Composer\IO\IOInterface;
 49064 use Composer\Cache;
 49065 use Composer\Config;
 49066 
 49067 
 49068 
 49069 
 49070 class GitDriver extends VcsDriver
 49071 {
 49072 
 49073 protected $tags;
 49074 
 49075 protected $branches;
 49076 
 49077 protected $rootIdentifier;
 49078 
 49079 protected $repoDir;
 49080 
 49081 
 49082 
 49083 
 49084 public function initialize()
 49085 {
 49086 if (Filesystem::isLocalPath($this->url)) {
 49087 $this->url = Preg::replace('{[\\/]\.git/?$}', '', $this->url);
 49088 if (!is_dir($this->url)) {
 49089 throw new \RuntimeException('Failed to read package information from '.$this->url.' as the path does not exist');
 49090 }
 49091 $this->repoDir = $this->url;
 49092 $cacheUrl = realpath($this->url);
 49093 } else {
 49094 if (!Cache::isUsable((string) $this->config->get('cache-vcs-dir'))) {
 49095 throw new \RuntimeException('GitDriver requires a usable cache directory, and it looks like you set it to be disabled');
 49096 }
 49097 
 49098 $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . Preg::replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
 49099 
 49100 GitUtil::cleanEnv();
 49101 
 49102 $fs = new Filesystem();
 49103 $fs->ensureDirectoryExists(dirname($this->repoDir));
 49104 
 49105 if (!is_writable(dirname($this->repoDir))) {
 49106 throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.dirname($this->repoDir).'" directory is not writable by the current user.');
 49107 }
 49108 
 49109 if (Preg::isMatch('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
 49110 throw new \InvalidArgumentException('The source URL '.$this->url.' is invalid, ssh URLs should have a port number after ":".'."\n".'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
 49111 }
 49112 
 49113 $gitUtil = new GitUtil($this->io, $this->config, $this->process, $fs);
 49114 if (!$gitUtil->syncMirror($this->url, $this->repoDir)) {
 49115 if (!is_dir($this->repoDir)) {
 49116 throw new \RuntimeException('Failed to clone '.$this->url.' to read package information from it');
 49117 }
 49118 $this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated</error>');
 49119 }
 49120 
 49121 $cacheUrl = $this->url;
 49122 }
 49123 
 49124 $this->getTags();
 49125 $this->getBranches();
 49126 
 49127 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($cacheUrl)));
 49128 $this->cache->setReadOnly($this->config->get('cache-read-only'));
 49129 }
 49130 
 49131 
 49132 
 49133 
 49134 public function getRootIdentifier()
 49135 {
 49136 if (null === $this->rootIdentifier) {
 49137 $this->rootIdentifier = 'master';
 49138 
 49139 
 49140 $this->process->execute('git branch --no-color', $output, $this->repoDir);
 49141 $branches = $this->process->splitLines($output);
 49142 if (!in_array('* master', $branches)) {
 49143 foreach ($branches as $branch) {
 49144 if ($branch && Preg::isMatch('{^\* +(\S+)}', $branch, $match)) {
 49145 $this->rootIdentifier = $match[1];
 49146 break;
 49147 }
 49148 }
 49149 }
 49150 }
 49151 
 49152 return $this->rootIdentifier;
 49153 }
 49154 
 49155 
 49156 
 49157 
 49158 public function getUrl()
 49159 {
 49160 return $this->url;
 49161 }
 49162 
 49163 
 49164 
 49165 
 49166 public function getSource($identifier)
 49167 {
 49168 return array('type' => 'git', 'url' => $this->getUrl(), 'reference' => $identifier);
 49169 }
 49170 
 49171 
 49172 
 49173 
 49174 public function getDist($identifier)
 49175 {
 49176 return null;
 49177 }
 49178 
 49179 
 49180 
 49181 
 49182 public function getFileContent($file, $identifier)
 49183 {
 49184 $resource = sprintf('%s:%s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
 49185 $this->process->execute(sprintf('git show %s', $resource), $content, $this->repoDir);
 49186 
 49187 if (!trim($content)) {
 49188 return null;
 49189 }
 49190 
 49191 return $content;
 49192 }
 49193 
 49194 
 49195 
 49196 
 49197 public function getChangeDate($identifier)
 49198 {
 49199 $this->process->execute(sprintf(
 49200 'git -c log.showSignature=false log -1 --format=%%at %s',
 49201 ProcessExecutor::escape($identifier)
 49202 ), $output, $this->repoDir);
 49203 
 49204 return new \DateTime('@'.trim($output), new \DateTimeZone('UTC'));
 49205 }
 49206 
 49207 
 49208 
 49209 
 49210 public function getTags()
 49211 {
 49212 if (null === $this->tags) {
 49213 $this->tags = array();
 49214 
 49215 $this->process->execute('git show-ref --tags --dereference', $output, $this->repoDir);
 49216 foreach ($output = $this->process->splitLines($output) as $tag) {
 49217 if ($tag && Preg::isMatch('{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}', $tag, $match)) {
 49218 $this->tags[$match[2]] = (string) $match[1];
 49219 }
 49220 }
 49221 }
 49222 
 49223 return $this->tags;
 49224 }
 49225 
 49226 
 49227 
 49228 
 49229 public function getBranches()
 49230 {
 49231 if (null === $this->branches) {
 49232 $branches = array();
 49233 
 49234 $this->process->execute('git branch --no-color --no-abbrev -v', $output, $this->repoDir);
 49235 foreach ($this->process->splitLines($output) as $branch) {
 49236 if ($branch && !Preg::isMatch('{^ *[^/]+/HEAD }', $branch)) {
 49237 if (Preg::isMatch('{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}', $branch, $match)) {
 49238 $branches[$match[1]] = $match[2];
 49239 }
 49240 }
 49241 }
 49242 
 49243 $this->branches = $branches;
 49244 }
 49245 
 49246 return $this->branches;
 49247 }
 49248 
 49249 
 49250 
 49251 
 49252 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 49253 {
 49254 if (Preg::isMatch('#(^git://|\.git/?$|git(?:olite)?@|//git\.|//github.com/)#i', $url)) {
 49255 return true;
 49256 }
 49257 
 49258 
 49259 if (Filesystem::isLocalPath($url)) {
 49260 $url = Filesystem::getPlatformPath($url);
 49261 if (!is_dir($url)) {
 49262 return false;
 49263 }
 49264 
 49265 $process = new ProcessExecutor($io);
 49266 
 49267 if ($process->execute('git tag', $output, $url) === 0) {
 49268 return true;
 49269 }
 49270 }
 49271 
 49272 if (!$deep) {
 49273 return false;
 49274 }
 49275 
 49276 $gitUtil = new GitUtil($io, $config, new ProcessExecutor($io), new Filesystem());
 49277 GitUtil::cleanEnv();
 49278 
 49279 try {
 49280 $gitUtil->runCommand(function ($url) {
 49281 return 'git ls-remote --heads -- ' . ProcessExecutor::escape($url);
 49282 }, $url, sys_get_temp_dir());
 49283 } catch (\RuntimeException $e) {
 49284 return false;
 49285 }
 49286 
 49287 return true;
 49288 }
 49289 }
 49290 <?php
 49291 
 49292 
 49293 
 49294 
 49295 
 49296 
 49297 
 49298 
 49299 
 49300 
 49301 
 49302 namespace Composer\Repository\Vcs;
 49303 
 49304 use Composer\Config;
 49305 use Composer\Downloader\TransportException;
 49306 use Composer\Json\JsonFile;
 49307 use Composer\Cache;
 49308 use Composer\IO\IOInterface;
 49309 use Composer\Pcre\Preg;
 49310 use Composer\Util\GitHub;
 49311 use Composer\Util\Http\Response;
 49312 
 49313 
 49314 
 49315 
 49316 class GitHubDriver extends VcsDriver
 49317 {
 49318 
 49319 protected $owner;
 49320 
 49321 protected $repository;
 49322 
 49323 protected $tags;
 49324 
 49325 protected $branches;
 49326 
 49327 protected $rootIdentifier;
 49328 
 49329 protected $repoData;
 49330 
 49331 protected $hasIssues = false;
 49332 
 49333 protected $isPrivate = false;
 49334 
 49335 private $isArchived = false;
 49336 
 49337 private $fundingInfo;
 49338 
 49339 
 49340 
 49341 
 49342 
 49343 
 49344 protected $gitDriver = null;
 49345 
 49346 
 49347 
 49348 
 49349 public function initialize()
 49350 {
 49351 if (!Preg::isMatch('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/(.+?)(?:\.git|/)?$#', $this->url, $match)) {
 49352 throw new \InvalidArgumentException(sprintf('The GitHub repository URL %s is invalid.', $this->url));
 49353 }
 49354 
 49355 $this->owner = $match[3];
 49356 $this->repository = $match[4];
 49357 $this->originUrl = strtolower(!empty($match[1]) ? $match[1] : $match[2]);
 49358 if ($this->originUrl === 'www.github.com') {
 49359 $this->originUrl = 'github.com';
 49360 }
 49361 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->owner.'/'.$this->repository);
 49362 $this->cache->setReadOnly($this->config->get('cache-read-only'));
 49363 
 49364 if ($this->config->get('use-github-api') === false || (isset($this->repoConfig['no-api']) && $this->repoConfig['no-api'])) {
 49365 $this->setupGitDriver($this->url);
 49366 
 49367 return;
 49368 }
 49369 
 49370 $this->fetchRootIdentifier();
 49371 }
 49372 
 49373 
 49374 
 49375 
 49376 public function getRepositoryUrl()
 49377 {
 49378 return 'https://'.$this->originUrl.'/'.$this->owner.'/'.$this->repository;
 49379 }
 49380 
 49381 
 49382 
 49383 
 49384 public function getRootIdentifier()
 49385 {
 49386 if ($this->gitDriver) {
 49387 return $this->gitDriver->getRootIdentifier();
 49388 }
 49389 
 49390 return $this->rootIdentifier;
 49391 }
 49392 
 49393 
 49394 
 49395 
 49396 public function getUrl()
 49397 {
 49398 if ($this->gitDriver) {
 49399 return $this->gitDriver->getUrl();
 49400 }
 49401 
 49402 return 'https://' . $this->originUrl . '/'.$this->owner.'/'.$this->repository.'.git';
 49403 }
 49404 
 49405 
 49406 
 49407 
 49408 protected function getApiUrl()
 49409 {
 49410 if ('github.com' === $this->originUrl) {
 49411 $apiUrl = 'api.github.com';
 49412 } else {
 49413 $apiUrl = $this->originUrl . '/api/v3';
 49414 }
 49415 
 49416 return 'https://' . $apiUrl;
 49417 }
 49418 
 49419 
 49420 
 49421 
 49422 public function getSource($identifier)
 49423 {
 49424 if ($this->gitDriver) {
 49425 return $this->gitDriver->getSource($identifier);
 49426 }
 49427 if ($this->isPrivate) {
 49428 
 49429 
 49430 $url = $this->generateSshUrl();
 49431 } else {
 49432 $url = $this->getUrl();
 49433 }
 49434 
 49435 return array('type' => 'git', 'url' => $url, 'reference' => $identifier);
 49436 }
 49437 
 49438 
 49439 
 49440 
 49441 public function getDist($identifier)
 49442 {
 49443 $url = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/zipball/'.$identifier;
 49444 
 49445 return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');
 49446 }
 49447 
 49448 
 49449 
 49450 
 49451 public function getComposerInformation($identifier)
 49452 {
 49453 if ($this->gitDriver) {
 49454 return $this->gitDriver->getComposerInformation($identifier);
 49455 }
 49456 
 49457 if (!isset($this->infoCache[$identifier])) {
 49458 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
 49459 $composer = JsonFile::parseJson($res);
 49460 } else {
 49461 $composer = $this->getBaseComposerInformation($identifier);
 49462 
 49463 if ($this->shouldCache($identifier)) {
 49464 $this->cache->write($identifier, json_encode($composer));
 49465 }
 49466 }
 49467 
 49468 if ($composer) {
 49469 
 49470 if (!isset($composer['support']['source'])) {
 49471 $label = array_search($identifier, $this->getTags()) ?: array_search($identifier, $this->getBranches()) ?: $identifier;
 49472 $composer['support']['source'] = sprintf('https://%s/%s/%s/tree/%s', $this->originUrl, $this->owner, $this->repository, $label);
 49473 }
 49474 if (!isset($composer['support']['issues']) && $this->hasIssues) {
 49475 $composer['support']['issues'] = sprintf('https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository);
 49476 }
 49477 if (!isset($composer['abandoned']) && $this->isArchived) {
 49478 $composer['abandoned'] = true;
 49479 }
 49480 if (!isset($composer['funding']) && $funding = $this->getFundingInfo()) {
 49481 $composer['funding'] = $funding;
 49482 }
 49483 }
 49484 
 49485 $this->infoCache[$identifier] = $composer;
 49486 }
 49487 
 49488 return $this->infoCache[$identifier];
 49489 }
 49490 
 49491 
 49492 
 49493 
 49494 private function getFundingInfo()
 49495 {
 49496 if (null !== $this->fundingInfo) {
 49497 return $this->fundingInfo;
 49498 }
 49499 
 49500 if ($this->originUrl !== 'github.com') {
 49501 return $this->fundingInfo = false;
 49502 }
 49503 
 49504 foreach (array($this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/.github/FUNDING.yml', $this->getApiUrl() . '/repos/'.$this->owner.'/.github/contents/FUNDING.yml') as $file) {
 49505 try {
 49506 $response = $this->httpDownloader->get($file, array(
 49507 'retry-auth-failure' => false,
 49508 ))->decodeJson();
 49509 } catch (TransportException $e) {
 49510 continue;
 49511 }
 49512 if (empty($response['content']) || $response['encoding'] !== 'base64' || !($funding = base64_decode($response['content']))) {
 49513 continue;
 49514 }
 49515 break;
 49516 }
 49517 if (empty($funding)) {
 49518 return $this->fundingInfo = false;
 49519 }
 49520 
 49521 $result = array();
 49522 $key = null;
 49523 foreach (Preg::split('{\r?\n}', $funding) as $line) {
 49524 $line = trim($line);
 49525 if (Preg::isMatch('{^(\w+)\s*:\s*(.+)$}', $line, $match)) {
 49526 if (Preg::isMatch('{^\[(.*)\](?:\s*#.*)?$}', $match[2], $match2)) {
 49527 foreach (array_map('trim', Preg::split('{[\'"]?\s*,\s*[\'"]?}', $match2[1])) as $item) {
 49528 $result[] = array('type' => $match[1], 'url' => trim($item, '"\' '));
 49529 }
 49530 } elseif (Preg::isMatch('{^([^#].*?)(\s+#.*)?$}', $match[2], $match2)) {
 49531 $result[] = array('type' => $match[1], 'url' => trim($match2[1], '"\' '));
 49532 }
 49533 $key = null;
 49534 } elseif (Preg::isMatch('{^(\w+)\s*:\s*#\s*$}', $line, $match)) {
 49535 $key = $match[1];
 49536 } elseif ($key && Preg::isMatch('{^-\s*(.+)(\s+#.*)?$}', $line, $match)) {
 49537 $result[] = array('type' => $key, 'url' => trim($match[1], '"\' '));
 49538 }
 49539 }
 49540 
 49541 foreach ($result as $key => $item) {
 49542 switch ($item['type']) {
 49543 case 'tidelift':
 49544 $result[$key]['url'] = 'https://tidelift.com/funding/github/' . $item['url'];
 49545 break;
 49546 case 'github':
 49547 $result[$key]['url'] = 'https://github.com/' . basename($item['url']);
 49548 break;
 49549 case 'patreon':
 49550 $result[$key]['url'] = 'https://www.patreon.com/' . basename($item['url']);
 49551 break;
 49552 case 'otechie':
 49553 $result[$key]['url'] = 'https://otechie.com/' . basename($item['url']);
 49554 break;
 49555 case 'open_collective':
 49556 $result[$key]['url'] = 'https://opencollective.com/' . basename($item['url']);
 49557 break;
 49558 case 'liberapay':
 49559 $result[$key]['url'] = 'https://liberapay.com/' . basename($item['url']);
 49560 break;
 49561 case 'ko_fi':
 49562 $result[$key]['url'] = 'https://ko-fi.com/' . basename($item['url']);
 49563 break;
 49564 case 'issuehunt':
 49565 $result[$key]['url'] = 'https://issuehunt.io/r/' . $item['url'];
 49566 break;
 49567 case 'community_bridge':
 49568 $result[$key]['url'] = 'https://funding.communitybridge.org/projects/' . basename($item['url']);
 49569 break;
 49570 }
 49571 }
 49572 
 49573 return $this->fundingInfo = $result;
 49574 }
 49575 
 49576 
 49577 
 49578 
 49579 public function getFileContent($file, $identifier)
 49580 {
 49581 if ($this->gitDriver) {
 49582 return $this->gitDriver->getFileContent($file, $identifier);
 49583 }
 49584 
 49585 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier);
 49586 $resource = $this->getContents($resource)->decodeJson();
 49587 if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) {
 49588 throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier);
 49589 }
 49590 
 49591 return $content;
 49592 }
 49593 
 49594 
 49595 
 49596 
 49597 public function getChangeDate($identifier)
 49598 {
 49599 if ($this->gitDriver) {
 49600 return $this->gitDriver->getChangeDate($identifier);
 49601 }
 49602 
 49603 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier);
 49604 $commit = $this->getContents($resource)->decodeJson();
 49605 
 49606 return new \DateTime($commit['commit']['committer']['date']);
 49607 }
 49608 
 49609 
 49610 
 49611 
 49612 public function getTags()
 49613 {
 49614 if ($this->gitDriver) {
 49615 return $this->gitDriver->getTags();
 49616 }
 49617 if (null === $this->tags) {
 49618 $tags = array();
 49619 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/tags?per_page=100';
 49620 
 49621 do {
 49622 $response = $this->getContents($resource);
 49623 $tagsData = $response->decodeJson();
 49624 foreach ($tagsData as $tag) {
 49625 $tags[$tag['name']] = $tag['commit']['sha'];
 49626 }
 49627 
 49628 $resource = $this->getNextPage($response);
 49629 } while ($resource);
 49630 
 49631 $this->tags = $tags;
 49632 }
 49633 
 49634 return $this->tags;
 49635 }
 49636 
 49637 
 49638 
 49639 
 49640 public function getBranches()
 49641 {
 49642 if ($this->gitDriver) {
 49643 return $this->gitDriver->getBranches();
 49644 }
 49645 if (null === $this->branches) {
 49646 $branches = array();
 49647 $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/git/refs/heads?per_page=100';
 49648 
 49649 do {
 49650 $response = $this->getContents($resource);
 49651 $branchData = $response->decodeJson();
 49652 foreach ($branchData as $branch) {
 49653 $name = substr($branch['ref'], 11);
 49654 if ($name !== 'gh-pages') {
 49655 $branches[$name] = $branch['object']['sha'];
 49656 }
 49657 }
 49658 
 49659 $resource = $this->getNextPage($response);
 49660 } while ($resource);
 49661 
 49662 $this->branches = $branches;
 49663 }
 49664 
 49665 return $this->branches;
 49666 }
 49667 
 49668 
 49669 
 49670 
 49671 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 49672 {
 49673 if (!Preg::isMatch('#^((?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/(.+?)(?:\.git|/)?$#', $url, $matches)) {
 49674 return false;
 49675 }
 49676 
 49677 $originUrl = !empty($matches[2]) ? $matches[2] : $matches[3];
 49678 if (!in_array(strtolower(Preg::replace('{^www\.}i', '', $originUrl)), $config->get('github-domains'))) {
 49679 return false;
 49680 }
 49681 
 49682 if (!extension_loaded('openssl')) {
 49683 $io->writeError('Skipping GitHub driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
 49684 
 49685 return false;
 49686 }
 49687 
 49688 return true;
 49689 }
 49690 
 49691 
 49692 
 49693 
 49694 
 49695 
 49696 public function getRepoData()
 49697 {
 49698 $this->fetchRootIdentifier();
 49699 
 49700 return $this->repoData;
 49701 }
 49702 
 49703 
 49704 
 49705 
 49706 
 49707 
 49708 protected function generateSshUrl()
 49709 {
 49710 if (false !== strpos($this->originUrl, ':')) {
 49711 return 'ssh://git@' . $this->originUrl . '/'.$this->owner.'/'.$this->repository.'.git';
 49712 }
 49713 
 49714 return 'git@' . $this->originUrl . ':'.$this->owner.'/'.$this->repository.'.git';
 49715 }
 49716 
 49717 
 49718 
 49719 
 49720 
 49721 
 49722 protected function getContents($url, $fetchingRepoData = false)
 49723 {
 49724 try {
 49725 return parent::getContents($url);
 49726 } catch (TransportException $e) {
 49727 $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->httpDownloader);
 49728 
 49729 switch ($e->getCode()) {
 49730 case 401:
 49731 case 404:
 49732 
 49733 if (!$fetchingRepoData) {
 49734 throw $e;
 49735 }
 49736 
 49737 if ($gitHubUtil->authorizeOAuth($this->originUrl)) {
 49738 return parent::getContents($url);
 49739 }
 49740 
 49741 if (!$this->io->isInteractive()) {
 49742 $this->attemptCloneFallback();
 49743 
 49744 return new Response(array('url' => 'dummy'), 200, array(), 'null');
 49745 }
 49746 
 49747 $scopesIssued = array();
 49748 $scopesNeeded = array();
 49749 if ($headers = $e->getHeaders()) {
 49750 if ($scopes = Response::findHeaderValue($headers, 'X-OAuth-Scopes')) {
 49751 $scopesIssued = explode(' ', $scopes);
 49752 }
 49753 if ($scopes = Response::findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
 49754 $scopesNeeded = explode(' ', $scopes);
 49755 }
 49756 }
 49757 $scopesFailed = array_diff($scopesNeeded, $scopesIssued);
 49758 
 49759 
 49760 if (!$headers || !count($scopesNeeded) || count($scopesFailed)) {
 49761 $gitHubUtil->authorizeOAuthInteractively($this->originUrl, 'Your GitHub credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
 49762 }
 49763 
 49764 return parent::getContents($url);
 49765 
 49766 case 403:
 49767 if (!$this->io->hasAuthentication($this->originUrl) && $gitHubUtil->authorizeOAuth($this->originUrl)) {
 49768 return parent::getContents($url);
 49769 }
 49770 
 49771 if (!$this->io->isInteractive() && $fetchingRepoData) {
 49772 $this->attemptCloneFallback();
 49773 
 49774 return new Response(array('url' => 'dummy'), 200, array(), 'null');
 49775 }
 49776 
 49777 $rateLimited = $gitHubUtil->isRateLimited((array) $e->getHeaders());
 49778 
 49779 if (!$this->io->hasAuthentication($this->originUrl)) {
 49780 if (!$this->io->isInteractive()) {
 49781 $this->io->writeError('<error>GitHub API limit exhausted. Failed to get metadata for the '.$this->url.' repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit</error>');
 49782 throw $e;
 49783 }
 49784 
 49785 $gitHubUtil->authorizeOAuthInteractively($this->originUrl, 'API limit exhausted. Enter your GitHub credentials to get a larger API limit (<info>'.$this->url.'</info>)');
 49786 
 49787 return parent::getContents($url);
 49788 }
 49789 
 49790 if ($rateLimited) {
 49791 $rateLimit = $gitHubUtil->getRateLimit($e->getHeaders());
 49792 $this->io->writeError(sprintf(
 49793 '<error>GitHub API limit (%d calls/hr) is exhausted. You are already authorized so you have to wait until %s before doing more requests</error>',
 49794 $rateLimit['limit'],
 49795 $rateLimit['reset']
 49796 ));
 49797 }
 49798 
 49799 throw $e;
 49800 
 49801 default:
 49802 throw $e;
 49803 }
 49804 }
 49805 }
 49806 
 49807 
 49808 
 49809 
 49810 
 49811 
 49812 
 49813 protected function fetchRootIdentifier()
 49814 {
 49815 if ($this->repoData) {
 49816 return;
 49817 }
 49818 
 49819 $repoDataUrl = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository;
 49820 
 49821 try {
 49822 $this->repoData = $this->getContents($repoDataUrl, true)->decodeJson();
 49823 } catch (TransportException $e) {
 49824 if ($e->getCode() === 499) {
 49825 $this->attemptCloneFallback();
 49826 } else {
 49827 throw $e;
 49828 }
 49829 }
 49830 if (null === $this->repoData && null !== $this->gitDriver) {
 49831 return;
 49832 }
 49833 
 49834 $this->owner = $this->repoData['owner']['login'];
 49835 $this->repository = $this->repoData['name'];
 49836 
 49837 $this->isPrivate = !empty($this->repoData['private']);
 49838 if (isset($this->repoData['default_branch'])) {
 49839 $this->rootIdentifier = $this->repoData['default_branch'];
 49840 } elseif (isset($this->repoData['master_branch'])) {
 49841 $this->rootIdentifier = $this->repoData['master_branch'];
 49842 } else {
 49843 $this->rootIdentifier = 'master';
 49844 }
 49845 $this->hasIssues = !empty($this->repoData['has_issues']);
 49846 $this->isArchived = !empty($this->repoData['archived']);
 49847 }
 49848 
 49849 
 49850 
 49851 
 49852 
 49853 
 49854 
 49855 protected function attemptCloneFallback()
 49856 {
 49857 $this->isPrivate = true;
 49858 
 49859 try {
 49860 
 49861 
 49862 
 49863 
 49864 $this->setupGitDriver($this->generateSshUrl());
 49865 
 49866 return true;
 49867 } catch (\RuntimeException $e) {
 49868 $this->gitDriver = null;
 49869 
 49870 $this->io->writeError('<error>Failed to clone the '.$this->generateSshUrl().' repository, try running in interactive mode so that you can enter your GitHub credentials</error>');
 49871 throw $e;
 49872 }
 49873 }
 49874 
 49875 
 49876 
 49877 
 49878 
 49879 
 49880 protected function setupGitDriver($url)
 49881 {
 49882 $this->gitDriver = new GitDriver(
 49883 array('url' => $url),
 49884 $this->io,
 49885 $this->config,
 49886 $this->httpDownloader,
 49887 $this->process
 49888 );
 49889 $this->gitDriver->initialize();
 49890 }
 49891 
 49892 
 49893 
 49894 
 49895 protected function getNextPage(Response $response)
 49896 {
 49897 $header = $response->getHeader('link');
 49898 if (!$header) {
 49899 return null;
 49900 }
 49901 
 49902 $links = explode(',', $header);
 49903 foreach ($links as $link) {
 49904 if (Preg::isMatch('{<(.+?)>; *rel="next"}', $link, $match)) {
 49905 return $match[1];
 49906 }
 49907 }
 49908 
 49909 return null;
 49910 }
 49911 }
 49912 <?php
 49913 
 49914 
 49915 
 49916 
 49917 
 49918 
 49919 
 49920 
 49921 
 49922 
 49923 
 49924 namespace Composer\Repository\Vcs;
 49925 
 49926 use Composer\Config;
 49927 use Composer\Cache;
 49928 use Composer\IO\IOInterface;
 49929 use Composer\Json\JsonFile;
 49930 use Composer\Downloader\TransportException;
 49931 use Composer\Pcre\Preg;
 49932 use Composer\Util\HttpDownloader;
 49933 use Composer\Util\GitLab;
 49934 use Composer\Util\Http\Response;
 49935 
 49936 
 49937 
 49938 
 49939 
 49940 
 49941 
 49942 class GitLabDriver extends VcsDriver
 49943 {
 49944 
 49945 
 49946 
 49947 
 49948 private $scheme;
 49949 
 49950 private $namespace;
 49951 
 49952 private $repository;
 49953 
 49954 
 49955 
 49956 
 49957 private $project;
 49958 
 49959 
 49960 
 49961 
 49962 private $commits = array();
 49963 
 49964 
 49965 private $tags;
 49966 
 49967 
 49968 private $branches;
 49969 
 49970 
 49971 
 49972 
 49973 
 49974 
 49975 protected $gitDriver = null;
 49976 
 49977 
 49978 
 49979 
 49980 
 49981 
 49982 protected $protocol;
 49983 
 49984 
 49985 
 49986 
 49987 
 49988 
 49989 private $isPrivate = true;
 49990 
 49991 
 49992 
 49993 
 49994 private $hasNonstandardOrigin = false;
 49995 
 49996 const URL_REGEX = '#^(?:(?P<scheme>https?)://(?P<domain>.+?)(?::(?P<port>[0-9]+))?/|git@(?P<domain2>[^:]+):)(?P<parts>.+)/(?P<repo>[^/]+?)(?:\.git|/)?$#';
 49997 
 49998 
 49999 
 50000 
 50001 
 50002 
 50003 
 50004 
 50005 public function initialize()
 50006 {
 50007 if (!Preg::isMatch(self::URL_REGEX, $this->url, $match)) {
 50008 throw new \InvalidArgumentException(sprintf('The GitLab repository URL %s is invalid. It must be the HTTP URL of a GitLab project.', $this->url));
 50009 }
 50010 
 50011 $guessedDomain = !empty($match['domain']) ? $match['domain'] : $match['domain2'];
 50012 $configuredDomains = $this->config->get('gitlab-domains');
 50013 $urlParts = explode('/', $match['parts']);
 50014 
 50015 $this->scheme = !empty($match['scheme'])
 50016 ? $match['scheme']
 50017 : (isset($this->repoConfig['secure-http']) && $this->repoConfig['secure-http'] === false ? 'http' : 'https')
 50018 ;
 50019 $this->originUrl = self::determineOrigin($configuredDomains, $guessedDomain, $urlParts, $match['port']);
 50020 
 50021 if ($protocol = $this->config->get('gitlab-protocol')) {
 50022 
 50023 if (!in_array($protocol, array('git', 'http', 'https'))) {
 50024 throw new \RuntimeException('gitlab-protocol must be one of git, http.');
 50025 }
 50026 $this->protocol = $protocol === 'git' ? 'ssh' : 'http';
 50027 }
 50028 
 50029 if (false !== strpos($this->originUrl, ':') || false !== strpos($this->originUrl, '/')) {
 50030 $this->hasNonstandardOrigin = true;
 50031 }
 50032 
 50033 $this->namespace = implode('/', $urlParts);
 50034 $this->repository = Preg::replace('#(\.git)$#', '', $match['repo']);
 50035 
 50036 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.$this->originUrl.'/'.$this->namespace.'/'.$this->repository);
 50037 $this->cache->setReadOnly($this->config->get('cache-read-only'));
 50038 
 50039 $this->fetchProject();
 50040 }
 50041 
 50042 
 50043 
 50044 
 50045 
 50046 
 50047 
 50048 
 50049 
 50050 public function setHttpDownloader(HttpDownloader $httpDownloader)
 50051 {
 50052 $this->httpDownloader = $httpDownloader;
 50053 }
 50054 
 50055 
 50056 
 50057 
 50058 public function getComposerInformation($identifier)
 50059 {
 50060 if ($this->gitDriver) {
 50061 return $this->gitDriver->getComposerInformation($identifier);
 50062 }
 50063 
 50064 if (!isset($this->infoCache[$identifier])) {
 50065 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
 50066 $composer = JsonFile::parseJson($res);
 50067 } else {
 50068 $composer = $this->getBaseComposerInformation($identifier);
 50069 
 50070 if ($this->shouldCache($identifier)) {
 50071 $this->cache->write($identifier, json_encode($composer));
 50072 }
 50073 }
 50074 
 50075 if ($composer) {
 50076 
 50077 if (!isset($composer['support']['source']) && isset($this->project['web_url'])) {
 50078 $label = array_search($identifier, $this->getTags(), true) ?: array_search($identifier, $this->getBranches(), true) ?: $identifier;
 50079 $composer['support']['source'] = sprintf('%s/-/tree/%s', $this->project['web_url'], $label);
 50080 }
 50081 if (!isset($composer['support']['issues']) && !empty($this->project['issues_enabled']) && isset($this->project['web_url'])) {
 50082 $composer['support']['issues'] = sprintf('%s/-/issues', $this->project['web_url']);
 50083 }
 50084 if (!isset($composer['abandoned']) && !empty($this->project['archived'])) {
 50085 $composer['abandoned'] = true;
 50086 }
 50087 }
 50088 
 50089 $this->infoCache[$identifier] = $composer;
 50090 }
 50091 
 50092 return $this->infoCache[$identifier];
 50093 }
 50094 
 50095 
 50096 
 50097 
 50098 public function getFileContent($file, $identifier)
 50099 {
 50100 if ($this->gitDriver) {
 50101 return $this->gitDriver->getFileContent($file, $identifier);
 50102 }
 50103 
 50104 
 50105 if (!Preg::isMatch('{[a-f0-9]{40}}i', $identifier)) {
 50106 $branches = $this->getBranches();
 50107 if (isset($branches[$identifier])) {
 50108 $identifier = $branches[$identifier];
 50109 }
 50110 }
 50111 
 50112 $resource = $this->getApiUrl().'/repository/files/'.$this->urlEncodeAll($file).'/raw?ref='.$identifier;
 50113 
 50114 try {
 50115 $content = $this->getContents($resource)->getBody();
 50116 } catch (TransportException $e) {
 50117 if ($e->getCode() !== 404) {
 50118 throw $e;
 50119 }
 50120 
 50121 return null;
 50122 }
 50123 
 50124 return $content;
 50125 }
 50126 
 50127 
 50128 
 50129 
 50130 public function getChangeDate($identifier)
 50131 {
 50132 if ($this->gitDriver) {
 50133 return $this->gitDriver->getChangeDate($identifier);
 50134 }
 50135 
 50136 if (isset($this->commits[$identifier])) {
 50137 return new \DateTime($this->commits[$identifier]['committed_date']);
 50138 }
 50139 
 50140 return new \DateTime();
 50141 }
 50142 
 50143 
 50144 
 50145 
 50146 public function getRepositoryUrl()
 50147 {
 50148 if ($this->protocol) {
 50149 return $this->project["{$this->protocol}_url_to_repo"];
 50150 }
 50151 
 50152 return $this->isPrivate ? $this->project['ssh_url_to_repo'] : $this->project['http_url_to_repo'];
 50153 }
 50154 
 50155 
 50156 
 50157 
 50158 public function getUrl()
 50159 {
 50160 if ($this->gitDriver) {
 50161 return $this->gitDriver->getUrl();
 50162 }
 50163 
 50164 return $this->project['web_url'];
 50165 }
 50166 
 50167 
 50168 
 50169 
 50170 public function getDist($identifier)
 50171 {
 50172 $url = $this->getApiUrl().'/repository/archive.zip?sha='.$identifier;
 50173 
 50174 return array('type' => 'zip', 'url' => $url, 'reference' => $identifier, 'shasum' => '');
 50175 }
 50176 
 50177 
 50178 
 50179 
 50180 public function getSource($identifier)
 50181 {
 50182 if ($this->gitDriver) {
 50183 return $this->gitDriver->getSource($identifier);
 50184 }
 50185 
 50186 return array('type' => 'git', 'url' => $this->getRepositoryUrl(), 'reference' => $identifier);
 50187 }
 50188 
 50189 
 50190 
 50191 
 50192 public function getRootIdentifier()
 50193 {
 50194 if ($this->gitDriver) {
 50195 return $this->gitDriver->getRootIdentifier();
 50196 }
 50197 
 50198 return $this->project['default_branch'];
 50199 }
 50200 
 50201 
 50202 
 50203 
 50204 public function getBranches()
 50205 {
 50206 if ($this->gitDriver) {
 50207 return $this->gitDriver->getBranches();
 50208 }
 50209 
 50210 if (!$this->branches) {
 50211 $this->branches = $this->getReferences('branches');
 50212 }
 50213 
 50214 return $this->branches;
 50215 }
 50216 
 50217 
 50218 
 50219 
 50220 public function getTags()
 50221 {
 50222 if ($this->gitDriver) {
 50223 return $this->gitDriver->getTags();
 50224 }
 50225 
 50226 if (!$this->tags) {
 50227 $this->tags = $this->getReferences('tags');
 50228 }
 50229 
 50230 return $this->tags;
 50231 }
 50232 
 50233 
 50234 
 50235 
 50236 public function getApiUrl()
 50237 {
 50238 return $this->scheme.'://'.$this->originUrl.'/api/v4/projects/'.$this->urlEncodeAll($this->namespace).'%2F'.$this->urlEncodeAll($this->repository);
 50239 }
 50240 
 50241 
 50242 
 50243 
 50244 
 50245 
 50246 
 50247 private function urlEncodeAll($string)
 50248 {
 50249 $encoded = '';
 50250 for ($i = 0; isset($string[$i]); $i++) {
 50251 $character = $string[$i];
 50252 if (!ctype_alnum($character) && !in_array($character, array('-', '_'), true)) {
 50253 $character = '%' . sprintf('%02X', ord($character));
 50254 }
 50255 $encoded .= $character;
 50256 }
 50257 
 50258 return $encoded;
 50259 }
 50260 
 50261 
 50262 
 50263 
 50264 
 50265 
 50266 protected function getReferences($type)
 50267 {
 50268 $perPage = 100;
 50269 $resource = $this->getApiUrl().'/repository/'.$type.'?per_page='.$perPage;
 50270 
 50271 $references = array();
 50272 do {
 50273 $response = $this->getContents($resource);
 50274 $data = $response->decodeJson();
 50275 
 50276 foreach ($data as $datum) {
 50277 $references[$datum['name']] = $datum['commit']['id'];
 50278 
 50279 
 50280 
 50281 $this->commits[$datum['commit']['id']] = $datum['commit'];
 50282 }
 50283 
 50284 if (count($data) >= $perPage) {
 50285 $resource = $this->getNextPage($response);
 50286 } else {
 50287 $resource = false;
 50288 }
 50289 } while ($resource);
 50290 
 50291 return $references;
 50292 }
 50293 
 50294 
 50295 
 50296 
 50297 protected function fetchProject()
 50298 {
 50299 
 50300 $resource = $this->getApiUrl();
 50301 $this->project = $this->getContents($resource, true)->decodeJson();
 50302 if (isset($this->project['visibility'])) {
 50303 $this->isPrivate = $this->project['visibility'] !== 'public';
 50304 } else {
 50305 
 50306 $this->isPrivate = false;
 50307 }
 50308 }
 50309 
 50310 
 50311 
 50312 
 50313 
 50314 
 50315 
 50316 protected function attemptCloneFallback()
 50317 {
 50318 if ($this->isPrivate === false) {
 50319 $url = $this->generatePublicUrl();
 50320 } else {
 50321 $url = $this->generateSshUrl();
 50322 }
 50323 
 50324 try {
 50325 
 50326 
 50327 
 50328 $this->setupGitDriver($url);
 50329 
 50330 return true;
 50331 } catch (\RuntimeException $e) {
 50332 $this->gitDriver = null;
 50333 
 50334 $this->io->writeError('<error>Failed to clone the '.$url.' repository, try running in interactive mode so that you can enter your credentials</error>');
 50335 throw $e;
 50336 }
 50337 }
 50338 
 50339 
 50340 
 50341 
 50342 
 50343 
 50344 protected function generateSshUrl()
 50345 {
 50346 if ($this->hasNonstandardOrigin) {
 50347 return 'ssh://git@'.$this->originUrl.'/'.$this->namespace.'/'.$this->repository.'.git';
 50348 }
 50349 
 50350 return 'git@' . $this->originUrl . ':'.$this->namespace.'/'.$this->repository.'.git';
 50351 }
 50352 
 50353 
 50354 
 50355 
 50356 protected function generatePublicUrl()
 50357 {
 50358 return $this->scheme . '://' . $this->originUrl . '/'.$this->namespace.'/'.$this->repository.'.git';
 50359 }
 50360 
 50361 
 50362 
 50363 
 50364 
 50365 
 50366 protected function setupGitDriver($url)
 50367 {
 50368 $this->gitDriver = new GitDriver(
 50369 array('url' => $url),
 50370 $this->io,
 50371 $this->config,
 50372 $this->httpDownloader,
 50373 $this->process
 50374 );
 50375 $this->gitDriver->initialize();
 50376 }
 50377 
 50378 
 50379 
 50380 
 50381 
 50382 
 50383 protected function getContents($url, $fetchingRepoData = false)
 50384 {
 50385 try {
 50386 $response = parent::getContents($url);
 50387 
 50388 if ($fetchingRepoData) {
 50389 $json = $response->decodeJson();
 50390 
 50391 
 50392 
 50393 
 50394 if (!isset($json['default_branch']) && isset($json['permissions'])) {
 50395 $this->isPrivate = $json['visibility'] !== 'public';
 50396 
 50397 $moreThanGuestAccess = false;
 50398 
 50399 
 50400 
 50401 foreach ($json['permissions'] as $permission) {
 50402 if ($permission && $permission['access_level'] > 10) {
 50403 $moreThanGuestAccess = true;
 50404 }
 50405 }
 50406 
 50407 if (!$moreThanGuestAccess) {
 50408 $this->io->writeError('<warning>GitLab token with Guest only access detected</warning>');
 50409 
 50410 $this->attemptCloneFallback();
 50411 
 50412 return new Response(array('url' => 'dummy'), 200, array(), 'null');
 50413 }
 50414 }
 50415 
 50416 
 50417 if (!isset($json['default_branch'])) {
 50418 
 50419 if (isset($json['repository_access_level']) && $json['repository_access_level'] === 'disabled') {
 50420 throw new TransportException('The GitLab repository is disabled in the project', 400);
 50421 }
 50422 
 50423 if (!empty($json['id'])) {
 50424 $this->isPrivate = false;
 50425 }
 50426 
 50427 throw new TransportException('GitLab API seems to not be authenticated as it did not return a default_branch', 401);
 50428 }
 50429 }
 50430 
 50431 return $response;
 50432 } catch (TransportException $e) {
 50433 $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->httpDownloader);
 50434 
 50435 switch ($e->getCode()) {
 50436 case 401:
 50437 case 404:
 50438 
 50439 if (!$fetchingRepoData) {
 50440 throw $e;
 50441 }
 50442 
 50443 if ($gitLabUtil->authorizeOAuth($this->originUrl)) {
 50444 return parent::getContents($url);
 50445 }
 50446 
 50447 if (!$this->io->isInteractive()) {
 50448 $this->attemptCloneFallback();
 50449 
 50450 return new Response(array('url' => 'dummy'), 200, array(), 'null');
 50451 }
 50452 $this->io->writeError('<warning>Failed to download ' . $this->namespace . '/' . $this->repository . ':' . $e->getMessage() . '</warning>');
 50453 $gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
 50454 
 50455 return parent::getContents($url);
 50456 
 50457 case 403:
 50458 if (!$this->io->hasAuthentication($this->originUrl) && $gitLabUtil->authorizeOAuth($this->originUrl)) {
 50459 return parent::getContents($url);
 50460 }
 50461 
 50462 if (!$this->io->isInteractive() && $fetchingRepoData) {
 50463 $this->attemptCloneFallback();
 50464 
 50465 return new Response(array('url' => 'dummy'), 200, array(), 'null');
 50466 }
 50467 
 50468 throw $e;
 50469 
 50470 default:
 50471 throw $e;
 50472 }
 50473 }
 50474 }
 50475 
 50476 
 50477 
 50478 
 50479 
 50480 
 50481 
 50482 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 50483 {
 50484 if (!Preg::isMatch(self::URL_REGEX, $url, $match)) {
 50485 return false;
 50486 }
 50487 
 50488 $scheme = !empty($match['scheme']) ? $match['scheme'] : null;
 50489 $guessedDomain = !empty($match['domain']) ? $match['domain'] : $match['domain2'];
 50490 $urlParts = explode('/', $match['parts']);
 50491 
 50492 if (false === self::determineOrigin((array) $config->get('gitlab-domains'), $guessedDomain, $urlParts, $match['port'])) {
 50493 return false;
 50494 }
 50495 
 50496 if ('https' === $scheme && !extension_loaded('openssl')) {
 50497 $io->writeError('Skipping GitLab driver for '.$url.' because the OpenSSL PHP extension is missing.', true, IOInterface::VERBOSE);
 50498 
 50499 return false;
 50500 }
 50501 
 50502 return true;
 50503 }
 50504 
 50505 
 50506 
 50507 
 50508 protected function getNextPage(Response $response)
 50509 {
 50510 $header = $response->getHeader('link');
 50511 
 50512 $links = explode(',', $header);
 50513 foreach ($links as $link) {
 50514 if (Preg::isMatch('{<(.+?)>; *rel="next"}', $link, $match)) {
 50515 return $match[1];
 50516 }
 50517 }
 50518 
 50519 return null;
 50520 }
 50521 
 50522 
 50523 
 50524 
 50525 
 50526 
 50527 
 50528 
 50529 
 50530 private static function determineOrigin(array $configuredDomains, $guessedDomain, array &$urlParts, $portNumber)
 50531 {
 50532 $guessedDomain = strtolower($guessedDomain);
 50533 
 50534 if (in_array($guessedDomain, $configuredDomains) || ($portNumber && in_array($guessedDomain.':'.$portNumber, $configuredDomains))) {
 50535 if ($portNumber) {
 50536 return $guessedDomain.':'.$portNumber;
 50537 }
 50538 
 50539 return $guessedDomain;
 50540 }
 50541 
 50542 if ($portNumber) {
 50543 $guessedDomain .= ':'.$portNumber;
 50544 }
 50545 
 50546 while (null !== ($part = array_shift($urlParts))) {
 50547 $guessedDomain .= '/' . $part;
 50548 
 50549 if (in_array($guessedDomain, $configuredDomains) || ($portNumber && in_array(Preg::replace('{:\d+}', '', $guessedDomain), $configuredDomains))) {
 50550 return $guessedDomain;
 50551 }
 50552 }
 50553 
 50554 return false;
 50555 }
 50556 }
 50557 <?php
 50558 
 50559 
 50560 
 50561 
 50562 
 50563 
 50564 
 50565 
 50566 
 50567 
 50568 
 50569 namespace Composer\Repository\Vcs;
 50570 
 50571 use Composer\Config;
 50572 use Composer\Cache;
 50573 use Composer\Pcre\Preg;
 50574 use Composer\Util\Hg as HgUtils;
 50575 use Composer\Util\ProcessExecutor;
 50576 use Composer\Util\Filesystem;
 50577 use Composer\IO\IOInterface;
 50578 
 50579 
 50580 
 50581 
 50582 class HgDriver extends VcsDriver
 50583 {
 50584 
 50585 protected $tags;
 50586 
 50587 protected $branches;
 50588 
 50589 protected $rootIdentifier;
 50590 
 50591 protected $repoDir;
 50592 
 50593 
 50594 
 50595 
 50596 public function initialize()
 50597 {
 50598 if (Filesystem::isLocalPath($this->url)) {
 50599 $this->repoDir = $this->url;
 50600 } else {
 50601 if (!Cache::isUsable((string) $this->config->get('cache-vcs-dir'))) {
 50602 throw new \RuntimeException('HgDriver requires a usable cache directory, and it looks like you set it to be disabled');
 50603 }
 50604 
 50605 $cacheDir = $this->config->get('cache-vcs-dir');
 50606 $this->repoDir = $cacheDir . '/' . Preg::replace('{[^a-z0-9]}i', '-', $this->url) . '/';
 50607 
 50608 $fs = new Filesystem();
 50609 $fs->ensureDirectoryExists($cacheDir);
 50610 
 50611 if (!is_writable(dirname($this->repoDir))) {
 50612 throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.$cacheDir.'" directory is not writable by the current user.');
 50613 }
 50614 
 50615 
 50616 $this->config->prohibitUrlByConfig($this->url, $this->io);
 50617 
 50618 $hgUtils = new HgUtils($this->io, $this->config, $this->process);
 50619 
 50620 
 50621 if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) {
 50622 if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) {
 50623 $this->io->writeError('<error>Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')</error>');
 50624 }
 50625 } else {
 50626 
 50627 $fs->removeDirectory($this->repoDir);
 50628 
 50629 $repoDir = $this->repoDir;
 50630 $command = function ($url) use ($repoDir) {
 50631 return sprintf('hg clone --noupdate -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($repoDir));
 50632 };
 50633 
 50634 $hgUtils->runCommand($command, $this->url, null);
 50635 }
 50636 }
 50637 
 50638 $this->getTags();
 50639 $this->getBranches();
 50640 }
 50641 
 50642 
 50643 
 50644 
 50645 public function getRootIdentifier()
 50646 {
 50647 if (null === $this->rootIdentifier) {
 50648 $this->process->execute(sprintf('hg tip --template "{node}"'), $output, $this->repoDir);
 50649 $output = $this->process->splitLines($output);
 50650 $this->rootIdentifier = $output[0];
 50651 }
 50652 
 50653 return $this->rootIdentifier;
 50654 }
 50655 
 50656 
 50657 
 50658 
 50659 public function getUrl()
 50660 {
 50661 return $this->url;
 50662 }
 50663 
 50664 
 50665 
 50666 
 50667 public function getSource($identifier)
 50668 {
 50669 return array('type' => 'hg', 'url' => $this->getUrl(), 'reference' => $identifier);
 50670 }
 50671 
 50672 
 50673 
 50674 
 50675 public function getDist($identifier)
 50676 {
 50677 return null;
 50678 }
 50679 
 50680 
 50681 
 50682 
 50683 public function getFileContent($file, $identifier)
 50684 {
 50685 $resource = sprintf('hg cat -r %s %s', ProcessExecutor::escape($identifier), ProcessExecutor::escape($file));
 50686 $this->process->execute($resource, $content, $this->repoDir);
 50687 
 50688 if (!trim($content)) {
 50689 return null;
 50690 }
 50691 
 50692 return $content;
 50693 }
 50694 
 50695 
 50696 
 50697 
 50698 public function getChangeDate($identifier)
 50699 {
 50700 $this->process->execute(
 50701 sprintf(
 50702 'hg log --template "{date|rfc3339date}" -r %s',
 50703 ProcessExecutor::escape($identifier)
 50704 ),
 50705 $output,
 50706 $this->repoDir
 50707 );
 50708 
 50709 return new \DateTime(trim($output), new \DateTimeZone('UTC'));
 50710 }
 50711 
 50712 
 50713 
 50714 
 50715 public function getTags()
 50716 {
 50717 if (null === $this->tags) {
 50718 $tags = array();
 50719 
 50720 $this->process->execute('hg tags', $output, $this->repoDir);
 50721 foreach ($this->process->splitLines($output) as $tag) {
 50722 if ($tag && Preg::isMatch('(^([^\s]+)\s+\d+:(.*)$)', $tag, $match)) {
 50723 $tags[$match[1]] = $match[2];
 50724 }
 50725 }
 50726 unset($tags['tip']);
 50727 
 50728 $this->tags = $tags;
 50729 }
 50730 
 50731 return $this->tags;
 50732 }
 50733 
 50734 
 50735 
 50736 
 50737 public function getBranches()
 50738 {
 50739 if (null === $this->branches) {
 50740 $branches = array();
 50741 $bookmarks = array();
 50742 
 50743 $this->process->execute('hg branches', $output, $this->repoDir);
 50744 foreach ($this->process->splitLines($output) as $branch) {
 50745 if ($branch && Preg::isMatch('(^([^\s]+)\s+\d+:([a-f0-9]+))', $branch, $match)) {
 50746 $branches[$match[1]] = $match[2];
 50747 }
 50748 }
 50749 
 50750 $this->process->execute('hg bookmarks', $output, $this->repoDir);
 50751 foreach ($this->process->splitLines($output) as $branch) {
 50752 if ($branch && Preg::isMatch('(^(?:[\s*]*)([^\s]+)\s+\d+:(.*)$)', $branch, $match)) {
 50753 $bookmarks[$match[1]] = $match[2];
 50754 }
 50755 }
 50756 
 50757 
 50758 $this->branches = array_merge($bookmarks, $branches);
 50759 }
 50760 
 50761 return $this->branches;
 50762 }
 50763 
 50764 
 50765 
 50766 
 50767 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 50768 {
 50769 if (Preg::isMatch('#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i', $url)) {
 50770 return true;
 50771 }
 50772 
 50773 
 50774 if (Filesystem::isLocalPath($url)) {
 50775 $url = Filesystem::getPlatformPath($url);
 50776 if (!is_dir($url)) {
 50777 return false;
 50778 }
 50779 
 50780 $process = new ProcessExecutor($io);
 50781 
 50782 if ($process->execute('hg summary', $output, $url) === 0) {
 50783 return true;
 50784 }
 50785 }
 50786 
 50787 if (!$deep) {
 50788 return false;
 50789 }
 50790 
 50791 $process = new ProcessExecutor($io);
 50792 $exit = $process->execute(sprintf('hg identify -- %s', ProcessExecutor::escape($url)), $ignored);
 50793 
 50794 return $exit === 0;
 50795 }
 50796 }
 50797 <?php
 50798 
 50799 
 50800 
 50801 
 50802 
 50803 
 50804 
 50805 
 50806 
 50807 
 50808 
 50809 namespace Composer\Repository\Vcs;
 50810 
 50811 use Composer\Config;
 50812 use Composer\Cache;
 50813 use Composer\IO\IOInterface;
 50814 use Composer\Pcre\Preg;
 50815 use Composer\Util\ProcessExecutor;
 50816 use Composer\Util\Perforce;
 50817 
 50818 
 50819 
 50820 
 50821 class PerforceDriver extends VcsDriver
 50822 {
 50823 
 50824 protected $depot;
 50825 
 50826 protected $branch;
 50827 
 50828 protected $perforce = null;
 50829 
 50830 
 50831 
 50832 
 50833 public function initialize()
 50834 {
 50835 $this->depot = $this->repoConfig['depot'];
 50836 $this->branch = '';
 50837 if (!empty($this->repoConfig['branch'])) {
 50838 $this->branch = $this->repoConfig['branch'];
 50839 }
 50840 
 50841 $this->initPerforce($this->repoConfig);
 50842 $this->perforce->p4Login();
 50843 $this->perforce->checkStream();
 50844 
 50845 $this->perforce->writeP4ClientSpec();
 50846 $this->perforce->connectClient();
 50847 }
 50848 
 50849 
 50850 
 50851 
 50852 
 50853 
 50854 private function initPerforce($repoConfig)
 50855 {
 50856 if (!empty($this->perforce)) {
 50857 return;
 50858 }
 50859 
 50860 if (!Cache::isUsable((string) $this->config->get('cache-vcs-dir'))) {
 50861 throw new \RuntimeException('PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled');
 50862 }
 50863 
 50864 $repoDir = $this->config->get('cache-vcs-dir') . '/' . $this->depot;
 50865 $this->perforce = Perforce::create($repoConfig, $this->getUrl(), $repoDir, $this->process, $this->io);
 50866 }
 50867 
 50868 
 50869 
 50870 
 50871 public function getFileContent($file, $identifier)
 50872 {
 50873 return $this->perforce->getFileContent($file, $identifier);
 50874 }
 50875 
 50876 
 50877 
 50878 
 50879 public function getChangeDate($identifier)
 50880 {
 50881 return null;
 50882 }
 50883 
 50884 
 50885 
 50886 
 50887 public function getRootIdentifier()
 50888 {
 50889 return $this->branch;
 50890 }
 50891 
 50892 
 50893 
 50894 
 50895 public function getBranches()
 50896 {
 50897 return $this->perforce->getBranches();
 50898 }
 50899 
 50900 
 50901 
 50902 
 50903 public function getTags()
 50904 {
 50905 return $this->perforce->getTags();
 50906 }
 50907 
 50908 
 50909 
 50910 
 50911 public function getDist($identifier)
 50912 {
 50913 return null;
 50914 }
 50915 
 50916 
 50917 
 50918 
 50919 public function getSource($identifier)
 50920 {
 50921 return array(
 50922 'type' => 'perforce',
 50923 'url' => $this->repoConfig['url'],
 50924 'reference' => $identifier,
 50925 'p4user' => $this->perforce->getUser(),
 50926 );
 50927 }
 50928 
 50929 
 50930 
 50931 
 50932 public function getUrl()
 50933 {
 50934 return $this->url;
 50935 }
 50936 
 50937 
 50938 
 50939 
 50940 public function hasComposerFile($identifier)
 50941 {
 50942 $composerInfo = $this->perforce->getComposerInformation('//' . $this->depot . '/' . $identifier);
 50943 
 50944 return !empty($composerInfo);
 50945 }
 50946 
 50947 
 50948 
 50949 
 50950 public function getContents($url)
 50951 {
 50952 throw new \BadMethodCallException('Not implemented/used in PerforceDriver');
 50953 }
 50954 
 50955 
 50956 
 50957 
 50958 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 50959 {
 50960 if ($deep || Preg::isMatch('#\b(perforce|p4)\b#i', $url)) {
 50961 return Perforce::checkServerExists($url, new ProcessExecutor($io));
 50962 }
 50963 
 50964 return false;
 50965 }
 50966 
 50967 
 50968 
 50969 
 50970 public function cleanup()
 50971 {
 50972 $this->perforce->cleanupClientSpec();
 50973 $this->perforce = null;
 50974 }
 50975 
 50976 
 50977 
 50978 
 50979 public function getDepot()
 50980 {
 50981 return $this->depot;
 50982 }
 50983 
 50984 
 50985 
 50986 
 50987 public function getBranch()
 50988 {
 50989 return $this->branch;
 50990 }
 50991 }
 50992 <?php
 50993 
 50994 
 50995 
 50996 
 50997 
 50998 
 50999 
 51000 
 51001 
 51002 
 51003 
 51004 namespace Composer\Repository\Vcs;
 51005 
 51006 use Composer\Cache;
 51007 use Composer\Config;
 51008 use Composer\Json\JsonFile;
 51009 use Composer\Pcre\Preg;
 51010 use Composer\Util\ProcessExecutor;
 51011 use Composer\Util\Filesystem;
 51012 use Composer\Util\Url;
 51013 use Composer\Util\Svn as SvnUtil;
 51014 use Composer\IO\IOInterface;
 51015 use Composer\Downloader\TransportException;
 51016 
 51017 
 51018 
 51019 
 51020 
 51021 class SvnDriver extends VcsDriver
 51022 {
 51023 
 51024 protected $baseUrl;
 51025 
 51026 protected $tags;
 51027 
 51028 protected $branches;
 51029 
 51030 protected $rootIdentifier;
 51031 
 51032 
 51033 protected $trunkPath = 'trunk';
 51034 
 51035 protected $branchesPath = 'branches';
 51036 
 51037 protected $tagsPath = 'tags';
 51038 
 51039 protected $packagePath = '';
 51040 
 51041 protected $cacheCredentials = true;
 51042 
 51043 
 51044 
 51045 
 51046 private $util;
 51047 
 51048 
 51049 
 51050 
 51051 public function initialize()
 51052 {
 51053 $this->url = $this->baseUrl = rtrim(self::normalizeUrl($this->url), '/');
 51054 
 51055 SvnUtil::cleanEnv();
 51056 
 51057 if (isset($this->repoConfig['trunk-path'])) {
 51058 $this->trunkPath = $this->repoConfig['trunk-path'];
 51059 }
 51060 if (isset($this->repoConfig['branches-path'])) {
 51061 $this->branchesPath = $this->repoConfig['branches-path'];
 51062 }
 51063 if (isset($this->repoConfig['tags-path'])) {
 51064 $this->tagsPath = $this->repoConfig['tags-path'];
 51065 }
 51066 if (array_key_exists('svn-cache-credentials', $this->repoConfig)) {
 51067 $this->cacheCredentials = (bool) $this->repoConfig['svn-cache-credentials'];
 51068 }
 51069 if (isset($this->repoConfig['package-path'])) {
 51070 $this->packagePath = '/' . trim($this->repoConfig['package-path'], '/');
 51071 }
 51072 
 51073 if (false !== ($pos = strrpos($this->url, '/' . $this->trunkPath))) {
 51074 $this->baseUrl = substr($this->url, 0, $pos);
 51075 }
 51076 
 51077 $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir').'/'.Preg::replace('{[^a-z0-9.]}i', '-', Url::sanitize($this->baseUrl)));
 51078 $this->cache->setReadOnly($this->config->get('cache-read-only'));
 51079 
 51080 $this->getBranches();
 51081 $this->getTags();
 51082 }
 51083 
 51084 
 51085 
 51086 
 51087 public function getRootIdentifier()
 51088 {
 51089 return $this->rootIdentifier ?: $this->trunkPath;
 51090 }
 51091 
 51092 
 51093 
 51094 
 51095 public function getUrl()
 51096 {
 51097 return $this->url;
 51098 }
 51099 
 51100 
 51101 
 51102 
 51103 public function getSource($identifier)
 51104 {
 51105 return array('type' => 'svn', 'url' => $this->baseUrl, 'reference' => $identifier);
 51106 }
 51107 
 51108 
 51109 
 51110 
 51111 public function getDist($identifier)
 51112 {
 51113 return null;
 51114 }
 51115 
 51116 
 51117 
 51118 
 51119 protected function shouldCache($identifier)
 51120 {
 51121 return $this->cache && Preg::isMatch('{@\d+$}', $identifier);
 51122 }
 51123 
 51124 
 51125 
 51126 
 51127 public function getComposerInformation($identifier)
 51128 {
 51129 if (!isset($this->infoCache[$identifier])) {
 51130 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier.'.json')) {
 51131 return $this->infoCache[$identifier] = JsonFile::parseJson($res);
 51132 }
 51133 
 51134 try {
 51135 $composer = $this->getBaseComposerInformation($identifier);
 51136 } catch (TransportException $e) {
 51137 $message = $e->getMessage();
 51138 if (stripos($message, 'path not found') === false && stripos($message, 'svn: warning: W160013') === false) {
 51139 throw $e;
 51140 }
 51141 
 51142 $composer = '';
 51143 }
 51144 
 51145 if ($this->shouldCache($identifier)) {
 51146 $this->cache->write($identifier.'.json', json_encode($composer));
 51147 }
 51148 
 51149 $this->infoCache[$identifier] = $composer;
 51150 }
 51151 
 51152 return $this->infoCache[$identifier];
 51153 }
 51154 
 51155 
 51156 
 51157 
 51158 
 51159 public function getFileContent($file, $identifier)
 51160 {
 51161 $identifier = '/' . trim($identifier, '/') . '/';
 51162 
 51163 Preg::match('{^(.+?)(@\d+)?/$}', $identifier, $match);
 51164 if (!empty($match[2])) {
 51165 $path = $match[1];
 51166 $rev = $match[2];
 51167 } else {
 51168 $path = $identifier;
 51169 $rev = '';
 51170 }
 51171 
 51172 try {
 51173 $resource = $path.$file;
 51174 $output = $this->execute('svn cat', $this->baseUrl . $resource . $rev);
 51175 if (!trim($output)) {
 51176 return null;
 51177 }
 51178 } catch (\RuntimeException $e) {
 51179 throw new TransportException($e->getMessage());
 51180 }
 51181 
 51182 return $output;
 51183 }
 51184 
 51185 
 51186 
 51187 
 51188 public function getChangeDate($identifier)
 51189 {
 51190 $identifier = '/' . trim($identifier, '/') . '/';
 51191 
 51192 Preg::match('{^(.+?)(@\d+)?/$}', $identifier, $match);
 51193 if (!empty($match[2])) {
 51194 $path = $match[1];
 51195 $rev = $match[2];
 51196 } else {
 51197 $path = $identifier;
 51198 $rev = '';
 51199 }
 51200 
 51201 $output = $this->execute('svn info', $this->baseUrl . $path . $rev);
 51202 foreach ($this->process->splitLines($output) as $line) {
 51203 if ($line && Preg::isMatch('{^Last Changed Date: ([^(]+)}', $line, $match)) {
 51204 return new \DateTime($match[1], new \DateTimeZone('UTC'));
 51205 }
 51206 }
 51207 
 51208 return null;
 51209 }
 51210 
 51211 
 51212 
 51213 
 51214 public function getTags()
 51215 {
 51216 if (null === $this->tags) {
 51217 $tags = array();
 51218 
 51219 if ($this->tagsPath !== false) {
 51220 $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->tagsPath);
 51221 if ($output) {
 51222 foreach ($this->process->splitLines($output) as $line) {
 51223 $line = trim($line);
 51224 if ($line && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) {
 51225 if (isset($match[1], $match[2]) && $match[2] !== './') {
 51226 $tags[rtrim($match[2], '/')] = $this->buildIdentifier(
 51227 '/' . $this->tagsPath . '/' . $match[2],
 51228 $match[1]
 51229 );
 51230 }
 51231 }
 51232 }
 51233 }
 51234 }
 51235 
 51236 $this->tags = $tags;
 51237 }
 51238 
 51239 return $this->tags;
 51240 }
 51241 
 51242 
 51243 
 51244 
 51245 public function getBranches()
 51246 {
 51247 if (null === $this->branches) {
 51248 $branches = array();
 51249 
 51250 if (false === $this->trunkPath) {
 51251 $trunkParent = $this->baseUrl . '/';
 51252 } else {
 51253 $trunkParent = $this->baseUrl . '/' . $this->trunkPath;
 51254 }
 51255 
 51256 $output = $this->execute('svn ls --verbose', $trunkParent);
 51257 if ($output) {
 51258 foreach ($this->process->splitLines($output) as $line) {
 51259 $line = trim($line);
 51260 if ($line && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) {
 51261 if (isset($match[1], $match[2]) && $match[2] === './') {
 51262 $branches['trunk'] = $this->buildIdentifier(
 51263 '/' . $this->trunkPath,
 51264 $match[1]
 51265 );
 51266 $this->rootIdentifier = $branches['trunk'];
 51267 break;
 51268 }
 51269 }
 51270 }
 51271 }
 51272 unset($output);
 51273 
 51274 if ($this->branchesPath !== false) {
 51275 $output = $this->execute('svn ls --verbose', $this->baseUrl . '/' . $this->branchesPath);
 51276 if ($output) {
 51277 foreach ($this->process->splitLines(trim($output)) as $line) {
 51278 $line = trim($line);
 51279 if ($line && Preg::isMatch('{^\s*(\S+).*?(\S+)\s*$}', $line, $match)) {
 51280 if (isset($match[1], $match[2]) && $match[2] !== './') {
 51281 $branches[rtrim($match[2], '/')] = $this->buildIdentifier(
 51282 '/' . $this->branchesPath . '/' . $match[2],
 51283 $match[1]
 51284 );
 51285 }
 51286 }
 51287 }
 51288 }
 51289 }
 51290 
 51291 $this->branches = $branches;
 51292 }
 51293 
 51294 return $this->branches;
 51295 }
 51296 
 51297 
 51298 
 51299 
 51300 public static function supports(IOInterface $io, Config $config, $url, $deep = false)
 51301 {
 51302 $url = self::normalizeUrl($url);
 51303 if (Preg::isMatch('#(^svn://|^svn\+ssh://|svn\.)#i', $url)) {
 51304 return true;
 51305 }
 51306 
 51307 
 51308 if (!$deep && !Filesystem::isLocalPath($url)) {
 51309 return false;
 51310 }
 51311 
 51312 $process = new ProcessExecutor($io);
 51313 $exit = $process->execute(
 51314 "svn info --non-interactive -- ".ProcessExecutor::escape($url),
 51315 $ignoredOutput
 51316 );
 51317 
 51318 if ($exit === 0) {
 51319 
 51320 return true;
 51321 }
 51322 
 51323 
 51324 if (false !== stripos($process->getErrorOutput(), 'authorization failed:')) {
 51325 
 51326 
 51327 return true;
 51328 }
 51329 
 51330 
 51331 if (false !== stripos($process->getErrorOutput(), 'Authentication failed')) {
 51332 
 51333 
 51334 return true;
 51335 }
 51336 
 51337 return false;
 51338 }
 51339 
 51340 
 51341 
 51342 
 51343 
 51344 
 51345 
 51346 
 51347 protected static function normalizeUrl($url)
 51348 {
 51349 $fs = new Filesystem();
 51350 if ($fs->isAbsolutePath($url)) {
 51351 return 'file://' . strtr($url, '\\', '/');
 51352 }
 51353 
 51354 return $url;
 51355 }
 51356 
 51357 
 51358 
 51359 
 51360 
 51361 
 51362 
 51363 
 51364 
 51365 
 51366 protected function execute($command, $url)
 51367 {
 51368 if (null === $this->util) {
 51369 $this->util = new SvnUtil($this->baseUrl, $this->io, $this->config, $this->process);
 51370 $this->util->setCacheCredentials($this->cacheCredentials);
 51371 }
 51372 
 51373 try {
 51374 return $this->util->execute($command, $url);
 51375 } catch (\RuntimeException $e) {
 51376 if (null === $this->util->binaryVersion()) {
 51377 throw new \RuntimeException('Failed to load '.$this->url.', svn was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput());
 51378 }
 51379 
 51380 throw new \RuntimeException(
 51381 'Repository '.$this->url.' could not be processed, '.$e->getMessage()
 51382 );
 51383 }
 51384 }
 51385 
 51386 
 51387 
 51388 
 51389 
 51390 
 51391 
 51392 
 51393 
 51394 protected function buildIdentifier($baseDir, $revision)
 51395 {
 51396 return rtrim($baseDir, '/') . $this->packagePath . '/@' . $revision;
 51397 }
 51398 }
 51399 <?php
 51400 
 51401 
 51402 
 51403 
 51404 
 51405 
 51406 
 51407 
 51408 
 51409 
 51410 
 51411 namespace Composer\Repository\Vcs;
 51412 
 51413 use Composer\Cache;
 51414 use Composer\Downloader\TransportException;
 51415 use Composer\Config;
 51416 use Composer\IO\IOInterface;
 51417 use Composer\Json\JsonFile;
 51418 use Composer\Pcre\Preg;
 51419 use Composer\Util\ProcessExecutor;
 51420 use Composer\Util\HttpDownloader;
 51421 use Composer\Util\Filesystem;
 51422 use Composer\Util\Http\Response;
 51423 
 51424 
 51425 
 51426 
 51427 
 51428 
 51429 abstract class VcsDriver implements VcsDriverInterface
 51430 {
 51431 
 51432 protected $url;
 51433 
 51434 protected $originUrl;
 51435 
 51436 protected $repoConfig;
 51437 
 51438 protected $io;
 51439 
 51440 protected $config;
 51441 
 51442 protected $process;
 51443 
 51444 protected $httpDownloader;
 51445 
 51446 protected $infoCache = array();
 51447 
 51448 protected $cache;
 51449 
 51450 
 51451 
 51452 
 51453 
 51454 
 51455 
 51456 
 51457 
 51458 
 51459 final public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process)
 51460 {
 51461 if (Filesystem::isLocalPath($repoConfig['url'])) {
 51462 $repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']);
 51463 }
 51464 
 51465 $this->url = $repoConfig['url'];
 51466 $this->originUrl = $repoConfig['url'];
 51467 $this->repoConfig = $repoConfig;
 51468 $this->io = $io;
 51469 $this->config = $config;
 51470 $this->httpDownloader = $httpDownloader;
 51471 $this->process = $process;
 51472 }
 51473 
 51474 
 51475 
 51476 
 51477 
 51478 
 51479 
 51480 protected function shouldCache($identifier)
 51481 {
 51482 return $this->cache && Preg::isMatch('{^[a-f0-9]{40}$}iD', $identifier);
 51483 }
 51484 
 51485 
 51486 
 51487 
 51488 public function getComposerInformation($identifier)
 51489 {
 51490 if (!isset($this->infoCache[$identifier])) {
 51491 if ($this->shouldCache($identifier) && $res = $this->cache->read($identifier)) {
 51492 return $this->infoCache[$identifier] = JsonFile::parseJson($res);
 51493 }
 51494 
 51495 $composer = $this->getBaseComposerInformation($identifier);
 51496 
 51497 if ($this->shouldCache($identifier)) {
 51498 $this->cache->write($identifier, JsonFile::encode($composer, 0));
 51499 }
 51500 
 51501 $this->infoCache[$identifier] = $composer;
 51502 }
 51503 
 51504 return $this->infoCache[$identifier];
 51505 }
 51506 
 51507 
 51508 
 51509 
 51510 
 51511 
 51512 protected function getBaseComposerInformation($identifier)
 51513 {
 51514 $composerFileContent = $this->getFileContent('composer.json', $identifier);
 51515 
 51516 if (!$composerFileContent) {
 51517 return null;
 51518 }
 51519 
 51520 $composer = JsonFile::parseJson($composerFileContent, $identifier . ':composer.json');
 51521 
 51522 if (empty($composer['time']) && $changeDate = $this->getChangeDate($identifier)) {
 51523 $composer['time'] = $changeDate->format(DATE_RFC3339);
 51524 }
 51525 
 51526 return $composer;
 51527 }
 51528 
 51529 
 51530 
 51531 
 51532 public function hasComposerFile($identifier)
 51533 {
 51534 try {
 51535 return (bool) $this->getComposerInformation($identifier);
 51536 } catch (TransportException $e) {
 51537 }
 51538 
 51539 return false;
 51540 }
 51541 
 51542 
 51543 
 51544 
 51545 
 51546 
 51547 
 51548 
 51549 protected function getScheme()
 51550 {
 51551 if (extension_loaded('openssl')) {
 51552 return 'https';
 51553 }
 51554 
 51555 return 'http';
 51556 }
 51557 
 51558 
 51559 
 51560 
 51561 
 51562 
 51563 
 51564 
 51565 
 51566 protected function getContents($url)
 51567 {
 51568 $options = isset($this->repoConfig['options']) ? $this->repoConfig['options'] : array();
 51569 
 51570 return $this->httpDownloader->get($url, $options);
 51571 }
 51572 
 51573 
 51574 
 51575 
 51576 public function cleanup()
 51577 {
 51578 return;
 51579 }
 51580 }
 51581 <?php
 51582 
 51583 
 51584 
 51585 
 51586 
 51587 
 51588 
 51589 
 51590 
 51591 
 51592 
 51593 namespace Composer\Repository\Vcs;
 51594 
 51595 use Composer\Config;
 51596 use Composer\IO\IOInterface;
 51597 
 51598 
 51599 
 51600 
 51601 interface VcsDriverInterface
 51602 {
 51603 
 51604 
 51605 
 51606 
 51607 
 51608 public function initialize();
 51609 
 51610 
 51611 
 51612 
 51613 
 51614 
 51615 
 51616 public function getComposerInformation($identifier);
 51617 
 51618 
 51619 
 51620 
 51621 
 51622 
 51623 
 51624 
 51625 public function getFileContent($file, $identifier);
 51626 
 51627 
 51628 
 51629 
 51630 
 51631 
 51632 
 51633 public function getChangeDate($identifier);
 51634 
 51635 
 51636 
 51637 
 51638 
 51639 
 51640 public function getRootIdentifier();
 51641 
 51642 
 51643 
 51644 
 51645 
 51646 
 51647 public function getBranches();
 51648 
 51649 
 51650 
 51651 
 51652 
 51653 
 51654 public function getTags();
 51655 
 51656 
 51657 
 51658 
 51659 
 51660 
 51661 public function getDist($identifier);
 51662 
 51663 
 51664 
 51665 
 51666 
 51667 
 51668 public function getSource($identifier);
 51669 
 51670 
 51671 
 51672 
 51673 
 51674 
 51675 public function getUrl();
 51676 
 51677 
 51678 
 51679 
 51680 
 51681 
 51682 
 51683 
 51684 public function hasComposerFile($identifier);
 51685 
 51686 
 51687 
 51688 
 51689 
 51690 
 51691 public function cleanup();
 51692 
 51693 
 51694 
 51695 
 51696 
 51697 
 51698 
 51699 
 51700 
 51701 
 51702 public static function supports(IOInterface $io, Config $config, $url, $deep = false);
 51703 }
 51704 <?php
 51705 
 51706 
 51707 
 51708 
 51709 
 51710 
 51711 
 51712 
 51713 
 51714 
 51715 
 51716 namespace Composer\Repository;
 51717 
 51718 use Composer\Downloader\TransportException;
 51719 use Composer\Pcre\Preg;
 51720 use Composer\Repository\Vcs\VcsDriverInterface;
 51721 use Composer\Package\Version\VersionParser;
 51722 use Composer\Package\Loader\ArrayLoader;
 51723 use Composer\Package\Loader\ValidatingArrayLoader;
 51724 use Composer\Package\Loader\InvalidPackageException;
 51725 use Composer\Package\Loader\LoaderInterface;
 51726 use Composer\EventDispatcher\EventDispatcher;
 51727 use Composer\Util\ProcessExecutor;
 51728 use Composer\Util\HttpDownloader;
 51729 use Composer\Util\Url;
 51730 use Composer\Semver\Constraint\Constraint;
 51731 use Composer\IO\IOInterface;
 51732 use Composer\Config;
 51733 
 51734 
 51735 
 51736 
 51737 class VcsRepository extends ArrayRepository implements ConfigurableRepositoryInterface
 51738 {
 51739 
 51740 protected $url;
 51741 
 51742 protected $packageName;
 51743 
 51744 protected $isVerbose;
 51745 
 51746 protected $isVeryVerbose;
 51747 
 51748 protected $io;
 51749 
 51750 protected $config;
 51751 
 51752 protected $versionParser;
 51753 
 51754 protected $type;
 51755 
 51756 protected $loader;
 51757 
 51758 protected $repoConfig;
 51759 
 51760 protected $httpDownloader;
 51761 
 51762 protected $processExecutor;
 51763 
 51764 protected $branchErrorOccurred = false;
 51765 
 51766 private $drivers;
 51767 
 51768 private $driver;
 51769 
 51770 private $versionCache;
 51771 
 51772 private $emptyReferences = array();
 51773 
 51774 private $versionTransportExceptions = array();
 51775 
 51776 
 51777 
 51778 
 51779 
 51780 public function __construct(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $dispatcher = null, ProcessExecutor $process = null, array $drivers = null, VersionCacheInterface $versionCache = null)
 51781 {
 51782 parent::__construct();
 51783 $this->drivers = $drivers ?: array(
 51784 'github' => 'Composer\Repository\Vcs\GitHubDriver',
 51785 'gitlab' => 'Composer\Repository\Vcs\GitLabDriver',
 51786 'bitbucket' => 'Composer\Repository\Vcs\GitBitbucketDriver',
 51787 'git-bitbucket' => 'Composer\Repository\Vcs\GitBitbucketDriver',
 51788 'git' => 'Composer\Repository\Vcs\GitDriver',
 51789 'hg' => 'Composer\Repository\Vcs\HgDriver',
 51790 'perforce' => 'Composer\Repository\Vcs\PerforceDriver',
 51791 'fossil' => 'Composer\Repository\Vcs\FossilDriver',
 51792 
 51793 'svn' => 'Composer\Repository\Vcs\SvnDriver',
 51794 );
 51795 
 51796 $this->url = $repoConfig['url'];
 51797 $this->io = $io;
 51798 $this->type = isset($repoConfig['type']) ? $repoConfig['type'] : 'vcs';
 51799 $this->isVerbose = $io->isVerbose();
 51800 $this->isVeryVerbose = $io->isVeryVerbose();
 51801 $this->config = $config;
 51802 $this->repoConfig = $repoConfig;
 51803 $this->versionCache = $versionCache;
 51804 $this->httpDownloader = $httpDownloader;
 51805 $this->processExecutor = $process ?: new ProcessExecutor($io);
 51806 }
 51807 
 51808 public function getRepoName()
 51809 {
 51810 $driverClass = get_class($this->getDriver());
 51811 $driverType = array_search($driverClass, $this->drivers);
 51812 if (!$driverType) {
 51813 $driverType = $driverClass;
 51814 }
 51815 
 51816 return 'vcs repo ('.$driverType.' '.Url::sanitize($this->url).')';
 51817 }
 51818 
 51819 public function getRepoConfig()
 51820 {
 51821 return $this->repoConfig;
 51822 }
 51823 
 51824 
 51825 
 51826 
 51827 public function setLoader(LoaderInterface $loader)
 51828 {
 51829 $this->loader = $loader;
 51830 }
 51831 
 51832 
 51833 
 51834 
 51835 public function getDriver()
 51836 {
 51837 if ($this->driver) {
 51838 return $this->driver;
 51839 }
 51840 
 51841 if (isset($this->drivers[$this->type])) {
 51842 $class = $this->drivers[$this->type];
 51843 $this->driver = new $class($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->processExecutor);
 51844 $this->driver->initialize();
 51845 
 51846 return $this->driver;
 51847 }
 51848 
 51849 foreach ($this->drivers as $driver) {
 51850 if ($driver::supports($this->io, $this->config, $this->url)) {
 51851 $this->driver = new $driver($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->processExecutor);
 51852 $this->driver->initialize();
 51853 
 51854 return $this->driver;
 51855 }
 51856 }
 51857 
 51858 foreach ($this->drivers as $driver) {
 51859 if ($driver::supports($this->io, $this->config, $this->url, true)) {
 51860 $this->driver = new $driver($this->repoConfig, $this->io, $this->config, $this->httpDownloader, $this->processExecutor);
 51861 $this->driver->initialize();
 51862 
 51863 return $this->driver;
 51864 }
 51865 }
 51866 
 51867 return null;
 51868 }
 51869 
 51870 
 51871 
 51872 
 51873 public function hadInvalidBranches()
 51874 {
 51875 return $this->branchErrorOccurred;
 51876 }
 51877 
 51878 
 51879 
 51880 
 51881 public function getEmptyReferences()
 51882 {
 51883 return $this->emptyReferences;
 51884 }
 51885 
 51886 
 51887 
 51888 
 51889 public function getVersionTransportExceptions()
 51890 {
 51891 return $this->versionTransportExceptions;
 51892 }
 51893 
 51894 protected function initialize()
 51895 {
 51896 parent::initialize();
 51897 
 51898 $isVerbose = $this->isVerbose;
 51899 $isVeryVerbose = $this->isVeryVerbose;
 51900 
 51901 $driver = $this->getDriver();
 51902 if (!$driver) {
 51903 throw new \InvalidArgumentException('No driver found to handle VCS repository '.$this->url);
 51904 }
 51905 
 51906 $this->versionParser = new VersionParser;
 51907 if (!$this->loader) {
 51908 $this->loader = new ArrayLoader($this->versionParser);
 51909 }
 51910 
 51911 $hasRootIdentifierComposerJson = false;
 51912 try {
 51913 $hasRootIdentifierComposerJson = $driver->hasComposerFile($driver->getRootIdentifier());
 51914 if ($hasRootIdentifierComposerJson) {
 51915 $data = $driver->getComposerInformation($driver->getRootIdentifier());
 51916 $this->packageName = !empty($data['name']) ? $data['name'] : null;
 51917 }
 51918 } catch (\Exception $e) {
 51919 if ($e instanceof TransportException && $this->shouldRethrowTransportException($e)) {
 51920 throw $e;
 51921 }
 51922 
 51923 if ($isVeryVerbose) {
 51924 $this->io->writeError('<error>Skipped parsing '.$driver->getRootIdentifier().', '.$e->getMessage().'</error>');
 51925 }
 51926 }
 51927 
 51928 foreach ($driver->getTags() as $tag => $identifier) {
 51929 $tag = (string) $tag;
 51930 $msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $tag . '</comment>)';
 51931 if ($isVeryVerbose) {
 51932 $this->io->writeError($msg);
 51933 } elseif ($isVerbose) {
 51934 $this->io->overwriteError($msg, false);
 51935 }
 51936 
 51937 
 51938 $tag = str_replace('release-', '', $tag);
 51939 
 51940 $cachedPackage = $this->getCachedPackageVersion($tag, $identifier, $isVerbose, $isVeryVerbose);
 51941 if ($cachedPackage) {
 51942 $this->addPackage($cachedPackage);
 51943 
 51944 continue;
 51945 }
 51946 if ($cachedPackage === false) {
 51947 $this->emptyReferences[] = $identifier;
 51948 
 51949 continue;
 51950 }
 51951 
 51952 if (!$parsedTag = $this->validateTag($tag)) {
 51953 if ($isVeryVerbose) {
 51954 $this->io->writeError('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
 51955 }
 51956 continue;
 51957 }
 51958 
 51959 try {
 51960 if (!$data = $driver->getComposerInformation($identifier)) {
 51961 if ($isVeryVerbose) {
 51962 $this->io->writeError('<warning>Skipped tag '.$tag.', no composer file</warning>');
 51963 }
 51964 $this->emptyReferences[] = $identifier;
 51965 continue;
 51966 }
 51967 
 51968 
 51969 if (isset($data['version'])) {
 51970 $data['version_normalized'] = $this->versionParser->normalize($data['version']);
 51971 } else {
 51972 
 51973 $data['version'] = $tag;
 51974 $data['version_normalized'] = $parsedTag;
 51975 }
 51976 
 51977 
 51978 $data['version'] = Preg::replace('{[.-]?dev$}i', '', $data['version']);
 51979 $data['version_normalized'] = Preg::replace('{(^dev-|[.-]?dev$)}i', '', $data['version_normalized']);
 51980 
 51981 
 51982 unset($data['default-branch']);
 51983 
 51984 
 51985 if ($data['version_normalized'] !== $parsedTag) {
 51986 if ($isVeryVerbose) {
 51987 if (Preg::isMatch('{(^dev-|[.-]?dev$)}i', $parsedTag)) {
 51988 $this->io->writeError('<warning>Skipped tag '.$tag.', invalid tag name, tags can not use dev prefixes or suffixes</warning>');
 51989 } else {
 51990 $this->io->writeError('<warning>Skipped tag '.$tag.', tag ('.$parsedTag.') does not match version ('.$data['version_normalized'].') in composer.json</warning>');
 51991 }
 51992 }
 51993 continue;
 51994 }
 51995 
 51996 $tagPackageName = $this->packageName ?: (isset($data['name']) ? $data['name'] : '');
 51997 if ($existingPackage = $this->findPackage($tagPackageName, $data['version_normalized'])) {
 51998 if ($isVeryVerbose) {
 51999 $this->io->writeError('<warning>Skipped tag '.$tag.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$data['version_normalized'].' internally</warning>');
 52000 }
 52001 continue;
 52002 }
 52003 
 52004 if ($isVeryVerbose) {
 52005 $this->io->writeError('Importing tag '.$tag.' ('.$data['version_normalized'].')');
 52006 }
 52007 
 52008 $this->addPackage($this->loader->load($this->preProcess($driver, $data, $identifier)));
 52009 } catch (\Exception $e) {
 52010 if ($e instanceof TransportException) {
 52011 $this->versionTransportExceptions['tags'][$tag] = $e;
 52012 if ($e->getCode() === 404) {
 52013 $this->emptyReferences[] = $identifier;
 52014 }
 52015 if ($this->shouldRethrowTransportException($e)) {
 52016 throw $e;
 52017 }
 52018 }
 52019 if ($isVeryVerbose) {
 52020 $this->io->writeError('<warning>Skipped tag '.$tag.', '.($e instanceof TransportException ? 'no composer file was found (' . $e->getCode() . ' HTTP status code)' : $e->getMessage()).'</warning>');
 52021 }
 52022 continue;
 52023 }
 52024 }
 52025 
 52026 if (!$isVeryVerbose) {
 52027 $this->io->overwriteError('', false);
 52028 }
 52029 
 52030 $branches = $driver->getBranches();
 52031 
 52032 if ($hasRootIdentifierComposerJson && isset($branches[$driver->getRootIdentifier()])) {
 52033 $branches = array($driver->getRootIdentifier() => $branches[$driver->getRootIdentifier()]) + $branches;
 52034 }
 52035 
 52036 foreach ($branches as $branch => $identifier) {
 52037 $branch = (string) $branch;
 52038 $msg = 'Reading composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $branch . '</comment>)';
 52039 if ($isVeryVerbose) {
 52040 $this->io->writeError($msg);
 52041 } elseif ($isVerbose) {
 52042 $this->io->overwriteError($msg, false);
 52043 }
 52044 
 52045 if (!$parsedBranch = $this->validateBranch($branch)) {
 52046 if ($isVeryVerbose) {
 52047 $this->io->writeError('<warning>Skipped branch '.$branch.', invalid name</warning>');
 52048 }
 52049 continue;
 52050 }
 52051 
 52052 
 52053 if (strpos($parsedBranch, 'dev-') === 0 || VersionParser::DEFAULT_BRANCH_ALIAS === $parsedBranch) {
 52054 $version = 'dev-' . $branch;
 52055 } else {
 52056 $prefix = strpos($branch, 'v') === 0 ? 'v' : '';
 52057 $version = $prefix . Preg::replace('{(\.9{7})+}', '.x', $parsedBranch);
 52058 }
 52059 
 52060 $cachedPackage = $this->getCachedPackageVersion($version, $identifier, $isVerbose, $isVeryVerbose, $driver->getRootIdentifier() === $branch);
 52061 if ($cachedPackage) {
 52062 $this->addPackage($cachedPackage);
 52063 
 52064 continue;
 52065 }
 52066 if ($cachedPackage === false) {
 52067 $this->emptyReferences[] = $identifier;
 52068 
 52069 continue;
 52070 }
 52071 
 52072 try {
 52073 if (!$data = $driver->getComposerInformation($identifier)) {
 52074 if ($isVeryVerbose) {
 52075 $this->io->writeError('<warning>Skipped branch '.$branch.', no composer file</warning>');
 52076 }
 52077 $this->emptyReferences[] = $identifier;
 52078 continue;
 52079 }
 52080 
 52081 
 52082 $data['version'] = $version;
 52083 $data['version_normalized'] = $parsedBranch;
 52084 
 52085 unset($data['default-branch']);
 52086 if ($driver->getRootIdentifier() === $branch) {
 52087 $data['default-branch'] = true;
 52088 }
 52089 
 52090 if ($isVeryVerbose) {
 52091 $this->io->writeError('Importing branch '.$branch.' ('.$data['version'].')');
 52092 }
 52093 
 52094 $packageData = $this->preProcess($driver, $data, $identifier);
 52095 $package = $this->loader->load($packageData);
 52096 if ($this->loader instanceof ValidatingArrayLoader && $this->loader->getWarnings()) {
 52097 throw new InvalidPackageException($this->loader->getErrors(), $this->loader->getWarnings(), $packageData);
 52098 }
 52099 $this->addPackage($package);
 52100 } catch (TransportException $e) {
 52101 $this->versionTransportExceptions['branches'][$branch] = $e;
 52102 if ($e->getCode() === 404) {
 52103 $this->emptyReferences[] = $identifier;
 52104 }
 52105 if ($this->shouldRethrowTransportException($e)) {
 52106 throw $e;
 52107 }
 52108 if ($isVeryVerbose) {
 52109 $this->io->writeError('<warning>Skipped branch '.$branch.', no composer file was found (' . $e->getCode() . ' HTTP status code)</warning>');
 52110 }
 52111 continue;
 52112 } catch (\Exception $e) {
 52113 if (!$isVeryVerbose) {
 52114 $this->io->writeError('');
 52115 }
 52116 $this->branchErrorOccurred = true;
 52117 $this->io->writeError('<error>Skipped branch '.$branch.', '.$e->getMessage().'</error>');
 52118 $this->io->writeError('');
 52119 continue;
 52120 }
 52121 }
 52122 $driver->cleanup();
 52123 
 52124 if (!$isVeryVerbose) {
 52125 $this->io->overwriteError('', false);
 52126 }
 52127 
 52128 if (!$this->getPackages()) {
 52129 throw new InvalidRepositoryException('No valid composer.json was found in any branch or tag of '.$this->url.', could not load a package from it.');
 52130 }
 52131 }
 52132 
 52133 
 52134 
 52135 
 52136 
 52137 
 52138 
 52139 
 52140 protected function preProcess(VcsDriverInterface $driver, array $data, $identifier)
 52141 {
 52142 
 52143 
 52144 
 52145 $dataPackageName = isset($data['name']) ? $data['name'] : null;
 52146 $data['name'] = $this->packageName ?: $dataPackageName;
 52147 
 52148 if (!isset($data['dist'])) {
 52149 $data['dist'] = $driver->getDist($identifier);
 52150 }
 52151 if (!isset($data['source'])) {
 52152 $data['source'] = $driver->getSource($identifier);
 52153 }
 52154 
 52155 return $data;
 52156 }
 52157 
 52158 
 52159 
 52160 
 52161 
 52162 
 52163 private function validateBranch($branch)
 52164 {
 52165 try {
 52166 $normalizedBranch = $this->versionParser->normalizeBranch($branch);
 52167 
 52168 
 52169 $this->versionParser->parseConstraints($normalizedBranch);
 52170 
 52171 return $normalizedBranch;
 52172 } catch (\Exception $e) {
 52173 }
 52174 
 52175 return false;
 52176 }
 52177 
 52178 
 52179 
 52180 
 52181 
 52182 
 52183 private function validateTag($version)
 52184 {
 52185 try {
 52186 return $this->versionParser->normalize($version);
 52187 } catch (\Exception $e) {
 52188 }
 52189 
 52190 return false;
 52191 }
 52192 
 52193 
 52194 
 52195 
 52196 
 52197 
 52198 
 52199 
 52200 
 52201 
 52202 private function getCachedPackageVersion($version, $identifier, $isVerbose, $isVeryVerbose, $isDefaultBranch = false)
 52203 {
 52204 if (!$this->versionCache) {
 52205 return null;
 52206 }
 52207 
 52208 $cachedPackage = $this->versionCache->getVersionPackage($version, $identifier);
 52209 if ($cachedPackage === false) {
 52210 if ($isVeryVerbose) {
 52211 $this->io->writeError('<warning>Skipped '.$version.', no composer file (cached from ref '.$identifier.')</warning>');
 52212 }
 52213 
 52214 return false;
 52215 }
 52216 
 52217 if ($cachedPackage) {
 52218 $msg = 'Found cached composer.json of <info>' . ($this->packageName ?: $this->url) . '</info> (<comment>' . $version . '</comment>)';
 52219 if ($isVeryVerbose) {
 52220 $this->io->writeError($msg);
 52221 } elseif ($isVerbose) {
 52222 $this->io->overwriteError($msg, false);
 52223 }
 52224 
 52225 unset($cachedPackage['default-branch']);
 52226 if ($isDefaultBranch) {
 52227 $cachedPackage['default-branch'] = true;
 52228 }
 52229 
 52230 if ($existingPackage = $this->findPackage($cachedPackage['name'], new Constraint('=', $cachedPackage['version_normalized']))) {
 52231 if ($isVeryVerbose) {
 52232 $this->io->writeError('<warning>Skipped cached version '.$version.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$cachedPackage['version_normalized'].' internally</warning>');
 52233 }
 52234 $cachedPackage = null;
 52235 }
 52236 }
 52237 
 52238 if ($cachedPackage) {
 52239 return $this->loader->load($cachedPackage);
 52240 }
 52241 
 52242 return null;
 52243 }
 52244 
 52245 
 52246 
 52247 
 52248 private function shouldRethrowTransportException(TransportException $e)
 52249 {
 52250 return in_array($e->getCode(), array(401, 403, 429), true) || $e->getCode() >= 500;
 52251 }
 52252 }
 52253 <?php
 52254 
 52255 
 52256 
 52257 
 52258 
 52259 
 52260 
 52261 
 52262 
 52263 
 52264 
 52265 namespace Composer\Repository;
 52266 
 52267 interface VersionCacheInterface
 52268 {
 52269 
 52270 
 52271 
 52272 
 52273 
 52274 public function getVersionPackage($version, $identifier);
 52275 }
 52276 <?php
 52277 
 52278 
 52279 
 52280 
 52281 
 52282 
 52283 
 52284 
 52285 
 52286 
 52287 
 52288 namespace Composer\Repository;
 52289 
 52290 use Composer\Package\AliasPackage;
 52291 use Composer\Installer\InstallationManager;
 52292 
 52293 
 52294 
 52295 
 52296 
 52297 
 52298 class WritableArrayRepository extends ArrayRepository implements WritableRepositoryInterface
 52299 {
 52300 
 52301 
 52302 
 52303 protected $devPackageNames = array();
 52304 
 52305 
 52306 private $devMode = null;
 52307 
 52308 
 52309 
 52310 
 52311 public function getDevMode()
 52312 {
 52313 return $this->devMode;
 52314 }
 52315 
 52316 
 52317 
 52318 
 52319 public function setDevPackageNames(array $devPackageNames)
 52320 {
 52321 $this->devPackageNames = $devPackageNames;
 52322 }
 52323 
 52324 
 52325 
 52326 
 52327 public function getDevPackageNames()
 52328 {
 52329 return $this->devPackageNames;
 52330 }
 52331 
 52332 
 52333 
 52334 
 52335 public function write($devMode, InstallationManager $installationManager)
 52336 {
 52337 $this->devMode = $devMode;
 52338 }
 52339 
 52340 
 52341 
 52342 
 52343 public function reload()
 52344 {
 52345 $this->devMode = null;
 52346 }
 52347 
 52348 
 52349 
 52350 
 52351 public function getCanonicalPackages()
 52352 {
 52353 $packages = $this->getPackages();
 52354 
 52355 
 52356 $packagesByName = array();
 52357 foreach ($packages as $package) {
 52358 if (!isset($packagesByName[$package->getName()]) || $packagesByName[$package->getName()] instanceof AliasPackage) {
 52359 $packagesByName[$package->getName()] = $package;
 52360 }
 52361 }
 52362 
 52363 $canonicalPackages = array();
 52364 
 52365 
 52366 foreach ($packagesByName as $package) {
 52367 while ($package instanceof AliasPackage) {
 52368 $package = $package->getAliasOf();
 52369 }
 52370 
 52371 $canonicalPackages[] = $package;
 52372 }
 52373 
 52374 return $canonicalPackages;
 52375 }
 52376 }
 52377 <?php
 52378 
 52379 
 52380 
 52381 
 52382 
 52383 
 52384 
 52385 
 52386 
 52387 
 52388 
 52389 namespace Composer\Repository;
 52390 
 52391 use Composer\Package\PackageInterface;
 52392 use Composer\Installer\InstallationManager;
 52393 
 52394 
 52395 
 52396 
 52397 
 52398 
 52399 interface WritableRepositoryInterface extends RepositoryInterface
 52400 {
 52401 
 52402 
 52403 
 52404 
 52405 
 52406 
 52407 public function write($devMode, InstallationManager $installationManager);
 52408 
 52409 
 52410 
 52411 
 52412 
 52413 
 52414 
 52415 public function addPackage(PackageInterface $package);
 52416 
 52417 
 52418 
 52419 
 52420 
 52421 
 52422 
 52423 public function removePackage(PackageInterface $package);
 52424 
 52425 
 52426 
 52427 
 52428 
 52429 
 52430 public function getCanonicalPackages();
 52431 
 52432 
 52433 
 52434 
 52435 
 52436 
 52437 public function reload();
 52438 
 52439 
 52440 
 52441 
 52442 
 52443 public function setDevPackageNames(array $devPackageNames);
 52444 
 52445 
 52446 
 52447 
 52448 public function getDevPackageNames();
 52449 }
 52450 <?php
 52451 
 52452 
 52453 
 52454 
 52455 
 52456 
 52457 
 52458 
 52459 
 52460 
 52461 
 52462 namespace Composer\Script;
 52463 
 52464 use Composer\Composer;
 52465 use Composer\IO\IOInterface;
 52466 use Composer\EventDispatcher\Event as BaseEvent;
 52467 
 52468 
 52469 
 52470 
 52471 
 52472 
 52473 
 52474 class Event extends BaseEvent
 52475 {
 52476 
 52477 
 52478 
 52479 private $composer;
 52480 
 52481 
 52482 
 52483 
 52484 private $io;
 52485 
 52486 
 52487 
 52488 
 52489 private $devMode;
 52490 
 52491 
 52492 
 52493 
 52494 private $originatingEvent;
 52495 
 52496 
 52497 
 52498 
 52499 
 52500 
 52501 
 52502 
 52503 
 52504 
 52505 
 52506 public function __construct($name, Composer $composer, IOInterface $io, $devMode = false, array $args = array(), array $flags = array())
 52507 {
 52508 parent::__construct($name, $args, $flags);
 52509 $this->composer = $composer;
 52510 $this->io = $io;
 52511 $this->devMode = $devMode;
 52512 }
 52513 
 52514 
 52515 
 52516 
 52517 
 52518 
 52519 public function getComposer()
 52520 {
 52521 return $this->composer;
 52522 }
 52523 
 52524 
 52525 
 52526 
 52527 
 52528 
 52529 public function getIO()
 52530 {
 52531 return $this->io;
 52532 }
 52533 
 52534 
 52535 
 52536 
 52537 
 52538 
 52539 public function isDevMode()
 52540 {
 52541 return $this->devMode;
 52542 }
 52543 
 52544 
 52545 
 52546 
 52547 
 52548 
 52549 public function getOriginatingEvent()
 52550 {
 52551 return $this->originatingEvent;
 52552 }
 52553 
 52554 
 52555 
 52556 
 52557 
 52558 
 52559 
 52560 public function setOriginatingEvent(BaseEvent $event)
 52561 {
 52562 $this->originatingEvent = $this->calculateOriginatingEvent($event);
 52563 
 52564 return $this;
 52565 }
 52566 
 52567 
 52568 
 52569 
 52570 
 52571 
 52572 
 52573 private function calculateOriginatingEvent(BaseEvent $event)
 52574 {
 52575 if ($event instanceof Event && $event->getOriginatingEvent()) {
 52576 return $this->calculateOriginatingEvent($event->getOriginatingEvent());
 52577 }
 52578 
 52579 return $event;
 52580 }
 52581 }
 52582 <?php
 52583 
 52584 
 52585 
 52586 
 52587 
 52588 
 52589 
 52590 
 52591 
 52592 
 52593 
 52594 namespace Composer\Script;
 52595 
 52596 
 52597 
 52598 
 52599 
 52600 
 52601 
 52602 class ScriptEvents
 52603 {
 52604 
 52605 
 52606 
 52607 
 52608 
 52609 
 52610 
 52611 const PRE_INSTALL_CMD = 'pre-install-cmd';
 52612 
 52613 
 52614 
 52615 
 52616 
 52617 
 52618 
 52619 
 52620 const POST_INSTALL_CMD = 'post-install-cmd';
 52621 
 52622 
 52623 
 52624 
 52625 
 52626 
 52627 
 52628 
 52629 const PRE_UPDATE_CMD = 'pre-update-cmd';
 52630 
 52631 
 52632 
 52633 
 52634 
 52635 
 52636 
 52637 
 52638 const POST_UPDATE_CMD = 'post-update-cmd';
 52639 
 52640 
 52641 
 52642 
 52643 
 52644 
 52645 
 52646 
 52647 const PRE_STATUS_CMD = 'pre-status-cmd';
 52648 
 52649 
 52650 
 52651 
 52652 
 52653 
 52654 
 52655 
 52656 const POST_STATUS_CMD = 'post-status-cmd';
 52657 
 52658 
 52659 
 52660 
 52661 
 52662 
 52663 
 52664 
 52665 const PRE_AUTOLOAD_DUMP = 'pre-autoload-dump';
 52666 
 52667 
 52668 
 52669 
 52670 
 52671 
 52672 
 52673 
 52674 const POST_AUTOLOAD_DUMP = 'post-autoload-dump';
 52675 
 52676 
 52677 
 52678 
 52679 
 52680 
 52681 
 52682 
 52683 const POST_ROOT_PACKAGE_INSTALL = 'post-root-package-install';
 52684 
 52685 
 52686 
 52687 
 52688 
 52689 
 52690 
 52691 
 52692 
 52693 const POST_CREATE_PROJECT_CMD = 'post-create-project-cmd';
 52694 
 52695 
 52696 
 52697 
 52698 
 52699 
 52700 
 52701 
 52702 const PRE_ARCHIVE_CMD = 'pre-archive-cmd';
 52703 
 52704 
 52705 
 52706 
 52707 
 52708 
 52709 
 52710 
 52711 const POST_ARCHIVE_CMD = 'post-archive-cmd';
 52712 }
 52713 <?php
 52714 
 52715 
 52716 
 52717 
 52718 
 52719 
 52720 
 52721 
 52722 
 52723 
 52724 
 52725 namespace Composer\SelfUpdate;
 52726 
 52727 use Composer\Pcre\Preg;
 52728 
 52729 
 52730 
 52731 
 52732 class Keys
 52733 {
 52734 
 52735 
 52736 
 52737 
 52738 
 52739 public static function fingerprint($path)
 52740 {
 52741 $hash = strtoupper(hash('sha256', Preg::replace('{\s}', '', file_get_contents($path))));
 52742 
 52743 return implode(' ', array(
 52744 substr($hash, 0, 8),
 52745 substr($hash, 8, 8),
 52746 substr($hash, 16, 8),
 52747 substr($hash, 24, 8),
 52748 '', 
 52749 substr($hash, 32, 8),
 52750 substr($hash, 40, 8),
 52751 substr($hash, 48, 8),
 52752 substr($hash, 56, 8),
 52753 ));
 52754 }
 52755 }
 52756 <?php
 52757 
 52758 
 52759 
 52760 
 52761 
 52762 
 52763 
 52764 
 52765 
 52766 
 52767 
 52768 namespace Composer\SelfUpdate;
 52769 
 52770 use Composer\Util\HttpDownloader;
 52771 use Composer\Config;
 52772 
 52773 
 52774 
 52775 
 52776 class Versions
 52777 {
 52778 
 52779 public static $channels = array('stable', 'preview', 'snapshot', '1', '2');
 52780 
 52781 
 52782 private $httpDownloader;
 52783 
 52784 private $config;
 52785 
 52786 private $channel;
 52787 
 52788 private $versionsData;
 52789 
 52790 public function __construct(Config $config, HttpDownloader $httpDownloader)
 52791 {
 52792 $this->httpDownloader = $httpDownloader;
 52793 $this->config = $config;
 52794 }
 52795 
 52796 
 52797 
 52798 
 52799 public function getChannel()
 52800 {
 52801 if ($this->channel) {
 52802 return $this->channel;
 52803 }
 52804 
 52805 $channelFile = $this->config->get('home').'/update-channel';
 52806 if (file_exists($channelFile)) {
 52807 $channel = trim(file_get_contents($channelFile));
 52808 if (in_array($channel, array('stable', 'preview', 'snapshot'), true)) {
 52809 return $this->channel = $channel;
 52810 }
 52811 }
 52812 
 52813 return $this->channel = 'stable';
 52814 }
 52815 
 52816 
 52817 
 52818 
 52819 
 52820 
 52821 public function setChannel($channel)
 52822 {
 52823 if (!in_array($channel, self::$channels, true)) {
 52824 throw new \InvalidArgumentException('Invalid channel '.$channel.', must be one of: ' . implode(', ', self::$channels));
 52825 }
 52826 
 52827 $channelFile = $this->config->get('home').'/update-channel';
 52828 $this->channel = $channel;
 52829 file_put_contents($channelFile, (is_numeric($channel) ? 'stable' : $channel).PHP_EOL);
 52830 }
 52831 
 52832 
 52833 
 52834 
 52835 
 52836 
 52837 public function getLatest($channel = null)
 52838 {
 52839 $versions = $this->getVersionsData();
 52840 
 52841 foreach ($versions[$channel ?: $this->getChannel()] as $version) {
 52842 if ($version['min-php'] <= PHP_VERSION_ID) {
 52843 return $version;
 52844 }
 52845 }
 52846 
 52847 throw new \UnexpectedValueException('There is no version of Composer available for your PHP version ('.PHP_VERSION.')');
 52848 }
 52849 
 52850 
 52851 
 52852 
 52853 private function getVersionsData()
 52854 {
 52855 if (!$this->versionsData) {
 52856 if ($this->config->get('disable-tls') === true) {
 52857 $protocol = 'http';
 52858 } else {
 52859 $protocol = 'https';
 52860 }
 52861 
 52862 $this->versionsData = $this->httpDownloader->get($protocol . '://getcomposer.org/versions')->decodeJson();
 52863 }
 52864 
 52865 return $this->versionsData;
 52866 }
 52867 }
 52868 <?php
 52869 
 52870 
 52871 
 52872 
 52873 
 52874 
 52875 
 52876 
 52877 
 52878 
 52879 
 52880 namespace Composer\Util;
 52881 
 52882 use Composer\Config;
 52883 use Composer\IO\IOInterface;
 52884 use Composer\Downloader\TransportException;
 52885 use Composer\Pcre\Preg;
 52886 
 52887 
 52888 
 52889 
 52890 class AuthHelper
 52891 {
 52892 
 52893 protected $io;
 52894 
 52895 protected $config;
 52896 
 52897 private $displayedOriginAuthentications = array();
 52898 
 52899 public function __construct(IOInterface $io, Config $config)
 52900 {
 52901 $this->io = $io;
 52902 $this->config = $config;
 52903 }
 52904 
 52905 
 52906 
 52907 
 52908 
 52909 
 52910 
 52911 public function storeAuth($origin, $storeAuth)
 52912 {
 52913 $store = false;
 52914 $configSource = $this->config->getAuthConfigSource();
 52915 if ($storeAuth === true) {
 52916 $store = $configSource;
 52917 } elseif ($storeAuth === 'prompt') {
 52918 $answer = $this->io->askAndValidate(
 52919 'Do you want to store credentials for '.$origin.' in '.$configSource->getName().' ? [Yn] ',
 52920 function ($value) {
 52921 $input = strtolower(substr(trim($value), 0, 1));
 52922 if (in_array($input, array('y','n'))) {
 52923 return $input;
 52924 }
 52925 throw new \RuntimeException('Please answer (y)es or (n)o');
 52926 },
 52927 null,
 52928 'y'
 52929 );
 52930 
 52931 if ($answer === 'y') {
 52932 $store = $configSource;
 52933 }
 52934 }
 52935 if ($store) {
 52936 $store->addConfigSetting(
 52937 'http-basic.'.$origin,
 52938 $this->io->getAuthentication($origin)
 52939 );
 52940 }
 52941 }
 52942 
 52943 
 52944 
 52945 
 52946 
 52947 
 52948 
 52949 
 52950 
 52951 
 52952 
 52953 public function promptAuthIfNeeded($url, $origin, $statusCode, $reason = null, $headers = array())
 52954 {
 52955 $storeAuth = false;
 52956 
 52957 if (in_array($origin, $this->config->get('github-domains'), true)) {
 52958 $gitHubUtil = new GitHub($this->io, $this->config, null);
 52959 $message = "\n";
 52960 
 52961 $rateLimited = $gitHubUtil->isRateLimited($headers);
 52962 $requiresSso = $gitHubUtil->requiresSso($headers);
 52963 
 52964 if ($requiresSso) {
 52965 $ssoUrl = $gitHubUtil->getSsoUrl($headers);
 52966 $message = 'GitHub API token requires SSO authorization. Authorize this token at ' . $ssoUrl . "\n";
 52967 $this->io->writeError($message);
 52968 if (!$this->io->isInteractive()) {
 52969 throw new TransportException('Could not authenticate against ' . $origin, 403);
 52970 }
 52971 $this->io->ask('After authorizing your token, confirm that you would like to retry the request');
 52972 
 52973 return array('retry' => true, 'storeAuth' => $storeAuth);
 52974 }
 52975 
 52976 if ($rateLimited) {
 52977 $rateLimit = $gitHubUtil->getRateLimit($headers);
 52978 if ($this->io->hasAuthentication($origin)) {
 52979 $message = 'Review your configured GitHub OAuth token or enter a new one to go over the API rate limit.';
 52980 } else {
 52981 $message = 'Create a GitHub OAuth token to go over the API rate limit.';
 52982 }
 52983 
 52984 $message = sprintf(
 52985 'GitHub API limit (%d calls/hr) is exhausted, could not fetch '.$url.'. '.$message.' You can also wait until %s for the rate limit to reset.',
 52986 $rateLimit['limit'],
 52987 $rateLimit['reset']
 52988 )."\n";
 52989 } else {
 52990 $message .= 'Could not fetch '.$url.', please ';
 52991 if ($this->io->hasAuthentication($origin)) {
 52992 $message .= 'review your configured GitHub OAuth token or enter a new one to access private repos';
 52993 } else {
 52994 $message .= 'create a GitHub OAuth token to access private repos';
 52995 }
 52996 }
 52997 
 52998 if (!$gitHubUtil->authorizeOAuth($origin)
 52999 && (!$this->io->isInteractive() || !$gitHubUtil->authorizeOAuthInteractively($origin, $message))
 53000 ) {
 53001 throw new TransportException('Could not authenticate against '.$origin, 401);
 53002 }
 53003 } elseif (in_array($origin, $this->config->get('gitlab-domains'), true)) {
 53004 $message = "\n".'Could not fetch '.$url.', enter your ' . $origin . ' credentials ' .($statusCode === 401 ? 'to access private repos' : 'to go over the API rate limit');
 53005 $gitLabUtil = new GitLab($this->io, $this->config, null);
 53006 
 53007 if ($this->io->hasAuthentication($origin)) {
 53008 $auth = $this->io->getAuthentication($origin);
 53009 if (in_array($auth['password'], array('gitlab-ci-token', 'private-token', 'oauth2'), true)) {
 53010 throw new TransportException("Invalid credentials for '" . $url . "', aborting.", $statusCode);
 53011 }
 53012 }
 53013 
 53014 if (!$gitLabUtil->authorizeOAuth($origin)
 53015 && (!$this->io->isInteractive() || !$gitLabUtil->authorizeOAuthInteractively(parse_url($url, PHP_URL_SCHEME), $origin, $message))
 53016 ) {
 53017 throw new TransportException('Could not authenticate against '.$origin, 401);
 53018 }
 53019 } elseif ($origin === 'bitbucket.org' || $origin === 'api.bitbucket.org') {
 53020 $askForOAuthToken = true;
 53021 $origin = 'bitbucket.org';
 53022 if ($this->io->hasAuthentication($origin)) {
 53023 $auth = $this->io->getAuthentication($origin);
 53024 if ($auth['username'] !== 'x-token-auth') {
 53025 $bitbucketUtil = new Bitbucket($this->io, $this->config);
 53026 $accessToken = $bitbucketUtil->requestToken($origin, $auth['username'], $auth['password']);
 53027 if (!empty($accessToken)) {
 53028 $this->io->setAuthentication($origin, 'x-token-auth', $accessToken);
 53029 $askForOAuthToken = false;
 53030 }
 53031 } else {
 53032 throw new TransportException('Could not authenticate against ' . $origin, 401);
 53033 }
 53034 }
 53035 
 53036 if ($askForOAuthToken) {
 53037 $message = "\n".'Could not fetch ' . $url . ', please create a bitbucket OAuth token to ' . (($statusCode === 401 || $statusCode === 403) ? 'access private repos' : 'go over the API rate limit');
 53038 $bitBucketUtil = new Bitbucket($this->io, $this->config);
 53039 if (!$bitBucketUtil->authorizeOAuth($origin)
 53040 && (!$this->io->isInteractive() || !$bitBucketUtil->authorizeOAuthInteractively($origin, $message))
 53041 ) {
 53042 throw new TransportException('Could not authenticate against ' . $origin, 401);
 53043 }
 53044 }
 53045 } else {
 53046 
 53047 if ($statusCode === 404) {
 53048 return null;
 53049 }
 53050 
 53051 
 53052 if (!$this->io->isInteractive()) {
 53053 if ($statusCode === 401) {
 53054 $message = "The '" . $url . "' URL required authentication.\nYou must be using the interactive console to authenticate";
 53055 } elseif ($statusCode === 403) {
 53056 $message = "The '" . $url . "' URL could not be accessed: " . $reason;
 53057 } else {
 53058 $message = "Unknown error code '" . $statusCode . "', reason: " . $reason;
 53059 }
 53060 
 53061 throw new TransportException($message, $statusCode);
 53062 }
 53063 
 53064 if ($this->io->hasAuthentication($origin)) {
 53065 throw new TransportException("Invalid credentials for '" . $url . "', aborting.", $statusCode);
 53066 }
 53067 
 53068 $this->io->writeError('    Authentication required (<info>'.$origin.'</info>):');
 53069 $username = $this->io->ask('      Username: ');
 53070 $password = $this->io->askAndHideAnswer('      Password: ');
 53071 $this->io->setAuthentication($origin, $username, $password);
 53072 $storeAuth = $this->config->get('store-auths');
 53073 }
 53074 
 53075 return array('retry' => true, 'storeAuth' => $storeAuth);
 53076 }
 53077 
 53078 
 53079 
 53080 
 53081 
 53082 
 53083 
 53084 
 53085 public function addAuthenticationHeader(array $headers, $origin, $url)
 53086 {
 53087 if ($this->io->hasAuthentication($origin)) {
 53088 $authenticationDisplayMessage = null;
 53089 $auth = $this->io->getAuthentication($origin);
 53090 if ($auth['password'] === 'bearer') {
 53091 $headers[] = 'Authorization: Bearer '.$auth['username'];
 53092 } elseif ('github.com' === $origin && 'x-oauth-basic' === $auth['password']) {
 53093 
 53094 if (Preg::isMatch('{^https?://api\.github\.com/}', $url)) {
 53095 $headers[] = 'Authorization: token '.$auth['username'];
 53096 $authenticationDisplayMessage = 'Using GitHub token authentication';
 53097 }
 53098 } elseif (
 53099 in_array($origin, $this->config->get('gitlab-domains'), true)
 53100 && in_array($auth['password'], array('oauth2', 'private-token', 'gitlab-ci-token'), true)
 53101 ) {
 53102 if ($auth['password'] === 'oauth2') {
 53103 $headers[] = 'Authorization: Bearer '.$auth['username'];
 53104 $authenticationDisplayMessage = 'Using GitLab OAuth token authentication';
 53105 } else {
 53106 $headers[] = 'PRIVATE-TOKEN: '.$auth['username'];
 53107 $authenticationDisplayMessage = 'Using GitLab private token authentication';
 53108 }
 53109 } elseif (
 53110 'bitbucket.org' === $origin
 53111 && $url !== Bitbucket::OAUTH2_ACCESS_TOKEN_URL
 53112 && 'x-token-auth' === $auth['username']
 53113 ) {
 53114 if (!$this->isPublicBitBucketDownload($url)) {
 53115 $headers[] = 'Authorization: Bearer ' . $auth['password'];
 53116 $authenticationDisplayMessage = 'Using Bitbucket OAuth token authentication';
 53117 }
 53118 } else {
 53119 $authStr = base64_encode($auth['username'] . ':' . $auth['password']);
 53120 $headers[] = 'Authorization: Basic '.$authStr;
 53121 $authenticationDisplayMessage = 'Using HTTP basic authentication with username "' . $auth['username'] . '"';
 53122 }
 53123 
 53124 if ($authenticationDisplayMessage && (!isset($this->displayedOriginAuthentications[$origin]) || $this->displayedOriginAuthentications[$origin] !== $authenticationDisplayMessage)) {
 53125 $this->io->writeError($authenticationDisplayMessage, true, IOInterface::DEBUG);
 53126 $this->displayedOriginAuthentications[$origin] = $authenticationDisplayMessage;
 53127 }
 53128 } elseif (in_array($origin, array('api.bitbucket.org', 'api.github.com'), true)) {
 53129 return $this->addAuthenticationHeader($headers, str_replace('api.', '', $origin), $url);
 53130 }
 53131 
 53132 return $headers;
 53133 }
 53134 
 53135 
 53136 
 53137 
 53138 
 53139 
 53140 
 53141 
 53142 public function isPublicBitBucketDownload($urlToBitBucketFile)
 53143 {
 53144 $domain = parse_url($urlToBitBucketFile, PHP_URL_HOST);
 53145 if (strpos($domain, 'bitbucket.org') === false) {
 53146 
 53147 
 53148 return true;
 53149 }
 53150 
 53151 $path = parse_url($urlToBitBucketFile, PHP_URL_PATH);
 53152 
 53153 
 53154 
 53155 $pathParts = explode('/', $path);
 53156 
 53157 return count($pathParts) >= 4 && $pathParts[3] == 'downloads';
 53158 }
 53159 }
 53160 <?php
 53161 
 53162 
 53163 
 53164 
 53165 
 53166 
 53167 
 53168 
 53169 
 53170 
 53171 
 53172 namespace Composer\Util;
 53173 
 53174 use Composer\Factory;
 53175 use Composer\IO\IOInterface;
 53176 use Composer\Config;
 53177 use Composer\Downloader\TransportException;
 53178 
 53179 
 53180 
 53181 
 53182 class Bitbucket
 53183 {
 53184 
 53185 private $io;
 53186 
 53187 private $config;
 53188 
 53189 private $process;
 53190 
 53191 private $httpDownloader;
 53192 
 53193 private $token = null;
 53194 
 53195 private $time;
 53196 
 53197 const OAUTH2_ACCESS_TOKEN_URL = 'https://bitbucket.org/site/oauth2/access_token';
 53198 
 53199 
 53200 
 53201 
 53202 
 53203 
 53204 
 53205 
 53206 
 53207 
 53208 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null, $time = null)
 53209 {
 53210 $this->io = $io;
 53211 $this->config = $config;
 53212 $this->process = $process ?: new ProcessExecutor($io);
 53213 $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
 53214 $this->time = $time;
 53215 }
 53216 
 53217 
 53218 
 53219 
 53220 public function getToken()
 53221 {
 53222 if (!isset($this->token['access_token'])) {
 53223 return '';
 53224 }
 53225 
 53226 return $this->token['access_token'];
 53227 }
 53228 
 53229 
 53230 
 53231 
 53232 
 53233 
 53234 
 53235 public function authorizeOAuth($originUrl)
 53236 {
 53237 if ($originUrl !== 'bitbucket.org') {
 53238 return false;
 53239 }
 53240 
 53241 
 53242 if (0 === $this->process->execute('git config bitbucket.accesstoken', $output)) {
 53243 $this->io->setAuthentication($originUrl, 'x-token-auth', trim($output));
 53244 
 53245 return true;
 53246 }
 53247 
 53248 return false;
 53249 }
 53250 
 53251 
 53252 
 53253 
 53254 private function requestAccessToken()
 53255 {
 53256 try {
 53257 $response = $this->httpDownloader->get(self::OAUTH2_ACCESS_TOKEN_URL, array(
 53258 'retry-auth-failure' => false,
 53259 'http' => array(
 53260 'method' => 'POST',
 53261 'content' => 'grant_type=client_credentials',
 53262 ),
 53263 ));
 53264 
 53265 $token = $response->decodeJson();
 53266 if (!isset($token['expires_in']) || !isset($token['access_token'])) {
 53267 throw new \LogicException('Expected a token configured with expires_in and access_token present, got '.json_encode($token));
 53268 }
 53269 
 53270 $this->token = $token;
 53271 } catch (TransportException $e) {
 53272 if ($e->getCode() === 400) {
 53273 $this->io->writeError('<error>Invalid OAuth consumer provided.</error>');
 53274 $this->io->writeError('This can have two reasons:');
 53275 $this->io->writeError('1. You are authenticating with a bitbucket username/password combination');
 53276 $this->io->writeError('2. You are using an OAuth consumer, but didn\'t configure a (dummy) callback url');
 53277 
 53278 return false;
 53279 }
 53280 if (in_array($e->getCode(), array(403, 401))) {
 53281 $this->io->writeError('<error>Invalid OAuth consumer provided.</error>');
 53282 $this->io->writeError('You can also add it manually later by using "composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>"');
 53283 
 53284 return false;
 53285 }
 53286 
 53287 throw $e;
 53288 }
 53289 
 53290 return true;
 53291 }
 53292 
 53293 
 53294 
 53295 
 53296 
 53297 
 53298 
 53299 
 53300 
 53301 
 53302 public function authorizeOAuthInteractively($originUrl, $message = null)
 53303 {
 53304 if ($message) {
 53305 $this->io->writeError($message);
 53306 }
 53307 
 53308 $url = 'https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/';
 53309 $this->io->writeError(sprintf('Follow the instructions on %s', $url));
 53310 $this->io->writeError(sprintf('to create a consumer. It will be stored in "%s" for future use by Composer.', $this->config->getAuthConfigSource()->getName()));
 53311 $this->io->writeError('Ensure you enter a "Callback URL" (http://example.com is fine) or it will not be possible to create an Access Token (this callback url will not be used by composer)');
 53312 
 53313 $consumerKey = trim((string) $this->io->askAndHideAnswer('Consumer Key (hidden): '));
 53314 
 53315 if (!$consumerKey) {
 53316 $this->io->writeError('<warning>No consumer key given, aborting.</warning>');
 53317 $this->io->writeError('You can also add it manually later by using "composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>"');
 53318 
 53319 return false;
 53320 }
 53321 
 53322 $consumerSecret = trim((string) $this->io->askAndHideAnswer('Consumer Secret (hidden): '));
 53323 
 53324 if (!$consumerSecret) {
 53325 $this->io->writeError('<warning>No consumer secret given, aborting.</warning>');
 53326 $this->io->writeError('You can also add it manually later by using "composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>"');
 53327 
 53328 return false;
 53329 }
 53330 
 53331 $this->io->setAuthentication($originUrl, $consumerKey, $consumerSecret);
 53332 
 53333 if (!$this->requestAccessToken()) {
 53334 return false;
 53335 }
 53336 
 53337 
 53338 $this->storeInAuthConfig($originUrl, $consumerKey, $consumerSecret);
 53339 
 53340 
 53341 $this->config->getAuthConfigSource()->removeConfigSetting('http-basic.' . $originUrl);
 53342 
 53343 $this->io->writeError('<info>Consumer stored successfully.</info>');
 53344 
 53345 return true;
 53346 }
 53347 
 53348 
 53349 
 53350 
 53351 
 53352 
 53353 
 53354 
 53355 
 53356 public function requestToken($originUrl, $consumerKey, $consumerSecret)
 53357 {
 53358 if ($this->token !== null || $this->getTokenFromConfig($originUrl)) {
 53359 return $this->token['access_token'];
 53360 }
 53361 
 53362 $this->io->setAuthentication($originUrl, $consumerKey, $consumerSecret);
 53363 if (!$this->requestAccessToken()) {
 53364 return '';
 53365 }
 53366 
 53367 $this->storeInAuthConfig($originUrl, $consumerKey, $consumerSecret);
 53368 
 53369 if (!isset($this->token['access_token'])) {
 53370 throw new \LogicException('Failed to initialize token above');
 53371 }
 53372 
 53373 return $this->token['access_token'];
 53374 }
 53375 
 53376 
 53377 
 53378 
 53379 
 53380 
 53381 
 53382 
 53383 
 53384 
 53385 private function storeInAuthConfig($originUrl, $consumerKey, $consumerSecret)
 53386 {
 53387 $this->config->getConfigSource()->removeConfigSetting('bitbucket-oauth.'.$originUrl);
 53388 
 53389 if (null === $this->token || !isset($this->token['expires_in'])) {
 53390 throw new \LogicException('Expected a token configured with expires_in present, got '.json_encode($this->token));
 53391 }
 53392 
 53393 $time = null === $this->time ? time() : $this->time;
 53394 $consumer = array(
 53395 "consumer-key" => $consumerKey,
 53396 "consumer-secret" => $consumerSecret,
 53397 "access-token" => $this->token['access_token'],
 53398 "access-token-expiration" => $time + $this->token['expires_in'],
 53399 );
 53400 
 53401 $this->config->getAuthConfigSource()->addConfigSetting('bitbucket-oauth.'.$originUrl, $consumer);
 53402 }
 53403 
 53404 
 53405 
 53406 
 53407 
 53408 private function getTokenFromConfig($originUrl)
 53409 {
 53410 $authConfig = $this->config->get('bitbucket-oauth');
 53411 
 53412 if (
 53413 !isset($authConfig[$originUrl]['access-token'], $authConfig[$originUrl]['access-token-expiration'])
 53414 || time() > $authConfig[$originUrl]['access-token-expiration']
 53415 ) {
 53416 return false;
 53417 }
 53418 
 53419 $this->token = array(
 53420 'access_token' => $authConfig[$originUrl]['access-token'],
 53421 );
 53422 
 53423 return true;
 53424 }
 53425 }
 53426 <?php
 53427 
 53428 
 53429 
 53430 
 53431 
 53432 
 53433 
 53434 
 53435 
 53436 
 53437 
 53438 namespace Composer\Util;
 53439 
 53440 use Composer\Pcre\Preg;
 53441 
 53442 
 53443 
 53444 
 53445 
 53446 
 53447 class ComposerMirror
 53448 {
 53449 
 53450 
 53451 
 53452 
 53453 
 53454 
 53455 
 53456 
 53457 
 53458 
 53459 public static function processUrl($mirrorUrl, $packageName, $version, $reference, $type, $prettyVersion = null)
 53460 {
 53461 if ($reference) {
 53462 $reference = Preg::isMatch('{^([a-f0-9]*|%reference%)$}', $reference) ? $reference : md5($reference);
 53463 }
 53464 $version = strpos($version, '/') === false ? $version : md5($version);
 53465 
 53466 $from = array('%package%', '%version%', '%reference%', '%type%');
 53467 $to = array($packageName, $version, $reference, $type);
 53468 if (null !== $prettyVersion) {
 53469 $from[] = '%prettyVersion%';
 53470 $to[] = $prettyVersion;
 53471 }
 53472 
 53473 return str_replace($from, $to, $mirrorUrl);
 53474 }
 53475 
 53476 
 53477 
 53478 
 53479 
 53480 
 53481 
 53482 
 53483 
 53484 public static function processGitUrl($mirrorUrl, $packageName, $url, $type)
 53485 {
 53486 if (Preg::isMatch('#^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$#', $url, $match)) {
 53487 $url = 'gh-'.$match[1].'/'.$match[2];
 53488 } elseif (Preg::isMatch('#^https://bitbucket\.org/([^/]+)/(.+?)(?:\.git)?/?$#', $url, $match)) {
 53489 $url = 'bb-'.$match[1].'/'.$match[2];
 53490 } else {
 53491 $url = Preg::replace('{[^a-z0-9_.-]}i', '-', trim($url, '/'));
 53492 }
 53493 
 53494 return str_replace(
 53495 array('%package%', '%normalizedUrl%', '%type%'),
 53496 array($packageName, $url, $type),
 53497 $mirrorUrl
 53498 );
 53499 }
 53500 
 53501 
 53502 
 53503 
 53504 
 53505 
 53506 
 53507 
 53508 
 53509 public static function processHgUrl($mirrorUrl, $packageName, $url, $type)
 53510 {
 53511 return self::processGitUrl($mirrorUrl, $packageName, $url, $type);
 53512 }
 53513 }
 53514 <?php
 53515 
 53516 
 53517 
 53518 
 53519 
 53520 
 53521 
 53522 
 53523 
 53524 
 53525 
 53526 namespace Composer\Util;
 53527 
 53528 use Composer\Package\Loader\ArrayLoader;
 53529 use Composer\Package\Loader\ValidatingArrayLoader;
 53530 use Composer\Package\Loader\InvalidPackageException;
 53531 use Composer\Json\JsonValidationException;
 53532 use Composer\IO\IOInterface;
 53533 use Composer\Json\JsonFile;
 53534 use Composer\Pcre\Preg;
 53535 use Composer\Spdx\SpdxLicenses;
 53536 
 53537 
 53538 
 53539 
 53540 
 53541 
 53542 
 53543 class ConfigValidator
 53544 {
 53545 const CHECK_VERSION = 1;
 53546 
 53547 
 53548 private $io;
 53549 
 53550 public function __construct(IOInterface $io)
 53551 {
 53552 $this->io = $io;
 53553 }
 53554 
 53555 
 53556 
 53557 
 53558 
 53559 
 53560 
 53561 
 53562 
 53563 
 53564 public function validate($file, $arrayLoaderValidationFlags = ValidatingArrayLoader::CHECK_ALL, $flags = self::CHECK_VERSION)
 53565 {
 53566 $errors = array();
 53567 $publishErrors = array();
 53568 $warnings = array();
 53569 
 53570 
 53571 $laxValid = false;
 53572 try {
 53573 $json = new JsonFile($file, null, $this->io);
 53574 $manifest = $json->read();
 53575 
 53576 $json->validateSchema(JsonFile::LAX_SCHEMA);
 53577 $laxValid = true;
 53578 $json->validateSchema();
 53579 } catch (JsonValidationException $e) {
 53580 foreach ($e->getErrors() as $message) {
 53581 if ($laxValid) {
 53582 $publishErrors[] = $message;
 53583 } else {
 53584 $errors[] = $message;
 53585 }
 53586 }
 53587 } catch (\Exception $e) {
 53588 $errors[] = $e->getMessage();
 53589 
 53590 return array($errors, $publishErrors, $warnings);
 53591 }
 53592 
 53593 
 53594 if (empty($manifest['license'])) {
 53595 $warnings[] = 'No license specified, it is recommended to do so. For closed-source software you may use "proprietary" as license.';
 53596 } else {
 53597 $licenses = (array) $manifest['license'];
 53598 
 53599 
 53600 foreach ($licenses as $key => $license) {
 53601 if ('proprietary' === $license) {
 53602 unset($licenses[$key]);
 53603 }
 53604 }
 53605 
 53606 $licenseValidator = new SpdxLicenses();
 53607 foreach ($licenses as $license) {
 53608 $spdxLicense = $licenseValidator->getLicenseByIdentifier($license);
 53609 if ($spdxLicense && $spdxLicense[3]) {
 53610 if (Preg::isMatch('{^[AL]?GPL-[123](\.[01])?\+$}i', $license)) {
 53611 $warnings[] = sprintf(
 53612 'License "%s" is a deprecated SPDX license identifier, use "'.str_replace('+', '', $license).'-or-later" instead',
 53613 $license
 53614 );
 53615 } elseif (Preg::isMatch('{^[AL]?GPL-[123](\.[01])?$}i', $license)) {
 53616 $warnings[] = sprintf(
 53617 'License "%s" is a deprecated SPDX license identifier, use "'.$license.'-only" or "'.$license.'-or-later" instead',
 53618 $license
 53619 );
 53620 } else {
 53621 $warnings[] = sprintf(
 53622 'License "%s" is a deprecated SPDX license identifier, see https://spdx.org/licenses/',
 53623 $license
 53624 );
 53625 }
 53626 }
 53627 }
 53628 }
 53629 
 53630 if (($flags & self::CHECK_VERSION) && isset($manifest['version'])) {
 53631 $warnings[] = 'The version field is present, it is recommended to leave it out if the package is published on Packagist.';
 53632 }
 53633 
 53634 if (!empty($manifest['name']) && Preg::isMatch('{[A-Z]}', $manifest['name'])) {
 53635 $suggestName = Preg::replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $manifest['name']);
 53636 $suggestName = strtolower($suggestName);
 53637 
 53638 $publishErrors[] = sprintf(
 53639 'Name "%s" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using "%s" instead. As such you will not be able to submit it to Packagist.',
 53640 $manifest['name'],
 53641 $suggestName
 53642 );
 53643 }
 53644 
 53645 if (!empty($manifest['type']) && $manifest['type'] == 'composer-installer') {
 53646 $warnings[] = "The package type 'composer-installer' is deprecated. Please distribute your custom installers as plugins from now on. See https://getcomposer.org/doc/articles/plugins.md for plugin documentation.";
 53647 }
 53648 
 53649 
 53650 if (isset($manifest['require'], $manifest['require-dev'])) {
 53651 $requireOverrides = array_intersect_key($manifest['require'], $manifest['require-dev']);
 53652 
 53653 if (!empty($requireOverrides)) {
 53654 $plural = (count($requireOverrides) > 1) ? 'are' : 'is';
 53655 $warnings[] = implode(', ', array_keys($requireOverrides)). " {$plural} required both in require and require-dev, this can lead to unexpected behavior";
 53656 }
 53657 }
 53658 
 53659 
 53660 foreach (array('provide', 'replace') as $linkType) {
 53661 if (isset($manifest[$linkType])) {
 53662 foreach (array('require', 'require-dev') as $requireType) {
 53663 if (isset($manifest[$requireType])) {
 53664 foreach ($manifest[$linkType] as $provide => $constraint) {
 53665 if (isset($manifest[$requireType][$provide])) {
 53666 $warnings[] = 'The package ' . $provide . ' in '.$requireType.' is also listed in '.$linkType.' which satisfies the requirement. Remove it from '.$linkType.' if you wish to install it.';
 53667 }
 53668 }
 53669 }
 53670 }
 53671 }
 53672 }
 53673 
 53674 
 53675 $require = isset($manifest['require']) ? $manifest['require'] : array();
 53676 $requireDev = isset($manifest['require-dev']) ? $manifest['require-dev'] : array();
 53677 $packages = array_merge($require, $requireDev);
 53678 foreach ($packages as $package => $version) {
 53679 if (Preg::isMatch('/#/', $version)) {
 53680 $warnings[] = sprintf(
 53681 'The package "%s" is pointing to a commit-ref, this is bad practice and can cause unforeseen issues.',
 53682 $package
 53683 );
 53684 }
 53685 }
 53686 
 53687 
 53688 $scriptsDescriptions = isset($manifest['scripts-descriptions']) ? $manifest['scripts-descriptions'] : array();
 53689 $scripts = isset($manifest['scripts']) ? $manifest['scripts'] : array();
 53690 foreach ($scriptsDescriptions as $scriptName => $scriptDescription) {
 53691 if (!array_key_exists($scriptName, $scripts)) {
 53692 $warnings[] = sprintf(
 53693 'Description for non-existent script "%s" found in "scripts-descriptions"',
 53694 $scriptName
 53695 );
 53696 }
 53697 }
 53698 
 53699 
 53700 if (isset($manifest['autoload']['psr-0'][''])) {
 53701 $warnings[] = "Defining autoload.psr-0 with an empty namespace prefix is a bad idea for performance";
 53702 }
 53703 if (isset($manifest['autoload']['psr-4'][''])) {
 53704 $warnings[] = "Defining autoload.psr-4 with an empty namespace prefix is a bad idea for performance";
 53705 }
 53706 
 53707 $loader = new ValidatingArrayLoader(new ArrayLoader(), true, null, $arrayLoaderValidationFlags);
 53708 try {
 53709 if (!isset($manifest['version'])) {
 53710 $manifest['version'] = '1.0.0';
 53711 }
 53712 if (!isset($manifest['name'])) {
 53713 $manifest['name'] = 'dummy/dummy';
 53714 }
 53715 $loader->load($manifest);
 53716 } catch (InvalidPackageException $e) {
 53717 $errors = array_merge($errors, $e->getErrors());
 53718 }
 53719 
 53720 $warnings = array_merge($warnings, $loader->getWarnings());
 53721 
 53722 return array($errors, $publishErrors, $warnings);
 53723 }
 53724 }
 53725 <?php
 53726 
 53727 
 53728 
 53729 
 53730 
 53731 
 53732 
 53733 
 53734 
 53735 
 53736 
 53737 namespace Composer\Util;
 53738 
 53739 use Composer\IO\IOInterface;
 53740 use Composer\Pcre\Preg;
 53741 
 53742 
 53743 
 53744 
 53745 
 53746 
 53747 class ErrorHandler
 53748 {
 53749 
 53750 private static $io;
 53751 
 53752 
 53753 
 53754 
 53755 
 53756 
 53757 
 53758 
 53759 
 53760 
 53761 
 53762 
 53763 
 53764 public static function handle($level, $message, $file, $line)
 53765 {
 53766 
 53767 if (!(error_reporting() & $level)) {
 53768 return true;
 53769 }
 53770 
 53771 if (filter_var(ini_get('xdebug.scream'), FILTER_VALIDATE_BOOLEAN)) {
 53772 $message .= "\n\nWarning: You have xdebug.scream enabled, the warning above may be".
 53773 "\na legitimately suppressed error that you were not supposed to see.";
 53774 }
 53775 
 53776 if ($level !== E_DEPRECATED && $level !== E_USER_DEPRECATED) {
 53777 throw new \ErrorException($message, 0, $level, $file, $line);
 53778 }
 53779 
 53780 if (self::$io) {
 53781 
 53782 
 53783 if (Preg::isMatch('{^Return type of Symfony\\\\.*ReturnTypeWillChange}is', $message)) {
 53784 return true;
 53785 }
 53786 if (strpos(strtr($file, '\\', '/'), 'vendor/symfony/') !== false) {
 53787 return true;
 53788 }
 53789 
 53790 self::$io->writeError('<warning>Deprecation Notice: '.$message.' in '.$file.':'.$line.'</warning>');
 53791 if (self::$io->isVerbose()) {
 53792 self::$io->writeError('<warning>Stack trace:</warning>');
 53793 self::$io->writeError(array_filter(array_map(function ($a) {
 53794 if (isset($a['line'], $a['file'])) {
 53795 return '<warning> '.$a['file'].':'.$a['line'].'</warning>';
 53796 }
 53797 
 53798 return null;
 53799 }, array_slice(debug_backtrace(), 2))));
 53800 }
 53801 }
 53802 
 53803 return true;
 53804 }
 53805 
 53806 
 53807 
 53808 
 53809 
 53810 
 53811 
 53812 
 53813 public static function register(IOInterface $io = null)
 53814 {
 53815 set_error_handler(array(__CLASS__, 'handle'));
 53816 error_reporting(E_ALL | E_STRICT);
 53817 self::$io = $io;
 53818 }
 53819 }
 53820 <?php
 53821 
 53822 
 53823 
 53824 
 53825 
 53826 
 53827 
 53828 
 53829 
 53830 
 53831 
 53832 namespace Composer\Util;
 53833 
 53834 use Composer\Pcre\Preg;
 53835 use React\Promise\PromiseInterface;
 53836 use RecursiveDirectoryIterator;
 53837 use RecursiveIteratorIterator;
 53838 use Symfony\Component\Filesystem\Exception\IOException;
 53839 use Symfony\Component\Finder\Finder;
 53840 
 53841 
 53842 
 53843 
 53844 
 53845 class Filesystem
 53846 {
 53847 
 53848 private $processExecutor;
 53849 
 53850 public function __construct(ProcessExecutor $executor = null)
 53851 {
 53852 $this->processExecutor = $executor;
 53853 }
 53854 
 53855 
 53856 
 53857 
 53858 
 53859 
 53860 public function remove($file)
 53861 {
 53862 if (is_dir($file)) {
 53863 return $this->removeDirectory($file);
 53864 }
 53865 
 53866 if (file_exists($file)) {
 53867 return $this->unlink($file);
 53868 }
 53869 
 53870 return false;
 53871 }
 53872 
 53873 
 53874 
 53875 
 53876 
 53877 
 53878 
 53879 public function isDirEmpty($dir)
 53880 {
 53881 $finder = Finder::create()
 53882 ->ignoreVCS(false)
 53883 ->ignoreDotFiles(false)
 53884 ->depth(0)
 53885 ->in($dir);
 53886 
 53887 return \count($finder) === 0;
 53888 }
 53889 
 53890 
 53891 
 53892 
 53893 
 53894 
 53895 
 53896 public function emptyDirectory($dir, $ensureDirectoryExists = true)
 53897 {
 53898 if (is_link($dir) && file_exists($dir)) {
 53899 $this->unlink($dir);
 53900 }
 53901 
 53902 if ($ensureDirectoryExists) {
 53903 $this->ensureDirectoryExists($dir);
 53904 }
 53905 
 53906 if (is_dir($dir)) {
 53907 $finder = Finder::create()
 53908 ->ignoreVCS(false)
 53909 ->ignoreDotFiles(false)
 53910 ->depth(0)
 53911 ->in($dir);
 53912 
 53913 foreach ($finder as $path) {
 53914 $this->remove((string) $path);
 53915 }
 53916 }
 53917 }
 53918 
 53919 
 53920 
 53921 
 53922 
 53923 
 53924 
 53925 
 53926 
 53927 
 53928 
 53929 public function removeDirectory($directory)
 53930 {
 53931 $edgeCaseResult = $this->removeEdgeCases($directory);
 53932 if ($edgeCaseResult !== null) {
 53933 return $edgeCaseResult;
 53934 }
 53935 
 53936 if (Platform::isWindows()) {
 53937 $cmd = sprintf('rmdir /S /Q %s', ProcessExecutor::escape(realpath($directory)));
 53938 } else {
 53939 $cmd = sprintf('rm -rf %s', ProcessExecutor::escape($directory));
 53940 }
 53941 
 53942 $result = $this->getProcess()->execute($cmd, $output) === 0;
 53943 
 53944 
 53945 clearstatcache();
 53946 
 53947 if ($result && !is_dir($directory)) {
 53948 return true;
 53949 }
 53950 
 53951 return $this->removeDirectoryPhp($directory);
 53952 }
 53953 
 53954 
 53955 
 53956 
 53957 
 53958 
 53959 
 53960 
 53961 
 53962 
 53963 
 53964 public function removeDirectoryAsync($directory)
 53965 {
 53966 $edgeCaseResult = $this->removeEdgeCases($directory);
 53967 if ($edgeCaseResult !== null) {
 53968 return \React\Promise\resolve($edgeCaseResult);
 53969 }
 53970 
 53971 if (Platform::isWindows()) {
 53972 $cmd = sprintf('rmdir /S /Q %s', ProcessExecutor::escape(realpath($directory)));
 53973 } else {
 53974 $cmd = sprintf('rm -rf %s', ProcessExecutor::escape($directory));
 53975 }
 53976 
 53977 $promise = $this->getProcess()->executeAsync($cmd);
 53978 
 53979 $self = $this;
 53980 
 53981 return $promise->then(function ($process) use ($directory, $self) {
 53982 
 53983 clearstatcache();
 53984 
 53985 if ($process->isSuccessful()) {
 53986 if (!is_dir($directory)) {
 53987 return \React\Promise\resolve(true);
 53988 }
 53989 }
 53990 
 53991 return \React\Promise\resolve($self->removeDirectoryPhp($directory));
 53992 });
 53993 }
 53994 
 53995 
 53996 
 53997 
 53998 
 53999 
 54000 
 54001 private function removeEdgeCases($directory, $fallbackToPhp = true)
 54002 {
 54003 if ($this->isSymlinkedDirectory($directory)) {
 54004 return $this->unlinkSymlinkedDirectory($directory);
 54005 }
 54006 
 54007 if ($this->isJunction($directory)) {
 54008 return $this->removeJunction($directory);
 54009 }
 54010 
 54011 if (is_link($directory)) {
 54012 return unlink($directory);
 54013 }
 54014 
 54015 if (!is_dir($directory) || !file_exists($directory)) {
 54016 return true;
 54017 }
 54018 
 54019 if (Preg::isMatch('{^(?:[a-z]:)?[/\\\\]+$}i', $directory)) {
 54020 throw new \RuntimeException('Aborting an attempted deletion of '.$directory.', this was probably not intended, if it is a real use case please report it.');
 54021 }
 54022 
 54023 if (!\function_exists('proc_open') && $fallbackToPhp) {
 54024 return $this->removeDirectoryPhp($directory);
 54025 }
 54026 
 54027 return null;
 54028 }
 54029 
 54030 
 54031 
 54032 
 54033 
 54034 
 54035 
 54036 
 54037 
 54038 
 54039 
 54040 public function removeDirectoryPhp($directory)
 54041 {
 54042 $edgeCaseResult = $this->removeEdgeCases($directory, false);
 54043 if ($edgeCaseResult !== null) {
 54044 return $edgeCaseResult;
 54045 }
 54046 
 54047 try {
 54048 $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
 54049 } catch (\UnexpectedValueException $e) {
 54050 
 54051 
 54052 clearstatcache();
 54053 usleep(100000);
 54054 if (!is_dir($directory)) {
 54055 return true;
 54056 }
 54057 $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
 54058 }
 54059 $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
 54060 
 54061 foreach ($ri as $file) {
 54062 if ($file->isDir()) {
 54063 $this->rmdir($file->getPathname());
 54064 } else {
 54065 $this->unlink($file->getPathname());
 54066 }
 54067 }
 54068 
 54069 
 54070 unset($ri, $it, $file);
 54071 
 54072 return $this->rmdir($directory);
 54073 }
 54074 
 54075 
 54076 
 54077 
 54078 
 54079 
 54080 public function ensureDirectoryExists($directory)
 54081 {
 54082 if (!is_dir($directory)) {
 54083 if (file_exists($directory)) {
 54084 throw new \RuntimeException(
 54085 $directory.' exists and is not a directory.'
 54086 );
 54087 }
 54088 if (!@mkdir($directory, 0777, true)) {
 54089 throw new \RuntimeException(
 54090 $directory.' does not exist and could not be created.'
 54091 );
 54092 }
 54093 }
 54094 }
 54095 
 54096 
 54097 
 54098 
 54099 
 54100 
 54101 
 54102 
 54103 public function unlink($path)
 54104 {
 54105 $unlinked = @$this->unlinkImplementation($path);
 54106 if (!$unlinked) {
 54107 
 54108 if (Platform::isWindows()) {
 54109 usleep(350000);
 54110 $unlinked = @$this->unlinkImplementation($path);
 54111 }
 54112 
 54113 if (!$unlinked) {
 54114 $error = error_get_last();
 54115 $message = 'Could not delete '.$path.': ' . @$error['message'];
 54116 if (Platform::isWindows()) {
 54117 $message .= "\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed";
 54118 }
 54119 
 54120 throw new \RuntimeException($message);
 54121 }
 54122 }
 54123 
 54124 return true;
 54125 }
 54126 
 54127 
 54128 
 54129 
 54130 
 54131 
 54132 
 54133 
 54134 public function rmdir($path)
 54135 {
 54136 $deleted = @rmdir($path);
 54137 if (!$deleted) {
 54138 
 54139 if (Platform::isWindows()) {
 54140 usleep(350000);
 54141 $deleted = @rmdir($path);
 54142 }
 54143 
 54144 if (!$deleted) {
 54145 $error = error_get_last();
 54146 $message = 'Could not delete '.$path.': ' . @$error['message'];
 54147 if (Platform::isWindows()) {
 54148 $message .= "\nThis can be due to an antivirus or the Windows Search Indexer locking the file while they are analyzed";
 54149 }
 54150 
 54151 throw new \RuntimeException($message);
 54152 }
 54153 }
 54154 
 54155 return true;
 54156 }
 54157 
 54158 
 54159 
 54160 
 54161 
 54162 
 54163 
 54164 
 54165 
 54166 
 54167 
 54168 
 54169 public function copyThenRemove($source, $target)
 54170 {
 54171 $this->copy($source, $target);
 54172 if (!is_dir($source)) {
 54173 $this->unlink($source);
 54174 
 54175 return;
 54176 }
 54177 
 54178 $this->removeDirectoryPhp($source);
 54179 }
 54180 
 54181 
 54182 
 54183 
 54184 
 54185 
 54186 
 54187 
 54188 public function copy($source, $target)
 54189 {
 54190 if (!is_dir($source)) {
 54191 return copy($source, $target);
 54192 }
 54193 
 54194 $it = new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS);
 54195 $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::SELF_FIRST);
 54196 $this->ensureDirectoryExists($target);
 54197 
 54198 $result = true;
 54199 
 54200 foreach ($ri as $file) {
 54201 $targetPath = $target . DIRECTORY_SEPARATOR . $ri->getSubPathname();
 54202 if ($file->isDir()) {
 54203 $this->ensureDirectoryExists($targetPath);
 54204 } else {
 54205 $result = $result && copy($file->getPathname(), $targetPath);
 54206 }
 54207 }
 54208 
 54209 return $result;
 54210 }
 54211 
 54212 
 54213 
 54214 
 54215 
 54216 
 54217 
 54218 public function rename($source, $target)
 54219 {
 54220 if (true === @rename($source, $target)) {
 54221 return;
 54222 }
 54223 
 54224 if (!\function_exists('proc_open')) {
 54225 $this->copyThenRemove($source, $target);
 54226 
 54227 return;
 54228 }
 54229 
 54230 if (Platform::isWindows()) {
 54231 
 54232 $command = sprintf('xcopy %s %s /E /I /Q /Y', ProcessExecutor::escape($source), ProcessExecutor::escape($target));
 54233 $result = $this->getProcess()->execute($command, $output);
 54234 
 54235 
 54236 clearstatcache();
 54237 
 54238 if (0 === $result) {
 54239 $this->remove($source);
 54240 
 54241 return;
 54242 }
 54243 } else {
 54244 
 54245 
 54246 $command = sprintf('mv %s %s', ProcessExecutor::escape($source), ProcessExecutor::escape($target));
 54247 $result = $this->getProcess()->execute($command, $output);
 54248 
 54249 
 54250 clearstatcache();
 54251 
 54252 if (0 === $result) {
 54253 return;
 54254 }
 54255 }
 54256 
 54257 $this->copyThenRemove($source, $target);
 54258 }
 54259 
 54260 
 54261 
 54262 
 54263 
 54264 
 54265 
 54266 
 54267 
 54268 
 54269 public function findShortestPath($from, $to, $directories = false)
 54270 {
 54271 if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) {
 54272 throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
 54273 }
 54274 
 54275 $from = lcfirst($this->normalizePath($from));
 54276 $to = lcfirst($this->normalizePath($to));
 54277 
 54278 if ($directories) {
 54279 $from = rtrim($from, '/') . '/dummy_file';
 54280 }
 54281 
 54282 if (\dirname($from) === \dirname($to)) {
 54283 return './'.basename($to);
 54284 }
 54285 
 54286 $commonPath = $to;
 54287 while (strpos($from.'/', $commonPath.'/') !== 0 && '/' !== $commonPath && !Preg::isMatch('{^[a-z]:/?$}i', $commonPath)) {
 54288 $commonPath = strtr(\dirname($commonPath), '\\', '/');
 54289 }
 54290 
 54291 if (0 !== strpos($from, $commonPath) || '/' === $commonPath) {
 54292 return $to;
 54293 }
 54294 
 54295 $commonPath = rtrim($commonPath, '/') . '/';
 54296 $sourcePathDepth = substr_count(substr($from, \strlen($commonPath)), '/');
 54297 $commonPathCode = str_repeat('../', $sourcePathDepth);
 54298 
 54299 return ($commonPathCode . substr($to, \strlen($commonPath))) ?: './';
 54300 }
 54301 
 54302 
 54303 
 54304 
 54305 
 54306 
 54307 
 54308 
 54309 
 54310 
 54311 
 54312 public function findShortestPathCode($from, $to, $directories = false, $staticCode = false)
 54313 {
 54314 if (!$this->isAbsolutePath($from) || !$this->isAbsolutePath($to)) {
 54315 throw new \InvalidArgumentException(sprintf('$from (%s) and $to (%s) must be absolute paths.', $from, $to));
 54316 }
 54317 
 54318 $from = lcfirst($this->normalizePath($from));
 54319 $to = lcfirst($this->normalizePath($to));
 54320 
 54321 if ($from === $to) {
 54322 return $directories ? '__DIR__' : '__FILE__';
 54323 }
 54324 
 54325 $commonPath = $to;
 54326 while (strpos($from.'/', $commonPath.'/') !== 0 && '/' !== $commonPath && !Preg::isMatch('{^[a-z]:/?$}i', $commonPath) && '.' !== $commonPath) {
 54327 $commonPath = strtr(\dirname($commonPath), '\\', '/');
 54328 }
 54329 
 54330 if (0 !== strpos($from, $commonPath) || '/' === $commonPath || '.' === $commonPath) {
 54331 return var_export($to, true);
 54332 }
 54333 
 54334 $commonPath = rtrim($commonPath, '/') . '/';
 54335 if (strpos($to, $from.'/') === 0) {
 54336 return '__DIR__ . '.var_export(substr($to, \strlen($from)), true);
 54337 }
 54338 $sourcePathDepth = substr_count(substr($from, \strlen($commonPath)), '/') + $directories;
 54339 if ($staticCode) {
 54340 $commonPathCode = "__DIR__ . '".str_repeat('/..', $sourcePathDepth)."'";
 54341 } else {
 54342 $commonPathCode = str_repeat('dirname(', $sourcePathDepth).'__DIR__'.str_repeat(')', $sourcePathDepth);
 54343 }
 54344 $relTarget = substr($to, \strlen($commonPath));
 54345 
 54346 return $commonPathCode . (\strlen($relTarget) ? '.' . var_export('/' . $relTarget, true) : '');
 54347 }
 54348 
 54349 
 54350 
 54351 
 54352 
 54353 
 54354 
 54355 public function isAbsolutePath($path)
 54356 {
 54357 return strpos($path, '/') === 0 || substr($path, 1, 1) === ':' || strpos($path, '\\\\') === 0;
 54358 }
 54359 
 54360 
 54361 
 54362 
 54363 
 54364 
 54365 
 54366 
 54367 
 54368 public function size($path)
 54369 {
 54370 if (!file_exists($path)) {
 54371 throw new \RuntimeException("$path does not exist.");
 54372 }
 54373 if (is_dir($path)) {
 54374 return $this->directorySize($path);
 54375 }
 54376 
 54377 return filesize($path);
 54378 }
 54379 
 54380 
 54381 
 54382 
 54383 
 54384 
 54385 
 54386 
 54387 public function normalizePath($path)
 54388 {
 54389 $parts = array();
 54390 $path = strtr($path, '\\', '/');
 54391 $prefix = '';
 54392 $absolute = '';
 54393 
 54394 
 54395 if (strpos($path, '//') === 0 && \strlen($path) > 2) {
 54396 $absolute = '//';
 54397 $path = substr($path, 2);
 54398 }
 54399 
 54400 
 54401 if (Preg::isMatch('{^( [0-9a-z]{2,}+: (?: // (?: [a-z]: )? )? | [a-z]: )}ix', $path, $match)) {
 54402 $prefix = $match[1];
 54403 $path = substr($path, \strlen($prefix));
 54404 }
 54405 
 54406 if (strpos($path, '/') === 0) {
 54407 $absolute = '/';
 54408 $path = substr($path, 1);
 54409 }
 54410 
 54411 $up = false;
 54412 foreach (explode('/', $path) as $chunk) {
 54413 if ('..' === $chunk && ($absolute !== '' || $up)) {
 54414 array_pop($parts);
 54415 $up = !(empty($parts) || '..' === end($parts));
 54416 } elseif ('.' !== $chunk && '' !== $chunk) {
 54417 $parts[] = $chunk;
 54418 $up = '..' !== $chunk;
 54419 }
 54420 }
 54421 
 54422 return $prefix.((string) $absolute).implode('/', $parts);
 54423 }
 54424 
 54425 
 54426 
 54427 
 54428 
 54429 
 54430 
 54431 
 54432 
 54433 public static function trimTrailingSlash($path)
 54434 {
 54435 if (!Preg::isMatch('{^[/\\\\]+$}', $path)) {
 54436 $path = rtrim($path, '/\\');
 54437 }
 54438 
 54439 return $path;
 54440 }
 54441 
 54442 
 54443 
 54444 
 54445 
 54446 
 54447 
 54448 public static function isLocalPath($path)
 54449 {
 54450 return Preg::isMatch('{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path);
 54451 }
 54452 
 54453 
 54454 
 54455 
 54456 
 54457 
 54458 public static function getPlatformPath($path)
 54459 {
 54460 if (Platform::isWindows()) {
 54461 $path = Preg::replace('{^(?:file:///([a-z]):?/)}i', 'file://$1:/', $path);
 54462 }
 54463 
 54464 return (string) Preg::replace('{^file://}i', '', $path);
 54465 }
 54466 
 54467 
 54468 
 54469 
 54470 
 54471 
 54472 
 54473 
 54474 
 54475 
 54476 public static function isReadable($path)
 54477 {
 54478 if (is_readable($path)) {
 54479 return true;
 54480 }
 54481 
 54482 if (is_file($path)) {
 54483 return false !== Silencer::call('file_get_contents', $path, false, null, 0, 1);
 54484 }
 54485 
 54486 if (is_dir($path)) {
 54487 return false !== Silencer::call('opendir', $path);
 54488 }
 54489 
 54490 
 54491 return false;
 54492 }
 54493 
 54494 
 54495 
 54496 
 54497 
 54498 
 54499 protected function directorySize($directory)
 54500 {
 54501 $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
 54502 $ri = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
 54503 
 54504 $size = 0;
 54505 foreach ($ri as $file) {
 54506 if ($file->isFile()) {
 54507 $size += $file->getSize();
 54508 }
 54509 }
 54510 
 54511 return $size;
 54512 }
 54513 
 54514 
 54515 
 54516 
 54517 protected function getProcess()
 54518 {
 54519 if (!$this->processExecutor) {
 54520 $this->processExecutor = new ProcessExecutor();
 54521 }
 54522 
 54523 return $this->processExecutor;
 54524 }
 54525 
 54526 
 54527 
 54528 
 54529 
 54530 
 54531 
 54532 
 54533 
 54534 
 54535 private function unlinkImplementation($path)
 54536 {
 54537 if (Platform::isWindows() && is_dir($path) && is_link($path)) {
 54538 return rmdir($path);
 54539 }
 54540 
 54541 return unlink($path);
 54542 }
 54543 
 54544 
 54545 
 54546 
 54547 
 54548 
 54549 
 54550 
 54551 public function relativeSymlink($target, $link)
 54552 {
 54553 if (!function_exists('symlink')) {
 54554 return false;
 54555 }
 54556 
 54557 $cwd = getcwd();
 54558 
 54559 $relativePath = $this->findShortestPath($link, $target);
 54560 chdir(\dirname($link));
 54561 $result = @symlink($relativePath, $link);
 54562 
 54563 chdir($cwd);
 54564 
 54565 return $result;
 54566 }
 54567 
 54568 
 54569 
 54570 
 54571 
 54572 
 54573 
 54574 
 54575 public function isSymlinkedDirectory($directory)
 54576 {
 54577 if (!is_dir($directory)) {
 54578 return false;
 54579 }
 54580 
 54581 $resolved = $this->resolveSymlinkedDirectorySymlink($directory);
 54582 
 54583 return is_link($resolved);
 54584 }
 54585 
 54586 
 54587 
 54588 
 54589 
 54590 
 54591 private function unlinkSymlinkedDirectory($directory)
 54592 {
 54593 $resolved = $this->resolveSymlinkedDirectorySymlink($directory);
 54594 
 54595 return $this->unlink($resolved);
 54596 }
 54597 
 54598 
 54599 
 54600 
 54601 
 54602 
 54603 
 54604 
 54605 private function resolveSymlinkedDirectorySymlink($pathname)
 54606 {
 54607 if (!is_dir($pathname)) {
 54608 return $pathname;
 54609 }
 54610 
 54611 $resolved = rtrim($pathname, '/');
 54612 
 54613 if (!\strlen($resolved)) {
 54614 return $pathname;
 54615 }
 54616 
 54617 return $resolved;
 54618 }
 54619 
 54620 
 54621 
 54622 
 54623 
 54624 
 54625 
 54626 
 54627 
 54628 public function junction($target, $junction)
 54629 {
 54630 if (!Platform::isWindows()) {
 54631 throw new \LogicException(sprintf('Function %s is not available on non-Windows platform', __CLASS__));
 54632 }
 54633 if (!is_dir($target)) {
 54634 throw new IOException(sprintf('Cannot junction to "%s" as it is not a directory.', $target), 0, null, $target);
 54635 }
 54636 $cmd = sprintf(
 54637 'mklink /J %s %s',
 54638 ProcessExecutor::escape(str_replace('/', DIRECTORY_SEPARATOR, $junction)),
 54639 ProcessExecutor::escape(realpath($target))
 54640 );
 54641 if ($this->getProcess()->execute($cmd, $output) !== 0) {
 54642 throw new IOException(sprintf('Failed to create junction to "%s" at "%s".', $target, $junction), 0, null, $target);
 54643 }
 54644 clearstatcache(true, $junction);
 54645 }
 54646 
 54647 
 54648 
 54649 
 54650 
 54651 
 54652 
 54653 
 54654 
 54655 
 54656 
 54657 
 54658 
 54659 
 54660 
 54661 
 54662 
 54663 
 54664 
 54665 
 54666 
 54667 public function isJunction($junction)
 54668 {
 54669 if (!Platform::isWindows()) {
 54670 return false;
 54671 }
 54672 
 54673 
 54674 clearstatcache(true, $junction);
 54675 
 54676 if (!is_dir($junction) || is_link($junction)) {
 54677 return false;
 54678 }
 54679 
 54680 $stat = lstat($junction);
 54681 
 54682 
 54683 return $stat ? 0x4000 !== ($stat['mode'] & 0xF000) : false;
 54684 }
 54685 
 54686 
 54687 
 54688 
 54689 
 54690 
 54691 
 54692 public function removeJunction($junction)
 54693 {
 54694 if (!Platform::isWindows()) {
 54695 return false;
 54696 }
 54697 $junction = rtrim(str_replace('/', DIRECTORY_SEPARATOR, $junction), DIRECTORY_SEPARATOR);
 54698 if (!$this->isJunction($junction)) {
 54699 throw new IOException(sprintf('%s is not a junction and thus cannot be removed as one', $junction));
 54700 }
 54701 
 54702 return $this->rmdir($junction);
 54703 }
 54704 
 54705 
 54706 
 54707 
 54708 
 54709 
 54710 
 54711 public function filePutContentsIfModified($path, $content)
 54712 {
 54713 $currentContent = @file_get_contents($path);
 54714 if (!$currentContent || ($currentContent != $content)) {
 54715 return file_put_contents($path, $content);
 54716 }
 54717 
 54718 return 0;
 54719 }
 54720 
 54721 
 54722 
 54723 
 54724 
 54725 
 54726 
 54727 
 54728 
 54729 public function safeCopy($source, $target)
 54730 {
 54731 if (!file_exists($target) || !file_exists($source) || !$this->filesAreEqual($source, $target)) {
 54732 $source = fopen($source, 'r');
 54733 $target = fopen($target, 'w+');
 54734 
 54735 stream_copy_to_stream($source, $target);
 54736 fclose($source);
 54737 fclose($target);
 54738 }
 54739 }
 54740 
 54741 
 54742 
 54743 
 54744 
 54745 
 54746 
 54747 
 54748 
 54749 
 54750 private function filesAreEqual($a, $b)
 54751 {
 54752 
 54753 if (filesize($a) !== filesize($b)) {
 54754 return false;
 54755 }
 54756 
 54757 
 54758 $ah = fopen($a, 'rb');
 54759 $bh = fopen($b, 'rb');
 54760 
 54761 $result = true;
 54762 while (!feof($ah)) {
 54763 if (fread($ah, 8192) != fread($bh, 8192)) {
 54764 $result = false;
 54765 break;
 54766 }
 54767 }
 54768 
 54769 fclose($ah);
 54770 fclose($bh);
 54771 
 54772 return $result;
 54773 }
 54774 }
 54775 <?php
 54776 
 54777 
 54778 
 54779 
 54780 
 54781 
 54782 
 54783 
 54784 
 54785 
 54786 
 54787 namespace Composer\Util;
 54788 
 54789 use Composer\Config;
 54790 use Composer\IO\IOInterface;
 54791 use Composer\Pcre\Preg;
 54792 
 54793 
 54794 
 54795 
 54796 class Git
 54797 {
 54798 
 54799 private static $version = false;
 54800 
 54801 
 54802 protected $io;
 54803 
 54804 protected $config;
 54805 
 54806 protected $process;
 54807 
 54808 protected $filesystem;
 54809 
 54810 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process, Filesystem $fs)
 54811 {
 54812 $this->io = $io;
 54813 $this->config = $config;
 54814 $this->process = $process;
 54815 $this->filesystem = $fs;
 54816 }
 54817 
 54818 
 54819 
 54820 
 54821 
 54822 
 54823 
 54824 
 54825 
 54826 public function runCommand($commandCallable, $url, $cwd, $initialClone = false)
 54827 {
 54828 
 54829 $this->config->prohibitUrlByConfig($url, $this->io);
 54830 
 54831 if ($initialClone) {
 54832 $origCwd = $cwd;
 54833 $cwd = null;
 54834 }
 54835 
 54836 if (Preg::isMatch('{^ssh://[^@]+@[^:]+:[^0-9]+}', $url)) {
 54837 throw new \InvalidArgumentException('The source URL ' . $url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
 54838 }
 54839 
 54840 if (!$initialClone) {
 54841 
 54842 $this->process->execute('git remote -v', $output, $cwd);
 54843 if (Preg::isMatch('{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im', $output, $match) && !$this->io->hasAuthentication($match[3])) {
 54844 $this->io->setAuthentication($match[3], rawurldecode($match[1]), rawurldecode($match[2]));
 54845 }
 54846 }
 54847 
 54848 $protocols = $this->config->get('github-protocols');
 54849 if (!is_array($protocols)) {
 54850 throw new \RuntimeException('Config value "github-protocols" must be an array, got ' . gettype($protocols));
 54851 }
 54852 
 54853 if (Preg::isMatch('{^(?:https?|git)://' . self::getGitHubDomainsRegex($this->config) . '/(.*)}', $url, $match)) {
 54854 $messages = array();
 54855 foreach ($protocols as $protocol) {
 54856 if ('ssh' === $protocol) {
 54857 $protoUrl = "git@" . $match[1] . ":" . $match[2];
 54858 } else {
 54859 $protoUrl = $protocol . "://" . $match[1] . "/" . $match[2];
 54860 }
 54861 
 54862 if (0 === $this->process->execute(call_user_func($commandCallable, $protoUrl), $ignoredOutput, $cwd)) {
 54863 return;
 54864 }
 54865 $messages[] = '- ' . $protoUrl . "\n" . Preg::replace('#^#m', '  ', $this->process->getErrorOutput());
 54866 
 54867 if ($initialClone && isset($origCwd)) {
 54868 $this->filesystem->removeDirectory($origCwd);
 54869 }
 54870 }
 54871 
 54872 
 54873 if (!$this->io->hasAuthentication($match[1]) && !$this->io->isInteractive()) {
 54874 $this->throwException('Failed to clone ' . $url . ' via ' . implode(', ', $protocols) . ' protocols, aborting.' . "\n\n" . implode("\n", $messages), $url);
 54875 }
 54876 }
 54877 
 54878 
 54879 $bypassSshForGitHub = Preg::isMatch('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url) && !in_array('ssh', $protocols, true);
 54880 
 54881 $command = call_user_func($commandCallable, $url);
 54882 
 54883 $auth = null;
 54884 $credentials = array();
 54885 if ($bypassSshForGitHub || 0 !== $this->process->execute($command, $ignoredOutput, $cwd)) {
 54886 $errorMsg = $this->process->getErrorOutput();
 54887 
 54888 if (Preg::isMatch('{^git@' . self::getGitHubDomainsRegex($this->config) . ':(.+?)\.git$}i', $url, $match)
 54889 || Preg::isMatch('{^https?://' . self::getGitHubDomainsRegex($this->config) . '/(.*?)(?:\.git)?$}i', $url, $match)
 54890 ) {
 54891 if (!$this->io->hasAuthentication($match[1])) {
 54892 $gitHubUtil = new GitHub($this->io, $this->config, $this->process);
 54893 $message = 'Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos';
 54894 
 54895 if (!$gitHubUtil->authorizeOAuth($match[1]) && $this->io->isInteractive()) {
 54896 $gitHubUtil->authorizeOAuthInteractively($match[1], $message);
 54897 }
 54898 }
 54899 
 54900 if ($this->io->hasAuthentication($match[1])) {
 54901 $auth = $this->io->getAuthentication($match[1]);
 54902 $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[1] . '/' . $match[2] . '.git';
 54903 $command = call_user_func($commandCallable, $authUrl);
 54904 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 54905 return;
 54906 }
 54907 
 54908 $credentials = array(rawurlencode($auth['username']), rawurlencode($auth['password']));
 54909 $errorMsg = $this->process->getErrorOutput();
 54910 }
 54911 } elseif (Preg::isMatch('{^https://(bitbucket\.org)/(.*?)(?:\.git)?$}i', $url, $match)) { 
 54912 $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process);
 54913 
 54914 if (!$this->io->hasAuthentication($match[1])) {
 54915 $message = 'Enter your Bitbucket credentials to access private repos';
 54916 
 54917 if (!$bitbucketUtil->authorizeOAuth($match[1]) && $this->io->isInteractive()) {
 54918 $bitbucketUtil->authorizeOAuthInteractively($match[1], $message);
 54919 $accessToken = $bitbucketUtil->getToken();
 54920 $this->io->setAuthentication($match[1], 'x-token-auth', $accessToken);
 54921 }
 54922 } else { 
 54923 $auth = $this->io->getAuthentication($match[1]);
 54924 
 54925 
 54926 if ($auth['username'] !== 'x-token-auth') {
 54927 $accessToken = $bitbucketUtil->requestToken($match[1], $auth['username'], $auth['password']);
 54928 if (!empty($accessToken)) {
 54929 $this->io->setAuthentication($match[1], 'x-token-auth', $accessToken);
 54930 }
 54931 }
 54932 }
 54933 
 54934 if ($this->io->hasAuthentication($match[1])) {
 54935 $auth = $this->io->getAuthentication($match[1]);
 54936 $authUrl = 'https://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[1] . '/' . $match[2] . '.git';
 54937 
 54938 $command = call_user_func($commandCallable, $authUrl);
 54939 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 54940 return;
 54941 }
 54942 
 54943 $credentials = array(rawurlencode($auth['username']), rawurlencode($auth['password']));
 54944 $errorMsg = $this->process->getErrorOutput();
 54945 } else { 
 54946 $sshUrl = 'git@bitbucket.org:' . $match[2] . '.git';
 54947 $this->io->writeError('    No bitbucket authentication configured. Falling back to ssh.');
 54948 $command = call_user_func($commandCallable, $sshUrl);
 54949 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 54950 return;
 54951 }
 54952 
 54953 $errorMsg = $this->process->getErrorOutput();
 54954 }
 54955 } elseif (
 54956 Preg::isMatch('{^(git)@' . self::getGitLabDomainsRegex($this->config) . ':(.+?\.git)$}i', $url, $match)
 54957 || Preg::isMatch('{^(https?)://' . self::getGitLabDomainsRegex($this->config) . '/(.*)}i', $url, $match)
 54958 ) {
 54959 if ($match[1] === 'git') {
 54960 $match[1] = 'https';
 54961 }
 54962 
 54963 if (!$this->io->hasAuthentication($match[2])) {
 54964 $gitLabUtil = new GitLab($this->io, $this->config, $this->process);
 54965 $message = 'Cloning failed, enter your GitLab credentials to access private repos';
 54966 
 54967 if (!$gitLabUtil->authorizeOAuth($match[2]) && $this->io->isInteractive()) {
 54968 $gitLabUtil->authorizeOAuthInteractively($match[1], $match[2], $message);
 54969 }
 54970 }
 54971 
 54972 if ($this->io->hasAuthentication($match[2])) {
 54973 $auth = $this->io->getAuthentication($match[2]);
 54974 if ($auth['password'] === 'private-token' || $auth['password'] === 'oauth2' || $auth['password'] === 'gitlab-ci-token') {
 54975 $authUrl = $match[1] . '://' . rawurlencode($auth['password']) . ':' . rawurlencode($auth['username']) . '@' . $match[2] . '/' . $match[3]; 
 54976 } else {
 54977 $authUrl = $match[1] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[2] . '/' . $match[3];
 54978 }
 54979 
 54980 $command = call_user_func($commandCallable, $authUrl);
 54981 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 54982 return;
 54983 }
 54984 
 54985 $credentials = array(rawurlencode($auth['username']), rawurlencode($auth['password']));
 54986 $errorMsg = $this->process->getErrorOutput();
 54987 }
 54988 } elseif ($this->isAuthenticationFailure($url, $match)) { 
 54989 if (strpos($match[2], '@')) {
 54990 list($authParts, $match[2]) = explode('@', $match[2], 2);
 54991 }
 54992 
 54993 $storeAuth = false;
 54994 if ($this->io->hasAuthentication($match[2])) {
 54995 $auth = $this->io->getAuthentication($match[2]);
 54996 } elseif ($this->io->isInteractive()) {
 54997 $defaultUsername = null;
 54998 if (isset($authParts) && $authParts) {
 54999 if (false !== strpos($authParts, ':')) {
 55000 list($defaultUsername, ) = explode(':', $authParts, 2);
 55001 } else {
 55002 $defaultUsername = $authParts;
 55003 }
 55004 }
 55005 
 55006 $this->io->writeError('    Authentication required (<info>' . $match[2] . '</info>):');
 55007 $auth = array(
 55008 'username' => $this->io->ask('      Username: ', $defaultUsername),
 55009 'password' => $this->io->askAndHideAnswer('      Password: '),
 55010 );
 55011 $storeAuth = $this->config->get('store-auths');
 55012 }
 55013 
 55014 if ($auth) {
 55015 $authUrl = $match[1] . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[2] . $match[3];
 55016 
 55017 $command = call_user_func($commandCallable, $authUrl);
 55018 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 55019 $this->io->setAuthentication($match[2], $auth['username'], $auth['password']);
 55020 $authHelper = new AuthHelper($this->io, $this->config);
 55021 $authHelper->storeAuth($match[2], $storeAuth);
 55022 
 55023 return;
 55024 }
 55025 
 55026 $credentials = array(rawurlencode($auth['username']), rawurlencode($auth['password']));
 55027 $errorMsg = $this->process->getErrorOutput();
 55028 }
 55029 }
 55030 
 55031 if ($initialClone && isset($origCwd)) {
 55032 $this->filesystem->removeDirectory($origCwd);
 55033 }
 55034 
 55035 if (count($credentials) > 0) {
 55036 $command = $this->maskCredentials($command, $credentials);
 55037 $errorMsg = $this->maskCredentials($errorMsg, $credentials);
 55038 }
 55039 $this->throwException('Failed to execute ' . $command . "\n\n" . $errorMsg, $url);
 55040 }
 55041 }
 55042 
 55043 
 55044 
 55045 
 55046 
 55047 
 55048 
 55049 public function syncMirror($url, $dir)
 55050 {
 55051 if (Platform::getEnv('COMPOSER_DISABLE_NETWORK') && Platform::getEnv('COMPOSER_DISABLE_NETWORK') !== 'prime') {
 55052 $this->io->writeError('<warning>Aborting git mirror sync of '.$url.' as network is disabled</warning>');
 55053 
 55054 return false;
 55055 }
 55056 
 55057 
 55058 if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
 55059 try {
 55060 $commandCallable = function ($url) {
 55061 $sanitizedUrl = Preg::replace('{://([^@]+?):(.+?)@}', '://', $url);
 55062 
 55063 return sprintf('git remote set-url origin -- %s && git remote update --prune origin && git remote set-url origin -- %s && git gc --auto', ProcessExecutor::escape($url), ProcessExecutor::escape($sanitizedUrl));
 55064 };
 55065 $this->runCommand($commandCallable, $url, $dir);
 55066 } catch (\Exception $e) {
 55067 $this->io->writeError('<error>Sync mirror failed: ' . $e->getMessage() . '</error>', true, IOInterface::DEBUG);
 55068 
 55069 return false;
 55070 }
 55071 
 55072 return true;
 55073 }
 55074 
 55075 
 55076 $this->filesystem->removeDirectory($dir);
 55077 
 55078 $commandCallable = function ($url) use ($dir) {
 55079 return sprintf('git clone --mirror -- %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($dir));
 55080 };
 55081 
 55082 $this->runCommand($commandCallable, $url, $dir, true);
 55083 
 55084 return true;
 55085 }
 55086 
 55087 
 55088 
 55089 
 55090 
 55091 
 55092 
 55093 
 55094 public function fetchRefOrSyncMirror($url, $dir, $ref)
 55095 {
 55096 if ($this->checkRefIsInMirror($dir, $ref)) {
 55097 return true;
 55098 }
 55099 
 55100 if ($this->syncMirror($url, $dir)) {
 55101 return $this->checkRefIsInMirror($dir, $ref);
 55102 }
 55103 
 55104 return false;
 55105 }
 55106 
 55107 
 55108 
 55109 
 55110 public static function getNoShowSignatureFlag(ProcessExecutor $process)
 55111 {
 55112 $gitVersion = self::getVersion($process);
 55113 if ($gitVersion && version_compare($gitVersion, '2.10.0-rc0', '>=')) {
 55114 return ' --no-show-signature';
 55115 }
 55116 
 55117 return '';
 55118 }
 55119 
 55120 
 55121 
 55122 
 55123 
 55124 
 55125 
 55126 private function checkRefIsInMirror($dir, $ref)
 55127 {
 55128 if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
 55129 $escapedRef = ProcessExecutor::escape($ref.'^{commit}');
 55130 $exitCode = $this->process->execute(sprintf('git rev-parse --quiet --verify %s', $escapedRef), $ignoredOutput, $dir);
 55131 if ($exitCode === 0) {
 55132 return true;
 55133 }
 55134 }
 55135 
 55136 return false;
 55137 }
 55138 
 55139 
 55140 
 55141 
 55142 
 55143 
 55144 
 55145 private function isAuthenticationFailure($url, &$match)
 55146 {
 55147 if (!Preg::isMatch('{^(https?://)([^/]+)(.*)$}i', $url, $match)) {
 55148 return false;
 55149 }
 55150 
 55151 $authFailures = array(
 55152 'fatal: Authentication failed',
 55153 'remote error: Invalid username or password.',
 55154 'error: 401 Unauthorized',
 55155 'fatal: unable to access',
 55156 'fatal: could not read Username',
 55157 );
 55158 
 55159 $errorOutput = $this->process->getErrorOutput();
 55160 foreach ($authFailures as $authFailure) {
 55161 if (strpos($errorOutput, $authFailure) !== false) {
 55162 return true;
 55163 }
 55164 }
 55165 
 55166 return false;
 55167 }
 55168 
 55169 
 55170 
 55171 
 55172 public static function cleanEnv()
 55173 {
 55174 if (PHP_VERSION_ID < 50400 && ini_get('safe_mode') && false === strpos(ini_get('safe_mode_allowed_env_vars'), 'GIT_ASKPASS')) {
 55175 throw new \RuntimeException('safe_mode is enabled and safe_mode_allowed_env_vars does not contain GIT_ASKPASS, can not set env var. You can disable safe_mode with "-dsafe_mode=0" when running composer');
 55176 }
 55177 
 55178 
 55179 if (Platform::getEnv('GIT_ASKPASS') !== 'echo') {
 55180 Platform::putEnv('GIT_ASKPASS', 'echo');
 55181 }
 55182 
 55183 
 55184 if (Platform::getEnv('GIT_DIR')) {
 55185 Platform::clearEnv('GIT_DIR');
 55186 }
 55187 if (Platform::getEnv('GIT_WORK_TREE')) {
 55188 Platform::clearEnv('GIT_WORK_TREE');
 55189 }
 55190 
 55191 
 55192 if (Platform::getEnv('LANGUAGE') !== 'C') {
 55193 Platform::putEnv('LANGUAGE', 'C');
 55194 }
 55195 
 55196 
 55197 Platform::clearEnv('DYLD_LIBRARY_PATH');
 55198 }
 55199 
 55200 
 55201 
 55202 
 55203 public static function getGitHubDomainsRegex(Config $config)
 55204 {
 55205 return '(' . implode('|', array_map('preg_quote', $config->get('github-domains'))) . ')';
 55206 }
 55207 
 55208 
 55209 
 55210 
 55211 public static function getGitLabDomainsRegex(Config $config)
 55212 {
 55213 return '(' . implode('|', array_map('preg_quote', $config->get('gitlab-domains'))) . ')';
 55214 }
 55215 
 55216 
 55217 
 55218 
 55219 
 55220 
 55221 
 55222 private function throwException($message, $url)
 55223 {
 55224 
 55225 clearstatcache();
 55226 
 55227 if (0 !== $this->process->execute('git --version', $ignoredOutput)) {
 55228 throw new \RuntimeException(Url::sanitize('Failed to clone ' . $url . ', git was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput()));
 55229 }
 55230 
 55231 throw new \RuntimeException(Url::sanitize($message));
 55232 }
 55233 
 55234 
 55235 
 55236 
 55237 
 55238 
 55239 public static function getVersion(ProcessExecutor $process)
 55240 {
 55241 if (false === self::$version) {
 55242 self::$version = null;
 55243 if (0 === $process->execute('git --version', $output) && Preg::isMatch('/^git version (\d+(?:\.\d+)+)/m', $output, $matches)) {
 55244 self::$version = $matches[1];
 55245 }
 55246 }
 55247 
 55248 return self::$version;
 55249 }
 55250 
 55251 
 55252 
 55253 
 55254 
 55255 
 55256 
 55257 private function maskCredentials($error, array $credentials)
 55258 {
 55259 $maskedCredentials = array();
 55260 
 55261 foreach ($credentials as $credential) {
 55262 if (in_array($credential, array('private-token', 'x-token-auth', 'oauth2', 'gitlab-ci-token', 'x-oauth-basic'))) {
 55263 $maskedCredentials[] = $credential;
 55264 } elseif (strlen($credential) > 6) {
 55265 $maskedCredentials[] = substr($credential, 0, 3) . '...' . substr($credential, -3);
 55266 } elseif (strlen($credential) > 3) {
 55267 $maskedCredentials[] = substr($credential, 0, 3) . '...';
 55268 } else {
 55269 $maskedCredentials[] = 'XXX';
 55270 }
 55271 }
 55272 
 55273 return str_replace($credentials, $maskedCredentials, $error);
 55274 }
 55275 }
 55276 <?php
 55277 
 55278 
 55279 
 55280 
 55281 
 55282 
 55283 
 55284 
 55285 
 55286 
 55287 
 55288 namespace Composer\Util;
 55289 
 55290 use Composer\Factory;
 55291 use Composer\IO\IOInterface;
 55292 use Composer\Config;
 55293 use Composer\Downloader\TransportException;
 55294 use Composer\Pcre\Preg;
 55295 
 55296 
 55297 
 55298 
 55299 class GitHub
 55300 {
 55301 
 55302 protected $io;
 55303 
 55304 protected $config;
 55305 
 55306 protected $process;
 55307 
 55308 protected $httpDownloader;
 55309 
 55310 
 55311 
 55312 
 55313 
 55314 
 55315 
 55316 
 55317 
 55318 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
 55319 {
 55320 $this->io = $io;
 55321 $this->config = $config;
 55322 $this->process = $process ?: new ProcessExecutor($io);
 55323 $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
 55324 }
 55325 
 55326 
 55327 
 55328 
 55329 
 55330 
 55331 
 55332 public function authorizeOAuth($originUrl)
 55333 {
 55334 if (!in_array($originUrl, $this->config->get('github-domains'))) {
 55335 return false;
 55336 }
 55337 
 55338 
 55339 if (0 === $this->process->execute('git config github.accesstoken', $output)) {
 55340 $this->io->setAuthentication($originUrl, trim($output), 'x-oauth-basic');
 55341 
 55342 return true;
 55343 }
 55344 
 55345 return false;
 55346 }
 55347 
 55348 
 55349 
 55350 
 55351 
 55352 
 55353 
 55354 
 55355 
 55356 
 55357 public function authorizeOAuthInteractively($originUrl, $message = null)
 55358 {
 55359 if ($message) {
 55360 $this->io->writeError($message);
 55361 }
 55362 
 55363 $note = 'Composer';
 55364 if ($this->config->get('github-expose-hostname') === true && 0 === $this->process->execute('hostname', $output)) {
 55365 $note .= ' on ' . trim($output);
 55366 }
 55367 $note .= ' ' . date('Y-m-d Hi');
 55368 
 55369 $url = 'https://'.$originUrl.'/settings/tokens/new?scopes=&description=' . str_replace('%20', '+', rawurlencode($note));
 55370 $this->io->writeError(sprintf('When working with _public_ GitHub repositories only, head to %s to retrieve a token.', $url));
 55371 $this->io->writeError('This token will have read-only permission for public information only.');
 55372 
 55373 $url = 'https://'.$originUrl.'/settings/tokens/new?scopes=repo&description=' . str_replace('%20', '+', rawurlencode($note));
 55374 $this->io->writeError(sprintf('When you need to access _private_ GitHub repositories as well, go to %s', $url));
 55375 $this->io->writeError('Note that such tokens have broad read/write permissions on your behalf, even if not needed by Composer.');
 55376 $this->io->writeError(sprintf('Tokens will be stored in plain text in "%s" for future use by Composer.', $this->config->getAuthConfigSource()->getName()));
 55377 $this->io->writeError('For additional information, check https://getcomposer.org/doc/articles/authentication-for-private-packages.md#github-oauth');
 55378 
 55379 $token = trim($this->io->askAndHideAnswer('Token (hidden): '));
 55380 
 55381 if (!$token) {
 55382 $this->io->writeError('<warning>No token given, aborting.</warning>');
 55383 $this->io->writeError('You can also add it manually later by using "composer config --global --auth github-oauth.github.com <token>"');
 55384 
 55385 return false;
 55386 }
 55387 
 55388 $this->io->setAuthentication($originUrl, $token, 'x-oauth-basic');
 55389 
 55390 try {
 55391 $apiUrl = ('github.com' === $originUrl) ? 'api.github.com/' : $originUrl . '/api/v3/';
 55392 
 55393 $this->httpDownloader->get('https://'. $apiUrl, array(
 55394 'retry-auth-failure' => false,
 55395 ));
 55396 } catch (TransportException $e) {
 55397 if (in_array($e->getCode(), array(403, 401))) {
 55398 $this->io->writeError('<error>Invalid token provided.</error>');
 55399 $this->io->writeError('You can also add it manually later by using "composer config --global --auth github-oauth.github.com <token>"');
 55400 
 55401 return false;
 55402 }
 55403 
 55404 throw $e;
 55405 }
 55406 
 55407 
 55408 $this->config->getConfigSource()->removeConfigSetting('github-oauth.'.$originUrl);
 55409 $this->config->getAuthConfigSource()->addConfigSetting('github-oauth.'.$originUrl, $token);
 55410 
 55411 $this->io->writeError('<info>Token stored successfully.</info>');
 55412 
 55413 return true;
 55414 }
 55415 
 55416 
 55417 
 55418 
 55419 
 55420 
 55421 
 55422 
 55423 public function getRateLimit(array $headers)
 55424 {
 55425 $rateLimit = array(
 55426 'limit' => '?',
 55427 'reset' => '?',
 55428 );
 55429 
 55430 foreach ($headers as $header) {
 55431 $header = trim($header);
 55432 if (false === strpos($header, 'X-RateLimit-')) {
 55433 continue;
 55434 }
 55435 list($type, $value) = explode(':', $header, 2);
 55436 switch ($type) {
 55437 case 'X-RateLimit-Limit':
 55438 $rateLimit['limit'] = (int) trim($value);
 55439 break;
 55440 case 'X-RateLimit-Reset':
 55441 $rateLimit['reset'] = date('Y-m-d H:i:s', (int) trim($value));
 55442 break;
 55443 }
 55444 }
 55445 
 55446 return $rateLimit;
 55447 }
 55448 
 55449 
 55450 
 55451 
 55452 
 55453 
 55454 
 55455 
 55456 public function getSsoUrl(array $headers)
 55457 {
 55458 foreach ($headers as $header) {
 55459 $header = trim($header);
 55460 if (false === stripos($header, 'x-github-sso: required')) {
 55461 continue;
 55462 }
 55463 if (Preg::isMatch('{\burl=(?P<url>[^\s;]+)}', $header, $match)) {
 55464 return $match['url'];
 55465 }
 55466 }
 55467 
 55468 return null;
 55469 }
 55470 
 55471 
 55472 
 55473 
 55474 
 55475 
 55476 
 55477 
 55478 public function isRateLimited(array $headers)
 55479 {
 55480 foreach ($headers as $header) {
 55481 if (Preg::isMatch('{^X-RateLimit-Remaining: *0$}i', trim($header))) {
 55482 return true;
 55483 }
 55484 }
 55485 
 55486 return false;
 55487 }
 55488 
 55489 
 55490 
 55491 
 55492 
 55493 
 55494 
 55495 
 55496 
 55497 
 55498 public function requiresSso(array $headers)
 55499 {
 55500 foreach ($headers as $header) {
 55501 if (Preg::isMatch('{^X-GitHub-SSO: required}i', trim($header))) {
 55502 return true;
 55503 }
 55504 }
 55505 
 55506 return false;
 55507 }
 55508 }
 55509 <?php
 55510 
 55511 
 55512 
 55513 
 55514 
 55515 
 55516 
 55517 
 55518 
 55519 
 55520 
 55521 namespace Composer\Util;
 55522 
 55523 use Composer\IO\IOInterface;
 55524 use Composer\Config;
 55525 use Composer\Factory;
 55526 use Composer\Downloader\TransportException;
 55527 use Composer\Pcre\Preg;
 55528 
 55529 
 55530 
 55531 
 55532 class GitLab
 55533 {
 55534 
 55535 protected $io;
 55536 
 55537 protected $config;
 55538 
 55539 protected $process;
 55540 
 55541 protected $httpDownloader;
 55542 
 55543 
 55544 
 55545 
 55546 
 55547 
 55548 
 55549 
 55550 
 55551 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
 55552 {
 55553 $this->io = $io;
 55554 $this->config = $config;
 55555 $this->process = $process ?: new ProcessExecutor($io);
 55556 $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
 55557 }
 55558 
 55559 
 55560 
 55561 
 55562 
 55563 
 55564 
 55565 
 55566 public function authorizeOAuth($originUrl)
 55567 {
 55568 
 55569 $bcOriginUrl = Preg::replace('{:\d+}', '', $originUrl);
 55570 
 55571 if (!in_array($originUrl, $this->config->get('gitlab-domains'), true) && !in_array($bcOriginUrl, $this->config->get('gitlab-domains'), true)) {
 55572 return false;
 55573 }
 55574 
 55575 
 55576 if (0 === $this->process->execute('git config gitlab.accesstoken', $output)) {
 55577 $this->io->setAuthentication($originUrl, trim($output), 'oauth2');
 55578 
 55579 return true;
 55580 }
 55581 
 55582 
 55583 if (0 === $this->process->execute('git config gitlab.deploytoken.user', $tokenUser) && 0 === $this->process->execute('git config gitlab.deploytoken.token', $tokenPassword)) {
 55584 $this->io->setAuthentication($originUrl, trim($tokenUser), trim($tokenPassword));
 55585 
 55586 return true;
 55587 }
 55588 
 55589 
 55590 $authTokens = $this->config->get('gitlab-token');
 55591 
 55592 if (isset($authTokens[$originUrl])) {
 55593 $token = $authTokens[$originUrl];
 55594 }
 55595 
 55596 if (isset($authTokens[$bcOriginUrl])) {
 55597 $token = $authTokens[$bcOriginUrl];
 55598 }
 55599 
 55600 if (isset($token)) {
 55601 $username = is_array($token) && array_key_exists("username", $token) ? $token["username"] : $token;
 55602 $password = is_array($token) && array_key_exists("token", $token) ? $token["token"] : 'private-token';
 55603 $this->io->setAuthentication($originUrl, $username, $password);
 55604 
 55605 return true;
 55606 }
 55607 
 55608 return false;
 55609 }
 55610 
 55611 
 55612 
 55613 
 55614 
 55615 
 55616 
 55617 
 55618 
 55619 
 55620 
 55621 
 55622 
 55623 public function authorizeOAuthInteractively($scheme, $originUrl, $message = null)
 55624 {
 55625 if ($message) {
 55626 $this->io->writeError($message);
 55627 }
 55628 
 55629 $this->io->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName()));
 55630 $this->io->writeError('To revoke access to this token you can visit '.$scheme.'://'.$originUrl.'/-/profile/personal_access_tokens');
 55631 
 55632 $attemptCounter = 0;
 55633 
 55634 while ($attemptCounter++ < 5) {
 55635 try {
 55636 $response = $this->createToken($scheme, $originUrl);
 55637 } catch (TransportException $e) {
 55638 
 55639 
 55640 if (in_array($e->getCode(), array(403, 401))) {
 55641 if (401 === $e->getCode()) {
 55642 $response = json_decode($e->getResponse(), true);
 55643 if (isset($response['error']) && $response['error'] === 'invalid_grant') {
 55644 $this->io->writeError('Bad credentials. If you have two factor authentication enabled you will have to manually create a personal access token');
 55645 } else {
 55646 $this->io->writeError('Bad credentials.');
 55647 }
 55648 } else {
 55649 $this->io->writeError('Maximum number of login attempts exceeded. Please try again later.');
 55650 }
 55651 
 55652 $this->io->writeError('You can also manually create a personal access token enabling the "read_api" scope at '.$scheme.'://'.$originUrl.'/profile/personal_access_tokens');
 55653 $this->io->writeError('Add it using "composer config --global --auth gitlab-token.'.$originUrl.' <token>"');
 55654 
 55655 continue;
 55656 }
 55657 
 55658 throw $e;
 55659 }
 55660 
 55661 $this->io->setAuthentication($originUrl, $response['access_token'], 'oauth2');
 55662 
 55663 
 55664 $this->config->getAuthConfigSource()->addConfigSetting('gitlab-oauth.'.$originUrl, $response['access_token']);
 55665 
 55666 return true;
 55667 }
 55668 
 55669 throw new \RuntimeException('Invalid GitLab credentials 5 times in a row, aborting.');
 55670 }
 55671 
 55672 
 55673 
 55674 
 55675 
 55676 
 55677 
 55678 
 55679 
 55680 private function createToken($scheme, $originUrl)
 55681 {
 55682 $username = $this->io->ask('Username: ');
 55683 $password = $this->io->askAndHideAnswer('Password: ');
 55684 
 55685 $headers = array('Content-Type: application/x-www-form-urlencoded');
 55686 
 55687 $apiUrl = $originUrl;
 55688 $data = http_build_query(array(
 55689 'username' => $username,
 55690 'password' => $password,
 55691 'grant_type' => 'password',
 55692 ), '', '&');
 55693 $options = array(
 55694 'retry-auth-failure' => false,
 55695 'http' => array(
 55696 'method' => 'POST',
 55697 'header' => $headers,
 55698 'content' => $data,
 55699 ),
 55700 );
 55701 
 55702 $token = $this->httpDownloader->get($scheme.'://'.$apiUrl.'/oauth/token', $options)->decodeJson();
 55703 
 55704 $this->io->writeError('Token successfully created');
 55705 
 55706 return $token;
 55707 }
 55708 }
 55709 <?php
 55710 
 55711 
 55712 
 55713 
 55714 
 55715 
 55716 
 55717 
 55718 
 55719 
 55720 
 55721 namespace Composer\Util;
 55722 
 55723 use Composer\Config;
 55724 use Composer\IO\IOInterface;
 55725 use Composer\Pcre\Preg;
 55726 
 55727 
 55728 
 55729 
 55730 class Hg
 55731 {
 55732 
 55733 private static $version = false;
 55734 
 55735 
 55736 
 55737 
 55738 private $io;
 55739 
 55740 
 55741 
 55742 
 55743 private $config;
 55744 
 55745 
 55746 
 55747 
 55748 private $process;
 55749 
 55750 public function __construct(IOInterface $io, Config $config, ProcessExecutor $process)
 55751 {
 55752 $this->io = $io;
 55753 $this->config = $config;
 55754 $this->process = $process;
 55755 }
 55756 
 55757 
 55758 
 55759 
 55760 
 55761 
 55762 
 55763 
 55764 public function runCommand($commandCallable, $url, $cwd)
 55765 {
 55766 $this->config->prohibitUrlByConfig($url, $this->io);
 55767 
 55768 
 55769 $command = call_user_func($commandCallable, $url);
 55770 
 55771 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 55772 return;
 55773 }
 55774 
 55775 
 55776 if (Preg::isMatch('{^(https?)://((.+)(?:\:(.+))?@)?([^/]+)(/.*)?}mi', $url, $match) && $this->io->hasAuthentication($match[5])) {
 55777 $auth = $this->io->getAuthentication($match[5]);
 55778 $authenticatedUrl = $match[1] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[5] . (!empty($match[6]) ? $match[6] : null);
 55779 
 55780 $command = call_user_func($commandCallable, $authenticatedUrl);
 55781 
 55782 if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) {
 55783 return;
 55784 }
 55785 
 55786 $error = $this->process->getErrorOutput();
 55787 } else {
 55788 $error = 'The given URL (' . $url . ') does not match the required format (http(s)://(username:password@)example.com/path-to-repository)';
 55789 }
 55790 
 55791 $this->throwException('Failed to clone ' . $url . ', ' . "\n\n" . $error, $url);
 55792 }
 55793 
 55794 
 55795 
 55796 
 55797 
 55798 
 55799 
 55800 private function throwException($message, $url)
 55801 {
 55802 if (null === self::getVersion($this->process)) {
 55803 throw new \RuntimeException(Url::sanitize('Failed to clone ' . $url . ', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput()));
 55804 }
 55805 
 55806 throw new \RuntimeException(Url::sanitize($message));
 55807 }
 55808 
 55809 
 55810 
 55811 
 55812 
 55813 
 55814 public static function getVersion(ProcessExecutor $process)
 55815 {
 55816 if (false === self::$version) {
 55817 self::$version = null;
 55818 if (0 === $process->execute('hg --version', $output) && Preg::isMatch('/^.+? (\d+(?:\.\d+)+)\)?\r?\n/', $output, $matches)) {
 55819 self::$version = $matches[1];
 55820 }
 55821 }
 55822 
 55823 return self::$version;
 55824 }
 55825 }
 55826 <?php
 55827 
 55828 
 55829 
 55830 
 55831 
 55832 
 55833 
 55834 
 55835 
 55836 
 55837 
 55838 namespace Composer\Util\Http;
 55839 
 55840 use Composer\Config;
 55841 use Composer\Downloader\MaxFileSizeExceededException;
 55842 use Composer\IO\IOInterface;
 55843 use Composer\Downloader\TransportException;
 55844 use Composer\Pcre\Preg;
 55845 use Composer\Util\StreamContextFactory;
 55846 use Composer\Util\AuthHelper;
 55847 use Composer\Util\Url;
 55848 use Composer\Util\HttpDownloader;
 55849 use React\Promise\Promise;
 55850 
 55851 
 55852 
 55853 
 55854 
 55855 
 55856 
 55857 
 55858 class CurlDownloader
 55859 {
 55860 
 55861 private $multiHandle;
 55862 
 55863 private $shareHandle;
 55864 
 55865 private $jobs = array();
 55866 
 55867 private $io;
 55868 
 55869 private $config;
 55870 
 55871 private $authHelper;
 55872 
 55873 private $selectTimeout = 5.0;
 55874 
 55875 private $maxRedirects = 20;
 55876 
 55877 private $maxRetries = 3;
 55878 
 55879 private $proxyManager;
 55880 
 55881 private $supportsSecureProxy;
 55882 
 55883 protected $multiErrors = array(
 55884 CURLM_BAD_HANDLE => array('CURLM_BAD_HANDLE', 'The passed-in handle is not a valid CURLM handle.'),
 55885 CURLM_BAD_EASY_HANDLE => array('CURLM_BAD_EASY_HANDLE', "An easy handle was not good/valid. It could mean that it isn't an easy handle at all, or possibly that the handle already is in used by this or another multi handle."),
 55886 CURLM_OUT_OF_MEMORY => array('CURLM_OUT_OF_MEMORY', 'You are doomed.'),
 55887 CURLM_INTERNAL_ERROR => array('CURLM_INTERNAL_ERROR', 'This can only be returned if libcurl bugs. Please report it to us!'),
 55888 );
 55889 
 55890 
 55891 private static $options = array(
 55892 'http' => array(
 55893 'method' => CURLOPT_CUSTOMREQUEST,
 55894 'content' => CURLOPT_POSTFIELDS,
 55895 'header' => CURLOPT_HTTPHEADER,
 55896 'timeout' => CURLOPT_TIMEOUT,
 55897 ),
 55898 'ssl' => array(
 55899 'cafile' => CURLOPT_CAINFO,
 55900 'capath' => CURLOPT_CAPATH,
 55901 'verify_peer' => CURLOPT_SSL_VERIFYPEER,
 55902 'verify_peer_name' => CURLOPT_SSL_VERIFYHOST,
 55903 'local_cert' => CURLOPT_SSLCERT,
 55904 'local_pk' => CURLOPT_SSLKEY,
 55905 'passphrase' => CURLOPT_SSLKEYPASSWD,
 55906 ),
 55907 );
 55908 
 55909 
 55910 private static $timeInfo = array(
 55911 'total_time' => true,
 55912 'namelookup_time' => true,
 55913 'connect_time' => true,
 55914 'pretransfer_time' => true,
 55915 'starttransfer_time' => true,
 55916 'redirect_time' => true,
 55917 );
 55918 
 55919 
 55920 
 55921 
 55922 
 55923 public function __construct(IOInterface $io, Config $config, array $options = array(), $disableTls = false)
 55924 {
 55925 $this->io = $io;
 55926 $this->config = $config;
 55927 
 55928 $this->multiHandle = $mh = curl_multi_init();
 55929 if (function_exists('curl_multi_setopt')) {
 55930 curl_multi_setopt($mh, CURLMOPT_PIPELINING, PHP_VERSION_ID >= 70400 ?  2 :  3);
 55931 if (defined('CURLMOPT_MAX_HOST_CONNECTIONS') && !defined('HHVM_VERSION')) {
 55932 curl_multi_setopt($mh, CURLMOPT_MAX_HOST_CONNECTIONS, 8);
 55933 }
 55934 }
 55935 
 55936 if (function_exists('curl_share_init')) {
 55937 $this->shareHandle = $sh = curl_share_init();
 55938 curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
 55939 curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
 55940 curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
 55941 }
 55942 
 55943 $this->authHelper = new AuthHelper($io, $config);
 55944 $this->proxyManager = ProxyManager::getInstance();
 55945 
 55946 $version = curl_version();
 55947 $features = $version['features'];
 55948 $this->supportsSecureProxy = defined('CURL_VERSION_HTTPS_PROXY') && ($features & CURL_VERSION_HTTPS_PROXY);
 55949 }
 55950 
 55951 
 55952 
 55953 
 55954 
 55955 
 55956 
 55957 
 55958 
 55959 
 55960 
 55961 public function download($resolve, $reject, $origin, $url, $options, $copyTo = null)
 55962 {
 55963 $attributes = array();
 55964 if (isset($options['retry-auth-failure'])) {
 55965 $attributes['retryAuthFailure'] = $options['retry-auth-failure'];
 55966 unset($options['retry-auth-failure']);
 55967 }
 55968 
 55969 return $this->initDownload($resolve, $reject, $origin, $url, $options, $copyTo, $attributes);
 55970 }
 55971 
 55972 
 55973 
 55974 
 55975 
 55976 
 55977 
 55978 
 55979 
 55980 
 55981 
 55982 
 55983 
 55984 private function initDownload($resolve, $reject, $origin, $url, $options, $copyTo = null, array $attributes = array())
 55985 {
 55986 $attributes = array_merge(array(
 55987 'retryAuthFailure' => true,
 55988 'redirects' => 0,
 55989 'retries' => 0,
 55990 'storeAuth' => false,
 55991 ), $attributes);
 55992 
 55993 $originalOptions = $options;
 55994 
 55995 
 55996 if (!Preg::isMatch('{^http://(repo\.)?packagist\.org/p/}', $url) || (false === strpos($url, '$') && false === strpos($url, '%24'))) {
 55997 $this->config->prohibitUrlByConfig($url, $this->io);
 55998 }
 55999 
 56000 $curlHandle = curl_init();
 56001 $headerHandle = fopen('php://temp/maxmemory:32768', 'w+b');
 56002 if (false === $headerHandle) {
 56003 throw new \RuntimeException('Failed to open a temp stream to store curl headers');
 56004 }
 56005 
 56006 if ($copyTo) {
 56007 $errorMessage = '';
 56008 
 56009 set_error_handler(function ($code, $msg) use (&$errorMessage) {
 56010 if ($errorMessage) {
 56011 $errorMessage .= "\n";
 56012 }
 56013 $errorMessage .= Preg::replace('{^fopen\(.*?\): }', '', $msg);
 56014 });
 56015 $bodyHandle = fopen($copyTo.'~', 'w+b');
 56016 restore_error_handler();
 56017 if (!$bodyHandle) {
 56018 throw new TransportException('The "'.$url.'" file could not be written to '.$copyTo.': '.$errorMessage);
 56019 }
 56020 } else {
 56021 $bodyHandle = @fopen('php://temp/maxmemory:524288', 'w+b');
 56022 }
 56023 
 56024 curl_setopt($curlHandle, CURLOPT_URL, $url);
 56025 curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION, false);
 56026 curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 10);
 56027 curl_setopt($curlHandle, CURLOPT_TIMEOUT, max((int) ini_get("default_socket_timeout"), 300));
 56028 curl_setopt($curlHandle, CURLOPT_WRITEHEADER, $headerHandle);
 56029 curl_setopt($curlHandle, CURLOPT_FILE, $bodyHandle);
 56030 curl_setopt($curlHandle, CURLOPT_ENCODING, ""); 
 56031 curl_setopt($curlHandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
 56032 
 56033 if (function_exists('curl_share_init')) {
 56034 curl_setopt($curlHandle, CURLOPT_SHARE, $this->shareHandle);
 56035 }
 56036 
 56037 if (!isset($options['http']['header'])) {
 56038 $options['http']['header'] = array();
 56039 }
 56040 
 56041 $options['http']['header'] = array_diff($options['http']['header'], array('Connection: close'));
 56042 $options['http']['header'][] = 'Connection: keep-alive';
 56043 
 56044 $version = curl_version();
 56045 $features = $version['features'];
 56046 if (0 === strpos($url, 'https://') && \defined('CURL_VERSION_HTTP2') && \defined('CURL_HTTP_VERSION_2_0') && (CURL_VERSION_HTTP2 & $features)) {
 56047 curl_setopt($curlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
 56048 }
 56049 
 56050 $options['http']['header'] = $this->authHelper->addAuthenticationHeader($options['http']['header'], $origin, $url);
 56051 $options = StreamContextFactory::initOptions($url, $options, true);
 56052 
 56053 foreach (self::$options as $type => $curlOptions) {
 56054 foreach ($curlOptions as $name => $curlOption) {
 56055 if (isset($options[$type][$name])) {
 56056 if ($type === 'ssl' && $name === 'verify_peer_name') {
 56057 curl_setopt($curlHandle, $curlOption, $options[$type][$name] === true ? 2 : $options[$type][$name]);
 56058 } else {
 56059 curl_setopt($curlHandle, $curlOption, $options[$type][$name]);
 56060 }
 56061 }
 56062 }
 56063 }
 56064 
 56065 
 56066 
 56067 $proxy = $this->proxyManager->getProxyForRequest($url);
 56068 curl_setopt($curlHandle, CURLOPT_PROXY, $proxy->getUrl());
 56069 
 56070 
 56071 
 56072 if ($proxy->isSecure()) {
 56073 if (!$this->supportsSecureProxy) {
 56074 throw new TransportException('Connecting to a secure proxy using curl is not supported on PHP versions below 7.3.0.');
 56075 }
 56076 if (!empty($options['ssl']['cafile'])) {
 56077 curl_setopt($curlHandle, CURLOPT_PROXY_CAINFO, $options['ssl']['cafile']);
 56078 }
 56079 if (!empty($options['ssl']['capath'])) {
 56080 curl_setopt($curlHandle, CURLOPT_PROXY_CAPATH, $options['ssl']['capath']);
 56081 }
 56082 }
 56083 
 56084 $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo);
 56085 
 56086 $this->jobs[(int) $curlHandle] = array(
 56087 'url' => $url,
 56088 'origin' => $origin,
 56089 'attributes' => $attributes,
 56090 'options' => $originalOptions,
 56091 'progress' => $progress,
 56092 'curlHandle' => $curlHandle,
 56093 'filename' => $copyTo,
 56094 'headerHandle' => $headerHandle,
 56095 'bodyHandle' => $bodyHandle,
 56096 'resolve' => $resolve,
 56097 'reject' => $reject,
 56098 );
 56099 
 56100 $usingProxy = $proxy->getFormattedUrl(' using proxy (%s)');
 56101 $ifModified = false !== stripos(implode(',', $options['http']['header']), 'if-modified-since:') ? ' if modified' : '';
 56102 if ($attributes['redirects'] === 0 && $attributes['retries'] === 0) {
 56103 $this->io->writeError('Downloading ' . Url::sanitize($url) . $usingProxy . $ifModified, true, IOInterface::DEBUG);
 56104 }
 56105 
 56106 $this->checkCurlResult(curl_multi_add_handle($this->multiHandle, $curlHandle));
 56107 
 56108 
 56109 return (int) $curlHandle;
 56110 }
 56111 
 56112 
 56113 
 56114 
 56115 
 56116 public function abortRequest($id)
 56117 {
 56118 if (isset($this->jobs[$id], $this->jobs[$id]['curlHandle'])) {
 56119 $job = $this->jobs[$id];
 56120 curl_multi_remove_handle($this->multiHandle, $job['curlHandle']);
 56121 curl_close($job['curlHandle']);
 56122 if (is_resource($job['headerHandle'])) {
 56123 fclose($job['headerHandle']);
 56124 }
 56125 if (is_resource($job['bodyHandle'])) {
 56126 fclose($job['bodyHandle']);
 56127 }
 56128 if ($job['filename']) {
 56129 @unlink($job['filename'].'~');
 56130 }
 56131 unset($this->jobs[$id]);
 56132 }
 56133 }
 56134 
 56135 
 56136 
 56137 
 56138 public function tick()
 56139 {
 56140 static $timeoutWarning = false;
 56141 
 56142 if (!$this->jobs) {
 56143 return;
 56144 }
 56145 
 56146 $active = true;
 56147 $this->checkCurlResult(curl_multi_exec($this->multiHandle, $active));
 56148 if (-1 === curl_multi_select($this->multiHandle, $this->selectTimeout)) {
 56149 
 56150 usleep(150);
 56151 }
 56152 
 56153 while ($progress = curl_multi_info_read($this->multiHandle)) {
 56154 $curlHandle = $progress['handle'];
 56155 $result = $progress['result'];
 56156 $i = (int) $curlHandle;
 56157 if (!isset($this->jobs[$i])) {
 56158 continue;
 56159 }
 56160 
 56161 $progress = curl_getinfo($curlHandle);
 56162 $job = $this->jobs[$i];
 56163 unset($this->jobs[$i]);
 56164 $error = curl_error($curlHandle);
 56165 $errno = curl_errno($curlHandle);
 56166 curl_multi_remove_handle($this->multiHandle, $curlHandle);
 56167 curl_close($curlHandle);
 56168 
 56169 $headers = null;
 56170 $statusCode = null;
 56171 $response = null;
 56172 try {
 56173 
 56174 if (CURLE_OK !== $errno || $error || $result !== CURLE_OK) {
 56175 $errno = $errno ?: $result;
 56176 if (!$error && function_exists('curl_strerror')) {
 56177 $error = curl_strerror($errno);
 56178 }
 56179 $progress['error_code'] = $errno;
 56180 
 56181 if (
 56182 (!isset($job['options']['http']['method']) || $job['options']['http']['method'] === 'GET')
 56183 && (
 56184 in_array($errno, array(7 , 16 , 92 ), true)
 56185 || ($errno === 35  && false !== strpos($error, 'Connection reset by peer'))
 56186 ) && $job['attributes']['retries'] < $this->maxRetries
 56187 ) {
 56188 $this->io->writeError('Retrying ('.($job['attributes']['retries'] + 1).') ' . Url::sanitize($job['url']) . ' due to curl error '. $errno, true, IOInterface::DEBUG);
 56189 $this->restartJob($job, $job['url'], array('retries' => $job['attributes']['retries'] + 1));
 56190 continue;
 56191 }
 56192 
 56193 if ($errno === 28  && isset($progress['namelookup_time']) && $progress['namelookup_time'] == 0 && !$timeoutWarning) {
 56194 $timeoutWarning = true;
 56195 $this->io->writeError('<warning>A connection timeout was encountered. If you intend to run Composer without connecting to the internet, run the command again prefixed with COMPOSER_DISABLE_NETWORK=1 to make Composer run in offline mode.</warning>');
 56196 }
 56197 
 56198 throw new TransportException('curl error '.$errno.' while downloading '.Url::sanitize($progress['url']).': '.$error);
 56199 }
 56200 $statusCode = $progress['http_code'];
 56201 rewind($job['headerHandle']);
 56202 $headers = explode("\r\n", rtrim(stream_get_contents($job['headerHandle'])));
 56203 fclose($job['headerHandle']);
 56204 
 56205 if ($statusCode === 0) {
 56206 throw new \LogicException('Received unexpected http status code 0 without error for '.Url::sanitize($progress['url']).': headers '.var_export($headers, true).' curl info '.var_export($progress, true));
 56207 }
 56208 
 56209 
 56210 if ($job['filename']) {
 56211 $contents = $job['filename'].'~';
 56212 if ($statusCode >= 300) {
 56213 rewind($job['bodyHandle']);
 56214 $contents = stream_get_contents($job['bodyHandle']);
 56215 }
 56216 $response = new CurlResponse(array('url' => $progress['url']), $statusCode, $headers, $contents, $progress);
 56217 $this->io->writeError('['.$statusCode.'] '.Url::sanitize($progress['url']), true, IOInterface::DEBUG);
 56218 } else {
 56219 rewind($job['bodyHandle']);
 56220 $contents = stream_get_contents($job['bodyHandle']);
 56221 $response = new CurlResponse(array('url' => $progress['url']), $statusCode, $headers, $contents, $progress);
 56222 $this->io->writeError('['.$statusCode.'] '.Url::sanitize($progress['url']), true, IOInterface::DEBUG);
 56223 }
 56224 fclose($job['bodyHandle']);
 56225 
 56226 if ($response->getStatusCode() >= 400 && $response->getHeader('content-type') === 'application/json') {
 56227 HttpDownloader::outputWarnings($this->io, $job['origin'], json_decode($response->getBody(), true));
 56228 }
 56229 
 56230 $result = $this->isAuthenticatedRetryNeeded($job, $response);
 56231 if ($result['retry']) {
 56232 $this->restartJob($job, $job['url'], array('storeAuth' => $result['storeAuth']));
 56233 continue;
 56234 }
 56235 
 56236 
 56237 if ($statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $job['attributes']['redirects'] < $this->maxRedirects) {
 56238 $location = $this->handleRedirect($job, $response);
 56239 if ($location) {
 56240 $this->restartJob($job, $location, array('redirects' => $job['attributes']['redirects'] + 1));
 56241 continue;
 56242 }
 56243 }
 56244 
 56245 
 56246 if ($statusCode >= 400 && $statusCode <= 599) {
 56247 if (
 56248 (!isset($job['options']['http']['method']) || $job['options']['http']['method'] === 'GET')
 56249 && in_array($statusCode, array(423, 425, 500, 502, 503, 504, 507, 510), true)
 56250 && $job['attributes']['retries'] < $this->maxRetries
 56251 ) {
 56252 $this->io->writeError('Retrying ('.($job['attributes']['retries'] + 1).') ' . Url::sanitize($job['url']) . ' due to status code '. $statusCode, true, IOInterface::DEBUG);
 56253 $this->restartJob($job, $job['url'], array('retries' => $job['attributes']['retries'] + 1));
 56254 continue;
 56255 }
 56256 
 56257 throw $this->failResponse($job, $response, $response->getStatusMessage());
 56258 }
 56259 
 56260 if ($job['attributes']['storeAuth']) {
 56261 $this->authHelper->storeAuth($job['origin'], $job['attributes']['storeAuth']);
 56262 }
 56263 
 56264 
 56265 if ($job['filename']) {
 56266 rename($job['filename'].'~', $job['filename']);
 56267 call_user_func($job['resolve'], $response);
 56268 } else {
 56269 call_user_func($job['resolve'], $response);
 56270 }
 56271 } catch (\Exception $e) {
 56272 if ($e instanceof TransportException && $headers) {
 56273 $e->setHeaders($headers);
 56274 $e->setStatusCode($statusCode);
 56275 }
 56276 if ($e instanceof TransportException && $response) {
 56277 $e->setResponse($response->getBody());
 56278 }
 56279 if ($e instanceof TransportException && $progress) {
 56280 $e->setResponseInfo($progress);
 56281 }
 56282 
 56283 $this->rejectJob($job, $e);
 56284 }
 56285 }
 56286 
 56287 foreach ($this->jobs as $i => $curlHandle) {
 56288 if (!isset($this->jobs[$i])) {
 56289 continue;
 56290 }
 56291 $curlHandle = $this->jobs[$i]['curlHandle'];
 56292 $progress = array_diff_key(curl_getinfo($curlHandle), self::$timeInfo);
 56293 
 56294 if ($this->jobs[$i]['progress'] !== $progress) {
 56295 $this->jobs[$i]['progress'] = $progress;
 56296 
 56297 if (isset($this->jobs[$i]['options']['max_file_size'])) {
 56298 
 56299 if ($this->jobs[$i]['options']['max_file_size'] < $progress['download_content_length']) {
 56300 $this->rejectJob($this->jobs[$i], new MaxFileSizeExceededException('Maximum allowed download size reached. Content-length header indicates ' . $progress['download_content_length'] . ' bytes. Allowed ' . $this->jobs[$i]['options']['max_file_size'] . ' bytes'));
 56301 }
 56302 
 56303 
 56304 if ($this->jobs[$i]['options']['max_file_size'] < $progress['size_download']) {
 56305 $this->rejectJob($this->jobs[$i], new MaxFileSizeExceededException('Maximum allowed download size reached. Downloaded ' . $progress['size_download'] . ' of allowed ' . $this->jobs[$i]['options']['max_file_size'] . ' bytes'));
 56306 }
 56307 }
 56308 
 56309 
 56310 }
 56311 }
 56312 }
 56313 
 56314 
 56315 
 56316 
 56317 
 56318 private function handleRedirect(array $job, Response $response)
 56319 {
 56320 if ($locationHeader = $response->getHeader('location')) {
 56321 if (parse_url($locationHeader, PHP_URL_SCHEME)) {
 56322 
 56323 $targetUrl = $locationHeader;
 56324 } elseif (parse_url($locationHeader, PHP_URL_HOST)) {
 56325 
 56326 $targetUrl = parse_url($job['url'], PHP_URL_SCHEME).':'.$locationHeader;
 56327 } elseif ('/' === $locationHeader[0]) {
 56328 
 56329 $urlHost = parse_url($job['url'], PHP_URL_HOST);
 56330 
 56331 
 56332 $targetUrl = Preg::replace('{^(.+(?://|@)'.preg_quote($urlHost).'(?::\d+)?)(?:[/\?].*)?$}', '\1'.$locationHeader, $job['url']);
 56333 } else {
 56334 
 56335 
 56336 $targetUrl = Preg::replace('{^(.+/)[^/?]*(?:\?.*)?$}', '\1'.$locationHeader, $job['url']);
 56337 }
 56338 }
 56339 
 56340 if (!empty($targetUrl)) {
 56341 $this->io->writeError(sprintf('Following redirect (%u) %s', $job['attributes']['redirects'] + 1, Url::sanitize($targetUrl)), true, IOInterface::DEBUG);
 56342 
 56343 return $targetUrl;
 56344 }
 56345 
 56346 throw new TransportException('The "'.$job['url'].'" file could not be downloaded, got redirect without Location ('.$response->getStatusMessage().')');
 56347 }
 56348 
 56349 
 56350 
 56351 
 56352 
 56353 private function isAuthenticatedRetryNeeded(array $job, Response $response)
 56354 {
 56355 if (in_array($response->getStatusCode(), array(401, 403)) && $job['attributes']['retryAuthFailure']) {
 56356 $result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], $response->getStatusCode(), $response->getStatusMessage(), $response->getHeaders());
 56357 
 56358 if ($result['retry']) {
 56359 return $result;
 56360 }
 56361 }
 56362 
 56363 $locationHeader = $response->getHeader('location');
 56364 $needsAuthRetry = false;
 56365 
 56366 
 56367 if (
 56368 $job['origin'] === 'bitbucket.org'
 56369 && !$this->authHelper->isPublicBitBucketDownload($job['url'])
 56370 && substr($job['url'], -4) === '.zip'
 56371 && (!$locationHeader || substr($locationHeader, -4) !== '.zip')
 56372 && Preg::isMatch('{^text/html\b}i', $response->getHeader('content-type'))
 56373 ) {
 56374 $needsAuthRetry = 'Bitbucket requires authentication and it was not provided';
 56375 }
 56376 
 56377 
 56378 if (
 56379 $response->getStatusCode() === 404
 56380 && in_array($job['origin'], $this->config->get('gitlab-domains'), true)
 56381 && false !== strpos($job['url'], 'archive.zip')
 56382 ) {
 56383 $needsAuthRetry = 'GitLab requires authentication and it was not provided';
 56384 }
 56385 
 56386 if ($needsAuthRetry) {
 56387 if ($job['attributes']['retryAuthFailure']) {
 56388 $result = $this->authHelper->promptAuthIfNeeded($job['url'], $job['origin'], 401);
 56389 if ($result['retry']) {
 56390 return $result;
 56391 }
 56392 }
 56393 
 56394 throw $this->failResponse($job, $response, $needsAuthRetry);
 56395 }
 56396 
 56397 return array('retry' => false, 'storeAuth' => false);
 56398 }
 56399 
 56400 
 56401 
 56402 
 56403 
 56404 
 56405 
 56406 
 56407 
 56408 private function restartJob(array $job, $url, array $attributes = array())
 56409 {
 56410 if ($job['filename']) {
 56411 @unlink($job['filename'].'~');
 56412 }
 56413 
 56414 $attributes = array_merge($job['attributes'], $attributes);
 56415 $origin = Url::getOrigin($this->config, $url);
 56416 
 56417 $this->initDownload($job['resolve'], $job['reject'], $origin, $url, $job['options'], $job['filename'], $attributes);
 56418 }
 56419 
 56420 
 56421 
 56422 
 56423 
 56424 
 56425 private function failResponse(array $job, Response $response, $errorMessage)
 56426 {
 56427 if ($job['filename']) {
 56428 @unlink($job['filename'].'~');
 56429 }
 56430 
 56431 $details = '';
 56432 if (in_array(strtolower($response->getHeader('content-type')), array('application/json', 'application/json; charset=utf-8'), true)) {
 56433 $details = ':'.PHP_EOL.substr($response->getBody(), 0, 200).(strlen($response->getBody()) > 200 ? '...' : '');
 56434 }
 56435 
 56436 return new TransportException('The "'.$job['url'].'" file could not be downloaded ('.$errorMessage.')' . $details, $response->getStatusCode());
 56437 }
 56438 
 56439 
 56440 
 56441 
 56442 
 56443 private function rejectJob(array $job, \Exception $e)
 56444 {
 56445 if (is_resource($job['headerHandle'])) {
 56446 fclose($job['headerHandle']);
 56447 }
 56448 if (is_resource($job['bodyHandle'])) {
 56449 fclose($job['bodyHandle']);
 56450 }
 56451 if ($job['filename']) {
 56452 @unlink($job['filename'].'~');
 56453 }
 56454 call_user_func($job['reject'], $e);
 56455 }
 56456 
 56457 
 56458 
 56459 
 56460 
 56461 private function checkCurlResult($code)
 56462 {
 56463 if ($code != CURLM_OK && $code != CURLM_CALL_MULTI_PERFORM) {
 56464 throw new \RuntimeException(
 56465 isset($this->multiErrors[$code])
 56466 ? "cURL error: {$code} ({$this->multiErrors[$code][0]}): cURL message: {$this->multiErrors[$code][1]}"
 56467 : 'Unexpected cURL error: ' . $code
 56468 );
 56469 }
 56470 }
 56471 }
 56472 <?php
 56473 
 56474 
 56475 
 56476 
 56477 
 56478 
 56479 
 56480 
 56481 
 56482 
 56483 
 56484 namespace Composer\Util\Http;
 56485 
 56486 
 56487 
 56488 
 56489 class CurlResponse extends Response
 56490 {
 56491 
 56492 
 56493 
 56494 
 56495 private $curlInfo;
 56496 
 56497 
 56498 
 56499 
 56500 public function __construct(array $request, $code, array $headers, $body, array $curlInfo)
 56501 {
 56502 parent::__construct($request, $code, $headers, $body);
 56503 $this->curlInfo = $curlInfo;
 56504 }
 56505 
 56506 
 56507 
 56508 
 56509 public function getCurlInfo()
 56510 {
 56511 return $this->curlInfo;
 56512 }
 56513 }
 56514 <?php
 56515 
 56516 
 56517 
 56518 
 56519 
 56520 
 56521 
 56522 
 56523 
 56524 
 56525 
 56526 namespace Composer\Util\Http;
 56527 
 56528 
 56529 
 56530 
 56531 
 56532 
 56533 
 56534 class ProxyHelper
 56535 {
 56536 
 56537 
 56538 
 56539 
 56540 
 56541 
 56542 
 56543 public static function getProxyData()
 56544 {
 56545 $httpProxy = null;
 56546 $httpsProxy = null;
 56547 
 56548 
 56549 if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
 56550 if ($env = self::getProxyEnv(array('http_proxy', 'HTTP_PROXY'), $name)) {
 56551 $httpProxy = self::checkProxy($env, $name);
 56552 }
 56553 }
 56554 
 56555 
 56556 if ($env = self::getProxyEnv(array('CGI_HTTP_PROXY'), $name)) {
 56557 $httpProxy = self::checkProxy($env, $name);
 56558 }
 56559 
 56560 
 56561 if ($env = self::getProxyEnv(array('https_proxy', 'HTTPS_PROXY'), $name)) {
 56562 $httpsProxy = self::checkProxy($env, $name);
 56563 } else {
 56564 $httpsProxy = $httpProxy;
 56565 }
 56566 
 56567 
 56568 $noProxy = self::getProxyEnv(array('no_proxy', 'NO_PROXY'), $name);
 56569 
 56570 return array($httpProxy, $httpsProxy, $noProxy);
 56571 }
 56572 
 56573 
 56574 
 56575 
 56576 
 56577 
 56578 
 56579 
 56580 public static function getContextOptions($proxyUrl)
 56581 {
 56582 $proxy = parse_url($proxyUrl);
 56583 
 56584 
 56585 $proxyUrl = self::formatParsedUrl($proxy, false);
 56586 $proxyUrl = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyUrl);
 56587 
 56588 $options['http']['proxy'] = $proxyUrl;
 56589 
 56590 
 56591 if (isset($proxy['user'])) {
 56592 $auth = rawurldecode($proxy['user']);
 56593 
 56594 if (isset($proxy['pass'])) {
 56595 $auth .= ':' . rawurldecode($proxy['pass']);
 56596 }
 56597 $auth = base64_encode($auth);
 56598 
 56599 $options['http']['header'] = "Proxy-Authorization: Basic {$auth}";
 56600 }
 56601 
 56602 return $options;
 56603 }
 56604 
 56605 
 56606 
 56607 
 56608 
 56609 
 56610 
 56611 
 56612 
 56613 public static function setRequestFullUri($requestUrl, array &$options)
 56614 {
 56615 if ('http' === parse_url($requestUrl, PHP_URL_SCHEME)) {
 56616 $options['http']['request_fulluri'] = true;
 56617 } else {
 56618 unset($options['http']['request_fulluri']);
 56619 }
 56620 }
 56621 
 56622 
 56623 
 56624 
 56625 
 56626 
 56627 
 56628 
 56629 
 56630 private static function getProxyEnv(array $names, &$name)
 56631 {
 56632 foreach ($names as $name) {
 56633 if (!empty($_SERVER[$name])) {
 56634 return $_SERVER[$name];
 56635 }
 56636 }
 56637 
 56638 return null;
 56639 }
 56640 
 56641 
 56642 
 56643 
 56644 
 56645 
 56646 
 56647 
 56648 
 56649 private static function checkProxy($proxyUrl, $envName)
 56650 {
 56651 $error = sprintf('malformed %s url', $envName);
 56652 $proxy = parse_url($proxyUrl);
 56653 
 56654 
 56655 if (!isset($proxy['host'])) {
 56656 throw new \RuntimeException($error);
 56657 }
 56658 
 56659 $proxyUrl = self::formatParsedUrl($proxy, true);
 56660 
 56661 
 56662 if (!parse_url($proxyUrl, PHP_URL_PORT)) {
 56663 throw new \RuntimeException($error);
 56664 }
 56665 
 56666 return $proxyUrl;
 56667 }
 56668 
 56669 
 56670 
 56671 
 56672 
 56673 
 56674 
 56675 
 56676 
 56677 private static function formatParsedUrl(array $proxy, $includeAuth)
 56678 {
 56679 $proxyUrl = isset($proxy['scheme']) ? strtolower($proxy['scheme']) . '://' : '';
 56680 
 56681 if ($includeAuth && isset($proxy['user'])) {
 56682 $proxyUrl .= $proxy['user'];
 56683 
 56684 if (isset($proxy['pass'])) {
 56685 $proxyUrl .= ':' . $proxy['pass'];
 56686 }
 56687 $proxyUrl .= '@';
 56688 }
 56689 
 56690 $proxyUrl .= $proxy['host'];
 56691 
 56692 if (isset($proxy['port'])) {
 56693 $proxyUrl .= ':' . $proxy['port'];
 56694 } elseif (strpos($proxyUrl, 'http://') === 0) {
 56695 $proxyUrl .= ':80';
 56696 } elseif (strpos($proxyUrl, 'https://') === 0) {
 56697 $proxyUrl .= ':443';
 56698 }
 56699 
 56700 return $proxyUrl;
 56701 }
 56702 }
 56703 <?php
 56704 
 56705 
 56706 
 56707 
 56708 
 56709 
 56710 
 56711 
 56712 
 56713 
 56714 
 56715 namespace Composer\Util\Http;
 56716 
 56717 use Composer\Downloader\TransportException;
 56718 use Composer\Util\NoProxyPattern;
 56719 use Composer\Util\Url;
 56720 
 56721 
 56722 
 56723 
 56724 
 56725 class ProxyManager
 56726 {
 56727 
 56728 private $error = null;
 56729 
 56730 private $fullProxy;
 56731 
 56732 private $safeProxy;
 56733 
 56734 private $streams;
 56735 
 56736 private $hasProxy;
 56737 
 56738 private $info = null;
 56739 
 56740 private $noProxyHandler = null;
 56741 
 56742 
 56743 private static $instance = null;
 56744 
 56745 private function __construct()
 56746 {
 56747 $this->fullProxy = $this->safeProxy = array(
 56748 'http' => null,
 56749 'https' => null,
 56750 );
 56751 
 56752 $this->streams['http'] = $this->streams['https'] = array(
 56753 'options' => null,
 56754 );
 56755 
 56756 $this->hasProxy = false;
 56757 $this->initProxyData();
 56758 }
 56759 
 56760 
 56761 
 56762 
 56763 public static function getInstance()
 56764 {
 56765 if (!self::$instance) {
 56766 self::$instance = new self();
 56767 }
 56768 
 56769 return self::$instance;
 56770 }
 56771 
 56772 
 56773 
 56774 
 56775 
 56776 
 56777 public static function reset()
 56778 {
 56779 self::$instance = null;
 56780 }
 56781 
 56782 
 56783 
 56784 
 56785 
 56786 
 56787 
 56788 public function getProxyForRequest($requestUrl)
 56789 {
 56790 if ($this->error) {
 56791 throw new TransportException('Unable to use a proxy: '.$this->error);
 56792 }
 56793 
 56794 $scheme = parse_url($requestUrl, PHP_URL_SCHEME) ?: 'http';
 56795 $proxyUrl = '';
 56796 $options = array();
 56797 $formattedProxyUrl = '';
 56798 
 56799 if ($this->hasProxy && in_array($scheme, array('http', 'https'), true) && $this->fullProxy[$scheme]) {
 56800 if ($this->noProxy($requestUrl)) {
 56801 $formattedProxyUrl = 'excluded by no_proxy';
 56802 } else {
 56803 $proxyUrl = $this->fullProxy[$scheme];
 56804 $options = $this->streams[$scheme]['options'];
 56805 ProxyHelper::setRequestFullUri($requestUrl, $options);
 56806 $formattedProxyUrl = $this->safeProxy[$scheme];
 56807 }
 56808 }
 56809 
 56810 return new RequestProxy($proxyUrl, $options, $formattedProxyUrl);
 56811 }
 56812 
 56813 
 56814 
 56815 
 56816 
 56817 
 56818 public function isProxying()
 56819 {
 56820 return $this->hasProxy;
 56821 }
 56822 
 56823 
 56824 
 56825 
 56826 
 56827 
 56828 public function getFormattedProxy()
 56829 {
 56830 return $this->hasProxy ? $this->info : $this->error;
 56831 }
 56832 
 56833 
 56834 
 56835 
 56836 
 56837 
 56838 private function initProxyData()
 56839 {
 56840 try {
 56841 list($httpProxy, $httpsProxy, $noProxy) = ProxyHelper::getProxyData();
 56842 } catch (\RuntimeException $e) {
 56843 $this->error = $e->getMessage();
 56844 
 56845 return;
 56846 }
 56847 
 56848 $info = array();
 56849 
 56850 if ($httpProxy) {
 56851 $info[] = $this->setData($httpProxy, 'http');
 56852 }
 56853 if ($httpsProxy) {
 56854 $info[] = $this->setData($httpsProxy, 'https');
 56855 }
 56856 if ($this->hasProxy) {
 56857 $this->info = implode(', ', $info);
 56858 if ($noProxy) {
 56859 $this->noProxyHandler = new NoProxyPattern($noProxy);
 56860 }
 56861 }
 56862 }
 56863 
 56864 
 56865 
 56866 
 56867 
 56868 
 56869 
 56870 
 56871 
 56872 private function setData($url, $scheme)
 56873 {
 56874 $safeProxy = Url::sanitize($url);
 56875 $this->fullProxy[$scheme] = $url;
 56876 $this->safeProxy[$scheme] = $safeProxy;
 56877 $this->streams[$scheme]['options'] = ProxyHelper::getContextOptions($url);
 56878 $this->hasProxy = true;
 56879 
 56880 return sprintf('%s=%s', $scheme, $safeProxy);
 56881 }
 56882 
 56883 
 56884 
 56885 
 56886 
 56887 
 56888 
 56889 private function noProxy($requestUrl)
 56890 {
 56891 return $this->noProxyHandler && $this->noProxyHandler->test($requestUrl);
 56892 }
 56893 }
 56894 <?php
 56895 
 56896 
 56897 
 56898 
 56899 
 56900 
 56901 
 56902 
 56903 
 56904 
 56905 
 56906 namespace Composer\Util\Http;
 56907 
 56908 use Composer\Util\Url;
 56909 
 56910 
 56911 
 56912 
 56913 
 56914 class RequestProxy
 56915 {
 56916 
 56917 private $contextOptions;
 56918 
 56919 private $isSecure;
 56920 
 56921 private $formattedUrl;
 56922 
 56923 private $url;
 56924 
 56925 
 56926 
 56927 
 56928 
 56929 
 56930 public function __construct($url, array $contextOptions, $formattedUrl)
 56931 {
 56932 $this->url = $url;
 56933 $this->contextOptions = $contextOptions;
 56934 $this->formattedUrl = $formattedUrl;
 56935 $this->isSecure = 0 === strpos($url, 'https://');
 56936 }
 56937 
 56938 
 56939 
 56940 
 56941 
 56942 
 56943 public function getContextOptions()
 56944 {
 56945 return $this->contextOptions;
 56946 }
 56947 
 56948 
 56949 
 56950 
 56951 
 56952 
 56953 
 56954 public function getFormattedUrl($format = '')
 56955 {
 56956 $result = '';
 56957 if ($this->formattedUrl) {
 56958 $format = $format ?: '%s';
 56959 $result = sprintf($format, $this->formattedUrl);
 56960 }
 56961 
 56962 return $result;
 56963 }
 56964 
 56965 
 56966 
 56967 
 56968 
 56969 
 56970 public function getUrl()
 56971 {
 56972 return $this->url;
 56973 }
 56974 
 56975 
 56976 
 56977 
 56978 
 56979 
 56980 public function isSecure()
 56981 {
 56982 return $this->isSecure;
 56983 }
 56984 }
 56985 <?php
 56986 
 56987 
 56988 
 56989 
 56990 
 56991 
 56992 
 56993 
 56994 
 56995 
 56996 
 56997 namespace Composer\Util\Http;
 56998 
 56999 use Composer\Json\JsonFile;
 57000 use Composer\Pcre\Preg;
 57001 use Composer\Util\HttpDownloader;
 57002 
 57003 
 57004 
 57005 
 57006 class Response
 57007 {
 57008 
 57009 private $request;
 57010 
 57011 private $code;
 57012 
 57013 private $headers;
 57014 
 57015 private $body;
 57016 
 57017 
 57018 
 57019 
 57020 
 57021 
 57022 
 57023 public function __construct(array $request, $code, array $headers, $body)
 57024 {
 57025 if (!isset($request['url'])) { 
 57026 throw new \LogicException('url key missing from request array');
 57027 }
 57028 $this->request = $request;
 57029 $this->code = (int) $code;
 57030 $this->headers = $headers;
 57031 $this->body = $body;
 57032 }
 57033 
 57034 
 57035 
 57036 
 57037 public function getStatusCode()
 57038 {
 57039 return $this->code;
 57040 }
 57041 
 57042 
 57043 
 57044 
 57045 public function getStatusMessage()
 57046 {
 57047 $value = null;
 57048 foreach ($this->headers as $header) {
 57049 if (Preg::isMatch('{^HTTP/\S+ \d+}i', $header)) {
 57050 
 57051 
 57052 $value = $header;
 57053 }
 57054 }
 57055 
 57056 return $value;
 57057 }
 57058 
 57059 
 57060 
 57061 
 57062 public function getHeaders()
 57063 {
 57064 return $this->headers;
 57065 }
 57066 
 57067 
 57068 
 57069 
 57070 
 57071 public function getHeader($name)
 57072 {
 57073 return self::findHeaderValue($this->headers, $name);
 57074 }
 57075 
 57076 
 57077 
 57078 
 57079 public function getBody()
 57080 {
 57081 return $this->body;
 57082 }
 57083 
 57084 
 57085 
 57086 
 57087 public function decodeJson()
 57088 {
 57089 return JsonFile::parseJson($this->body, $this->request['url']);
 57090 }
 57091 
 57092 
 57093 
 57094 
 57095 
 57096 public function collect()
 57097 {
 57098 
 57099 $this->request = $this->code = $this->headers = $this->body = null;
 57100 }
 57101 
 57102 
 57103 
 57104 
 57105 
 57106 
 57107 public static function findHeaderValue(array $headers, $name)
 57108 {
 57109 $value = null;
 57110 foreach ($headers as $header) {
 57111 if (Preg::isMatch('{^'.preg_quote($name).':\s*(.+?)\s*$}i', $header, $match)) {
 57112 $value = $match[1];
 57113 }
 57114 }
 57115 
 57116 return $value;
 57117 }
 57118 }
 57119 <?php
 57120 
 57121 
 57122 
 57123 
 57124 
 57125 
 57126 
 57127 
 57128 
 57129 
 57130 
 57131 namespace Composer\Util;
 57132 
 57133 use Composer\Config;
 57134 use Composer\IO\IOInterface;
 57135 use Composer\Downloader\TransportException;
 57136 use Composer\Pcre\Preg;
 57137 use Composer\Util\Http\Response;
 57138 use Composer\Util\Http\CurlDownloader;
 57139 use Composer\Composer;
 57140 use Composer\Package\Version\VersionParser;
 57141 use Composer\Semver\Constraint\Constraint;
 57142 use Composer\Exception\IrrecoverableDownloadException;
 57143 use React\Promise\Promise;
 57144 use React\Promise\PromiseInterface;
 57145 
 57146 
 57147 
 57148 
 57149 
 57150 
 57151 class HttpDownloader
 57152 {
 57153 const STATUS_QUEUED = 1;
 57154 const STATUS_STARTED = 2;
 57155 const STATUS_COMPLETED = 3;
 57156 const STATUS_FAILED = 4;
 57157 const STATUS_ABORTED = 5;
 57158 
 57159 
 57160 private $io;
 57161 
 57162 private $config;
 57163 
 57164 private $jobs = array();
 57165 
 57166 private $options = array();
 57167 
 57168 private $runningJobs = 0;
 57169 
 57170 private $maxJobs = 12;
 57171 
 57172 private $curl;
 57173 
 57174 private $rfs;
 57175 
 57176 private $idGen = 0;
 57177 
 57178 private $disabled;
 57179 
 57180 private $allowAsync = false;
 57181 
 57182 
 57183 
 57184 
 57185 
 57186 
 57187 
 57188 public function __construct(IOInterface $io, Config $config, array $options = array(), $disableTls = false)
 57189 {
 57190 $this->io = $io;
 57191 
 57192 $this->disabled = (bool) Platform::getEnv('COMPOSER_DISABLE_NETWORK');
 57193 
 57194 
 57195 
 57196 if ($disableTls === false) {
 57197 $this->options = StreamContextFactory::getTlsDefaults($options, $io);
 57198 }
 57199 
 57200 
 57201 $this->options = array_replace_recursive($this->options, $options);
 57202 $this->config = $config;
 57203 
 57204 if (self::isCurlEnabled()) {
 57205 $this->curl = new CurlDownloader($io, $config, $options, $disableTls);
 57206 }
 57207 
 57208 $this->rfs = new RemoteFilesystem($io, $config, $options, $disableTls);
 57209 
 57210 if (is_numeric($maxJobs = Platform::getEnv('COMPOSER_MAX_PARALLEL_HTTP'))) {
 57211 $this->maxJobs = max(1, min(50, (int) $maxJobs));
 57212 }
 57213 }
 57214 
 57215 
 57216 
 57217 
 57218 
 57219 
 57220 
 57221 
 57222 
 57223 
 57224 public function get($url, $options = array())
 57225 {
 57226 list($job) = $this->addJob(array('url' => $url, 'options' => $options, 'copyTo' => null), true);
 57227 $this->wait($job['id']);
 57228 
 57229 $response = $this->getResponse($job['id']);
 57230 
 57231 
 57232 if (
 57233 $this->curl
 57234 && PHP_VERSION_ID < 70000
 57235 && $response->getBody() === null
 57236 && $response->getStatusCode() === 200
 57237 && $response->getHeader('content-length') !== '0'
 57238 ) {
 57239 $this->io->writeError('<warning>cURL downloader failed to return a response, disabling it and proceeding in slow mode.</warning>');
 57240 
 57241 $this->curl = null;
 57242 
 57243 list($job) = $this->addJob(array('url' => $url, 'options' => $options, 'copyTo' => null), true);
 57244 $this->wait($job['id']);
 57245 
 57246 $response = $this->getResponse($job['id']);
 57247 }
 57248 
 57249 return $response;
 57250 }
 57251 
 57252 
 57253 
 57254 
 57255 
 57256 
 57257 
 57258 
 57259 
 57260 
 57261 public function add($url, $options = array())
 57262 {
 57263 list(, $promise) = $this->addJob(array('url' => $url, 'options' => $options, 'copyTo' => null));
 57264 
 57265 return $promise;
 57266 }
 57267 
 57268 
 57269 
 57270 
 57271 
 57272 
 57273 
 57274 
 57275 
 57276 
 57277 
 57278 public function copy($url, $to, $options = array())
 57279 {
 57280 list($job) = $this->addJob(array('url' => $url, 'options' => $options, 'copyTo' => $to), true);
 57281 $this->wait($job['id']);
 57282 
 57283 return $this->getResponse($job['id']);
 57284 }
 57285 
 57286 
 57287 
 57288 
 57289 
 57290 
 57291 
 57292 
 57293 
 57294 
 57295 
 57296 public function addCopy($url, $to, $options = array())
 57297 {
 57298 list(, $promise) = $this->addJob(array('url' => $url, 'options' => $options, 'copyTo' => $to));
 57299 
 57300 return $promise;
 57301 }
 57302 
 57303 
 57304 
 57305 
 57306 
 57307 
 57308 public function getOptions()
 57309 {
 57310 return $this->options;
 57311 }
 57312 
 57313 
 57314 
 57315 
 57316 
 57317 
 57318 
 57319 public function setOptions(array $options)
 57320 {
 57321 $this->options = array_replace_recursive($this->options, $options);
 57322 }
 57323 
 57324 
 57325 
 57326 
 57327 
 57328 
 57329 
 57330 private function addJob($request, $sync = false)
 57331 {
 57332 $request['options'] = array_replace_recursive($this->options, $request['options']);
 57333 
 57334 
 57335 $job = array(
 57336 'id' => $this->idGen++,
 57337 'status' => self::STATUS_QUEUED,
 57338 'request' => $request,
 57339 'sync' => $sync,
 57340 'origin' => Url::getOrigin($this->config, $request['url']),
 57341 );
 57342 
 57343 if (!$sync && !$this->allowAsync) {
 57344 throw new \LogicException('You must use the HttpDownloader instance which is part of a Composer\Loop instance to be able to run async http requests');
 57345 }
 57346 
 57347 
 57348 if (Preg::isMatch('{^https?://([^:/]+):([^@/]+)@([^/]+)}i', $request['url'], $match)) {
 57349 $this->io->setAuthentication($job['origin'], rawurldecode($match[1]), rawurldecode($match[2]));
 57350 }
 57351 
 57352 $rfs = $this->rfs;
 57353 
 57354 if ($this->canUseCurl($job)) {
 57355 $resolver = function ($resolve, $reject) use (&$job) {
 57356 $job['status'] = HttpDownloader::STATUS_QUEUED;
 57357 $job['resolve'] = $resolve;
 57358 $job['reject'] = $reject;
 57359 };
 57360 } else {
 57361 $resolver = function ($resolve, $reject) use (&$job, $rfs) {
 57362 
 57363 $url = $job['request']['url'];
 57364 $options = $job['request']['options'];
 57365 
 57366 $job['status'] = HttpDownloader::STATUS_STARTED;
 57367 
 57368 if ($job['request']['copyTo']) {
 57369 $rfs->copy($job['origin'], $url, $job['request']['copyTo'], false , $options);
 57370 
 57371 $headers = $rfs->getLastHeaders();
 57372 $response = new Http\Response($job['request'], $rfs->findStatusCode($headers), $headers, $job['request']['copyTo'].'~');
 57373 
 57374 $resolve($response);
 57375 } else {
 57376 $body = $rfs->getContents($job['origin'], $url, false , $options);
 57377 $headers = $rfs->getLastHeaders();
 57378 $response = new Http\Response($job['request'], $rfs->findStatusCode($headers), $headers, $body);
 57379 
 57380 $resolve($response);
 57381 }
 57382 };
 57383 }
 57384 
 57385 $downloader = $this;
 57386 $curl = $this->curl;
 57387 
 57388 $canceler = function () use (&$job, $curl) {
 57389 if ($job['status'] === HttpDownloader::STATUS_QUEUED) {
 57390 $job['status'] = HttpDownloader::STATUS_ABORTED;
 57391 }
 57392 if ($job['status'] !== HttpDownloader::STATUS_STARTED) {
 57393 return;
 57394 }
 57395 $job['status'] = HttpDownloader::STATUS_ABORTED;
 57396 if (isset($job['curl_id'])) {
 57397 $curl->abortRequest($job['curl_id']);
 57398 }
 57399 throw new IrrecoverableDownloadException('Download of ' . Url::sanitize($job['request']['url']) . ' canceled');
 57400 };
 57401 
 57402 $promise = new Promise($resolver, $canceler);
 57403 $promise = $promise->then(function ($response) use (&$job, $downloader) {
 57404 $job['status'] = HttpDownloader::STATUS_COMPLETED;
 57405 $job['response'] = $response;
 57406 
 57407 
 57408 $downloader->markJobDone();
 57409 
 57410 return $response;
 57411 }, function ($e) use (&$job, $downloader) {
 57412 $job['status'] = HttpDownloader::STATUS_FAILED;
 57413 $job['exception'] = $e;
 57414 
 57415 $downloader->markJobDone();
 57416 
 57417 throw $e;
 57418 });
 57419 $this->jobs[$job['id']] = &$job;
 57420 
 57421 if ($this->runningJobs < $this->maxJobs) {
 57422 $this->startJob($job['id']);
 57423 }
 57424 
 57425 return array($job, $promise);
 57426 }
 57427 
 57428 
 57429 
 57430 
 57431 
 57432 private function startJob($id)
 57433 {
 57434 $job = &$this->jobs[$id];
 57435 if ($job['status'] !== self::STATUS_QUEUED) {
 57436 return;
 57437 }
 57438 
 57439 
 57440 $job['status'] = self::STATUS_STARTED;
 57441 $this->runningJobs++;
 57442 
 57443 $resolve = $job['resolve'];
 57444 $reject = $job['reject'];
 57445 $url = $job['request']['url'];
 57446 $options = $job['request']['options'];
 57447 $origin = $job['origin'];
 57448 
 57449 if ($this->disabled) {
 57450 if (isset($job['request']['options']['http']['header']) && false !== stripos(implode('', $job['request']['options']['http']['header']), 'if-modified-since')) {
 57451 $resolve(new Response(array('url' => $url), 304, array(), ''));
 57452 } else {
 57453 $e = new TransportException('Network disabled, request canceled: '.Url::sanitize($url), 499);
 57454 $e->setStatusCode(499);
 57455 $reject($e);
 57456 }
 57457 
 57458 return;
 57459 }
 57460 
 57461 try {
 57462 if ($job['request']['copyTo']) {
 57463 $job['curl_id'] = $this->curl->download($resolve, $reject, $origin, $url, $options, $job['request']['copyTo']);
 57464 } else {
 57465 $job['curl_id'] = $this->curl->download($resolve, $reject, $origin, $url, $options);
 57466 }
 57467 } catch (\Exception $exception) {
 57468 $reject($exception);
 57469 }
 57470 }
 57471 
 57472 
 57473 
 57474 
 57475 
 57476 public function markJobDone()
 57477 {
 57478 $this->runningJobs--;
 57479 }
 57480 
 57481 
 57482 
 57483 
 57484 
 57485 
 57486 
 57487 
 57488 public function wait($index = null)
 57489 {
 57490 do {
 57491 $jobCount = $this->countActiveJobs($index);
 57492 } while ($jobCount);
 57493 }
 57494 
 57495 
 57496 
 57497 
 57498 
 57499 
 57500 public function enableAsync()
 57501 {
 57502 $this->allowAsync = true;
 57503 }
 57504 
 57505 
 57506 
 57507 
 57508 
 57509 
 57510 
 57511 public function countActiveJobs($index = null)
 57512 {
 57513 if ($this->runningJobs < $this->maxJobs) {
 57514 foreach ($this->jobs as $job) {
 57515 if ($job['status'] === self::STATUS_QUEUED && $this->runningJobs < $this->maxJobs) {
 57516 $this->startJob($job['id']);
 57517 }
 57518 }
 57519 }
 57520 
 57521 if ($this->curl) {
 57522 $this->curl->tick();
 57523 }
 57524 
 57525 if (null !== $index) {
 57526 return $this->jobs[$index]['status'] < self::STATUS_COMPLETED ? 1 : 0;
 57527 }
 57528 
 57529 $active = 0;
 57530 foreach ($this->jobs as $job) {
 57531 if ($job['status'] < self::STATUS_COMPLETED) {
 57532 $active++;
 57533 } elseif (!$job['sync']) {
 57534 unset($this->jobs[$job['id']]);
 57535 }
 57536 }
 57537 
 57538 return $active;
 57539 }
 57540 
 57541 
 57542 
 57543 
 57544 
 57545 private function getResponse($index)
 57546 {
 57547 if (!isset($this->jobs[$index])) {
 57548 throw new \LogicException('Invalid request id');
 57549 }
 57550 
 57551 if ($this->jobs[$index]['status'] === self::STATUS_FAILED) {
 57552 throw $this->jobs[$index]['exception'];
 57553 }
 57554 
 57555 if (!isset($this->jobs[$index]['response'])) {
 57556 throw new \LogicException('Response not available yet, call wait() first');
 57557 }
 57558 
 57559 $resp = $this->jobs[$index]['response'];
 57560 
 57561 unset($this->jobs[$index]);
 57562 
 57563 return $resp;
 57564 }
 57565 
 57566 
 57567 
 57568 
 57569 
 57570 
 57571 
 57572 
 57573 public static function outputWarnings(IOInterface $io, $url, $data)
 57574 {
 57575 $cleanMessage = function ($msg) use ($io) {
 57576 if (!$io->isDecorated()) {
 57577 $msg = Preg::replace('{'.chr(27).'\\[[;\d]*m}u', '', $msg);
 57578 }
 57579 
 57580 return $msg;
 57581 };
 57582 
 57583 
 57584 foreach (array('warning', 'info') as $type) {
 57585 if (empty($data[$type])) {
 57586 continue;
 57587 }
 57588 
 57589 if (!empty($data[$type . '-versions'])) {
 57590 $versionParser = new VersionParser();
 57591 $constraint = $versionParser->parseConstraints($data[$type . '-versions']);
 57592 $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion()));
 57593 if (!$constraint->matches($composer)) {
 57594 continue;
 57595 }
 57596 }
 57597 
 57598 $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$cleanMessage($data[$type]).'</'.$type.'>');
 57599 }
 57600 
 57601 
 57602 foreach (array('warnings', 'infos') as $key) {
 57603 if (empty($data[$key])) {
 57604 continue;
 57605 }
 57606 
 57607 $versionParser = new VersionParser();
 57608 foreach ($data[$key] as $spec) {
 57609 $type = substr($key, 0, -1);
 57610 $constraint = $versionParser->parseConstraints($spec['versions']);
 57611 $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion()));
 57612 if (!$constraint->matches($composer)) {
 57613 continue;
 57614 }
 57615 
 57616 $io->writeError('<'.$type.'>'.ucfirst($type).' from '.Url::sanitize($url).': '.$cleanMessage($spec['message']).'</'.$type.'>');
 57617 }
 57618 }
 57619 }
 57620 
 57621 
 57622 
 57623 
 57624 
 57625 
 57626 public static function getExceptionHints(\Exception $e)
 57627 {
 57628 if (!$e instanceof TransportException) {
 57629 return null;
 57630 }
 57631 
 57632 if (
 57633 false !== strpos($e->getMessage(), 'Resolving timed out')
 57634 || false !== strpos($e->getMessage(), 'Could not resolve host')
 57635 ) {
 57636 Silencer::suppress();
 57637 $testConnectivity = file_get_contents('https://8.8.8.8', false, stream_context_create(array(
 57638 'ssl' => array('verify_peer' => false),
 57639 'http' => array('follow_location' => false, 'ignore_errors' => true),
 57640 )));
 57641 Silencer::restore();
 57642 if (false !== $testConnectivity) {
 57643 return array(
 57644 '<error>The following exception probably indicates you have misconfigured DNS resolver(s)</error>',
 57645 );
 57646 }
 57647 
 57648 return array(
 57649 '<error>The following exception probably indicates you are offline or have misconfigured DNS resolver(s)</error>',
 57650 );
 57651 }
 57652 
 57653 return null;
 57654 }
 57655 
 57656 
 57657 
 57658 
 57659 
 57660 private function canUseCurl(array $job)
 57661 {
 57662 if (!$this->curl) {
 57663 return false;
 57664 }
 57665 
 57666 if (!Preg::isMatch('{^https?://}i', $job['request']['url'])) {
 57667 return false;
 57668 }
 57669 
 57670 if (!empty($job['request']['options']['ssl']['allow_self_signed'])) {
 57671 return false;
 57672 }
 57673 
 57674 return true;
 57675 }
 57676 
 57677 
 57678 
 57679 
 57680 
 57681 public static function isCurlEnabled()
 57682 {
 57683 return \extension_loaded('curl') && \function_exists('curl_multi_exec') && \function_exists('curl_multi_init');
 57684 }
 57685 }
 57686 <?php
 57687 
 57688 
 57689 
 57690 
 57691 
 57692 
 57693 
 57694 
 57695 
 57696 
 57697 
 57698 namespace Composer\Util;
 57699 
 57700 use Composer\XdebugHandler\XdebugHandler;
 57701 
 57702 
 57703 
 57704 
 57705 
 57706 
 57707 
 57708 
 57709 class IniHelper
 57710 {
 57711 
 57712 
 57713 
 57714 
 57715 
 57716 
 57717 
 57718 
 57719 public static function getAll()
 57720 {
 57721 return XdebugHandler::getAllIniFiles();
 57722 }
 57723 
 57724 
 57725 
 57726 
 57727 
 57728 
 57729 public static function getMessage()
 57730 {
 57731 $paths = self::getAll();
 57732 
 57733 if (empty($paths[0])) {
 57734 array_shift($paths);
 57735 }
 57736 
 57737 $ini = array_shift($paths);
 57738 
 57739 if (empty($ini)) {
 57740 return 'A php.ini file does not exist. You will have to create one.';
 57741 }
 57742 
 57743 if (!empty($paths)) {
 57744 return 'Your command-line PHP is using multiple ini files. Run `php --ini` to show them.';
 57745 }
 57746 
 57747 return 'The php.ini used by your command-line PHP is: '.$ini;
 57748 }
 57749 }
 57750 <?php
 57751 
 57752 
 57753 
 57754 
 57755 
 57756 
 57757 
 57758 
 57759 
 57760 
 57761 
 57762 namespace Composer\Util;
 57763 
 57764 use React\Promise\CancellablePromiseInterface;
 57765 use Symfony\Component\Console\Helper\ProgressBar;
 57766 use React\Promise\PromiseInterface;
 57767 
 57768 
 57769 
 57770 
 57771 class Loop
 57772 {
 57773 
 57774 private $httpDownloader;
 57775 
 57776 private $processExecutor;
 57777 
 57778 private $currentPromises = array();
 57779 
 57780 private $waitIndex = 0;
 57781 
 57782 public function __construct(HttpDownloader $httpDownloader, ProcessExecutor $processExecutor = null)
 57783 {
 57784 $this->httpDownloader = $httpDownloader;
 57785 $this->httpDownloader->enableAsync();
 57786 
 57787 $this->processExecutor = $processExecutor;
 57788 if ($this->processExecutor) {
 57789 $this->processExecutor->enableAsync();
 57790 }
 57791 }
 57792 
 57793 
 57794 
 57795 
 57796 public function getHttpDownloader()
 57797 {
 57798 return $this->httpDownloader;
 57799 }
 57800 
 57801 
 57802 
 57803 
 57804 public function getProcessExecutor()
 57805 {
 57806 return $this->processExecutor;
 57807 }
 57808 
 57809 
 57810 
 57811 
 57812 
 57813 
 57814 public function wait(array $promises, ProgressBar $progress = null)
 57815 {
 57816 
 57817 $uncaught = null;
 57818 
 57819 \React\Promise\all($promises)->then(
 57820 function () {
 57821 },
 57822 function ($e) use (&$uncaught) {
 57823 $uncaught = $e;
 57824 }
 57825 );
 57826 
 57827 
 57828 
 57829 $waitIndex = $this->waitIndex++;
 57830 $this->currentPromises[$waitIndex] = $promises;
 57831 
 57832 if ($progress) {
 57833 $totalJobs = 0;
 57834 $totalJobs += $this->httpDownloader->countActiveJobs();
 57835 if ($this->processExecutor) {
 57836 $totalJobs += $this->processExecutor->countActiveJobs();
 57837 }
 57838 $progress->start($totalJobs);
 57839 }
 57840 
 57841 $lastUpdate = 0;
 57842 while (true) {
 57843 $activeJobs = 0;
 57844 
 57845 $activeJobs += $this->httpDownloader->countActiveJobs();
 57846 if ($this->processExecutor) {
 57847 $activeJobs += $this->processExecutor->countActiveJobs();
 57848 }
 57849 
 57850 if ($progress && microtime(true) - $lastUpdate > 0.1) {
 57851 $lastUpdate = microtime(true);
 57852 $progress->setProgress($progress->getMaxSteps() - $activeJobs);
 57853 }
 57854 
 57855 if (!$activeJobs) {
 57856 break;
 57857 }
 57858 }
 57859 
 57860 
 57861 if ($progress) {
 57862 $progress->finish();
 57863 }
 57864 
 57865 unset($this->currentPromises[$waitIndex]);
 57866 if ($uncaught) {
 57867 throw $uncaught;
 57868 }
 57869 }
 57870 
 57871 
 57872 
 57873 
 57874 public function abortJobs()
 57875 {
 57876 foreach ($this->currentPromises as $promiseGroup) {
 57877 foreach ($promiseGroup as $promise) {
 57878 if ($promise instanceof CancellablePromiseInterface) {
 57879 $promise->cancel();
 57880 }
 57881 }
 57882 }
 57883 }
 57884 }
 57885 <?php
 57886 
 57887 
 57888 
 57889 
 57890 
 57891 
 57892 
 57893 
 57894 
 57895 
 57896 
 57897 namespace Composer\Util;
 57898 
 57899 @trigger_error('Composer\Util\MetadataMinifier is deprecated, use Composer\MetadataMinifier\MetadataMinifier from composer/metadata-minifier instead.', E_USER_DEPRECATED);
 57900 
 57901 
 57902 
 57903 
 57904 class MetadataMinifier extends \Composer\MetadataMinifier\MetadataMinifier
 57905 {
 57906 }
 57907 <?php
 57908 
 57909 
 57910 
 57911 
 57912 
 57913 
 57914 
 57915 
 57916 
 57917 
 57918 
 57919 namespace Composer\Util;
 57920 
 57921 use Composer\Pcre\Preg;
 57922 use stdClass;
 57923 
 57924 
 57925 
 57926 
 57927 class NoProxyPattern
 57928 {
 57929 
 57930 
 57931 
 57932 protected $hostNames = array();
 57933 
 57934 
 57935 
 57936 
 57937 protected $rules = array();
 57938 
 57939 
 57940 
 57941 
 57942 protected $noproxy;
 57943 
 57944 
 57945 
 57946 
 57947 public function __construct($pattern)
 57948 {
 57949 $this->hostNames = Preg::split('{[\s,]+}', $pattern, -1, PREG_SPLIT_NO_EMPTY);
 57950 $this->noproxy = empty($this->hostNames) || '*' === $this->hostNames[0];
 57951 }
 57952 
 57953 
 57954 
 57955 
 57956 
 57957 
 57958 
 57959 
 57960 public function test($url)
 57961 {
 57962 if ($this->noproxy) {
 57963 return true;
 57964 }
 57965 
 57966 if (!$urlData = $this->getUrlData($url)) {
 57967 return false;
 57968 }
 57969 
 57970 foreach ($this->hostNames as $index => $hostName) {
 57971 if ($this->match($index, $hostName, $urlData)) {
 57972 return true;
 57973 }
 57974 }
 57975 
 57976 return false;
 57977 }
 57978 
 57979 
 57980 
 57981 
 57982 
 57983 
 57984 
 57985 
 57986 protected function getUrlData($url)
 57987 {
 57988 if (!$host = parse_url($url, PHP_URL_HOST)) {
 57989 return false;
 57990 }
 57991 
 57992 $port = parse_url($url, PHP_URL_PORT);
 57993 
 57994 if (empty($port)) {
 57995 switch (parse_url($url, PHP_URL_SCHEME)) {
 57996 case 'http':
 57997 $port = 80;
 57998 break;
 57999 case 'https':
 58000 $port = 443;
 58001 break;
 58002 }
 58003 }
 58004 
 58005 $hostName = $host . ($port ? ':' . $port : '');
 58006 list($host, $port, $err) = $this->splitHostPort($hostName);
 58007 
 58008 if ($err || !$this->ipCheckData($host, $ipdata)) {
 58009 return false;
 58010 }
 58011 
 58012 return $this->makeData($host, $port, $ipdata);
 58013 }
 58014 
 58015 
 58016 
 58017 
 58018 
 58019 
 58020 
 58021 
 58022 
 58023 
 58024 protected function match($index, $hostName, $url)
 58025 {
 58026 if (!$rule = $this->getRule($index, $hostName)) {
 58027 
 58028 return false;
 58029 }
 58030 
 58031 if ($rule->ipdata) {
 58032 
 58033 if (!$url->ipdata) {
 58034 return false;
 58035 }
 58036 
 58037 if ($rule->ipdata->netmask) {
 58038 return $this->matchRange($rule->ipdata, $url->ipdata);
 58039 }
 58040 
 58041 $match = $rule->ipdata->ip === $url->ipdata->ip;
 58042 } else {
 58043 
 58044 $haystack = substr($url->name, -strlen($rule->name));
 58045 $match = stripos($haystack, $rule->name) === 0;
 58046 }
 58047 
 58048 if ($match && $rule->port) {
 58049 $match = $rule->port === $url->port;
 58050 }
 58051 
 58052 return $match;
 58053 }
 58054 
 58055 
 58056 
 58057 
 58058 
 58059 
 58060 
 58061 
 58062 
 58063 protected function matchRange(stdClass $network, stdClass $target)
 58064 {
 58065 $net = unpack('C*', $network->ip);
 58066 $mask = unpack('C*', $network->netmask);
 58067 $ip = unpack('C*', $target->ip);
 58068 if (false === $net) {
 58069 throw new \RuntimeException('Could not parse network IP '.$network->ip);
 58070 }
 58071 if (false === $mask) {
 58072 throw new \RuntimeException('Could not parse netmask '.$network->netmask);
 58073 }
 58074 if (false === $ip) {
 58075 throw new \RuntimeException('Could not parse target IP '.$target->ip);
 58076 }
 58077 
 58078 for ($i = 1; $i < 17; ++$i) {
 58079 if (($net[$i] & $mask[$i]) !== ($ip[$i] & $mask[$i])) {
 58080 return false;
 58081 }
 58082 }
 58083 
 58084 return true;
 58085 }
 58086 
 58087 
 58088 
 58089 
 58090 
 58091 
 58092 
 58093 
 58094 
 58095 private function getRule($index, $hostName)
 58096 {
 58097 if (array_key_exists($index, $this->rules)) {
 58098 return $this->rules[$index];
 58099 }
 58100 
 58101 $this->rules[$index] = null;
 58102 list($host, $port, $err) = $this->splitHostPort($hostName);
 58103 
 58104 if ($err || !$this->ipCheckData($host, $ipdata, true)) {
 58105 return null;
 58106 }
 58107 
 58108 $this->rules[$index] = $this->makeData($host, $port, $ipdata);
 58109 
 58110 return $this->rules[$index];
 58111 }
 58112 
 58113 
 58114 
 58115 
 58116 
 58117 
 58118 
 58119 
 58120 
 58121 
 58122 private function ipCheckData($host, &$ipdata, $allowPrefix = false)
 58123 {
 58124 $ipdata = null;
 58125 $netmask = null;
 58126 $prefix = null;
 58127 $modified = false;
 58128 
 58129 
 58130 if (strpos($host, '/') !== false) {
 58131 list($host, $prefix) = explode('/', $host);
 58132 
 58133 if (!$allowPrefix || !$this->validateInt($prefix, 0, 128)) {
 58134 return false;
 58135 }
 58136 $prefix = (int) $prefix;
 58137 $modified = true;
 58138 }
 58139 
 58140 
 58141 if (!filter_var($host, FILTER_VALIDATE_IP)) {
 58142 return !$modified;
 58143 }
 58144 
 58145 list($ip, $size) = $this->ipGetAddr($host);
 58146 
 58147 if ($prefix !== null) {
 58148 
 58149 if ($prefix > $size * 8) {
 58150 return false;
 58151 }
 58152 
 58153 list($ip, $netmask) = $this->ipGetNetwork($ip, $size, $prefix);
 58154 }
 58155 
 58156 $ipdata = $this->makeIpData($ip, $size, $netmask);
 58157 
 58158 return true;
 58159 }
 58160 
 58161 
 58162 
 58163 
 58164 
 58165 
 58166 
 58167 
 58168 
 58169 
 58170 
 58171 private function ipGetAddr($host)
 58172 {
 58173 $ip = inet_pton($host);
 58174 $size = strlen($ip);
 58175 $mapped = $this->ipMapTo6($ip, $size);
 58176 
 58177 return array($mapped, $size);
 58178 }
 58179 
 58180 
 58181 
 58182 
 58183 
 58184 
 58185 
 58186 
 58187 
 58188 private function ipGetMask($prefix, $size)
 58189 {
 58190 $mask = '';
 58191 
 58192 if ($ones = floor($prefix / 8)) {
 58193 $mask = str_repeat(chr(255), (int) $ones);
 58194 }
 58195 
 58196 if ($remainder = $prefix % 8) {
 58197 $mask .= chr(0xff ^ (0xff >> $remainder));
 58198 }
 58199 
 58200 $mask = str_pad($mask, $size, chr(0));
 58201 
 58202 return $this->ipMapTo6($mask, $size);
 58203 }
 58204 
 58205 
 58206 
 58207 
 58208 
 58209 
 58210 
 58211 
 58212 
 58213 
 58214 private function ipGetNetwork($rangeIp, $size, $prefix)
 58215 {
 58216 $netmask = $this->ipGetMask($prefix, $size);
 58217 
 58218 
 58219 $mask = unpack('C*', $netmask);
 58220 $ip = unpack('C*', $rangeIp);
 58221 $net = '';
 58222 if (false === $mask) {
 58223 throw new \RuntimeException('Could not parse netmask '.$netmask);
 58224 }
 58225 if (false === $ip) {
 58226 throw new \RuntimeException('Could not parse range IP '.$rangeIp);
 58227 }
 58228 
 58229 for ($i = 1; $i < 17; ++$i) {
 58230 $net .= chr($ip[$i] & $mask[$i]);
 58231 }
 58232 
 58233 return array($net, $netmask);
 58234 }
 58235 
 58236 
 58237 
 58238 
 58239 
 58240 
 58241 
 58242 
 58243 
 58244 private function ipMapTo6($binary, $size)
 58245 {
 58246 if ($size === 4) {
 58247 $prefix = str_repeat(chr(0), 10) . str_repeat(chr(255), 2);
 58248 $binary = $prefix . $binary;
 58249 }
 58250 
 58251 return $binary;
 58252 }
 58253 
 58254 
 58255 
 58256 
 58257 
 58258 
 58259 
 58260 
 58261 
 58262 
 58263 private function makeData($host, $port, $ipdata)
 58264 {
 58265 return (object) array(
 58266 'host' => $host,
 58267 'name' => '.' . ltrim($host, '.'),
 58268 'port' => $port,
 58269 'ipdata' => $ipdata,
 58270 );
 58271 }
 58272 
 58273 
 58274 
 58275 
 58276 
 58277 
 58278 
 58279 
 58280 
 58281 
 58282 private function makeIpData($ip, $size, $netmask)
 58283 {
 58284 return (object) array(
 58285 'ip' => $ip,
 58286 'size' => $size,
 58287 'netmask' => $netmask,
 58288 );
 58289 }
 58290 
 58291 
 58292 
 58293 
 58294 
 58295 
 58296 
 58297 
 58298 private function splitHostPort($hostName)
 58299 {
 58300 
 58301 $error = array('', '', true);
 58302 $port = 0;
 58303 $ip6 = '';
 58304 
 58305 
 58306 if ($hostName[0] === '[') {
 58307 $index = strpos($hostName, ']');
 58308 
 58309 
 58310 if (false === $index || $index < 3) {
 58311 return $error;
 58312 }
 58313 
 58314 $ip6 = substr($hostName, 1, $index - 1);
 58315 $hostName = substr($hostName, $index + 1);
 58316 
 58317 if (strpbrk($hostName, '[]') !== false || substr_count($hostName, ':') > 1) {
 58318 return $error;
 58319 }
 58320 }
 58321 
 58322 if (substr_count($hostName, ':') === 1) {
 58323 $index = strpos($hostName, ':');
 58324 $port = substr($hostName, $index + 1);
 58325 $hostName = substr($hostName, 0, $index);
 58326 
 58327 if (!$this->validateInt($port, 1, 65535)) {
 58328 return $error;
 58329 }
 58330 
 58331 $port = (int) $port;
 58332 }
 58333 
 58334 $host = $ip6 . $hostName;
 58335 
 58336 return array($host, $port, false);
 58337 }
 58338 
 58339 
 58340 
 58341 
 58342 
 58343 
 58344 
 58345 
 58346 
 58347 
 58348 private function validateInt($int, $min, $max)
 58349 {
 58350 $options = array(
 58351 'options' => array(
 58352 'min_range' => $min,
 58353 'max_range' => $max,
 58354 ),
 58355 );
 58356 
 58357 return false !== filter_var($int, FILTER_VALIDATE_INT, $options);
 58358 }
 58359 }
 58360 <?php
 58361 
 58362 
 58363 
 58364 
 58365 
 58366 
 58367 
 58368 
 58369 
 58370 
 58371 
 58372 namespace Composer\Util;
 58373 
 58374 use Composer\Package\PackageInterface;
 58375 use Composer\Package\RootPackageInterface;
 58376 
 58377 class PackageSorter
 58378 {
 58379 
 58380 
 58381 
 58382 
 58383 
 58384 
 58385 
 58386 
 58387 
 58388 public static function sortPackages(array $packages, array $weights = array())
 58389 {
 58390 $usageList = array();
 58391 
 58392 foreach ($packages as $package) {
 58393 $links = $package->getRequires();
 58394 if ($package instanceof RootPackageInterface) {
 58395 $links = array_merge($links, $package->getDevRequires());
 58396 }
 58397 foreach ($links as $link) {
 58398 $target = $link->getTarget();
 58399 $usageList[$target][] = $package->getName();
 58400 }
 58401 }
 58402 $computing = array();
 58403 $computed = array();
 58404 $computeImportance = function ($name) use (&$computeImportance, &$computing, &$computed, $usageList, $weights) {
 58405 
 58406 if (isset($computed[$name])) {
 58407 return $computed[$name];
 58408 }
 58409 
 58410 
 58411 if (isset($computing[$name])) {
 58412 return 0;
 58413 }
 58414 
 58415 $computing[$name] = true;
 58416 $weight = isset($weights[$name]) ? $weights[$name] : 0;
 58417 
 58418 if (isset($usageList[$name])) {
 58419 foreach ($usageList[$name] as $user) {
 58420 $weight -= 1 - $computeImportance($user);
 58421 }
 58422 }
 58423 
 58424 unset($computing[$name]);
 58425 $computed[$name] = $weight;
 58426 
 58427 return $weight;
 58428 };
 58429 
 58430 $weightedPackages = array();
 58431 
 58432 foreach ($packages as $index => $package) {
 58433 $name = $package->getName();
 58434 $weight = $computeImportance($name);
 58435 $weightedPackages[] = array('name' => $name, 'weight' => $weight, 'index' => $index);
 58436 }
 58437 
 58438 usort($weightedPackages, function ($a, $b) {
 58439 if ($a['weight'] !== $b['weight']) {
 58440 return $a['weight'] - $b['weight'];
 58441 }
 58442 
 58443 return strnatcasecmp($a['name'], $b['name']);
 58444 });
 58445 
 58446 $sortedPackages = array();
 58447 
 58448 foreach ($weightedPackages as $pkg) {
 58449 $sortedPackages[] = $packages[$pkg['index']];
 58450 }
 58451 
 58452 return $sortedPackages;
 58453 }
 58454 }
 58455 <?php
 58456 
 58457 
 58458 
 58459 
 58460 
 58461 
 58462 
 58463 
 58464 
 58465 
 58466 
 58467 namespace Composer\Util;
 58468 
 58469 use Composer\IO\IOInterface;
 58470 use Composer\Pcre\Preg;
 58471 use Symfony\Component\Process\Process;
 58472 
 58473 
 58474 
 58475 
 58476 
 58477 
 58478 class Perforce
 58479 {
 58480 
 58481 protected $path;
 58482 
 58483 protected $p4Depot;
 58484 
 58485 protected $p4Client;
 58486 
 58487 protected $p4User;
 58488 
 58489 protected $p4Password;
 58490 
 58491 protected $p4Port;
 58492 
 58493 protected $p4Stream;
 58494 
 58495 protected $p4ClientSpec;
 58496 
 58497 protected $p4DepotType;
 58498 
 58499 protected $p4Branch;
 58500 
 58501 protected $process;
 58502 
 58503 protected $uniquePerforceClientName;
 58504 
 58505 protected $windowsFlag;
 58506 
 58507 protected $commandResult;
 58508 
 58509 
 58510 protected $io;
 58511 
 58512 
 58513 protected $filesystem;
 58514 
 58515 
 58516 
 58517 
 58518 
 58519 
 58520 
 58521 
 58522 
 58523 public function __construct($repoConfig, $port, $path, ProcessExecutor $process, $isWindows, IOInterface $io)
 58524 {
 58525 $this->windowsFlag = $isWindows;
 58526 $this->p4Port = $port;
 58527 $this->initializePath($path);
 58528 $this->process = $process;
 58529 $this->initialize($repoConfig);
 58530 $this->io = $io;
 58531 }
 58532 
 58533 
 58534 
 58535 
 58536 
 58537 
 58538 
 58539 
 58540 
 58541 
 58542 public static function create($repoConfig, $port, $path, ProcessExecutor $process, IOInterface $io)
 58543 {
 58544 return new Perforce($repoConfig, $port, $path, $process, Platform::isWindows(), $io);
 58545 }
 58546 
 58547 
 58548 
 58549 
 58550 
 58551 
 58552 
 58553 public static function checkServerExists($url, ProcessExecutor $processExecutor)
 58554 {
 58555 $output = null;
 58556 
 58557 return 0 === $processExecutor->execute('p4 -p ' . ProcessExecutor::escape($url) . ' info -s', $output);
 58558 }
 58559 
 58560 
 58561 
 58562 
 58563 
 58564 
 58565 public function initialize($repoConfig)
 58566 {
 58567 $this->uniquePerforceClientName = $this->generateUniquePerforceClientName();
 58568 if (!$repoConfig) {
 58569 return;
 58570 }
 58571 if (isset($repoConfig['unique_perforce_client_name'])) {
 58572 $this->uniquePerforceClientName = $repoConfig['unique_perforce_client_name'];
 58573 }
 58574 
 58575 if (isset($repoConfig['depot'])) {
 58576 $this->p4Depot = $repoConfig['depot'];
 58577 }
 58578 if (isset($repoConfig['branch'])) {
 58579 $this->p4Branch = $repoConfig['branch'];
 58580 }
 58581 if (isset($repoConfig['p4user'])) {
 58582 $this->p4User = $repoConfig['p4user'];
 58583 } else {
 58584 $this->p4User = $this->getP4variable('P4USER');
 58585 }
 58586 if (isset($repoConfig['p4password'])) {
 58587 $this->p4Password = $repoConfig['p4password'];
 58588 }
 58589 }
 58590 
 58591 
 58592 
 58593 
 58594 
 58595 
 58596 
 58597 public function initializeDepotAndBranch($depot, $branch)
 58598 {
 58599 if (isset($depot)) {
 58600 $this->p4Depot = $depot;
 58601 }
 58602 if (isset($branch)) {
 58603 $this->p4Branch = $branch;
 58604 }
 58605 }
 58606 
 58607 
 58608 
 58609 
 58610 public function generateUniquePerforceClientName()
 58611 {
 58612 return gethostname() . "_" . time();
 58613 }
 58614 
 58615 
 58616 
 58617 
 58618 public function cleanupClientSpec()
 58619 {
 58620 $client = $this->getClient();
 58621 $task = 'client -d ' . ProcessExecutor::escape($client);
 58622 $useP4Client = false;
 58623 $command = $this->generateP4Command($task, $useP4Client);
 58624 $this->executeCommand($command);
 58625 $clientSpec = $this->getP4ClientSpec();
 58626 $fileSystem = $this->getFilesystem();
 58627 $fileSystem->remove($clientSpec);
 58628 }
 58629 
 58630 
 58631 
 58632 
 58633 
 58634 
 58635 protected function executeCommand($command)
 58636 {
 58637 $this->commandResult = '';
 58638 
 58639 return $this->process->execute($command, $this->commandResult);
 58640 }
 58641 
 58642 
 58643 
 58644 
 58645 public function getClient()
 58646 {
 58647 if (!isset($this->p4Client)) {
 58648 $cleanStreamName = str_replace(array('//', '/', '@'), array('', '_', ''), $this->getStream());
 58649 $this->p4Client = 'composer_perforce_' . $this->uniquePerforceClientName . '_' . $cleanStreamName;
 58650 }
 58651 
 58652 return $this->p4Client;
 58653 }
 58654 
 58655 
 58656 
 58657 
 58658 protected function getPath()
 58659 {
 58660 return $this->path;
 58661 }
 58662 
 58663 
 58664 
 58665 
 58666 
 58667 
 58668 public function initializePath($path)
 58669 {
 58670 $this->path = $path;
 58671 $fs = $this->getFilesystem();
 58672 $fs->ensureDirectoryExists($path);
 58673 }
 58674 
 58675 
 58676 
 58677 
 58678 protected function getPort()
 58679 {
 58680 return $this->p4Port;
 58681 }
 58682 
 58683 
 58684 
 58685 
 58686 
 58687 
 58688 public function setStream($stream)
 58689 {
 58690 $this->p4Stream = $stream;
 58691 $index = strrpos($stream, '/');
 58692 
 58693 if ($index > 2) {
 58694 $this->p4DepotType = 'stream';
 58695 }
 58696 }
 58697 
 58698 
 58699 
 58700 
 58701 public function isStream()
 58702 {
 58703 return is_string($this->p4DepotType) && (strcmp($this->p4DepotType, 'stream') === 0);
 58704 }
 58705 
 58706 
 58707 
 58708 
 58709 public function getStream()
 58710 {
 58711 if (!isset($this->p4Stream)) {
 58712 if ($this->isStream()) {
 58713 $this->p4Stream = '//' . $this->p4Depot . '/' . $this->p4Branch;
 58714 } else {
 58715 $this->p4Stream = '//' . $this->p4Depot;
 58716 }
 58717 }
 58718 
 58719 return $this->p4Stream;
 58720 }
 58721 
 58722 
 58723 
 58724 
 58725 
 58726 
 58727 public function getStreamWithoutLabel($stream)
 58728 {
 58729 $index = strpos($stream, '@');
 58730 if ($index === false) {
 58731 return $stream;
 58732 }
 58733 
 58734 return substr($stream, 0, $index);
 58735 }
 58736 
 58737 
 58738 
 58739 
 58740 public function getP4ClientSpec()
 58741 {
 58742 return $this->path . '/' . $this->getClient() . '.p4.spec';
 58743 }
 58744 
 58745 
 58746 
 58747 
 58748 public function getUser()
 58749 {
 58750 return $this->p4User;
 58751 }
 58752 
 58753 
 58754 
 58755 
 58756 
 58757 
 58758 public function setUser($user)
 58759 {
 58760 $this->p4User = $user;
 58761 }
 58762 
 58763 
 58764 
 58765 
 58766 public function queryP4User()
 58767 {
 58768 $this->getUser();
 58769 if (strlen((string) $this->p4User) > 0) {
 58770 return;
 58771 }
 58772 $this->p4User = $this->getP4variable('P4USER');
 58773 if (strlen((string) $this->p4User) > 0) {
 58774 return;
 58775 }
 58776 $this->p4User = $this->io->ask('Enter P4 User:');
 58777 if ($this->windowsFlag) {
 58778 $command = 'p4 set P4USER=' . $this->p4User;
 58779 } else {
 58780 $command = 'export P4USER=' . $this->p4User;
 58781 }
 58782 $this->executeCommand($command);
 58783 }
 58784 
 58785 
 58786 
 58787 
 58788 
 58789 protected function getP4variable($name)
 58790 {
 58791 if ($this->windowsFlag) {
 58792 $command = 'p4 set';
 58793 $this->executeCommand($command);
 58794 $result = trim($this->commandResult);
 58795 $resArray = explode(PHP_EOL, $result);
 58796 foreach ($resArray as $line) {
 58797 $fields = explode('=', $line);
 58798 if (strcmp($name, $fields[0]) == 0) {
 58799 $index = strpos($fields[1], ' ');
 58800 if ($index === false) {
 58801 $value = $fields[1];
 58802 } else {
 58803 $value = substr($fields[1], 0, $index);
 58804 }
 58805 $value = trim($value);
 58806 
 58807 return $value;
 58808 }
 58809 }
 58810 
 58811 return null;
 58812 }
 58813 
 58814 $command = 'echo $' . $name;
 58815 $this->executeCommand($command);
 58816 $result = trim($this->commandResult);
 58817 
 58818 return $result;
 58819 }
 58820 
 58821 
 58822 
 58823 
 58824 public function queryP4Password()
 58825 {
 58826 if (isset($this->p4Password)) {
 58827 return $this->p4Password;
 58828 }
 58829 $password = $this->getP4variable('P4PASSWD');
 58830 if (strlen((string) $password) <= 0) {
 58831 $password = $this->io->askAndHideAnswer('Enter password for Perforce user ' . $this->getUser() . ': ');
 58832 }
 58833 $this->p4Password = $password;
 58834 
 58835 return $password;
 58836 }
 58837 
 58838 
 58839 
 58840 
 58841 
 58842 
 58843 
 58844 public function generateP4Command($command, $useClient = true)
 58845 {
 58846 $p4Command = 'p4 ';
 58847 $p4Command .= '-u ' . $this->getUser() . ' ';
 58848 if ($useClient) {
 58849 $p4Command .= '-c ' . $this->getClient() . ' ';
 58850 }
 58851 $p4Command .= '-p ' . $this->getPort() . ' ' . $command;
 58852 
 58853 return $p4Command;
 58854 }
 58855 
 58856 
 58857 
 58858 
 58859 public function isLoggedIn()
 58860 {
 58861 $command = $this->generateP4Command('login -s', false);
 58862 $exitCode = $this->executeCommand($command);
 58863 if ($exitCode) {
 58864 $errorOutput = $this->process->getErrorOutput();
 58865 $index = strpos($errorOutput, $this->getUser());
 58866 if ($index === false) {
 58867 $index = strpos($errorOutput, 'p4');
 58868 if ($index === false) {
 58869 return false;
 58870 }
 58871 throw new \Exception('p4 command not found in path: ' . $errorOutput);
 58872 }
 58873 throw new \Exception('Invalid user name: ' . $this->getUser());
 58874 }
 58875 
 58876 return true;
 58877 }
 58878 
 58879 
 58880 
 58881 
 58882 public function connectClient()
 58883 {
 58884 $p4CreateClientCommand = $this->generateP4Command(
 58885 'client -i < ' . str_replace(" ", "\\ ", $this->getP4ClientSpec())
 58886 );
 58887 $this->executeCommand($p4CreateClientCommand);
 58888 }
 58889 
 58890 
 58891 
 58892 
 58893 
 58894 
 58895 public function syncCodeBase($sourceReference)
 58896 {
 58897 $prevDir = getcwd();
 58898 chdir($this->path);
 58899 $p4SyncCommand = $this->generateP4Command('sync -f ');
 58900 if (null !== $sourceReference) {
 58901 $p4SyncCommand .= '@' . $sourceReference;
 58902 }
 58903 $this->executeCommand($p4SyncCommand);
 58904 chdir($prevDir);
 58905 }
 58906 
 58907 
 58908 
 58909 
 58910 
 58911 
 58912 public function writeClientSpecToFile($spec)
 58913 {
 58914 fwrite($spec, 'Client: ' . $this->getClient() . PHP_EOL . PHP_EOL);
 58915 fwrite($spec, 'Update: ' . date('Y/m/d H:i:s') . PHP_EOL . PHP_EOL);
 58916 fwrite($spec, 'Access: ' . date('Y/m/d H:i:s') . PHP_EOL);
 58917 fwrite($spec, 'Owner:  ' . $this->getUser() . PHP_EOL . PHP_EOL);
 58918 fwrite($spec, 'Description:' . PHP_EOL);
 58919 fwrite($spec, '  Created by ' . $this->getUser() . ' from composer.' . PHP_EOL . PHP_EOL);
 58920 fwrite($spec, 'Root: ' . $this->getPath() . PHP_EOL . PHP_EOL);
 58921 fwrite($spec, 'Options:  noallwrite noclobber nocompress unlocked modtime rmdir' . PHP_EOL . PHP_EOL);
 58922 fwrite($spec, 'SubmitOptions:  revertunchanged' . PHP_EOL . PHP_EOL);
 58923 fwrite($spec, 'LineEnd:  local' . PHP_EOL . PHP_EOL);
 58924 if ($this->isStream()) {
 58925 fwrite($spec, 'Stream:' . PHP_EOL);
 58926 fwrite($spec, '  ' . $this->getStreamWithoutLabel($this->p4Stream) . PHP_EOL);
 58927 } else {
 58928 fwrite(
 58929 $spec,
 58930 'View:  ' . $this->getStream() . '/...  //' . $this->getClient() . '/... ' . PHP_EOL
 58931 );
 58932 }
 58933 }
 58934 
 58935 
 58936 
 58937 
 58938 public function writeP4ClientSpec()
 58939 {
 58940 $clientSpec = $this->getP4ClientSpec();
 58941 $spec = fopen($clientSpec, 'w');
 58942 try {
 58943 $this->writeClientSpecToFile($spec);
 58944 } catch (\Exception $e) {
 58945 fclose($spec);
 58946 throw $e;
 58947 }
 58948 fclose($spec);
 58949 }
 58950 
 58951 
 58952 
 58953 
 58954 
 58955 
 58956 
 58957 protected function read($pipe, $name)
 58958 {
 58959 if (feof($pipe)) {
 58960 return;
 58961 }
 58962 $line = fgets($pipe);
 58963 while ($line !== false) {
 58964 $line = fgets($pipe);
 58965 }
 58966 }
 58967 
 58968 
 58969 
 58970 
 58971 
 58972 
 58973 public function windowsLogin($password)
 58974 {
 58975 $command = $this->generateP4Command(' login -a');
 58976 
 58977 
 58978 if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
 58979 $process = Process::fromShellCommandline($command, null, null, $password);
 58980 } else {
 58981 
 58982 $process = new Process($command, null, null, $password);
 58983 }
 58984 
 58985 return $process->run();
 58986 }
 58987 
 58988 
 58989 
 58990 
 58991 public function p4Login()
 58992 {
 58993 $this->queryP4User();
 58994 if (!$this->isLoggedIn()) {
 58995 $password = $this->queryP4Password();
 58996 if ($this->windowsFlag) {
 58997 $this->windowsLogin($password);
 58998 } else {
 58999 $command = 'echo ' . ProcessExecutor::escape($password) . ' | ' . $this->generateP4Command(' login -a', false);
 59000 $exitCode = $this->executeCommand($command);
 59001 if ($exitCode) {
 59002 throw new \Exception("Error logging in:" . $this->process->getErrorOutput());
 59003 }
 59004 }
 59005 }
 59006 }
 59007 
 59008 
 59009 
 59010 
 59011 
 59012 
 59013 public function getComposerInformation($identifier)
 59014 {
 59015 $composerFileContent = $this->getFileContent('composer.json', $identifier);
 59016 
 59017 if (!$composerFileContent) {
 59018 return;
 59019 }
 59020 
 59021 return json_decode($composerFileContent, true);
 59022 }
 59023 
 59024 
 59025 
 59026 
 59027 
 59028 
 59029 
 59030 public function getFileContent($file, $identifier)
 59031 {
 59032 $path = $this->getFilePath($file, $identifier);
 59033 
 59034 $command = $this->generateP4Command(' print ' . ProcessExecutor::escape($path));
 59035 $this->executeCommand($command);
 59036 $result = $this->commandResult;
 59037 
 59038 if (!trim($result)) {
 59039 return null;
 59040 }
 59041 
 59042 return $result;
 59043 }
 59044 
 59045 
 59046 
 59047 
 59048 
 59049 
 59050 
 59051 public function getFilePath($file, $identifier)
 59052 {
 59053 $index = strpos($identifier, '@');
 59054 if ($index === false) {
 59055 return $identifier. '/' . $file;
 59056 }
 59057 
 59058 $path = substr($identifier, 0, $index) . '/' . $file . substr($identifier, $index);
 59059 $command = $this->generateP4Command(' files ' . ProcessExecutor::escape($path), false);
 59060 $this->executeCommand($command);
 59061 $result = $this->commandResult;
 59062 $index2 = strpos($result, 'no such file(s).');
 59063 if ($index2 === false) {
 59064 $index3 = strpos($result, 'change');
 59065 if ($index3 !== false) {
 59066 $phrase = trim(substr($result, $index3));
 59067 $fields = explode(' ', $phrase);
 59068 
 59069 return substr($identifier, 0, $index) . '/' . $file . '@' . $fields[1];
 59070 }
 59071 }
 59072 
 59073 return null;
 59074 }
 59075 
 59076 
 59077 
 59078 
 59079 public function getBranches()
 59080 {
 59081 $possibleBranches = array();
 59082 if (!$this->isStream()) {
 59083 $possibleBranches[$this->p4Branch] = $this->getStream();
 59084 } else {
 59085 $command = $this->generateP4Command('streams '.ProcessExecutor::escape('//' . $this->p4Depot . '/...'));
 59086 $this->executeCommand($command);
 59087 $result = $this->commandResult;
 59088 $resArray = explode(PHP_EOL, $result);
 59089 foreach ($resArray as $line) {
 59090 $resBits = explode(' ', $line);
 59091 if (count($resBits) > 4) {
 59092 $branch = Preg::replace('/[^A-Za-z0-9 ]/', '', $resBits[4]);
 59093 $possibleBranches[$branch] = $resBits[1];
 59094 }
 59095 }
 59096 }
 59097 $command = $this->generateP4Command('changes '. ProcessExecutor::escape($this->getStream() . '/...'), false);
 59098 $this->executeCommand($command);
 59099 $result = $this->commandResult;
 59100 $resArray = explode(PHP_EOL, $result);
 59101 $lastCommit = $resArray[0];
 59102 $lastCommitArr = explode(' ', $lastCommit);
 59103 $lastCommitNum = $lastCommitArr[1];
 59104 
 59105 return array('master' => $possibleBranches[$this->p4Branch] . '@'. $lastCommitNum);
 59106 }
 59107 
 59108 
 59109 
 59110 
 59111 public function getTags()
 59112 {
 59113 $command = $this->generateP4Command('labels');
 59114 $this->executeCommand($command);
 59115 $result = $this->commandResult;
 59116 $resArray = explode(PHP_EOL, $result);
 59117 $tags = array();
 59118 foreach ($resArray as $line) {
 59119 if (strpos($line, 'Label') !== false) {
 59120 $fields = explode(' ', $line);
 59121 $tags[$fields[1]] = $this->getStream() . '@' . $fields[1];
 59122 }
 59123 }
 59124 
 59125 return $tags;
 59126 }
 59127 
 59128 
 59129 
 59130 
 59131 public function checkStream()
 59132 {
 59133 $command = $this->generateP4Command('depots', false);
 59134 $this->executeCommand($command);
 59135 $result = $this->commandResult;
 59136 $resArray = explode(PHP_EOL, $result);
 59137 foreach ($resArray as $line) {
 59138 if (strpos($line, 'Depot') !== false) {
 59139 $fields = explode(' ', $line);
 59140 if (strcmp($this->p4Depot, $fields[1]) === 0) {
 59141 $this->p4DepotType = $fields[3];
 59142 
 59143 return $this->isStream();
 59144 }
 59145 }
 59146 }
 59147 
 59148 return false;
 59149 }
 59150 
 59151 
 59152 
 59153 
 59154 
 59155 protected function getChangeList($reference)
 59156 {
 59157 $index = strpos($reference, '@');
 59158 if ($index === false) {
 59159 return null;
 59160 }
 59161 $label = substr($reference, $index);
 59162 $command = $this->generateP4Command(' changes -m1 ' . ProcessExecutor::escape($label));
 59163 $this->executeCommand($command);
 59164 $changes = $this->commandResult;
 59165 if (strpos($changes, 'Change') !== 0) {
 59166 return null;
 59167 }
 59168 $fields = explode(' ', $changes);
 59169 
 59170 return $fields[1];
 59171 }
 59172 
 59173 
 59174 
 59175 
 59176 
 59177 
 59178 public function getCommitLogs($fromReference, $toReference)
 59179 {
 59180 $fromChangeList = $this->getChangeList($fromReference);
 59181 if ($fromChangeList === null) {
 59182 return null;
 59183 }
 59184 $toChangeList = $this->getChangeList($toReference);
 59185 if ($toChangeList === null) {
 59186 return null;
 59187 }
 59188 $index = strpos($fromReference, '@');
 59189 $main = substr($fromReference, 0, $index) . '/...';
 59190 $command = $this->generateP4Command('filelog ' . ProcessExecutor::escape($main . '@' . $fromChangeList. ',' . $toChangeList));
 59191 $this->executeCommand($command);
 59192 
 59193 return $this->commandResult;
 59194 }
 59195 
 59196 
 59197 
 59198 
 59199 public function getFilesystem()
 59200 {
 59201 if (null === $this->filesystem) {
 59202 $this->filesystem = new Filesystem($this->process);
 59203 }
 59204 
 59205 return $this->filesystem;
 59206 }
 59207 
 59208 
 59209 
 59210 
 59211 public function setFilesystem(Filesystem $fs)
 59212 {
 59213 $this->filesystem = $fs;
 59214 }
 59215 }
 59216 <?php
 59217 
 59218 
 59219 
 59220 
 59221 
 59222 
 59223 
 59224 
 59225 
 59226 
 59227 
 59228 namespace Composer\Util;
 59229 
 59230 use Composer\Pcre\Preg;
 59231 
 59232 
 59233 
 59234 
 59235 
 59236 
 59237 class Platform
 59238 {
 59239 
 59240 private static $isVirtualBoxGuest = null;
 59241 
 59242 private static $isWindowsSubsystemForLinux = null;
 59243 
 59244 
 59245 
 59246 
 59247 
 59248 
 59249 
 59250 public static function getEnv($name)
 59251 {
 59252 if (array_key_exists($name, $_SERVER)) {
 59253 return (string) $_SERVER[$name];
 59254 }
 59255 if (array_key_exists($name, $_ENV)) {
 59256 return (string) $_ENV[$name];
 59257 }
 59258 
 59259 return getenv($name);
 59260 }
 59261 
 59262 
 59263 
 59264 
 59265 
 59266 
 59267 
 59268 
 59269 public static function putEnv($name, $value)
 59270 {
 59271 $value = (string) $value;
 59272 putenv($name . '=' . $value);
 59273 $_SERVER[$name] = $_ENV[$name] = $value;
 59274 }
 59275 
 59276 
 59277 
 59278 
 59279 
 59280 
 59281 
 59282 public static function clearEnv($name)
 59283 {
 59284 putenv($name);
 59285 unset($_SERVER[$name], $_ENV[$name]);
 59286 }
 59287 
 59288 
 59289 
 59290 
 59291 
 59292 
 59293 
 59294 public static function expandPath($path)
 59295 {
 59296 if (Preg::isMatch('#^~[\\/]#', $path)) {
 59297 return self::getUserDirectory() . substr($path, 1);
 59298 }
 59299 
 59300 return Preg::replaceCallback('#^(\$|(?P<percent>%))(?P<var>\w++)(?(percent)%)(?P<path>.*)#', function ($matches) {
 59301 
 59302 if (Platform::isWindows() && $matches['var'] == 'HOME') {
 59303 return (Platform::getEnv('HOME') ?: Platform::getEnv('USERPROFILE')) . $matches['path'];
 59304 }
 59305 
 59306 return Platform::getEnv($matches['var']) . $matches['path'];
 59307 }, $path);
 59308 }
 59309 
 59310 
 59311 
 59312 
 59313 
 59314 public static function getUserDirectory()
 59315 {
 59316 if (false !== ($home = self::getEnv('HOME'))) {
 59317 return $home;
 59318 }
 59319 
 59320 if (self::isWindows() && false !== ($home = self::getEnv('USERPROFILE'))) {
 59321 return $home;
 59322 }
 59323 
 59324 if (\function_exists('posix_getuid') && \function_exists('posix_getpwuid')) {
 59325 $info = posix_getpwuid(posix_getuid());
 59326 
 59327 return $info['dir'];
 59328 }
 59329 
 59330 throw new \RuntimeException('Could not determine user directory');
 59331 }
 59332 
 59333 
 59334 
 59335 
 59336 public static function isWindowsSubsystemForLinux()
 59337 {
 59338 if (null === self::$isWindowsSubsystemForLinux) {
 59339 self::$isWindowsSubsystemForLinux = false;
 59340 
 59341 
 59342 if (self::isWindows()) {
 59343 return self::$isWindowsSubsystemForLinux = false;
 59344 }
 59345 
 59346 if (
 59347 !ini_get('open_basedir')
 59348 && is_readable('/proc/version')
 59349 && false !== stripos(Silencer::call('file_get_contents', '/proc/version'), 'microsoft')
 59350 && !file_exists('/.dockerenv') 
 59351 ) {
 59352 return self::$isWindowsSubsystemForLinux = true;
 59353 }
 59354 }
 59355 
 59356 return self::$isWindowsSubsystemForLinux;
 59357 }
 59358 
 59359 
 59360 
 59361 
 59362 public static function isWindows()
 59363 {
 59364 return \defined('PHP_WINDOWS_VERSION_BUILD');
 59365 }
 59366 
 59367 
 59368 
 59369 
 59370 
 59371 public static function strlen($str)
 59372 {
 59373 static $useMbString = null;
 59374 if (null === $useMbString) {
 59375 $useMbString = \function_exists('mb_strlen') && ini_get('mbstring.func_overload');
 59376 }
 59377 
 59378 if ($useMbString) {
 59379 return mb_strlen($str, '8bit');
 59380 }
 59381 
 59382 return \strlen($str);
 59383 }
 59384 
 59385 
 59386 
 59387 
 59388 
 59389 public static function isTty($fd = null)
 59390 {
 59391 if ($fd === null) {
 59392 $fd = defined('STDOUT') ? STDOUT : fopen('php://stdout', 'w');
 59393 }
 59394 
 59395 
 59396 
 59397 if (in_array(strtoupper(self::getEnv('MSYSTEM') ?: ''), array('MINGW32', 'MINGW64'), true)) {
 59398 return true;
 59399 }
 59400 
 59401 
 59402 
 59403 if (function_exists('stream_isatty')) {
 59404 return stream_isatty($fd);
 59405 }
 59406 
 59407 
 59408 if (function_exists('posix_isatty') && posix_isatty($fd)) {
 59409 return true;
 59410 }
 59411 
 59412 $stat = @fstat($fd);
 59413 
 59414 return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
 59415 }
 59416 
 59417 
 59418 
 59419 
 59420 public static function workaroundFilesystemIssues()
 59421 {
 59422 if (self::isVirtualBoxGuest()) {
 59423 usleep(200000);
 59424 }
 59425 }
 59426 
 59427 
 59428 
 59429 
 59430 
 59431 
 59432 
 59433 
 59434 private static function isVirtualBoxGuest()
 59435 {
 59436 if (null === self::$isVirtualBoxGuest) {
 59437 self::$isVirtualBoxGuest = false;
 59438 if (self::isWindows()) {
 59439 return self::$isVirtualBoxGuest;
 59440 }
 59441 
 59442 if (function_exists('posix_getpwuid') && function_exists('posix_geteuid')) {
 59443 $processUser = posix_getpwuid(posix_geteuid());
 59444 if ($processUser && $processUser['name'] === 'vagrant') {
 59445 return self::$isVirtualBoxGuest = true;
 59446 }
 59447 }
 59448 
 59449 if (self::getEnv('COMPOSER_RUNTIME_ENV') === 'virtualbox') {
 59450 return self::$isVirtualBoxGuest = true;
 59451 }
 59452 
 59453 if (defined('PHP_OS_FAMILY') && PHP_OS_FAMILY === 'Linux') {
 59454 $process = new ProcessExecutor();
 59455 try {
 59456 if (0 === $process->execute('lsmod | grep vboxguest', $ignoredOutput)) {
 59457 return self::$isVirtualBoxGuest = true;
 59458 }
 59459 } catch (\Exception $e) {
 59460 
 59461 }
 59462 }
 59463 }
 59464 
 59465 return self::$isVirtualBoxGuest;
 59466 }
 59467 }
 59468 <?php
 59469 
 59470 
 59471 
 59472 
 59473 
 59474 
 59475 
 59476 
 59477 
 59478 
 59479 
 59480 namespace Composer\Util;
 59481 
 59482 use Composer\IO\IOInterface;
 59483 use Composer\Pcre\Preg;
 59484 use Symfony\Component\Process\Process;
 59485 use Symfony\Component\Process\Exception\RuntimeException;
 59486 use React\Promise\Promise;
 59487 use React\Promise\PromiseInterface;
 59488 
 59489 
 59490 
 59491 
 59492 
 59493 class ProcessExecutor
 59494 {
 59495 const STATUS_QUEUED = 1;
 59496 const STATUS_STARTED = 2;
 59497 const STATUS_COMPLETED = 3;
 59498 const STATUS_FAILED = 4;
 59499 const STATUS_ABORTED = 5;
 59500 
 59501 
 59502 protected static $timeout = 300;
 59503 
 59504 
 59505 protected $captureOutput = false;
 59506 
 59507 protected $errorOutput = '';
 59508 
 59509 protected $io;
 59510 
 59511 
 59512 
 59513 
 59514 private $jobs = array();
 59515 
 59516 private $runningJobs = 0;
 59517 
 59518 private $maxJobs = 10;
 59519 
 59520 private $idGen = 0;
 59521 
 59522 private $allowAsync = false;
 59523 
 59524 public function __construct(IOInterface $io = null)
 59525 {
 59526 $this->io = $io;
 59527 }
 59528 
 59529 
 59530 
 59531 
 59532 
 59533 
 59534 
 59535 
 59536 
 59537 
 59538 public function execute($command, &$output = null, $cwd = null)
 59539 {
 59540 if (func_num_args() > 1) {
 59541 return $this->doExecute($command, $cwd, false, $output);
 59542 }
 59543 
 59544 return $this->doExecute($command, $cwd, false);
 59545 }
 59546 
 59547 
 59548 
 59549 
 59550 
 59551 
 59552 
 59553 
 59554 public function executeTty($command, $cwd = null)
 59555 {
 59556 if (Platform::isTty()) {
 59557 return $this->doExecute($command, $cwd, true);
 59558 }
 59559 
 59560 return $this->doExecute($command, $cwd, false);
 59561 }
 59562 
 59563 
 59564 
 59565 
 59566 
 59567 
 59568 
 59569 
 59570 private function doExecute($command, $cwd, $tty, &$output = null)
 59571 {
 59572 $this->outputCommandRun($command, $cwd, false);
 59573 
 59574 
 59575 
 59576 
 59577 if (null === $cwd && Platform::isWindows() && false !== strpos($command, 'git') && getcwd()) {
 59578 $cwd = realpath(getcwd());
 59579 }
 59580 if (null !== $cwd && !is_dir($cwd)) {
 59581 throw new \RuntimeException('The given CWD for the process does not exist: '.$cwd);
 59582 }
 59583 
 59584 $this->captureOutput = func_num_args() > 3;
 59585 $this->errorOutput = '';
 59586 
 59587 
 59588 if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
 59589 $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout());
 59590 } else {
 59591 
 59592 $process = new Process($command, $cwd, null, null, static::getTimeout());
 59593 }
 59594 if (!Platform::isWindows() && $tty) {
 59595 try {
 59596 $process->setTty(true);
 59597 } catch (RuntimeException $e) {
 59598 
 59599 }
 59600 }
 59601 
 59602 $callback = is_callable($output) ? $output : array($this, 'outputHandler');
 59603 $process->run($callback);
 59604 
 59605 if ($this->captureOutput && !is_callable($output)) {
 59606 $output = $process->getOutput();
 59607 }
 59608 
 59609 $this->errorOutput = $process->getErrorOutput();
 59610 
 59611 return $process->getExitCode();
 59612 }
 59613 
 59614 
 59615 
 59616 
 59617 
 59618 
 59619 
 59620 
 59621 public function executeAsync($command, $cwd = null)
 59622 {
 59623 if (!$this->allowAsync) {
 59624 throw new \LogicException('You must use the ProcessExecutor instance which is part of a Composer\Loop instance to be able to run async processes');
 59625 }
 59626 
 59627 $job = array(
 59628 'id' => $this->idGen++,
 59629 'status' => self::STATUS_QUEUED,
 59630 'command' => $command,
 59631 'cwd' => $cwd,
 59632 );
 59633 
 59634 $resolver = function ($resolve, $reject) use (&$job) {
 59635 $job['status'] = ProcessExecutor::STATUS_QUEUED;
 59636 $job['resolve'] = $resolve;
 59637 $job['reject'] = $reject;
 59638 };
 59639 
 59640 $self = $this;
 59641 
 59642 $canceler = function () use (&$job) {
 59643 if ($job['status'] === ProcessExecutor::STATUS_QUEUED) {
 59644 $job['status'] = ProcessExecutor::STATUS_ABORTED;
 59645 }
 59646 if ($job['status'] !== ProcessExecutor::STATUS_STARTED) {
 59647 return;
 59648 }
 59649 $job['status'] = ProcessExecutor::STATUS_ABORTED;
 59650 try {
 59651 if (defined('SIGINT')) {
 59652 $job['process']->signal(SIGINT);
 59653 }
 59654 } catch (\Exception $e) {
 59655 
 59656 }
 59657 $job['process']->stop(1);
 59658 
 59659 throw new \RuntimeException('Aborted process');
 59660 };
 59661 
 59662 $promise = new Promise($resolver, $canceler);
 59663 $promise = $promise->then(function () use (&$job, $self) {
 59664 if ($job['process']->isSuccessful()) {
 59665 $job['status'] = ProcessExecutor::STATUS_COMPLETED;
 59666 } else {
 59667 $job['status'] = ProcessExecutor::STATUS_FAILED;
 59668 }
 59669 
 59670 
 59671 $self->markJobDone();
 59672 
 59673 return $job['process'];
 59674 }, function ($e) use (&$job, $self) {
 59675 $job['status'] = ProcessExecutor::STATUS_FAILED;
 59676 
 59677 $self->markJobDone();
 59678 
 59679 throw $e;
 59680 });
 59681 $this->jobs[$job['id']] = &$job;
 59682 
 59683 if ($this->runningJobs < $this->maxJobs) {
 59684 $this->startJob($job['id']);
 59685 }
 59686 
 59687 return $promise;
 59688 }
 59689 
 59690 
 59691 
 59692 
 59693 
 59694 private function startJob($id)
 59695 {
 59696 $job = &$this->jobs[$id];
 59697 if ($job['status'] !== self::STATUS_QUEUED) {
 59698 return;
 59699 }
 59700 
 59701 
 59702 $job['status'] = self::STATUS_STARTED;
 59703 $this->runningJobs++;
 59704 
 59705 $command = $job['command'];
 59706 $cwd = $job['cwd'];
 59707 
 59708 $this->outputCommandRun($command, $cwd, true);
 59709 
 59710 
 59711 
 59712 
 59713 if (null === $cwd && Platform::isWindows() && false !== strpos($command, 'git') && getcwd()) {
 59714 $cwd = realpath(getcwd());
 59715 }
 59716 if (null !== $cwd && !is_dir($cwd)) {
 59717 throw new \RuntimeException('The given CWD for the process does not exist: '.$cwd);
 59718 }
 59719 
 59720 try {
 59721 
 59722 if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
 59723 $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout());
 59724 } else {
 59725 $process = new Process($command, $cwd, null, null, static::getTimeout());
 59726 }
 59727 } catch (\Exception $e) {
 59728 call_user_func($job['reject'], $e);
 59729 
 59730 return;
 59731 } catch (\Throwable $e) {
 59732 call_user_func($job['reject'], $e);
 59733 
 59734 return;
 59735 }
 59736 
 59737 $job['process'] = $process;
 59738 
 59739 try {
 59740 $process->start();
 59741 } catch (\Exception $e) {
 59742 call_user_func($job['reject'], $e);
 59743 
 59744 return;
 59745 } catch (\Throwable $e) {
 59746 call_user_func($job['reject'], $e);
 59747 
 59748 return;
 59749 }
 59750 }
 59751 
 59752 
 59753 
 59754 
 59755 
 59756 public function wait($index = null)
 59757 {
 59758 while (true) {
 59759 if (!$this->countActiveJobs($index)) {
 59760 return;
 59761 }
 59762 
 59763 usleep(1000);
 59764 }
 59765 }
 59766 
 59767 
 59768 
 59769 
 59770 
 59771 
 59772 public function enableAsync()
 59773 {
 59774 $this->allowAsync = true;
 59775 }
 59776 
 59777 
 59778 
 59779 
 59780 
 59781 
 59782 
 59783 public function countActiveJobs($index = null)
 59784 {
 59785 
 59786 foreach ($this->jobs as $job) {
 59787 if ($job['status'] === self::STATUS_STARTED) {
 59788 if (!$job['process']->isRunning()) {
 59789 call_user_func($job['resolve'], $job['process']);
 59790 }
 59791 
 59792 $job['process']->checkTimeout();
 59793 }
 59794 
 59795 if ($this->runningJobs < $this->maxJobs) {
 59796 if ($job['status'] === self::STATUS_QUEUED) {
 59797 $this->startJob($job['id']);
 59798 }
 59799 }
 59800 }
 59801 
 59802 if (null !== $index) {
 59803 return $this->jobs[$index]['status'] < self::STATUS_COMPLETED ? 1 : 0;
 59804 }
 59805 
 59806 $active = 0;
 59807 foreach ($this->jobs as $job) {
 59808 if ($job['status'] < self::STATUS_COMPLETED) {
 59809 $active++;
 59810 } else {
 59811 unset($this->jobs[$job['id']]);
 59812 }
 59813 }
 59814 
 59815 return $active;
 59816 }
 59817 
 59818 
 59819 
 59820 
 59821 
 59822 
 59823 public function markJobDone()
 59824 {
 59825 $this->runningJobs--;
 59826 }
 59827 
 59828 
 59829 
 59830 
 59831 
 59832 public function splitLines($output)
 59833 {
 59834 $output = trim((string) $output);
 59835 
 59836 return $output === '' ? array() : Preg::split('{\r?\n}', $output);
 59837 }
 59838 
 59839 
 59840 
 59841 
 59842 
 59843 
 59844 public function getErrorOutput()
 59845 {
 59846 return $this->errorOutput;
 59847 }
 59848 
 59849 
 59850 
 59851 
 59852 
 59853 
 59854 
 59855 
 59856 
 59857 public function outputHandler($type, $buffer)
 59858 {
 59859 if ($this->captureOutput) {
 59860 return;
 59861 }
 59862 
 59863 if (null === $this->io) {
 59864 echo $buffer;
 59865 
 59866 return;
 59867 }
 59868 
 59869 if (Process::ERR === $type) {
 59870 $this->io->writeErrorRaw($buffer, false);
 59871 } else {
 59872 $this->io->writeRaw($buffer, false);
 59873 }
 59874 }
 59875 
 59876 
 59877 
 59878 
 59879 public static function getTimeout()
 59880 {
 59881 return static::$timeout;
 59882 }
 59883 
 59884 
 59885 
 59886 
 59887 
 59888 public static function setTimeout($timeout)
 59889 {
 59890 static::$timeout = $timeout;
 59891 }
 59892 
 59893 
 59894 
 59895 
 59896 
 59897 
 59898 
 59899 
 59900 public static function escape($argument)
 59901 {
 59902 return self::escapeArgument($argument);
 59903 }
 59904 
 59905 
 59906 
 59907 
 59908 
 59909 
 59910 
 59911 private function outputCommandRun($command, $cwd, $async)
 59912 {
 59913 if (null === $this->io || !$this->io->isDebug()) {
 59914 return;
 59915 }
 59916 
 59917 $safeCommand = Preg::replaceCallback('{://(?P<user>[^:/\s]+):(?P<password>[^@\s/]+)@}i', function ($m) {
 59918 
 59919 if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) {
 59920 return '://***:***@';
 59921 }
 59922 if (Preg::isMatch('{^[a-f0-9]{12,}$}', $m['user'])) {
 59923 return '://***:***@';
 59924 }
 59925 
 59926 return '://'.$m['user'].':***@';
 59927 }, $command);
 59928 $safeCommand = Preg::replace("{--password (.*[^\\\\]\') }", '--password \'***\' ', $safeCommand);
 59929 $this->io->writeError('Executing'.($async ? ' async' : '').' command ('.($cwd ?: 'CWD').'): '.$safeCommand);
 59930 }
 59931 
 59932 
 59933 
 59934 
 59935 
 59936 
 59937 
 59938 
 59939 
 59940 
 59941 
 59942 
 59943 
 59944 
 59945 
 59946 
 59947 private static function escapeArgument($argument)
 59948 {
 59949 if ('' === ($argument = (string) $argument)) {
 59950 return escapeshellarg($argument);
 59951 }
 59952 
 59953 if (!Platform::isWindows()) {
 59954 return "'".str_replace("'", "'\\''", $argument)."'";
 59955 }
 59956 
 59957 
 59958 $argument = strtr($argument, "\n", ' ');
 59959 
 59960 $quote = strpbrk($argument, " \t") !== false;
 59961 $argument = Preg::replace('/(\\\\*)"/', '$1$1\\"', $argument, -1, $dquotes);
 59962 $meta = $dquotes || Preg::isMatch('/%[^%]+%|![^!]+!/', $argument);
 59963 
 59964 if (!$meta && !$quote) {
 59965 $quote = strpbrk($argument, '^&|<>()') !== false;
 59966 }
 59967 
 59968 if ($quote) {
 59969 $argument = '"'.Preg::replace('/(\\\\*)$/', '$1$1', $argument).'"';
 59970 }
 59971 
 59972 if ($meta) {
 59973 $argument = Preg::replace('/(["^&|<>()%])/', '^$1', $argument);
 59974 $argument = Preg::replace('/(!)/', '^^$1', $argument);
 59975 }
 59976 
 59977 return $argument;
 59978 }
 59979 }
 59980 <?php
 59981 
 59982 
 59983 
 59984 
 59985 
 59986 
 59987 
 59988 
 59989 
 59990 
 59991 
 59992 namespace Composer\Util;
 59993 
 59994 use Composer\Config;
 59995 use Composer\Downloader\MaxFileSizeExceededException;
 59996 use Composer\IO\IOInterface;
 59997 use Composer\Downloader\TransportException;
 59998 use Composer\CaBundle\CaBundle;
 59999 use Composer\Pcre\Preg;
 60000 use Composer\Util\Http\Response;
 60001 use Composer\Util\Http\ProxyManager;
 60002 
 60003 
 60004 
 60005 
 60006 
 60007 
 60008 
 60009 class RemoteFilesystem
 60010 {
 60011 
 60012 private $io;
 60013 
 60014 private $config;
 60015 
 60016 private $scheme;
 60017 
 60018 private $bytesMax;
 60019 
 60020 private $originUrl;
 60021 
 60022 private $fileUrl;
 60023 
 60024 private $fileName;
 60025 
 60026 private $retry = false;
 60027 
 60028 private $progress;
 60029 
 60030 private $lastProgress;
 60031 
 60032 private $options = array();
 60033 
 60034 private $peerCertificateMap = array();
 60035 
 60036 private $disableTls = false;
 60037 
 60038 private $lastHeaders;
 60039 
 60040 private $storeAuth = false;
 60041 
 60042 private $authHelper;
 60043 
 60044 private $degradedMode = false;
 60045 
 60046 private $redirects;
 60047 
 60048 private $maxRedirects = 20;
 60049 
 60050 private $proxyManager;
 60051 
 60052 
 60053 
 60054 
 60055 
 60056 
 60057 
 60058 
 60059 
 60060 
 60061 public function __construct(IOInterface $io, Config $config, array $options = array(), $disableTls = false, AuthHelper $authHelper = null)
 60062 {
 60063 $this->io = $io;
 60064 
 60065 
 60066 
 60067 if ($disableTls === false) {
 60068 $this->options = StreamContextFactory::getTlsDefaults($options, $io);
 60069 } else {
 60070 $this->disableTls = true;
 60071 }
 60072 
 60073 
 60074 $this->options = array_replace_recursive($this->options, $options);
 60075 $this->config = $config;
 60076 $this->authHelper = isset($authHelper) ? $authHelper : new AuthHelper($io, $config);
 60077 $this->proxyManager = ProxyManager::getInstance();
 60078 }
 60079 
 60080 
 60081 
 60082 
 60083 
 60084 
 60085 
 60086 
 60087 
 60088 
 60089 
 60090 
 60091 public function copy($originUrl, $fileUrl, $fileName, $progress = true, $options = array())
 60092 {
 60093 return $this->get($originUrl, $fileUrl, $options, $fileName, $progress);
 60094 }
 60095 
 60096 
 60097 
 60098 
 60099 
 60100 
 60101 
 60102 
 60103 
 60104 
 60105 
 60106 public function getContents($originUrl, $fileUrl, $progress = true, $options = array())
 60107 {
 60108 return $this->get($originUrl, $fileUrl, $options, null, $progress);
 60109 }
 60110 
 60111 
 60112 
 60113 
 60114 
 60115 
 60116 public function getOptions()
 60117 {
 60118 return $this->options;
 60119 }
 60120 
 60121 
 60122 
 60123 
 60124 
 60125 
 60126 
 60127 public function setOptions(array $options)
 60128 {
 60129 $this->options = array_replace_recursive($this->options, $options);
 60130 }
 60131 
 60132 
 60133 
 60134 
 60135 
 60136 
 60137 public function isTlsDisabled()
 60138 {
 60139 return $this->disableTls === true;
 60140 }
 60141 
 60142 
 60143 
 60144 
 60145 
 60146 
 60147 public function getLastHeaders()
 60148 {
 60149 return $this->lastHeaders;
 60150 }
 60151 
 60152 
 60153 
 60154 
 60155 
 60156 public static function findStatusCode(array $headers)
 60157 {
 60158 $value = null;
 60159 foreach ($headers as $header) {
 60160 if (Preg::isMatch('{^HTTP/\S+ (\d+)}i', $header, $match)) {
 60161 
 60162 
 60163 $value = (int) $match[1];
 60164 }
 60165 }
 60166 
 60167 return $value;
 60168 }
 60169 
 60170 
 60171 
 60172 
 60173 
 60174 public function findStatusMessage(array $headers)
 60175 {
 60176 $value = null;
 60177 foreach ($headers as $header) {
 60178 if (Preg::isMatch('{^HTTP/\S+ \d+}i', $header)) {
 60179 
 60180 
 60181 $value = $header;
 60182 }
 60183 }
 60184 
 60185 return $value;
 60186 }
 60187 
 60188 
 60189 
 60190 
 60191 
 60192 
 60193 
 60194 
 60195 
 60196 
 60197 
 60198 
 60199 
 60200 
 60201 
 60202 protected function get($originUrl, $fileUrl, $additionalOptions = array(), $fileName = null, $progress = true)
 60203 {
 60204 $this->scheme = parse_url($fileUrl, PHP_URL_SCHEME);
 60205 $this->bytesMax = 0;
 60206 $this->originUrl = $originUrl;
 60207 $this->fileUrl = $fileUrl;
 60208 $this->fileName = $fileName;
 60209 $this->progress = $progress;
 60210 $this->lastProgress = null;
 60211 $retryAuthFailure = true;
 60212 $this->lastHeaders = array();
 60213 $this->redirects = 1; 
 60214 
 60215 $tempAdditionalOptions = $additionalOptions;
 60216 if (isset($tempAdditionalOptions['retry-auth-failure'])) {
 60217 $retryAuthFailure = (bool) $tempAdditionalOptions['retry-auth-failure'];
 60218 
 60219 unset($tempAdditionalOptions['retry-auth-failure']);
 60220 }
 60221 
 60222 $isRedirect = false;
 60223 if (isset($tempAdditionalOptions['redirects'])) {
 60224 $this->redirects = $tempAdditionalOptions['redirects'];
 60225 $isRedirect = true;
 60226 
 60227 unset($tempAdditionalOptions['redirects']);
 60228 }
 60229 
 60230 $options = $this->getOptionsForUrl($originUrl, $tempAdditionalOptions);
 60231 unset($tempAdditionalOptions);
 60232 
 60233 $origFileUrl = $fileUrl;
 60234 
 60235 if (isset($options['gitlab-token'])) {
 60236 $fileUrl .= (false === strpos($fileUrl, '?') ? '?' : '&') . 'access_token='.$options['gitlab-token'];
 60237 unset($options['gitlab-token']);
 60238 }
 60239 
 60240 if (isset($options['http'])) {
 60241 $options['http']['ignore_errors'] = true;
 60242 }
 60243 
 60244 if ($this->degradedMode && strpos($fileUrl, 'http://repo.packagist.org/') === 0) {
 60245 
 60246 $fileUrl = 'http://' . gethostbyname('repo.packagist.org') . substr($fileUrl, 20);
 60247 $degradedPackagist = true;
 60248 }
 60249 
 60250 $maxFileSize = null;
 60251 if (isset($options['max_file_size'])) {
 60252 $maxFileSize = $options['max_file_size'];
 60253 unset($options['max_file_size']);
 60254 }
 60255 
 60256 $ctx = StreamContextFactory::getContext($fileUrl, $options, array('notification' => array($this, 'callbackGet')));
 60257 
 60258 $proxy = $this->proxyManager->getProxyForRequest($fileUrl);
 60259 $usingProxy = $proxy->getFormattedUrl(' using proxy (%s)');
 60260 $this->io->writeError((strpos($origFileUrl, 'http') === 0 ? 'Downloading ' : 'Reading ') . Url::sanitize($origFileUrl) . $usingProxy, true, IOInterface::DEBUG);
 60261 unset($origFileUrl, $proxy, $usingProxy);
 60262 
 60263 
 60264 if ((!Preg::isMatch('{^http://(repo\.)?packagist\.org/p/}', $fileUrl) || (false === strpos($fileUrl, '$') && false === strpos($fileUrl, '%24'))) && empty($degradedPackagist)) {
 60265 $this->config->prohibitUrlByConfig($fileUrl, $this->io);
 60266 }
 60267 
 60268 if ($this->progress && !$isRedirect) {
 60269 $this->io->writeError("Downloading (<comment>connecting...</comment>)", false);
 60270 }
 60271 
 60272 $errorMessage = '';
 60273 $errorCode = 0;
 60274 $result = false;
 60275 set_error_handler(function ($code, $msg) use (&$errorMessage) {
 60276 if ($errorMessage) {
 60277 $errorMessage .= "\n";
 60278 }
 60279 $errorMessage .= Preg::replace('{^file_get_contents\(.*?\): }', '', $msg);
 60280 
 60281 return true;
 60282 });
 60283 $http_response_header = array();
 60284 try {
 60285 $result = $this->getRemoteContents($originUrl, $fileUrl, $ctx, $http_response_header, $maxFileSize);
 60286 
 60287 if (!empty($http_response_header[0])) {
 60288 $statusCode = self::findStatusCode($http_response_header);
 60289 if ($statusCode >= 400 && Response::findHeaderValue($http_response_header, 'content-type') === 'application/json') {
 60290 HttpDownloader::outputWarnings($this->io, $originUrl, json_decode($result, true));
 60291 }
 60292 
 60293 if (in_array($statusCode, array(401, 403)) && $retryAuthFailure) {
 60294 $this->promptAuthAndRetry($statusCode, $this->findStatusMessage($http_response_header), $http_response_header);
 60295 }
 60296 }
 60297 
 60298 $contentLength = !empty($http_response_header[0]) ? Response::findHeaderValue($http_response_header, 'content-length') : null;
 60299 if ($contentLength && Platform::strlen($result) < $contentLength) {
 60300 
 60301 $e = new TransportException('Content-Length mismatch, received '.Platform::strlen($result).' bytes out of the expected '.$contentLength);
 60302 $e->setHeaders($http_response_header);
 60303 $e->setStatusCode(self::findStatusCode($http_response_header));
 60304 try {
 60305 $e->setResponse($this->decodeResult($result, $http_response_header));
 60306 } catch (\Exception $discarded) {
 60307 $e->setResponse($this->normalizeResult($result));
 60308 }
 60309 
 60310 $this->io->writeError('Content-Length mismatch, received '.Platform::strlen($result).' out of '.$contentLength.' bytes: (' . base64_encode($result).')', true, IOInterface::DEBUG);
 60311 
 60312 throw $e;
 60313 }
 60314 
 60315 if (PHP_VERSION_ID < 50600 && !empty($options['ssl']['peer_fingerprint'])) {
 60316 
 60317 $params = stream_context_get_params($ctx);
 60318 $expectedPeerFingerprint = $options['ssl']['peer_fingerprint'];
 60319 $peerFingerprint = TlsHelper::getCertificateFingerprint($params['options']['ssl']['peer_certificate']);
 60320 
 60321 
 60322 if ($expectedPeerFingerprint !== $peerFingerprint) {
 60323 throw new TransportException('Peer fingerprint did not match');
 60324 }
 60325 }
 60326 } catch (\Exception $e) {
 60327 if ($e instanceof TransportException && !empty($http_response_header[0])) {
 60328 $e->setHeaders($http_response_header);
 60329 $e->setStatusCode(self::findStatusCode($http_response_header));
 60330 }
 60331 if ($e instanceof TransportException && $result !== false) {
 60332 $e->setResponse($this->decodeResult($result, $http_response_header));
 60333 }
 60334 $result = false;
 60335 }
 60336 if ($errorMessage && !filter_var(ini_get('allow_url_fopen'), FILTER_VALIDATE_BOOLEAN)) {
 60337 $errorMessage = 'allow_url_fopen must be enabled in php.ini ('.$errorMessage.')';
 60338 }
 60339 restore_error_handler();
 60340 if (isset($e) && !$this->retry) {
 60341 if (!$this->degradedMode && false !== strpos($e->getMessage(), 'Operation timed out')) {
 60342 $this->degradedMode = true;
 60343 $this->io->writeError('');
 60344 $this->io->writeError(array(
 60345 '<error>'.$e->getMessage().'</error>',
 60346 '<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>',
 60347 ));
 60348 
 60349 return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
 60350 }
 60351 
 60352 throw $e;
 60353 }
 60354 
 60355 $statusCode = null;
 60356 $contentType = null;
 60357 $locationHeader = null;
 60358 if (!empty($http_response_header[0])) {
 60359 $statusCode = self::findStatusCode($http_response_header);
 60360 $contentType = Response::findHeaderValue($http_response_header, 'content-type');
 60361 $locationHeader = Response::findHeaderValue($http_response_header, 'location');
 60362 }
 60363 
 60364 
 60365 if ($originUrl === 'bitbucket.org'
 60366 && !$this->authHelper->isPublicBitBucketDownload($fileUrl)
 60367 && substr($fileUrl, -4) === '.zip'
 60368 && (!$locationHeader || substr(parse_url($locationHeader, PHP_URL_PATH), -4) !== '.zip')
 60369 && $contentType && Preg::isMatch('{^text/html\b}i', $contentType)
 60370 ) {
 60371 $result = false;
 60372 if ($retryAuthFailure) {
 60373 $this->promptAuthAndRetry(401);
 60374 }
 60375 }
 60376 
 60377 
 60378 if ($statusCode === 404
 60379 && in_array($originUrl, $this->config->get('gitlab-domains'), true)
 60380 && false !== strpos($fileUrl, 'archive.zip')
 60381 ) {
 60382 $result = false;
 60383 if ($retryAuthFailure) {
 60384 $this->promptAuthAndRetry(401);
 60385 }
 60386 }
 60387 
 60388 
 60389 $hasFollowedRedirect = false;
 60390 if ($statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $this->redirects < $this->maxRedirects) {
 60391 $hasFollowedRedirect = true;
 60392 $result = $this->handleRedirect($http_response_header, $additionalOptions, $result);
 60393 }
 60394 
 60395 
 60396 if ($statusCode && $statusCode >= 400 && $statusCode <= 599) {
 60397 if (!$this->retry) {
 60398 if ($this->progress && !$isRedirect) {
 60399 $this->io->overwriteError("Downloading (<error>failed</error>)", false);
 60400 }
 60401 
 60402 $e = new TransportException('The "'.$this->fileUrl.'" file could not be downloaded ('.$http_response_header[0].')', $statusCode);
 60403 $e->setHeaders($http_response_header);
 60404 $e->setResponse($this->decodeResult($result, $http_response_header));
 60405 $e->setStatusCode($statusCode);
 60406 throw $e;
 60407 }
 60408 $result = false;
 60409 }
 60410 
 60411 if ($this->progress && !$this->retry && !$isRedirect) {
 60412 $this->io->overwriteError("Downloading (".($result === false ? '<error>failed</error>' : '<comment>100%</comment>').")", false);
 60413 }
 60414 
 60415 
 60416 if ($result && extension_loaded('zlib') && strpos($fileUrl, 'http') === 0 && !$hasFollowedRedirect) {
 60417 try {
 60418 $result = $this->decodeResult($result, $http_response_header);
 60419 } catch (\Exception $e) {
 60420 if ($this->degradedMode) {
 60421 throw $e;
 60422 }
 60423 
 60424 $this->degradedMode = true;
 60425 $this->io->writeError(array(
 60426 '',
 60427 '<error>Failed to decode response: '.$e->getMessage().'</error>',
 60428 '<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>',
 60429 ));
 60430 
 60431 return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
 60432 }
 60433 }
 60434 
 60435 
 60436 if (false !== $result && null !== $fileName && !$isRedirect) {
 60437 if ('' === $result) {
 60438 throw new TransportException('"'.$this->fileUrl.'" appears broken, and returned an empty 200 response');
 60439 }
 60440 
 60441 $errorMessage = '';
 60442 set_error_handler(function ($code, $msg) use (&$errorMessage) {
 60443 if ($errorMessage) {
 60444 $errorMessage .= "\n";
 60445 }
 60446 $errorMessage .= Preg::replace('{^file_put_contents\(.*?\): }', '', $msg);
 60447 
 60448 return true;
 60449 });
 60450 $result = (bool) file_put_contents($fileName, $result);
 60451 restore_error_handler();
 60452 if (false === $result) {
 60453 throw new TransportException('The "'.$this->fileUrl.'" file could not be written to '.$fileName.': '.$errorMessage);
 60454 }
 60455 }
 60456 
 60457 
 60458 if (false === $result && false !== strpos($errorMessage, 'Peer certificate') && PHP_VERSION_ID < 50600) {
 60459 
 60460 
 60461 
 60462 
 60463 
 60464 
 60465 
 60466 
 60467 
 60468 
 60469 
 60470 
 60471 
 60472 
 60473 
 60474 
 60475 if (CaBundle::isOpensslParseSafe()) {
 60476 $certDetails = $this->getCertificateCnAndFp($this->fileUrl, $options);
 60477 
 60478 if ($certDetails) {
 60479 $this->peerCertificateMap[$this->getUrlAuthority($this->fileUrl)] = $certDetails;
 60480 
 60481 $this->retry = true;
 60482 }
 60483 } else {
 60484 $this->io->writeError('');
 60485 $this->io->writeError(sprintf(
 60486 '<error>Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.</error>',
 60487 PHP_VERSION
 60488 ));
 60489 }
 60490 }
 60491 
 60492 if ($this->retry) {
 60493 $this->retry = false;
 60494 
 60495 $result = $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
 60496 
 60497 if ($this->storeAuth) {
 60498 $this->authHelper->storeAuth($this->originUrl, $this->storeAuth);
 60499 $this->storeAuth = false;
 60500 }
 60501 
 60502 return $result;
 60503 }
 60504 
 60505 if (false === $result) {
 60506 $e = new TransportException('The "'.$this->fileUrl.'" file could not be downloaded: '.$errorMessage, $errorCode);
 60507 if (!empty($http_response_header[0])) {
 60508 $e->setHeaders($http_response_header);
 60509 }
 60510 
 60511 if (!$this->degradedMode && false !== strpos($e->getMessage(), 'Operation timed out')) {
 60512 $this->degradedMode = true;
 60513 $this->io->writeError('');
 60514 $this->io->writeError(array(
 60515 '<error>'.$e->getMessage().'</error>',
 60516 '<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>',
 60517 ));
 60518 
 60519 return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
 60520 }
 60521 
 60522 throw $e;
 60523 }
 60524 
 60525 if (!empty($http_response_header[0])) {
 60526 $this->lastHeaders = $http_response_header;
 60527 }
 60528 
 60529 return $result;
 60530 }
 60531 
 60532 
 60533 
 60534 
 60535 
 60536 
 60537 
 60538 
 60539 
 60540 
 60541 
 60542 
 60543 protected function getRemoteContents($originUrl, $fileUrl, $context, array &$responseHeaders = null, $maxFileSize = null)
 60544 {
 60545 $result = false;
 60546 
 60547 try {
 60548 $e = null;
 60549 if ($maxFileSize !== null) {
 60550 $result = file_get_contents($fileUrl, false, $context, 0, $maxFileSize);
 60551 } else {
 60552 
 60553 $result = file_get_contents($fileUrl, false, $context);
 60554 }
 60555 } catch (\Exception $e) {
 60556 } catch (\Throwable $e) {
 60557 }
 60558 
 60559 if ($maxFileSize !== null && Platform::strlen($result) >= $maxFileSize) {
 60560 throw new MaxFileSizeExceededException('Maximum allowed download size reached. Downloaded ' . Platform::strlen($result) . ' of allowed ' . $maxFileSize . ' bytes');
 60561 }
 60562 
 60563 
 60564 $responseHeaders = isset($http_response_header) ? $http_response_header : array();
 60565 
 60566 if (null !== $e) {
 60567 throw $e;
 60568 }
 60569 
 60570 return $result;
 60571 }
 60572 
 60573 
 60574 
 60575 
 60576 
 60577 
 60578 
 60579 
 60580 
 60581 
 60582 
 60583 
 60584 
 60585 
 60586 
 60587 protected function callbackGet($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax)
 60588 {
 60589 switch ($notificationCode) {
 60590 case STREAM_NOTIFY_FAILURE:
 60591 if (400 === $messageCode) {
 60592 
 60593 
 60594 throw new TransportException("The '" . $this->fileUrl . "' URL could not be accessed: " . $message, $messageCode);
 60595 }
 60596 break;
 60597 
 60598 case STREAM_NOTIFY_FILE_SIZE_IS:
 60599 $this->bytesMax = $bytesMax;
 60600 break;
 60601 
 60602 case STREAM_NOTIFY_PROGRESS:
 60603 if ($this->bytesMax > 0 && $this->progress) {
 60604 $progression = min(100, (int) round($bytesTransferred / $this->bytesMax * 100));
 60605 
 60606 if ((0 === $progression % 5) && 100 !== $progression && $progression !== $this->lastProgress) {
 60607 $this->lastProgress = $progression;
 60608 $this->io->overwriteError("Downloading (<comment>$progression%</comment>)", false);
 60609 }
 60610 }
 60611 break;
 60612 
 60613 default:
 60614 break;
 60615 }
 60616 }
 60617 
 60618 
 60619 
 60620 
 60621 
 60622 
 60623 
 60624 
 60625 protected function promptAuthAndRetry($httpStatus, $reason = null, $headers = array())
 60626 {
 60627 $result = $this->authHelper->promptAuthIfNeeded($this->fileUrl, $this->originUrl, $httpStatus, $reason, $headers);
 60628 
 60629 $this->storeAuth = $result['storeAuth'];
 60630 $this->retry = $result['retry'];
 60631 
 60632 if ($this->retry) {
 60633 throw new TransportException('RETRY');
 60634 }
 60635 }
 60636 
 60637 
 60638 
 60639 
 60640 
 60641 
 60642 
 60643 protected function getOptionsForUrl($originUrl, $additionalOptions)
 60644 {
 60645 $tlsOptions = array();
 60646 
 60647 
 60648 if ($this->disableTls === false && PHP_VERSION_ID < 50600 && !stream_is_local($this->fileUrl)) {
 60649 $host = parse_url($this->fileUrl, PHP_URL_HOST);
 60650 
 60651 if (PHP_VERSION_ID < 50304) {
 60652 
 60653 
 60654 
 60655 
 60656 
 60657 if ($host === 'github.com' || $host === 'api.github.com') {
 60658 $host = '*.github.com';
 60659 }
 60660 }
 60661 
 60662 $tlsOptions['ssl']['CN_match'] = $host;
 60663 $tlsOptions['ssl']['SNI_server_name'] = $host;
 60664 
 60665 $urlAuthority = $this->getUrlAuthority($this->fileUrl);
 60666 
 60667 if (isset($this->peerCertificateMap[$urlAuthority])) {
 60668 
 60669 $certMap = $this->peerCertificateMap[$urlAuthority];
 60670 
 60671 $this->io->writeError('', true, IOInterface::DEBUG);
 60672 $this->io->writeError(sprintf(
 60673 'Using <info>%s</info> as CN for subjectAltName enabled host <info>%s</info>',
 60674 $certMap['cn'],
 60675 $urlAuthority
 60676 ), true, IOInterface::DEBUG);
 60677 
 60678 $tlsOptions['ssl']['CN_match'] = $certMap['cn'];
 60679 $tlsOptions['ssl']['peer_fingerprint'] = $certMap['fp'];
 60680 } elseif (!CaBundle::isOpensslParseSafe() && $host === 'repo.packagist.org') {
 60681 
 60682 $tlsOptions['ssl']['CN_match'] = 'packagist.org';
 60683 }
 60684 }
 60685 
 60686 $headers = array();
 60687 
 60688 if (extension_loaded('zlib')) {
 60689 $headers[] = 'Accept-Encoding: gzip';
 60690 }
 60691 
 60692 $options = array_replace_recursive($this->options, $tlsOptions, $additionalOptions);
 60693 if (!$this->degradedMode) {
 60694 
 60695 
 60696 $options['http']['protocol_version'] = 1.1;
 60697 $headers[] = 'Connection: close';
 60698 }
 60699 
 60700 $headers = $this->authHelper->addAuthenticationHeader($headers, $originUrl, $this->fileUrl);
 60701 
 60702 $options['http']['follow_location'] = 0;
 60703 
 60704 if (isset($options['http']['header']) && !is_array($options['http']['header'])) {
 60705 $options['http']['header'] = explode("\r\n", trim($options['http']['header'], "\r\n"));
 60706 }
 60707 foreach ($headers as $header) {
 60708 $options['http']['header'][] = $header;
 60709 }
 60710 
 60711 return $options;
 60712 }
 60713 
 60714 
 60715 
 60716 
 60717 
 60718 
 60719 
 60720 
 60721 private function handleRedirect(array $http_response_header, array $additionalOptions, $result)
 60722 {
 60723 if ($locationHeader = Response::findHeaderValue($http_response_header, 'location')) {
 60724 if (parse_url($locationHeader, PHP_URL_SCHEME)) {
 60725 
 60726 $targetUrl = $locationHeader;
 60727 } elseif (parse_url($locationHeader, PHP_URL_HOST)) {
 60728 
 60729 $targetUrl = $this->scheme.':'.$locationHeader;
 60730 } elseif ('/' === $locationHeader[0]) {
 60731 
 60732 $urlHost = parse_url($this->fileUrl, PHP_URL_HOST);
 60733 
 60734 
 60735 $targetUrl = Preg::replace('{^(.+(?://|@)'.preg_quote($urlHost).'(?::\d+)?)(?:[/\?].*)?$}', '\1'.$locationHeader, $this->fileUrl);
 60736 } else {
 60737 
 60738 
 60739 $targetUrl = Preg::replace('{^(.+/)[^/?]*(?:\?.*)?$}', '\1'.$locationHeader, $this->fileUrl);
 60740 }
 60741 }
 60742 
 60743 if (!empty($targetUrl)) {
 60744 $this->redirects++;
 60745 
 60746 $this->io->writeError('', true, IOInterface::DEBUG);
 60747 $this->io->writeError(sprintf('Following redirect (%u) %s', $this->redirects, Url::sanitize($targetUrl)), true, IOInterface::DEBUG);
 60748 
 60749 $additionalOptions['redirects'] = $this->redirects;
 60750 
 60751 return $this->get(parse_url($targetUrl, PHP_URL_HOST), $targetUrl, $additionalOptions, $this->fileName, $this->progress);
 60752 }
 60753 
 60754 if (!$this->retry) {
 60755 $e = new TransportException('The "'.$this->fileUrl.'" file could not be downloaded, got redirect without Location ('.$http_response_header[0].')');
 60756 $e->setHeaders($http_response_header);
 60757 $e->setResponse($this->decodeResult($result, $http_response_header));
 60758 
 60759 throw $e;
 60760 }
 60761 
 60762 return false;
 60763 }
 60764 
 60765 
 60766 
 60767 
 60768 
 60769 
 60770 
 60771 
 60772 
 60773 
 60774 
 60775 private function getCertificateCnAndFp($url, $options)
 60776 {
 60777 if (PHP_VERSION_ID >= 50600) {
 60778 throw new \BadMethodCallException(sprintf(
 60779 '%s must not be used on PHP >= 5.6',
 60780 __METHOD__
 60781 ));
 60782 }
 60783 
 60784 $context = StreamContextFactory::getContext($url, $options, array('options' => array(
 60785 'ssl' => array(
 60786 'capture_peer_cert' => true,
 60787 'verify_peer' => false, 
 60788 ), ),
 60789 ));
 60790 
 60791 
 60792 
 60793 if (false === $handle = @fopen($url, 'rb', false, $context)) {
 60794 return null;
 60795 }
 60796 
 60797 
 60798 fclose($handle);
 60799 $handle = null;
 60800 
 60801 $params = stream_context_get_params($context);
 60802 
 60803 if (!empty($params['options']['ssl']['peer_certificate'])) {
 60804 $peerCertificate = $params['options']['ssl']['peer_certificate'];
 60805 
 60806 if (TlsHelper::checkCertificateHost($peerCertificate, parse_url($url, PHP_URL_HOST), $commonName)) {
 60807 return array(
 60808 'cn' => $commonName,
 60809 'fp' => TlsHelper::getCertificateFingerprint($peerCertificate),
 60810 );
 60811 }
 60812 }
 60813 
 60814 return null;
 60815 }
 60816 
 60817 
 60818 
 60819 
 60820 
 60821 
 60822 private function getUrlAuthority($url)
 60823 {
 60824 $defaultPorts = array(
 60825 'ftp' => 21,
 60826 'http' => 80,
 60827 'https' => 443,
 60828 'ssh2.sftp' => 22,
 60829 'ssh2.scp' => 22,
 60830 );
 60831 
 60832 $scheme = parse_url($url, PHP_URL_SCHEME);
 60833 
 60834 if (!isset($defaultPorts[$scheme])) {
 60835 throw new \InvalidArgumentException(sprintf(
 60836 'Could not get default port for unknown scheme: %s',
 60837 $scheme
 60838 ));
 60839 }
 60840 
 60841 $defaultPort = $defaultPorts[$scheme];
 60842 $port = parse_url($url, PHP_URL_PORT) ?: $defaultPort;
 60843 
 60844 return parse_url($url, PHP_URL_HOST).':'.$port;
 60845 }
 60846 
 60847 
 60848 
 60849 
 60850 
 60851 
 60852 
 60853 private function decodeResult($result, $http_response_header)
 60854 {
 60855 
 60856 if ($result && extension_loaded('zlib')) {
 60857 $contentEncoding = Response::findHeaderValue($http_response_header, 'content-encoding');
 60858 $decode = $contentEncoding && 'gzip' === strtolower($contentEncoding);
 60859 
 60860 if ($decode) {
 60861 if (PHP_VERSION_ID >= 50400) {
 60862 $result = zlib_decode($result);
 60863 } else {
 60864 
 60865 $result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
 60866 }
 60867 
 60868 if ($result === false) {
 60869 throw new TransportException('Failed to decode zlib stream');
 60870 }
 60871 }
 60872 }
 60873 
 60874 return $this->normalizeResult($result);
 60875 }
 60876 
 60877 
 60878 
 60879 
 60880 
 60881 
 60882 private function normalizeResult($result)
 60883 {
 60884 if ($result === false) {
 60885 return null;
 60886 }
 60887 
 60888 return $result;
 60889 }
 60890 }
 60891 <?php
 60892 
 60893 
 60894 
 60895 
 60896 
 60897 
 60898 
 60899 
 60900 
 60901 
 60902 
 60903 namespace Composer\Util;
 60904 
 60905 
 60906 
 60907 
 60908 
 60909 
 60910 class Silencer
 60911 {
 60912 
 60913 
 60914 
 60915 private static $stack = array();
 60916 
 60917 
 60918 
 60919 
 60920 
 60921 
 60922 
 60923 public static function suppress($mask = null)
 60924 {
 60925 if (!isset($mask)) {
 60926 $mask = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT;
 60927 }
 60928 $old = error_reporting();
 60929 self::$stack[] = $old;
 60930 error_reporting($old & ~$mask);
 60931 
 60932 return $old;
 60933 }
 60934 
 60935 
 60936 
 60937 
 60938 
 60939 
 60940 public static function restore()
 60941 {
 60942 if (!empty(self::$stack)) {
 60943 error_reporting(array_pop(self::$stack));
 60944 }
 60945 }
 60946 
 60947 
 60948 
 60949 
 60950 
 60951 
 60952 
 60953 
 60954 
 60955 
 60956 public static function call($callable )
 60957 {
 60958 try {
 60959 self::suppress();
 60960 $result = call_user_func_array($callable, array_slice(func_get_args(), 1));
 60961 self::restore();
 60962 
 60963 return $result;
 60964 } catch (\Exception $e) {
 60965 
 60966 self::restore();
 60967 throw $e;
 60968 }
 60969 }
 60970 }
 60971 <?php
 60972 
 60973 
 60974 
 60975 
 60976 
 60977 
 60978 
 60979 
 60980 
 60981 
 60982 
 60983 namespace Composer\Util;
 60984 
 60985 use Composer\Composer;
 60986 use Composer\CaBundle\CaBundle;
 60987 use Composer\Downloader\TransportException;
 60988 use Composer\Repository\PlatformRepository;
 60989 use Composer\Util\Http\ProxyManager;
 60990 use Psr\Log\LoggerInterface;
 60991 
 60992 
 60993 
 60994 
 60995 
 60996 
 60997 
 60998 final class StreamContextFactory
 60999 {
 61000 
 61001 
 61002 
 61003 
 61004 
 61005 
 61006 
 61007 
 61008 
 61009 
 61010 public static function getContext($url, array $defaultOptions = array(), array $defaultParams = array())
 61011 {
 61012 $options = array('http' => array(
 61013 
 61014 'follow_location' => 1,
 61015 'max_redirects' => 20,
 61016 ));
 61017 
 61018 $options = array_replace_recursive($options, self::initOptions($url, $defaultOptions));
 61019 unset($defaultOptions['http']['header']);
 61020 $options = array_replace_recursive($options, $defaultOptions);
 61021 
 61022 if (isset($options['http']['header'])) {
 61023 $options['http']['header'] = self::fixHttpHeaderField($options['http']['header']);
 61024 }
 61025 
 61026 return stream_context_create($options, $defaultParams);
 61027 }
 61028 
 61029 
 61030 
 61031 
 61032 
 61033 
 61034 
 61035 
 61036 public static function initOptions($url, array $options, $forCurl = false)
 61037 {
 61038 
 61039 if (!isset($options['http']['header'])) {
 61040 $options['http']['header'] = array();
 61041 }
 61042 if (is_string($options['http']['header'])) {
 61043 $options['http']['header'] = explode("\r\n", $options['http']['header']);
 61044 }
 61045 
 61046 
 61047 if (!$forCurl) {
 61048 $proxy = ProxyManager::getInstance()->getProxyForRequest($url);
 61049 if ($proxyOptions = $proxy->getContextOptions()) {
 61050 $isHttpsRequest = 0 === strpos($url, 'https://');
 61051 
 61052 if ($proxy->isSecure()) {
 61053 if (!extension_loaded('openssl')) {
 61054 throw new TransportException('You must enable the openssl extension to use a secure proxy.');
 61055 }
 61056 if ($isHttpsRequest) {
 61057 throw new TransportException('You must enable the curl extension to make https requests through a secure proxy.');
 61058 }
 61059 } elseif ($isHttpsRequest && !extension_loaded('openssl')) {
 61060 throw new TransportException('You must enable the openssl extension to make https requests through a proxy.');
 61061 }
 61062 
 61063 
 61064 if (isset($proxyOptions['http']['header'])) {
 61065 $options['http']['header'][] = $proxyOptions['http']['header'];
 61066 unset($proxyOptions['http']['header']);
 61067 }
 61068 $options = array_replace_recursive($options, $proxyOptions);
 61069 }
 61070 }
 61071 
 61072 if (defined('HHVM_VERSION')) {
 61073 $phpVersion = 'HHVM ' . HHVM_VERSION;
 61074 } else {
 61075 $phpVersion = 'PHP ' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION;
 61076 }
 61077 
 61078 if ($forCurl) {
 61079 $curl = curl_version();
 61080 $httpVersion = 'cURL '.$curl['version'];
 61081 } else {
 61082 $httpVersion = 'streams';
 61083 }
 61084 
 61085 if (!isset($options['http']['header']) || false === stripos(implode('', $options['http']['header']), 'user-agent')) {
 61086 $platformPhpVersion = PlatformRepository::getPlatformPhpVersion();
 61087 $options['http']['header'][] = sprintf(
 61088 'User-Agent: Composer/%s (%s; %s; %s; %s%s%s)',
 61089 Composer::getVersion(),
 61090 function_exists('php_uname') ? php_uname('s') : 'Unknown',
 61091 function_exists('php_uname') ? php_uname('r') : 'Unknown',
 61092 $phpVersion,
 61093 $httpVersion,
 61094 $platformPhpVersion ? '; Platform-PHP '.$platformPhpVersion : '',
 61095 Platform::getEnv('CI') ? '; CI' : ''
 61096 );
 61097 }
 61098 
 61099 return $options;
 61100 }
 61101 
 61102 
 61103 
 61104 
 61105 
 61106 
 61107 public static function getTlsDefaults(array $options, LoggerInterface $logger = null)
 61108 {
 61109 $ciphers = implode(':', array(
 61110 'ECDHE-RSA-AES128-GCM-SHA256',
 61111 'ECDHE-ECDSA-AES128-GCM-SHA256',
 61112 'ECDHE-RSA-AES256-GCM-SHA384',
 61113 'ECDHE-ECDSA-AES256-GCM-SHA384',
 61114 'DHE-RSA-AES128-GCM-SHA256',
 61115 'DHE-DSS-AES128-GCM-SHA256',
 61116 'kEDH+AESGCM',
 61117 'ECDHE-RSA-AES128-SHA256',
 61118 'ECDHE-ECDSA-AES128-SHA256',
 61119 'ECDHE-RSA-AES128-SHA',
 61120 'ECDHE-ECDSA-AES128-SHA',
 61121 'ECDHE-RSA-AES256-SHA384',
 61122 'ECDHE-ECDSA-AES256-SHA384',
 61123 'ECDHE-RSA-AES256-SHA',
 61124 'ECDHE-ECDSA-AES256-SHA',
 61125 'DHE-RSA-AES128-SHA256',
 61126 'DHE-RSA-AES128-SHA',
 61127 'DHE-DSS-AES128-SHA256',
 61128 'DHE-RSA-AES256-SHA256',
 61129 'DHE-DSS-AES256-SHA',
 61130 'DHE-RSA-AES256-SHA',
 61131 'AES128-GCM-SHA256',
 61132 'AES256-GCM-SHA384',
 61133 'AES128-SHA256',
 61134 'AES256-SHA256',
 61135 'AES128-SHA',
 61136 'AES256-SHA',
 61137 'AES',
 61138 'CAMELLIA',
 61139 'DES-CBC3-SHA',
 61140 '!aNULL',
 61141 '!eNULL',
 61142 '!EXPORT',
 61143 '!DES',
 61144 '!RC4',
 61145 '!MD5',
 61146 '!PSK',
 61147 '!aECDH',
 61148 '!EDH-DSS-DES-CBC3-SHA',
 61149 '!EDH-RSA-DES-CBC3-SHA',
 61150 '!KRB5-DES-CBC3-SHA',
 61151 ));
 61152 
 61153 
 61154 
 61155 
 61156 
 61157 
 61158 
 61159 $defaults = array(
 61160 'ssl' => array(
 61161 'ciphers' => $ciphers,
 61162 'verify_peer' => true,
 61163 'verify_depth' => 7,
 61164 'SNI_enabled' => true,
 61165 'capture_peer_cert' => true,
 61166 ),
 61167 );
 61168 
 61169 if (isset($options['ssl'])) {
 61170 $defaults['ssl'] = array_replace_recursive($defaults['ssl'], $options['ssl']);
 61171 }
 61172 
 61173 
 61174 
 61175 
 61176 
 61177 if (!isset($defaults['ssl']['cafile']) && !isset($defaults['ssl']['capath'])) {
 61178 $result = CaBundle::getSystemCaRootBundlePath($logger);
 61179 
 61180 if (is_dir($result)) {
 61181 $defaults['ssl']['capath'] = $result;
 61182 } else {
 61183 $defaults['ssl']['cafile'] = $result;
 61184 }
 61185 }
 61186 
 61187 if (isset($defaults['ssl']['cafile']) && (!Filesystem::isReadable($defaults['ssl']['cafile']) || !CaBundle::validateCaFile($defaults['ssl']['cafile'], $logger))) {
 61188 throw new TransportException('The configured cafile was not valid or could not be read.');
 61189 }
 61190 
 61191 if (isset($defaults['ssl']['capath']) && (!is_dir($defaults['ssl']['capath']) || !Filesystem::isReadable($defaults['ssl']['capath']))) {
 61192 throw new TransportException('The configured capath was not valid or could not be read.');
 61193 }
 61194 
 61195 
 61196 
 61197 
 61198 if (PHP_VERSION_ID >= 50413) {
 61199 $defaults['ssl']['disable_compression'] = true;
 61200 }
 61201 
 61202 return $defaults;
 61203 }
 61204 
 61205 
 61206 
 61207 
 61208 
 61209 
 61210 
 61211 
 61212 
 61213 
 61214 
 61215 private static function fixHttpHeaderField($header)
 61216 {
 61217 if (!is_array($header)) {
 61218 $header = explode("\r\n", $header);
 61219 }
 61220 uasort($header, function ($el) {
 61221 return stripos($el, 'content-type') === 0 ? 1 : -1;
 61222 });
 61223 
 61224 return $header;
 61225 }
 61226 }
 61227 <?php
 61228 
 61229 
 61230 
 61231 
 61232 
 61233 
 61234 
 61235 
 61236 
 61237 
 61238 
 61239 namespace Composer\Util;
 61240 
 61241 use Composer\Config;
 61242 use Composer\IO\IOInterface;
 61243 use Composer\Pcre\Preg;
 61244 
 61245 
 61246 
 61247 
 61248 
 61249 class Svn
 61250 {
 61251 const MAX_QTY_AUTH_TRIES = 5;
 61252 
 61253 
 61254 
 61255 
 61256 protected $credentials;
 61257 
 61258 
 61259 
 61260 
 61261 protected $hasAuth;
 61262 
 61263 
 61264 
 61265 
 61266 protected $io;
 61267 
 61268 
 61269 
 61270 
 61271 protected $url;
 61272 
 61273 
 61274 
 61275 
 61276 protected $cacheCredentials = true;
 61277 
 61278 
 61279 
 61280 
 61281 protected $process;
 61282 
 61283 
 61284 
 61285 
 61286 protected $qtyAuthTries = 0;
 61287 
 61288 
 61289 
 61290 
 61291 protected $config;
 61292 
 61293 
 61294 
 61295 
 61296 private static $version;
 61297 
 61298 
 61299 
 61300 
 61301 
 61302 
 61303 
 61304 public function __construct($url, IOInterface $io, Config $config, ProcessExecutor $process = null)
 61305 {
 61306 $this->url = $url;
 61307 $this->io = $io;
 61308 $this->config = $config;
 61309 $this->process = $process ?: new ProcessExecutor($io);
 61310 }
 61311 
 61312 
 61313 
 61314 
 61315 public static function cleanEnv()
 61316 {
 61317 
 61318 Platform::clearEnv('DYLD_LIBRARY_PATH');
 61319 }
 61320 
 61321 
 61322 
 61323 
 61324 
 61325 
 61326 
 61327 
 61328 
 61329 
 61330 
 61331 
 61332 
 61333 
 61334 public function execute($command, $url, $cwd = null, $path = null, $verbose = false)
 61335 {
 61336 
 61337 $this->config->prohibitUrlByConfig($url, $this->io);
 61338 
 61339 return $this->executeWithAuthRetry($command, $cwd, $url, $path, $verbose);
 61340 }
 61341 
 61342 
 61343 
 61344 
 61345 
 61346 
 61347 
 61348 
 61349 
 61350 
 61351 
 61352 
 61353 
 61354 public function executeLocal($command, $path, $cwd = null, $verbose = false)
 61355 {
 61356 
 61357 return $this->executeWithAuthRetry($command, $cwd, '', $path, $verbose);
 61358 }
 61359 
 61360 
 61361 
 61362 
 61363 
 61364 
 61365 
 61366 
 61367 
 61368 
 61369 private function executeWithAuthRetry($svnCommand, $cwd, $url, $path, $verbose)
 61370 {
 61371 
 61372 $command = $this->getCommand($svnCommand, $url, $path);
 61373 
 61374 $output = null;
 61375 $io = $this->io;
 61376 $handler = function ($type, $buffer) use (&$output, $io, $verbose) {
 61377 if ($type !== 'out') {
 61378 return null;
 61379 }
 61380 if (strpos($buffer, 'Redirecting to URL ') === 0) {
 61381 return null;
 61382 }
 61383 $output .= $buffer;
 61384 if ($verbose) {
 61385 $io->writeError($buffer, false);
 61386 }
 61387 };
 61388 $status = $this->process->execute($command, $handler, $cwd);
 61389 if (0 === $status) {
 61390 return $output;
 61391 }
 61392 
 61393 $errorOutput = $this->process->getErrorOutput();
 61394 $fullOutput = implode("\n", array($output, $errorOutput));
 61395 
 61396 
 61397 if (false === stripos($fullOutput, 'Could not authenticate to server:')
 61398 && false === stripos($fullOutput, 'authorization failed')
 61399 && false === stripos($fullOutput, 'svn: E170001:')
 61400 && false === stripos($fullOutput, 'svn: E215004:')) {
 61401 throw new \RuntimeException($fullOutput);
 61402 }
 61403 
 61404 if (!$this->hasAuth()) {
 61405 $this->doAuthDance();
 61406 }
 61407 
 61408 
 61409 if ($this->qtyAuthTries++ < self::MAX_QTY_AUTH_TRIES) {
 61410 
 61411 return $this->executeWithAuthRetry($svnCommand, $cwd, $url, $path, $verbose);
 61412 }
 61413 
 61414 throw new \RuntimeException(
 61415 'wrong credentials provided ('.$fullOutput.')'
 61416 );
 61417 }
 61418 
 61419 
 61420 
 61421 
 61422 
 61423 public function setCacheCredentials($cacheCredentials)
 61424 {
 61425 $this->cacheCredentials = $cacheCredentials;
 61426 }
 61427 
 61428 
 61429 
 61430 
 61431 
 61432 
 61433 
 61434 protected function doAuthDance()
 61435 {
 61436 
 61437 if (!$this->io->isInteractive()) {
 61438 throw new \RuntimeException(
 61439 'can not ask for authentication in non interactive mode'
 61440 );
 61441 }
 61442 
 61443 $this->io->writeError("The Subversion server ({$this->url}) requested credentials:");
 61444 
 61445 $this->hasAuth = true;
 61446 $this->credentials = array(
 61447 'username' => (string) $this->io->ask("Username: ", ''),
 61448 'password' => (string) $this->io->askAndHideAnswer("Password: "),
 61449 );
 61450 
 61451 $this->cacheCredentials = $this->io->askConfirmation("Should Subversion cache these credentials? (yes/no) ");
 61452 
 61453 return $this;
 61454 }
 61455 
 61456 
 61457 
 61458 
 61459 
 61460 
 61461 
 61462 
 61463 
 61464 
 61465 protected function getCommand($cmd, $url, $path = null)
 61466 {
 61467 $cmd = sprintf(
 61468 '%s %s%s -- %s',
 61469 $cmd,
 61470 '--non-interactive ',
 61471 $this->getCredentialString(),
 61472 ProcessExecutor::escape($url)
 61473 );
 61474 
 61475 if ($path) {
 61476 $cmd .= ' ' . ProcessExecutor::escape($path);
 61477 }
 61478 
 61479 return $cmd;
 61480 }
 61481 
 61482 
 61483 
 61484 
 61485 
 61486 
 61487 
 61488 
 61489 protected function getCredentialString()
 61490 {
 61491 if (!$this->hasAuth()) {
 61492 return '';
 61493 }
 61494 
 61495 return sprintf(
 61496 ' %s--username %s --password %s ',
 61497 $this->getAuthCache(),
 61498 ProcessExecutor::escape($this->getUsername()),
 61499 ProcessExecutor::escape($this->getPassword())
 61500 );
 61501 }
 61502 
 61503 
 61504 
 61505 
 61506 
 61507 
 61508 
 61509 protected function getPassword()
 61510 {
 61511 if ($this->credentials === null) {
 61512 throw new \LogicException("No svn auth detected.");
 61513 }
 61514 
 61515 return $this->credentials['password'];
 61516 }
 61517 
 61518 
 61519 
 61520 
 61521 
 61522 
 61523 
 61524 protected function getUsername()
 61525 {
 61526 if ($this->credentials === null) {
 61527 throw new \LogicException("No svn auth detected.");
 61528 }
 61529 
 61530 return $this->credentials['username'];
 61531 }
 61532 
 61533 
 61534 
 61535 
 61536 
 61537 
 61538 protected function hasAuth()
 61539 {
 61540 if (null !== $this->hasAuth) {
 61541 return $this->hasAuth;
 61542 }
 61543 
 61544 if (false === $this->createAuthFromConfig()) {
 61545 $this->createAuthFromUrl();
 61546 }
 61547 
 61548 return (bool) $this->hasAuth;
 61549 }
 61550 
 61551 
 61552 
 61553 
 61554 
 61555 
 61556 protected function getAuthCache()
 61557 {
 61558 return $this->cacheCredentials ? '' : '--no-auth-cache ';
 61559 }
 61560 
 61561 
 61562 
 61563 
 61564 
 61565 
 61566 private function createAuthFromConfig()
 61567 {
 61568 if (!$this->config->has('http-basic')) {
 61569 return $this->hasAuth = false;
 61570 }
 61571 
 61572 $authConfig = $this->config->get('http-basic');
 61573 
 61574 $host = parse_url($this->url, PHP_URL_HOST);
 61575 if (isset($authConfig[$host])) {
 61576 $this->credentials = array(
 61577 'username' => $authConfig[$host]['username'],
 61578 'password' => $authConfig[$host]['password'],
 61579 );
 61580 
 61581 return $this->hasAuth = true;
 61582 }
 61583 
 61584 return $this->hasAuth = false;
 61585 }
 61586 
 61587 
 61588 
 61589 
 61590 
 61591 
 61592 private function createAuthFromUrl()
 61593 {
 61594 $uri = parse_url($this->url);
 61595 if (empty($uri['user'])) {
 61596 return $this->hasAuth = false;
 61597 }
 61598 
 61599 $this->credentials = array(
 61600 'username' => $uri['user'],
 61601 'password' => !empty($uri['pass']) ? $uri['pass'] : '',
 61602 );
 61603 
 61604 return $this->hasAuth = true;
 61605 }
 61606 
 61607 
 61608 
 61609 
 61610 
 61611 
 61612 public function binaryVersion()
 61613 {
 61614 if (!self::$version) {
 61615 if (0 === $this->process->execute('svn --version', $output)) {
 61616 if (Preg::isMatch('{(\d+(?:\.\d+)+)}', $output, $match)) {
 61617 self::$version = $match[1];
 61618 }
 61619 }
 61620 }
 61621 
 61622 return self::$version;
 61623 }
 61624 }
 61625 <?php
 61626 
 61627 
 61628 
 61629 
 61630 
 61631 
 61632 
 61633 
 61634 
 61635 
 61636 
 61637 namespace Composer\Util;
 61638 
 61639 use Composer\Downloader\DownloaderInterface;
 61640 use Composer\Package\PackageInterface;
 61641 use React\Promise\PromiseInterface;
 61642 
 61643 class SyncHelper
 61644 {
 61645 
 61646 
 61647 
 61648 
 61649 
 61650 
 61651 
 61652 
 61653 
 61654 
 61655 
 61656 
 61657 
 61658 public static function downloadAndInstallPackageSync(Loop $loop, DownloaderInterface $downloader, $path, PackageInterface $package, PackageInterface $prevPackage = null)
 61659 {
 61660 $type = $prevPackage ? 'update' : 'install';
 61661 
 61662 try {
 61663 self::await($loop, $downloader->download($package, $path, $prevPackage));
 61664 
 61665 self::await($loop, $downloader->prepare($type, $package, $path, $prevPackage));
 61666 
 61667 if ($type === 'update') {
 61668 self::await($loop, $downloader->update($package, $prevPackage, $path));
 61669 } else {
 61670 self::await($loop, $downloader->install($package, $path));
 61671 }
 61672 } catch (\Exception $e) {
 61673 self::await($loop, $downloader->cleanup($type, $package, $path, $prevPackage));
 61674 throw $e;
 61675 }
 61676 
 61677 self::await($loop, $downloader->cleanup($type, $package, $path, $prevPackage));
 61678 }
 61679 
 61680 
 61681 
 61682 
 61683 
 61684 
 61685 
 61686 
 61687 
 61688 public static function await(Loop $loop, PromiseInterface $promise = null)
 61689 {
 61690 if ($promise) {
 61691 $loop->wait(array($promise));
 61692 }
 61693 }
 61694 }
 61695 <?php
 61696 
 61697 
 61698 
 61699 
 61700 
 61701 
 61702 
 61703 
 61704 
 61705 
 61706 
 61707 namespace Composer\Util;
 61708 
 61709 
 61710 
 61711 
 61712 class Tar
 61713 {
 61714 
 61715 
 61716 
 61717 
 61718 
 61719 public static function getComposerJson($pathToArchive)
 61720 {
 61721 $phar = new \PharData($pathToArchive);
 61722 
 61723 if (!$phar->valid()) {
 61724 return null;
 61725 }
 61726 
 61727 return self::extractComposerJsonFromFolder($phar);
 61728 }
 61729 
 61730 
 61731 
 61732 
 61733 
 61734 
 61735 
 61736 
 61737 private static function extractComposerJsonFromFolder(\PharData $phar)
 61738 {
 61739 if (isset($phar['composer.json'])) {
 61740 return $phar['composer.json']->getContent();
 61741 }
 61742 
 61743 $topLevelPaths = array();
 61744 foreach ($phar as $folderFile) {
 61745 $name = $folderFile->getBasename();
 61746 
 61747 if ($folderFile->isDir()) {
 61748 $topLevelPaths[$name] = true;
 61749 if (\count($topLevelPaths) > 1) {
 61750 throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths)));
 61751 }
 61752 }
 61753 }
 61754 
 61755 $composerJsonPath = key($topLevelPaths).'/composer.json';
 61756 if ($topLevelPaths && isset($phar[$composerJsonPath])) {
 61757 return $phar[$composerJsonPath]->getContent();
 61758 }
 61759 
 61760 throw new \RuntimeException('No composer.json found either at the top level or within the topmost directory');
 61761 }
 61762 }
 61763 <?php
 61764 
 61765 
 61766 
 61767 
 61768 
 61769 
 61770 
 61771 
 61772 
 61773 
 61774 
 61775 namespace Composer\Util;
 61776 
 61777 use Composer\CaBundle\CaBundle;
 61778 use Composer\Pcre\Preg;
 61779 
 61780 
 61781 
 61782 
 61783 final class TlsHelper
 61784 {
 61785 
 61786 
 61787 
 61788 
 61789 
 61790 
 61791 
 61792 
 61793 
 61794 public static function checkCertificateHost($certificate, $hostname, &$cn = null)
 61795 {
 61796 $names = self::getCertificateNames($certificate);
 61797 
 61798 if (empty($names)) {
 61799 return false;
 61800 }
 61801 
 61802 $combinedNames = array_merge($names['san'], array($names['cn']));
 61803 $hostname = strtolower($hostname);
 61804 
 61805 foreach ($combinedNames as $certName) {
 61806 $matcher = self::certNameMatcher($certName);
 61807 
 61808 if ($matcher && $matcher($hostname)) {
 61809 $cn = $names['cn'];
 61810 
 61811 return true;
 61812 }
 61813 }
 61814 
 61815 return false;
 61816 }
 61817 
 61818 
 61819 
 61820 
 61821 
 61822 
 61823 
 61824 
 61825 public static function getCertificateNames($certificate)
 61826 {
 61827 if (is_array($certificate)) {
 61828 $info = $certificate;
 61829 } elseif (CaBundle::isOpensslParseSafe()) {
 61830 $info = openssl_x509_parse($certificate, false);
 61831 }
 61832 
 61833 if (!isset($info['subject']['commonName'])) {
 61834 return null;
 61835 }
 61836 
 61837 $commonName = strtolower($info['subject']['commonName']);
 61838 $subjectAltNames = array();
 61839 
 61840 if (isset($info['extensions']['subjectAltName'])) {
 61841 $subjectAltNames = Preg::split('{\s*,\s*}', $info['extensions']['subjectAltName']);
 61842 $subjectAltNames = array_filter(array_map(function ($name) {
 61843 if (0 === strpos($name, 'DNS:')) {
 61844 return strtolower(ltrim(substr($name, 4)));
 61845 }
 61846 
 61847 return null;
 61848 }, $subjectAltNames));
 61849 $subjectAltNames = array_values($subjectAltNames);
 61850 }
 61851 
 61852 return array(
 61853 'cn' => $commonName,
 61854 'san' => $subjectAltNames,
 61855 );
 61856 }
 61857 
 61858 
 61859 
 61860 
 61861 
 61862 
 61863 
 61864 
 61865 
 61866 
 61867 
 61868 
 61869 
 61870 
 61871 
 61872 
 61873 
 61874 
 61875 
 61876 
 61877 
 61878 
 61879 
 61880 
 61881 
 61882 
 61883 
 61884 
 61885 
 61886 
 61887 
 61888 
 61889 
 61890 
 61891 
 61892 
 61893 
 61894 
 61895 
 61896 
 61897 
 61898 
 61899 
 61900 public static function getCertificateFingerprint($certificate)
 61901 {
 61902 $pubkeydetails = openssl_pkey_get_details(openssl_get_publickey($certificate));
 61903 $pubkeypem = $pubkeydetails['key'];
 61904 
 61905 $start = '-----BEGIN PUBLIC KEY-----';
 61906 $end = '-----END PUBLIC KEY-----';
 61907 $pemtrim = substr($pubkeypem, strpos($pubkeypem, $start) + strlen($start), (strlen($pubkeypem) - strpos($pubkeypem, $end)) * (-1));
 61908 $der = base64_decode($pemtrim);
 61909 
 61910 return sha1($der);
 61911 }
 61912 
 61913 
 61914 
 61915 
 61916 
 61917 
 61918 
 61919 
 61920 
 61921 public static function isOpensslParseSafe()
 61922 {
 61923 return CaBundle::isOpensslParseSafe();
 61924 }
 61925 
 61926 
 61927 
 61928 
 61929 
 61930 
 61931 
 61932 
 61933 private static function certNameMatcher($certName)
 61934 {
 61935 $wildcards = substr_count($certName, '*');
 61936 
 61937 if (0 === $wildcards) {
 61938 
 61939 return function ($hostname) use ($certName) {
 61940 return $hostname === $certName;
 61941 };
 61942 }
 61943 
 61944 if (1 === $wildcards) {
 61945 $components = explode('.', $certName);
 61946 
 61947 if (3 > count($components)) {
 61948 
 61949 return null;
 61950 }
 61951 
 61952 $firstComponent = $components[0];
 61953 
 61954 
 61955 if ('*' !== $firstComponent[strlen($firstComponent) - 1]) {
 61956 return null;
 61957 }
 61958 
 61959 $wildcardRegex = preg_quote($certName);
 61960 $wildcardRegex = str_replace('\\*', '[a-z0-9-]+', $wildcardRegex);
 61961 $wildcardRegex = "{^{$wildcardRegex}$}";
 61962 
 61963 return function ($hostname) use ($wildcardRegex) {
 61964 return Preg::isMatch($wildcardRegex, $hostname);
 61965 };
 61966 }
 61967 
 61968 return null;
 61969 }
 61970 }
 61971 <?php
 61972 
 61973 
 61974 
 61975 
 61976 
 61977 
 61978 
 61979 
 61980 
 61981 
 61982 
 61983 namespace Composer\Util;
 61984 
 61985 use Composer\Config;
 61986 use Composer\Pcre\Preg;
 61987 
 61988 
 61989 
 61990 
 61991 class Url
 61992 {
 61993 
 61994 
 61995 
 61996 
 61997 
 61998 
 61999 public static function updateDistReference(Config $config, $url, $ref)
 62000 {
 62001 $host = parse_url($url, PHP_URL_HOST);
 62002 
 62003 if ($host === 'api.github.com' || $host === 'github.com' || $host === 'www.github.com') {
 62004 if (Preg::isMatch('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i', $url, $match)) {
 62005 
 62006 $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
 62007 } elseif (Preg::isMatch('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i', $url, $match)) {
 62008 
 62009 $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
 62010 } elseif (Preg::isMatch('{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i', $url, $match)) {
 62011 
 62012 $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
 62013 }
 62014 } elseif ($host === 'bitbucket.org' || $host === 'www.bitbucket.org') {
 62015 if (Preg::isMatch('{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i', $url, $match)) {
 62016 
 62017 $url = 'https://bitbucket.org/' . $match[1] . '/'. $match[2] . '/get/' . $ref . '.' . $match[4];
 62018 }
 62019 } elseif ($host === 'gitlab.com' || $host === 'www.gitlab.com') {
 62020 if (Preg::isMatch('{^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$}i', $url, $match)) {
 62021 
 62022 $url = 'https://gitlab.com/api/v4/projects/' . $match[1] . '/repository/archive.' . $match[2] . '?sha=' . $ref;
 62023 }
 62024 } elseif (in_array($host, $config->get('github-domains'), true)) {
 62025 $url = Preg::replace('{(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$}i', '$1/'.$ref, $url);
 62026 } elseif (in_array($host, $config->get('gitlab-domains'), true)) {
 62027 $url = Preg::replace('{(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$}i', '${1}'.$ref, $url);
 62028 }
 62029 
 62030 return $url;
 62031 }
 62032 
 62033 
 62034 
 62035 
 62036 
 62037 public static function getOrigin(Config $config, $url)
 62038 {
 62039 if (0 === strpos($url, 'file://')) {
 62040 return $url;
 62041 }
 62042 
 62043 $origin = (string) parse_url($url, PHP_URL_HOST);
 62044 if ($port = parse_url($url, PHP_URL_PORT)) {
 62045 $origin .= ':'.$port;
 62046 }
 62047 
 62048 if (strpos($origin, '.github.com') === (strlen($origin) - 11)) {
 62049 return 'github.com';
 62050 }
 62051 
 62052 if ($origin === 'repo.packagist.org') {
 62053 return 'packagist.org';
 62054 }
 62055 
 62056 if ($origin === '') {
 62057 $origin = $url;
 62058 }
 62059 
 62060 
 62061 
 62062 if (
 62063 is_array($config->get('gitlab-domains'))
 62064 && false === strpos($origin, '/')
 62065 && !in_array($origin, $config->get('gitlab-domains'))
 62066 ) {
 62067 foreach ($config->get('gitlab-domains') as $gitlabDomain) {
 62068 if (0 === strpos($gitlabDomain, $origin)) {
 62069 return $gitlabDomain;
 62070 }
 62071 }
 62072 }
 62073 
 62074 return $origin;
 62075 }
 62076 
 62077 
 62078 
 62079 
 62080 
 62081 public static function sanitize($url)
 62082 {
 62083 
 62084 
 62085 $url = Preg::replace('{([&?]access_token=)[^&]+}', '$1***', $url);
 62086 
 62087 $url = Preg::replaceCallback('{^(?P<prefix>[a-z0-9]+://)?(?P<user>[^:/\s@]+):(?P<password>[^@\s/]+)@}i', function ($m) {
 62088 
 62089 if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) {
 62090 return $m['prefix'].'***:***@';
 62091 }
 62092 
 62093 return $m['prefix'].$m['user'].':***@';
 62094 }, $url);
 62095 
 62096 return $url;
 62097 }
 62098 }
 62099 <?php
 62100 
 62101 
 62102 
 62103 
 62104 
 62105 
 62106 
 62107 
 62108 
 62109 
 62110 
 62111 namespace Composer\Util;
 62112 
 62113 
 62114 
 62115 
 62116 class Zip
 62117 {
 62118 
 62119 
 62120 
 62121 
 62122 
 62123 
 62124 
 62125 public static function getComposerJson($pathToZip)
 62126 {
 62127 if (!extension_loaded('zip')) {
 62128 throw new \RuntimeException('The Zip Util requires PHP\'s zip extension');
 62129 }
 62130 
 62131 $zip = new \ZipArchive();
 62132 if ($zip->open($pathToZip) !== true) {
 62133 return null;
 62134 }
 62135 
 62136 if (0 == $zip->numFiles) {
 62137 $zip->close();
 62138 
 62139 return null;
 62140 }
 62141 
 62142 $foundFileIndex = self::locateFile($zip, 'composer.json');
 62143 
 62144 $content = null;
 62145 $configurationFileName = $zip->getNameIndex($foundFileIndex);
 62146 $stream = $zip->getStream($configurationFileName);
 62147 
 62148 if (false !== $stream) {
 62149 $content = stream_get_contents($stream);
 62150 }
 62151 
 62152 $zip->close();
 62153 
 62154 return $content;
 62155 }
 62156 
 62157 
 62158 
 62159 
 62160 
 62161 
 62162 
 62163 
 62164 
 62165 
 62166 private static function locateFile(\ZipArchive $zip, $filename)
 62167 {
 62168 
 62169 if (false !== ($index = $zip->locateName($filename)) && $zip->getFromIndex($index) !== false) {
 62170 return $index;
 62171 }
 62172 
 62173 $topLevelPaths = array();
 62174 for ($i = 0; $i < $zip->numFiles; $i++) {
 62175 $name = $zip->getNameIndex($i);
 62176 $dirname = dirname($name);
 62177 
 62178 
 62179 if (strpos($name, '__MACOSX') !== false) {
 62180 continue;
 62181 }
 62182 
 62183 
 62184 if ($dirname === '.') {
 62185 $topLevelPaths[$name] = true;
 62186 if (\count($topLevelPaths) > 1) {
 62187 throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths)));
 62188 }
 62189 continue;
 62190 }
 62191 
 62192 
 62193 if (false === strpos($dirname, '\\') && false === strpos($dirname, '/')) {
 62194 $topLevelPaths[$dirname.'/'] = true;
 62195 if (\count($topLevelPaths) > 1) {
 62196 throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths)));
 62197 }
 62198 }
 62199 }
 62200 
 62201 if ($topLevelPaths && false !== ($index = $zip->locateName(key($topLevelPaths).$filename)) && $zip->getFromIndex($index) !== false) {
 62202 return $index;
 62203 }
 62204 
 62205 throw new \RuntimeException('No composer.json found either at the top level or within the topmost directory');
 62206 }
 62207 }
 62208 <?php
 62209 
 62210 
 62211 
 62212 
 62213 
 62214 
 62215 
 62216 
 62217 
 62218 
 62219 
 62220 
 62221 
 62222 
 62223 
 62224 function includeIfExists($file)
 62225 {
 62226 return file_exists($file) ? include $file : null;
 62227 }
 62228 
 62229 if ((!$loader = includeIfExists(__DIR__.'/../vendor/autoload.php')) && (!$loader = includeIfExists(__DIR__.'/../../../autoload.php'))) {
 62230 echo 'You must set up the project dependencies using `composer install`'.PHP_EOL.
 62231 'See https://getcomposer.org/download/ for instructions on installing Composer'.PHP_EOL;
 62232 exit(1);
 62233 }
 62234 
 62235 return $loader;
 62236 <?php
 62237 
 62238 /*
 62239  * This file is part of Composer.
 62240  *
 62241  * (c) Nils Adermann <naderman@naderman.de>
 62242  *     Jordi Boggiano <j.boggiano@seld.be>
 62243  *
 62244  * For the full copyright and license information, please view the LICENSE
 62245  * file that was distributed with this source code.
 62246  */
 62247 
 62248 namespace Composer\Autoload;
 62249 
 62250 /**
 62251  * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 62252  *
 62253  *     $loader = new \Composer\Autoload\ClassLoader();
 62254  *
 62255  *     // register classes with namespaces
 62256  *     $loader->add('Symfony\Component', __DIR__.'/component');
 62257  *     $loader->add('Symfony',           __DIR__.'/framework');
 62258  *
 62259  *     // activate the autoloader
 62260  *     $loader->register();
 62261  *
 62262  *     // to enable searching the include path (eg. for PEAR packages)
 62263  *     $loader->setUseIncludePath(true);
 62264  *
 62265  * In this example, if you try to use a class in the Symfony\Component
 62266  * namespace or one of its children (Symfony\Component\Console for instance),
 62267  * the autoloader will first look for the class under the component/
 62268  * directory, and it will then fallback to the framework/ directory if not
 62269  * found before giving up.
 62270  *
 62271  * This class is loosely based on the Symfony UniversalClassLoader.
 62272  *
 62273  * @author Fabien Potencier <fabien@symfony.com>
 62274  * @author Jordi Boggiano <j.boggiano@seld.be>
 62275  * @see    https://www.php-fig.org/psr/psr-0/
 62276  * @see    https://www.php-fig.org/psr/psr-4/
 62277  */
 62278 class ClassLoader
 62279 {
 62280     /** @var ?string */
 62281     private $vendorDir;
 62282 
 62283     // PSR-4
 62284     /**
 62285      * @var array[]
 62286      * @psalm-var array<string, array<string, int>>
 62287      */
 62288     private $prefixLengthsPsr4 = array();
 62289     /**
 62290      * @var array[]
 62291      * @psalm-var array<string, array<int, string>>
 62292      */
 62293     private $prefixDirsPsr4 = array();
 62294     /**
 62295      * @var array[]
 62296      * @psalm-var array<string, string>
 62297      */
 62298     private $fallbackDirsPsr4 = array();
 62299 
 62300     // PSR-0
 62301     /**
 62302      * @var array[]
 62303      * @psalm-var array<string, array<string, string[]>>
 62304      */
 62305     private $prefixesPsr0 = array();
 62306     /**
 62307      * @var array[]
 62308      * @psalm-var array<string, string>
 62309      */
 62310     private $fallbackDirsPsr0 = array();
 62311 
 62312     /** @var bool */
 62313     private $useIncludePath = false;
 62314 
 62315     /**
 62316      * @var string[]
 62317      * @psalm-var array<string, string>
 62318      */
 62319     private $classMap = array();
 62320 
 62321     /** @var bool */
 62322     private $classMapAuthoritative = false;
 62323 
 62324     /**
 62325      * @var bool[]
 62326      * @psalm-var array<string, bool>
 62327      */
 62328     private $missingClasses = array();
 62329 
 62330     /** @var ?string */
 62331     private $apcuPrefix;
 62332 
 62333     /**
 62334      * @var self[]
 62335      */
 62336     private static $registeredLoaders = array();
 62337 
 62338     /**
 62339      * @param ?string $vendorDir
 62340      */
 62341     public function __construct($vendorDir = null)
 62342     {
 62343         $this->vendorDir = $vendorDir;
 62344     }
 62345 
 62346     /**
 62347      * @return string[]
 62348      */
 62349     public function getPrefixes()
 62350     {
 62351         if (!empty($this->prefixesPsr0)) {
 62352             return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
 62353         }
 62354 
 62355         return array();
 62356     }
 62357 
 62358     /**
 62359      * @return array[]
 62360      * @psalm-return array<string, array<int, string>>
 62361      */
 62362     public function getPrefixesPsr4()
 62363     {
 62364         return $this->prefixDirsPsr4;
 62365     }
 62366 
 62367     /**
 62368      * @return array[]
 62369      * @psalm-return array<string, string>
 62370      */
 62371     public function getFallbackDirs()
 62372     {
 62373         return $this->fallbackDirsPsr0;
 62374     }
 62375 
 62376     /**
 62377      * @return array[]
 62378      * @psalm-return array<string, string>
 62379      */
 62380     public function getFallbackDirsPsr4()
 62381     {
 62382         return $this->fallbackDirsPsr4;
 62383     }
 62384 
 62385     /**
 62386      * @return string[] Array of classname => path
 62387      * @psalm-return array<string, string>
 62388      */
 62389     public function getClassMap()
 62390     {
 62391         return $this->classMap;
 62392     }
 62393 
 62394     /**
 62395      * @param string[] $classMap Class to filename map
 62396      * @psalm-param array<string, string> $classMap
 62397      *
 62398      * @return void
 62399      */
 62400     public function addClassMap(array $classMap)
 62401     {
 62402         if ($this->classMap) {
 62403             $this->classMap = array_merge($this->classMap, $classMap);
 62404         } else {
 62405             $this->classMap = $classMap;
 62406         }
 62407     }
 62408 
 62409     /**
 62410      * Registers a set of PSR-0 directories for a given prefix, either
 62411      * appending or prepending to the ones previously set for this prefix.
 62412      *
 62413      * @param string          $prefix  The prefix
 62414      * @param string[]|string $paths   The PSR-0 root directories
 62415      * @param bool            $prepend Whether to prepend the directories
 62416      *
 62417      * @return void
 62418      */
 62419     public function add($prefix, $paths, $prepend = false)
 62420     {
 62421         if (!$prefix) {
 62422             if ($prepend) {
 62423                 $this->fallbackDirsPsr0 = array_merge(
 62424                     (array) $paths,
 62425                     $this->fallbackDirsPsr0
 62426                 );
 62427             } else {
 62428                 $this->fallbackDirsPsr0 = array_merge(
 62429                     $this->fallbackDirsPsr0,
 62430                     (array) $paths
 62431                 );
 62432             }
 62433 
 62434             return;
 62435         }
 62436 
 62437         $first = $prefix[0];
 62438         if (!isset($this->prefixesPsr0[$first][$prefix])) {
 62439             $this->prefixesPsr0[$first][$prefix] = (array) $paths;
 62440 
 62441             return;
 62442         }
 62443         if ($prepend) {
 62444             $this->prefixesPsr0[$first][$prefix] = array_merge(
 62445                 (array) $paths,
 62446                 $this->prefixesPsr0[$first][$prefix]
 62447             );
 62448         } else {
 62449             $this->prefixesPsr0[$first][$prefix] = array_merge(
 62450                 $this->prefixesPsr0[$first][$prefix],
 62451                 (array) $paths
 62452             );
 62453         }
 62454     }
 62455 
 62456     /**
 62457      * Registers a set of PSR-4 directories for a given namespace, either
 62458      * appending or prepending to the ones previously set for this namespace.
 62459      *
 62460      * @param string          $prefix  The prefix/namespace, with trailing '\\'
 62461      * @param string[]|string $paths   The PSR-4 base directories
 62462      * @param bool            $prepend Whether to prepend the directories
 62463      *
 62464      * @throws \InvalidArgumentException
 62465      *
 62466      * @return void
 62467      */
 62468     public function addPsr4($prefix, $paths, $prepend = false)
 62469     {
 62470         if (!$prefix) {
 62471             // Register directories for the root namespace.
 62472             if ($prepend) {
 62473                 $this->fallbackDirsPsr4 = array_merge(
 62474                     (array) $paths,
 62475                     $this->fallbackDirsPsr4
 62476                 );
 62477             } else {
 62478                 $this->fallbackDirsPsr4 = array_merge(
 62479                     $this->fallbackDirsPsr4,
 62480                     (array) $paths
 62481                 );
 62482             }
 62483         } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
 62484             // Register directories for a new namespace.
 62485             $length = strlen($prefix);
 62486             if ('\\' !== $prefix[$length - 1]) {
 62487                 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
 62488             }
 62489             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
 62490             $this->prefixDirsPsr4[$prefix] = (array) $paths;
 62491         } elseif ($prepend) {
 62492             // Prepend directories for an already registered namespace.
 62493             $this->prefixDirsPsr4[$prefix] = array_merge(
 62494                 (array) $paths,
 62495                 $this->prefixDirsPsr4[$prefix]
 62496             );
 62497         } else {
 62498             // Append directories for an already registered namespace.
 62499             $this->prefixDirsPsr4[$prefix] = array_merge(
 62500                 $this->prefixDirsPsr4[$prefix],
 62501                 (array) $paths
 62502             );
 62503         }
 62504     }
 62505 
 62506     /**
 62507      * Registers a set of PSR-0 directories for a given prefix,
 62508      * replacing any others previously set for this prefix.
 62509      *
 62510      * @param string          $prefix The prefix
 62511      * @param string[]|string $paths  The PSR-0 base directories
 62512      *
 62513      * @return void
 62514      */
 62515     public function set($prefix, $paths)
 62516     {
 62517         if (!$prefix) {
 62518             $this->fallbackDirsPsr0 = (array) $paths;
 62519         } else {
 62520             $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
 62521         }
 62522     }
 62523 
 62524     /**
 62525      * Registers a set of PSR-4 directories for a given namespace,
 62526      * replacing any others previously set for this namespace.
 62527      *
 62528      * @param string          $prefix The prefix/namespace, with trailing '\\'
 62529      * @param string[]|string $paths  The PSR-4 base directories
 62530      *
 62531      * @throws \InvalidArgumentException
 62532      *
 62533      * @return void
 62534      */
 62535     public function setPsr4($prefix, $paths)
 62536     {
 62537         if (!$prefix) {
 62538             $this->fallbackDirsPsr4 = (array) $paths;
 62539         } else {
 62540             $length = strlen($prefix);
 62541             if ('\\' !== $prefix[$length - 1]) {
 62542                 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
 62543             }
 62544             $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
 62545             $this->prefixDirsPsr4[$prefix] = (array) $paths;
 62546         }
 62547     }
 62548 
 62549     /**
 62550      * Turns on searching the include path for class files.
 62551      *
 62552      * @param bool $useIncludePath
 62553      *
 62554      * @return void
 62555      */
 62556     public function setUseIncludePath($useIncludePath)
 62557     {
 62558         $this->useIncludePath = $useIncludePath;
 62559     }
 62560 
 62561     /**
 62562      * Can be used to check if the autoloader uses the include path to check
 62563      * for classes.
 62564      *
 62565      * @return bool
 62566      */
 62567     public function getUseIncludePath()
 62568     {
 62569         return $this->useIncludePath;
 62570     }
 62571 
 62572     /**
 62573      * Turns off searching the prefix and fallback directories for classes
 62574      * that have not been registered with the class map.
 62575      *
 62576      * @param bool $classMapAuthoritative
 62577      *
 62578      * @return void
 62579      */
 62580     public function setClassMapAuthoritative($classMapAuthoritative)
 62581     {
 62582         $this->classMapAuthoritative = $classMapAuthoritative;
 62583     }
 62584 
 62585     /**
 62586      * Should class lookup fail if not found in the current class map?
 62587      *
 62588      * @return bool
 62589      */
 62590     public function isClassMapAuthoritative()
 62591     {
 62592         return $this->classMapAuthoritative;
 62593     }
 62594 
 62595     /**
 62596      * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
 62597      *
 62598      * @param string|null $apcuPrefix
 62599      *
 62600      * @return void
 62601      */
 62602     public function setApcuPrefix($apcuPrefix)
 62603     {
 62604         $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
 62605     }
 62606 
 62607     /**
 62608      * The APCu prefix in use, or null if APCu caching is not enabled.
 62609      *
 62610      * @return string|null
 62611      */
 62612     public function getApcuPrefix()
 62613     {
 62614         return $this->apcuPrefix;
 62615     }
 62616 
 62617     /**
 62618      * Registers this instance as an autoloader.
 62619      *
 62620      * @param bool $prepend Whether to prepend the autoloader or not
 62621      *
 62622      * @return void
 62623      */
 62624     public function register($prepend = false)
 62625     {
 62626         spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 62627 
 62628         if (null === $this->vendorDir) {
 62629             return;
 62630         }
 62631 
 62632         if ($prepend) {
 62633             self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
 62634         } else {
 62635             unset(self::$registeredLoaders[$this->vendorDir]);
 62636             self::$registeredLoaders[$this->vendorDir] = $this;
 62637         }
 62638     }
 62639 
 62640     /**
 62641      * Unregisters this instance as an autoloader.
 62642      *
 62643      * @return void
 62644      */
 62645     public function unregister()
 62646     {
 62647         spl_autoload_unregister(array($this, 'loadClass'));
 62648 
 62649         if (null !== $this->vendorDir) {
 62650             unset(self::$registeredLoaders[$this->vendorDir]);
 62651         }
 62652     }
 62653 
 62654     /**
 62655      * Loads the given class or interface.
 62656      *
 62657      * @param  string    $class The name of the class
 62658      * @return true|null True if loaded, null otherwise
 62659      */
 62660     public function loadClass($class)
 62661     {
 62662         if ($file = $this->findFile($class)) {
 62663             includeFile($file);
 62664 
 62665             return true;
 62666         }
 62667 
 62668         return null;
 62669     }
 62670 
 62671     /**
 62672      * Finds the path to the file where the class is defined.
 62673      *
 62674      * @param string $class The name of the class
 62675      *
 62676      * @return string|false The path if found, false otherwise
 62677      */
 62678     public function findFile($class)
 62679     {
 62680         // class map lookup
 62681         if (isset($this->classMap[$class])) {
 62682             return $this->classMap[$class];
 62683         }
 62684         if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
 62685             return false;
 62686         }
 62687         if (null !== $this->apcuPrefix) {
 62688             $file = apcu_fetch($this->apcuPrefix.$class, $hit);
 62689             if ($hit) {
 62690                 return $file;
 62691             }
 62692         }
 62693 
 62694         $file = $this->findFileWithExtension($class, '.php');
 62695 
 62696         // Search for Hack files if we are running on HHVM
 62697         if (false === $file && defined('HHVM_VERSION')) {
 62698             $file = $this->findFileWithExtension($class, '.hh');
 62699         }
 62700 
 62701         if (null !== $this->apcuPrefix) {
 62702             apcu_add($this->apcuPrefix.$class, $file);
 62703         }
 62704 
 62705         if (false === $file) {
 62706             // Remember that this class does not exist.
 62707             $this->missingClasses[$class] = true;
 62708         }
 62709 
 62710         return $file;
 62711     }
 62712 
 62713     /**
 62714      * Returns the currently registered loaders indexed by their corresponding vendor directories.
 62715      *
 62716      * @return self[]
 62717      */
 62718     public static function getRegisteredLoaders()
 62719     {
 62720         return self::$registeredLoaders;
 62721     }
 62722 
 62723     /**
 62724      * @param  string       $class
 62725      * @param  string       $ext
 62726      * @return string|false
 62727      */
 62728     private function findFileWithExtension($class, $ext)
 62729     {
 62730         // PSR-4 lookup
 62731         $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
 62732 
 62733         $first = $class[0];
 62734         if (isset($this->prefixLengthsPsr4[$first])) {
 62735             $subPath = $class;
 62736             while (false !== $lastPos = strrpos($subPath, '\\')) {
 62737                 $subPath = substr($subPath, 0, $lastPos);
 62738                 $search = $subPath . '\\';
 62739                 if (isset($this->prefixDirsPsr4[$search])) {
 62740                     $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
 62741                     foreach ($this->prefixDirsPsr4[$search] as $dir) {
 62742                         if (file_exists($file = $dir . $pathEnd)) {
 62743                             return $file;
 62744                         }
 62745                     }
 62746                 }
 62747             }
 62748         }
 62749 
 62750         // PSR-4 fallback dirs
 62751         foreach ($this->fallbackDirsPsr4 as $dir) {
 62752             if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
 62753                 return $file;
 62754             }
 62755         }
 62756 
 62757         // PSR-0 lookup
 62758         if (false !== $pos = strrpos($class, '\\')) {
 62759             // namespaced class name
 62760             $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
 62761                 . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
 62762         } else {
 62763             // PEAR-like class name
 62764             $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
 62765         }
 62766 
 62767         if (isset($this->prefixesPsr0[$first])) {
 62768             foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
 62769                 if (0 === strpos($class, $prefix)) {
 62770                     foreach ($dirs as $dir) {
 62771                         if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
 62772                             return $file;
 62773                         }
 62774                     }
 62775                 }
 62776             }
 62777         }
 62778 
 62779         // PSR-0 fallback dirs
 62780         foreach ($this->fallbackDirsPsr0 as $dir) {
 62781             if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
 62782                 return $file;
 62783             }
 62784         }
 62785 
 62786         // PSR-0 include paths.
 62787         if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
 62788             return $file;
 62789         }
 62790 
 62791         return false;
 62792     }
 62793 }
 62794 
 62795 /**
 62796  * Scope isolated include.
 62797  *
 62798  * Prevents access to $this/self from included files.
 62799  *
 62800  * @param  string $file
 62801  * @return void
 62802  * @private
 62803  */
 62804 function includeFile($file)
 62805 {
 62806     include $file;
 62807 }
 62808 <?php
 62809 
 62810 /*
 62811  * This file is part of Composer.
 62812  *
 62813  * (c) Nils Adermann <naderman@naderman.de>
 62814  *     Jordi Boggiano <j.boggiano@seld.be>
 62815  *
 62816  * For the full copyright and license information, please view the LICENSE
 62817  * file that was distributed with this source code.
 62818  */
 62819 
 62820 namespace Composer;
 62821 
 62822 use Composer\Autoload\ClassLoader;
 62823 use Composer\Semver\VersionParser;
 62824 
 62825 /**
 62826  * This class is copied in every Composer installed project and available to all
 62827  *
 62828  * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
 62829  *
 62830  * To require its presence, you can require `composer-runtime-api ^2.0`
 62831  */
 62832 class InstalledVersions
 62833 {
 62834     /**
 62835      * @var mixed[]|null
 62836      * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
 62837      */
 62838     private static $installed;
 62839 
 62840     /**
 62841      * @var bool|null
 62842      */
 62843     private static $canGetVendors;
 62844 
 62845     /**
 62846      * @var array[]
 62847      * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
 62848      */
 62849     private static $installedByVendor = array();
 62850 
 62851     /**
 62852      * Returns a list of all package names which are present, either by being installed, replaced or provided
 62853      *
 62854      * @return string[]
 62855      * @psalm-return list<string>
 62856      */
 62857     public static function getInstalledPackages()
 62858     {
 62859         $packages = array();
 62860         foreach (self::getInstalled() as $installed) {
 62861             $packages[] = array_keys($installed['versions']);
 62862         }
 62863 
 62864         if (1 === \count($packages)) {
 62865             return $packages[0];
 62866         }
 62867 
 62868         return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
 62869     }
 62870 
 62871     /**
 62872      * Returns a list of all package names with a specific type e.g. 'library'
 62873      *
 62874      * @param  string   $type
 62875      * @return string[]
 62876      * @psalm-return list<string>
 62877      */
 62878     public static function getInstalledPackagesByType($type)
 62879     {
 62880         $packagesByType = array();
 62881 
 62882         foreach (self::getInstalled() as $installed) {
 62883             foreach ($installed['versions'] as $name => $package) {
 62884                 if (isset($package['type']) && $package['type'] === $type) {
 62885                     $packagesByType[] = $name;
 62886                 }
 62887             }
 62888         }
 62889 
 62890         return $packagesByType;
 62891     }
 62892 
 62893     /**
 62894      * Checks whether the given package is installed
 62895      *
 62896      * This also returns true if the package name is provided or replaced by another package
 62897      *
 62898      * @param  string $packageName
 62899      * @param  bool   $includeDevRequirements
 62900      * @return bool
 62901      */
 62902     public static function isInstalled($packageName, $includeDevRequirements = true)
 62903     {
 62904         foreach (self::getInstalled() as $installed) {
 62905             if (isset($installed['versions'][$packageName])) {
 62906                 return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
 62907             }
 62908         }
 62909 
 62910         return false;
 62911     }
 62912 
 62913     /**
 62914      * Checks whether the given package satisfies a version constraint
 62915      *
 62916      * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
 62917      *
 62918      *   Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
 62919      *
 62920      * @param  VersionParser $parser      Install composer/semver to have access to this class and functionality
 62921      * @param  string        $packageName
 62922      * @param  string|null   $constraint  A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
 62923      * @return bool
 62924      */
 62925     public static function satisfies(VersionParser $parser, $packageName, $constraint)
 62926     {
 62927         $constraint = $parser->parseConstraints($constraint);
 62928         $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
 62929 
 62930         return $provided->matches($constraint);
 62931     }
 62932 
 62933     /**
 62934      * Returns a version constraint representing all the range(s) which are installed for a given package
 62935      *
 62936      * It is easier to use this via isInstalled() with the $constraint argument if you need to check
 62937      * whether a given version of a package is installed, and not just whether it exists
 62938      *
 62939      * @param  string $packageName
 62940      * @return string Version constraint usable with composer/semver
 62941      */
 62942     public static function getVersionRanges($packageName)
 62943     {
 62944         foreach (self::getInstalled() as $installed) {
 62945             if (!isset($installed['versions'][$packageName])) {
 62946                 continue;
 62947             }
 62948 
 62949             $ranges = array();
 62950             if (isset($installed['versions'][$packageName]['pretty_version'])) {
 62951                 $ranges[] = $installed['versions'][$packageName]['pretty_version'];
 62952             }
 62953             if (array_key_exists('aliases', $installed['versions'][$packageName])) {
 62954                 $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
 62955             }
 62956             if (array_key_exists('replaced', $installed['versions'][$packageName])) {
 62957                 $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
 62958             }
 62959             if (array_key_exists('provided', $installed['versions'][$packageName])) {
 62960                 $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
 62961             }
 62962 
 62963             return implode(' || ', $ranges);
 62964         }
 62965 
 62966         throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 62967     }
 62968 
 62969     /**
 62970      * @param  string      $packageName
 62971      * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
 62972      */
 62973     public static function getVersion($packageName)
 62974     {
 62975         foreach (self::getInstalled() as $installed) {
 62976             if (!isset($installed['versions'][$packageName])) {
 62977                 continue;
 62978             }
 62979 
 62980             if (!isset($installed['versions'][$packageName]['version'])) {
 62981                 return null;
 62982             }
 62983 
 62984             return $installed['versions'][$packageName]['version'];
 62985         }
 62986 
 62987         throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 62988     }
 62989 
 62990     /**
 62991      * @param  string      $packageName
 62992      * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
 62993      */
 62994     public static function getPrettyVersion($packageName)
 62995     {
 62996         foreach (self::getInstalled() as $installed) {
 62997             if (!isset($installed['versions'][$packageName])) {
 62998                 continue;
 62999             }
 63000 
 63001             if (!isset($installed['versions'][$packageName]['pretty_version'])) {
 63002                 return null;
 63003             }
 63004 
 63005             return $installed['versions'][$packageName]['pretty_version'];
 63006         }
 63007 
 63008         throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 63009     }
 63010 
 63011     /**
 63012      * @param  string      $packageName
 63013      * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
 63014      */
 63015     public static function getReference($packageName)
 63016     {
 63017         foreach (self::getInstalled() as $installed) {
 63018             if (!isset($installed['versions'][$packageName])) {
 63019                 continue;
 63020             }
 63021 
 63022             if (!isset($installed['versions'][$packageName]['reference'])) {
 63023                 return null;
 63024             }
 63025 
 63026             return $installed['versions'][$packageName]['reference'];
 63027         }
 63028 
 63029         throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 63030     }
 63031 
 63032     /**
 63033      * @param  string      $packageName
 63034      * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
 63035      */
 63036     public static function getInstallPath($packageName)
 63037     {
 63038         foreach (self::getInstalled() as $installed) {
 63039             if (!isset($installed['versions'][$packageName])) {
 63040                 continue;
 63041             }
 63042 
 63043             return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
 63044         }
 63045 
 63046         throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 63047     }
 63048 
 63049     /**
 63050      * @return array
 63051      * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
 63052      */
 63053     public static function getRootPackage()
 63054     {
 63055         $installed = self::getInstalled();
 63056 
 63057         return $installed[0]['root'];
 63058     }
 63059 
 63060     /**
 63061      * Returns the raw installed.php data for custom implementations
 63062      *
 63063      * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
 63064      * @return array[]
 63065      * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
 63066      */
 63067     public static function getRawData()
 63068     {
 63069         @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
 63070 
 63071         if (null === self::$installed) {
 63072             // only require the installed.php file if this file is loaded from its dumped location,
 63073             // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
 63074             if (substr(__DIR__, -8, 1) !== 'C') {
 63075                 self::$installed = include __DIR__ . '/installed.php';
 63076             } else {
 63077                 self::$installed = array();
 63078             }
 63079         }
 63080 
 63081         return self::$installed;
 63082     }
 63083 
 63084     /**
 63085      * Returns the raw data of all installed.php which are currently loaded for custom implementations
 63086      *
 63087      * @return array[]
 63088      * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
 63089      */
 63090     public static function getAllRawData()
 63091     {
 63092         return self::getInstalled();
 63093     }
 63094 
 63095     /**
 63096      * Lets you reload the static array from another file
 63097      *
 63098      * This is only useful for complex integrations in which a project needs to use
 63099      * this class but then also needs to execute another project's autoloader in process,
 63100      * and wants to ensure both projects have access to their version of installed.php.
 63101      *
 63102      * A typical case would be PHPUnit, where it would need to make sure it reads all
 63103      * the data it needs from this class, then call reload() with
 63104      * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
 63105      * the project in which it runs can then also use this class safely, without
 63106      * interference between PHPUnit's dependencies and the project's dependencies.
 63107      *
 63108      * @param  array[] $data A vendor/composer/installed.php data set
 63109      * @return void
 63110      *
 63111      * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
 63112      */
 63113     public static function reload($data)
 63114     {
 63115         self::$installed = $data;
 63116         self::$installedByVendor = array();
 63117     }
 63118 
 63119     /**
 63120      * @return array[]
 63121      * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
 63122      */
 63123     private static function getInstalled()
 63124     {
 63125         if (null === self::$canGetVendors) {
 63126             self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
 63127         }
 63128 
 63129         $installed = array();
 63130 
 63131         if (self::$canGetVendors) {
 63132             foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
 63133                 if (isset(self::$installedByVendor[$vendorDir])) {
 63134                     $installed[] = self::$installedByVendor[$vendorDir];
 63135                 } elseif (is_file($vendorDir.'/composer/installed.php')) {
 63136                     $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
 63137                     if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
 63138                         self::$installed = $installed[count($installed) - 1];
 63139                     }
 63140                 }
 63141             }
 63142         }
 63143 
 63144         if (null === self::$installed) {
 63145             // only require the installed.php file if this file is loaded from its dumped location,
 63146             // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
 63147             if (substr(__DIR__, -8, 1) !== 'C') {
 63148                 self::$installed = require __DIR__ . '/installed.php';
 63149             } else {
 63150                 self::$installed = array();
 63151             }
 63152         }
 63153         $installed[] = self::$installed;
 63154 
 63155         return $installed;
 63156     }
 63157 }
 63158 {
 63159     "$schema": "https://json-schema.org/draft-04/schema#",
 63160     "description": "A representation of packages metadata.",
 63161     "type": "object",
 63162     "oneOf": [
 63163         { "required": [ "packages" ] },
 63164         { "required": [ "providers" ] },
 63165         { "required": [ "provider-includes", "providers-url" ] }
 63166     ],
 63167     "properties": {
 63168         "packages": {
 63169             "type": ["object", "array"],
 63170             "description": "A hashmap of package names in the form of <vendor>/<name>.",
 63171             "additionalProperties": { "$ref": "#/definitions/versions" }
 63172         },
 63173         "providers-url": {
 63174             "type": "string",
 63175             "description": "Endpoint to retrieve provider data from, e.g. '/p/%package%$%hash%.json'."
 63176         },
 63177         "provider-includes": {
 63178             "type": "object",
 63179             "description": "A hashmap of provider listings.",
 63180             "additionalProperties": { "$ref": "#/definitions/provider" }
 63181         },
 63182         "providers": {
 63183             "type": "object",
 63184             "description": "A hashmap of package names in the form of <vendor>/<name>.",
 63185             "additionalProperties": { "$ref": "#/definitions/provider" }
 63186         },
 63187         "notify-batch": {
 63188             "type": "string",
 63189             "description": "Endpoint to call after multiple packages have been installed, e.g. '/downloads/'."
 63190         },
 63191         "search": {
 63192             "type": "string",
 63193             "description": "Endpoint that provides search capabilities, e.g. '/search.json?q=%query%&type=%type%'."
 63194         },
 63195         "warning": {
 63196             "type": "string",
 63197             "description": "A message that will be output by Composer as a warning when this source is consulted."
 63198         }
 63199     },
 63200     "definitions": {
 63201         "versions": {
 63202             "type": "object",
 63203             "description": "A hashmap of versions and their metadata.",
 63204             "additionalProperties": { "$ref": "#/definitions/version" }
 63205         },
 63206         "version": {
 63207             "type": "object",
 63208             "oneOf": [
 63209                 { "$ref": "#/definitions/package" },
 63210                 { "$ref": "#/definitions/metapackage" }
 63211             ]
 63212         },
 63213         "package-base": {
 63214             "properties": {
 63215                 "name": { "type": "string" },
 63216                 "type": { "type": "string" },
 63217                 "version": { "type": "string" },
 63218                 "version_normalized": {
 63219                     "type": "string",
 63220                     "description": "Normalized version, optional but can save computational time on client side."
 63221                 },
 63222                 "autoload": { "type": "object" },
 63223                 "require": { "type": "object" },
 63224                 "replace": { "type": "object" },
 63225                 "conflict": { "type": "object" },
 63226                 "provide": { "type": "object" },
 63227                 "time": { "type": "string" }
 63228             },
 63229             "additionalProperties": true
 63230         },
 63231         "package": {
 63232             "allOf": [
 63233                 { "$ref": "#/definitions/package-base" },
 63234                 {
 63235                     "properties": {
 63236                         "dist": { "type": "object" },
 63237                         "source": { "type": "object" }
 63238                     }
 63239                 },
 63240                 { "oneOf": [
 63241                     { "required": [ "name", "version", "source" ] },
 63242                     { "required": [ "name", "version", "dist" ] }
 63243                 ] }
 63244             ]
 63245         },
 63246         "metapackage": {
 63247             "allOf": [
 63248                 { "$ref": "#/definitions/package-base" },
 63249                 {
 63250                     "properties": {
 63251                         "type": { "type": "string", "enum": [ "metapackage" ] }
 63252                     },
 63253                     "required": [ "name", "version", "type" ]
 63254                 }
 63255             ]
 63256         },
 63257         "provider": {
 63258             "type": "object",
 63259             "properties": {
 63260                 "sha256": {
 63261                     "type": "string",
 63262                     "description": "Hash value that can be used to validate the resource."
 63263                 }
 63264             }
 63265         }
 63266     }
 63267 }
 63268 {
 63269     "$schema": "https://json-schema.org/draft-04/schema#",
 63270     "title": "Package",
 63271     "type": "object",
 63272     "properties": {
 63273         "name": {
 63274             "type": "string",
 63275             "description": "Package name, including 'vendor-name/' prefix.",
 63276             "pattern": "^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$"
 63277         },
 63278         "description": {
 63279             "type": "string",
 63280             "description": "Short package description."
 63281         },
 63282         "license": {
 63283             "type": ["string", "array"],
 63284             "description": "License name. Or an array of license names."
 63285         },
 63286         "type": {
 63287             "description": "Package type, either 'library' for common packages, 'composer-plugin' for plugins, 'metapackage' for empty packages, or a custom type ([a-z0-9-]+) defined by whatever project this package applies to.",
 63288             "type": "string",
 63289             "pattern": "^[a-z0-9-]+$"
 63290         },
 63291         "abandoned": {
 63292             "type": ["boolean", "string"],
 63293             "description": "Indicates whether this package has been abandoned, it can be boolean or a package name/URL pointing to a recommended alternative. Defaults to false."
 63294         },
 63295         "version": {
 63296             "type": "string",
 63297             "description": "Package version, see https://getcomposer.org/doc/04-schema.md#version for more info on valid schemes.",
 63298             "pattern": "^v?\\d+(\\.\\d+){0,3}|^dev-"
 63299         },
 63300         "default-branch": {
 63301             "type": ["boolean"],
 63302             "description": "Internal use only, do not specify this in composer.json. Indicates whether this version is the default branch of the linked VCS repository. Defaults to false."
 63303         },
 63304         "non-feature-branches": {
 63305             "type": ["array"],
 63306             "description": "A set of string or regex patterns for non-numeric branch names that will not be handled as feature branches.",
 63307             "items": {
 63308                 "type": "string"
 63309             }
 63310         },
 63311         "keywords": {
 63312             "type": "array",
 63313             "items": {
 63314                 "type": "string",
 63315                 "description": "A tag/keyword that this package relates to."
 63316             }
 63317         },
 63318         "readme": {
 63319             "type": "string",
 63320             "description": "Relative path to the readme document."
 63321         },
 63322         "time": {
 63323             "type": "string",
 63324             "description": "Package release date, in 'YYYY-MM-DD', 'YYYY-MM-DD HH:MM:SS' or 'YYYY-MM-DDTHH:MM:SSZ' format."
 63325         },
 63326         "authors": {
 63327             "$ref": "#/definitions/authors"
 63328         },
 63329         "homepage": {
 63330             "type": "string",
 63331             "description": "Homepage URL for the project.",
 63332             "format": "uri"
 63333         },
 63334         "support": {
 63335             "type": "object",
 63336             "properties": {
 63337                 "email": {
 63338                     "type": "string",
 63339                     "description": "Email address for support.",
 63340                     "format": "email"
 63341                 },
 63342                 "issues": {
 63343                     "type": "string",
 63344                     "description": "URL to the issue tracker.",
 63345                     "format": "uri"
 63346                 },
 63347                 "forum": {
 63348                     "type": "string",
 63349                     "description": "URL to the forum.",
 63350                     "format": "uri"
 63351                 },
 63352                 "wiki": {
 63353                     "type": "string",
 63354                     "description": "URL to the wiki.",
 63355                     "format": "uri"
 63356                 },
 63357                 "irc": {
 63358                     "type": "string",
 63359                     "description": "IRC channel for support, as irc://server/channel.",
 63360                     "format": "uri"
 63361                 },
 63362                 "chat": {
 63363                     "type": "string",
 63364                     "description": "URL to the support chat.",
 63365                     "format": "uri"
 63366                 },
 63367                 "source": {
 63368                     "type": "string",
 63369                     "description": "URL to browse or download the sources.",
 63370                     "format": "uri"
 63371                 },
 63372                 "docs": {
 63373                     "type": "string",
 63374                     "description": "URL to the documentation.",
 63375                     "format": "uri"
 63376                 },
 63377                 "rss": {
 63378                     "type": "string",
 63379                     "description": "URL to the RSS feed.",
 63380                     "format": "uri"
 63381                 }
 63382             }
 63383         },
 63384         "funding": {
 63385             "type": "array",
 63386             "description": "A list of options to fund the development and maintenance of the package.",
 63387             "items": {
 63388                 "type": "object",
 63389                 "properties": {
 63390                     "type": {
 63391                         "type": "string",
 63392                         "description": "Type of funding or platform through which funding is possible."
 63393                     },
 63394                     "url": {
 63395                         "type": "string",
 63396                         "description": "URL to a website with details on funding and a way to fund the package.",
 63397                         "format": "uri"
 63398                     }
 63399                 }
 63400             }
 63401         },
 63402         "_comment": {
 63403             "type": ["array", "string"],
 63404             "description": "A key to store comments in"
 63405         },
 63406         "require": {
 63407             "type": "object",
 63408             "description": "This is an object of package name (keys) and version constraints (values) that are required to run this package.",
 63409             "additionalProperties": {
 63410                 "type": "string"
 63411             }
 63412         },
 63413         "require-dev": {
 63414             "type": "object",
 63415             "description": "This is an object of package name (keys) and version constraints (values) that this package requires for developing it (testing tools and such).",
 63416             "additionalProperties": {
 63417                 "type": "string"
 63418             }
 63419         },
 63420         "replace": {
 63421             "type": "object",
 63422             "description": "This is an object of package name (keys) and version constraints (values) that can be replaced by this package.",
 63423             "additionalProperties": {
 63424                 "type": "string"
 63425             }
 63426         },
 63427         "conflict": {
 63428             "type": "object",
 63429             "description": "This is an object of package name (keys) and version constraints (values) that conflict with this package.",
 63430             "additionalProperties": {
 63431                 "type": "string"
 63432             }
 63433         },
 63434         "provide": {
 63435             "type": "object",
 63436             "description": "This is an object of package name (keys) and version constraints (values) that this package provides in addition to this package's name.",
 63437             "additionalProperties": {
 63438                 "type": "string"
 63439             }
 63440         },
 63441         "suggest": {
 63442             "type": "object",
 63443             "description": "This is an object of package name (keys) and descriptions (values) that this package suggests work well with it (this will be suggested to the user during installation).",
 63444             "additionalProperties": {
 63445                 "type": "string"
 63446             }
 63447         },
 63448         "repositories": {
 63449             "type": ["object", "array"],
 63450             "description": "A set of additional repositories where packages can be found.",
 63451             "additionalProperties": {
 63452                 "anyOf": [
 63453                     { "$ref": "#/definitions/repository" },
 63454                     { "type": "boolean", "enum": [false] }
 63455                 ]
 63456             },
 63457             "items": {
 63458                 "anyOf": [
 63459                     { "$ref": "#/definitions/repository" },
 63460                     {
 63461                         "type": "object",
 63462                         "additionalProperties": { "type": "boolean", "enum": [false] },
 63463                         "minProperties": 1,
 63464                         "maxProperties": 1
 63465                     }
 63466                 ]
 63467             }
 63468         },
 63469         "minimum-stability": {
 63470             "type": ["string"],
 63471             "description": "The minimum stability the packages must have to be install-able. Possible values are: dev, alpha, beta, RC, stable.",
 63472             "enum": ["dev", "alpha", "beta", "rc", "RC", "stable"]
 63473         },
 63474         "prefer-stable": {
 63475             "type": ["boolean"],
 63476             "description": "If set to true, stable packages will be preferred to dev packages when possible, even if the minimum-stability allows unstable packages."
 63477         },
 63478         "autoload": {
 63479             "$ref": "#/definitions/autoload"
 63480         },
 63481         "autoload-dev": {
 63482             "type": "object",
 63483             "description": "Description of additional autoload rules for development purpose (eg. a test suite).",
 63484             "properties": {
 63485                 "psr-0": {
 63486                     "type": "object",
 63487                     "description": "This is an object of namespaces (keys) and the directories they can be found into (values, can be arrays of paths) by the autoloader.",
 63488                     "additionalProperties": {
 63489                         "type": ["string", "array"],
 63490                         "items": {
 63491                             "type": "string"
 63492                         }
 63493                     }
 63494                 },
 63495                 "psr-4": {
 63496                     "type": "object",
 63497                     "description": "This is an object of namespaces (keys) and the PSR-4 directories they can map to (values, can be arrays of paths) by the autoloader.",
 63498                     "additionalProperties": {
 63499                         "type": ["string", "array"],
 63500                         "items": {
 63501                             "type": "string"
 63502                         }
 63503                     }
 63504                 },
 63505                 "classmap": {
 63506                     "type": "array",
 63507                     "description": "This is an array of paths that contain classes to be included in the class-map generation process."
 63508                 },
 63509                 "files": {
 63510                     "type": "array",
 63511                     "description": "This is an array of files that are always required on every request."
 63512                 }
 63513             }
 63514         },
 63515         "target-dir": {
 63516             "description": "DEPRECATED: Forces the package to be installed into the given subdirectory path. This is used for autoloading PSR-0 packages that do not contain their full path. Use forward slashes for cross-platform compatibility.",
 63517             "type": "string"
 63518         },
 63519         "include-path": {
 63520             "type": ["array"],
 63521             "description": "DEPRECATED: A list of directories which should get added to PHP's include path. This is only present to support legacy projects, and all new code should preferably use autoloading.",
 63522             "items": {
 63523                 "type": "string"
 63524             }
 63525         },
 63526         "bin": {
 63527             "type": ["string", "array"],
 63528             "description": "A set of files, or a single file, that should be treated as binaries and symlinked into bin-dir (from config).",
 63529             "items": {
 63530                 "type": "string"
 63531             }
 63532         },
 63533         "archive": {
 63534             "type": ["object"],
 63535             "description": "Options for creating package archives for distribution.",
 63536             "properties": {
 63537                 "name": {
 63538                     "type": "string",
 63539                     "description": "A base name for archive."
 63540                 },
 63541                 "exclude": {
 63542                     "type": "array",
 63543                     "description": "A list of patterns for paths to exclude or include if prefixed with an exclamation mark."
 63544                 }
 63545             }
 63546         },
 63547         "config": {
 63548             "type": "object",
 63549             "description": "Composer options.",
 63550             "properties": {
 63551                 "platform": {
 63552                     "type": "object",
 63553                     "description": "This is an object of package name (keys) and version (values) that will be used to mock the platform packages on this machine.",
 63554                     "additionalProperties": {
 63555                         "type": ["string", "boolean"]
 63556                     }
 63557                 },
 63558                 "allow-plugins": {
 63559                     "type": ["object", "boolean"],
 63560                     "description": "This is an object of {\"pattern\": true|false} with packages which are allowed to be loaded as plugins, or true to allow all, false to allow none. Defaults to {} which prompts when an unknown plugin is added.",
 63561                     "additionalProperties": {
 63562                         "type": ["boolean"]
 63563                     }
 63564                 },
 63565                 "process-timeout": {
 63566                     "type": "integer",
 63567                     "description": "The timeout in seconds for process executions, defaults to 300 (5mins)."
 63568                 },
 63569                 "use-include-path": {
 63570                     "type": "boolean",
 63571                     "description": "If true, the Composer autoloader will also look for classes in the PHP include path."
 63572                 },
 63573                 "use-parent-dir": {
 63574                     "type": ["string", "boolean"],
 63575                     "description": "When running Composer in a directory where there is no composer.json, if there is one present in a directory above Composer will by default ask you whether you want to use that directory's composer.json instead. One of: true (always use parent if needed), false (never ask or use it) or \"prompt\" (ask every time), defaults to prompt."
 63576                 },
 63577                 "preferred-install": {
 63578                     "type": ["string", "object"],
 63579                     "description": "The install method Composer will prefer to use, defaults to auto and can be any of source, dist, auto, or an object of {\"pattern\": \"preference\"}.",
 63580                     "additionalProperties": {
 63581                         "type": ["string"]
 63582                     }
 63583                 },
 63584                 "notify-on-install": {
 63585                     "type": "boolean",
 63586                     "description": "Composer allows repositories to define a notification URL, so that they get notified whenever a package from that repository is installed. This option allows you to disable that behaviour, defaults to true."
 63587                 },
 63588                 "github-protocols": {
 63589                     "type": "array",
 63590                     "description": "A list of protocols to use for github.com clones, in priority order, defaults to [\"git\", \"https\", \"http\"].",
 63591                     "items": {
 63592                         "type": "string"
 63593                     }
 63594                 },
 63595                 "github-oauth": {
 63596                     "type": "object",
 63597                     "description": "An object of domain name => github API oauth tokens, typically {\"github.com\":\"<token>\"}.",
 63598                     "additionalProperties": {
 63599                         "type": "string"
 63600                     }
 63601                 },
 63602                 "gitlab-oauth": {
 63603                     "type": "object",
 63604                     "description": "An object of domain name => gitlab API oauth tokens, typically {\"gitlab.com\":\"<token>\"}.",
 63605                     "additionalProperties": {
 63606                         "type": "string"
 63607                     }
 63608                 },
 63609                 "gitlab-token": {
 63610                     "type": "object",
 63611                     "description": "An object of domain name => gitlab private tokens, typically {\"gitlab.com\":\"<token>\"}.",
 63612                     "additionalProperties": {
 63613                         "type": "string"
 63614                     }
 63615                 },
 63616                 "gitlab-protocol": {
 63617                     "enum": ["git", "http", "https"],
 63618                     "description": "A protocol to force use of when creating a repository URL for the `source` value of the package metadata. One of `git` or `http`. By default, Composer will generate a git URL for private repositories and http one for public repos."
 63619                 },
 63620                 "bearer": {
 63621                     "type": "object",
 63622                     "description": "An object of domain name => bearer authentication token, for example {\"example.com\":\"<token>\"}.",
 63623                     "additionalProperties": {
 63624                         "type": "string"
 63625                     }
 63626                 },
 63627                 "disable-tls": {
 63628                     "type": "boolean",
 63629                     "description": "Defaults to `false`. If set to true all HTTPS URLs will be tried with HTTP instead and no network level encryption is performed. Enabling this is a security risk and is NOT recommended. The better way is to enable the php_openssl extension in php.ini."
 63630                 },
 63631                 "secure-http": {
 63632                     "type": "boolean",
 63633                     "description": "Defaults to `true`. If set to true only HTTPS URLs are allowed to be downloaded via Composer. If you really absolutely need HTTP access to something then you can disable it, but using \"Let's Encrypt\" to get a free SSL certificate is generally a better alternative."
 63634                 },
 63635                 "secure-svn-domains": {
 63636                     "type": "array",
 63637                     "description": "A list of domains which should be trusted/marked as using a secure Subversion/SVN transport. By default svn:// protocol is seen as insecure and will throw. This is a better/safer alternative to disabling `secure-http` altogether.",
 63638                     "items": {
 63639                         "type": "string"
 63640                     }
 63641                 },
 63642                 "cafile": {
 63643                     "type": "string",
 63644                     "description": "A way to set the path to the openssl CA file. In PHP 5.6+ you should rather set this via openssl.cafile in php.ini, although PHP 5.6+ should be able to detect your system CA file automatically."
 63645                 },
 63646                 "capath": {
 63647                     "type": "string",
 63648                     "description": "If cafile is not specified or if the certificate is not found there, the directory pointed to by capath is searched for a suitable certificate. capath must be a correctly hashed certificate directory."
 63649                 },
 63650                 "http-basic": {
 63651                     "type": "object",
 63652                     "description": "An object of domain name => {\"username\": \"...\", \"password\": \"...\"}.",
 63653                     "additionalProperties": {
 63654                         "type": "object",
 63655                         "required": ["username", "password"],
 63656                         "properties": {
 63657                             "username": {
 63658                                 "type": "string",
 63659                                 "description": "The username used for HTTP Basic authentication"
 63660                             },
 63661                             "password": {
 63662                                 "type": "string",
 63663                                 "description": "The password used for HTTP Basic authentication"
 63664                             }
 63665                         }
 63666                     }
 63667                 },
 63668                 "store-auths": {
 63669                     "type": ["string", "boolean"],
 63670                     "description": "What to do after prompting for authentication, one of: true (store), false (do not store) or \"prompt\" (ask every time), defaults to prompt."
 63671                 },
 63672                 "vendor-dir": {
 63673                     "type": "string",
 63674                     "description": "The location where all packages are installed, defaults to \"vendor\"."
 63675                 },
 63676                 "bin-dir": {
 63677                     "type": "string",
 63678                     "description": "The location where all binaries are linked, defaults to \"vendor/bin\"."
 63679                 },
 63680                 "data-dir": {
 63681                     "type": "string",
 63682                     "description": "The location where old phar files are stored, defaults to \"$home\" except on XDG Base Directory compliant unixes."
 63683                 },
 63684                 "cache-dir": {
 63685                     "type": "string",
 63686                     "description": "The location where all caches are located, defaults to \"~/.composer/cache\" on *nix and \"%LOCALAPPDATA%\\Composer\" on windows."
 63687                 },
 63688                 "cache-files-dir": {
 63689                     "type": "string",
 63690                     "description": "The location where files (zip downloads) are cached, defaults to \"{$cache-dir}/files\"."
 63691                 },
 63692                 "cache-repo-dir": {
 63693                     "type": "string",
 63694                     "description": "The location where repo (git/hg repo clones) are cached, defaults to \"{$cache-dir}/repo\"."
 63695                 },
 63696                 "cache-vcs-dir": {
 63697                     "type": "string",
 63698                     "description": "The location where vcs infos (git clones, github api calls, etc. when reading vcs repos) are cached, defaults to \"{$cache-dir}/vcs\"."
 63699                 },
 63700                 "cache-ttl": {
 63701                     "type": "integer",
 63702                     "description": "The default cache time-to-live, defaults to 15552000 (6 months)."
 63703                 },
 63704                 "cache-files-ttl": {
 63705                     "type": "integer",
 63706                     "description": "The cache time-to-live for files, defaults to the value of cache-ttl."
 63707                 },
 63708                 "cache-files-maxsize": {
 63709                     "type": ["string", "integer"],
 63710                     "description": "The cache max size for the files cache, defaults to \"300MiB\"."
 63711                 },
 63712                 "cache-read-only": {
 63713                     "type": ["boolean"],
 63714                     "description": "Whether to use the Composer cache in read-only mode."
 63715                 },
 63716                 "bin-compat": {
 63717                     "enum": ["auto", "full", "proxy", "symlink"],
 63718                     "description": "The compatibility of the binaries, defaults to \"auto\" (automatically guessed), can be \"full\" (compatible with both Windows and Unix-based systems) and \"proxy\" (only bash-style proxy)."
 63719                 },
 63720                 "discard-changes": {
 63721                     "type": ["string", "boolean"],
 63722                     "description": "The default style of handling dirty updates, defaults to false and can be any of true, false or \"stash\"."
 63723                 },
 63724                 "autoloader-suffix": {
 63725                     "type": "string",
 63726                     "description": "Optional string to be used as a suffix for the generated Composer autoloader. When null a random one will be generated."
 63727                 },
 63728                 "optimize-autoloader": {
 63729                     "type": "boolean",
 63730                     "description": "Always optimize when dumping the autoloader."
 63731                 },
 63732                 "prepend-autoloader": {
 63733                     "type": "boolean",
 63734                     "description": "If false, the composer autoloader will not be prepended to existing autoloaders, defaults to true."
 63735                 },
 63736                 "classmap-authoritative": {
 63737                     "type": "boolean",
 63738                     "description": "If true, the composer autoloader will not scan the filesystem for classes that are not found in the class map, defaults to false."
 63739                 },
 63740                 "apcu-autoloader": {
 63741                     "type": "boolean",
 63742                     "description": "If true, the Composer autoloader will check for APCu and use it to cache found/not-found classes when the extension is enabled, defaults to false."
 63743                 },
 63744                 "github-domains": {
 63745                     "type": "array",
 63746                     "description": "A list of domains to use in github mode. This is used for GitHub Enterprise setups, defaults to [\"github.com\"].",
 63747                     "items": {
 63748                         "type": "string"
 63749                     }
 63750                 },
 63751                 "github-expose-hostname": {
 63752                     "type": "boolean",
 63753                     "description": "Defaults to true. If set to false, the OAuth tokens created to access the github API will have a date instead of the machine hostname."
 63754                 },
 63755                 "gitlab-domains": {
 63756                     "type": "array",
 63757                     "description": "A list of domains to use in gitlab mode. This is used for custom GitLab setups, defaults to [\"gitlab.com\"].",
 63758                     "items": {
 63759                         "type": "string"
 63760                     }
 63761                 },
 63762                 "use-github-api": {
 63763                     "type": "boolean",
 63764                     "description": "Defaults to true.  If set to false, globally disables the use of the GitHub API for all GitHub repositories and clones the repository as it would for any other repository."
 63765                 },
 63766                 "archive-format": {
 63767                     "type": "string",
 63768                     "description": "The default archiving format when not provided on cli, defaults to \"tar\"."
 63769                 },
 63770                 "archive-dir": {
 63771                     "type": "string",
 63772                     "description": "The default archive path when not provided on cli, defaults to \".\"."
 63773                 },
 63774                 "htaccess-protect": {
 63775                     "type": "boolean",
 63776                     "description": "Defaults to true. If set to false, Composer will not create .htaccess files in the composer home, cache, and data directories."
 63777                 },
 63778                 "sort-packages": {
 63779                     "type": "boolean",
 63780                     "description": "Defaults to false. If set to true, Composer will sort packages when adding/updating a new dependency."
 63781                 },
 63782                 "lock": {
 63783                     "type": "boolean",
 63784                     "description": "Defaults to true. If set to false, Composer will not create a composer.lock file."
 63785                 },
 63786                 "platform-check": {
 63787                     "type": ["boolean", "string"],
 63788                     "description": "Defaults to \"php-only\" which checks only the PHP version. Setting to true will also check the presence of required PHP extensions. If set to false, Composer will not create and require a platform_check.php file as part of the autoloader bootstrap."
 63789                 }
 63790             }
 63791         },
 63792         "extra": {
 63793             "type": ["object", "array"],
 63794             "description": "Arbitrary extra data that can be used by plugins, for example, package of type composer-plugin may have a 'class' key defining an installer class name.",
 63795             "additionalProperties": true
 63796         },
 63797         "scripts": {
 63798             "type": ["object"],
 63799             "description": "Script listeners that will be executed before/after some events.",
 63800             "properties": {
 63801                 "pre-install-cmd": {
 63802                     "type": ["array", "string"],
 63803                     "description": "Occurs before the install command is executed, contains one or more Class::method callables or shell commands."
 63804                 },
 63805                 "post-install-cmd": {
 63806                     "type": ["array", "string"],
 63807                     "description": "Occurs after the install command is executed, contains one or more Class::method callables or shell commands."
 63808                 },
 63809                 "pre-update-cmd": {
 63810                     "type": ["array", "string"],
 63811                     "description": "Occurs before the update command is executed, contains one or more Class::method callables or shell commands."
 63812                 },
 63813                 "post-update-cmd": {
 63814                     "type": ["array", "string"],
 63815                     "description": "Occurs after the update command is executed, contains one or more Class::method callables or shell commands."
 63816                 },
 63817                 "pre-status-cmd": {
 63818                     "type": ["array", "string"],
 63819                     "description": "Occurs before the status command is executed, contains one or more Class::method callables or shell commands."
 63820                 },
 63821                 "post-status-cmd": {
 63822                     "type": ["array", "string"],
 63823                     "description": "Occurs after the status command is executed, contains one or more Class::method callables or shell commands."
 63824                 },
 63825                 "pre-package-install": {
 63826                     "type": ["array", "string"],
 63827                     "description": "Occurs before a package is installed, contains one or more Class::method callables or shell commands."
 63828                 },
 63829                 "post-package-install": {
 63830                     "type": ["array", "string"],
 63831                     "description": "Occurs after a package is installed, contains one or more Class::method callables or shell commands."
 63832                 },
 63833                 "pre-package-update": {
 63834                     "type": ["array", "string"],
 63835                     "description": "Occurs before a package is updated, contains one or more Class::method callables or shell commands."
 63836                 },
 63837                 "post-package-update": {
 63838                     "type": ["array", "string"],
 63839                     "description": "Occurs after a package is updated, contains one or more Class::method callables or shell commands."
 63840                 },
 63841                 "pre-package-uninstall": {
 63842                     "type": ["array", "string"],
 63843                     "description": "Occurs before a package has been uninstalled, contains one or more Class::method callables or shell commands."
 63844                 },
 63845                 "post-package-uninstall": {
 63846                     "type": ["array", "string"],
 63847                     "description": "Occurs after a package has been uninstalled, contains one or more Class::method callables or shell commands."
 63848                 },
 63849                 "pre-autoload-dump": {
 63850                     "type": ["array", "string"],
 63851                     "description": "Occurs before the autoloader is dumped, contains one or more Class::method callables or shell commands."
 63852                 },
 63853                 "post-autoload-dump": {
 63854                     "type": ["array", "string"],
 63855                     "description": "Occurs after the autoloader is dumped, contains one or more Class::method callables or shell commands."
 63856                 },
 63857                 "post-root-package-install": {
 63858                     "type": ["array", "string"],
 63859                     "description": "Occurs after the root-package is installed, contains one or more Class::method callables or shell commands."
 63860                 },
 63861                 "post-create-project-cmd": {
 63862                     "type": ["array", "string"],
 63863                     "description": "Occurs after the create-project command is executed, contains one or more Class::method callables or shell commands."
 63864                 }
 63865             }
 63866         },
 63867         "scripts-descriptions": {
 63868             "type": ["object"],
 63869             "description": "Descriptions for custom commands, shown in console help.",
 63870             "additionalProperties": {
 63871                 "type": "string"
 63872             }
 63873         }
 63874     },
 63875     "definitions": {
 63876         "authors": {
 63877             "type": "array",
 63878             "description": "List of authors that contributed to the package. This is typically the main maintainers, not the full list.",
 63879             "items": {
 63880                 "type": "object",
 63881                 "additionalProperties": false,
 63882                 "required": [ "name"],
 63883                 "properties": {
 63884                     "name": {
 63885                         "type": "string",
 63886                         "description": "Full name of the author."
 63887                     },
 63888                     "email": {
 63889                         "type": "string",
 63890                         "description": "Email address of the author.",
 63891                         "format": "email"
 63892                     },
 63893                     "homepage": {
 63894                         "type": "string",
 63895                         "description": "Homepage URL for the author.",
 63896                         "format": "uri"
 63897                     },
 63898                     "role": {
 63899                         "type": "string",
 63900                         "description": "Author's role in the project."
 63901                     }
 63902                 }
 63903             }
 63904         },
 63905         "autoload": {
 63906             "type": "object",
 63907             "description": "Description of how the package can be autoloaded.",
 63908             "properties": {
 63909                 "psr-0": {
 63910                     "type": "object",
 63911                     "description": "This is an object of namespaces (keys) and the directories they can be found in (values, can be arrays of paths) by the autoloader.",
 63912                     "additionalProperties": {
 63913                         "type": ["string", "array"],
 63914                         "items": {
 63915                             "type": "string"
 63916                         }
 63917                     }
 63918                 },
 63919                 "psr-4": {
 63920                     "type": "object",
 63921                     "description": "This is an object of namespaces (keys) and the PSR-4 directories they can map to (values, can be arrays of paths) by the autoloader.",
 63922                     "additionalProperties": {
 63923                         "type": ["string", "array"],
 63924                         "items": {
 63925                             "type": "string"
 63926                         }
 63927                     }
 63928                 },
 63929                 "classmap": {
 63930                     "type": "array",
 63931                     "description": "This is an array of paths that contain classes to be included in the class-map generation process."
 63932                 },
 63933                 "files": {
 63934                     "type": "array",
 63935                     "description": "This is an array of files that are always required on every request."
 63936                 },
 63937                 "exclude-from-classmap": {
 63938                     "type": "array",
 63939                     "description": "This is an array of patterns to exclude from autoload classmap generation. (e.g. \"exclude-from-classmap\": [\"/test/\", \"/tests/\", \"/Tests/\"]"
 63940                 }
 63941             }
 63942         },
 63943         "repository": {
 63944             "type": "object",
 63945             "anyOf": [
 63946                 { "$ref": "#/definitions/composer-repository" },
 63947                 { "$ref": "#/definitions/vcs-repository" },
 63948                 { "$ref": "#/definitions/path-repository" },
 63949                 { "$ref": "#/definitions/artifact-repository" },
 63950                 { "$ref": "#/definitions/pear-repository" },
 63951                 { "$ref": "#/definitions/package-repository" }
 63952             ]
 63953         },
 63954         "composer-repository": {
 63955             "type": "object",
 63956             "required": ["type", "url"],
 63957             "properties": {
 63958                 "type": { "type": "string", "enum": ["composer"] },
 63959                 "url": { "type": "string" },
 63960                 "canonical": { "type": "boolean" },
 63961                 "only": {
 63962                     "type": "array",
 63963                     "items": {
 63964                         "type": "string"
 63965                     }
 63966                 },
 63967                 "exclude": {
 63968                     "type": "array",
 63969                     "items": {
 63970                         "type": "string"
 63971                     }
 63972                 },
 63973                 "options": {
 63974                     "type": "object",
 63975                     "additionalProperties": true
 63976                 },
 63977                 "allow_ssl_downgrade": { "type": "boolean" },
 63978                 "force-lazy-providers": { "type": "boolean" }
 63979             }
 63980         },
 63981         "vcs-repository": {
 63982             "type": "object",
 63983             "required": ["type", "url"],
 63984             "properties": {
 63985                 "type": { "type": "string", "enum": ["vcs", "github", "git", "gitlab", "bitbucket", "git-bitbucket", "hg", "fossil", "perforce", "svn"] },
 63986                 "url": { "type": "string" },
 63987                 "canonical": { "type": "boolean" },
 63988                 "only": {
 63989                     "type": "array",
 63990                     "items": {
 63991                         "type": "string"
 63992                     }
 63993                 },
 63994                 "exclude": {
 63995                     "type": "array",
 63996                     "items": {
 63997                         "type": "string"
 63998                     }
 63999                 },
 64000                 "no-api": { "type": "boolean" },
 64001                 "secure-http": { "type": "boolean" },
 64002                 "svn-cache-credentials": { "type": "boolean" },
 64003                 "trunk-path": { "type": ["string", "boolean"] },
 64004                 "branches-path": { "type": ["string", "boolean"] },
 64005                 "tags-path": { "type": ["string", "boolean"] },
 64006                 "package-path": { "type": "string" },
 64007                 "depot": { "type": "string" },
 64008                 "branch": { "type": "string" },
 64009                 "unique_perforce_client_name": { "type": "string" },
 64010                 "p4user": { "type": "string" },
 64011                 "p4password": { "type": "string" }
 64012             }
 64013         },
 64014         "path-repository": {
 64015             "type": "object",
 64016             "required": ["type", "url"],
 64017             "properties": {
 64018                 "type": { "type": "string", "enum": ["path"] },
 64019                 "url": { "type": "string" },
 64020                 "canonical": { "type": "boolean" },
 64021                 "only": {
 64022                     "type": "array",
 64023                     "items": {
 64024                         "type": "string"
 64025                     }
 64026                 },
 64027                 "exclude": {
 64028                     "type": "array",
 64029                     "items": {
 64030                         "type": "string"
 64031                     }
 64032                 },
 64033                 "options": {
 64034                     "type": "object",
 64035                     "properties": {
 64036                         "symlink": { "type": ["boolean", "null"] }
 64037                     },
 64038                     "additionalProperties": true
 64039                 }
 64040             }
 64041         },
 64042         "artifact-repository": {
 64043             "type": "object",
 64044             "required": ["type", "url"],
 64045             "properties": {
 64046                 "type": { "type": "string", "enum": ["artifact"] },
 64047                 "url": { "type": "string" },
 64048                 "canonical": { "type": "boolean" },
 64049                 "only": {
 64050                     "type": "array",
 64051                     "items": {
 64052                         "type": "string"
 64053                     }
 64054                 },
 64055                 "exclude": {
 64056                     "type": "array",
 64057                     "items": {
 64058                         "type": "string"
 64059                     }
 64060                 }
 64061             }
 64062         },
 64063         "pear-repository": {
 64064             "type": "object",
 64065             "required": ["type", "url"],
 64066             "properties": {
 64067                 "type": { "type": "string", "enum": ["pear"] },
 64068                 "url": { "type": "string" },
 64069                 "canonical": { "type": "boolean" },
 64070                 "only": {
 64071                     "type": "array",
 64072                     "items": {
 64073                         "type": "string"
 64074                     }
 64075                 },
 64076                 "exclude": {
 64077                     "type": "array",
 64078                     "items": {
 64079                         "type": "string"
 64080                     }
 64081                 },
 64082                 "vendor-alias": { "type": "string" }
 64083             }
 64084         },
 64085         "package-repository": {
 64086             "type": "object",
 64087             "required": ["type", "package"],
 64088             "properties": {
 64089                 "type": { "type": "string", "enum": ["package"] },
 64090                 "canonical": { "type": "boolean" },
 64091                 "only": {
 64092                     "type": "array",
 64093                     "items": {
 64094                         "type": "string"
 64095                     }
 64096                 },
 64097                 "exclude": {
 64098                     "type": "array",
 64099                     "items": {
 64100                         "type": "string"
 64101                     }
 64102                 },
 64103                 "package": {
 64104                     "oneOf": [
 64105                         { "$ref": "#/definitions/inline-package" },
 64106                         {
 64107                             "type": "array",
 64108                             "items": { "$ref": "#/definitions/inline-package" }
 64109                         }
 64110                     ]
 64111                 }
 64112             }
 64113         },
 64114         "inline-package": {
 64115             "type": "object",
 64116             "required": ["name", "version"],
 64117             "properties": {
 64118                 "name": {
 64119                     "type": "string",
 64120                     "description": "Package name, including 'vendor-name/' prefix."
 64121                 },
 64122                 "type": {
 64123                     "type": "string"
 64124                 },
 64125                 "target-dir": {
 64126                     "description": "DEPRECATED: Forces the package to be installed into the given subdirectory path. This is used for autoloading PSR-0 packages that do not contain their full path. Use forward slashes for cross-platform compatibility.",
 64127                     "type": "string"
 64128                 },
 64129                 "description": {
 64130                     "type": "string"
 64131                 },
 64132                 "keywords": {
 64133                     "type": "array",
 64134                     "items": {
 64135                         "type": "string"
 64136                     }
 64137                 },
 64138                 "homepage": {
 64139                     "type": "string",
 64140                     "format": "uri"
 64141                 },
 64142                 "version": {
 64143                     "type": "string"
 64144                 },
 64145                 "time": {
 64146                     "type": "string"
 64147                 },
 64148                 "license": {
 64149                     "type": [
 64150                         "string",
 64151                         "array"
 64152                     ]
 64153                 },
 64154                 "authors": {
 64155                     "$ref": "#/definitions/authors"
 64156                 },
 64157                 "require": {
 64158                     "type": "object",
 64159                     "additionalProperties": {
 64160                         "type": "string"
 64161                     }
 64162                 },
 64163                 "replace": {
 64164                     "type": "object",
 64165                     "additionalProperties": {
 64166                         "type": "string"
 64167                     }
 64168                 },
 64169                 "conflict": {
 64170                     "type": "object",
 64171                     "additionalProperties": {
 64172                         "type": "string"
 64173                     }
 64174                 },
 64175                 "provide": {
 64176                     "type": "object",
 64177                     "additionalProperties": {
 64178                         "type": "string"
 64179                     }
 64180                 },
 64181                 "require-dev": {
 64182                     "type": "object",
 64183                     "additionalProperties": {
 64184                         "type": "string"
 64185                     }
 64186                 },
 64187                 "suggest": {
 64188                     "type": "object",
 64189                     "additionalProperties": {
 64190                         "type": "string"
 64191                     }
 64192                 },
 64193                 "extra": {
 64194                     "type": ["object", "array"],
 64195                     "additionalProperties": true
 64196                 },
 64197                 "autoload": {
 64198                     "$ref": "#/definitions/autoload"
 64199                 },
 64200                 "archive": {
 64201                     "type": ["object"],
 64202                     "properties": {
 64203                         "exclude": {
 64204                             "type": "array"
 64205                         }
 64206                     }
 64207                 },
 64208                 "bin": {
 64209                     "type": ["string", "array"],
 64210                     "description": "A set of files, or a single file, that should be treated as binaries and symlinked into bin-dir (from config).",
 64211                     "items": {
 64212                         "type": "string"
 64213                     }
 64214                 },
 64215                 "include-path": {
 64216                     "type": ["array"],
 64217                     "description": "DEPRECATED: A list of directories which should get added to PHP's include path. This is only present to support legacy projects, and all new code should preferably use autoloading.",
 64218                     "items": {
 64219                         "type": "string"
 64220                     }
 64221                 },
 64222                 "source": {
 64223                     "type": "object",
 64224                     "required": ["type", "url", "reference"],
 64225                     "properties": {
 64226                         "type": {
 64227                             "type": "string"
 64228                         },
 64229                         "url": {
 64230                             "type": "string"
 64231                         },
 64232                         "reference": {
 64233                             "type": "string"
 64234                         },
 64235                         "mirrors": {
 64236                             "type": "array"
 64237                         }
 64238                     }
 64239                 },
 64240                 "dist": {
 64241                     "type": "object",
 64242                     "required": ["type", "url"],
 64243                     "properties": {
 64244                         "type": {
 64245                             "type": "string"
 64246                         },
 64247                         "url": {
 64248                             "type": "string"
 64249                         },
 64250                         "reference": {
 64251                             "type": "string"
 64252                         },
 64253                         "shasum": {
 64254                             "type": "string"
 64255                         },
 64256                         "mirrors": {
 64257                             "type": "array"
 64258                         }
 64259                     }
 64260                 }
 64261             },
 64262             "additionalProperties": true
 64263         }
 64264     }
 64265 }
 64266 <?php
 64267 
 64268 
 64269 
 64270 require_once __DIR__ . '/composer/autoload_real.php';
 64271 
 64272 return ComposerAutoloaderInitComposerPhar1647378817::getLoader();
 64273 <?php
 64274 
 64275 
 64276 
 64277 
 64278 
 64279 
 64280 
 64281 
 64282 
 64283 
 64284 
 64285 namespace Composer\Autoload;
 64286 
 64287 
 64288 
 64289 
 64290 
 64291 
 64292 
 64293 
 64294 
 64295 
 64296 
 64297 
 64298 
 64299 
 64300 
 64301 
 64302 
 64303 
 64304 
 64305 
 64306 
 64307 
 64308 
 64309 
 64310 
 64311 
 64312 
 64313 
 64314 
 64315 class ClassLoader
 64316 {
 64317 
 64318 private $vendorDir;
 64319 
 64320 
 64321 
 64322 
 64323 
 64324 
 64325 private $prefixLengthsPsr4 = array();
 64326 
 64327 
 64328 
 64329 
 64330 private $prefixDirsPsr4 = array();
 64331 
 64332 
 64333 
 64334 
 64335 private $fallbackDirsPsr4 = array();
 64336 
 64337 
 64338 
 64339 
 64340 
 64341 
 64342 private $prefixesPsr0 = array();
 64343 
 64344 
 64345 
 64346 
 64347 private $fallbackDirsPsr0 = array();
 64348 
 64349 
 64350 private $useIncludePath = false;
 64351 
 64352 
 64353 
 64354 
 64355 
 64356 private $classMap = array();
 64357 
 64358 
 64359 private $classMapAuthoritative = false;
 64360 
 64361 
 64362 
 64363 
 64364 
 64365 private $missingClasses = array();
 64366 
 64367 
 64368 private $apcuPrefix;
 64369 
 64370 
 64371 
 64372 
 64373 private static $registeredLoaders = array();
 64374 
 64375 
 64376 
 64377 
 64378 public function __construct($vendorDir = null)
 64379 {
 64380 $this->vendorDir = $vendorDir;
 64381 }
 64382 
 64383 
 64384 
 64385 
 64386 public function getPrefixes()
 64387 {
 64388 if (!empty($this->prefixesPsr0)) {
 64389 return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
 64390 }
 64391 
 64392 return array();
 64393 }
 64394 
 64395 
 64396 
 64397 
 64398 
 64399 public function getPrefixesPsr4()
 64400 {
 64401 return $this->prefixDirsPsr4;
 64402 }
 64403 
 64404 
 64405 
 64406 
 64407 
 64408 public function getFallbackDirs()
 64409 {
 64410 return $this->fallbackDirsPsr0;
 64411 }
 64412 
 64413 
 64414 
 64415 
 64416 
 64417 public function getFallbackDirsPsr4()
 64418 {
 64419 return $this->fallbackDirsPsr4;
 64420 }
 64421 
 64422 
 64423 
 64424 
 64425 
 64426 public function getClassMap()
 64427 {
 64428 return $this->classMap;
 64429 }
 64430 
 64431 
 64432 
 64433 
 64434 
 64435 
 64436 
 64437 public function addClassMap(array $classMap)
 64438 {
 64439 if ($this->classMap) {
 64440 $this->classMap = array_merge($this->classMap, $classMap);
 64441 } else {
 64442 $this->classMap = $classMap;
 64443 }
 64444 }
 64445 
 64446 
 64447 
 64448 
 64449 
 64450 
 64451 
 64452 
 64453 
 64454 
 64455 
 64456 public function add($prefix, $paths, $prepend = false)
 64457 {
 64458 if (!$prefix) {
 64459 if ($prepend) {
 64460 $this->fallbackDirsPsr0 = array_merge(
 64461 (array) $paths,
 64462 $this->fallbackDirsPsr0
 64463 );
 64464 } else {
 64465 $this->fallbackDirsPsr0 = array_merge(
 64466 $this->fallbackDirsPsr0,
 64467 (array) $paths
 64468 );
 64469 }
 64470 
 64471 return;
 64472 }
 64473 
 64474 $first = $prefix[0];
 64475 if (!isset($this->prefixesPsr0[$first][$prefix])) {
 64476 $this->prefixesPsr0[$first][$prefix] = (array) $paths;
 64477 
 64478 return;
 64479 }
 64480 if ($prepend) {
 64481 $this->prefixesPsr0[$first][$prefix] = array_merge(
 64482 (array) $paths,
 64483 $this->prefixesPsr0[$first][$prefix]
 64484 );
 64485 } else {
 64486 $this->prefixesPsr0[$first][$prefix] = array_merge(
 64487 $this->prefixesPsr0[$first][$prefix],
 64488 (array) $paths
 64489 );
 64490 }
 64491 }
 64492 
 64493 
 64494 
 64495 
 64496 
 64497 
 64498 
 64499 
 64500 
 64501 
 64502 
 64503 
 64504 
 64505 public function addPsr4($prefix, $paths, $prepend = false)
 64506 {
 64507 if (!$prefix) {
 64508 
 64509 if ($prepend) {
 64510 $this->fallbackDirsPsr4 = array_merge(
 64511 (array) $paths,
 64512 $this->fallbackDirsPsr4
 64513 );
 64514 } else {
 64515 $this->fallbackDirsPsr4 = array_merge(
 64516 $this->fallbackDirsPsr4,
 64517 (array) $paths
 64518 );
 64519 }
 64520 } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
 64521 
 64522 $length = strlen($prefix);
 64523 if ('\\' !== $prefix[$length - 1]) {
 64524 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
 64525 }
 64526 $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
 64527 $this->prefixDirsPsr4[$prefix] = (array) $paths;
 64528 } elseif ($prepend) {
 64529 
 64530 $this->prefixDirsPsr4[$prefix] = array_merge(
 64531 (array) $paths,
 64532 $this->prefixDirsPsr4[$prefix]
 64533 );
 64534 } else {
 64535 
 64536 $this->prefixDirsPsr4[$prefix] = array_merge(
 64537 $this->prefixDirsPsr4[$prefix],
 64538 (array) $paths
 64539 );
 64540 }
 64541 }
 64542 
 64543 
 64544 
 64545 
 64546 
 64547 
 64548 
 64549 
 64550 
 64551 
 64552 public function set($prefix, $paths)
 64553 {
 64554 if (!$prefix) {
 64555 $this->fallbackDirsPsr0 = (array) $paths;
 64556 } else {
 64557 $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
 64558 }
 64559 }
 64560 
 64561 
 64562 
 64563 
 64564 
 64565 
 64566 
 64567 
 64568 
 64569 
 64570 
 64571 
 64572 public function setPsr4($prefix, $paths)
 64573 {
 64574 if (!$prefix) {
 64575 $this->fallbackDirsPsr4 = (array) $paths;
 64576 } else {
 64577 $length = strlen($prefix);
 64578 if ('\\' !== $prefix[$length - 1]) {
 64579 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
 64580 }
 64581 $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
 64582 $this->prefixDirsPsr4[$prefix] = (array) $paths;
 64583 }
 64584 }
 64585 
 64586 
 64587 
 64588 
 64589 
 64590 
 64591 
 64592 
 64593 public function setUseIncludePath($useIncludePath)
 64594 {
 64595 $this->useIncludePath = $useIncludePath;
 64596 }
 64597 
 64598 
 64599 
 64600 
 64601 
 64602 
 64603 
 64604 public function getUseIncludePath()
 64605 {
 64606 return $this->useIncludePath;
 64607 }
 64608 
 64609 
 64610 
 64611 
 64612 
 64613 
 64614 
 64615 
 64616 
 64617 public function setClassMapAuthoritative($classMapAuthoritative)
 64618 {
 64619 $this->classMapAuthoritative = $classMapAuthoritative;
 64620 }
 64621 
 64622 
 64623 
 64624 
 64625 
 64626 
 64627 public function isClassMapAuthoritative()
 64628 {
 64629 return $this->classMapAuthoritative;
 64630 }
 64631 
 64632 
 64633 
 64634 
 64635 
 64636 
 64637 
 64638 
 64639 public function setApcuPrefix($apcuPrefix)
 64640 {
 64641 $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
 64642 }
 64643 
 64644 
 64645 
 64646 
 64647 
 64648 
 64649 public function getApcuPrefix()
 64650 {
 64651 return $this->apcuPrefix;
 64652 }
 64653 
 64654 
 64655 
 64656 
 64657 
 64658 
 64659 
 64660 
 64661 public function register($prepend = false)
 64662 {
 64663 spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 64664 
 64665 if (null === $this->vendorDir) {
 64666 return;
 64667 }
 64668 
 64669 if ($prepend) {
 64670 self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
 64671 } else {
 64672 unset(self::$registeredLoaders[$this->vendorDir]);
 64673 self::$registeredLoaders[$this->vendorDir] = $this;
 64674 }
 64675 }
 64676 
 64677 
 64678 
 64679 
 64680 
 64681 
 64682 public function unregister()
 64683 {
 64684 spl_autoload_unregister(array($this, 'loadClass'));
 64685 
 64686 if (null !== $this->vendorDir) {
 64687 unset(self::$registeredLoaders[$this->vendorDir]);
 64688 }
 64689 }
 64690 
 64691 
 64692 
 64693 
 64694 
 64695 
 64696 
 64697 public function loadClass($class)
 64698 {
 64699 if ($file = $this->findFile($class)) {
 64700 includeFile($file);
 64701 
 64702 return true;
 64703 }
 64704 
 64705 return null;
 64706 }
 64707 
 64708 
 64709 
 64710 
 64711 
 64712 
 64713 
 64714 
 64715 public function findFile($class)
 64716 {
 64717 
 64718 if (isset($this->classMap[$class])) {
 64719 return $this->classMap[$class];
 64720 }
 64721 if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
 64722 return false;
 64723 }
 64724 if (null !== $this->apcuPrefix) {
 64725 $file = apcu_fetch($this->apcuPrefix.$class, $hit);
 64726 if ($hit) {
 64727 return $file;
 64728 }
 64729 }
 64730 
 64731 $file = $this->findFileWithExtension($class, '.php');
 64732 
 64733 
 64734 if (false === $file && defined('HHVM_VERSION')) {
 64735 $file = $this->findFileWithExtension($class, '.hh');
 64736 }
 64737 
 64738 if (null !== $this->apcuPrefix) {
 64739 apcu_add($this->apcuPrefix.$class, $file);
 64740 }
 64741 
 64742 if (false === $file) {
 64743 
 64744 $this->missingClasses[$class] = true;
 64745 }
 64746 
 64747 return $file;
 64748 }
 64749 
 64750 
 64751 
 64752 
 64753 
 64754 
 64755 public static function getRegisteredLoaders()
 64756 {
 64757 return self::$registeredLoaders;
 64758 }
 64759 
 64760 
 64761 
 64762 
 64763 
 64764 
 64765 private function findFileWithExtension($class, $ext)
 64766 {
 64767 
 64768 $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
 64769 
 64770 $first = $class[0];
 64771 if (isset($this->prefixLengthsPsr4[$first])) {
 64772 $subPath = $class;
 64773 while (false !== $lastPos = strrpos($subPath, '\\')) {
 64774 $subPath = substr($subPath, 0, $lastPos);
 64775 $search = $subPath . '\\';
 64776 if (isset($this->prefixDirsPsr4[$search])) {
 64777 $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
 64778 foreach ($this->prefixDirsPsr4[$search] as $dir) {
 64779 if (file_exists($file = $dir . $pathEnd)) {
 64780 return $file;
 64781 }
 64782 }
 64783 }
 64784 }
 64785 }
 64786 
 64787 
 64788 foreach ($this->fallbackDirsPsr4 as $dir) {
 64789 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
 64790 return $file;
 64791 }
 64792 }
 64793 
 64794 
 64795 if (false !== $pos = strrpos($class, '\\')) {
 64796 
 64797 $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
 64798 . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
 64799 } else {
 64800 
 64801 $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
 64802 }
 64803 
 64804 if (isset($this->prefixesPsr0[$first])) {
 64805 foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
 64806 if (0 === strpos($class, $prefix)) {
 64807 foreach ($dirs as $dir) {
 64808 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
 64809 return $file;
 64810 }
 64811 }
 64812 }
 64813 }
 64814 }
 64815 
 64816 
 64817 foreach ($this->fallbackDirsPsr0 as $dir) {
 64818 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
 64819 return $file;
 64820 }
 64821 }
 64822 
 64823 
 64824 if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
 64825 return $file;
 64826 }
 64827 
 64828 return false;
 64829 }
 64830 }
 64831 
 64832 
 64833 
 64834 
 64835 
 64836 
 64837 
 64838 
 64839 
 64840 
 64841 function includeFile($file)
 64842 {
 64843 include $file;
 64844 }
 64845 <?php
 64846 
 64847 
 64848 
 64849 
 64850 
 64851 
 64852 
 64853 
 64854 
 64855 
 64856 
 64857 namespace Composer;
 64858 
 64859 use Composer\Autoload\ClassLoader;
 64860 use Composer\Semver\VersionParser;
 64861 
 64862 
 64863 
 64864 
 64865 
 64866 
 64867 
 64868 
 64869 class InstalledVersions
 64870 {
 64871 
 64872 
 64873 
 64874 
 64875 private static $installed;
 64876 
 64877 
 64878 
 64879 
 64880 private static $canGetVendors;
 64881 
 64882 
 64883 
 64884 
 64885 
 64886 private static $installedByVendor = array();
 64887 
 64888 
 64889 
 64890 
 64891 
 64892 
 64893 
 64894 public static function getInstalledPackages()
 64895 {
 64896 $packages = array();
 64897 foreach (self::getInstalled() as $installed) {
 64898 $packages[] = array_keys($installed['versions']);
 64899 }
 64900 
 64901 if (1 === \count($packages)) {
 64902 return $packages[0];
 64903 }
 64904 
 64905 return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
 64906 }
 64907 
 64908 
 64909 
 64910 
 64911 
 64912 
 64913 
 64914 
 64915 public static function getInstalledPackagesByType($type)
 64916 {
 64917 $packagesByType = array();
 64918 
 64919 foreach (self::getInstalled() as $installed) {
 64920 foreach ($installed['versions'] as $name => $package) {
 64921 if (isset($package['type']) && $package['type'] === $type) {
 64922 $packagesByType[] = $name;
 64923 }
 64924 }
 64925 }
 64926 
 64927 return $packagesByType;
 64928 }
 64929 
 64930 
 64931 
 64932 
 64933 
 64934 
 64935 
 64936 
 64937 
 64938 
 64939 public static function isInstalled($packageName, $includeDevRequirements = true)
 64940 {
 64941 foreach (self::getInstalled() as $installed) {
 64942 if (isset($installed['versions'][$packageName])) {
 64943 return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
 64944 }
 64945 }
 64946 
 64947 return false;
 64948 }
 64949 
 64950 
 64951 
 64952 
 64953 
 64954 
 64955 
 64956 
 64957 
 64958 
 64959 
 64960 
 64961 
 64962 public static function satisfies(VersionParser $parser, $packageName, $constraint)
 64963 {
 64964 $constraint = $parser->parseConstraints($constraint);
 64965 $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
 64966 
 64967 return $provided->matches($constraint);
 64968 }
 64969 
 64970 
 64971 
 64972 
 64973 
 64974 
 64975 
 64976 
 64977 
 64978 
 64979 public static function getVersionRanges($packageName)
 64980 {
 64981 foreach (self::getInstalled() as $installed) {
 64982 if (!isset($installed['versions'][$packageName])) {
 64983 continue;
 64984 }
 64985 
 64986 $ranges = array();
 64987 if (isset($installed['versions'][$packageName]['pretty_version'])) {
 64988 $ranges[] = $installed['versions'][$packageName]['pretty_version'];
 64989 }
 64990 if (array_key_exists('aliases', $installed['versions'][$packageName])) {
 64991 $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
 64992 }
 64993 if (array_key_exists('replaced', $installed['versions'][$packageName])) {
 64994 $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
 64995 }
 64996 if (array_key_exists('provided', $installed['versions'][$packageName])) {
 64997 $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
 64998 }
 64999 
 65000 return implode(' || ', $ranges);
 65001 }
 65002 
 65003 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 65004 }
 65005 
 65006 
 65007 
 65008 
 65009 
 65010 public static function getVersion($packageName)
 65011 {
 65012 foreach (self::getInstalled() as $installed) {
 65013 if (!isset($installed['versions'][$packageName])) {
 65014 continue;
 65015 }
 65016 
 65017 if (!isset($installed['versions'][$packageName]['version'])) {
 65018 return null;
 65019 }
 65020 
 65021 return $installed['versions'][$packageName]['version'];
 65022 }
 65023 
 65024 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 65025 }
 65026 
 65027 
 65028 
 65029 
 65030 
 65031 public static function getPrettyVersion($packageName)
 65032 {
 65033 foreach (self::getInstalled() as $installed) {
 65034 if (!isset($installed['versions'][$packageName])) {
 65035 continue;
 65036 }
 65037 
 65038 if (!isset($installed['versions'][$packageName]['pretty_version'])) {
 65039 return null;
 65040 }
 65041 
 65042 return $installed['versions'][$packageName]['pretty_version'];
 65043 }
 65044 
 65045 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 65046 }
 65047 
 65048 
 65049 
 65050 
 65051 
 65052 public static function getReference($packageName)
 65053 {
 65054 foreach (self::getInstalled() as $installed) {
 65055 if (!isset($installed['versions'][$packageName])) {
 65056 continue;
 65057 }
 65058 
 65059 if (!isset($installed['versions'][$packageName]['reference'])) {
 65060 return null;
 65061 }
 65062 
 65063 return $installed['versions'][$packageName]['reference'];
 65064 }
 65065 
 65066 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 65067 }
 65068 
 65069 
 65070 
 65071 
 65072 
 65073 public static function getInstallPath($packageName)
 65074 {
 65075 foreach (self::getInstalled() as $installed) {
 65076 if (!isset($installed['versions'][$packageName])) {
 65077 continue;
 65078 }
 65079 
 65080 return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
 65081 }
 65082 
 65083 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
 65084 }
 65085 
 65086 
 65087 
 65088 
 65089 
 65090 public static function getRootPackage()
 65091 {
 65092 $installed = self::getInstalled();
 65093 
 65094 return $installed[0]['root'];
 65095 }
 65096 
 65097 
 65098 
 65099 
 65100 
 65101 
 65102 
 65103 
 65104 public static function getRawData()
 65105 {
 65106 @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
 65107 
 65108 if (null === self::$installed) {
 65109 
 65110 
 65111 if (substr(__DIR__, -8, 1) !== 'C') {
 65112 self::$installed = include __DIR__ . '/installed.php';
 65113 } else {
 65114 self::$installed = array();
 65115 }
 65116 }
 65117 
 65118 return self::$installed;
 65119 }
 65120 
 65121 
 65122 
 65123 
 65124 
 65125 
 65126 
 65127 public static function getAllRawData()
 65128 {
 65129 return self::getInstalled();
 65130 }
 65131 
 65132 
 65133 
 65134 
 65135 
 65136 
 65137 
 65138 
 65139 
 65140 
 65141 
 65142 
 65143 
 65144 
 65145 
 65146 
 65147 
 65148 
 65149 
 65150 public static function reload($data)
 65151 {
 65152 self::$installed = $data;
 65153 self::$installedByVendor = array();
 65154 }
 65155 
 65156 
 65157 
 65158 
 65159 
 65160 private static function getInstalled()
 65161 {
 65162 if (null === self::$canGetVendors) {
 65163 self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
 65164 }
 65165 
 65166 $installed = array();
 65167 
 65168 if (self::$canGetVendors) {
 65169 foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
 65170 if (isset(self::$installedByVendor[$vendorDir])) {
 65171 $installed[] = self::$installedByVendor[$vendorDir];
 65172 } elseif (is_file($vendorDir.'/composer/installed.php')) {
 65173 $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
 65174 if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
 65175 self::$installed = $installed[count($installed) - 1];
 65176 }
 65177 }
 65178 }
 65179 }
 65180 
 65181 if (null === self::$installed) {
 65182 
 65183 
 65184 if (substr(__DIR__, -8, 1) !== 'C') {
 65185 self::$installed = require __DIR__ . '/installed.php';
 65186 } else {
 65187 self::$installed = array();
 65188 }
 65189 }
 65190 $installed[] = self::$installed;
 65191 
 65192 return $installed;
 65193 }
 65194 }
 65195 <?php
 65196 
 65197 
 65198 
 65199 $vendorDir = dirname(dirname(__FILE__));
 65200 $baseDir = dirname($vendorDir);
 65201 
 65202 return array(
 65203 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
 65204 );
 65205 <?php
 65206 
 65207 
 65208 
 65209 $vendorDir = dirname(dirname(__FILE__));
 65210 $baseDir = dirname($vendorDir);
 65211 
 65212 return array(
 65213 '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
 65214 '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
 65215 '7844cce90d4037f1a077c08319eef109' => $vendorDir . '/react/promise/src/React/Promise/functions_include.php',
 65216 );
 65217 <?php
 65218 
 65219 
 65220 
 65221 $vendorDir = dirname(dirname(__FILE__));
 65222 $baseDir = dirname($vendorDir);
 65223 
 65224 return array(
 65225 'React\\Promise' => array($vendorDir . '/react/promise/src'),
 65226 );
 65227 <?php
 65228 
 65229 
 65230 
 65231 $vendorDir = dirname(dirname(__FILE__));
 65232 $baseDir = dirname($vendorDir);
 65233 
 65234 return array(
 65235 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
 65236 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
 65237 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
 65238 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
 65239 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
 65240 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
 65241 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
 65242 'Seld\\PharUtils\\' => array($vendorDir . '/seld/phar-utils/src'),
 65243 'Seld\\JsonLint\\' => array($vendorDir . '/seld/jsonlint/src/Seld/JsonLint'),
 65244 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
 65245 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'),
 65246 'Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'),
 65247 'Composer\\Spdx\\' => array($vendorDir . '/composer/spdx-licenses/src'),
 65248 'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
 65249 'Composer\\Pcre\\' => array($vendorDir . '/composer/pcre/src'),
 65250 'Composer\\MetadataMinifier\\' => array($vendorDir . '/composer/metadata-minifier/src'),
 65251 'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'),
 65252 'Composer\\' => array($baseDir . '/src/Composer'),
 65253 );
 65254 <?php
 65255 
 65256 
 65257 
 65258 class ComposerAutoloaderInitComposerPhar1647378817
 65259 {
 65260 private static $loader;
 65261 
 65262 public static function loadClassLoader($class)
 65263 {
 65264 if ('Composer\Autoload\ClassLoader' === $class) {
 65265 require __DIR__ . '/ClassLoader.php';
 65266 }
 65267 }
 65268 
 65269 
 65270 
 65271 
 65272 public static function getLoader()
 65273 {
 65274 if (null !== self::$loader) {
 65275 return self::$loader;
 65276 }
 65277 
 65278 spl_autoload_register(array('ComposerAutoloaderInitComposerPhar1647378817', 'loadClassLoader'), true, true);
 65279 self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
 65280 spl_autoload_unregister(array('ComposerAutoloaderInitComposerPhar1647378817', 'loadClassLoader'));
 65281 
 65282 $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
 65283 if ($useStaticLoader) {
 65284 require __DIR__ . '/autoload_static.php';
 65285 
 65286 call_user_func(\Composer\Autoload\ComposerStaticInitComposerPhar1647378817::getInitializer($loader));
 65287 } else {
 65288 $map = require __DIR__ . '/autoload_namespaces.php';
 65289 foreach ($map as $namespace => $path) {
 65290 $loader->set($namespace, $path);
 65291 }
 65292 
 65293 $map = require __DIR__ . '/autoload_psr4.php';
 65294 foreach ($map as $namespace => $path) {
 65295 $loader->setPsr4($namespace, $path);
 65296 }
 65297 
 65298 $classMap = require __DIR__ . '/autoload_classmap.php';
 65299 if ($classMap) {
 65300 $loader->addClassMap($classMap);
 65301 }
 65302 }
 65303 
 65304 $loader->register(true);
 65305 
 65306 if ($useStaticLoader) {
 65307 $includeFiles = Composer\Autoload\ComposerStaticInitComposerPhar1647378817::$files;
 65308 } else {
 65309 $includeFiles = require __DIR__ . '/autoload_files.php';
 65310 }
 65311 foreach ($includeFiles as $fileIdentifier => $file) {
 65312 composerRequireComposerPhar1647378817($fileIdentifier, $file);
 65313 }
 65314 
 65315 return $loader;
 65316 }
 65317 }
 65318 
 65319 
 65320 
 65321 
 65322 
 65323 
 65324 function composerRequireComposerPhar1647378817($fileIdentifier, $file)
 65325 {
 65326 if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
 65327 $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
 65328 
 65329 require $file;
 65330 }
 65331 }
 65332 <?php
 65333 
 65334 
 65335 
 65336 namespace Composer\Autoload;
 65337 
 65338 class ComposerStaticInitComposerPhar1647378817
 65339 {
 65340 public static $files = array (
 65341 '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
 65342 '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
 65343 '7844cce90d4037f1a077c08319eef109' => __DIR__ . '/..' . '/react/promise/src/React/Promise/functions_include.php',
 65344 );
 65345 
 65346 public static $prefixLengthsPsr4 = array (
 65347 'S' => 
 65348 array (
 65349 'Symfony\\Polyfill\\Mbstring\\' => 26,
 65350 'Symfony\\Polyfill\\Ctype\\' => 23,
 65351 'Symfony\\Component\\Process\\' => 26,
 65352 'Symfony\\Component\\Finder\\' => 25,
 65353 'Symfony\\Component\\Filesystem\\' => 29,
 65354 'Symfony\\Component\\Debug\\' => 24,
 65355 'Symfony\\Component\\Console\\' => 26,
 65356 'Seld\\PharUtils\\' => 15,
 65357 'Seld\\JsonLint\\' => 14,
 65358 ),
 65359 'P' => 
 65360 array (
 65361 'Psr\\Log\\' => 8,
 65362 ),
 65363 'J' => 
 65364 array (
 65365 'JsonSchema\\' => 11,
 65366 ),
 65367 'C' => 
 65368 array (
 65369 'Composer\\XdebugHandler\\' => 23,
 65370 'Composer\\Spdx\\' => 14,
 65371 'Composer\\Semver\\' => 16,
 65372 'Composer\\Pcre\\' => 14,
 65373 'Composer\\MetadataMinifier\\' => 26,
 65374 'Composer\\CaBundle\\' => 18,
 65375 'Composer\\' => 9,
 65376 ),
 65377 );
 65378 
 65379 public static $prefixDirsPsr4 = array (
 65380 'Symfony\\Polyfill\\Mbstring\\' => 
 65381 array (
 65382 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
 65383 ),
 65384 'Symfony\\Polyfill\\Ctype\\' => 
 65385 array (
 65386 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
 65387 ),
 65388 'Symfony\\Component\\Process\\' => 
 65389 array (
 65390 0 => __DIR__ . '/..' . '/symfony/process',
 65391 ),
 65392 'Symfony\\Component\\Finder\\' => 
 65393 array (
 65394 0 => __DIR__ . '/..' . '/symfony/finder',
 65395 ),
 65396 'Symfony\\Component\\Filesystem\\' => 
 65397 array (
 65398 0 => __DIR__ . '/..' . '/symfony/filesystem',
 65399 ),
 65400 'Symfony\\Component\\Debug\\' => 
 65401 array (
 65402 0 => __DIR__ . '/..' . '/symfony/debug',
 65403 ),
 65404 'Symfony\\Component\\Console\\' => 
 65405 array (
 65406 0 => __DIR__ . '/..' . '/symfony/console',
 65407 ),
 65408 'Seld\\PharUtils\\' => 
 65409 array (
 65410 0 => __DIR__ . '/..' . '/seld/phar-utils/src',
 65411 ),
 65412 'Seld\\JsonLint\\' => 
 65413 array (
 65414 0 => __DIR__ . '/..' . '/seld/jsonlint/src/Seld/JsonLint',
 65415 ),
 65416 'Psr\\Log\\' => 
 65417 array (
 65418 0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
 65419 ),
 65420 'JsonSchema\\' => 
 65421 array (
 65422 0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema',
 65423 ),
 65424 'Composer\\XdebugHandler\\' => 
 65425 array (
 65426 0 => __DIR__ . '/..' . '/composer/xdebug-handler/src',
 65427 ),
 65428 'Composer\\Spdx\\' => 
 65429 array (
 65430 0 => __DIR__ . '/..' . '/composer/spdx-licenses/src',
 65431 ),
 65432 'Composer\\Semver\\' => 
 65433 array (
 65434 0 => __DIR__ . '/..' . '/composer/semver/src',
 65435 ),
 65436 'Composer\\Pcre\\' => 
 65437 array (
 65438 0 => __DIR__ . '/..' . '/composer/pcre/src',
 65439 ),
 65440 'Composer\\MetadataMinifier\\' => 
 65441 array (
 65442 0 => __DIR__ . '/..' . '/composer/metadata-minifier/src',
 65443 ),
 65444 'Composer\\CaBundle\\' => 
 65445 array (
 65446 0 => __DIR__ . '/..' . '/composer/ca-bundle/src',
 65447 ),
 65448 'Composer\\' => 
 65449 array (
 65450 0 => __DIR__ . '/../..' . '/src/Composer',
 65451 ),
 65452 );
 65453 
 65454 public static $prefixesPsr0 = array (
 65455 'R' => 
 65456 array (
 65457 'React\\Promise' => 
 65458 array (
 65459 0 => __DIR__ . '/..' . '/react/promise/src',
 65460 ),
 65461 ),
 65462 );
 65463 
 65464 public static $classMap = array (
 65465 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
 65466 );
 65467 
 65468 public static function getInitializer(ClassLoader $loader)
 65469 {
 65470 return \Closure::bind(function () use ($loader) {
 65471 $loader->prefixLengthsPsr4 = ComposerStaticInitComposerPhar1647378817::$prefixLengthsPsr4;
 65472 $loader->prefixDirsPsr4 = ComposerStaticInitComposerPhar1647378817::$prefixDirsPsr4;
 65473 $loader->prefixesPsr0 = ComposerStaticInitComposerPhar1647378817::$prefixesPsr0;
 65474 $loader->classMap = ComposerStaticInitComposerPhar1647378817::$classMap;
 65475 
 65476 }, null, ClassLoader::class);
 65477 }
 65478 }
 65479 
 65480 Copyright (C) 2016 Composer
 65481 
 65482 Permission is hereby granted, free of charge, to any person obtaining a copy of
 65483 this software and associated documentation files (the "Software"), to deal in
 65484 the Software without restriction, including without limitation the rights to
 65485 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 65486 of the Software, and to permit persons to whom the Software is furnished to do
 65487 so, subject to the following conditions:
 65488 
 65489 The above copyright notice and this permission notice shall be included in all
 65490 copies or substantial portions of the Software.
 65491 
 65492 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 65493 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 65494 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 65495 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 65496 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 65497 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 65498 SOFTWARE.
 65499 
 65500 ##
 65501 ## Bundle of CA Root Certificates
 65502 ##
 65503 ## Certificate data from Mozilla as of: Tue Oct 26 03:12:05 2021 GMT
 65504 ##
 65505 ## This is a bundle of X.509 certificates of public Certificate Authorities
 65506 ## (CA). These were automatically extracted from Mozilla's root certificates
 65507 ## file (certdata.txt).  This file can be found in the mozilla source tree:
 65508 ## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
 65509 ##
 65510 ## It contains the certificates in PEM format and therefore
 65511 ## can be directly used with curl / libcurl / php_curl, or with
 65512 ## an Apache+mod_ssl webserver for SSL client authentication.
 65513 ## Just configure this file as the SSLCACertificateFile.
 65514 ##
 65515 ## Conversion done with mk-ca-bundle.pl version 1.28.
 65516 ## SHA256: bb36818a81feaa4cca61101e6d6276cd09e972efcb08112dfed846918ca41d7f
 65517 ##
 65518 
 65519 
 65520 GlobalSign Root CA
 65521 ==================
 65522 -----BEGIN CERTIFICATE-----
 65523 MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
 65524 GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
 65525 b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
 65526 BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
 65527 VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
 65528 DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
 65529 THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
 65530 Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
 65531 c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
 65532 gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
 65533 HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
 65534 AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
 65535 Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
 65536 j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
 65537 hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
 65538 X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
 65539 -----END CERTIFICATE-----
 65540 
 65541 GlobalSign Root CA - R2
 65542 =======================
 65543 -----BEGIN CERTIFICATE-----
 65544 MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
 65545 YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
 65546 bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
 65547 aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
 65548 bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
 65549 ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
 65550 s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
 65551 S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
 65552 TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
 65553 ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
 65554 FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
 65555 YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
 65556 BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
 65557 9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
 65558 01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
 65559 9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
 65560 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
 65561 -----END CERTIFICATE-----
 65562 
 65563 Entrust.net Premium 2048 Secure Server CA
 65564 =========================================
 65565 -----BEGIN CERTIFICATE-----
 65566 MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
 65567 ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
 65568 bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
 65569 BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
 65570 NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
 65571 d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
 65572 MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
 65573 ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
 65574 MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
 65575 Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
 65576 hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
 65577 nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
 65578 VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E
 65579 BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ
 65580 KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy
 65581 T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
 65582 zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT
 65583 J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e
 65584 nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=
 65585 -----END CERTIFICATE-----
 65586 
 65587 Baltimore CyberTrust Root
 65588 =========================
 65589 -----BEGIN CERTIFICATE-----
 65590 MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
 65591 ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
 65592 ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
 65593 SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
 65594 dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
 65595 uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
 65596 UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
 65597 G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
 65598 XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
 65599 l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
 65600 VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
 65601 BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
 65602 cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
 65603 hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
 65604 Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
 65605 RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
 65606 -----END CERTIFICATE-----
 65607 
 65608 Entrust Root Certification Authority
 65609 ====================================
 65610 -----BEGIN CERTIFICATE-----
 65611 MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
 65612 BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
 65613 b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
 65614 A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
 65615 MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
 65616 MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
 65617 Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
 65618 dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
 65619 ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
 65620 A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
 65621 Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
 65622 j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
 65623 rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
 65624 DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
 65625 MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
 65626 hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
 65627 A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
 65628 Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
 65629 v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
 65630 W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
 65631 tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
 65632 -----END CERTIFICATE-----
 65633 
 65634 Comodo AAA Services root
 65635 ========================
 65636 -----BEGIN CERTIFICATE-----
 65637 MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
 65638 R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
 65639 TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
 65640 MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
 65641 c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
 65642 BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
 65643 ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
 65644 C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
 65645 i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
 65646 Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
 65647 Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
 65648 Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
 65649 BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
 65650 cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
 65651 LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
 65652 7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
 65653 Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
 65654 8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
 65655 12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
 65656 -----END CERTIFICATE-----
 65657 
 65658 QuoVadis Root CA 2
 65659 ==================
 65660 -----BEGIN CERTIFICATE-----
 65661 MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
 65662 EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
 65663 ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
 65664 aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
 65665 DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
 65666 XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
 65667 lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
 65668 lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
 65669 lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
 65670 66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
 65671 wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
 65672 D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
 65673 BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
 65674 J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
 65675 DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
 65676 a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
 65677 ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
 65678 Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
 65679 UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
 65680 VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
 65681 +JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
 65682 IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
 65683 WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
 65684 f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
 65685 4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
 65686 VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
 65687 -----END CERTIFICATE-----
 65688 
 65689 QuoVadis Root CA 3
 65690 ==================
 65691 -----BEGIN CERTIFICATE-----
 65692 MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
 65693 EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
 65694 OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
 65695 aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
 65696 DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
 65697 DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
 65698 KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
 65699 DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
 65700 BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
 65701 p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
 65702 nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
 65703 MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
 65704 Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
 65705 uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
 65706 BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
 65707 YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
 65708 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
 65709 BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
 65710 VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
 65711 ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
 65712 AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
 65713 qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
 65714 hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
 65715 POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
 65716 Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
 65717 8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
 65718 bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
 65719 g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
 65720 vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
 65721 qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
 65722 -----END CERTIFICATE-----
 65723 
 65724 Security Communication Root CA
 65725 ==============================
 65726 -----BEGIN CERTIFICATE-----
 65727 MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
 65728 U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
 65729 HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
 65730 U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
 65731 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
 65732 8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
 65733 DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
 65734 5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
 65735 DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
 65736 JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
 65737 DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
 65738 0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
 65739 mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
 65740 s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
 65741 6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
 65742 FL39vmwLAw==
 65743 -----END CERTIFICATE-----
 65744 
 65745 XRamp Global CA Root
 65746 ====================
 65747 -----BEGIN CERTIFICATE-----
 65748 MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
 65749 BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
 65750 dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
 65751 dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
 65752 HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
 65753 U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
 65754 dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
 65755 IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
 65756 foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
 65757 zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
 65758 AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
 65759 xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
 65760 EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
 65761 oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
 65762 AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
 65763 /Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
 65764 qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
 65765 nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
 65766 8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
 65767 -----END CERTIFICATE-----
 65768 
 65769 Go Daddy Class 2 CA
 65770 ===================
 65771 -----BEGIN CERTIFICATE-----
 65772 MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
 65773 VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
 65774 ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
 65775 A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
 65776 RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
 65777 ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
 65778 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
 65779 qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
 65780 YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
 65781 vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
 65782 BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
 65783 atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
 65784 MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
 65785 A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
 65786 PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
 65787 I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
 65788 HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
 65789 Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
 65790 vZ8=
 65791 -----END CERTIFICATE-----
 65792 
 65793 Starfield Class 2 CA
 65794 ====================
 65795 -----BEGIN CERTIFICATE-----
 65796 MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
 65797 U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
 65798 Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
 65799 MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
 65800 A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
 65801 SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
 65802 bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
 65803 JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
 65804 epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
 65805 F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
 65806 MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
 65807 hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
 65808 bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
 65809 QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
 65810 afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
 65811 PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
 65812 xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
 65813 KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
 65814 QBFGmh95DmK/D5fs4C8fF5Q=
 65815 -----END CERTIFICATE-----
 65816 
 65817 DigiCert Assured ID Root CA
 65818 ===========================
 65819 -----BEGIN CERTIFICATE-----
 65820 MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
 65821 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
 65822 IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
 65823 MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
 65824 ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
 65825 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
 65826 9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
 65827 UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
 65828 /lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
 65829 oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
 65830 GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
 65831 66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
 65832 hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
 65833 EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
 65834 SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
 65835 8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
 65836 +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
 65837 -----END CERTIFICATE-----
 65838 
 65839 DigiCert Global Root CA
 65840 =======================
 65841 -----BEGIN CERTIFICATE-----
 65842 MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
 65843 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
 65844 HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
 65845 MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
 65846 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
 65847 hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
 65848 TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
 65849 BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
 65850 4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
 65851 7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
 65852 o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
 65853 8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
 65854 BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
 65855 EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
 65856 tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
 65857 UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
 65858 CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
 65859 -----END CERTIFICATE-----
 65860 
 65861 DigiCert High Assurance EV Root CA
 65862 ==================================
 65863 -----BEGIN CERTIFICATE-----
 65864 MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
 65865 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
 65866 KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
 65867 MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
 65868 MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
 65869 Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
 65870 Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
 65871 OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
 65872 MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
 65873 NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
 65874 h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
 65875 Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
 65876 JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
 65877 V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
 65878 myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
 65879 mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
 65880 vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
 65881 -----END CERTIFICATE-----
 65882 
 65883 SwissSign Gold CA - G2
 65884 ======================
 65885 -----BEGIN CERTIFICATE-----
 65886 MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
 65887 EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
 65888 MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
 65889 c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
 65890 AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
 65891 t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
 65892 jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
 65893 vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
 65894 ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
 65895 AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
 65896 jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
 65897 peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
 65898 7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
 65899 GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
 65900 AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
 65901 OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
 65902 L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
 65903 5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
 65904 44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
 65905 Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
 65906 Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
 65907 mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
 65908 vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
 65909 KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
 65910 NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
 65911 viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
 65912 -----END CERTIFICATE-----
 65913 
 65914 SwissSign Silver CA - G2
 65915 ========================
 65916 -----BEGIN CERTIFICATE-----
 65917 MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
 65918 BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
 65919 DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
 65920 aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
 65921 9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
 65922 N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
 65923 +/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
 65924 6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
 65925 MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
 65926 qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
 65927 FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
 65928 ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
 65929 celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
 65930 CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
 65931 BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
 65932 tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
 65933 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
 65934 4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
 65935 kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
 65936 3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
 65937 /uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
 65938 DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
 65939 e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
 65940 WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
 65941 DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
 65942 DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
 65943 -----END CERTIFICATE-----
 65944 
 65945 SecureTrust CA
 65946 ==============
 65947 -----BEGIN CERTIFICATE-----
 65948 MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
 65949 EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
 65950 dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
 65951 BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
 65952 ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
 65953 OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
 65954 DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
 65955 GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
 65956 01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
 65957 ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
 65958 BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
 65959 aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
 65960 KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
 65961 SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
 65962 mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
 65963 nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
 65964 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
 65965 -----END CERTIFICATE-----
 65966 
 65967 Secure Global CA
 65968 ================
 65969 -----BEGIN CERTIFICATE-----
 65970 MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
 65971 EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
 65972 bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
 65973 MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
 65974 Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
 65975 YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
 65976 bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
 65977 8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
 65978 HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
 65979 0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
 65980 EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
 65981 oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
 65982 MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
 65983 OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
 65984 CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
 65985 3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
 65986 f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
 65987 -----END CERTIFICATE-----
 65988 
 65989 COMODO Certification Authority
 65990 ==============================
 65991 -----BEGIN CERTIFICATE-----
 65992 MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
 65993 BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
 65994 A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
 65995 dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
 65996 MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
 65997 T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
 65998 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
 65999 +7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
 66000 xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
 66001 4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
 66002 1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
 66003 rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
 66004 BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
 66005 b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
 66006 AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
 66007 OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
 66008 RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
 66009 IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
 66010 +8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
 66011 -----END CERTIFICATE-----
 66012 
 66013 Network Solutions Certificate Authority
 66014 =======================================
 66015 -----BEGIN CERTIFICATE-----
 66016 MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
 66017 EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
 66018 IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
 66019 MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
 66020 MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
 66021 CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
 66022 jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
 66023 aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
 66024 crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
 66025 /Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
 66026 AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
 66027 BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
 66028 bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
 66029 A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
 66030 4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
 66031 GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
 66032 wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
 66033 ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
 66034 -----END CERTIFICATE-----
 66035 
 66036 COMODO ECC Certification Authority
 66037 ==================================
 66038 -----BEGIN CERTIFICATE-----
 66039 MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
 66040 R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
 66041 ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
 66042 dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
 66043 GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
 66044 Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
 66045 b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
 66046 4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
 66047 wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
 66048 BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
 66049 FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
 66050 U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
 66051 -----END CERTIFICATE-----
 66052 
 66053 Certigna
 66054 ========
 66055 -----BEGIN CERTIFICATE-----
 66056 MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
 66057 EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
 66058 MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
 66059 Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
 66060 XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
 66061 GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
 66062 ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
 66063 DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
 66064 Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
 66065 tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
 66066 BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
 66067 SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
 66068 hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
 66069 ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
 66070 PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
 66071 1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
 66072 WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
 66073 -----END CERTIFICATE-----
 66074 
 66075 Cybertrust Global Root
 66076 ======================
 66077 -----BEGIN CERTIFICATE-----
 66078 MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
 66079 ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
 66080 MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
 66081 ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
 66082 +Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
 66083 0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
 66084 AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
 66085 89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
 66086 8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
 66087 BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
 66088 MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
 66089 A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
 66090 lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
 66091 5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
 66092 hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
 66093 X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
 66094 WL1WMRJOEcgh4LMRkWXbtKaIOM5V
 66095 -----END CERTIFICATE-----
 66096 
 66097 ePKI Root Certification Authority
 66098 =================================
 66099 -----BEGIN CERTIFICATE-----
 66100 MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
 66101 EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
 66102 Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
 66103 MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
 66104 MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
 66105 AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
 66106 IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
 66107 lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
 66108 qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
 66109 12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
 66110 WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
 66111 ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
 66112 lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
 66113 vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
 66114 Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
 66115 MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
 66116 ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
 66117 1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
 66118 KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
 66119 xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
 66120 NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
 66121 GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
 66122 xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
 66123 gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
 66124 sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
 66125 BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
 66126 -----END CERTIFICATE-----
 66127 
 66128 certSIGN ROOT CA
 66129 ================
 66130 -----BEGIN CERTIFICATE-----
 66131 MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
 66132 VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
 66133 Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
 66134 CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
 66135 JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
 66136 rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
 66137 ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
 66138 0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
 66139 AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
 66140 Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
 66141 AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
 66142 SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
 66143 x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
 66144 vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
 66145 TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
 66146 -----END CERTIFICATE-----
 66147 
 66148 NetLock Arany (Class Gold) Főtanúsítvány
 66149 ========================================
 66150 -----BEGIN CERTIFICATE-----
 66151 MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
 66152 A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
 66153 dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
 66154 cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
 66155 MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
 66156 ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
 66157 biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
 66158 c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
 66159 0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
 66160 /HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
 66161 H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
 66162 fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
 66163 neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
 66164 BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
 66165 qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
 66166 YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
 66167 bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
 66168 NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
 66169 dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
 66170 -----END CERTIFICATE-----
 66171 
 66172 Hongkong Post Root CA 1
 66173 =======================
 66174 -----BEGIN CERTIFICATE-----
 66175 MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
 66176 DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
 66177 NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
 66178 IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
 66179 AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
 66180 ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
 66181 auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
 66182 qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
 66183 V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
 66184 HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
 66185 h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
 66186 l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
 66187 IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
 66188 T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
 66189 c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
 66190 -----END CERTIFICATE-----
 66191 
 66192 SecureSign RootCA11
 66193 ===================
 66194 -----BEGIN CERTIFICATE-----
 66195 MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
 66196 SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
 66197 b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
 66198 KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
 66199 cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
 66200 TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
 66201 wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
 66202 g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
 66203 O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
 66204 bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
 66205 t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
 66206 OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
 66207 bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
 66208 Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
 66209 y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
 66210 lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
 66211 -----END CERTIFICATE-----
 66212 
 66213 Microsec e-Szigno Root CA 2009
 66214 ==============================
 66215 -----BEGIN CERTIFICATE-----
 66216 MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
 66217 MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
 66218 c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
 66219 dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
 66220 BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
 66221 U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
 66222 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
 66223 fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
 66224 0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
 66225 pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
 66226 1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
 66227 AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
 66228 QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
 66229 FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
 66230 lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
 66231 I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
 66232 tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
 66233 yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
 66234 LXpUq3DDfSJlgnCW
 66235 -----END CERTIFICATE-----
 66236 
 66237 GlobalSign Root CA - R3
 66238 =======================
 66239 -----BEGIN CERTIFICATE-----
 66240 MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
 66241 YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
 66242 bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
 66243 aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
 66244 bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
 66245 iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
 66246 0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
 66247 rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
 66248 OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
 66249 xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
 66250 FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
 66251 lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
 66252 EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
 66253 bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
 66254 YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
 66255 kpeDMdmztcpHWD9f
 66256 -----END CERTIFICATE-----
 66257 
 66258 Autoridad de Certificacion Firmaprofesional CIF A62634068
 66259 =========================================================
 66260 -----BEGIN CERTIFICATE-----
 66261 MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
 66262 BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
 66263 MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
 66264 QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
 66265 NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
 66266 Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
 66267 B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
 66268 7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
 66269 ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
 66270 plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
 66271 MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
 66272 LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
 66273 bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
 66274 vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
 66275 EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
 66276 DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
 66277 cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
 66278 bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
 66279 ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
 66280 51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
 66281 R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
 66282 T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
 66283 Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
 66284 osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
 66285 crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
 66286 saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
 66287 KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
 66288 6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
 66289 -----END CERTIFICATE-----
 66290 
 66291 Izenpe.com
 66292 ==========
 66293 -----BEGIN CERTIFICATE-----
 66294 MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
 66295 EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
 66296 MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
 66297 QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
 66298 03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
 66299 ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
 66300 +zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
 66301 PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
 66302 OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
 66303 F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
 66304 0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
 66305 0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
 66306 leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
 66307 AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
 66308 SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
 66309 NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
 66310 MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
 66311 BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
 66312 Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
 66313 kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
 66314 hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
 66315 g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
 66316 aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
 66317 nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
 66318 ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
 66319 Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
 66320 WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
 66321 -----END CERTIFICATE-----
 66322 
 66323 Go Daddy Root Certificate Authority - G2
 66324 ========================================
 66325 -----BEGIN CERTIFICATE-----
 66326 MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
 66327 B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
 66328 MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
 66329 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
 66330 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
 66331 A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
 66332 hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
 66333 9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
 66334 +qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
 66335 fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
 66336 NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
 66337 MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
 66338 BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
 66339 vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
 66340 5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
 66341 N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
 66342 LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
 66343 -----END CERTIFICATE-----
 66344 
 66345 Starfield Root Certificate Authority - G2
 66346 =========================================
 66347 -----BEGIN CERTIFICATE-----
 66348 MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
 66349 B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
 66350 b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
 66351 eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
 66352 DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
 66353 VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
 66354 dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
 66355 W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
 66356 bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
 66357 N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
 66358 ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
 66359 JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
 66360 AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
 66361 TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
 66362 4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
 66363 F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
 66364 pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
 66365 c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
 66366 -----END CERTIFICATE-----
 66367 
 66368 Starfield Services Root Certificate Authority - G2
 66369 ==================================================
 66370 -----BEGIN CERTIFICATE-----
 66371 MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
 66372 B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
 66373 b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
 66374 IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
 66375 BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
 66376 dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
 66377 Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
 66378 AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
 66379 h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
 66380 hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
 66381 LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
 66382 rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
 66383 AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
 66384 SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
 66385 E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
 66386 xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
 66387 iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
 66388 YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
 66389 -----END CERTIFICATE-----
 66390 
 66391 AffirmTrust Commercial
 66392 ======================
 66393 -----BEGIN CERTIFICATE-----
 66394 MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
 66395 BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
 66396 MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
 66397 bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
 66398 AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
 66399 DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
 66400 C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
 66401 BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
 66402 MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
 66403 HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
 66404 AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
 66405 hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
 66406 qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
 66407 0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
 66408 sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
 66409 -----END CERTIFICATE-----
 66410 
 66411 AffirmTrust Networking
 66412 ======================
 66413 -----BEGIN CERTIFICATE-----
 66414 MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
 66415 BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
 66416 MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
 66417 bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
 66418 AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
 66419 Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
 66420 dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
 66421 /PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
 66422 h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
 66423 HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
 66424 AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
 66425 UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
 66426 12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
 66427 WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
 66428 /ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
 66429 -----END CERTIFICATE-----
 66430 
 66431 AffirmTrust Premium
 66432 ===================
 66433 -----BEGIN CERTIFICATE-----
 66434 MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
 66435 BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
 66436 OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
 66437 dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
 66438 MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
 66439 BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
 66440 5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
 66441 +7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
 66442 GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
 66443 p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
 66444 S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
 66445 6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
 66446 /bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
 66447 +Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
 66448 /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
 66449 MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
 66450 Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
 66451 6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
 66452 L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
 66453 +4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
 66454 BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
 66455 IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
 66456 g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
 66457 zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
 66458 -----END CERTIFICATE-----
 66459 
 66460 AffirmTrust Premium ECC
 66461 =======================
 66462 -----BEGIN CERTIFICATE-----
 66463 MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
 66464 BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
 66465 MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
 66466 cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
 66467 IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
 66468 N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
 66469 BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
 66470 BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
 66471 57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
 66472 eQ==
 66473 -----END CERTIFICATE-----
 66474 
 66475 Certum Trusted Network CA
 66476 =========================
 66477 -----BEGIN CERTIFICATE-----
 66478 MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
 66479 ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
 66480 biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
 66481 MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
 66482 ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
 66483 MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
 66484 AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
 66485 l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
 66486 J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
 66487 fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
 66488 cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
 66489 Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
 66490 DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
 66491 jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
 66492 mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
 66493 Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
 66494 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
 66495 -----END CERTIFICATE-----
 66496 
 66497 TWCA Root Certification Authority
 66498 =================================
 66499 -----BEGIN CERTIFICATE-----
 66500 MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
 66501 VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
 66502 dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
 66503 EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
 66504 IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
 66505 AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
 66506 QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
 66507 oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
 66508 4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
 66509 y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
 66510 BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
 66511 9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
 66512 mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
 66513 QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
 66514 T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
 66515 Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
 66516 -----END CERTIFICATE-----
 66517 
 66518 Security Communication RootCA2
 66519 ==============================
 66520 -----BEGIN CERTIFICATE-----
 66521 MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
 66522 U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
 66523 dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
 66524 SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
 66525 aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
 66526 ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
 66527 +T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
 66528 3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
 66529 spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
 66530 EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
 66531 QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
 66532 CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
 66533 u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
 66534 3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
 66535 tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
 66536 mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
 66537 -----END CERTIFICATE-----
 66538 
 66539 EC-ACC
 66540 ======
 66541 -----BEGIN CERTIFICATE-----
 66542 MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
 66543 BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
 66544 ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
 66545 VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
 66546 CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
 66547 BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
 66548 MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
 66549 SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
 66550 Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
 66551 cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
 66552 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
 66553 w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
 66554 ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
 66555 HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
 66556 E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
 66557 0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
 66558 BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
 66559 VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
 66560 Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
 66561 dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
 66562 lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
 66563 Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
 66564 l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
 66565 E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
 66566 5EI=
 66567 -----END CERTIFICATE-----
 66568 
 66569 Hellenic Academic and Research Institutions RootCA 2011
 66570 =======================================================
 66571 -----BEGIN CERTIFICATE-----
 66572 MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
 66573 O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
 66574 aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
 66575 IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
 66576 AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
 66577 IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
 66578 IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
 66579 AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
 66580 1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
 66581 71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
 66582 8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
 66583 3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
 66584 MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
 66585 MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
 66586 b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
 66587 XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
 66588 TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
 66589 /md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
 66590 7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
 66591 -----END CERTIFICATE-----
 66592 
 66593 Actalis Authentication Root CA
 66594 ==============================
 66595 -----BEGIN CERTIFICATE-----
 66596 MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
 66597 BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
 66598 AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
 66599 MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
 66600 IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
 66601 IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
 66602 wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
 66603 by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
 66604 zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
 66605 YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
 66606 oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
 66607 EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
 66608 hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
 66609 EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
 66610 jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
 66611 iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
 66612 ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
 66613 WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
 66614 JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
 66615 K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
 66616 Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
 66617 4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
 66618 2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
 66619 lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
 66620 OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
 66621 vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
 66622 -----END CERTIFICATE-----
 66623 
 66624 Buypass Class 2 Root CA
 66625 =======================
 66626 -----BEGIN CERTIFICATE-----
 66627 MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
 66628 QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X
 66629 DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
 66630 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw
 66631 DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1
 66632 g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn
 66633 9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b
 66634 /+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU
 66635 CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff
 66636 awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI
 66637 zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn
 66638 Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX
 66639 Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
 66640 M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
 66641 VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
 66642 AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
 66643 A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI
 66644 osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S
 66645 aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd
 66646 DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD
 66647 LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0
 66648 oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC
 66649 wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS
 66650 CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN
 66651 rJgWVqA=
 66652 -----END CERTIFICATE-----
 66653 
 66654 Buypass Class 3 Root CA
 66655 =======================
 66656 -----BEGIN CERTIFICATE-----
 66657 MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
 66658 QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X
 66659 DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
 66660 eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw
 66661 DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH
 66662 sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR
 66663 5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh
 66664 7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ
 66665 ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH
 66666 2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV
 66667 /afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ
 66668 RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA
 66669 Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq
 66670 j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
 66671 VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
 66672 AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
 66673 cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G
 66674 uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG
 66675 Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8
 66676 ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2
 66677 KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
 66678 6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug
 66679 UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
 66680 eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi
 66681 Cp/HuZc=
 66682 -----END CERTIFICATE-----
 66683 
 66684 T-TeleSec GlobalRoot Class 3
 66685 ============================
 66686 -----BEGIN CERTIFICATE-----
 66687 MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
 66688 IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
 66689 cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
 66690 MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
 66691 dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
 66692 ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
 66693 DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
 66694 9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
 66695 NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
 66696 iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
 66697 0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
 66698 MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
 66699 AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
 66700 fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
 66701 ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
 66702 P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
 66703 e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
 66704 -----END CERTIFICATE-----
 66705 
 66706 D-TRUST Root Class 3 CA 2 2009
 66707 ==============================
 66708 -----BEGIN CERTIFICATE-----
 66709 MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK
 66710 DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe
 66711 Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE
 66712 LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw
 66713 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD
 66714 ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA
 66715 BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv
 66716 KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z
 66717 p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC
 66718 AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ
 66719 4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y
 66720 eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw
 66721 MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G
 66722 PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw
 66723 OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm
 66724 2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
 66725 o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV
 66726 dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph
 66727 X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=
 66728 -----END CERTIFICATE-----
 66729 
 66730 D-TRUST Root Class 3 CA 2 EV 2009
 66731 =================================
 66732 -----BEGIN CERTIFICATE-----
 66733 MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
 66734 DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
 66735 OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
 66736 DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
 66737 OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS
 66738 egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh
 66739 zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T
 66740 7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60
 66741 sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35
 66742 11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv
 66743 cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v
 66744 ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El
 66745 MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp
 66746 b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh
 66747 c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+
 66748 PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
 66749 nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX
 66750 ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA
 66751 NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv
 66752 w9y4AyHqnxbxLFS1
 66753 -----END CERTIFICATE-----
 66754 
 66755 CA Disig Root R2
 66756 ================
 66757 -----BEGIN CERTIFICATE-----
 66758 MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw
 66759 EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp
 66760 ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx
 66761 EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp
 66762 c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC
 66763 w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia
 66764 xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7
 66765 A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S
 66766 GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV
 66767 g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa
 66768 5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE
 66769 koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A
 66770 Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i
 66771 Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV
 66772 HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u
 66773 Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
 66774 tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV
 66775 sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je
 66776 dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8
 66777 1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx
 66778 mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01
 66779 utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0
 66780 sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg
 66781 UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV
 66782 7+ZtsH8tZ/3zbBt1RqPlShfppNcL
 66783 -----END CERTIFICATE-----
 66784 
 66785 ACCVRAIZ1
 66786 =========
 66787 -----BEGIN CERTIFICATE-----
 66788 MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB
 66789 SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1
 66790 MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH
 66791 UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
 66792 DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM
 66793 jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0
 66794 RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD
 66795 aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ
 66796 0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG
 66797 WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7
 66798 8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR
 66799 5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J
 66800 9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK
 66801 Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw
 66802 Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu
 66803 Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
 66804 VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM
 66805 Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA
 66806 QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh
 66807 AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA
 66808 YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj
 66809 AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA
 66810 IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk
 66811 aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0
 66812 dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2
 66813 MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI
 66814 hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E
 66815 R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN
 66816 YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49
 66817 nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ
 66818 TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3
 66819 sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
 66820 I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg
 66821 Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd
 66822 3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p
 66823 EfbRD0tVNEYqi4Y7
 66824 -----END CERTIFICATE-----
 66825 
 66826 TWCA Global Root CA
 66827 ===================
 66828 -----BEGIN CERTIFICATE-----
 66829 MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT
 66830 CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD
 66831 QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK
 66832 EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg
 66833 Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C
 66834 nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV
 66835 r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR
 66836 Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV
 66837 tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W
 66838 KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99
 66839 sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p
 66840 yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn
 66841 kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI
 66842 zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC
 66843 AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g
 66844 cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
 66845 LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M
 66846 8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg
 66847 /eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg
 66848 lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP
 66849 A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m
 66850 i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
 66851 EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
 66852 zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
 66853 -----END CERTIFICATE-----
 66854 
 66855 TeliaSonera Root CA v1
 66856 ======================
 66857 -----BEGIN CERTIFICATE-----
 66858 MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
 66859 CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
 66860 MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
 66861 VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
 66862 6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
 66863 3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
 66864 B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
 66865 Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
 66866 oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
 66867 F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
 66868 oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
 66869 gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
 66870 TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
 66871 AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
 66872 DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
 66873 zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
 66874 0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
 66875 pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
 66876 G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
 66877 c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
 66878 JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
 66879 qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
 66880 Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
 66881 WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
 66882 -----END CERTIFICATE-----
 66883 
 66884 E-Tugra Certification Authority
 66885 ===============================
 66886 -----BEGIN CERTIFICATE-----
 66887 MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
 66888 DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
 66889 ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
 66890 ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
 66891 NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
 66892 QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
 66893 cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
 66894 DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
 66895 MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
 66896 hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
 66897 CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
 66898 ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
 66899 BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
 66900 E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
 66901 rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
 66902 jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
 66903 rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
 66904 dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
 66905 /wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
 66906 MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
 66907 kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
 66908 XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
 66909 VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
 66910 a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
 66911 dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
 66912 KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
 66913 Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
 66914 8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
 66915 C7TbO6Orb1wdtn7os4I07QZcJA==
 66916 -----END CERTIFICATE-----
 66917 
 66918 T-TeleSec GlobalRoot Class 2
 66919 ============================
 66920 -----BEGIN CERTIFICATE-----
 66921 MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
 66922 IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
 66923 cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
 66924 MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
 66925 dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
 66926 ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
 66927 DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
 66928 SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
 66929 vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
 66930 2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
 66931 WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
 66932 MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
 66933 YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
 66934 r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
 66935 vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
 66936 3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
 66937 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
 66938 -----END CERTIFICATE-----
 66939 
 66940 Atos TrustedRoot 2011
 66941 =====================
 66942 -----BEGIN CERTIFICATE-----
 66943 MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
 66944 cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
 66945 MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
 66946 A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
 66947 hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
 66948 54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
 66949 DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
 66950 HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
 66951 z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
 66952 l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
 66953 bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
 66954 CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
 66955 k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
 66956 TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
 66957 61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
 66958 3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
 66959 -----END CERTIFICATE-----
 66960 
 66961 QuoVadis Root CA 1 G3
 66962 =====================
 66963 -----BEGIN CERTIFICATE-----
 66964 MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG
 66965 A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
 66966 b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN
 66967 MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg
 66968 RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE
 66969 PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm
 66970 PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6
 66971 Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN
 66972 ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l
 66973 g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV
 66974 7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX
 66975 9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f
 66976 iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg
 66977 t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
 66978 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI
 66979 hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
 66980 MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3
 66981 GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct
 66982 Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP
 66983 +V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh
 66984 3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa
 66985 wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6
 66986 O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0
 66987 FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV
 66988 hMJKzRwuJIczYOXD
 66989 -----END CERTIFICATE-----
 66990 
 66991 QuoVadis Root CA 2 G3
 66992 =====================
 66993 -----BEGIN CERTIFICATE-----
 66994 MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG
 66995 A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
 66996 b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN
 66997 MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg
 66998 RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh
 66999 ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY
 67000 NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t
 67001 oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o
 67002 MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l
 67003 V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo
 67004 L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ
 67005 sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD
 67006 6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh
 67007 lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
 67008 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI
 67009 hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
 67010 AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K
 67011 pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9
 67012 x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz
 67013 dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X
 67014 U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw
 67015 mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD
 67016 zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN
 67017 JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr
 67018 O3jtZsSOeWmD3n+M
 67019 -----END CERTIFICATE-----
 67020 
 67021 QuoVadis Root CA 3 G3
 67022 =====================
 67023 -----BEGIN CERTIFICATE-----
 67024 MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG
 67025 A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
 67026 b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN
 67027 MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg
 67028 RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286
 67029 IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL
 67030 Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe
 67031 6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3
 67032 I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U
 67033 VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7
 67034 5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi
 67035 Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM
 67036 dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt
 67037 rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
 67038 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI
 67039 hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
 67040 KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS
 67041 t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ
 67042 TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du
 67043 DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib
 67044 Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD
 67045 hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX
 67046 0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW
 67047 dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2
 67048 PpxxVJkES/1Y+Zj0
 67049 -----END CERTIFICATE-----
 67050 
 67051 DigiCert Assured ID Root G2
 67052 ===========================
 67053 -----BEGIN CERTIFICATE-----
 67054 MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG
 67055 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
 67056 IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw
 67057 MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
 67058 ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw
 67059 ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH
 67060 35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq
 67061 bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw
 67062 VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP
 67063 YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn
 67064 lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO
 67065 w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv
 67066 0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz
 67067 d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW
 67068 hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M
 67069 jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
 67070 IhNzbM8m9Yop5w==
 67071 -----END CERTIFICATE-----
 67072 
 67073 DigiCert Assured ID Root G3
 67074 ===========================
 67075 -----BEGIN CERTIFICATE-----
 67076 MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
 67077 UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD
 67078 VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
 67079 MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 67080 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ
 67081 BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb
 67082 RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs
 67083 KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF
 67084 UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy
 67085 YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy
 67086 1vUhZscv6pZjamVFkpUBtA==
 67087 -----END CERTIFICATE-----
 67088 
 67089 DigiCert Global Root G2
 67090 =======================
 67091 -----BEGIN CERTIFICATE-----
 67092 MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG
 67093 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
 67094 HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx
 67095 MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
 67096 dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq
 67097 hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ
 67098 kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO
 67099 3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV
 67100 BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM
 67101 UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB
 67102 o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu
 67103 5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr
 67104 F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U
 67105 WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH
 67106 QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/
 67107 iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
 67108 MrY=
 67109 -----END CERTIFICATE-----
 67110 
 67111 DigiCert Global Root G3
 67112 =======================
 67113 -----BEGIN CERTIFICATE-----
 67114 MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV
 67115 UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD
 67116 VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw
 67117 MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
 67118 aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C
 67119 AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O
 67120 YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP
 67121 BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp
 67122 Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y
 67123 3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34
 67124 VOKa5Vt8sycX
 67125 -----END CERTIFICATE-----
 67126 
 67127 DigiCert Trusted Root G4
 67128 ========================
 67129 -----BEGIN CERTIFICATE-----
 67130 MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
 67131 EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw
 67132 HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
 67133 MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
 67134 d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G
 67135 CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp
 67136 pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o
 67137 k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa
 67138 vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
 67139 QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6
 67140 MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm
 67141 mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7
 67142 f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH
 67143 dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8
 67144 oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
 67145 DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
 67146 ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
 67147 ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr
 67148 yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy
 67149 7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah
 67150 ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN
 67151 5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb
 67152 /UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa
 67153 5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK
 67154 G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP
 67155 82Z+
 67156 -----END CERTIFICATE-----
 67157 
 67158 COMODO RSA Certification Authority
 67159 ==================================
 67160 -----BEGIN CERTIFICATE-----
 67161 MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
 67162 BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
 67163 A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv
 67164 biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC
 67165 R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
 67166 ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB
 67167 dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn
 67168 dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ
 67169 FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+
 67170 5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG
 67171 x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX
 67172 2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL
 67173 OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3
 67174 sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C
 67175 GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5
 67176 WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
 67177 FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
 67178 DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt
 67179 rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+
 67180 nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
 67181 tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW
 67182 sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp
 67183 pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA
 67184 zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq
 67185 ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52
 67186 7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I
 67187 LaZRfyHBNVOFBkpdn627G190
 67188 -----END CERTIFICATE-----
 67189 
 67190 USERTrust RSA Certification Authority
 67191 =====================================
 67192 -----BEGIN CERTIFICATE-----
 67193 MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE
 67194 BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
 67195 ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
 67196 dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE
 67197 BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
 67198 ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
 67199 dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz
 67200 0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j
 67201 Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
 67202 RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O
 67203 +T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq
 67204 /nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE
 67205 Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM
 67206 lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
 67207 yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+
 67208 eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
 67209 BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
 67210 MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
 67211 FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ
 67212 7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ
 67213 Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM
 67214 8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi
 67215 FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi
 67216 yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c
 67217 J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
 67218 sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx
 67219 Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
 67220 -----END CERTIFICATE-----
 67221 
 67222 USERTrust ECC Certification Authority
 67223 =====================================
 67224 -----BEGIN CERTIFICATE-----
 67225 MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
 67226 VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
 67227 aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
 67228 biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
 67229 VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
 67230 aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
 67231 biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
 67232 0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
 67233 nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
 67234 HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
 67235 HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
 67236 9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
 67237 -----END CERTIFICATE-----
 67238 
 67239 GlobalSign ECC Root CA - R4
 67240 ===========================
 67241 -----BEGIN CERTIFICATE-----
 67242 MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
 67243 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
 67244 EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
 67245 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
 67246 EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
 67247 OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
 67248 AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
 67249 MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
 67250 JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
 67251 -----END CERTIFICATE-----
 67252 
 67253 GlobalSign ECC Root CA - R5
 67254 ===========================
 67255 -----BEGIN CERTIFICATE-----
 67256 MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
 67257 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
 67258 EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
 67259 R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
 67260 EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
 67261 SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
 67262 h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
 67263 BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
 67264 uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
 67265 yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
 67266 -----END CERTIFICATE-----
 67267 
 67268 Staat der Nederlanden EV Root CA
 67269 ================================
 67270 -----BEGIN CERTIFICATE-----
 67271 MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE
 67272 CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
 67273 RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M
 67274 MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl
 67275 cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk
 67276 SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW
 67277 O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r
 67278 0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8
 67279 Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV
 67280 XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr
 67281 08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV
 67282 0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd
 67283 74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx
 67284 fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC
 67285 MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa
 67286 ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
 67287 eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu
 67288 c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq
 67289 5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN
 67290 b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN
 67291 f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi
 67292 5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4
 67293 WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK
 67294 DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy
 67295 eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
 67296 -----END CERTIFICATE-----
 67297 
 67298 IdenTrust Commercial Root CA 1
 67299 ==============================
 67300 -----BEGIN CERTIFICATE-----
 67301 MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG
 67302 EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS
 67303 b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES
 67304 MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB
 67305 IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld
 67306 hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/
 67307 mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi
 67308 1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C
 67309 XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl
 67310 3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy
 67311 NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV
 67312 WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg
 67313 xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix
 67314 uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
 67315 AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI
 67316 hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
 67317 6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg
 67318 ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt
 67319 ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV
 67320 YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX
 67321 feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro
 67322 kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe
 67323 2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz
 67324 Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R
 67325 cGzM7vRX+Bi6hG6H
 67326 -----END CERTIFICATE-----
 67327 
 67328 IdenTrust Public Sector Root CA 1
 67329 =================================
 67330 -----BEGIN CERTIFICATE-----
 67331 MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG
 67332 EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv
 67333 ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV
 67334 UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS
 67335 b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy
 67336 P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6
 67337 Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI
 67338 rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf
 67339 qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS
 67340 mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn
 67341 ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh
 67342 LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v
 67343 iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL
 67344 4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B
 67345 Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw
 67346 DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
 67347 t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A
 67348 mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt
 67349 GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt
 67350 m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx
 67351 NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4
 67352 Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI
 67353 ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC
 67354 ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ
 67355 3Wl9af0AVqW3rLatt8o+Ae+c
 67356 -----END CERTIFICATE-----
 67357 
 67358 Entrust Root Certification Authority - G2
 67359 =========================================
 67360 -----BEGIN CERTIFICATE-----
 67361 MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
 67362 BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
 67363 bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
 67364 b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
 67365 HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
 67366 DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
 67367 OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
 67368 eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
 67369 MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
 67370 /vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
 67371 HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
 67372 s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
 67373 TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
 67374 AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
 67375 0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
 67376 iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
 67377 Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
 67378 nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
 67379 vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
 67380 e4pIb4tF9g==
 67381 -----END CERTIFICATE-----
 67382 
 67383 Entrust Root Certification Authority - EC1
 67384 ==========================================
 67385 -----BEGIN CERTIFICATE-----
 67386 MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
 67387 FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
 67388 YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
 67389 ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
 67390 IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
 67391 FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
 67392 LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
 67393 dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
 67394 IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
 67395 AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
 67396 9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
 67397 FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
 67398 vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
 67399 kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
 67400 -----END CERTIFICATE-----
 67401 
 67402 CFCA EV ROOT
 67403 ============
 67404 -----BEGIN CERTIFICATE-----
 67405 MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE
 67406 CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB
 67407 IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw
 67408 MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD
 67409 DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV
 67410 BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD
 67411 7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN
 67412 uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW
 67413 ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7
 67414 xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f
 67415 py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K
 67416 gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol
 67417 hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ
 67418 tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf
 67419 BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
 67420 /wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
 67421 ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q
 67422 ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua
 67423 4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG
 67424 E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX
 67425 BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn
 67426 aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy
 67427 PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
 67428 kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
 67429 ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
 67430 -----END CERTIFICATE-----
 67431 
 67432 OISTE WISeKey Global Root GB CA
 67433 ===============================
 67434 -----BEGIN CERTIFICATE-----
 67435 MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
 67436 EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
 67437 ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
 67438 MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
 67439 VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
 67440 b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
 67441 scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
 67442 rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
 67443 9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
 67444 Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
 67445 GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
 67446 /zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
 67447 hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
 67448 dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
 67449 VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
 67450 HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
 67451 Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
 67452 -----END CERTIFICATE-----
 67453 
 67454 SZAFIR ROOT CA2
 67455 ===============
 67456 -----BEGIN CERTIFICATE-----
 67457 MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
 67458 A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
 67459 BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
 67460 BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
 67461 VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
 67462 qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
 67463 DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
 67464 2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
 67465 ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
 67466 ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
 67467 AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
 67468 AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
 67469 O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
 67470 oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
 67471 4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
 67472 +/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
 67473 -----END CERTIFICATE-----
 67474 
 67475 Certum Trusted Network CA 2
 67476 ===========================
 67477 -----BEGIN CERTIFICATE-----
 67478 MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
 67479 BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
 67480 bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
 67481 ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
 67482 TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
 67483 cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
 67484 IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
 67485 7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
 67486 CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
 67487 Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
 67488 uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
 67489 GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
 67490 9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
 67491 Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
 67492 hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
 67493 BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
 67494 AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
 67495 hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
 67496 Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
 67497 L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
 67498 clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
 67499 pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
 67500 w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
 67501 J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
 67502 ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
 67503 is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
 67504 zAYspsbiDrW5viSP
 67505 -----END CERTIFICATE-----
 67506 
 67507 Hellenic Academic and Research Institutions RootCA 2015
 67508 =======================================================
 67509 -----BEGIN CERTIFICATE-----
 67510 MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT
 67511 BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0
 67512 aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
 67513 YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx
 67514 MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg
 67515 QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV
 67516 BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw
 67517 MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv
 67518 bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh
 67519 iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+
 67520 6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd
 67521 FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr
 67522 i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F
 67523 GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2
 67524 fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu
 67525 iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
 67526 Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
 67527 AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI
 67528 hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+
 67529 D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM
 67530 d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y
 67531 d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn
 67532 82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb
 67533 davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F
 67534 Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt
 67535 J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa
 67536 JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q
 67537 p/UsQu0yrbYhnr68
 67538 -----END CERTIFICATE-----
 67539 
 67540 Hellenic Academic and Research Institutions ECC RootCA 2015
 67541 ===========================================================
 67542 -----BEGIN CERTIFICATE-----
 67543 MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0
 67544 aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
 67545 cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
 67546 aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw
 67547 MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj
 67548 IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD
 67549 VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290
 67550 Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP
 67551 dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK
 67552 Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
 67553 BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA
 67554 GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn
 67555 dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
 67556 -----END CERTIFICATE-----
 67557 
 67558 ISRG Root X1
 67559 ============
 67560 -----BEGIN CERTIFICATE-----
 67561 MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE
 67562 BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD
 67563 EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG
 67564 EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT
 67565 DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r
 67566 Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1
 67567 3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K
 67568 b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN
 67569 Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ
 67570 4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf
 67571 1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu
 67572 hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH
 67573 usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r
 67574 OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G
 67575 A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY
 67576 9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
 67577 ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV
 67578 0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt
 67579 hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw
 67580 TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx
 67581 e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA
 67582 JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD
 67583 YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n
 67584 JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ
 67585 m+kXQ99b21/+jh5Xos1AnX5iItreGCc=
 67586 -----END CERTIFICATE-----
 67587 
 67588 AC RAIZ FNMT-RCM
 67589 ================
 67590 -----BEGIN CERTIFICATE-----
 67591 MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT
 67592 AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw
 67593 MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD
 67594 TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
 67595 ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf
 67596 qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr
 67597 btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL
 67598 j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou
 67599 08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw
 67600 WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT
 67601 tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ
 67602 47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC
 67603 ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa
 67604 i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
 67605 FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o
 67606 dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
 67607 nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s
 67608 D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ
 67609 j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT
 67610 Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW
 67611 +YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7
 67612 Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d
 67613 8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm
 67614 5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG
 67615 rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
 67616 -----END CERTIFICATE-----
 67617 
 67618 Amazon Root CA 1
 67619 ================
 67620 -----BEGIN CERTIFICATE-----
 67621 MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD
 67622 VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1
 67623 MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
 67624 bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
 67625 ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH
 67626 FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ
 67627 gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t
 67628 dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce
 67629 VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
 67630 /zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3
 67631 DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM
 67632 CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy
 67633 8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa
 67634 2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2
 67635 xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5
 67636 -----END CERTIFICATE-----
 67637 
 67638 Amazon Root CA 2
 67639 ================
 67640 -----BEGIN CERTIFICATE-----
 67641 MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD
 67642 VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1
 67643 MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
 67644 bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
 67645 ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4
 67646 kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp
 67647 N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9
 67648 AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd
 67649 fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx
 67650 kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS
 67651 btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0
 67652 Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN
 67653 c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+
 67654 3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw
 67655 DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA
 67656 A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
 67657 +gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE
 67658 YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW
 67659 xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ
 67660 gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW
 67661 aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV
 67662 Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3
 67663 KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi
 67664 JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=
 67665 -----END CERTIFICATE-----
 67666 
 67667 Amazon Root CA 3
 67668 ================
 67669 -----BEGIN CERTIFICATE-----
 67670 MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG
 67671 EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy
 67672 NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
 67673 MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB
 67674 f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr
 67675 Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43
 67676 rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc
 67677 eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==
 67678 -----END CERTIFICATE-----
 67679 
 67680 Amazon Root CA 4
 67681 ================
 67682 -----BEGIN CERTIFICATE-----
 67683 MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG
 67684 EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy
 67685 NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
 67686 MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN
 67687 /sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri
 67688 83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
 67689 HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA
 67690 MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1
 67691 AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==
 67692 -----END CERTIFICATE-----
 67693 
 67694 TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
 67695 =============================================
 67696 -----BEGIN CERTIFICATE-----
 67697 MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT
 67698 D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr
 67699 IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g
 67700 TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp
 67701 ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD
 67702 VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt
 67703 c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth
 67704 bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11
 67705 IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
 67706 MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8
 67707 6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc
 67708 wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0
 67709 3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9
 67710 WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU
 67711 ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
 67712 KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
 67713 AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc
 67714 lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R
 67715 e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j
 67716 q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
 67717 -----END CERTIFICATE-----
 67718 
 67719 GDCA TrustAUTH R5 ROOT
 67720 ======================
 67721 -----BEGIN CERTIFICATE-----
 67722 MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw
 67723 BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD
 67724 DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow
 67725 YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ
 67726 IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B
 67727 AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs
 67728 AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p
 67729 OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr
 67730 pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ
 67731 9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ
 67732 xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM
 67733 R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ
 67734 D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4
 67735 oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx
 67736 9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR
 67737 MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg
 67738 p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9
 67739 H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35
 67740 6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd
 67741 +PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ
 67742 HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD
 67743 F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ
 67744 8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv
 67745 /EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT
 67746 aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
 67747 -----END CERTIFICATE-----
 67748 
 67749 TrustCor RootCert CA-1
 67750 ======================
 67751 -----BEGIN CERTIFICATE-----
 67752 MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP
 67753 MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig
 67754 U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp
 67755 dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx
 67756 MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu
 67757 YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe
 67758 VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy
 67759 dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq
 67760 jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4
 67761 pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0
 67762 JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h
 67763 gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw
 67764 /Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j
 67765 BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
 67766 AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5
 67767 mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf
 67768 ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C
 67769 qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P
 67770 3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk=
 67771 -----END CERTIFICATE-----
 67772 
 67773 TrustCor RootCert CA-2
 67774 ======================
 67775 -----BEGIN CERTIFICATE-----
 67776 MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w
 67777 DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT
 67778 eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0
 67779 eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy
 67780 MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h
 67781 bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
 67782 cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0
 67783 IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb
 67784 ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk
 67785 RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1
 67786 oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb
 67787 XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1
 67788 /p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q
 67789 jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP
 67790 eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg
 67791 rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh
 67792 8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU
 67793 2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD
 67794 VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h
 67795 Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp
 67796 kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv
 67797 2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3
 67798 S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw
 67799 PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv
 67800 DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU
 67801 RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE
 67802 xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX
 67803 RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ
 67804 -----END CERTIFICATE-----
 67805 
 67806 TrustCor ECA-1
 67807 ==============
 67808 -----BEGIN CERTIFICATE-----
 67809 MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP
 67810 MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig
 67811 U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp
 67812 dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw
 67813 N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5
 67814 MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y
 67815 IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG
 67816 SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR
 67817 MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23
 67818 xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc
 67819 p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+
 67820 fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj
 67821 YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL
 67822 f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
 67823 AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u
 67824 /ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F
 67825 hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs
 67826 J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC
 67827 jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g==
 67828 -----END CERTIFICATE-----
 67829 
 67830 SSL.com Root Certification Authority RSA
 67831 ========================================
 67832 -----BEGIN CERTIFICATE-----
 67833 MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM
 67834 BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x
 67835 MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw
 67836 MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx
 67837 EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM
 67838 LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD
 67839 ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C
 67840 Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8
 67841 P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge
 67842 oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp
 67843 k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z
 67844 fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ
 67845 gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2
 67846 UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8
 67847 1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s
 67848 bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
 67849 HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE
 67850 AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr
 67851 dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf
 67852 ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl
 67853 u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq
 67854 erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj
 67855 MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ
 67856 vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI
 67857 Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y
 67858 wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI
 67859 WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k=
 67860 -----END CERTIFICATE-----
 67861 
 67862 SSL.com Root Certification Authority ECC
 67863 ========================================
 67864 -----BEGIN CERTIFICATE-----
 67865 MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV
 67866 BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv
 67867 BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy
 67868 MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO
 67869 BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
 67870 bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA
 67871 BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+
 67872 8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR
 67873 hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT
 67874 jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW
 67875 e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z
 67876 5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
 67877 -----END CERTIFICATE-----
 67878 
 67879 SSL.com EV Root Certification Authority RSA R2
 67880 ==============================================
 67881 -----BEGIN CERTIFICATE-----
 67882 MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w
 67883 DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u
 67884 MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
 67885 MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI
 67886 DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD
 67887 VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN
 67888 BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh
 67889 hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w
 67890 cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO
 67891 Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+
 67892 B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh
 67893 CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim
 67894 9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto
 67895 RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm
 67896 JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48
 67897 +qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
 67898 HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp
 67899 qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1
 67900 ++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx
 67901 Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G
 67902 guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz
 67903 OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7
 67904 CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq
 67905 lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR
 67906 rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1
 67907 hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX
 67908 9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
 67909 -----END CERTIFICATE-----
 67910 
 67911 SSL.com EV Root Certification Authority ECC
 67912 ===========================================
 67913 -----BEGIN CERTIFICATE-----
 67914 MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV
 67915 BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy
 67916 BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw
 67917 MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx
 67918 EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM
 67919 LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
 67920 BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy
 67921 3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O
 67922 BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe
 67923 5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ
 67924 N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm
 67925 m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
 67926 -----END CERTIFICATE-----
 67927 
 67928 GlobalSign Root CA - R6
 67929 =======================
 67930 -----BEGIN CERTIFICATE-----
 67931 MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX
 67932 R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds
 67933 b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i
 67934 YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs
 67935 U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss
 67936 grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE
 67937 3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF
 67938 vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM
 67939 PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+
 67940 azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O
 67941 WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy
 67942 CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP
 67943 0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN
 67944 b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE
 67945 AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV
 67946 HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
 67947 nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0
 67948 lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY
 67949 BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym
 67950 Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr
 67951 3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1
 67952 0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T
 67953 uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK
 67954 oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t
 67955 JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
 67956 -----END CERTIFICATE-----
 67957 
 67958 OISTE WISeKey Global Root GC CA
 67959 ===============================
 67960 -----BEGIN CERTIFICATE-----
 67961 MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD
 67962 SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo
 67963 MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa
 67964 Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL
 67965 ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
 67966 bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr
 67967 VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab
 67968 NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
 67969 BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E
 67970 AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk
 67971 AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
 67972 -----END CERTIFICATE-----
 67973 
 67974 GTS Root R1
 67975 ===========
 67976 -----BEGIN CERTIFICATE-----
 67977 MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG
 67978 EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv
 67979 b3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG
 67980 A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIi
 67981 MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx
 67982 9vaMf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7r
 67983 aKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnW
 67984 r4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqM
 67985 LnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly
 67986 4cpk9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr
 67987 06zqkUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
 67988 wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om
 67989 3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNu
 67990 JLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
 67991 VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEM
 67992 BQADggIBADiWCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1
 67993 d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6ZXPYfcX3v73sv
 67994 fuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZRgyFmxhE+885H7pwoHyXa/6xm
 67995 ld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9b
 67996 gsiG1eGZbYwE8na6SfZu6W0eX6DvJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq
 67997 4BjFbkerQUIpm/ZgDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWEr
 67998 tXvM+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyyF62ARPBo
 67999 pY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9SQ98POyDGCBDTtWTurQ0
 68000 sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdwsE3PYJ/HQcu51OyLemGhmW/HGY0dVHLql
 68001 CFF1pkgl
 68002 -----END CERTIFICATE-----
 68003 
 68004 GTS Root R2
 68005 ===========
 68006 -----BEGIN CERTIFICATE-----
 68007 MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG
 68008 EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv
 68009 b3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG
 68010 A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIi
 68011 MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTuk
 68012 k3LvCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo
 68013 7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWI
 68014 m8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5Gm
 68015 dFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbu
 68016 ak7MkogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscsz
 68017 cTJGr61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW
 68018 Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73Vululycsl
 68019 aVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy
 68020 5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
 68021 VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEM
 68022 BQADggIBALZp8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT
 68023 vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiTz9D2PGcDFWEJ
 68024 +YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiApJiS4wGWAqoC7o87xdFtCjMw
 68025 c3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvbpxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3Da
 68026 WsYDQvTtN6LwG1BUSw7YhN4ZKJmBR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5r
 68027 n/WkhLx3+WuXrD5RRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56Gtmwfu
 68028 Nmsk0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC5AwiWVIQ
 68029 7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiFizoHCBy69Y9Vmhh1fuXs
 68030 gWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLnyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ld
 68031 o/DUhgkC
 68032 -----END CERTIFICATE-----
 68033 
 68034 GTS Root R3
 68035 ===========
 68036 -----BEGIN CERTIFICATE-----
 68037 MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV
 68038 UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg
 68039 UjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE
 68040 ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcq
 68041 hkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUU
 68042 Rout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24Cej
 68043 QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP
 68044 0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFukfCPAlaUs3L6JbyO5o91lAFJekazInXJ0
 68045 glMLfalAvWhgxeG4VDvBNhcl2MG9AjEAnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOa
 68046 KaqW04MjyaR7YbPMAuhd
 68047 -----END CERTIFICATE-----
 68048 
 68049 GTS Root R4
 68050 ===========
 68051 -----BEGIN CERTIFICATE-----
 68052 MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV
 68053 UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg
 68054 UjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE
 68055 ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcq
 68056 hkjOPQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa
 68057 6zzuhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqj
 68058 QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV
 68059 2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0CMRw3J5QdCHojXohw0+WbhXRIjVhLfoI
 68060 N+4Zba3bssx9BzT1YBkstTTZbyACMANxsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11x
 68061 zPKwTdb+mciUqXWi4w==
 68062 -----END CERTIFICATE-----
 68063 
 68064 UCA Global G2 Root
 68065 ==================
 68066 -----BEGIN CERTIFICATE-----
 68067 MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG
 68068 EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x
 68069 NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU
 68070 cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
 68071 MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT
 68072 oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV
 68073 8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS
 68074 h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o
 68075 LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/
 68076 R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe
 68077 KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa
 68078 4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc
 68079 OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97
 68080 8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
 68081 BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo
 68082 5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5
 68083 1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A
 68084 Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9
 68085 yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX
 68086 c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo
 68087 jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk
 68088 bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x
 68089 ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn
 68090 RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A==
 68091 -----END CERTIFICATE-----
 68092 
 68093 UCA Extended Validation Root
 68094 ============================
 68095 -----BEGIN CERTIFICATE-----
 68096 MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG
 68097 EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u
 68098 IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G
 68099 A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi
 68100 MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs
 68101 iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF
 68102 Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu
 68103 eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR
 68104 59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH
 68105 0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR
 68106 el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv
 68107 B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth
 68108 WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS
 68109 NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS
 68110 3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL
 68111 BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
 68112 ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM
 68113 aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4
 68114 dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb
 68115 +7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW
 68116 F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi
 68117 GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc
 68118 GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi
 68119 djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr
 68120 dhh2n1ax
 68121 -----END CERTIFICATE-----
 68122 
 68123 Certigna Root CA
 68124 ================
 68125 -----BEGIN CERTIFICATE-----
 68126 MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE
 68127 BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ
 68128 MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda
 68129 MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz
 68130 MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC
 68131 DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX
 68132 stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz
 68133 KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8
 68134 JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16
 68135 XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq
 68136 4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej
 68137 wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ
 68138 lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI
 68139 jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/
 68140 /TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
 68141 HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
 68142 1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy
 68143 dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h
 68144 LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl
 68145 cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt
 68146 OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP
 68147 TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq
 68148 7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3
 68149 4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd
 68150 8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS
 68151 6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY
 68152 tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS
 68153 aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde
 68154 E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
 68155 -----END CERTIFICATE-----
 68156 
 68157 emSign Root CA - G1
 68158 ===================
 68159 -----BEGIN CERTIFICATE-----
 68160 MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET
 68161 MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl
 68162 ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx
 68163 ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk
 68164 aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB
 68165 IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN
 68166 LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1
 68167 cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW
 68168 DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ
 68169 6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH
 68170 hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG
 68171 MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2
 68172 vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q
 68173 NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q
 68174 +Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih
 68175 U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
 68176 iN66zB+Afko=
 68177 -----END CERTIFICATE-----
 68178 
 68179 emSign ECC Root CA - G3
 68180 =======================
 68181 -----BEGIN CERTIFICATE-----
 68182 MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG
 68183 A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg
 68184 MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4
 68185 MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11
 68186 ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
 68187 RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc
 68188 58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr
 68189 MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC
 68190 AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D
 68191 CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7
 68192 jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj
 68193 -----END CERTIFICATE-----
 68194 
 68195 emSign Root CA - C1
 68196 ===================
 68197 -----BEGIN CERTIFICATE-----
 68198 MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx
 68199 EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp
 68200 Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE
 68201 BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD
 68202 ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up
 68203 ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/
 68204 Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX
 68205 OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V
 68206 I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms
 68207 lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+
 68208 XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD
 68209 ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp
 68210 /6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1
 68211 NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9
 68212 wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ
 68213 BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI=
 68214 -----END CERTIFICATE-----
 68215 
 68216 emSign ECC Root CA - C3
 68217 =======================
 68218 -----BEGIN CERTIFICATE-----
 68219 MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG
 68220 A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF
 68221 Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE
 68222 BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD
 68223 ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd
 68224 6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9
 68225 SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA
 68226 B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA
 68227 MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU
 68228 ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==
 68229 -----END CERTIFICATE-----
 68230 
 68231 Hongkong Post Root CA 3
 68232 =======================
 68233 -----BEGIN CERTIFICATE-----
 68234 MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG
 68235 A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK
 68236 Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2
 68237 MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv
 68238 bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX
 68239 SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz
 68240 iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf
 68241 jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim
 68242 5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe
 68243 sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj
 68244 0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/
 68245 JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u
 68246 y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h
 68247 +bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG
 68248 xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID
 68249 AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e
 68250 i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN
 68251 AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw
 68252 W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld
 68253 y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov
 68254 +BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc
 68255 eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw
 68256 9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7
 68257 nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY
 68258 hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB
 68259 60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq
 68260 dBb9HxEGmpv0
 68261 -----END CERTIFICATE-----
 68262 
 68263 Entrust Root Certification Authority - G4
 68264 =========================================
 68265 -----BEGIN CERTIFICATE-----
 68266 MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV
 68267 BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu
 68268 bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1
 68269 dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1
 68270 dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT
 68271 AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
 68272 L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv
 68273 cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv
 68274 cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D
 68275 umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV
 68276 3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds
 68277 8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ
 68278 e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7
 68279 ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X
 68280 xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV
 68281 7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8
 68282 dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW
 68283 Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T
 68284 AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n
 68285 MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q
 68286 jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht
 68287 7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK
 68288 YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt
 68289 jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+
 68290 m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW
 68291 RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA
 68292 JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G
 68293 +TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT
 68294 kcpG2om3PVODLAgfi49T3f+sHw==
 68295 -----END CERTIFICATE-----
 68296 
 68297 Microsoft ECC Root Certificate Authority 2017
 68298 =============================================
 68299 -----BEGIN CERTIFICATE-----
 68300 MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
 68301 UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND
 68302 IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4
 68303 MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
 68304 NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ
 68305 BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6
 68306 thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB
 68307 eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM
 68308 +Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf
 68309 Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR
 68310 eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
 68311 -----END CERTIFICATE-----
 68312 
 68313 Microsoft RSA Root Certificate Authority 2017
 68314 =============================================
 68315 -----BEGIN CERTIFICATE-----
 68316 MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG
 68317 EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg
 68318 UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw
 68319 NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
 68320 MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw
 68321 ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml
 68322 7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e
 68323 S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7
 68324 1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+
 68325 dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F
 68326 yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS
 68327 MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr
 68328 lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ
 68329 0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ
 68330 ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw
 68331 DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
 68332 NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og
 68333 6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80
 68334 dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk
 68335 +ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex
 68336 /2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy
 68337 AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW
 68338 ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE
 68339 7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT
 68340 c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D
 68341 5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E
 68342 -----END CERTIFICATE-----
 68343 
 68344 e-Szigno Root CA 2017
 68345 =====================
 68346 -----BEGIN CERTIFICATE-----
 68347 MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw
 68348 DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt
 68349 MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa
 68350 Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE
 68351 CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp
 68352 Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx
 68353 s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G
 68354 A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv
 68355 vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA
 68356 tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO
 68357 svxyqltZ+efcMQ==
 68358 -----END CERTIFICATE-----
 68359 
 68360 certSIGN Root CA G2
 68361 ===================
 68362 -----BEGIN CERTIFICATE-----
 68363 MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw
 68364 EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy
 68365 MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH
 68366 TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
 68367 ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05
 68368 N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk
 68369 abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg
 68370 wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp
 68371 dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh
 68372 ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732
 68373 jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf
 68374 95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc
 68375 z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL
 68376 iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
 68377 DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB
 68378 ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
 68379 b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB
 68380 /AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5
 68381 8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5
 68382 BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW
 68383 atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU
 68384 Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M
 68385 NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N
 68386 0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc=
 68387 -----END CERTIFICATE-----
 68388 
 68389 Trustwave Global Certification Authority
 68390 ========================================
 68391 -----BEGIN CERTIFICATE-----
 68392 MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV
 68393 UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2
 68394 ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u
 68395 IEF1dGhvcml0eTAeFw0xNzA4MjMxOTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJV
 68396 UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2
 68397 ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u
 68398 IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALldUShLPDeS0YLOvR29
 68399 zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0XznswuvCAAJWX/NKSqIk4cXGIDtiLK0thAf
 68400 LdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4Bq
 68401 stTnoApTAbqOl5F2brz81Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9o
 68402 WN0EACyW80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotPJqX+
 68403 OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1lRtzuzWniTY+HKE40
 68404 Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfwhI0Vcnyh78zyiGG69Gm7DIwLdVcE
 68405 uE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm
 68406 +9jaJXLE9gCxInm943xZYkqcBW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqj
 68407 ifLJS3tBEW1ntwiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
 68408 EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1UdDwEB/wQEAwIB
 68409 BjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W0OhUKDtkLSGm+J1WE2pIPU/H
 68410 PinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfeuyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0H
 68411 ZJDmHvUqoai7PF35owgLEQzxPy0QlG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla
 68412 4gt5kNdXElE1GYhBaCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5R
 68413 vbbEsLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPTMaCm/zjd
 68414 zyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qequ5AvzSxnI9O4fKSTx+O
 68415 856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxhVicGaeVyQYHTtgGJoC86cnn+OjC/QezH
 68416 Yj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu
 68417 3R3y4G5OBVixwJAWKqQ9EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP
 68418 29FpHOTKyeC2nOnOcXHebD8WpHk=
 68419 -----END CERTIFICATE-----
 68420 
 68421 Trustwave Global ECC P256 Certification Authority
 68422 =================================================
 68423 -----BEGIN CERTIFICATE-----
 68424 MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYDVQQGEwJVUzER
 68425 MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI
 68426 b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZp
 68427 Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYD
 68428 VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy
 68429 dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1
 68430 NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH77bOYj
 68431 43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoNFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqm
 68432 P62jQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt
 68433 0UrrdaVKEJmzsaGLSvcwCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjz
 68434 RM4q3wghDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
 68435 -----END CERTIFICATE-----
 68436 
 68437 Trustwave Global ECC P384 Certification Authority
 68438 =================================================
 68439 -----BEGIN CERTIFICATE-----
 68440 MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYDVQQGEwJVUzER
 68441 MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI
 68442 b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZp
 68443 Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYD
 68444 VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy
 68445 dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4
 68446 NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGvaDXU1CDFH
 68447 Ba5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr
 68448 /TklZvFe/oyujUF5nQlgziip04pt89ZF1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV
 68449 HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn
 68450 ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl
 68451 CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw==
 68452 -----END CERTIFICATE-----
 68453 
 68454 NAVER Global Root Certification Authority
 68455 =========================================
 68456 -----BEGIN CERTIFICATE-----
 68457 MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG
 68458 A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD
 68459 DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4
 68460 NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT
 68461 UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv
 68462 biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb
 68463 UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW
 68464 +j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7
 68465 XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2
 68466 aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4
 68467 Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z
 68468 VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B
 68469 A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai
 68470 cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy
 68471 YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV
 68472 HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
 68473 Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK
 68474 21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB
 68475 jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx
 68476 hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg
 68477 E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH
 68478 D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ
 68479 A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY
 68480 qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG
 68481 I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg
 68482 kpzNNIaRkPpkUZ3+/uul9XXeifdy
 68483 -----END CERTIFICATE-----
 68484 
 68485 AC RAIZ FNMT-RCM SERVIDORES SEGUROS
 68486 ===================================
 68487 -----BEGIN CERTIFICATE-----
 68488 MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF
 68489 UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy
 68490 NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4
 68491 MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt
 68492 UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB
 68493 QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA
 68494 BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2
 68495 LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw
 68496 AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG
 68497 SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD
 68498 zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c=
 68499 -----END CERTIFICATE-----
 68500 
 68501 GlobalSign Root R46
 68502 ===================
 68503 -----BEGIN CERTIFICATE-----
 68504 MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV
 68505 BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv
 68506 b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX
 68507 BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi
 68508 MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es
 68509 CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/
 68510 r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje
 68511 2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt
 68512 bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj
 68513 K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4
 68514 12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on
 68515 ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls
 68516 eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9
 68517 vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD
 68518 VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM
 68519 BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg
 68520 JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy
 68521 gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92
 68522 CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm
 68523 OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq
 68524 JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye
 68525 qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz
 68526 nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7
 68527 DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3
 68528 QEUxeCp6
 68529 -----END CERTIFICATE-----
 68530 
 68531 GlobalSign Root E46
 68532 ===================
 68533 -----BEGIN CERTIFICATE-----
 68534 MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT
 68535 AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg
 68536 RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV
 68537 BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq
 68538 hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB
 68539 jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj
 68540 QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL
 68541 gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk
 68542 vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+
 68543 CAezNIm8BZ/3Hobui3A=
 68544 -----END CERTIFICATE-----
 68545 
 68546 GLOBALTRUST 2020
 68547 ================
 68548 -----BEGIN CERTIFICATE-----
 68549 MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx
 68550 IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT
 68551 VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh
 68552 BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy
 68553 MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi
 68554 D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO
 68555 VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM
 68556 CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm
 68557 fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA
 68558 A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR
 68559 JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG
 68560 DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU
 68561 clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ
 68562 mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
 68563 AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud
 68564 IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
 68565 VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw
 68566 4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9
 68567 iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS
 68568 8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2
 68569 HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS
 68570 vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918
 68571 oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF
 68572 YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl
 68573 gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
 68574 -----END CERTIFICATE-----
 68575 
 68576 ANF Secure Server Root CA
 68577 =========================
 68578 -----BEGIN CERTIFICATE-----
 68579 MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNVBAUTCUc2MzI4
 68580 NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lv
 68581 bjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNVBAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3Qg
 68582 Q0EwHhcNMTkwOTA0MTAwMDM4WhcNMzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEw
 68583 MQswCQYDVQQGEwJFUzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQw
 68584 EgYDVQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9vdCBDQTCC
 68585 AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCjcqQZAZ2cC4Ffc0m6p6zz
 68586 BE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9qyGFOtibBTI3/TO80sh9l2Ll49a2pcbnv
 68587 T1gdpd50IJeh7WhM3pIXS7yr/2WanvtH2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcv
 68588 B2VSAKduyK9o7PQUlrZXH1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXse
 68589 zx76W0OLzc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyRp1RM
 68590 VwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQzW7i1o0TJrH93PB0j
 68591 7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/SiOL9V8BY9KHcyi1Swr1+KuCLH5z
 68592 JTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJnLNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe
 68593 8TZBAQIvfXOn3kLMTOmJDVb3n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVO
 68594 Hj1tyRRM4y5Bu8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj
 68595 o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAOBgNVHQ8BAf8E
 68596 BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEATh65isagmD9uw2nAalxJ
 68597 UqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzx
 68598 j6ptBZNscsdW699QIyjlRRA96Gejrw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDt
 68599 dD+4E5UGUcjohybKpFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM
 68600 5gf0vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjqOknkJjCb
 68601 5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ/zo1PqVUSlJZS2Db7v54
 68602 EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ92zg/LFis6ELhDtjTO0wugumDLmsx2d1H
 68603 hk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGy
 68604 g77FGr8H6lnco4g175x2MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3
 68605 r5+qPeoott7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
 68606 -----END CERTIFICATE-----
 68607 
 68608 Certum EC-384 CA
 68609 ================
 68610 -----BEGIN CERTIFICATE-----
 68611 MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ
 68612 TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy
 68613 dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2
 68614 MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh
 68615 dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx
 68616 GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq
 68617 vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn
 68618 iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
 68619 VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo
 68620 ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0
 68621 QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
 68622 -----END CERTIFICATE-----
 68623 
 68624 Certum Trusted Root CA
 68625 ======================
 68626 -----BEGIN CERTIFICATE-----
 68627 MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6MQswCQYDVQQG
 68628 EwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0g
 68629 Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0Ew
 68630 HhcNMTgwMzE2MTIxMDEzWhcNNDMwMzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMY
 68631 QXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBB
 68632 dXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB
 68633 AQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZn0EGze2jusDbCSzBfN8p
 68634 fktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/qp1x4EaTByIVcJdPTsuclzxFUl6s1wB52
 68635 HO8AU5853BSlLCIls3Jy/I2z5T4IHhQqNwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2
 68636 fJmItdUDmj0VDT06qKhF8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGt
 68637 g/BKEiJ3HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGamqi4
 68638 NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi7VdNIuJGmj8PkTQk
 68639 fVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSFytKAQd8FqKPVhJBPC/PgP5sZ0jeJ
 68640 P/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0PqafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSY
 68641 njYJdmZm/Bo/6khUHL4wvYBQv3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHK
 68642 HRzQ+8S1h9E6Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1
 68643 vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQADggIBAEii1QAL
 68644 LtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4WxmB82M+w85bj/UvXgF2Ez8s
 68645 ALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvozMrnadyHncI013nR03e4qllY/p0m+jiGPp2K
 68646 h2RX5Rc64vmNueMzeMGQ2Ljdt4NR5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8
 68647 CYyqOhNf6DR5UMEQGfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA
 68648 4kZf5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq0Uc9Nneo
 68649 WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj
 68650 6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTMqJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmT
 68651 OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck
 68652 bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
 68653 -----END CERTIFICATE-----
 68654 
 68655 TunTrust Root CA
 68656 ================
 68657 -----BEGIN CERTIFICATE-----
 68658 MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG
 68659 A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj
 68660 dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw
 68661 NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD
 68662 ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw
 68663 DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz
 68664 2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b
 68665 bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7
 68666 NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd
 68667 gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW
 68668 VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f
 68669 Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ
 68670 juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas
 68671 DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS
 68672 VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI
 68673 04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0
 68674 90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl
 68675 0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd
 68676 Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY
 68677 YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp
 68678 adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x
 68679 xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP
 68680 jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM
 68681 MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z
 68682 ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r
 68683 AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
 68684 -----END CERTIFICATE-----
 68685 
 68686 HARICA TLS RSA Root CA 2021
 68687 ===========================
 68688 -----BEGIN CERTIFICATE-----
 68689 MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG
 68690 EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
 68691 cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz
 68692 OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl
 68693 bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB
 68694 IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN
 68695 JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu
 68696 a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y
 68697 Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K
 68698 5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv
 68699 dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR
 68700 0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH
 68701 GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm
 68702 haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ
 68703 CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G
 68704 A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE
 68705 AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU
 68706 EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq
 68707 QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD
 68708 QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR
 68709 j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5
 68710 vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0
 68711 qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6
 68712 Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/
 68713 PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn
 68714 kf3/W9b3raYvAwtt41dU63ZTGI0RmLo=
 68715 -----END CERTIFICATE-----
 68716 
 68717 HARICA TLS ECC Root CA 2021
 68718 ===========================
 68719 -----BEGIN CERTIFICATE-----
 68720 MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH
 68721 UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD
 68722 QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX
 68723 DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj
 68724 IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv
 68725 b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l
 68726 AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b
 68727 ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW
 68728 0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi
 68729 rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw
 68730 CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
 68731 -----END CERTIFICATE-----
 68732 <?php
 68733 
 68734 
 68735 
 68736 
 68737 
 68738 
 68739 
 68740 
 68741 
 68742 
 68743 namespace Composer\CaBundle;
 68744 
 68745 use Psr\Log\LoggerInterface;
 68746 use Symfony\Component\Process\PhpProcess;
 68747 
 68748 
 68749 
 68750 
 68751 
 68752 class CaBundle
 68753 {
 68754 
 68755 private static $caPath;
 68756 
 68757 private static $caFileValidity = array();
 68758 
 68759 private static $useOpensslParse;
 68760 
 68761 
 68762 
 68763 
 68764 
 68765 
 68766 
 68767 
 68768 
 68769 
 68770 
 68771 
 68772 
 68773 
 68774 
 68775 
 68776 
 68777 
 68778 
 68779 
 68780 
 68781 
 68782 
 68783 
 68784 
 68785 
 68786 
 68787 
 68788 
 68789 
 68790 
 68791 
 68792 
 68793 
 68794 
 68795 
 68796 
 68797 
 68798 public static function getSystemCaRootBundlePath(LoggerInterface $logger = null)
 68799 {
 68800 if (self::$caPath !== null) {
 68801 return self::$caPath;
 68802 }
 68803 $caBundlePaths = array();
 68804 
 68805 
 68806 
 68807 $caBundlePaths[] = self::getEnvVariable('SSL_CERT_FILE');
 68808 
 68809 
 68810 
 68811 $caBundlePaths[] = self::getEnvVariable('SSL_CERT_DIR');
 68812 
 68813 $caBundlePaths[] = ini_get('openssl.cafile');
 68814 $caBundlePaths[] = ini_get('openssl.capath');
 68815 
 68816 $otherLocations = array(
 68817 '/etc/pki/tls/certs/ca-bundle.crt', 
 68818 '/etc/ssl/certs/ca-certificates.crt', 
 68819 '/etc/ssl/ca-bundle.pem', 
 68820 '/usr/local/share/certs/ca-root-nss.crt', 
 68821 '/usr/ssl/certs/ca-bundle.crt', 
 68822 '/opt/local/share/curl/curl-ca-bundle.crt', 
 68823 '/usr/local/share/curl/curl-ca-bundle.crt', 
 68824 '/usr/share/ssl/certs/ca-bundle.crt', 
 68825 '/etc/ssl/cert.pem', 
 68826 '/usr/local/etc/ssl/cert.pem', 
 68827 '/usr/local/etc/openssl/cert.pem', 
 68828 '/usr/local/etc/openssl@1.1/cert.pem', 
 68829 );
 68830 
 68831 foreach($otherLocations as $location) {
 68832 $otherLocations[] = dirname($location);
 68833 }
 68834 
 68835 $caBundlePaths = array_merge($caBundlePaths, $otherLocations);
 68836 
 68837 foreach ($caBundlePaths as $caBundle) {
 68838 if ($caBundle && self::caFileUsable($caBundle, $logger)) {
 68839 return self::$caPath = $caBundle;
 68840 }
 68841 
 68842 if ($caBundle && self::caDirUsable($caBundle, $logger)) {
 68843 return self::$caPath = $caBundle;
 68844 }
 68845 }
 68846 
 68847 return self::$caPath = static::getBundledCaBundlePath(); 
 68848 }
 68849 
 68850 
 68851 
 68852 
 68853 
 68854 
 68855 
 68856 
 68857 public static function getBundledCaBundlePath()
 68858 {
 68859 $caBundleFile = __DIR__.'/../res/cacert.pem';
 68860 
 68861 
 68862 
 68863 if (0 === strpos($caBundleFile, 'phar://')) {
 68864 $tempCaBundleFile = tempnam(sys_get_temp_dir(), 'openssl-ca-bundle-');
 68865 if (false === $tempCaBundleFile) {
 68866 throw new \RuntimeException('Could not create a temporary file to store the bundled CA file');
 68867 }
 68868 
 68869 file_put_contents(
 68870 $tempCaBundleFile,
 68871 file_get_contents($caBundleFile)
 68872 );
 68873 
 68874 register_shutdown_function(function() use ($tempCaBundleFile) {
 68875 @unlink($tempCaBundleFile);
 68876 });
 68877 
 68878 $caBundleFile = $tempCaBundleFile;
 68879 }
 68880 
 68881 return $caBundleFile;
 68882 }
 68883 
 68884 
 68885 
 68886 
 68887 
 68888 
 68889 
 68890 
 68891 
 68892 public static function validateCaFile($filename, LoggerInterface $logger = null)
 68893 {
 68894 static $warned = false;
 68895 
 68896 if (isset(self::$caFileValidity[$filename])) {
 68897 return self::$caFileValidity[$filename];
 68898 }
 68899 
 68900 $contents = file_get_contents($filename);
 68901 
 68902 
 68903 
 68904 if (!static::isOpensslParseSafe()) {
 68905 if (!$warned && $logger) {
 68906 $logger->warning(sprintf(
 68907 'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.',
 68908 PHP_VERSION
 68909 ));
 68910 $warned = true;
 68911 }
 68912 
 68913 $isValid = !empty($contents);
 68914 } elseif (is_string($contents) && strlen($contents) > 0) {
 68915 $contents = preg_replace("/^(\\-+(?:BEGIN|END))\\s+TRUSTED\\s+(CERTIFICATE\\-+)\$/m", '$1 $2', $contents);
 68916 if (null === $contents) {
 68917 
 68918 $isValid = false;
 68919 } else {
 68920 $isValid = (bool) openssl_x509_parse($contents);
 68921 }
 68922 } else {
 68923 $isValid = false;
 68924 }
 68925 
 68926 if ($logger) {
 68927 $logger->debug('Checked CA file '.realpath($filename).': '.($isValid ? 'valid' : 'invalid'));
 68928 }
 68929 
 68930 return self::$caFileValidity[$filename] = $isValid;
 68931 }
 68932 
 68933 
 68934 
 68935 
 68936 
 68937 
 68938 
 68939 
 68940 
 68941 public static function isOpensslParseSafe()
 68942 {
 68943 if (null !== self::$useOpensslParse) {
 68944 return self::$useOpensslParse;
 68945 }
 68946 
 68947 if (PHP_VERSION_ID >= 50600) {
 68948 return self::$useOpensslParse = true;
 68949 }
 68950 
 68951 
 68952 
 68953 
 68954 
 68955 if (
 68956 (PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328)
 68957 || (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423)
 68958 || PHP_VERSION_ID >= 50507
 68959 ) {
 68960 
 68961 return self::$useOpensslParse = true;
 68962 }
 68963 
 68964 if (defined('PHP_WINDOWS_VERSION_BUILD')) {
 68965 
 68966 return self::$useOpensslParse = false;
 68967 }
 68968 
 68969 $compareDistroVersionPrefix = function ($prefix, $fixedVersion) {
 68970 $regex = '{^'.preg_quote($prefix).'([0-9]+)$}';
 68971 
 68972 if (preg_match($regex, PHP_VERSION, $m)) {
 68973 return ((int) $m[1]) >= $fixedVersion;
 68974 }
 68975 
 68976 return false;
 68977 };
 68978 
 68979 
 68980 if (
 68981 $compareDistroVersionPrefix('5.3.3-7+squeeze', 18) 
 68982 || $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) 
 68983 || $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) 
 68984 ) {
 68985 return self::$useOpensslParse = true;
 68986 }
 68987 
 68988 
 68989 if (!class_exists('Symfony\Component\Process\PhpProcess')) {
 68990 return self::$useOpensslParse = false;
 68991 }
 68992 
 68993 
 68994 
 68995 
 68996 
 68997 
 68998 
 68999 
 69000 
 69001 
 69002 $cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K';
 69003 $script = <<<'EOT'
 69004 
 69005 error_reporting(-1);
 69006 $info = openssl_x509_parse(base64_decode('%s'));
 69007 var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']);
 69008 
 69009 EOT;
 69010 $script = '<'."?php\n".sprintf($script, $cert);
 69011 
 69012 try {
 69013 $process = new PhpProcess($script);
 69014 $process->mustRun();
 69015 } catch (\Exception $e) {
 69016 
 69017 
 69018 return self::$useOpensslParse = false;
 69019 }
 69020 
 69021 $output = preg_split('{\r?\n}', trim($process->getOutput()));
 69022 $errorOutput = trim($process->getErrorOutput());
 69023 
 69024 if (
 69025 is_array($output)
 69026 && count($output) === 3
 69027 && $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION)
 69028 && $output[1] === 'string(27) "stefan.esser@sektioneins.de"'
 69029 && $output[2] === 'int(-1)'
 69030 && preg_match('{openssl_x509_parse\(\): illegal (?:ASN1 data type for|length in) timestamp in - on line \d+}', $errorOutput)
 69031 ) {
 69032 
 69033 return self::$useOpensslParse = true;
 69034 }
 69035 
 69036 return self::$useOpensslParse = false;
 69037 }
 69038 
 69039 
 69040 
 69041 
 69042 
 69043 public static function reset()
 69044 {
 69045 self::$caFileValidity = array();
 69046 self::$caPath = null;
 69047 self::$useOpensslParse = null;
 69048 }
 69049 
 69050 
 69051 
 69052 
 69053 
 69054 private static function getEnvVariable($name)
 69055 {
 69056 if (isset($_SERVER[$name])) {
 69057 return (string) $_SERVER[$name];
 69058 }
 69059 
 69060 if (PHP_SAPI === 'cli' && ($value = getenv($name)) !== false && $value !== null) {
 69061 return (string) $value;
 69062 }
 69063 
 69064 return false;
 69065 }
 69066 
 69067 
 69068 
 69069 
 69070 
 69071 
 69072 private static function caFileUsable($certFile, LoggerInterface $logger = null)
 69073 {
 69074 return $certFile
 69075 && static::isFile($certFile, $logger)
 69076 && static::isReadable($certFile, $logger)
 69077 && static::validateCaFile($certFile, $logger);
 69078 }
 69079 
 69080 
 69081 
 69082 
 69083 
 69084 
 69085 private static function caDirUsable($certDir, LoggerInterface $logger = null)
 69086 {
 69087 return $certDir
 69088 && static::isDir($certDir, $logger)
 69089 && static::isReadable($certDir, $logger)
 69090 && static::glob($certDir . '/*', $logger);
 69091 }
 69092 
 69093 
 69094 
 69095 
 69096 
 69097 
 69098 private static function isFile($certFile, LoggerInterface $logger = null)
 69099 {
 69100 $isFile = @is_file($certFile);
 69101 if (!$isFile && $logger) {
 69102 $logger->debug(sprintf('Checked CA file %s does not exist or it is not a file.', $certFile));
 69103 }
 69104 
 69105 return $isFile;
 69106 }
 69107 
 69108 
 69109 
 69110 
 69111 
 69112 
 69113 private static function isDir($certDir, LoggerInterface $logger = null)
 69114 {
 69115 $isDir = @is_dir($certDir);
 69116 if (!$isDir && $logger) {
 69117 $logger->debug(sprintf('Checked directory %s does not exist or it is not a directory.', $certDir));
 69118 }
 69119 
 69120 return $isDir;
 69121 }
 69122 
 69123 
 69124 
 69125 
 69126 
 69127 
 69128 private static function isReadable($certFileOrDir, LoggerInterface $logger = null)
 69129 {
 69130 $isReadable = @is_readable($certFileOrDir);
 69131 if (!$isReadable && $logger) {
 69132 $logger->debug(sprintf('Checked file or directory %s is not readable.', $certFileOrDir));
 69133 }
 69134 
 69135 return $isReadable;
 69136 }
 69137 
 69138 
 69139 
 69140 
 69141 
 69142 
 69143 private static function glob($pattern, LoggerInterface $logger = null)
 69144 {
 69145 $certs = glob($pattern);
 69146 if ($certs === false) {
 69147 if ($logger) {
 69148 $logger->debug(sprintf("An error occurred while trying to find certificates for pattern: %s", $pattern));
 69149 }
 69150 return false;
 69151 }
 69152 
 69153 if (count($certs) === 0) {
 69154 if ($logger) {
 69155 $logger->debug(sprintf("No CA files found for pattern: %s", $pattern));
 69156 }
 69157 return false;
 69158 }
 69159 
 69160 return true;
 69161 }
 69162 }
 69163 <?php return array(
 69164 'root' => array(
 69165 'pretty_version' => '2.2.9',
 69166 'version' => '2.2.9.0',
 69167 'type' => 'library',
 69168 'install_path' => __DIR__ . '/../../',
 69169 'aliases' => array(),
 69170 'reference' => '07eccf080ad63d55d95a7c9133506db7d9029264',
 69171 'name' => 'composer/composer',
 69172 'dev' => false,
 69173 ),
 69174 'versions' => array(
 69175 'composer/ca-bundle' => array(
 69176 'pretty_version' => '1.3.1',
 69177 'version' => '1.3.1.0',
 69178 'type' => 'library',
 69179 'install_path' => __DIR__ . '/./ca-bundle',
 69180 'aliases' => array(),
 69181 'reference' => '4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b',
 69182 'dev_requirement' => false,
 69183 ),
 69184 'composer/composer' => array(
 69185 'pretty_version' => '2.2.9',
 69186 'version' => '2.2.9.0',
 69187 'type' => 'library',
 69188 'install_path' => __DIR__ . '/../../',
 69189 'aliases' => array(),
 69190 'reference' => '07eccf080ad63d55d95a7c9133506db7d9029264',
 69191 'dev_requirement' => false,
 69192 ),
 69193 'composer/metadata-minifier' => array(
 69194 'pretty_version' => '1.0.0',
 69195 'version' => '1.0.0.0',
 69196 'type' => 'library',
 69197 'install_path' => __DIR__ . '/./metadata-minifier',
 69198 'aliases' => array(),
 69199 'reference' => 'c549d23829536f0d0e984aaabbf02af91f443207',
 69200 'dev_requirement' => false,
 69201 ),
 69202 'composer/pcre' => array(
 69203 'pretty_version' => '1.0.1',
 69204 'version' => '1.0.1.0',
 69205 'type' => 'library',
 69206 'install_path' => __DIR__ . '/./pcre',
 69207 'aliases' => array(),
 69208 'reference' => '67a32d7d6f9f560b726ab25a061b38ff3a80c560',
 69209 'dev_requirement' => false,
 69210 ),
 69211 'composer/semver' => array(
 69212 'pretty_version' => '3.3.0',
 69213 'version' => '3.3.0.0',
 69214 'type' => 'library',
 69215 'install_path' => __DIR__ . '/./semver',
 69216 'aliases' => array(),
 69217 'reference' => 'f79c90ad4e9b41ac4dfc5d77bf398cf61fbd718b',
 69218 'dev_requirement' => false,
 69219 ),
 69220 'composer/spdx-licenses' => array(
 69221 'pretty_version' => '1.5.6',
 69222 'version' => '1.5.6.0',
 69223 'type' => 'library',
 69224 'install_path' => __DIR__ . '/./spdx-licenses',
 69225 'aliases' => array(),
 69226 'reference' => 'a30d487169d799745ca7280bc90fdfa693536901',
 69227 'dev_requirement' => false,
 69228 ),
 69229 'composer/xdebug-handler' => array(
 69230 'pretty_version' => '2.0.5',
 69231 'version' => '2.0.5.0',
 69232 'type' => 'library',
 69233 'install_path' => __DIR__ . '/./xdebug-handler',
 69234 'aliases' => array(),
 69235 'reference' => '9e36aeed4616366d2b690bdce11f71e9178c579a',
 69236 'dev_requirement' => false,
 69237 ),
 69238 'justinrainbow/json-schema' => array(
 69239 'pretty_version' => '5.2.11',
 69240 'version' => '5.2.11.0',
 69241 'type' => 'library',
 69242 'install_path' => __DIR__ . '/../justinrainbow/json-schema',
 69243 'aliases' => array(),
 69244 'reference' => '2ab6744b7296ded80f8cc4f9509abbff393399aa',
 69245 'dev_requirement' => false,
 69246 ),
 69247 'psr/log' => array(
 69248 'pretty_version' => '1.1.4',
 69249 'version' => '1.1.4.0',
 69250 'type' => 'library',
 69251 'install_path' => __DIR__ . '/../psr/log',
 69252 'aliases' => array(),
 69253 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
 69254 'dev_requirement' => false,
 69255 ),
 69256 'react/promise' => array(
 69257 'pretty_version' => 'v1.2.1',
 69258 'version' => '1.2.1.0',
 69259 'type' => 'library',
 69260 'install_path' => __DIR__ . '/../react/promise',
 69261 'aliases' => array(),
 69262 'reference' => 'eefff597e67ff66b719f8171480add3c91474a1e',
 69263 'dev_requirement' => false,
 69264 ),
 69265 'seld/jsonlint' => array(
 69266 'pretty_version' => '1.8.3',
 69267 'version' => '1.8.3.0',
 69268 'type' => 'library',
 69269 'install_path' => __DIR__ . '/../seld/jsonlint',
 69270 'aliases' => array(),
 69271 'reference' => '9ad6ce79c342fbd44df10ea95511a1b24dee5b57',
 69272 'dev_requirement' => false,
 69273 ),
 69274 'seld/phar-utils' => array(
 69275 'pretty_version' => '1.2.0',
 69276 'version' => '1.2.0.0',
 69277 'type' => 'library',
 69278 'install_path' => __DIR__ . '/../seld/phar-utils',
 69279 'aliases' => array(),
 69280 'reference' => '9f3452c93ff423469c0d56450431562ca423dcee',
 69281 'dev_requirement' => false,
 69282 ),
 69283 'symfony/console' => array(
 69284 'pretty_version' => 'v2.8.52',
 69285 'version' => '2.8.52.0',
 69286 'type' => 'library',
 69287 'install_path' => __DIR__ . '/../symfony/console',
 69288 'aliases' => array(),
 69289 'reference' => 'cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12',
 69290 'dev_requirement' => false,
 69291 ),
 69292 'symfony/debug' => array(
 69293 'pretty_version' => 'v2.8.52',
 69294 'version' => '2.8.52.0',
 69295 'type' => 'library',
 69296 'install_path' => __DIR__ . '/../symfony/debug',
 69297 'aliases' => array(),
 69298 'reference' => '74251c8d50dd3be7c4ce0c7b862497cdc641a5d0',
 69299 'dev_requirement' => false,
 69300 ),
 69301 'symfony/filesystem' => array(
 69302 'pretty_version' => 'v2.8.52',
 69303 'version' => '2.8.52.0',
 69304 'type' => 'library',
 69305 'install_path' => __DIR__ . '/../symfony/filesystem',
 69306 'aliases' => array(),
 69307 'reference' => '7ae46872dad09dffb7fe1e93a0937097339d0080',
 69308 'dev_requirement' => false,
 69309 ),
 69310 'symfony/finder' => array(
 69311 'pretty_version' => 'v2.8.52',
 69312 'version' => '2.8.52.0',
 69313 'type' => 'library',
 69314 'install_path' => __DIR__ . '/../symfony/finder',
 69315 'aliases' => array(),
 69316 'reference' => '1444eac52273e345d9b95129bf914639305a9ba4',
 69317 'dev_requirement' => false,
 69318 ),
 69319 'symfony/polyfill-ctype' => array(
 69320 'pretty_version' => 'v1.19.0',
 69321 'version' => '1.19.0.0',
 69322 'type' => 'library',
 69323 'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
 69324 'aliases' => array(),
 69325 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b',
 69326 'dev_requirement' => false,
 69327 ),
 69328 'symfony/polyfill-mbstring' => array(
 69329 'pretty_version' => 'v1.19.0',
 69330 'version' => '1.19.0.0',
 69331 'type' => 'library',
 69332 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
 69333 'aliases' => array(),
 69334 'reference' => 'b5f7b932ee6fa802fc792eabd77c4c88084517ce',
 69335 'dev_requirement' => false,
 69336 ),
 69337 'symfony/process' => array(
 69338 'pretty_version' => 'v2.8.52',
 69339 'version' => '2.8.52.0',
 69340 'type' => 'library',
 69341 'install_path' => __DIR__ . '/../symfony/process',
 69342 'aliases' => array(),
 69343 'reference' => 'c3591a09c78639822b0b290d44edb69bf9f05dc8',
 69344 'dev_requirement' => false,
 69345 ),
 69346 ),
 69347 );
 69348 
 69349 Copyright (C) 2021 Composer
 69350 
 69351 Permission is hereby granted, free of charge, to any person obtaining a copy of
 69352 this software and associated documentation files (the "Software"), to deal in
 69353 the Software without restriction, including without limitation the rights to
 69354 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 69355 of the Software, and to permit persons to whom the Software is furnished to do
 69356 so, subject to the following conditions:
 69357 
 69358 The above copyright notice and this permission notice shall be included in all
 69359 copies or substantial portions of the Software.
 69360 
 69361 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 69362 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 69363 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 69364 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 69365 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 69366 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 69367 SOFTWARE.
 69368 
 69369 <?php
 69370 
 69371 
 69372 
 69373 
 69374 
 69375 
 69376 
 69377 
 69378 
 69379 
 69380 namespace Composer\MetadataMinifier;
 69381 
 69382 class MetadataMinifier
 69383 {
 69384 
 69385 
 69386 
 69387 
 69388 
 69389 
 69390 public static function expand(array $versions)
 69391 {
 69392 $expanded = array();
 69393 $expandedVersion = null;
 69394 foreach ($versions as $versionData) {
 69395 if (!$expandedVersion) {
 69396 $expandedVersion = $versionData;
 69397 $expanded[] = $expandedVersion;
 69398 continue;
 69399 }
 69400 
 69401 
 69402 foreach ($versionData as $key => $val) {
 69403 if ($val === '__unset') {
 69404 unset($expandedVersion[$key]);
 69405 } else {
 69406 $expandedVersion[$key] = $val;
 69407 }
 69408 }
 69409 
 69410 $expanded[] = $expandedVersion;
 69411 }
 69412 
 69413 return $expanded;
 69414 }
 69415 
 69416 
 69417 
 69418 
 69419 
 69420 
 69421 
 69422 public static function minify(array $versions)
 69423 {
 69424 $minifiedVersions = array();
 69425 
 69426 $lastKnownVersionData = null;
 69427 foreach ($versions as $version) {
 69428 if (!$lastKnownVersionData) {
 69429 $lastKnownVersionData = $version;
 69430 $minifiedVersions[] = $version;
 69431 continue;
 69432 }
 69433 
 69434 $minifiedVersion = array();
 69435 
 69436 
 69437 foreach ($version as $key => $val) {
 69438 if (!isset($lastKnownVersionData[$key]) || $lastKnownVersionData[$key] !== $val) {
 69439 $minifiedVersion[$key] = $val;
 69440 $lastKnownVersionData[$key] = $val;
 69441 }
 69442 }
 69443 
 69444 
 69445 foreach ($lastKnownVersionData as $key => $val) {
 69446 if (!isset($version[$key])) {
 69447 $minifiedVersion[$key] = "__unset";
 69448 unset($lastKnownVersionData[$key]);
 69449 }
 69450 }
 69451 
 69452 $minifiedVersions[] = $minifiedVersion;
 69453 }
 69454 
 69455 return $minifiedVersions;
 69456 }
 69457 }
 69458 
 69459 Copyright (C) 2021 Composer
 69460 
 69461 Permission is hereby granted, free of charge, to any person obtaining a copy of
 69462 this software and associated documentation files (the "Software"), to deal in
 69463 the Software without restriction, including without limitation the rights to
 69464 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 69465 of the Software, and to permit persons to whom the Software is furnished to do
 69466 so, subject to the following conditions:
 69467 
 69468 The above copyright notice and this permission notice shall be included in all
 69469 copies or substantial portions of the Software.
 69470 
 69471 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 69472 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 69473 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 69474 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 69475 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 69476 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 69477 SOFTWARE.
 69478 
 69479 <?php
 69480 
 69481 
 69482 
 69483 
 69484 
 69485 
 69486 
 69487 
 69488 
 69489 
 69490 namespace Composer\Pcre;
 69491 
 69492 final class MatchAllResult
 69493 {
 69494 
 69495 
 69496 
 69497 
 69498 
 69499 
 69500 public $matches;
 69501 
 69502 
 69503 
 69504 
 69505 
 69506 public $count;
 69507 
 69508 
 69509 
 69510 
 69511 
 69512 public $matched;
 69513 
 69514 
 69515 
 69516 
 69517 
 69518 public function __construct($count, array $matches)
 69519 {
 69520 $this->matches = $matches;
 69521 $this->matched = (bool) $count;
 69522 $this->count = $count;
 69523 }
 69524 }
 69525 <?php
 69526 
 69527 
 69528 
 69529 
 69530 
 69531 
 69532 
 69533 
 69534 
 69535 
 69536 namespace Composer\Pcre;
 69537 
 69538 final class MatchAllWithOffsetsResult
 69539 {
 69540 
 69541 
 69542 
 69543 
 69544 
 69545 
 69546 
 69547 public $matches;
 69548 
 69549 
 69550 
 69551 
 69552 
 69553 public $count;
 69554 
 69555 
 69556 
 69557 
 69558 
 69559 public $matched;
 69560 
 69561 
 69562 
 69563 
 69564 
 69565 
 69566 public function __construct($count, array $matches)
 69567 {
 69568 $this->matches = $matches;
 69569 $this->matched = (bool) $count;
 69570 $this->count = $count;
 69571 }
 69572 }
 69573 <?php
 69574 
 69575 
 69576 
 69577 
 69578 
 69579 
 69580 
 69581 
 69582 
 69583 
 69584 namespace Composer\Pcre;
 69585 
 69586 final class MatchResult
 69587 {
 69588 
 69589 
 69590 
 69591 
 69592 
 69593 
 69594 public $matches;
 69595 
 69596 
 69597 
 69598 
 69599 
 69600 public $matched;
 69601 
 69602 
 69603 
 69604 
 69605 
 69606 public function __construct($count, array $matches)
 69607 {
 69608 $this->matches = $matches;
 69609 $this->matched = (bool) $count;
 69610 }
 69611 }
 69612 <?php
 69613 
 69614 
 69615 
 69616 
 69617 
 69618 
 69619 
 69620 
 69621 
 69622 
 69623 namespace Composer\Pcre;
 69624 
 69625 final class MatchWithOffsetsResult
 69626 {
 69627 
 69628 
 69629 
 69630 
 69631 
 69632 
 69633 
 69634 public $matches;
 69635 
 69636 
 69637 
 69638 
 69639 
 69640 public $matched;
 69641 
 69642 
 69643 
 69644 
 69645 
 69646 
 69647 public function __construct($count, array $matches)
 69648 {
 69649 $this->matches = $matches;
 69650 $this->matched = (bool) $count;
 69651 }
 69652 }
 69653 <?php
 69654 
 69655 
 69656 
 69657 
 69658 
 69659 
 69660 
 69661 
 69662 
 69663 
 69664 namespace Composer\Pcre;
 69665 
 69666 class PcreException extends \RuntimeException
 69667 {
 69668 
 69669 
 69670 
 69671 
 69672 
 69673 public static function fromFunction($function, $pattern)
 69674 {
 69675 $code = preg_last_error();
 69676 
 69677 if (is_array($pattern)) {
 69678 $pattern = implode(', ', $pattern);
 69679 }
 69680 
 69681 return new PcreException($function.'(): failed executing "'.$pattern.'": '.self::pcreLastErrorMessage($code), $code);
 69682 }
 69683 
 69684 
 69685 
 69686 
 69687 
 69688 private static function pcreLastErrorMessage($code)
 69689 {
 69690 if (PHP_VERSION_ID >= 80000) {
 69691 return preg_last_error_msg();
 69692 }
 69693 
 69694 
 69695 if (PHP_VERSION_ID < 70201 && $code === 0) {
 69696 return 'UNDEFINED_ERROR';
 69697 }
 69698 
 69699 $constants = get_defined_constants(true);
 69700 if (!isset($constants['pcre'])) {
 69701 return 'UNDEFINED_ERROR';
 69702 }
 69703 
 69704 foreach ($constants['pcre'] as $const => $val) {
 69705 if ($val === $code && substr($const, -6) === '_ERROR') {
 69706 return $const;
 69707 }
 69708 }
 69709 
 69710 return 'UNDEFINED_ERROR';
 69711 }
 69712 }
 69713 <?php
 69714 
 69715 
 69716 
 69717 
 69718 
 69719 
 69720 
 69721 
 69722 
 69723 
 69724 namespace Composer\Pcre;
 69725 
 69726 class Preg
 69727 {
 69728 const ARRAY_MSG = '$subject as an array is not supported. You can use \'foreach\' instead.';
 69729 
 69730 
 69731 
 69732 
 69733 
 69734 
 69735 
 69736 
 69737 
 69738 public static function match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
 69739 {
 69740 if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
 69741 throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use matchWithOffsets() instead');
 69742 }
 69743 
 69744 $result = preg_match($pattern, $subject, $matches, $flags, $offset);
 69745 if ($result === false) {
 69746 throw PcreException::fromFunction('preg_match', $pattern);
 69747 }
 69748 
 69749 return $result;
 69750 }
 69751 
 69752 
 69753 
 69754 
 69755 
 69756 
 69757 
 69758 
 69759 
 69760 
 69761 
 69762 
 69763 
 69764 public static function matchWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
 69765 {
 69766 $result = preg_match($pattern, $subject, $matches, $flags | PREG_OFFSET_CAPTURE, $offset);
 69767 if ($result === false) {
 69768 throw PcreException::fromFunction('preg_match', $pattern);
 69769 }
 69770 
 69771 return $result;
 69772 }
 69773 
 69774 
 69775 
 69776 
 69777 
 69778 
 69779 
 69780 
 69781 
 69782 public static function matchAll($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
 69783 {
 69784 if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
 69785 throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use matchAllWithOffsets() instead');
 69786 }
 69787 
 69788 if (($flags & PREG_SET_ORDER) !== 0) {
 69789 throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the type of $matches');
 69790 }
 69791 
 69792 $result = preg_match_all($pattern, $subject, $matches, $flags, $offset);
 69793 if ($result === false || $result === null) {
 69794 throw PcreException::fromFunction('preg_match_all', $pattern);
 69795 }
 69796 
 69797 return $result;
 69798 }
 69799 
 69800 
 69801 
 69802 
 69803 
 69804 
 69805 
 69806 
 69807 
 69808 
 69809 
 69810 
 69811 
 69812 public static function matchAllWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
 69813 {
 69814 $result = preg_match_all($pattern, $subject, $matches, $flags | PREG_OFFSET_CAPTURE, $offset);
 69815 if ($result === false || $result === null) {
 69816 throw PcreException::fromFunction('preg_match_all', $pattern);
 69817 }
 69818 
 69819 return $result;
 69820 }
 69821 
 69822 
 69823 
 69824 
 69825 
 69826 
 69827 
 69828 
 69829 
 69830 public static function replace($pattern, $replacement, $subject, $limit = -1, &$count = null)
 69831 {
 69832 if (is_array($subject)) { 
 69833 throw new \InvalidArgumentException(static::ARRAY_MSG);
 69834 }
 69835 
 69836 $result = preg_replace($pattern, $replacement, $subject, $limit, $count);
 69837 if ($result === null) {
 69838 throw PcreException::fromFunction('preg_replace', $pattern);
 69839 }
 69840 
 69841 return $result;
 69842 }
 69843 
 69844 
 69845 
 69846 
 69847 
 69848 
 69849 
 69850 
 69851 
 69852 
 69853 public static function replaceCallback($pattern, $replacement, $subject, $limit = -1, &$count = null, $flags = 0)
 69854 {
 69855 if (is_array($subject)) { 
 69856 throw new \InvalidArgumentException(static::ARRAY_MSG);
 69857 }
 69858 
 69859 if (PHP_VERSION_ID >= 70400) {
 69860 $result = preg_replace_callback($pattern, $replacement, $subject, $limit, $count, $flags);
 69861 } else {
 69862 $result = preg_replace_callback($pattern, $replacement, $subject, $limit, $count);
 69863 }
 69864 if ($result === null) {
 69865 throw PcreException::fromFunction('preg_replace_callback', $pattern);
 69866 }
 69867 
 69868 return $result;
 69869 }
 69870 
 69871 
 69872 
 69873 
 69874 
 69875 
 69876 
 69877 
 69878 
 69879 
 69880 
 69881 public static function replaceCallbackArray(array $pattern, $subject, $limit = -1, &$count = null, $flags = 0)
 69882 {
 69883 if (is_array($subject)) { 
 69884 throw new \InvalidArgumentException(static::ARRAY_MSG);
 69885 }
 69886 
 69887 if (PHP_VERSION_ID >= 70400) {
 69888 $result = preg_replace_callback_array($pattern, $subject, $limit, $count, $flags);
 69889 } else {
 69890 $result = preg_replace_callback_array($pattern, $subject, $limit, $count);
 69891 }
 69892 if ($result === null) {
 69893 $pattern = array_keys($pattern);
 69894 throw PcreException::fromFunction('preg_replace_callback_array', $pattern);
 69895 }
 69896 
 69897 return $result;
 69898 }
 69899 
 69900 
 69901 
 69902 
 69903 
 69904 
 69905 
 69906 
 69907 public static function split($pattern, $subject, $limit = -1, $flags = 0)
 69908 {
 69909 if (($flags & PREG_SPLIT_OFFSET_CAPTURE) !== 0) {
 69910 throw new \InvalidArgumentException('PREG_SPLIT_OFFSET_CAPTURE is not supported as it changes the type of $matches, use splitWithOffsets() instead');
 69911 }
 69912 
 69913 $result = preg_split($pattern, $subject, $limit, $flags);
 69914 if ($result === false) {
 69915 throw PcreException::fromFunction('preg_split', $pattern);
 69916 }
 69917 
 69918 return $result;
 69919 }
 69920 
 69921 
 69922 
 69923 
 69924 
 69925 
 69926 
 69927 
 69928 
 69929 public static function splitWithOffsets($pattern, $subject, $limit = -1, $flags = 0)
 69930 {
 69931 $result = preg_split($pattern, $subject, $limit, $flags | PREG_SPLIT_OFFSET_CAPTURE);
 69932 if ($result === false) {
 69933 throw PcreException::fromFunction('preg_split', $pattern);
 69934 }
 69935 
 69936 return $result;
 69937 }
 69938 
 69939 
 69940 
 69941 
 69942 
 69943 
 69944 
 69945 
 69946 public static function grep($pattern, array $array, $flags = 0)
 69947 {
 69948 $result = preg_grep($pattern, $array, $flags);
 69949 if ($result === false) {
 69950 throw PcreException::fromFunction('preg_grep', $pattern);
 69951 }
 69952 
 69953 return $result;
 69954 }
 69955 
 69956 
 69957 
 69958 
 69959 
 69960 
 69961 
 69962 
 69963 
 69964 public static function isMatch($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
 69965 {
 69966 return (bool) static::match($pattern, $subject, $matches, $flags, $offset);
 69967 }
 69968 
 69969 
 69970 
 69971 
 69972 
 69973 
 69974 
 69975 
 69976 
 69977 public static function isMatchAll($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
 69978 {
 69979 return (bool) static::matchAll($pattern, $subject, $matches, $flags, $offset);
 69980 }
 69981 
 69982 
 69983 
 69984 
 69985 
 69986 
 69987 
 69988 
 69989 
 69990 
 69991 
 69992 
 69993 
 69994 public static function isMatchWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
 69995 {
 69996 return (bool) static::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
 69997 }
 69998 
 69999 
 70000 
 70001 
 70002 
 70003 
 70004 
 70005 
 70006 
 70007 
 70008 
 70009 
 70010 
 70011 public static function isMatchAllWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
 70012 {
 70013 return (bool) static::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
 70014 }
 70015 }
 70016 <?php
 70017 
 70018 
 70019 
 70020 
 70021 
 70022 
 70023 
 70024 
 70025 
 70026 
 70027 namespace Composer\Pcre;
 70028 
 70029 class Regex
 70030 {
 70031 
 70032 
 70033 
 70034 
 70035 
 70036 
 70037 public static function isMatch($pattern, $subject, $offset = 0)
 70038 {
 70039 return (bool) Preg::match($pattern, $subject, $matches, 0, $offset);
 70040 }
 70041 
 70042 
 70043 
 70044 
 70045 
 70046 
 70047 
 70048 
 70049 public static function match($pattern, $subject, $flags = 0, $offset = 0)
 70050 {
 70051 if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
 70052 throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use matchWithOffsets() instead');
 70053 }
 70054 
 70055 $count = Preg::match($pattern, $subject, $matches, $flags, $offset);
 70056 
 70057 return new MatchResult($count, $matches);
 70058 }
 70059 
 70060 
 70061 
 70062 
 70063 
 70064 
 70065 
 70066 
 70067 
 70068 
 70069 public static function matchWithOffsets($pattern, $subject, $flags = 0, $offset = 0)
 70070 {
 70071 $count = Preg::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
 70072 
 70073 return new MatchWithOffsetsResult($count, $matches);
 70074 }
 70075 
 70076 
 70077 
 70078 
 70079 
 70080 
 70081 
 70082 
 70083 public static function matchAll($pattern, $subject, $flags = 0, $offset = 0)
 70084 {
 70085 if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
 70086 throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use matchAllWithOffsets() instead');
 70087 }
 70088 
 70089 if (($flags & PREG_SET_ORDER) !== 0) {
 70090 throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the return type');
 70091 }
 70092 
 70093 $count = Preg::matchAll($pattern, $subject, $matches, $flags, $offset);
 70094 
 70095 return new MatchAllResult($count, $matches);
 70096 }
 70097 
 70098 
 70099 
 70100 
 70101 
 70102 
 70103 
 70104 
 70105 
 70106 
 70107 public static function matchAllWithOffsets($pattern, $subject, $flags = 0, $offset = 0)
 70108 {
 70109 $count = Preg::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
 70110 
 70111 return new MatchAllWithOffsetsResult($count, $matches);
 70112 }
 70113 
 70114 
 70115 
 70116 
 70117 
 70118 
 70119 
 70120 public static function replace($pattern, $replacement, $subject, $limit = -1)
 70121 {
 70122 $result = Preg::replace($pattern, $replacement, $subject, $limit, $count);
 70123 
 70124 return new ReplaceResult($count, $result);
 70125 }
 70126 
 70127 
 70128 
 70129 
 70130 
 70131 
 70132 
 70133 
 70134 
 70135 public static function replaceCallback($pattern, $replacement, $subject, $limit = -1, $flags = 0)
 70136 {
 70137 $result = Preg::replaceCallback($pattern, $replacement, $subject, $limit, $count, $flags);
 70138 
 70139 return new ReplaceResult($count, $result);
 70140 }
 70141 
 70142 
 70143 
 70144 
 70145 
 70146 
 70147 
 70148 
 70149 
 70150 
 70151 public static function replaceCallbackArray($pattern, $subject, $limit = -1, $flags = 0)
 70152 {
 70153 $result = Preg::replaceCallbackArray($pattern, $subject, $limit, $count, $flags);
 70154 
 70155 return new ReplaceResult($count, $result);
 70156 }
 70157 }
 70158 <?php
 70159 
 70160 
 70161 
 70162 
 70163 
 70164 
 70165 
 70166 
 70167 
 70168 
 70169 namespace Composer\Pcre;
 70170 
 70171 final class ReplaceResult
 70172 {
 70173 
 70174 
 70175 
 70176 
 70177 public $result;
 70178 
 70179 
 70180 
 70181 
 70182 
 70183 public $count;
 70184 
 70185 
 70186 
 70187 
 70188 
 70189 public $matched;
 70190 
 70191 
 70192 
 70193 
 70194 
 70195 public function __construct($count, $result)
 70196 {
 70197 $this->count = $count;
 70198 $this->matched = (bool) $count;
 70199 $this->result = $result;
 70200 }
 70201 }
 70202 
 70203 Copyright (C) 2015 Composer
 70204 
 70205 Permission is hereby granted, free of charge, to any person obtaining a copy of
 70206 this software and associated documentation files (the "Software"), to deal in
 70207 the Software without restriction, including without limitation the rights to
 70208 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 70209 of the Software, and to permit persons to whom the Software is furnished to do
 70210 so, subject to the following conditions:
 70211 
 70212 The above copyright notice and this permission notice shall be included in all
 70213 copies or substantial portions of the Software.
 70214 
 70215 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 70216 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 70217 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 70218 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 70219 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 70220 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 70221 SOFTWARE.
 70222 
 70223 <?php
 70224 
 70225 
 70226 
 70227 
 70228 
 70229 
 70230 
 70231 
 70232 
 70233 
 70234 namespace Composer\Semver;
 70235 
 70236 use Composer\Semver\Constraint\Constraint;
 70237 
 70238 class Comparator
 70239 {
 70240 
 70241 
 70242 
 70243 
 70244 
 70245 
 70246 
 70247 
 70248 public static function greaterThan($version1, $version2)
 70249 {
 70250 return self::compare($version1, '>', $version2);
 70251 }
 70252 
 70253 
 70254 
 70255 
 70256 
 70257 
 70258 
 70259 
 70260 
 70261 public static function greaterThanOrEqualTo($version1, $version2)
 70262 {
 70263 return self::compare($version1, '>=', $version2);
 70264 }
 70265 
 70266 
 70267 
 70268 
 70269 
 70270 
 70271 
 70272 
 70273 
 70274 public static function lessThan($version1, $version2)
 70275 {
 70276 return self::compare($version1, '<', $version2);
 70277 }
 70278 
 70279 
 70280 
 70281 
 70282 
 70283 
 70284 
 70285 
 70286 
 70287 public static function lessThanOrEqualTo($version1, $version2)
 70288 {
 70289 return self::compare($version1, '<=', $version2);
 70290 }
 70291 
 70292 
 70293 
 70294 
 70295 
 70296 
 70297 
 70298 
 70299 
 70300 public static function equalTo($version1, $version2)
 70301 {
 70302 return self::compare($version1, '==', $version2);
 70303 }
 70304 
 70305 
 70306 
 70307 
 70308 
 70309 
 70310 
 70311 
 70312 
 70313 public static function notEqualTo($version1, $version2)
 70314 {
 70315 return self::compare($version1, '!=', $version2);
 70316 }
 70317 
 70318 
 70319 
 70320 
 70321 
 70322 
 70323 
 70324 
 70325 
 70326 
 70327 
 70328 
 70329 public static function compare($version1, $operator, $version2)
 70330 {
 70331 $constraint = new Constraint($operator, $version2);
 70332 
 70333 return $constraint->matchSpecific(new Constraint('==', $version1), true);
 70334 }
 70335 }
 70336 <?php
 70337 
 70338 
 70339 
 70340 
 70341 
 70342 
 70343 
 70344 
 70345 
 70346 
 70347 namespace Composer\Semver;
 70348 
 70349 use Composer\Semver\Constraint\Constraint;
 70350 use Composer\Semver\Constraint\ConstraintInterface;
 70351 
 70352 
 70353 
 70354 
 70355 class CompilingMatcher
 70356 {
 70357 
 70358 
 70359 
 70360 
 70361 private static $compiledCheckerCache = array();
 70362 
 70363 
 70364 
 70365 
 70366 private static $resultCache = array();
 70367 
 70368 
 70369 private static $enabled;
 70370 
 70371 
 70372 
 70373 
 70374 private static $transOpInt = array(
 70375 Constraint::OP_EQ => Constraint::STR_OP_EQ,
 70376 Constraint::OP_LT => Constraint::STR_OP_LT,
 70377 Constraint::OP_LE => Constraint::STR_OP_LE,
 70378 Constraint::OP_GT => Constraint::STR_OP_GT,
 70379 Constraint::OP_GE => Constraint::STR_OP_GE,
 70380 Constraint::OP_NE => Constraint::STR_OP_NE,
 70381 );
 70382 
 70383 
 70384 
 70385 
 70386 
 70387 
 70388 public static function clear()
 70389 {
 70390 self::$resultCache = array();
 70391 self::$compiledCheckerCache = array();
 70392 }
 70393 
 70394 
 70395 
 70396 
 70397 
 70398 
 70399 
 70400 
 70401 
 70402 
 70403 
 70404 public static function match(ConstraintInterface $constraint, $operator, $version)
 70405 {
 70406 $resultCacheKey = $operator.$constraint.$version;
 70407 
 70408 if (isset(self::$resultCache[$resultCacheKey])) {
 70409 return self::$resultCache[$resultCacheKey];
 70410 }
 70411 
 70412 if (self::$enabled === null) {
 70413 self::$enabled = !\in_array('eval', explode(',', (string) ini_get('disable_functions')), true);
 70414 }
 70415 if (!self::$enabled) {
 70416 return self::$resultCache[$resultCacheKey] = $constraint->matches(new Constraint(self::$transOpInt[$operator], $version));
 70417 }
 70418 
 70419 $cacheKey = $operator.$constraint;
 70420 if (!isset(self::$compiledCheckerCache[$cacheKey])) {
 70421 $code = $constraint->compile($operator);
 70422 self::$compiledCheckerCache[$cacheKey] = $function = eval('return function($v, $b){return '.$code.';};');
 70423 } else {
 70424 $function = self::$compiledCheckerCache[$cacheKey];
 70425 }
 70426 
 70427 return self::$resultCache[$resultCacheKey] = $function($version, strpos($version, 'dev-') === 0);
 70428 }
 70429 }
 70430 <?php
 70431 
 70432 
 70433 
 70434 
 70435 
 70436 
 70437 
 70438 
 70439 
 70440 
 70441 namespace Composer\Semver\Constraint;
 70442 
 70443 class Bound
 70444 {
 70445 
 70446 
 70447 
 70448 private $version;
 70449 
 70450 
 70451 
 70452 
 70453 private $isInclusive;
 70454 
 70455 
 70456 
 70457 
 70458 
 70459 public function __construct($version, $isInclusive)
 70460 {
 70461 $this->version = $version;
 70462 $this->isInclusive = $isInclusive;
 70463 }
 70464 
 70465 
 70466 
 70467 
 70468 public function getVersion()
 70469 {
 70470 return $this->version;
 70471 }
 70472 
 70473 
 70474 
 70475 
 70476 public function isInclusive()
 70477 {
 70478 return $this->isInclusive;
 70479 }
 70480 
 70481 
 70482 
 70483 
 70484 public function isZero()
 70485 {
 70486 return $this->getVersion() === '0.0.0.0-dev' && $this->isInclusive();
 70487 }
 70488 
 70489 
 70490 
 70491 
 70492 public function isPositiveInfinity()
 70493 {
 70494 return $this->getVersion() === PHP_INT_MAX.'.0.0.0' && !$this->isInclusive();
 70495 }
 70496 
 70497 
 70498 
 70499 
 70500 
 70501 
 70502 
 70503 
 70504 
 70505 public function compareTo(Bound $other, $operator)
 70506 {
 70507 if (!\in_array($operator, array('<', '>'), true)) {
 70508 throw new \InvalidArgumentException('Does not support any other operator other than > or <.');
 70509 }
 70510 
 70511 
 70512 if ($this == $other) {
 70513 return false;
 70514 }
 70515 
 70516 $compareResult = version_compare($this->getVersion(), $other->getVersion());
 70517 
 70518 
 70519 if (0 !== $compareResult) {
 70520 return (('>' === $operator) ? 1 : -1) === $compareResult;
 70521 }
 70522 
 70523 
 70524 return '>' === $operator ? $other->isInclusive() : !$other->isInclusive();
 70525 }
 70526 
 70527 public function __toString()
 70528 {
 70529 return sprintf(
 70530 '%s [%s]',
 70531 $this->getVersion(),
 70532 $this->isInclusive() ? 'inclusive' : 'exclusive'
 70533 );
 70534 }
 70535 
 70536 
 70537 
 70538 
 70539 public static function zero()
 70540 {
 70541 return new Bound('0.0.0.0-dev', true);
 70542 }
 70543 
 70544 
 70545 
 70546 
 70547 public static function positiveInfinity()
 70548 {
 70549 return new Bound(PHP_INT_MAX.'.0.0.0', false);
 70550 }
 70551 }
 70552 <?php
 70553 
 70554 
 70555 
 70556 
 70557 
 70558 
 70559 
 70560 
 70561 
 70562 
 70563 namespace Composer\Semver\Constraint;
 70564 
 70565 
 70566 
 70567 
 70568 class Constraint implements ConstraintInterface
 70569 {
 70570 
 70571 const OP_EQ = 0;
 70572 const OP_LT = 1;
 70573 const OP_LE = 2;
 70574 const OP_GT = 3;
 70575 const OP_GE = 4;
 70576 const OP_NE = 5;
 70577 
 70578 
 70579 const STR_OP_EQ = '==';
 70580 const STR_OP_EQ_ALT = '=';
 70581 const STR_OP_LT = '<';
 70582 const STR_OP_LE = '<=';
 70583 const STR_OP_GT = '>';
 70584 const STR_OP_GE = '>=';
 70585 const STR_OP_NE = '!=';
 70586 const STR_OP_NE_ALT = '<>';
 70587 
 70588 
 70589 
 70590 
 70591 
 70592 
 70593 
 70594 private static $transOpStr = array(
 70595 '=' => self::OP_EQ,
 70596 '==' => self::OP_EQ,
 70597 '<' => self::OP_LT,
 70598 '<=' => self::OP_LE,
 70599 '>' => self::OP_GT,
 70600 '>=' => self::OP_GE,
 70601 '<>' => self::OP_NE,
 70602 '!=' => self::OP_NE,
 70603 );
 70604 
 70605 
 70606 
 70607 
 70608 
 70609 
 70610 
 70611 private static $transOpInt = array(
 70612 self::OP_EQ => '==',
 70613 self::OP_LT => '<',
 70614 self::OP_LE => '<=',
 70615 self::OP_GT => '>',
 70616 self::OP_GE => '>=',
 70617 self::OP_NE => '!=',
 70618 );
 70619 
 70620 
 70621 
 70622 
 70623 
 70624 protected $operator;
 70625 
 70626 
 70627 protected $version;
 70628 
 70629 
 70630 protected $prettyString;
 70631 
 70632 
 70633 protected $lowerBound;
 70634 
 70635 
 70636 protected $upperBound;
 70637 
 70638 
 70639 
 70640 
 70641 
 70642 
 70643 
 70644 
 70645 
 70646 
 70647 
 70648 public function __construct($operator, $version)
 70649 {
 70650 if (!isset(self::$transOpStr[$operator])) {
 70651 throw new \InvalidArgumentException(sprintf(
 70652 'Invalid operator "%s" given, expected one of: %s',
 70653 $operator,
 70654 implode(', ', self::getSupportedOperators())
 70655 ));
 70656 }
 70657 
 70658 $this->operator = self::$transOpStr[$operator];
 70659 $this->version = $version;
 70660 }
 70661 
 70662 
 70663 
 70664 
 70665 public function getVersion()
 70666 {
 70667 return $this->version;
 70668 }
 70669 
 70670 
 70671 
 70672 
 70673 
 70674 
 70675 public function getOperator()
 70676 {
 70677 return self::$transOpInt[$this->operator];
 70678 }
 70679 
 70680 
 70681 
 70682 
 70683 
 70684 
 70685 public function matches(ConstraintInterface $provider)
 70686 {
 70687 if ($provider instanceof self) {
 70688 return $this->matchSpecific($provider);
 70689 }
 70690 
 70691 
 70692 return $provider->matches($this);
 70693 }
 70694 
 70695 
 70696 
 70697 
 70698 public function setPrettyString($prettyString)
 70699 {
 70700 $this->prettyString = $prettyString;
 70701 }
 70702 
 70703 
 70704 
 70705 
 70706 public function getPrettyString()
 70707 {
 70708 if ($this->prettyString) {
 70709 return $this->prettyString;
 70710 }
 70711 
 70712 return $this->__toString();
 70713 }
 70714 
 70715 
 70716 
 70717 
 70718 
 70719 
 70720 
 70721 
 70722 public static function getSupportedOperators()
 70723 {
 70724 return array_keys(self::$transOpStr);
 70725 }
 70726 
 70727 
 70728 
 70729 
 70730 
 70731 
 70732 
 70733 
 70734 public static function getOperatorConstant($operator)
 70735 {
 70736 return self::$transOpStr[$operator];
 70737 }
 70738 
 70739 
 70740 
 70741 
 70742 
 70743 
 70744 
 70745 
 70746 
 70747 
 70748 
 70749 
 70750 
 70751 public function versionCompare($a, $b, $operator, $compareBranches = false)
 70752 {
 70753 if (!isset(self::$transOpStr[$operator])) {
 70754 throw new \InvalidArgumentException(sprintf(
 70755 'Invalid operator "%s" given, expected one of: %s',
 70756 $operator,
 70757 implode(', ', self::getSupportedOperators())
 70758 ));
 70759 }
 70760 
 70761 $aIsBranch = strpos($a, 'dev-') === 0;
 70762 $bIsBranch = strpos($b, 'dev-') === 0;
 70763 
 70764 if ($operator === '!=' && ($aIsBranch || $bIsBranch)) {
 70765 return $a !== $b;
 70766 }
 70767 
 70768 if ($aIsBranch && $bIsBranch) {
 70769 return $operator === '==' && $a === $b;
 70770 }
 70771 
 70772 
 70773 if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
 70774 return false;
 70775 }
 70776 
 70777 return \version_compare($a, $b, $operator);
 70778 }
 70779 
 70780 
 70781 
 70782 
 70783 public function compile($otherOperator)
 70784 {
 70785 if (strpos($this->version, 'dev-') === 0) {
 70786 if (self::OP_EQ === $this->operator) {
 70787 if (self::OP_EQ === $otherOperator) {
 70788 return sprintf('$b && $v === %s', \var_export($this->version, true));
 70789 }
 70790 if (self::OP_NE === $otherOperator) {
 70791 return sprintf('!$b || $v !== %s', \var_export($this->version, true));
 70792 }
 70793 return 'false';
 70794 }
 70795 
 70796 if (self::OP_NE === $this->operator) {
 70797 if (self::OP_EQ === $otherOperator) {
 70798 return sprintf('!$b || $v !== %s', \var_export($this->version, true));
 70799 }
 70800 if (self::OP_NE === $otherOperator) {
 70801 return 'true';
 70802 }
 70803 return '!$b';
 70804 }
 70805 
 70806 return 'false';
 70807 }
 70808 
 70809 if (self::OP_EQ === $this->operator) {
 70810 if (self::OP_EQ === $otherOperator) {
 70811 return sprintf('\version_compare($v, %s, \'==\')', \var_export($this->version, true));
 70812 }
 70813 if (self::OP_NE === $otherOperator) {
 70814 return sprintf('$b || \version_compare($v, %s, \'!=\')', \var_export($this->version, true));
 70815 }
 70816 
 70817 return sprintf('!$b && \version_compare(%s, $v, \'%s\')', \var_export($this->version, true), self::$transOpInt[$otherOperator]);
 70818 }
 70819 
 70820 if (self::OP_NE === $this->operator) {
 70821 if (self::OP_EQ === $otherOperator) {
 70822 return sprintf('$b || (!$b && \version_compare($v, %s, \'!=\'))', \var_export($this->version, true));
 70823 }
 70824 
 70825 if (self::OP_NE === $otherOperator) {
 70826 return 'true';
 70827 }
 70828 return '!$b';
 70829 }
 70830 
 70831 if (self::OP_LT === $this->operator || self::OP_LE === $this->operator) {
 70832 if (self::OP_LT === $otherOperator || self::OP_LE === $otherOperator) {
 70833 return '!$b';
 70834 }
 70835 } else { 
 70836 if (self::OP_GT === $otherOperator || self::OP_GE === $otherOperator) {
 70837 return '!$b';
 70838 }
 70839 }
 70840 
 70841 if (self::OP_NE === $otherOperator) {
 70842 return 'true';
 70843 }
 70844 
 70845 $codeComparison = sprintf('\version_compare($v, %s, \'%s\')', \var_export($this->version, true), self::$transOpInt[$this->operator]);
 70846 if ($this->operator === self::OP_LE) {
 70847 if ($otherOperator === self::OP_GT) {
 70848 return sprintf('!$b && \version_compare($v, %s, \'!=\') && ', \var_export($this->version, true)) . $codeComparison;
 70849 }
 70850 } elseif ($this->operator === self::OP_GE) {
 70851 if ($otherOperator === self::OP_LT) {
 70852 return sprintf('!$b && \version_compare($v, %s, \'!=\') && ', \var_export($this->version, true)) . $codeComparison;
 70853 }
 70854 }
 70855 
 70856 return sprintf('!$b && %s', $codeComparison);
 70857 }
 70858 
 70859 
 70860 
 70861 
 70862 
 70863 
 70864 
 70865 public function matchSpecific(Constraint $provider, $compareBranches = false)
 70866 {
 70867 $noEqualOp = str_replace('=', '', self::$transOpInt[$this->operator]);
 70868 $providerNoEqualOp = str_replace('=', '', self::$transOpInt[$provider->operator]);
 70869 
 70870 $isEqualOp = self::OP_EQ === $this->operator;
 70871 $isNonEqualOp = self::OP_NE === $this->operator;
 70872 $isProviderEqualOp = self::OP_EQ === $provider->operator;
 70873 $isProviderNonEqualOp = self::OP_NE === $provider->operator;
 70874 
 70875 
 70876 
 70877 if ($isNonEqualOp || $isProviderNonEqualOp) {
 70878 if ($isNonEqualOp && !$isProviderNonEqualOp && !$isProviderEqualOp && strpos($provider->version, 'dev-') === 0) {
 70879 return false;
 70880 }
 70881 
 70882 if ($isProviderNonEqualOp && !$isNonEqualOp && !$isEqualOp && strpos($this->version, 'dev-') === 0) {
 70883 return false;
 70884 }
 70885 
 70886 if (!$isEqualOp && !$isProviderEqualOp) {
 70887 return true;
 70888 }
 70889 return $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
 70890 }
 70891 
 70892 
 70893 
 70894 if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) {
 70895 return !(strpos($this->version, 'dev-') === 0 || strpos($provider->version, 'dev-') === 0);
 70896 }
 70897 
 70898 $version1 = $isEqualOp ? $this->version : $provider->version;
 70899 $version2 = $isEqualOp ? $provider->version : $this->version;
 70900 $operator = $isEqualOp ? $provider->operator : $this->operator;
 70901 
 70902 if ($this->versionCompare($version1, $version2, self::$transOpInt[$operator], $compareBranches)) {
 70903 
 70904 
 70905 
 70906 return !(self::$transOpInt[$provider->operator] === $providerNoEqualOp
 70907 && self::$transOpInt[$this->operator] !== $noEqualOp
 70908 && \version_compare($provider->version, $this->version, '=='));
 70909 }
 70910 
 70911 return false;
 70912 }
 70913 
 70914 
 70915 
 70916 
 70917 public function __toString()
 70918 {
 70919 return self::$transOpInt[$this->operator] . ' ' . $this->version;
 70920 }
 70921 
 70922 
 70923 
 70924 
 70925 public function getLowerBound()
 70926 {
 70927 $this->extractBounds();
 70928 
 70929 return $this->lowerBound;
 70930 }
 70931 
 70932 
 70933 
 70934 
 70935 public function getUpperBound()
 70936 {
 70937 $this->extractBounds();
 70938 
 70939 return $this->upperBound;
 70940 }
 70941 
 70942 
 70943 
 70944 
 70945 private function extractBounds()
 70946 {
 70947 if (null !== $this->lowerBound) {
 70948 return;
 70949 }
 70950 
 70951 
 70952 if (strpos($this->version, 'dev-') === 0) {
 70953 $this->lowerBound = Bound::zero();
 70954 $this->upperBound = Bound::positiveInfinity();
 70955 
 70956 return;
 70957 }
 70958 
 70959 switch ($this->operator) {
 70960 case self::OP_EQ:
 70961 $this->lowerBound = new Bound($this->version, true);
 70962 $this->upperBound = new Bound($this->version, true);
 70963 break;
 70964 case self::OP_LT:
 70965 $this->lowerBound = Bound::zero();
 70966 $this->upperBound = new Bound($this->version, false);
 70967 break;
 70968 case self::OP_LE:
 70969 $this->lowerBound = Bound::zero();
 70970 $this->upperBound = new Bound($this->version, true);
 70971 break;
 70972 case self::OP_GT:
 70973 $this->lowerBound = new Bound($this->version, false);
 70974 $this->upperBound = Bound::positiveInfinity();
 70975 break;
 70976 case self::OP_GE:
 70977 $this->lowerBound = new Bound($this->version, true);
 70978 $this->upperBound = Bound::positiveInfinity();
 70979 break;
 70980 case self::OP_NE:
 70981 $this->lowerBound = Bound::zero();
 70982 $this->upperBound = Bound::positiveInfinity();
 70983 break;
 70984 }
 70985 }
 70986 }
 70987 <?php
 70988 
 70989 
 70990 
 70991 
 70992 
 70993 
 70994 
 70995 
 70996 
 70997 
 70998 namespace Composer\Semver\Constraint;
 70999 
 71000 
 71001 
 71002 
 71003 
 71004 
 71005 
 71006 interface ConstraintInterface
 71007 {
 71008 
 71009 
 71010 
 71011 
 71012 
 71013 
 71014 
 71015 public function matches(ConstraintInterface $provider);
 71016 
 71017 
 71018 
 71019 
 71020 
 71021 
 71022 
 71023 
 71024 
 71025 
 71026 
 71027 
 71028 
 71029 
 71030 
 71031 
 71032 
 71033 public function compile($otherOperator);
 71034 
 71035 
 71036 
 71037 
 71038 public function getUpperBound();
 71039 
 71040 
 71041 
 71042 
 71043 public function getLowerBound();
 71044 
 71045 
 71046 
 71047 
 71048 public function getPrettyString();
 71049 
 71050 
 71051 
 71052 
 71053 
 71054 
 71055 public function setPrettyString($prettyString);
 71056 
 71057 
 71058 
 71059 
 71060 public function __toString();
 71061 }
 71062 <?php
 71063 
 71064 
 71065 
 71066 
 71067 
 71068 
 71069 
 71070 
 71071 
 71072 
 71073 namespace Composer\Semver\Constraint;
 71074 
 71075 
 71076 
 71077 
 71078 
 71079 
 71080 class MatchAllConstraint implements ConstraintInterface
 71081 {
 71082 
 71083 protected $prettyString;
 71084 
 71085 
 71086 
 71087 
 71088 
 71089 
 71090 public function matches(ConstraintInterface $provider)
 71091 {
 71092 return true;
 71093 }
 71094 
 71095 
 71096 
 71097 
 71098 public function compile($otherOperator)
 71099 {
 71100 return 'true';
 71101 }
 71102 
 71103 
 71104 
 71105 
 71106 public function setPrettyString($prettyString)
 71107 {
 71108 $this->prettyString = $prettyString;
 71109 }
 71110 
 71111 
 71112 
 71113 
 71114 public function getPrettyString()
 71115 {
 71116 if ($this->prettyString) {
 71117 return $this->prettyString;
 71118 }
 71119 
 71120 return (string) $this;
 71121 }
 71122 
 71123 
 71124 
 71125 
 71126 public function __toString()
 71127 {
 71128 return '*';
 71129 }
 71130 
 71131 
 71132 
 71133 
 71134 public function getUpperBound()
 71135 {
 71136 return Bound::positiveInfinity();
 71137 }
 71138 
 71139 
 71140 
 71141 
 71142 public function getLowerBound()
 71143 {
 71144 return Bound::zero();
 71145 }
 71146 }
 71147 <?php
 71148 
 71149 
 71150 
 71151 
 71152 
 71153 
 71154 
 71155 
 71156 
 71157 
 71158 namespace Composer\Semver\Constraint;
 71159 
 71160 
 71161 
 71162 
 71163 class MatchNoneConstraint implements ConstraintInterface
 71164 {
 71165 
 71166 protected $prettyString;
 71167 
 71168 
 71169 
 71170 
 71171 
 71172 
 71173 public function matches(ConstraintInterface $provider)
 71174 {
 71175 return false;
 71176 }
 71177 
 71178 
 71179 
 71180 
 71181 public function compile($otherOperator)
 71182 {
 71183 return 'false';
 71184 }
 71185 
 71186 
 71187 
 71188 
 71189 public function setPrettyString($prettyString)
 71190 {
 71191 $this->prettyString = $prettyString;
 71192 }
 71193 
 71194 
 71195 
 71196 
 71197 public function getPrettyString()
 71198 {
 71199 if ($this->prettyString) {
 71200 return $this->prettyString;
 71201 }
 71202 
 71203 return (string) $this;
 71204 }
 71205 
 71206 
 71207 
 71208 
 71209 public function __toString()
 71210 {
 71211 return '[]';
 71212 }
 71213 
 71214 
 71215 
 71216 
 71217 public function getUpperBound()
 71218 {
 71219 return new Bound('0.0.0.0-dev', false);
 71220 }
 71221 
 71222 
 71223 
 71224 
 71225 public function getLowerBound()
 71226 {
 71227 return new Bound('0.0.0.0-dev', false);
 71228 }
 71229 }
 71230 <?php
 71231 
 71232 
 71233 
 71234 
 71235 
 71236 
 71237 
 71238 
 71239 
 71240 
 71241 namespace Composer\Semver\Constraint;
 71242 
 71243 
 71244 
 71245 
 71246 class MultiConstraint implements ConstraintInterface
 71247 {
 71248 
 71249 
 71250 
 71251 
 71252 protected $constraints;
 71253 
 71254 
 71255 protected $prettyString;
 71256 
 71257 
 71258 protected $string;
 71259 
 71260 
 71261 protected $conjunctive;
 71262 
 71263 
 71264 protected $lowerBound;
 71265 
 71266 
 71267 protected $upperBound;
 71268 
 71269 
 71270 
 71271 
 71272 
 71273 
 71274 
 71275 public function __construct(array $constraints, $conjunctive = true)
 71276 {
 71277 if (\count($constraints) < 2) {
 71278 throw new \InvalidArgumentException(
 71279 'Must provide at least two constraints for a MultiConstraint. Use '.
 71280 'the regular Constraint class for one constraint only or MatchAllConstraint for none. You may use '.
 71281 'MultiConstraint::create() which optimizes and handles those cases automatically.'
 71282 );
 71283 }
 71284 
 71285 $this->constraints = $constraints;
 71286 $this->conjunctive = $conjunctive;
 71287 }
 71288 
 71289 
 71290 
 71291 
 71292 public function getConstraints()
 71293 {
 71294 return $this->constraints;
 71295 }
 71296 
 71297 
 71298 
 71299 
 71300 public function isConjunctive()
 71301 {
 71302 return $this->conjunctive;
 71303 }
 71304 
 71305 
 71306 
 71307 
 71308 public function isDisjunctive()
 71309 {
 71310 return !$this->conjunctive;
 71311 }
 71312 
 71313 
 71314 
 71315 
 71316 public function compile($otherOperator)
 71317 {
 71318 $parts = array();
 71319 foreach ($this->constraints as $constraint) {
 71320 $code = $constraint->compile($otherOperator);
 71321 if ($code === 'true') {
 71322 if (!$this->conjunctive) {
 71323 return 'true';
 71324 }
 71325 } elseif ($code === 'false') {
 71326 if ($this->conjunctive) {
 71327 return 'false';
 71328 }
 71329 } else {
 71330 $parts[] = '('.$code.')';
 71331 }
 71332 }
 71333 
 71334 if (!$parts) {
 71335 return $this->conjunctive ? 'true' : 'false';
 71336 }
 71337 
 71338 return $this->conjunctive ? implode('&&', $parts) : implode('||', $parts);
 71339 }
 71340 
 71341 
 71342 
 71343 
 71344 
 71345 
 71346 public function matches(ConstraintInterface $provider)
 71347 {
 71348 if (false === $this->conjunctive) {
 71349 foreach ($this->constraints as $constraint) {
 71350 if ($provider->matches($constraint)) {
 71351 return true;
 71352 }
 71353 }
 71354 
 71355 return false;
 71356 }
 71357 
 71358 
 71359 
 71360 
 71361 if ($provider instanceof MultiConstraint && $provider->isDisjunctive()) {
 71362 return $provider->matches($this);
 71363 }
 71364 
 71365 foreach ($this->constraints as $constraint) {
 71366 if (!$provider->matches($constraint)) {
 71367 return false;
 71368 }
 71369 }
 71370 
 71371 return true;
 71372 }
 71373 
 71374 
 71375 
 71376 
 71377 public function setPrettyString($prettyString)
 71378 {
 71379 $this->prettyString = $prettyString;
 71380 }
 71381 
 71382 
 71383 
 71384 
 71385 public function getPrettyString()
 71386 {
 71387 if ($this->prettyString) {
 71388 return $this->prettyString;
 71389 }
 71390 
 71391 return (string) $this;
 71392 }
 71393 
 71394 
 71395 
 71396 
 71397 public function __toString()
 71398 {
 71399 if ($this->string !== null) {
 71400 return $this->string;
 71401 }
 71402 
 71403 $constraints = array();
 71404 foreach ($this->constraints as $constraint) {
 71405 $constraints[] = (string) $constraint;
 71406 }
 71407 
 71408 return $this->string = '[' . implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']';
 71409 }
 71410 
 71411 
 71412 
 71413 
 71414 public function getLowerBound()
 71415 {
 71416 $this->extractBounds();
 71417 
 71418 if (null === $this->lowerBound) {
 71419 throw new \LogicException('extractBounds should have populated the lowerBound property');
 71420 }
 71421 
 71422 return $this->lowerBound;
 71423 }
 71424 
 71425 
 71426 
 71427 
 71428 public function getUpperBound()
 71429 {
 71430 $this->extractBounds();
 71431 
 71432 if (null === $this->upperBound) {
 71433 throw new \LogicException('extractBounds should have populated the upperBound property');
 71434 }
 71435 
 71436 return $this->upperBound;
 71437 }
 71438 
 71439 
 71440 
 71441 
 71442 
 71443 
 71444 
 71445 
 71446 
 71447 
 71448 
 71449 
 71450 public static function create(array $constraints, $conjunctive = true)
 71451 {
 71452 if (0 === \count($constraints)) {
 71453 return new MatchAllConstraint();
 71454 }
 71455 
 71456 if (1 === \count($constraints)) {
 71457 return $constraints[0];
 71458 }
 71459 
 71460 $optimized = self::optimizeConstraints($constraints, $conjunctive);
 71461 if ($optimized !== null) {
 71462 list($constraints, $conjunctive) = $optimized;
 71463 if (\count($constraints) === 1) {
 71464 return $constraints[0];
 71465 }
 71466 }
 71467 
 71468 return new self($constraints, $conjunctive);
 71469 }
 71470 
 71471 
 71472 
 71473 
 71474 
 71475 
 71476 
 71477 
 71478 private static function optimizeConstraints(array $constraints, $conjunctive)
 71479 {
 71480 
 71481 
 71482 
 71483 if (!$conjunctive) {
 71484 $left = $constraints[0];
 71485 $mergedConstraints = array();
 71486 $optimized = false;
 71487 for ($i = 1, $l = \count($constraints); $i < $l; $i++) {
 71488 $right = $constraints[$i];
 71489 if (
 71490 $left instanceof self
 71491 && $left->conjunctive
 71492 && $right instanceof self
 71493 && $right->conjunctive
 71494 && \count($left->constraints) === 2
 71495 && \count($right->constraints) === 2
 71496 && ($left0 = (string) $left->constraints[0])
 71497 && $left0[0] === '>' && $left0[1] === '='
 71498 && ($left1 = (string) $left->constraints[1])
 71499 && $left1[0] === '<'
 71500 && ($right0 = (string) $right->constraints[0])
 71501 && $right0[0] === '>' && $right0[1] === '='
 71502 && ($right1 = (string) $right->constraints[1])
 71503 && $right1[0] === '<'
 71504 && substr($left1, 2) === substr($right0, 3)
 71505 ) {
 71506 $optimized = true;
 71507 $left = new MultiConstraint(
 71508 array(
 71509 $left->constraints[0],
 71510 $right->constraints[1],
 71511 ),
 71512 true);
 71513 } else {
 71514 $mergedConstraints[] = $left;
 71515 $left = $right;
 71516 }
 71517 }
 71518 if ($optimized) {
 71519 $mergedConstraints[] = $left;
 71520 return array($mergedConstraints, false);
 71521 }
 71522 }
 71523 
 71524 
 71525 
 71526 return null;
 71527 }
 71528 
 71529 
 71530 
 71531 
 71532 private function extractBounds()
 71533 {
 71534 if (null !== $this->lowerBound) {
 71535 return;
 71536 }
 71537 
 71538 foreach ($this->constraints as $constraint) {
 71539 if (null === $this->lowerBound || null === $this->upperBound) {
 71540 $this->lowerBound = $constraint->getLowerBound();
 71541 $this->upperBound = $constraint->getUpperBound();
 71542 continue;
 71543 }
 71544 
 71545 if ($constraint->getLowerBound()->compareTo($this->lowerBound, $this->isConjunctive() ? '>' : '<')) {
 71546 $this->lowerBound = $constraint->getLowerBound();
 71547 }
 71548 
 71549 if ($constraint->getUpperBound()->compareTo($this->upperBound, $this->isConjunctive() ? '<' : '>')) {
 71550 $this->upperBound = $constraint->getUpperBound();
 71551 }
 71552 }
 71553 }
 71554 }
 71555 <?php
 71556 
 71557 
 71558 
 71559 
 71560 
 71561 
 71562 
 71563 
 71564 
 71565 
 71566 namespace Composer\Semver;
 71567 
 71568 use Composer\Semver\Constraint\Constraint;
 71569 
 71570 class Interval
 71571 {
 71572 
 71573 private $start;
 71574 
 71575 private $end;
 71576 
 71577 public function __construct(Constraint $start, Constraint $end)
 71578 {
 71579 $this->start = $start;
 71580 $this->end = $end;
 71581 }
 71582 
 71583 
 71584 
 71585 
 71586 public function getStart()
 71587 {
 71588 return $this->start;
 71589 }
 71590 
 71591 
 71592 
 71593 
 71594 public function getEnd()
 71595 {
 71596 return $this->end;
 71597 }
 71598 
 71599 
 71600 
 71601 
 71602 public static function fromZero()
 71603 {
 71604 static $zero;
 71605 
 71606 if (null === $zero) {
 71607 $zero = new Constraint('>=', '0.0.0.0-dev');
 71608 }
 71609 
 71610 return $zero;
 71611 }
 71612 
 71613 
 71614 
 71615 
 71616 public static function untilPositiveInfinity()
 71617 {
 71618 static $positiveInfinity;
 71619 
 71620 if (null === $positiveInfinity) {
 71621 $positiveInfinity = new Constraint('<', PHP_INT_MAX.'.0.0.0');
 71622 }
 71623 
 71624 return $positiveInfinity;
 71625 }
 71626 
 71627 
 71628 
 71629 
 71630 public static function any()
 71631 {
 71632 return new self(self::fromZero(), self::untilPositiveInfinity());
 71633 }
 71634 
 71635 
 71636 
 71637 
 71638 public static function anyDev()
 71639 {
 71640 
 71641 return array('names' => array(), 'exclude' => true);
 71642 }
 71643 
 71644 
 71645 
 71646 
 71647 public static function noDev()
 71648 {
 71649 
 71650 return array('names' => array(), 'exclude' => false);
 71651 }
 71652 }
 71653 <?php
 71654 
 71655 
 71656 
 71657 
 71658 
 71659 
 71660 
 71661 
 71662 
 71663 
 71664 namespace Composer\Semver;
 71665 
 71666 use Composer\Semver\Constraint\Constraint;
 71667 use Composer\Semver\Constraint\ConstraintInterface;
 71668 use Composer\Semver\Constraint\MatchAllConstraint;
 71669 use Composer\Semver\Constraint\MatchNoneConstraint;
 71670 use Composer\Semver\Constraint\MultiConstraint;
 71671 
 71672 
 71673 
 71674 
 71675 
 71676 
 71677 
 71678 
 71679 
 71680 
 71681 
 71682 
 71683 
 71684 class Intervals
 71685 {
 71686 
 71687 
 71688 
 71689 private static $intervalsCache = array();
 71690 
 71691 
 71692 
 71693 
 71694 private static $opSortOrder = array(
 71695 '>=' => -3,
 71696 '<' => -2,
 71697 '>' => 2,
 71698 '<=' => 3,
 71699 );
 71700 
 71701 
 71702 
 71703 
 71704 
 71705 
 71706 public static function clear()
 71707 {
 71708 self::$intervalsCache = array();
 71709 }
 71710 
 71711 
 71712 
 71713 
 71714 
 71715 
 71716 public static function isSubsetOf(ConstraintInterface $candidate, ConstraintInterface $constraint)
 71717 {
 71718 if ($constraint instanceof MatchAllConstraint) {
 71719 return true;
 71720 }
 71721 
 71722 if ($candidate instanceof MatchNoneConstraint || $constraint instanceof MatchNoneConstraint) {
 71723 return false;
 71724 }
 71725 
 71726 $intersectionIntervals = self::get(new MultiConstraint(array($candidate, $constraint), true));
 71727 $candidateIntervals = self::get($candidate);
 71728 if (\count($intersectionIntervals['numeric']) !== \count($candidateIntervals['numeric'])) {
 71729 return false;
 71730 }
 71731 
 71732 foreach ($intersectionIntervals['numeric'] as $index => $interval) {
 71733 if (!isset($candidateIntervals['numeric'][$index])) {
 71734 return false;
 71735 }
 71736 
 71737 if ((string) $candidateIntervals['numeric'][$index]->getStart() !== (string) $interval->getStart()) {
 71738 return false;
 71739 }
 71740 
 71741 if ((string) $candidateIntervals['numeric'][$index]->getEnd() !== (string) $interval->getEnd()) {
 71742 return false;
 71743 }
 71744 }
 71745 
 71746 if ($intersectionIntervals['branches']['exclude'] !== $candidateIntervals['branches']['exclude']) {
 71747 return false;
 71748 }
 71749 if (\count($intersectionIntervals['branches']['names']) !== \count($candidateIntervals['branches']['names'])) {
 71750 return false;
 71751 }
 71752 foreach ($intersectionIntervals['branches']['names'] as $index => $name) {
 71753 if ($name !== $candidateIntervals['branches']['names'][$index]) {
 71754 return false;
 71755 }
 71756 }
 71757 
 71758 return true;
 71759 }
 71760 
 71761 
 71762 
 71763 
 71764 
 71765 
 71766 public static function haveIntersections(ConstraintInterface $a, ConstraintInterface $b)
 71767 {
 71768 if ($a instanceof MatchAllConstraint || $b instanceof MatchAllConstraint) {
 71769 return true;
 71770 }
 71771 
 71772 if ($a instanceof MatchNoneConstraint || $b instanceof MatchNoneConstraint) {
 71773 return false;
 71774 }
 71775 
 71776 $intersectionIntervals = self::generateIntervals(new MultiConstraint(array($a, $b), true), true);
 71777 
 71778 return \count($intersectionIntervals['numeric']) > 0 || $intersectionIntervals['branches']['exclude'] || \count($intersectionIntervals['branches']['names']) > 0;
 71779 }
 71780 
 71781 
 71782 
 71783 
 71784 
 71785 
 71786 
 71787 
 71788 
 71789 
 71790 
 71791 public static function compactConstraint(ConstraintInterface $constraint)
 71792 {
 71793 if (!$constraint instanceof MultiConstraint) {
 71794 return $constraint;
 71795 }
 71796 
 71797 $intervals = self::generateIntervals($constraint);
 71798 $constraints = array();
 71799 $hasNumericMatchAll = false;
 71800 
 71801 if (\count($intervals['numeric']) === 1 && (string) $intervals['numeric'][0]->getStart() === (string) Interval::fromZero() && (string) $intervals['numeric'][0]->getEnd() === (string) Interval::untilPositiveInfinity()) {
 71802 $constraints[] = $intervals['numeric'][0]->getStart();
 71803 $hasNumericMatchAll = true;
 71804 } else {
 71805 $unEqualConstraints = array();
 71806 for ($i = 0, $count = \count($intervals['numeric']); $i < $count; $i++) {
 71807 $interval = $intervals['numeric'][$i];
 71808 
 71809 
 71810 
 71811 
 71812 
 71813 if ($interval->getEnd()->getOperator() === '<' && $i+1 < $count) {
 71814 $nextInterval = $intervals['numeric'][$i+1];
 71815 if ($interval->getEnd()->getVersion() === $nextInterval->getStart()->getVersion() && $nextInterval->getStart()->getOperator() === '>') {
 71816 
 71817 
 71818 
 71819 if (\count($unEqualConstraints) === 0 && (string) $interval->getStart() !== (string) Interval::fromZero()) {
 71820 $unEqualConstraints[] = $interval->getStart();
 71821 }
 71822 $unEqualConstraints[] = new Constraint('!=', $interval->getEnd()->getVersion());
 71823 continue;
 71824 }
 71825 }
 71826 
 71827 if (\count($unEqualConstraints) > 0) {
 71828 
 71829 if ((string) $interval->getEnd() !== (string) Interval::untilPositiveInfinity()) {
 71830 $unEqualConstraints[] = $interval->getEnd();
 71831 }
 71832 
 71833 
 71834 if (\count($unEqualConstraints) > 1) {
 71835 $constraints[] = new MultiConstraint($unEqualConstraints, true);
 71836 } else {
 71837 $constraints[] = $unEqualConstraints[0];
 71838 }
 71839 
 71840 $unEqualConstraints = array();
 71841 continue;
 71842 }
 71843 
 71844 
 71845 if ($interval->getStart()->getVersion() === $interval->getEnd()->getVersion() && $interval->getStart()->getOperator() === '>=' && $interval->getEnd()->getOperator() === '<=') {
 71846 $constraints[] = new Constraint('==', $interval->getStart()->getVersion());
 71847 continue;
 71848 }
 71849 
 71850 if ((string) $interval->getStart() === (string) Interval::fromZero()) {
 71851 $constraints[] = $interval->getEnd();
 71852 } elseif ((string) $interval->getEnd() === (string) Interval::untilPositiveInfinity()) {
 71853 $constraints[] = $interval->getStart();
 71854 } else {
 71855 $constraints[] = new MultiConstraint(array($interval->getStart(), $interval->getEnd()), true);
 71856 }
 71857 }
 71858 }
 71859 
 71860 $devConstraints = array();
 71861 
 71862 if (0 === \count($intervals['branches']['names'])) {
 71863 if ($intervals['branches']['exclude']) {
 71864 if ($hasNumericMatchAll) {
 71865 return new MatchAllConstraint;
 71866 }
 71867 
 71868 }
 71869 } else {
 71870 foreach ($intervals['branches']['names'] as $branchName) {
 71871 if ($intervals['branches']['exclude']) {
 71872 $devConstraints[] = new Constraint('!=', $branchName);
 71873 } else {
 71874 $devConstraints[] = new Constraint('==', $branchName);
 71875 }
 71876 }
 71877 
 71878 
 71879 
 71880 if ($intervals['branches']['exclude']) {
 71881 if (\count($constraints) > 1) {
 71882 return new MultiConstraint(array_merge(
 71883 array(new MultiConstraint($constraints, false)),
 71884 $devConstraints
 71885 ), true);
 71886 }
 71887 
 71888 if (\count($constraints) === 1 && (string)$constraints[0] === (string)Interval::fromZero()) {
 71889 if (\count($devConstraints) > 1) {
 71890 return new MultiConstraint($devConstraints, true);
 71891 }
 71892 return $devConstraints[0];
 71893 }
 71894 
 71895 return new MultiConstraint(array_merge($constraints, $devConstraints), true);
 71896 }
 71897 
 71898 
 71899 
 71900 $constraints = array_merge($constraints, $devConstraints);
 71901 }
 71902 
 71903 if (\count($constraints) > 1) {
 71904 return new MultiConstraint($constraints, false);
 71905 }
 71906 
 71907 if (\count($constraints) === 1) {
 71908 return $constraints[0];
 71909 }
 71910 
 71911 return new MatchNoneConstraint;
 71912 }
 71913 
 71914 
 71915 
 71916 
 71917 
 71918 
 71919 
 71920 
 71921 
 71922 
 71923 
 71924 public static function get(ConstraintInterface $constraint)
 71925 {
 71926 $key = (string) $constraint;
 71927 
 71928 if (!isset(self::$intervalsCache[$key])) {
 71929 self::$intervalsCache[$key] = self::generateIntervals($constraint);
 71930 }
 71931 
 71932 return self::$intervalsCache[$key];
 71933 }
 71934 
 71935 
 71936 
 71937 
 71938 
 71939 
 71940 private static function generateIntervals(ConstraintInterface $constraint, $stopOnFirstValidInterval = false)
 71941 {
 71942 if ($constraint instanceof MatchAllConstraint) {
 71943 return array('numeric' => array(new Interval(Interval::fromZero(), Interval::untilPositiveInfinity())), 'branches' => Interval::anyDev());
 71944 }
 71945 
 71946 if ($constraint instanceof MatchNoneConstraint) {
 71947 return array('numeric' => array(), 'branches' => array('names' => array(), 'exclude' => false));
 71948 }
 71949 
 71950 if ($constraint instanceof Constraint) {
 71951 return self::generateSingleConstraintIntervals($constraint);
 71952 }
 71953 
 71954 if (!$constraint instanceof MultiConstraint) {
 71955 throw new \UnexpectedValueException('The constraint passed in should be an MatchAllConstraint, Constraint or MultiConstraint instance, got '.\get_class($constraint).'.');
 71956 }
 71957 
 71958 $constraints = $constraint->getConstraints();
 71959 
 71960 $numericGroups = array();
 71961 $constraintBranches = array();
 71962 foreach ($constraints as $c) {
 71963 $res = self::get($c);
 71964 $numericGroups[] = $res['numeric'];
 71965 $constraintBranches[] = $res['branches'];
 71966 }
 71967 
 71968 if ($constraint->isDisjunctive()) {
 71969 $branches = Interval::noDev();
 71970 foreach ($constraintBranches as $b) {
 71971 if ($b['exclude']) {
 71972 if ($branches['exclude']) {
 71973 
 71974 
 71975 $branches['names'] = array_intersect($branches['names'], $b['names']);
 71976 } else {
 71977 
 71978 
 71979 $branches['exclude'] = true;
 71980 $branches['names'] = array_diff($b['names'], $branches['names']);
 71981 }
 71982 } else {
 71983 if ($branches['exclude']) {
 71984 
 71985 
 71986 $branches['names'] = array_diff($branches['names'], $b['names']);
 71987 } else {
 71988 
 71989 
 71990 $branches['names'] = array_merge($branches['names'], $b['names']);
 71991 }
 71992 }
 71993 }
 71994 } else {
 71995 $branches = Interval::anyDev();
 71996 foreach ($constraintBranches as $b) {
 71997 if ($b['exclude']) {
 71998 if ($branches['exclude']) {
 71999 
 72000 
 72001 $branches['names'] = array_merge($branches['names'], $b['names']);
 72002 } else {
 72003 
 72004 
 72005 $branches['names'] = array_diff($branches['names'], $b['names']);
 72006 }
 72007 } else {
 72008 if ($branches['exclude']) {
 72009 
 72010 
 72011 $branches['names'] = array_diff($b['names'], $branches['names']);
 72012 $branches['exclude'] = false;
 72013 } else {
 72014 
 72015 
 72016 $branches['names'] = array_intersect($branches['names'], $b['names']);
 72017 }
 72018 }
 72019 }
 72020 }
 72021 
 72022 $branches['names'] = array_unique($branches['names']);
 72023 
 72024 if (\count($numericGroups) === 1) {
 72025 return array('numeric' => $numericGroups[0], 'branches' => $branches);
 72026 }
 72027 
 72028 $borders = array();
 72029 foreach ($numericGroups as $group) {
 72030 foreach ($group as $interval) {
 72031 $borders[] = array('version' => $interval->getStart()->getVersion(), 'operator' => $interval->getStart()->getOperator(), 'side' => 'start');
 72032 $borders[] = array('version' => $interval->getEnd()->getVersion(), 'operator' => $interval->getEnd()->getOperator(), 'side' => 'end');
 72033 }
 72034 }
 72035 
 72036 $opSortOrder = self::$opSortOrder;
 72037 usort($borders, function ($a, $b) use ($opSortOrder) {
 72038 $order = version_compare($a['version'], $b['version']);
 72039 if ($order === 0) {
 72040 return $opSortOrder[$a['operator']] - $opSortOrder[$b['operator']];
 72041 }
 72042 
 72043 return $order;
 72044 });
 72045 
 72046 $activeIntervals = 0;
 72047 $intervals = array();
 72048 $index = 0;
 72049 $activationThreshold = $constraint->isConjunctive() ? \count($numericGroups) : 1;
 72050 $start = null;
 72051 foreach ($borders as $border) {
 72052 if ($border['side'] === 'start') {
 72053 $activeIntervals++;
 72054 } else {
 72055 $activeIntervals--;
 72056 }
 72057 if (!$start && $activeIntervals >= $activationThreshold) {
 72058 $start = new Constraint($border['operator'], $border['version']);
 72059 } elseif ($start && $activeIntervals < $activationThreshold) {
 72060 
 72061 if (
 72062 version_compare($start->getVersion(), $border['version'], '=')
 72063 && (
 72064 ($start->getOperator() === '>' && $border['operator'] === '<=')
 72065 || ($start->getOperator() === '>=' && $border['operator'] === '<')
 72066 )
 72067 ) {
 72068 unset($intervals[$index]);
 72069 } else {
 72070 $intervals[$index] = new Interval($start, new Constraint($border['operator'], $border['version']));
 72071 $index++;
 72072 
 72073 if ($stopOnFirstValidInterval) {
 72074 break;
 72075 }
 72076 }
 72077 
 72078 $start = null;
 72079 }
 72080 }
 72081 
 72082 return array('numeric' => $intervals, 'branches' => $branches);
 72083 }
 72084 
 72085 
 72086 
 72087 
 72088 private static function generateSingleConstraintIntervals(Constraint $constraint)
 72089 {
 72090 $op = $constraint->getOperator();
 72091 
 72092 
 72093 if (strpos($constraint->getVersion(), 'dev-') === 0) {
 72094 $intervals = array();
 72095 $branches = array('names' => array(), 'exclude' => false);
 72096 
 72097 
 72098 if ($op === '!=') {
 72099 $intervals[] = new Interval(Interval::fromZero(), Interval::untilPositiveInfinity());
 72100 $branches = array('names' => array($constraint->getVersion()), 'exclude' => true);
 72101 } elseif ($op === '==') {
 72102 $branches['names'][] = $constraint->getVersion();
 72103 }
 72104 
 72105 return array(
 72106 'numeric' => $intervals,
 72107 'branches' => $branches,
 72108 );
 72109 }
 72110 
 72111 if ($op[0] === '>') { 
 72112 return array('numeric' => array(new Interval($constraint, Interval::untilPositiveInfinity())), 'branches' => Interval::noDev());
 72113 }
 72114 if ($op[0] === '<') { 
 72115 return array('numeric' => array(new Interval(Interval::fromZero(), $constraint)), 'branches' => Interval::noDev());
 72116 }
 72117 if ($op === '!=') {
 72118 
 72119 return array('numeric' => array(
 72120 new Interval(Interval::fromZero(), new Constraint('<', $constraint->getVersion())),
 72121 new Interval(new Constraint('>', $constraint->getVersion()), Interval::untilPositiveInfinity()),
 72122 ), 'branches' => Interval::anyDev());
 72123 }
 72124 
 72125 
 72126 return array('numeric' => array(
 72127 new Interval(new Constraint('>=', $constraint->getVersion()), new Constraint('<=', $constraint->getVersion())),
 72128 ), 'branches' => Interval::noDev());
 72129 }
 72130 }
 72131 <?php
 72132 
 72133 
 72134 
 72135 
 72136 
 72137 
 72138 
 72139 
 72140 
 72141 
 72142 namespace Composer\Semver;
 72143 
 72144 use Composer\Semver\Constraint\Constraint;
 72145 
 72146 class Semver
 72147 {
 72148 const SORT_ASC = 1;
 72149 const SORT_DESC = -1;
 72150 
 72151 
 72152 private static $versionParser;
 72153 
 72154 
 72155 
 72156 
 72157 
 72158 
 72159 
 72160 
 72161 
 72162 public static function satisfies($version, $constraints)
 72163 {
 72164 if (null === self::$versionParser) {
 72165 self::$versionParser = new VersionParser();
 72166 }
 72167 
 72168 $versionParser = self::$versionParser;
 72169 $provider = new Constraint('==', $versionParser->normalize($version));
 72170 $parsedConstraints = $versionParser->parseConstraints($constraints);
 72171 
 72172 return $parsedConstraints->matches($provider);
 72173 }
 72174 
 72175 
 72176 
 72177 
 72178 
 72179 
 72180 
 72181 
 72182 
 72183 public static function satisfiedBy(array $versions, $constraints)
 72184 {
 72185 $versions = array_filter($versions, function ($version) use ($constraints) {
 72186 return Semver::satisfies($version, $constraints);
 72187 });
 72188 
 72189 return array_values($versions);
 72190 }
 72191 
 72192 
 72193 
 72194 
 72195 
 72196 
 72197 
 72198 
 72199 public static function sort(array $versions)
 72200 {
 72201 return self::usort($versions, self::SORT_ASC);
 72202 }
 72203 
 72204 
 72205 
 72206 
 72207 
 72208 
 72209 
 72210 
 72211 public static function rsort(array $versions)
 72212 {
 72213 return self::usort($versions, self::SORT_DESC);
 72214 }
 72215 
 72216 
 72217 
 72218 
 72219 
 72220 
 72221 
 72222 private static function usort(array $versions, $direction)
 72223 {
 72224 if (null === self::$versionParser) {
 72225 self::$versionParser = new VersionParser();
 72226 }
 72227 
 72228 $versionParser = self::$versionParser;
 72229 $normalized = array();
 72230 
 72231 
 72232 
 72233 foreach ($versions as $key => $version) {
 72234 $normalizedVersion = $versionParser->normalize($version);
 72235 $normalizedVersion = $versionParser->normalizeDefaultBranch($normalizedVersion);
 72236 $normalized[] = array($normalizedVersion, $key);
 72237 }
 72238 
 72239 usort($normalized, function (array $left, array $right) use ($direction) {
 72240 if ($left[0] === $right[0]) {
 72241 return 0;
 72242 }
 72243 
 72244 if (Comparator::lessThan($left[0], $right[0])) {
 72245 return -$direction;
 72246 }
 72247 
 72248 return $direction;
 72249 });
 72250 
 72251 
 72252 $sorted = array();
 72253 foreach ($normalized as $item) {
 72254 $sorted[] = $versions[$item[1]];
 72255 }
 72256 
 72257 return $sorted;
 72258 }
 72259 }
 72260 <?php
 72261 
 72262 
 72263 
 72264 
 72265 
 72266 
 72267 
 72268 
 72269 
 72270 
 72271 namespace Composer\Semver;
 72272 
 72273 use Composer\Semver\Constraint\ConstraintInterface;
 72274 use Composer\Semver\Constraint\MatchAllConstraint;
 72275 use Composer\Semver\Constraint\MultiConstraint;
 72276 use Composer\Semver\Constraint\Constraint;
 72277 
 72278 
 72279 
 72280 
 72281 
 72282 
 72283 class VersionParser
 72284 {
 72285 
 72286 
 72287 
 72288 
 72289 
 72290 
 72291 
 72292 
 72293 
 72294 
 72295 
 72296 
 72297 
 72298 private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\d+)*+)?)?([.-]?dev)?';
 72299 
 72300 
 72301 private static $stabilitiesRegex = 'stable|RC|beta|alpha|dev';
 72302 
 72303 
 72304 
 72305 
 72306 
 72307 
 72308 
 72309 
 72310 
 72311 public static function parseStability($version)
 72312 {
 72313 $version = (string) preg_replace('{#.+$}', '', $version);
 72314 
 72315 if (strpos($version, 'dev-') === 0 || '-dev' === substr($version, -4)) {
 72316 return 'dev';
 72317 }
 72318 
 72319 preg_match('{' . self::$modifierRegex . '(?:\+.*)?$}i', strtolower($version), $match);
 72320 
 72321 if (!empty($match[3])) {
 72322 return 'dev';
 72323 }
 72324 
 72325 if (!empty($match[1])) {
 72326 if ('beta' === $match[1] || 'b' === $match[1]) {
 72327 return 'beta';
 72328 }
 72329 if ('alpha' === $match[1] || 'a' === $match[1]) {
 72330 return 'alpha';
 72331 }
 72332 if ('rc' === $match[1]) {
 72333 return 'RC';
 72334 }
 72335 }
 72336 
 72337 return 'stable';
 72338 }
 72339 
 72340 
 72341 
 72342 
 72343 
 72344 
 72345 public static function normalizeStability($stability)
 72346 {
 72347 $stability = strtolower($stability);
 72348 
 72349 return $stability === 'rc' ? 'RC' : $stability;
 72350 }
 72351 
 72352 
 72353 
 72354 
 72355 
 72356 
 72357 
 72358 
 72359 
 72360 
 72361 
 72362 public function normalize($version, $fullVersion = null)
 72363 {
 72364 $version = trim($version);
 72365 $origVersion = $version;
 72366 if (null === $fullVersion) {
 72367 $fullVersion = $version;
 72368 }
 72369 
 72370 
 72371 if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $version, $match)) {
 72372 $version = $match[1];
 72373 }
 72374 
 72375 
 72376 if (preg_match('{@(?:' . self::$stabilitiesRegex . ')$}i', $version, $match)) {
 72377 $version = substr($version, 0, strlen($version) - strlen($match[0]));
 72378 }
 72379 
 72380 
 72381 if (\in_array($version, array('master', 'trunk', 'default'), true)) {
 72382 $version = 'dev-' . $version;
 72383 }
 72384 
 72385 
 72386 if (stripos($version, 'dev-') === 0) {
 72387 return 'dev-' . substr($version, 4);
 72388 }
 72389 
 72390 
 72391 if (preg_match('{^([^,\s+]++)\+[^\s]++$}', $version, $match)) {
 72392 $version = $match[1];
 72393 }
 72394 
 72395 
 72396 if (preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
 72397 $version = $matches[1]
 72398 . (!empty($matches[2]) ? $matches[2] : '.0')
 72399 . (!empty($matches[3]) ? $matches[3] : '.0')
 72400 . (!empty($matches[4]) ? $matches[4] : '.0');
 72401 $index = 5;
 72402 
 72403 } elseif (preg_match('{^v?(\d{4}(?:[.:-]?\d{2}){1,6}(?:[.:-]?\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
 72404 $version = preg_replace('{\D}', '.', $matches[1]);
 72405 $index = 2;
 72406 }
 72407 
 72408 
 72409 if (isset($index)) {
 72410 if (!empty($matches[$index])) {
 72411 if ('stable' === $matches[$index]) {
 72412 return $version;
 72413 }
 72414 $version .= '-' . $this->expandStability($matches[$index]) . (isset($matches[$index + 1]) && '' !== $matches[$index + 1] ? ltrim($matches[$index + 1], '.-') : '');
 72415 }
 72416 
 72417 if (!empty($matches[$index + 2])) {
 72418 $version .= '-dev';
 72419 }
 72420 
 72421 return $version;
 72422 }
 72423 
 72424 
 72425 if (preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
 72426 try {
 72427 $normalized = $this->normalizeBranch($match[1]);
 72428 
 72429 
 72430 
 72431 if (strpos($normalized, 'dev-') === false) {
 72432 return $normalized;
 72433 }
 72434 } catch (\Exception $e) {
 72435 }
 72436 }
 72437 
 72438 $extraMessage = '';
 72439 if (preg_match('{ +as +' . preg_quote($version) . '(?:@(?:'.self::$stabilitiesRegex.'))?$}', $fullVersion)) {
 72440 $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version';
 72441 } elseif (preg_match('{^' . preg_quote($version) . '(?:@(?:'.self::$stabilitiesRegex.'))? +as +}', $fullVersion)) {
 72442 $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
 72443 }
 72444 
 72445 throw new \UnexpectedValueException('Invalid version string "' . $origVersion . '"' . $extraMessage);
 72446 }
 72447 
 72448 
 72449 
 72450 
 72451 
 72452 
 72453 
 72454 
 72455 public function parseNumericAliasPrefix($branch)
 72456 {
 72457 if (preg_match('{^(?P<version>(\d++\\.)*\d++)(?:\.x)?-dev$}i', $branch, $matches)) {
 72458 return $matches['version'] . '.';
 72459 }
 72460 
 72461 return false;
 72462 }
 72463 
 72464 
 72465 
 72466 
 72467 
 72468 
 72469 
 72470 
 72471 public function normalizeBranch($name)
 72472 {
 72473 $name = trim($name);
 72474 
 72475 if (preg_match('{^v?(\d++)(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?(\.(?:\d++|[xX*]))?$}i', $name, $matches)) {
 72476 $version = '';
 72477 for ($i = 1; $i < 5; ++$i) {
 72478 $version .= isset($matches[$i]) ? str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
 72479 }
 72480 
 72481 return str_replace('x', '9999999', $version) . '-dev';
 72482 }
 72483 
 72484 return 'dev-' . $name;
 72485 }
 72486 
 72487 
 72488 
 72489 
 72490 
 72491 
 72492 
 72493 
 72494 public function normalizeDefaultBranch($name)
 72495 {
 72496 if ($name === 'dev-master' || $name === 'dev-default' || $name === 'dev-trunk') {
 72497 return '9999999-dev';
 72498 }
 72499 
 72500 return $name;
 72501 }
 72502 
 72503 
 72504 
 72505 
 72506 
 72507 
 72508 
 72509 
 72510 public function parseConstraints($constraints)
 72511 {
 72512 $prettyConstraint = $constraints;
 72513 
 72514 $orConstraints = preg_split('{\s*\|\|?\s*}', trim($constraints));
 72515 if (false === $orConstraints) {
 72516 throw new \RuntimeException('Failed to preg_split string: '.$constraints);
 72517 }
 72518 $orGroups = array();
 72519 
 72520 foreach ($orConstraints as $constraints) {
 72521 $andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
 72522 if (false === $andConstraints) {
 72523 throw new \RuntimeException('Failed to preg_split string: '.$constraints);
 72524 }
 72525 if (\count($andConstraints) > 1) {
 72526 $constraintObjects = array();
 72527 foreach ($andConstraints as $constraint) {
 72528 foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
 72529 $constraintObjects[] = $parsedConstraint;
 72530 }
 72531 }
 72532 } else {
 72533 $constraintObjects = $this->parseConstraint($andConstraints[0]);
 72534 }
 72535 
 72536 if (1 === \count($constraintObjects)) {
 72537 $constraint = $constraintObjects[0];
 72538 } else {
 72539 $constraint = new MultiConstraint($constraintObjects);
 72540 }
 72541 
 72542 $orGroups[] = $constraint;
 72543 }
 72544 
 72545 $constraint = MultiConstraint::create($orGroups, false);
 72546 
 72547 $constraint->setPrettyString($prettyConstraint);
 72548 
 72549 return $constraint;
 72550 }
 72551 
 72552 
 72553 
 72554 
 72555 
 72556 
 72557 
 72558 
 72559 
 72560 
 72561 private function parseConstraint($constraint)
 72562 {
 72563 
 72564 if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $constraint, $match)) {
 72565 $constraint = $match[1];
 72566 }
 72567 
 72568 
 72569 if (preg_match('{^([^,\s]*?)@(' . self::$stabilitiesRegex . ')$}i', $constraint, $match)) {
 72570 $constraint = '' !== $match[1] ? $match[1] : '*';
 72571 if ($match[2] !== 'stable') {
 72572 $stabilityModifier = $match[2];
 72573 }
 72574 }
 72575 
 72576 
 72577 if (preg_match('{^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#.+$}i', $constraint, $match)) {
 72578 $constraint = $match[1];
 72579 }
 72580 
 72581 if (preg_match('{^(v)?[xX*](\.[xX*])*$}i', $constraint, $match)) {
 72582 if (!empty($match[1]) || !empty($match[2])) {
 72583 return array(new Constraint('>=', '0.0.0.0-dev'));
 72584 }
 72585 
 72586 return array(new MatchAllConstraint());
 72587 }
 72588 
 72589 $versionRegex = 'v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.(\d++))?(?:' . self::$modifierRegex . '|\.([xX*][.-]?dev))(?:\+[^\s]+)?';
 72590 
 72591 
 72592 
 72593 
 72594 
 72595 
 72596 if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
 72597 if (strpos($constraint, '~>') === 0) {
 72598 throw new \UnexpectedValueException(
 72599 'Could not parse version constraint ' . $constraint . ': ' .
 72600 'Invalid operator "~>", you probably meant to use the "~" operator'
 72601 );
 72602 }
 72603 
 72604 
 72605 if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
 72606 $position = 4;
 72607 } elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
 72608 $position = 3;
 72609 } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
 72610 $position = 2;
 72611 } else {
 72612 $position = 1;
 72613 }
 72614 
 72615 
 72616 if (!empty($matches[8])) {
 72617 $position++;
 72618 }
 72619 
 72620 
 72621 $stabilitySuffix = '';
 72622 if (empty($matches[5]) && empty($matches[7]) && empty($matches[8])) {
 72623 $stabilitySuffix .= '-dev';
 72624 }
 72625 
 72626 $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
 72627 $lowerBound = new Constraint('>=', $lowVersion);
 72628 
 72629 
 72630 
 72631 $highPosition = max(1, $position - 1);
 72632 $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
 72633 $upperBound = new Constraint('<', $highVersion);
 72634 
 72635 return array(
 72636 $lowerBound,
 72637 $upperBound,
 72638 );
 72639 }
 72640 
 72641 
 72642 
 72643 
 72644 
 72645 
 72646 if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) {
 72647 
 72648 if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
 72649 $position = 1;
 72650 } elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
 72651 $position = 2;
 72652 } else {
 72653 $position = 3;
 72654 }
 72655 
 72656 
 72657 $stabilitySuffix = '';
 72658 if (empty($matches[5]) && empty($matches[7]) && empty($matches[8])) {
 72659 $stabilitySuffix .= '-dev';
 72660 }
 72661 
 72662 $lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
 72663 $lowerBound = new Constraint('>=', $lowVersion);
 72664 
 72665 
 72666 
 72667 $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
 72668 $upperBound = new Constraint('<', $highVersion);
 72669 
 72670 return array(
 72671 $lowerBound,
 72672 $upperBound,
 72673 );
 72674 }
 72675 
 72676 
 72677 
 72678 
 72679 
 72680 if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) {
 72681 if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
 72682 $position = 3;
 72683 } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
 72684 $position = 2;
 72685 } else {
 72686 $position = 1;
 72687 }
 72688 
 72689 $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
 72690 $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
 72691 
 72692 if ($lowVersion === '0.0.0.0-dev') {
 72693 return array(new Constraint('<', $highVersion));
 72694 }
 72695 
 72696 return array(
 72697 new Constraint('>=', $lowVersion),
 72698 new Constraint('<', $highVersion),
 72699 );
 72700 }
 72701 
 72702 
 72703 
 72704 
 72705 
 72706 
 72707 
 72708 if (preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
 72709 
 72710 $lowStabilitySuffix = '';
 72711 if (empty($matches[6]) && empty($matches[8]) && empty($matches[9])) {
 72712 $lowStabilitySuffix = '-dev';
 72713 }
 72714 
 72715 $lowVersion = $this->normalize($matches['from']);
 72716 $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);
 72717 
 72718 $empty = function ($x) {
 72719 return ($x === 0 || $x === '0') ? false : empty($x);
 72720 };
 72721 
 72722 if ((!$empty($matches[12]) && !$empty($matches[13])) || !empty($matches[15]) || !empty($matches[17]) || !empty($matches[18])) {
 72723 $highVersion = $this->normalize($matches['to']);
 72724 $upperBound = new Constraint('<=', $highVersion);
 72725 } else {
 72726 $highMatch = array('', $matches[11], $matches[12], $matches[13], $matches[14]);
 72727 
 72728 
 72729 $this->normalize($matches['to']);
 72730 
 72731 $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[12]) ? 1 : 2, 1) . '-dev';
 72732 $upperBound = new Constraint('<', $highVersion);
 72733 }
 72734 
 72735 return array(
 72736 $lowerBound,
 72737 $upperBound,
 72738 );
 72739 }
 72740 
 72741 
 72742 if (preg_match('{^(<>|!=|>=?|<=?|==?)?\s*(.*)}', $constraint, $matches)) {
 72743 try {
 72744 try {
 72745 $version = $this->normalize($matches[2]);
 72746 } catch (\UnexpectedValueException $e) {
 72747 
 72748 
 72749 if (substr($matches[2], -4) === '-dev' && preg_match('{^[0-9a-zA-Z-./]+$}', $matches[2])) {
 72750 $version = $this->normalize('dev-'.substr($matches[2], 0, -4));
 72751 } else {
 72752 throw $e;
 72753 }
 72754 }
 72755 
 72756 $op = $matches[1] ?: '=';
 72757 
 72758 if ($op !== '==' && $op !== '=' && !empty($stabilityModifier) && self::parseStability($version) === 'stable') {
 72759 $version .= '-' . $stabilityModifier;
 72760 } elseif ('<' === $op || '>=' === $op) {
 72761 if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
 72762 if (strpos($matches[2], 'dev-') !== 0) {
 72763 $version .= '-dev';
 72764 }
 72765 }
 72766 }
 72767 
 72768 return array(new Constraint($matches[1] ?: '=', $version));
 72769 } catch (\Exception $e) {
 72770 }
 72771 }
 72772 
 72773 $message = 'Could not parse version constraint ' . $constraint;
 72774 if (isset($e)) {
 72775 $message .= ': ' . $e->getMessage();
 72776 }
 72777 
 72778 throw new \UnexpectedValueException($message);
 72779 }
 72780 
 72781 
 72782 
 72783 
 72784 
 72785 
 72786 
 72787 
 72788 
 72789 
 72790 
 72791 
 72792 
 72793 
 72794 
 72795 private function manipulateVersionString(array $matches, $position, $increment = 0, $pad = '0')
 72796 {
 72797 for ($i = 4; $i > 0; --$i) {
 72798 if ($i > $position) {
 72799 $matches[$i] = $pad;
 72800 } elseif ($i === $position && $increment) {
 72801 $matches[$i] += $increment;
 72802 
 72803 if ($matches[$i] < 0) {
 72804 $matches[$i] = $pad;
 72805 --$position;
 72806 
 72807 
 72808 if ($i === 1) {
 72809 return null;
 72810 }
 72811 }
 72812 }
 72813 }
 72814 
 72815 return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
 72816 }
 72817 
 72818 
 72819 
 72820 
 72821 
 72822 
 72823 
 72824 
 72825 private function expandStability($stability)
 72826 {
 72827 $stability = strtolower($stability);
 72828 
 72829 switch ($stability) {
 72830 case 'a':
 72831 return 'alpha';
 72832 case 'b':
 72833 return 'beta';
 72834 case 'p':
 72835 case 'pl':
 72836 return 'patch';
 72837 case 'rc':
 72838 return 'RC';
 72839 default:
 72840 return $stability;
 72841 }
 72842 }
 72843 }
 72844 
 72845 Copyright (C) 2015 Composer
 72846 
 72847 Permission is hereby granted, free of charge, to any person obtaining a copy of
 72848 this software and associated documentation files (the "Software"), to deal in
 72849 the Software without restriction, including without limitation the rights to
 72850 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 72851 of the Software, and to permit persons to whom the Software is furnished to do
 72852 so, subject to the following conditions:
 72853 
 72854 The above copyright notice and this permission notice shall be included in all
 72855 copies or substantial portions of the Software.
 72856 
 72857 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 72858 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 72859 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 72860 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 72861 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 72862 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 72863 SOFTWARE.
 72864 
 72865 {
 72866     "389-exception": [
 72867         "389 Directory Server Exception"
 72868     ],
 72869     "Autoconf-exception-2.0": [
 72870         "Autoconf exception 2.0"
 72871     ],
 72872     "Autoconf-exception-3.0": [
 72873         "Autoconf exception 3.0"
 72874     ],
 72875     "Bison-exception-2.2": [
 72876         "Bison exception 2.2"
 72877     ],
 72878     "Bootloader-exception": [
 72879         "Bootloader Distribution Exception"
 72880     ],
 72881     "Classpath-exception-2.0": [
 72882         "Classpath exception 2.0"
 72883     ],
 72884     "CLISP-exception-2.0": [
 72885         "CLISP exception 2.0"
 72886     ],
 72887     "DigiRule-FOSS-exception": [
 72888         "DigiRule FOSS License Exception"
 72889     ],
 72890     "eCos-exception-2.0": [
 72891         "eCos exception 2.0"
 72892     ],
 72893     "Fawkes-Runtime-exception": [
 72894         "Fawkes Runtime Exception"
 72895     ],
 72896     "FLTK-exception": [
 72897         "FLTK exception"
 72898     ],
 72899     "Font-exception-2.0": [
 72900         "Font exception 2.0"
 72901     ],
 72902     "freertos-exception-2.0": [
 72903         "FreeRTOS Exception 2.0"
 72904     ],
 72905     "GCC-exception-2.0": [
 72906         "GCC Runtime Library exception 2.0"
 72907     ],
 72908     "GCC-exception-3.1": [
 72909         "GCC Runtime Library exception 3.1"
 72910     ],
 72911     "gnu-javamail-exception": [
 72912         "GNU JavaMail exception"
 72913     ],
 72914     "GPL-3.0-linking-exception": [
 72915         "GPL-3.0 Linking Exception"
 72916     ],
 72917     "GPL-3.0-linking-source-exception": [
 72918         "GPL-3.0 Linking Exception (with Corresponding Source)"
 72919     ],
 72920     "GPL-CC-1.0": [
 72921         "GPL Cooperation Commitment 1.0"
 72922     ],
 72923     "i2p-gpl-java-exception": [
 72924         "i2p GPL+Java Exception"
 72925     ],
 72926     "LGPL-3.0-linking-exception": [
 72927         "LGPL-3.0 Linking Exception"
 72928     ],
 72929     "Libtool-exception": [
 72930         "Libtool Exception"
 72931     ],
 72932     "Linux-syscall-note": [
 72933         "Linux Syscall Note"
 72934     ],
 72935     "LLVM-exception": [
 72936         "LLVM Exception"
 72937     ],
 72938     "LZMA-exception": [
 72939         "LZMA exception"
 72940     ],
 72941     "mif-exception": [
 72942         "Macros and Inline Functions Exception"
 72943     ],
 72944     "Nokia-Qt-exception-1.1": [
 72945         "Nokia Qt LGPL exception 1.1"
 72946     ],
 72947     "OCaml-LGPL-linking-exception": [
 72948         "OCaml LGPL Linking Exception"
 72949     ],
 72950     "OCCT-exception-1.0": [
 72951         "Open CASCADE Exception 1.0"
 72952     ],
 72953     "OpenJDK-assembly-exception-1.0": [
 72954         "OpenJDK Assembly exception 1.0"
 72955     ],
 72956     "openvpn-openssl-exception": [
 72957         "OpenVPN OpenSSL Exception"
 72958     ],
 72959     "PS-or-PDF-font-exception-20170817": [
 72960         "PS/PDF font exception (2017-08-17)"
 72961     ],
 72962     "Qt-GPL-exception-1.0": [
 72963         "Qt GPL exception 1.0"
 72964     ],
 72965     "Qt-LGPL-exception-1.1": [
 72966         "Qt LGPL exception 1.1"
 72967     ],
 72968     "Qwt-exception-1.0": [
 72969         "Qwt exception 1.0"
 72970     ],
 72971     "SHL-2.0": [
 72972         "Solderpad Hardware License v2.0"
 72973     ],
 72974     "SHL-2.1": [
 72975         "Solderpad Hardware License v2.1"
 72976     ],
 72977     "Swift-exception": [
 72978         "Swift Exception"
 72979     ],
 72980     "u-boot-exception-2.0": [
 72981         "U-Boot exception 2.0"
 72982     ],
 72983     "Universal-FOSS-exception-1.0": [
 72984         "Universal FOSS Exception, Version 1.0"
 72985     ],
 72986     "WxWindows-exception-3.1": [
 72987         "WxWindows Library Exception 3.1"
 72988     ]
 72989 }{
 72990     "0BSD": [
 72991         "BSD Zero Clause License",
 72992         true,
 72993         false
 72994     ],
 72995     "AAL": [
 72996         "Attribution Assurance License",
 72997         true,
 72998         false
 72999     ],
 73000     "Abstyles": [
 73001         "Abstyles License",
 73002         false,
 73003         false
 73004     ],
 73005     "Adobe-2006": [
 73006         "Adobe Systems Incorporated Source Code License Agreement",
 73007         false,
 73008         false
 73009     ],
 73010     "Adobe-Glyph": [
 73011         "Adobe Glyph List License",
 73012         false,
 73013         false
 73014     ],
 73015     "ADSL": [
 73016         "Amazon Digital Services License",
 73017         false,
 73018         false
 73019     ],
 73020     "AFL-1.1": [
 73021         "Academic Free License v1.1",
 73022         true,
 73023         false
 73024     ],
 73025     "AFL-1.2": [
 73026         "Academic Free License v1.2",
 73027         true,
 73028         false
 73029     ],
 73030     "AFL-2.0": [
 73031         "Academic Free License v2.0",
 73032         true,
 73033         false
 73034     ],
 73035     "AFL-2.1": [
 73036         "Academic Free License v2.1",
 73037         true,
 73038         false
 73039     ],
 73040     "AFL-3.0": [
 73041         "Academic Free License v3.0",
 73042         true,
 73043         false
 73044     ],
 73045     "Afmparse": [
 73046         "Afmparse License",
 73047         false,
 73048         false
 73049     ],
 73050     "AGPL-1.0": [
 73051         "Affero General Public License v1.0",
 73052         false,
 73053         true
 73054     ],
 73055     "AGPL-1.0-only": [
 73056         "Affero General Public License v1.0 only",
 73057         false,
 73058         false
 73059     ],
 73060     "AGPL-1.0-or-later": [
 73061         "Affero General Public License v1.0 or later",
 73062         false,
 73063         false
 73064     ],
 73065     "AGPL-3.0": [
 73066         "GNU Affero General Public License v3.0",
 73067         true,
 73068         true
 73069     ],
 73070     "AGPL-3.0-only": [
 73071         "GNU Affero General Public License v3.0 only",
 73072         true,
 73073         false
 73074     ],
 73075     "AGPL-3.0-or-later": [
 73076         "GNU Affero General Public License v3.0 or later",
 73077         true,
 73078         false
 73079     ],
 73080     "Aladdin": [
 73081         "Aladdin Free Public License",
 73082         false,
 73083         false
 73084     ],
 73085     "AMDPLPA": [
 73086         "AMD's plpa_map.c License",
 73087         false,
 73088         false
 73089     ],
 73090     "AML": [
 73091         "Apple MIT License",
 73092         false,
 73093         false
 73094     ],
 73095     "AMPAS": [
 73096         "Academy of Motion Picture Arts and Sciences BSD",
 73097         false,
 73098         false
 73099     ],
 73100     "ANTLR-PD": [
 73101         "ANTLR Software Rights Notice",
 73102         false,
 73103         false
 73104     ],
 73105     "ANTLR-PD-fallback": [
 73106         "ANTLR Software Rights Notice with license fallback",
 73107         false,
 73108         false
 73109     ],
 73110     "Apache-1.0": [
 73111         "Apache License 1.0",
 73112         false,
 73113         false
 73114     ],
 73115     "Apache-1.1": [
 73116         "Apache License 1.1",
 73117         true,
 73118         false
 73119     ],
 73120     "Apache-2.0": [
 73121         "Apache License 2.0",
 73122         true,
 73123         false
 73124     ],
 73125     "APAFML": [
 73126         "Adobe Postscript AFM License",
 73127         false,
 73128         false
 73129     ],
 73130     "APL-1.0": [
 73131         "Adaptive Public License 1.0",
 73132         true,
 73133         false
 73134     ],
 73135     "APSL-1.0": [
 73136         "Apple Public Source License 1.0",
 73137         true,
 73138         false
 73139     ],
 73140     "APSL-1.1": [
 73141         "Apple Public Source License 1.1",
 73142         true,
 73143         false
 73144     ],
 73145     "APSL-1.2": [
 73146         "Apple Public Source License 1.2",
 73147         true,
 73148         false
 73149     ],
 73150     "APSL-2.0": [
 73151         "Apple Public Source License 2.0",
 73152         true,
 73153         false
 73154     ],
 73155     "Artistic-1.0": [
 73156         "Artistic License 1.0",
 73157         true,
 73158         false
 73159     ],
 73160     "Artistic-1.0-cl8": [
 73161         "Artistic License 1.0 w/clause 8",
 73162         true,
 73163         false
 73164     ],
 73165     "Artistic-1.0-Perl": [
 73166         "Artistic License 1.0 (Perl)",
 73167         true,
 73168         false
 73169     ],
 73170     "Artistic-2.0": [
 73171         "Artistic License 2.0",
 73172         true,
 73173         false
 73174     ],
 73175     "Bahyph": [
 73176         "Bahyph License",
 73177         false,
 73178         false
 73179     ],
 73180     "Barr": [
 73181         "Barr License",
 73182         false,
 73183         false
 73184     ],
 73185     "Beerware": [
 73186         "Beerware License",
 73187         false,
 73188         false
 73189     ],
 73190     "BitTorrent-1.0": [
 73191         "BitTorrent Open Source License v1.0",
 73192         false,
 73193         false
 73194     ],
 73195     "BitTorrent-1.1": [
 73196         "BitTorrent Open Source License v1.1",
 73197         false,
 73198         false
 73199     ],
 73200     "blessing": [
 73201         "SQLite Blessing",
 73202         false,
 73203         false
 73204     ],
 73205     "BlueOak-1.0.0": [
 73206         "Blue Oak Model License 1.0.0",
 73207         false,
 73208         false
 73209     ],
 73210     "Borceux": [
 73211         "Borceux license",
 73212         false,
 73213         false
 73214     ],
 73215     "BSD-1-Clause": [
 73216         "BSD 1-Clause License",
 73217         true,
 73218         false
 73219     ],
 73220     "BSD-2-Clause": [
 73221         "BSD 2-Clause \"Simplified\" License",
 73222         true,
 73223         false
 73224     ],
 73225     "BSD-2-Clause-FreeBSD": [
 73226         "BSD 2-Clause FreeBSD License",
 73227         false,
 73228         true
 73229     ],
 73230     "BSD-2-Clause-NetBSD": [
 73231         "BSD 2-Clause NetBSD License",
 73232         false,
 73233         true
 73234     ],
 73235     "BSD-2-Clause-Patent": [
 73236         "BSD-2-Clause Plus Patent License",
 73237         true,
 73238         false
 73239     ],
 73240     "BSD-2-Clause-Views": [
 73241         "BSD 2-Clause with views sentence",
 73242         false,
 73243         false
 73244     ],
 73245     "BSD-3-Clause": [
 73246         "BSD 3-Clause \"New\" or \"Revised\" License",
 73247         true,
 73248         false
 73249     ],
 73250     "BSD-3-Clause-Attribution": [
 73251         "BSD with attribution",
 73252         false,
 73253         false
 73254     ],
 73255     "BSD-3-Clause-Clear": [
 73256         "BSD 3-Clause Clear License",
 73257         false,
 73258         false
 73259     ],
 73260     "BSD-3-Clause-LBNL": [
 73261         "Lawrence Berkeley National Labs BSD variant license",
 73262         true,
 73263         false
 73264     ],
 73265     "BSD-3-Clause-Modification": [
 73266         "BSD 3-Clause Modification",
 73267         false,
 73268         false
 73269     ],
 73270     "BSD-3-Clause-No-Military-License": [
 73271         "BSD 3-Clause No Military License",
 73272         false,
 73273         false
 73274     ],
 73275     "BSD-3-Clause-No-Nuclear-License": [
 73276         "BSD 3-Clause No Nuclear License",
 73277         false,
 73278         false
 73279     ],
 73280     "BSD-3-Clause-No-Nuclear-License-2014": [
 73281         "BSD 3-Clause No Nuclear License 2014",
 73282         false,
 73283         false
 73284     ],
 73285     "BSD-3-Clause-No-Nuclear-Warranty": [
 73286         "BSD 3-Clause No Nuclear Warranty",
 73287         false,
 73288         false
 73289     ],
 73290     "BSD-3-Clause-Open-MPI": [
 73291         "BSD 3-Clause Open MPI variant",
 73292         false,
 73293         false
 73294     ],
 73295     "BSD-4-Clause": [
 73296         "BSD 4-Clause \"Original\" or \"Old\" License",
 73297         false,
 73298         false
 73299     ],
 73300     "BSD-4-Clause-Shortened": [
 73301         "BSD 4 Clause Shortened",
 73302         false,
 73303         false
 73304     ],
 73305     "BSD-4-Clause-UC": [
 73306         "BSD-4-Clause (University of California-Specific)",
 73307         false,
 73308         false
 73309     ],
 73310     "BSD-Protection": [
 73311         "BSD Protection License",
 73312         false,
 73313         false
 73314     ],
 73315     "BSD-Source-Code": [
 73316         "BSD Source Code Attribution",
 73317         false,
 73318         false
 73319     ],
 73320     "BSL-1.0": [
 73321         "Boost Software License 1.0",
 73322         true,
 73323         false
 73324     ],
 73325     "BUSL-1.1": [
 73326         "Business Source License 1.1",
 73327         false,
 73328         false
 73329     ],
 73330     "bzip2-1.0.5": [
 73331         "bzip2 and libbzip2 License v1.0.5",
 73332         false,
 73333         false
 73334     ],
 73335     "bzip2-1.0.6": [
 73336         "bzip2 and libbzip2 License v1.0.6",
 73337         false,
 73338         false
 73339     ],
 73340     "C-UDA-1.0": [
 73341         "Computational Use of Data Agreement v1.0",
 73342         false,
 73343         false
 73344     ],
 73345     "CAL-1.0": [
 73346         "Cryptographic Autonomy License 1.0",
 73347         true,
 73348         false
 73349     ],
 73350     "CAL-1.0-Combined-Work-Exception": [
 73351         "Cryptographic Autonomy License 1.0 (Combined Work Exception)",
 73352         true,
 73353         false
 73354     ],
 73355     "Caldera": [
 73356         "Caldera License",
 73357         false,
 73358         false
 73359     ],
 73360     "CATOSL-1.1": [
 73361         "Computer Associates Trusted Open Source License 1.1",
 73362         true,
 73363         false
 73364     ],
 73365     "CC-BY-1.0": [
 73366         "Creative Commons Attribution 1.0 Generic",
 73367         false,
 73368         false
 73369     ],
 73370     "CC-BY-2.0": [
 73371         "Creative Commons Attribution 2.0 Generic",
 73372         false,
 73373         false
 73374     ],
 73375     "CC-BY-2.5": [
 73376         "Creative Commons Attribution 2.5 Generic",
 73377         false,
 73378         false
 73379     ],
 73380     "CC-BY-2.5-AU": [
 73381         "Creative Commons Attribution 2.5 Australia",
 73382         false,
 73383         false
 73384     ],
 73385     "CC-BY-3.0": [
 73386         "Creative Commons Attribution 3.0 Unported",
 73387         false,
 73388         false
 73389     ],
 73390     "CC-BY-3.0-AT": [
 73391         "Creative Commons Attribution 3.0 Austria",
 73392         false,
 73393         false
 73394     ],
 73395     "CC-BY-3.0-DE": [
 73396         "Creative Commons Attribution 3.0 Germany",
 73397         false,
 73398         false
 73399     ],
 73400     "CC-BY-3.0-NL": [
 73401         "Creative Commons Attribution 3.0 Netherlands",
 73402         false,
 73403         false
 73404     ],
 73405     "CC-BY-3.0-US": [
 73406         "Creative Commons Attribution 3.0 United States",
 73407         false,
 73408         false
 73409     ],
 73410     "CC-BY-4.0": [
 73411         "Creative Commons Attribution 4.0 International",
 73412         false,
 73413         false
 73414     ],
 73415     "CC-BY-NC-1.0": [
 73416         "Creative Commons Attribution Non Commercial 1.0 Generic",
 73417         false,
 73418         false
 73419     ],
 73420     "CC-BY-NC-2.0": [
 73421         "Creative Commons Attribution Non Commercial 2.0 Generic",
 73422         false,
 73423         false
 73424     ],
 73425     "CC-BY-NC-2.5": [
 73426         "Creative Commons Attribution Non Commercial 2.5 Generic",
 73427         false,
 73428         false
 73429     ],
 73430     "CC-BY-NC-3.0": [
 73431         "Creative Commons Attribution Non Commercial 3.0 Unported",
 73432         false,
 73433         false
 73434     ],
 73435     "CC-BY-NC-3.0-DE": [
 73436         "Creative Commons Attribution Non Commercial 3.0 Germany",
 73437         false,
 73438         false
 73439     ],
 73440     "CC-BY-NC-4.0": [
 73441         "Creative Commons Attribution Non Commercial 4.0 International",
 73442         false,
 73443         false
 73444     ],
 73445     "CC-BY-NC-ND-1.0": [
 73446         "Creative Commons Attribution Non Commercial No Derivatives 1.0 Generic",
 73447         false,
 73448         false
 73449     ],
 73450     "CC-BY-NC-ND-2.0": [
 73451         "Creative Commons Attribution Non Commercial No Derivatives 2.0 Generic",
 73452         false,
 73453         false
 73454     ],
 73455     "CC-BY-NC-ND-2.5": [
 73456         "Creative Commons Attribution Non Commercial No Derivatives 2.5 Generic",
 73457         false,
 73458         false
 73459     ],
 73460     "CC-BY-NC-ND-3.0": [
 73461         "Creative Commons Attribution Non Commercial No Derivatives 3.0 Unported",
 73462         false,
 73463         false
 73464     ],
 73465     "CC-BY-NC-ND-3.0-DE": [
 73466         "Creative Commons Attribution Non Commercial No Derivatives 3.0 Germany",
 73467         false,
 73468         false
 73469     ],
 73470     "CC-BY-NC-ND-3.0-IGO": [
 73471         "Creative Commons Attribution Non Commercial No Derivatives 3.0 IGO",
 73472         false,
 73473         false
 73474     ],
 73475     "CC-BY-NC-ND-4.0": [
 73476         "Creative Commons Attribution Non Commercial No Derivatives 4.0 International",
 73477         false,
 73478         false
 73479     ],
 73480     "CC-BY-NC-SA-1.0": [
 73481         "Creative Commons Attribution Non Commercial Share Alike 1.0 Generic",
 73482         false,
 73483         false
 73484     ],
 73485     "CC-BY-NC-SA-2.0": [
 73486         "Creative Commons Attribution Non Commercial Share Alike 2.0 Generic",
 73487         false,
 73488         false
 73489     ],
 73490     "CC-BY-NC-SA-2.0-FR": [
 73491         "Creative Commons Attribution-NonCommercial-ShareAlike 2.0 France",
 73492         false,
 73493         false
 73494     ],
 73495     "CC-BY-NC-SA-2.0-UK": [
 73496         "Creative Commons Attribution Non Commercial Share Alike 2.0 England and Wales",
 73497         false,
 73498         false
 73499     ],
 73500     "CC-BY-NC-SA-2.5": [
 73501         "Creative Commons Attribution Non Commercial Share Alike 2.5 Generic",
 73502         false,
 73503         false
 73504     ],
 73505     "CC-BY-NC-SA-3.0": [
 73506         "Creative Commons Attribution Non Commercial Share Alike 3.0 Unported",
 73507         false,
 73508         false
 73509     ],
 73510     "CC-BY-NC-SA-3.0-DE": [
 73511         "Creative Commons Attribution Non Commercial Share Alike 3.0 Germany",
 73512         false,
 73513         false
 73514     ],
 73515     "CC-BY-NC-SA-3.0-IGO": [
 73516         "Creative Commons Attribution Non Commercial Share Alike 3.0 IGO",
 73517         false,
 73518         false
 73519     ],
 73520     "CC-BY-NC-SA-4.0": [
 73521         "Creative Commons Attribution Non Commercial Share Alike 4.0 International",
 73522         false,
 73523         false
 73524     ],
 73525     "CC-BY-ND-1.0": [
 73526         "Creative Commons Attribution No Derivatives 1.0 Generic",
 73527         false,
 73528         false
 73529     ],
 73530     "CC-BY-ND-2.0": [
 73531         "Creative Commons Attribution No Derivatives 2.0 Generic",
 73532         false,
 73533         false
 73534     ],
 73535     "CC-BY-ND-2.5": [
 73536         "Creative Commons Attribution No Derivatives 2.5 Generic",
 73537         false,
 73538         false
 73539     ],
 73540     "CC-BY-ND-3.0": [
 73541         "Creative Commons Attribution No Derivatives 3.0 Unported",
 73542         false,
 73543         false
 73544     ],
 73545     "CC-BY-ND-3.0-DE": [
 73546         "Creative Commons Attribution No Derivatives 3.0 Germany",
 73547         false,
 73548         false
 73549     ],
 73550     "CC-BY-ND-4.0": [
 73551         "Creative Commons Attribution No Derivatives 4.0 International",
 73552         false,
 73553         false
 73554     ],
 73555     "CC-BY-SA-1.0": [
 73556         "Creative Commons Attribution Share Alike 1.0 Generic",
 73557         false,
 73558         false
 73559     ],
 73560     "CC-BY-SA-2.0": [
 73561         "Creative Commons Attribution Share Alike 2.0 Generic",
 73562         false,
 73563         false
 73564     ],
 73565     "CC-BY-SA-2.0-UK": [
 73566         "Creative Commons Attribution Share Alike 2.0 England and Wales",
 73567         false,
 73568         false
 73569     ],
 73570     "CC-BY-SA-2.1-JP": [
 73571         "Creative Commons Attribution Share Alike 2.1 Japan",
 73572         false,
 73573         false
 73574     ],
 73575     "CC-BY-SA-2.5": [
 73576         "Creative Commons Attribution Share Alike 2.5 Generic",
 73577         false,
 73578         false
 73579     ],
 73580     "CC-BY-SA-3.0": [
 73581         "Creative Commons Attribution Share Alike 3.0 Unported",
 73582         false,
 73583         false
 73584     ],
 73585     "CC-BY-SA-3.0-AT": [
 73586         "Creative Commons Attribution Share Alike 3.0 Austria",
 73587         false,
 73588         false
 73589     ],
 73590     "CC-BY-SA-3.0-DE": [
 73591         "Creative Commons Attribution Share Alike 3.0 Germany",
 73592         false,
 73593         false
 73594     ],
 73595     "CC-BY-SA-4.0": [
 73596         "Creative Commons Attribution Share Alike 4.0 International",
 73597         false,
 73598         false
 73599     ],
 73600     "CC-PDDC": [
 73601         "Creative Commons Public Domain Dedication and Certification",
 73602         false,
 73603         false
 73604     ],
 73605     "CC0-1.0": [
 73606         "Creative Commons Zero v1.0 Universal",
 73607         false,
 73608         false
 73609     ],
 73610     "CDDL-1.0": [
 73611         "Common Development and Distribution License 1.0",
 73612         true,
 73613         false
 73614     ],
 73615     "CDDL-1.1": [
 73616         "Common Development and Distribution License 1.1",
 73617         false,
 73618         false
 73619     ],
 73620     "CDL-1.0": [
 73621         "Common Documentation License 1.0",
 73622         false,
 73623         false
 73624     ],
 73625     "CDLA-Permissive-1.0": [
 73626         "Community Data License Agreement Permissive 1.0",
 73627         false,
 73628         false
 73629     ],
 73630     "CDLA-Permissive-2.0": [
 73631         "Community Data License Agreement Permissive 2.0",
 73632         false,
 73633         false
 73634     ],
 73635     "CDLA-Sharing-1.0": [
 73636         "Community Data License Agreement Sharing 1.0",
 73637         false,
 73638         false
 73639     ],
 73640     "CECILL-1.0": [
 73641         "CeCILL Free Software License Agreement v1.0",
 73642         false,
 73643         false
 73644     ],
 73645     "CECILL-1.1": [
 73646         "CeCILL Free Software License Agreement v1.1",
 73647         false,
 73648         false
 73649     ],
 73650     "CECILL-2.0": [
 73651         "CeCILL Free Software License Agreement v2.0",
 73652         false,
 73653         false
 73654     ],
 73655     "CECILL-2.1": [
 73656         "CeCILL Free Software License Agreement v2.1",
 73657         true,
 73658         false
 73659     ],
 73660     "CECILL-B": [
 73661         "CeCILL-B Free Software License Agreement",
 73662         false,
 73663         false
 73664     ],
 73665     "CECILL-C": [
 73666         "CeCILL-C Free Software License Agreement",
 73667         false,
 73668         false
 73669     ],
 73670     "CERN-OHL-1.1": [
 73671         "CERN Open Hardware Licence v1.1",
 73672         false,
 73673         false
 73674     ],
 73675     "CERN-OHL-1.2": [
 73676         "CERN Open Hardware Licence v1.2",
 73677         false,
 73678         false
 73679     ],
 73680     "CERN-OHL-P-2.0": [
 73681         "CERN Open Hardware Licence Version 2 - Permissive",
 73682         true,
 73683         false
 73684     ],
 73685     "CERN-OHL-S-2.0": [
 73686         "CERN Open Hardware Licence Version 2 - Strongly Reciprocal",
 73687         true,
 73688         false
 73689     ],
 73690     "CERN-OHL-W-2.0": [
 73691         "CERN Open Hardware Licence Version 2 - Weakly Reciprocal",
 73692         true,
 73693         false
 73694     ],
 73695     "ClArtistic": [
 73696         "Clarified Artistic License",
 73697         false,
 73698         false
 73699     ],
 73700     "CNRI-Jython": [
 73701         "CNRI Jython License",
 73702         false,
 73703         false
 73704     ],
 73705     "CNRI-Python": [
 73706         "CNRI Python License",
 73707         true,
 73708         false
 73709     ],
 73710     "CNRI-Python-GPL-Compatible": [
 73711         "CNRI Python Open Source GPL Compatible License Agreement",
 73712         false,
 73713         false
 73714     ],
 73715     "COIL-1.0": [
 73716         "Copyfree Open Innovation License",
 73717         false,
 73718         false
 73719     ],
 73720     "Community-Spec-1.0": [
 73721         "Community Specification License 1.0",
 73722         false,
 73723         false
 73724     ],
 73725     "Condor-1.1": [
 73726         "Condor Public License v1.1",
 73727         false,
 73728         false
 73729     ],
 73730     "copyleft-next-0.3.0": [
 73731         "copyleft-next 0.3.0",
 73732         false,
 73733         false
 73734     ],
 73735     "copyleft-next-0.3.1": [
 73736         "copyleft-next 0.3.1",
 73737         false,
 73738         false
 73739     ],
 73740     "CPAL-1.0": [
 73741         "Common Public Attribution License 1.0",
 73742         true,
 73743         false
 73744     ],
 73745     "CPL-1.0": [
 73746         "Common Public License 1.0",
 73747         true,
 73748         false
 73749     ],
 73750     "CPOL-1.02": [
 73751         "Code Project Open License 1.02",
 73752         false,
 73753         false
 73754     ],
 73755     "Crossword": [
 73756         "Crossword License",
 73757         false,
 73758         false
 73759     ],
 73760     "CrystalStacker": [
 73761         "CrystalStacker License",
 73762         false,
 73763         false
 73764     ],
 73765     "CUA-OPL-1.0": [
 73766         "CUA Office Public License v1.0",
 73767         true,
 73768         false
 73769     ],
 73770     "Cube": [
 73771         "Cube License",
 73772         false,
 73773         false
 73774     ],
 73775     "curl": [
 73776         "curl License",
 73777         false,
 73778         false
 73779     ],
 73780     "D-FSL-1.0": [
 73781         "Deutsche Freie Software Lizenz",
 73782         false,
 73783         false
 73784     ],
 73785     "diffmark": [
 73786         "diffmark license",
 73787         false,
 73788         false
 73789     ],
 73790     "DOC": [
 73791         "DOC License",
 73792         false,
 73793         false
 73794     ],
 73795     "Dotseqn": [
 73796         "Dotseqn License",
 73797         false,
 73798         false
 73799     ],
 73800     "DRL-1.0": [
 73801         "Detection Rule License 1.0",
 73802         false,
 73803         false
 73804     ],
 73805     "DSDP": [
 73806         "DSDP License",
 73807         false,
 73808         false
 73809     ],
 73810     "dvipdfm": [
 73811         "dvipdfm License",
 73812         false,
 73813         false
 73814     ],
 73815     "ECL-1.0": [
 73816         "Educational Community License v1.0",
 73817         true,
 73818         false
 73819     ],
 73820     "ECL-2.0": [
 73821         "Educational Community License v2.0",
 73822         true,
 73823         false
 73824     ],
 73825     "eCos-2.0": [
 73826         "eCos license version 2.0",
 73827         false,
 73828         true
 73829     ],
 73830     "EFL-1.0": [
 73831         "Eiffel Forum License v1.0",
 73832         true,
 73833         false
 73834     ],
 73835     "EFL-2.0": [
 73836         "Eiffel Forum License v2.0",
 73837         true,
 73838         false
 73839     ],
 73840     "eGenix": [
 73841         "eGenix.com Public License 1.1.0",
 73842         false,
 73843         false
 73844     ],
 73845     "Entessa": [
 73846         "Entessa Public License v1.0",
 73847         true,
 73848         false
 73849     ],
 73850     "EPICS": [
 73851         "EPICS Open License",
 73852         false,
 73853         false
 73854     ],
 73855     "EPL-1.0": [
 73856         "Eclipse Public License 1.0",
 73857         true,
 73858         false
 73859     ],
 73860     "EPL-2.0": [
 73861         "Eclipse Public License 2.0",
 73862         true,
 73863         false
 73864     ],
 73865     "ErlPL-1.1": [
 73866         "Erlang Public License v1.1",
 73867         false,
 73868         false
 73869     ],
 73870     "etalab-2.0": [
 73871         "Etalab Open License 2.0",
 73872         false,
 73873         false
 73874     ],
 73875     "EUDatagrid": [
 73876         "EU DataGrid Software License",
 73877         true,
 73878         false
 73879     ],
 73880     "EUPL-1.0": [
 73881         "European Union Public License 1.0",
 73882         false,
 73883         false
 73884     ],
 73885     "EUPL-1.1": [
 73886         "European Union Public License 1.1",
 73887         true,
 73888         false
 73889     ],
 73890     "EUPL-1.2": [
 73891         "European Union Public License 1.2",
 73892         true,
 73893         false
 73894     ],
 73895     "Eurosym": [
 73896         "Eurosym License",
 73897         false,
 73898         false
 73899     ],
 73900     "Fair": [
 73901         "Fair License",
 73902         true,
 73903         false
 73904     ],
 73905     "FDK-AAC": [
 73906         "Fraunhofer FDK AAC Codec Library",
 73907         false,
 73908         false
 73909     ],
 73910     "Frameworx-1.0": [
 73911         "Frameworx Open License 1.0",
 73912         true,
 73913         false
 73914     ],
 73915     "FreeBSD-DOC": [
 73916         "FreeBSD Documentation License",
 73917         false,
 73918         false
 73919     ],
 73920     "FreeImage": [
 73921         "FreeImage Public License v1.0",
 73922         false,
 73923         false
 73924     ],
 73925     "FSFAP": [
 73926         "FSF All Permissive License",
 73927         false,
 73928         false
 73929     ],
 73930     "FSFUL": [
 73931         "FSF Unlimited License",
 73932         false,
 73933         false
 73934     ],
 73935     "FSFULLR": [
 73936         "FSF Unlimited License (with License Retention)",
 73937         false,
 73938         false
 73939     ],
 73940     "FTL": [
 73941         "Freetype Project License",
 73942         false,
 73943         false
 73944     ],
 73945     "GD": [
 73946         "GD License",
 73947         false,
 73948         false
 73949     ],
 73950     "GFDL-1.1": [
 73951         "GNU Free Documentation License v1.1",
 73952         false,
 73953         true
 73954     ],
 73955     "GFDL-1.1-invariants-only": [
 73956         "GNU Free Documentation License v1.1 only - invariants",
 73957         false,
 73958         false
 73959     ],
 73960     "GFDL-1.1-invariants-or-later": [
 73961         "GNU Free Documentation License v1.1 or later - invariants",
 73962         false,
 73963         false
 73964     ],
 73965     "GFDL-1.1-no-invariants-only": [
 73966         "GNU Free Documentation License v1.1 only - no invariants",
 73967         false,
 73968         false
 73969     ],
 73970     "GFDL-1.1-no-invariants-or-later": [
 73971         "GNU Free Documentation License v1.1 or later - no invariants",
 73972         false,
 73973         false
 73974     ],
 73975     "GFDL-1.1-only": [
 73976         "GNU Free Documentation License v1.1 only",
 73977         false,
 73978         false
 73979     ],
 73980     "GFDL-1.1-or-later": [
 73981         "GNU Free Documentation License v1.1 or later",
 73982         false,
 73983         false
 73984     ],
 73985     "GFDL-1.2": [
 73986         "GNU Free Documentation License v1.2",
 73987         false,
 73988         true
 73989     ],
 73990     "GFDL-1.2-invariants-only": [
 73991         "GNU Free Documentation License v1.2 only - invariants",
 73992         false,
 73993         false
 73994     ],
 73995     "GFDL-1.2-invariants-or-later": [
 73996         "GNU Free Documentation License v1.2 or later - invariants",
 73997         false,
 73998         false
 73999     ],
 74000     "GFDL-1.2-no-invariants-only": [
 74001         "GNU Free Documentation License v1.2 only - no invariants",
 74002         false,
 74003         false
 74004     ],
 74005     "GFDL-1.2-no-invariants-or-later": [
 74006         "GNU Free Documentation License v1.2 or later - no invariants",
 74007         false,
 74008         false
 74009     ],
 74010     "GFDL-1.2-only": [
 74011         "GNU Free Documentation License v1.2 only",
 74012         false,
 74013         false
 74014     ],
 74015     "GFDL-1.2-or-later": [
 74016         "GNU Free Documentation License v1.2 or later",
 74017         false,
 74018         false
 74019     ],
 74020     "GFDL-1.3": [
 74021         "GNU Free Documentation License v1.3",
 74022         false,
 74023         true
 74024     ],
 74025     "GFDL-1.3-invariants-only": [
 74026         "GNU Free Documentation License v1.3 only - invariants",
 74027         false,
 74028         false
 74029     ],
 74030     "GFDL-1.3-invariants-or-later": [
 74031         "GNU Free Documentation License v1.3 or later - invariants",
 74032         false,
 74033         false
 74034     ],
 74035     "GFDL-1.3-no-invariants-only": [
 74036         "GNU Free Documentation License v1.3 only - no invariants",
 74037         false,
 74038         false
 74039     ],
 74040     "GFDL-1.3-no-invariants-or-later": [
 74041         "GNU Free Documentation License v1.3 or later - no invariants",
 74042         false,
 74043         false
 74044     ],
 74045     "GFDL-1.3-only": [
 74046         "GNU Free Documentation License v1.3 only",
 74047         false,
 74048         false
 74049     ],
 74050     "GFDL-1.3-or-later": [
 74051         "GNU Free Documentation License v1.3 or later",
 74052         false,
 74053         false
 74054     ],
 74055     "Giftware": [
 74056         "Giftware License",
 74057         false,
 74058         false
 74059     ],
 74060     "GL2PS": [
 74061         "GL2PS License",
 74062         false,
 74063         false
 74064     ],
 74065     "Glide": [
 74066         "3dfx Glide License",
 74067         false,
 74068         false
 74069     ],
 74070     "Glulxe": [
 74071         "Glulxe License",
 74072         false,
 74073         false
 74074     ],
 74075     "GLWTPL": [
 74076         "Good Luck With That Public License",
 74077         false,
 74078         false
 74079     ],
 74080     "gnuplot": [
 74081         "gnuplot License",
 74082         false,
 74083         false
 74084     ],
 74085     "GPL-1.0": [
 74086         "GNU General Public License v1.0 only",
 74087         false,
 74088         true
 74089     ],
 74090     "GPL-1.0+": [
 74091         "GNU General Public License v1.0 or later",
 74092         false,
 74093         true
 74094     ],
 74095     "GPL-1.0-only": [
 74096         "GNU General Public License v1.0 only",
 74097         false,
 74098         false
 74099     ],
 74100     "GPL-1.0-or-later": [
 74101         "GNU General Public License v1.0 or later",
 74102         false,
 74103         false
 74104     ],
 74105     "GPL-2.0": [
 74106         "GNU General Public License v2.0 only",
 74107         true,
 74108         true
 74109     ],
 74110     "GPL-2.0+": [
 74111         "GNU General Public License v2.0 or later",
 74112         true,
 74113         true
 74114     ],
 74115     "GPL-2.0-only": [
 74116         "GNU General Public License v2.0 only",
 74117         true,
 74118         false
 74119     ],
 74120     "GPL-2.0-or-later": [
 74121         "GNU General Public License v2.0 or later",
 74122         true,
 74123         false
 74124     ],
 74125     "GPL-2.0-with-autoconf-exception": [
 74126         "GNU General Public License v2.0 w/Autoconf exception",
 74127         false,
 74128         true
 74129     ],
 74130     "GPL-2.0-with-bison-exception": [
 74131         "GNU General Public License v2.0 w/Bison exception",
 74132         false,
 74133         true
 74134     ],
 74135     "GPL-2.0-with-classpath-exception": [
 74136         "GNU General Public License v2.0 w/Classpath exception",
 74137         false,
 74138         true
 74139     ],
 74140     "GPL-2.0-with-font-exception": [
 74141         "GNU General Public License v2.0 w/Font exception",
 74142         false,
 74143         true
 74144     ],
 74145     "GPL-2.0-with-GCC-exception": [
 74146         "GNU General Public License v2.0 w/GCC Runtime Library exception",
 74147         false,
 74148         true
 74149     ],
 74150     "GPL-3.0": [
 74151         "GNU General Public License v3.0 only",
 74152         true,
 74153         true
 74154     ],
 74155     "GPL-3.0+": [
 74156         "GNU General Public License v3.0 or later",
 74157         true,
 74158         true
 74159     ],
 74160     "GPL-3.0-only": [
 74161         "GNU General Public License v3.0 only",
 74162         true,
 74163         false
 74164     ],
 74165     "GPL-3.0-or-later": [
 74166         "GNU General Public License v3.0 or later",
 74167         true,
 74168         false
 74169     ],
 74170     "GPL-3.0-with-autoconf-exception": [
 74171         "GNU General Public License v3.0 w/Autoconf exception",
 74172         false,
 74173         true
 74174     ],
 74175     "GPL-3.0-with-GCC-exception": [
 74176         "GNU General Public License v3.0 w/GCC Runtime Library exception",
 74177         true,
 74178         true
 74179     ],
 74180     "gSOAP-1.3b": [
 74181         "gSOAP Public License v1.3b",
 74182         false,
 74183         false
 74184     ],
 74185     "HaskellReport": [
 74186         "Haskell Language Report License",
 74187         false,
 74188         false
 74189     ],
 74190     "Hippocratic-2.1": [
 74191         "Hippocratic License 2.1",
 74192         false,
 74193         false
 74194     ],
 74195     "HPND": [
 74196         "Historical Permission Notice and Disclaimer",
 74197         true,
 74198         false
 74199     ],
 74200     "HPND-sell-variant": [
 74201         "Historical Permission Notice and Disclaimer - sell variant",
 74202         false,
 74203         false
 74204     ],
 74205     "HTMLTIDY": [
 74206         "HTML Tidy License",
 74207         false,
 74208         false
 74209     ],
 74210     "IBM-pibs": [
 74211         "IBM PowerPC Initialization and Boot Software",
 74212         false,
 74213         false
 74214     ],
 74215     "ICU": [
 74216         "ICU License",
 74217         false,
 74218         false
 74219     ],
 74220     "IJG": [
 74221         "Independent JPEG Group License",
 74222         false,
 74223         false
 74224     ],
 74225     "ImageMagick": [
 74226         "ImageMagick License",
 74227         false,
 74228         false
 74229     ],
 74230     "iMatix": [
 74231         "iMatix Standard Function Library Agreement",
 74232         false,
 74233         false
 74234     ],
 74235     "Imlib2": [
 74236         "Imlib2 License",
 74237         false,
 74238         false
 74239     ],
 74240     "Info-ZIP": [
 74241         "Info-ZIP License",
 74242         false,
 74243         false
 74244     ],
 74245     "Intel": [
 74246         "Intel Open Source License",
 74247         true,
 74248         false
 74249     ],
 74250     "Intel-ACPI": [
 74251         "Intel ACPI Software License Agreement",
 74252         false,
 74253         false
 74254     ],
 74255     "Interbase-1.0": [
 74256         "Interbase Public License v1.0",
 74257         false,
 74258         false
 74259     ],
 74260     "IPA": [
 74261         "IPA Font License",
 74262         true,
 74263         false
 74264     ],
 74265     "IPL-1.0": [
 74266         "IBM Public License v1.0",
 74267         true,
 74268         false
 74269     ],
 74270     "ISC": [
 74271         "ISC License",
 74272         true,
 74273         false
 74274     ],
 74275     "JasPer-2.0": [
 74276         "JasPer License",
 74277         false,
 74278         false
 74279     ],
 74280     "JPNIC": [
 74281         "Japan Network Information Center License",
 74282         false,
 74283         false
 74284     ],
 74285     "JSON": [
 74286         "JSON License",
 74287         false,
 74288         false
 74289     ],
 74290     "LAL-1.2": [
 74291         "Licence Art Libre 1.2",
 74292         false,
 74293         false
 74294     ],
 74295     "LAL-1.3": [
 74296         "Licence Art Libre 1.3",
 74297         false,
 74298         false
 74299     ],
 74300     "Latex2e": [
 74301         "Latex2e License",
 74302         false,
 74303         false
 74304     ],
 74305     "Leptonica": [
 74306         "Leptonica License",
 74307         false,
 74308         false
 74309     ],
 74310     "LGPL-2.0": [
 74311         "GNU Library General Public License v2 only",
 74312         true,
 74313         true
 74314     ],
 74315     "LGPL-2.0+": [
 74316         "GNU Library General Public License v2 or later",
 74317         true,
 74318         true
 74319     ],
 74320     "LGPL-2.0-only": [
 74321         "GNU Library General Public License v2 only",
 74322         true,
 74323         false
 74324     ],
 74325     "LGPL-2.0-or-later": [
 74326         "GNU Library General Public License v2 or later",
 74327         true,
 74328         false
 74329     ],
 74330     "LGPL-2.1": [
 74331         "GNU Lesser General Public License v2.1 only",
 74332         true,
 74333         true
 74334     ],
 74335     "LGPL-2.1+": [
 74336         "GNU Library General Public License v2.1 or later",
 74337         true,
 74338         true
 74339     ],
 74340     "LGPL-2.1-only": [
 74341         "GNU Lesser General Public License v2.1 only",
 74342         true,
 74343         false
 74344     ],
 74345     "LGPL-2.1-or-later": [
 74346         "GNU Lesser General Public License v2.1 or later",
 74347         true,
 74348         false
 74349     ],
 74350     "LGPL-3.0": [
 74351         "GNU Lesser General Public License v3.0 only",
 74352         true,
 74353         true
 74354     ],
 74355     "LGPL-3.0+": [
 74356         "GNU Lesser General Public License v3.0 or later",
 74357         true,
 74358         true
 74359     ],
 74360     "LGPL-3.0-only": [
 74361         "GNU Lesser General Public License v3.0 only",
 74362         true,
 74363         false
 74364     ],
 74365     "LGPL-3.0-or-later": [
 74366         "GNU Lesser General Public License v3.0 or later",
 74367         true,
 74368         false
 74369     ],
 74370     "LGPLLR": [
 74371         "Lesser General Public License For Linguistic Resources",
 74372         false,
 74373         false
 74374     ],
 74375     "Libpng": [
 74376         "libpng License",
 74377         false,
 74378         false
 74379     ],
 74380     "libpng-2.0": [
 74381         "PNG Reference Library version 2",
 74382         false,
 74383         false
 74384     ],
 74385     "libselinux-1.0": [
 74386         "libselinux public domain notice",
 74387         false,
 74388         false
 74389     ],
 74390     "libtiff": [
 74391         "libtiff License",
 74392         false,
 74393         false
 74394     ],
 74395     "LiLiQ-P-1.1": [
 74396         "Licence Libre du Qu\u00e9bec \u2013 Permissive version 1.1",
 74397         true,
 74398         false
 74399     ],
 74400     "LiLiQ-R-1.1": [
 74401         "Licence Libre du Qu\u00e9bec \u2013 R\u00e9ciprocit\u00e9 version 1.1",
 74402         true,
 74403         false
 74404     ],
 74405     "LiLiQ-Rplus-1.1": [
 74406         "Licence Libre du Qu\u00e9bec \u2013 R\u00e9ciprocit\u00e9 forte version 1.1",
 74407         true,
 74408         false
 74409     ],
 74410     "Linux-man-pages-copyleft": [
 74411         "Linux man-pages Copyleft",
 74412         false,
 74413         false
 74414     ],
 74415     "Linux-OpenIB": [
 74416         "Linux Kernel Variant of OpenIB.org license",
 74417         false,
 74418         false
 74419     ],
 74420     "LPL-1.0": [
 74421         "Lucent Public License Version 1.0",
 74422         true,
 74423         false
 74424     ],
 74425     "LPL-1.02": [
 74426         "Lucent Public License v1.02",
 74427         true,
 74428         false
 74429     ],
 74430     "LPPL-1.0": [
 74431         "LaTeX Project Public License v1.0",
 74432         false,
 74433         false
 74434     ],
 74435     "LPPL-1.1": [
 74436         "LaTeX Project Public License v1.1",
 74437         false,
 74438         false
 74439     ],
 74440     "LPPL-1.2": [
 74441         "LaTeX Project Public License v1.2",
 74442         false,
 74443         false
 74444     ],
 74445     "LPPL-1.3a": [
 74446         "LaTeX Project Public License v1.3a",
 74447         false,
 74448         false
 74449     ],
 74450     "LPPL-1.3c": [
 74451         "LaTeX Project Public License v1.3c",
 74452         true,
 74453         false
 74454     ],
 74455     "MakeIndex": [
 74456         "MakeIndex License",
 74457         false,
 74458         false
 74459     ],
 74460     "MirOS": [
 74461         "The MirOS Licence",
 74462         true,
 74463         false
 74464     ],
 74465     "MIT": [
 74466         "MIT License",
 74467         true,
 74468         false
 74469     ],
 74470     "MIT-0": [
 74471         "MIT No Attribution",
 74472         true,
 74473         false
 74474     ],
 74475     "MIT-advertising": [
 74476         "Enlightenment License (e16)",
 74477         false,
 74478         false
 74479     ],
 74480     "MIT-CMU": [
 74481         "CMU License",
 74482         false,
 74483         false
 74484     ],
 74485     "MIT-enna": [
 74486         "enna License",
 74487         false,
 74488         false
 74489     ],
 74490     "MIT-feh": [
 74491         "feh License",
 74492         false,
 74493         false
 74494     ],
 74495     "MIT-Modern-Variant": [
 74496         "MIT License Modern Variant",
 74497         true,
 74498         false
 74499     ],
 74500     "MIT-open-group": [
 74501         "MIT Open Group variant",
 74502         false,
 74503         false
 74504     ],
 74505     "MITNFA": [
 74506         "MIT +no-false-attribs license",
 74507         false,
 74508         false
 74509     ],
 74510     "Motosoto": [
 74511         "Motosoto License",
 74512         true,
 74513         false
 74514     ],
 74515     "mpich2": [
 74516         "mpich2 License",
 74517         false,
 74518         false
 74519     ],
 74520     "MPL-1.0": [
 74521         "Mozilla Public License 1.0",
 74522         true,
 74523         false
 74524     ],
 74525     "MPL-1.1": [
 74526         "Mozilla Public License 1.1",
 74527         true,
 74528         false
 74529     ],
 74530     "MPL-2.0": [
 74531         "Mozilla Public License 2.0",
 74532         true,
 74533         false
 74534     ],
 74535     "MPL-2.0-no-copyleft-exception": [
 74536         "Mozilla Public License 2.0 (no copyleft exception)",
 74537         true,
 74538         false
 74539     ],
 74540     "MS-PL": [
 74541         "Microsoft Public License",
 74542         true,
 74543         false
 74544     ],
 74545     "MS-RL": [
 74546         "Microsoft Reciprocal License",
 74547         true,
 74548         false
 74549     ],
 74550     "MTLL": [
 74551         "Matrix Template Library License",
 74552         false,
 74553         false
 74554     ],
 74555     "MulanPSL-1.0": [
 74556         "Mulan Permissive Software License, Version 1",
 74557         false,
 74558         false
 74559     ],
 74560     "MulanPSL-2.0": [
 74561         "Mulan Permissive Software License, Version 2",
 74562         true,
 74563         false
 74564     ],
 74565     "Multics": [
 74566         "Multics License",
 74567         true,
 74568         false
 74569     ],
 74570     "Mup": [
 74571         "Mup License",
 74572         false,
 74573         false
 74574     ],
 74575     "NAIST-2003": [
 74576         "Nara Institute of Science and Technology License (2003)",
 74577         false,
 74578         false
 74579     ],
 74580     "NASA-1.3": [
 74581         "NASA Open Source Agreement 1.3",
 74582         true,
 74583         false
 74584     ],
 74585     "Naumen": [
 74586         "Naumen Public License",
 74587         true,
 74588         false
 74589     ],
 74590     "NBPL-1.0": [
 74591         "Net Boolean Public License v1",
 74592         false,
 74593         false
 74594     ],
 74595     "NCGL-UK-2.0": [
 74596         "Non-Commercial Government Licence",
 74597         false,
 74598         false
 74599     ],
 74600     "NCSA": [
 74601         "University of Illinois/NCSA Open Source License",
 74602         true,
 74603         false
 74604     ],
 74605     "Net-SNMP": [
 74606         "Net-SNMP License",
 74607         false,
 74608         false
 74609     ],
 74610     "NetCDF": [
 74611         "NetCDF license",
 74612         false,
 74613         false
 74614     ],
 74615     "Newsletr": [
 74616         "Newsletr License",
 74617         false,
 74618         false
 74619     ],
 74620     "NGPL": [
 74621         "Nethack General Public License",
 74622         true,
 74623         false
 74624     ],
 74625     "NIST-PD": [
 74626         "NIST Public Domain Notice",
 74627         false,
 74628         false
 74629     ],
 74630     "NIST-PD-fallback": [
 74631         "NIST Public Domain Notice with license fallback",
 74632         false,
 74633         false
 74634     ],
 74635     "NLOD-1.0": [
 74636         "Norwegian Licence for Open Government Data (NLOD) 1.0",
 74637         false,
 74638         false
 74639     ],
 74640     "NLOD-2.0": [
 74641         "Norwegian Licence for Open Government Data (NLOD) 2.0",
 74642         false,
 74643         false
 74644     ],
 74645     "NLPL": [
 74646         "No Limit Public License",
 74647         false,
 74648         false
 74649     ],
 74650     "Nokia": [
 74651         "Nokia Open Source License",
 74652         true,
 74653         false
 74654     ],
 74655     "NOSL": [
 74656         "Netizen Open Source License",
 74657         false,
 74658         false
 74659     ],
 74660     "Noweb": [
 74661         "Noweb License",
 74662         false,
 74663         false
 74664     ],
 74665     "NPL-1.0": [
 74666         "Netscape Public License v1.0",
 74667         false,
 74668         false
 74669     ],
 74670     "NPL-1.1": [
 74671         "Netscape Public License v1.1",
 74672         false,
 74673         false
 74674     ],
 74675     "NPOSL-3.0": [
 74676         "Non-Profit Open Software License 3.0",
 74677         true,
 74678         false
 74679     ],
 74680     "NRL": [
 74681         "NRL License",
 74682         false,
 74683         false
 74684     ],
 74685     "NTP": [
 74686         "NTP License",
 74687         true,
 74688         false
 74689     ],
 74690     "NTP-0": [
 74691         "NTP No Attribution",
 74692         false,
 74693         false
 74694     ],
 74695     "Nunit": [
 74696         "Nunit License",
 74697         false,
 74698         true
 74699     ],
 74700     "O-UDA-1.0": [
 74701         "Open Use of Data Agreement v1.0",
 74702         false,
 74703         false
 74704     ],
 74705     "OCCT-PL": [
 74706         "Open CASCADE Technology Public License",
 74707         false,
 74708         false
 74709     ],
 74710     "OCLC-2.0": [
 74711         "OCLC Research Public License 2.0",
 74712         true,
 74713         false
 74714     ],
 74715     "ODbL-1.0": [
 74716         "Open Data Commons Open Database License v1.0",
 74717         false,
 74718         false
 74719     ],
 74720     "ODC-By-1.0": [
 74721         "Open Data Commons Attribution License v1.0",
 74722         false,
 74723         false
 74724     ],
 74725     "OFL-1.0": [
 74726         "SIL Open Font License 1.0",
 74727         false,
 74728         false
 74729     ],
 74730     "OFL-1.0-no-RFN": [
 74731         "SIL Open Font License 1.0 with no Reserved Font Name",
 74732         false,
 74733         false
 74734     ],
 74735     "OFL-1.0-RFN": [
 74736         "SIL Open Font License 1.0 with Reserved Font Name",
 74737         false,
 74738         false
 74739     ],
 74740     "OFL-1.1": [
 74741         "SIL Open Font License 1.1",
 74742         true,
 74743         false
 74744     ],
 74745     "OFL-1.1-no-RFN": [
 74746         "SIL Open Font License 1.1 with no Reserved Font Name",
 74747         true,
 74748         false
 74749     ],
 74750     "OFL-1.1-RFN": [
 74751         "SIL Open Font License 1.1 with Reserved Font Name",
 74752         true,
 74753         false
 74754     ],
 74755     "OGC-1.0": [
 74756         "OGC Software License, Version 1.0",
 74757         false,
 74758         false
 74759     ],
 74760     "OGDL-Taiwan-1.0": [
 74761         "Taiwan Open Government Data License, version 1.0",
 74762         false,
 74763         false
 74764     ],
 74765     "OGL-Canada-2.0": [
 74766         "Open Government Licence - Canada",
 74767         false,
 74768         false
 74769     ],
 74770     "OGL-UK-1.0": [
 74771         "Open Government Licence v1.0",
 74772         false,
 74773         false
 74774     ],
 74775     "OGL-UK-2.0": [
 74776         "Open Government Licence v2.0",
 74777         false,
 74778         false
 74779     ],
 74780     "OGL-UK-3.0": [
 74781         "Open Government Licence v3.0",
 74782         false,
 74783         false
 74784     ],
 74785     "OGTSL": [
 74786         "Open Group Test Suite License",
 74787         true,
 74788         false
 74789     ],
 74790     "OLDAP-1.1": [
 74791         "Open LDAP Public License v1.1",
 74792         false,
 74793         false
 74794     ],
 74795     "OLDAP-1.2": [
 74796         "Open LDAP Public License v1.2",
 74797         false,
 74798         false
 74799     ],
 74800     "OLDAP-1.3": [
 74801         "Open LDAP Public License v1.3",
 74802         false,
 74803         false
 74804     ],
 74805     "OLDAP-1.4": [
 74806         "Open LDAP Public License v1.4",
 74807         false,
 74808         false
 74809     ],
 74810     "OLDAP-2.0": [
 74811         "Open LDAP Public License v2.0 (or possibly 2.0A and 2.0B)",
 74812         false,
 74813         false
 74814     ],
 74815     "OLDAP-2.0.1": [
 74816         "Open LDAP Public License v2.0.1",
 74817         false,
 74818         false
 74819     ],
 74820     "OLDAP-2.1": [
 74821         "Open LDAP Public License v2.1",
 74822         false,
 74823         false
 74824     ],
 74825     "OLDAP-2.2": [
 74826         "Open LDAP Public License v2.2",
 74827         false,
 74828         false
 74829     ],
 74830     "OLDAP-2.2.1": [
 74831         "Open LDAP Public License v2.2.1",
 74832         false,
 74833         false
 74834     ],
 74835     "OLDAP-2.2.2": [
 74836         "Open LDAP Public License 2.2.2",
 74837         false,
 74838         false
 74839     ],
 74840     "OLDAP-2.3": [
 74841         "Open LDAP Public License v2.3",
 74842         false,
 74843         false
 74844     ],
 74845     "OLDAP-2.4": [
 74846         "Open LDAP Public License v2.4",
 74847         false,
 74848         false
 74849     ],
 74850     "OLDAP-2.5": [
 74851         "Open LDAP Public License v2.5",
 74852         false,
 74853         false
 74854     ],
 74855     "OLDAP-2.6": [
 74856         "Open LDAP Public License v2.6",
 74857         false,
 74858         false
 74859     ],
 74860     "OLDAP-2.7": [
 74861         "Open LDAP Public License v2.7",
 74862         false,
 74863         false
 74864     ],
 74865     "OLDAP-2.8": [
 74866         "Open LDAP Public License v2.8",
 74867         true,
 74868         false
 74869     ],
 74870     "OML": [
 74871         "Open Market License",
 74872         false,
 74873         false
 74874     ],
 74875     "OpenSSL": [
 74876         "OpenSSL License",
 74877         false,
 74878         false
 74879     ],
 74880     "OPL-1.0": [
 74881         "Open Public License v1.0",
 74882         false,
 74883         false
 74884     ],
 74885     "OPUBL-1.0": [
 74886         "Open Publication License v1.0",
 74887         false,
 74888         false
 74889     ],
 74890     "OSET-PL-2.1": [
 74891         "OSET Public License version 2.1",
 74892         true,
 74893         false
 74894     ],
 74895     "OSL-1.0": [
 74896         "Open Software License 1.0",
 74897         true,
 74898         false
 74899     ],
 74900     "OSL-1.1": [
 74901         "Open Software License 1.1",
 74902         false,
 74903         false
 74904     ],
 74905     "OSL-2.0": [
 74906         "Open Software License 2.0",
 74907         true,
 74908         false
 74909     ],
 74910     "OSL-2.1": [
 74911         "Open Software License 2.1",
 74912         true,
 74913         false
 74914     ],
 74915     "OSL-3.0": [
 74916         "Open Software License 3.0",
 74917         true,
 74918         false
 74919     ],
 74920     "Parity-6.0.0": [
 74921         "The Parity Public License 6.0.0",
 74922         false,
 74923         false
 74924     ],
 74925     "Parity-7.0.0": [
 74926         "The Parity Public License 7.0.0",
 74927         false,
 74928         false
 74929     ],
 74930     "PDDL-1.0": [
 74931         "Open Data Commons Public Domain Dedication & License 1.0",
 74932         false,
 74933         false
 74934     ],
 74935     "PHP-3.0": [
 74936         "PHP License v3.0",
 74937         true,
 74938         false
 74939     ],
 74940     "PHP-3.01": [
 74941         "PHP License v3.01",
 74942         true,
 74943         false
 74944     ],
 74945     "Plexus": [
 74946         "Plexus Classworlds License",
 74947         false,
 74948         false
 74949     ],
 74950     "PolyForm-Noncommercial-1.0.0": [
 74951         "PolyForm Noncommercial License 1.0.0",
 74952         false,
 74953         false
 74954     ],
 74955     "PolyForm-Small-Business-1.0.0": [
 74956         "PolyForm Small Business License 1.0.0",
 74957         false,
 74958         false
 74959     ],
 74960     "PostgreSQL": [
 74961         "PostgreSQL License",
 74962         true,
 74963         false
 74964     ],
 74965     "PSF-2.0": [
 74966         "Python Software Foundation License 2.0",
 74967         false,
 74968         false
 74969     ],
 74970     "psfrag": [
 74971         "psfrag License",
 74972         false,
 74973         false
 74974     ],
 74975     "psutils": [
 74976         "psutils License",
 74977         false,
 74978         false
 74979     ],
 74980     "Python-2.0": [
 74981         "Python License 2.0",
 74982         true,
 74983         false
 74984     ],
 74985     "Qhull": [
 74986         "Qhull License",
 74987         false,
 74988         false
 74989     ],
 74990     "QPL-1.0": [
 74991         "Q Public License 1.0",
 74992         true,
 74993         false
 74994     ],
 74995     "Rdisc": [
 74996         "Rdisc License",
 74997         false,
 74998         false
 74999     ],
 75000     "RHeCos-1.1": [
 75001         "Red Hat eCos Public License v1.1",
 75002         false,
 75003         false
 75004     ],
 75005     "RPL-1.1": [
 75006         "Reciprocal Public License 1.1",
 75007         true,
 75008         false
 75009     ],
 75010     "RPL-1.5": [
 75011         "Reciprocal Public License 1.5",
 75012         true,
 75013         false
 75014     ],
 75015     "RPSL-1.0": [
 75016         "RealNetworks Public Source License v1.0",
 75017         true,
 75018         false
 75019     ],
 75020     "RSA-MD": [
 75021         "RSA Message-Digest License",
 75022         false,
 75023         false
 75024     ],
 75025     "RSCPL": [
 75026         "Ricoh Source Code Public License",
 75027         true,
 75028         false
 75029     ],
 75030     "Ruby": [
 75031         "Ruby License",
 75032         false,
 75033         false
 75034     ],
 75035     "SAX-PD": [
 75036         "Sax Public Domain Notice",
 75037         false,
 75038         false
 75039     ],
 75040     "Saxpath": [
 75041         "Saxpath License",
 75042         false,
 75043         false
 75044     ],
 75045     "SCEA": [
 75046         "SCEA Shared Source License",
 75047         false,
 75048         false
 75049     ],
 75050     "Sendmail": [
 75051         "Sendmail License",
 75052         false,
 75053         false
 75054     ],
 75055     "Sendmail-8.23": [
 75056         "Sendmail License 8.23",
 75057         false,
 75058         false
 75059     ],
 75060     "SGI-B-1.0": [
 75061         "SGI Free Software License B v1.0",
 75062         false,
 75063         false
 75064     ],
 75065     "SGI-B-1.1": [
 75066         "SGI Free Software License B v1.1",
 75067         false,
 75068         false
 75069     ],
 75070     "SGI-B-2.0": [
 75071         "SGI Free Software License B v2.0",
 75072         false,
 75073         false
 75074     ],
 75075     "SHL-0.5": [
 75076         "Solderpad Hardware License v0.5",
 75077         false,
 75078         false
 75079     ],
 75080     "SHL-0.51": [
 75081         "Solderpad Hardware License, Version 0.51",
 75082         false,
 75083         false
 75084     ],
 75085     "SimPL-2.0": [
 75086         "Simple Public License 2.0",
 75087         true,
 75088         false
 75089     ],
 75090     "SISSL": [
 75091         "Sun Industry Standards Source License v1.1",
 75092         true,
 75093         false
 75094     ],
 75095     "SISSL-1.2": [
 75096         "Sun Industry Standards Source License v1.2",
 75097         false,
 75098         false
 75099     ],
 75100     "Sleepycat": [
 75101         "Sleepycat License",
 75102         true,
 75103         false
 75104     ],
 75105     "SMLNJ": [
 75106         "Standard ML of New Jersey License",
 75107         false,
 75108         false
 75109     ],
 75110     "SMPPL": [
 75111         "Secure Messaging Protocol Public License",
 75112         false,
 75113         false
 75114     ],
 75115     "SNIA": [
 75116         "SNIA Public License 1.1",
 75117         false,
 75118         false
 75119     ],
 75120     "Spencer-86": [
 75121         "Spencer License 86",
 75122         false,
 75123         false
 75124     ],
 75125     "Spencer-94": [
 75126         "Spencer License 94",
 75127         false,
 75128         false
 75129     ],
 75130     "Spencer-99": [
 75131         "Spencer License 99",
 75132         false,
 75133         false
 75134     ],
 75135     "SPL-1.0": [
 75136         "Sun Public License v1.0",
 75137         true,
 75138         false
 75139     ],
 75140     "SSH-OpenSSH": [
 75141         "SSH OpenSSH license",
 75142         false,
 75143         false
 75144     ],
 75145     "SSH-short": [
 75146         "SSH short notice",
 75147         false,
 75148         false
 75149     ],
 75150     "SSPL-1.0": [
 75151         "Server Side Public License, v 1",
 75152         false,
 75153         false
 75154     ],
 75155     "StandardML-NJ": [
 75156         "Standard ML of New Jersey License",
 75157         false,
 75158         true
 75159     ],
 75160     "SugarCRM-1.1.3": [
 75161         "SugarCRM Public License v1.1.3",
 75162         false,
 75163         false
 75164     ],
 75165     "SWL": [
 75166         "Scheme Widget Library (SWL) Software License Agreement",
 75167         false,
 75168         false
 75169     ],
 75170     "TAPR-OHL-1.0": [
 75171         "TAPR Open Hardware License v1.0",
 75172         false,
 75173         false
 75174     ],
 75175     "TCL": [
 75176         "TCL/TK License",
 75177         false,
 75178         false
 75179     ],
 75180     "TCP-wrappers": [
 75181         "TCP Wrappers License",
 75182         false,
 75183         false
 75184     ],
 75185     "TMate": [
 75186         "TMate Open Source License",
 75187         false,
 75188         false
 75189     ],
 75190     "TORQUE-1.1": [
 75191         "TORQUE v2.5+ Software License v1.1",
 75192         false,
 75193         false
 75194     ],
 75195     "TOSL": [
 75196         "Trusster Open Source License",
 75197         false,
 75198         false
 75199     ],
 75200     "TU-Berlin-1.0": [
 75201         "Technische Universitaet Berlin License 1.0",
 75202         false,
 75203         false
 75204     ],
 75205     "TU-Berlin-2.0": [
 75206         "Technische Universitaet Berlin License 2.0",
 75207         false,
 75208         false
 75209     ],
 75210     "UCL-1.0": [
 75211         "Upstream Compatibility License v1.0",
 75212         true,
 75213         false
 75214     ],
 75215     "Unicode-DFS-2015": [
 75216         "Unicode License Agreement - Data Files and Software (2015)",
 75217         false,
 75218         false
 75219     ],
 75220     "Unicode-DFS-2016": [
 75221         "Unicode License Agreement - Data Files and Software (2016)",
 75222         true,
 75223         false
 75224     ],
 75225     "Unicode-TOU": [
 75226         "Unicode Terms of Use",
 75227         false,
 75228         false
 75229     ],
 75230     "Unlicense": [
 75231         "The Unlicense",
 75232         true,
 75233         false
 75234     ],
 75235     "UPL-1.0": [
 75236         "Universal Permissive License v1.0",
 75237         true,
 75238         false
 75239     ],
 75240     "Vim": [
 75241         "Vim License",
 75242         false,
 75243         false
 75244     ],
 75245     "VOSTROM": [
 75246         "VOSTROM Public License for Open Source",
 75247         false,
 75248         false
 75249     ],
 75250     "VSL-1.0": [
 75251         "Vovida Software License v1.0",
 75252         true,
 75253         false
 75254     ],
 75255     "W3C": [
 75256         "W3C Software Notice and License (2002-12-31)",
 75257         true,
 75258         false
 75259     ],
 75260     "W3C-19980720": [
 75261         "W3C Software Notice and License (1998-07-20)",
 75262         false,
 75263         false
 75264     ],
 75265     "W3C-20150513": [
 75266         "W3C Software Notice and Document License (2015-05-13)",
 75267         false,
 75268         false
 75269     ],
 75270     "Watcom-1.0": [
 75271         "Sybase Open Watcom Public License 1.0",
 75272         true,
 75273         false
 75274     ],
 75275     "Wsuipa": [
 75276         "Wsuipa License",
 75277         false,
 75278         false
 75279     ],
 75280     "WTFPL": [
 75281         "Do What The F*ck You Want To Public License",
 75282         false,
 75283         false
 75284     ],
 75285     "wxWindows": [
 75286         "wxWindows Library License",
 75287         true,
 75288         true
 75289     ],
 75290     "X11": [
 75291         "X11 License",
 75292         false,
 75293         false
 75294     ],
 75295     "Xerox": [
 75296         "Xerox License",
 75297         false,
 75298         false
 75299     ],
 75300     "XFree86-1.1": [
 75301         "XFree86 License 1.1",
 75302         false,
 75303         false
 75304     ],
 75305     "xinetd": [
 75306         "xinetd License",
 75307         false,
 75308         false
 75309     ],
 75310     "Xnet": [
 75311         "X.Net License",
 75312         true,
 75313         false
 75314     ],
 75315     "xpp": [
 75316         "XPP License",
 75317         false,
 75318         false
 75319     ],
 75320     "XSkat": [
 75321         "XSkat License",
 75322         false,
 75323         false
 75324     ],
 75325     "YPL-1.0": [
 75326         "Yahoo! Public License v1.0",
 75327         false,
 75328         false
 75329     ],
 75330     "YPL-1.1": [
 75331         "Yahoo! Public License v1.1",
 75332         false,
 75333         false
 75334     ],
 75335     "Zed": [
 75336         "Zed License",
 75337         false,
 75338         false
 75339     ],
 75340     "Zend-2.0": [
 75341         "Zend License v2.0",
 75342         false,
 75343         false
 75344     ],
 75345     "Zimbra-1.3": [
 75346         "Zimbra Public License v1.3",
 75347         false,
 75348         false
 75349     ],
 75350     "Zimbra-1.4": [
 75351         "Zimbra Public License v1.4",
 75352         false,
 75353         false
 75354     ],
 75355     "Zlib": [
 75356         "zlib License",
 75357         true,
 75358         false
 75359     ],
 75360     "zlib-acknowledgement": [
 75361         "zlib/libpng License with Acknowledgement",
 75362         false,
 75363         false
 75364     ],
 75365     "ZPL-1.1": [
 75366         "Zope Public License 1.1",
 75367         false,
 75368         false
 75369     ],
 75370     "ZPL-2.0": [
 75371         "Zope Public License 2.0",
 75372         true,
 75373         false
 75374     ],
 75375     "ZPL-2.1": [
 75376         "Zope Public License 2.1",
 75377         true,
 75378         false
 75379     ]
 75380 }<?php
 75381 
 75382 
 75383 
 75384 
 75385 
 75386 
 75387 
 75388 
 75389 
 75390 
 75391 namespace Composer\Spdx;
 75392 
 75393 class SpdxLicenses
 75394 {
 75395 
 75396 const LICENSES_FILE = 'spdx-licenses.json';
 75397 
 75398 
 75399 const EXCEPTIONS_FILE = 'spdx-exceptions.json';
 75400 
 75401 
 75402 
 75403 
 75404 
 75405 
 75406 
 75407 
 75408 
 75409 
 75410 
 75411 
 75412 
 75413 
 75414 private $licenses;
 75415 
 75416 
 75417 
 75418 
 75419 private $licensesExpression;
 75420 
 75421 
 75422 
 75423 
 75424 
 75425 
 75426 
 75427 
 75428 
 75429 
 75430 
 75431 
 75432 
 75433 
 75434 private $exceptions;
 75435 
 75436 
 75437 
 75438 
 75439 private $exceptionsExpression;
 75440 
 75441 public function __construct()
 75442 {
 75443 $this->loadLicenses();
 75444 $this->loadExceptions();
 75445 }
 75446 
 75447 
 75448 
 75449 
 75450 
 75451 
 75452 
 75453 
 75454 
 75455 
 75456 
 75457 
 75458 
 75459 public function getLicenseByIdentifier($identifier)
 75460 {
 75461 $key = strtolower($identifier);
 75462 
 75463 if (!isset($this->licenses[$key])) {
 75464 return null;
 75465 }
 75466 
 75467 list($identifier, $name, $isOsiApproved, $isDeprecatedLicenseId) = $this->licenses[$key];
 75468 
 75469 return array(
 75470 $name,
 75471 $isOsiApproved,
 75472 'https://spdx.org/licenses/' . $identifier . '.html#licenseText',
 75473 $isDeprecatedLicenseId,
 75474 );
 75475 }
 75476 
 75477 
 75478 
 75479 
 75480 
 75481 
 75482 public function getLicenses()
 75483 {
 75484 return $this->licenses;
 75485 }
 75486 
 75487 
 75488 
 75489 
 75490 
 75491 
 75492 
 75493 
 75494 
 75495 
 75496 
 75497 
 75498 
 75499 public function getExceptionByIdentifier($identifier)
 75500 {
 75501 $key = strtolower($identifier);
 75502 
 75503 if (!isset($this->exceptions[$key])) {
 75504 return null;
 75505 }
 75506 
 75507 list($identifier, $name) = $this->exceptions[$key];
 75508 
 75509 return array(
 75510 $name,
 75511 'https://spdx.org/licenses/' . $identifier . '.html#licenseExceptionText',
 75512 );
 75513 }
 75514 
 75515 
 75516 
 75517 
 75518 
 75519 
 75520 
 75521 
 75522 public function getIdentifierByName($name)
 75523 {
 75524 foreach ($this->licenses as $licenseData) {
 75525 if ($licenseData[1] === $name) {
 75526 return $licenseData[0];
 75527 }
 75528 }
 75529 
 75530 foreach ($this->exceptions as $licenseData) {
 75531 if ($licenseData[1] === $name) {
 75532 return $licenseData[0];
 75533 }
 75534 }
 75535 
 75536 return null;
 75537 }
 75538 
 75539 
 75540 
 75541 
 75542 
 75543 
 75544 
 75545 
 75546 public function isOsiApprovedByIdentifier($identifier)
 75547 {
 75548 return $this->licenses[strtolower($identifier)][2];
 75549 }
 75550 
 75551 
 75552 
 75553 
 75554 
 75555 
 75556 
 75557 
 75558 public function isDeprecatedByIdentifier($identifier)
 75559 {
 75560 return $this->licenses[strtolower($identifier)][3];
 75561 }
 75562 
 75563 
 75564 
 75565 
 75566 
 75567 
 75568 
 75569 
 75570 public function validate($license)
 75571 {
 75572 if (is_array($license)) {
 75573 $count = count($license);
 75574 if ($count !== count(array_filter($license, 'is_string'))) {
 75575 throw new \InvalidArgumentException('Array of strings expected.');
 75576 }
 75577 $license = $count > 1 ? '(' . implode(' OR ', $license) . ')' : (string) reset($license);
 75578 }
 75579 
 75580 if (!is_string($license)) {
 75581 throw new \InvalidArgumentException(sprintf(
 75582 'Array or String expected, %s given.',
 75583 gettype($license)
 75584 ));
 75585 }
 75586 
 75587 return $this->isValidLicenseString($license);
 75588 }
 75589 
 75590 
 75591 
 75592 
 75593 public static function getResourcesDir()
 75594 {
 75595 return dirname(__DIR__) . '/res';
 75596 }
 75597 
 75598 
 75599 
 75600 
 75601 private function loadLicenses()
 75602 {
 75603 if (null !== $this->licenses) {
 75604 return;
 75605 }
 75606 
 75607 $json = file_get_contents(self::getResourcesDir() . '/' . self::LICENSES_FILE);
 75608 if (false === $json) {
 75609 throw new \RuntimeException('Missing license file in ' . self::getResourcesDir() . '/' . self::LICENSES_FILE);
 75610 }
 75611 $this->licenses = array();
 75612 
 75613 foreach (json_decode($json, true) as $identifier => $license) {
 75614 $this->licenses[strtolower($identifier)] = array($identifier, $license[0], $license[1], $license[2]);
 75615 }
 75616 }
 75617 
 75618 
 75619 
 75620 
 75621 private function loadExceptions()
 75622 {
 75623 if (null !== $this->exceptions) {
 75624 return;
 75625 }
 75626 
 75627 $json = file_get_contents(self::getResourcesDir() . '/' . self::EXCEPTIONS_FILE);
 75628 if (false === $json) {
 75629 throw new \RuntimeException('Missing exceptions file in ' . self::getResourcesDir() . '/' . self::EXCEPTIONS_FILE);
 75630 }
 75631 $this->exceptions = array();
 75632 
 75633 foreach (json_decode($json, true) as $identifier => $exception) {
 75634 $this->exceptions[strtolower($identifier)] = array($identifier, $exception[0]);
 75635 }
 75636 }
 75637 
 75638 
 75639 
 75640 
 75641 private function getLicensesExpression()
 75642 {
 75643 if (null === $this->licensesExpression) {
 75644 $licenses = array_map('preg_quote', array_keys($this->licenses));
 75645 rsort($licenses);
 75646 $licenses = implode('|', $licenses);
 75647 $this->licensesExpression = $licenses;
 75648 }
 75649 
 75650 return $this->licensesExpression;
 75651 }
 75652 
 75653 
 75654 
 75655 
 75656 private function getExceptionsExpression()
 75657 {
 75658 if (null === $this->exceptionsExpression) {
 75659 $exceptions = array_map('preg_quote', array_keys($this->exceptions));
 75660 rsort($exceptions);
 75661 $exceptions = implode('|', $exceptions);
 75662 $this->exceptionsExpression = $exceptions;
 75663 }
 75664 
 75665 return $this->exceptionsExpression;
 75666 }
 75667 
 75668 
 75669 
 75670 
 75671 
 75672 
 75673 
 75674 
 75675 private function isValidLicenseString($license)
 75676 {
 75677 if (isset($this->licenses[strtolower($license)])) {
 75678 return true;
 75679 }
 75680 
 75681 $licenses = $this->getLicensesExpression();
 75682 $exceptions = $this->getExceptionsExpression();
 75683 
 75684 $regex = <<<REGEX
 75685 {
 75686 (?(DEFINE)
 75687     # idstring: 1*( ALPHA / DIGIT / - / . )
 75688     (?<idstring>[\pL\pN.-]{1,})
 75689 
 75690     # license-id: taken from list
 75691     (?<licenseid>${licenses})
 75692 
 75693     # license-exception-id: taken from list
 75694     (?<licenseexceptionid>${exceptions})
 75695 
 75696     # license-ref: [DocumentRef-1*(idstring):]LicenseRef-1*(idstring)
 75697     (?<licenseref>(?:DocumentRef-(?&idstring):)?LicenseRef-(?&idstring))
 75698 
 75699     # simple-expresssion: license-id / license-id+ / license-ref
 75700     (?<simple_expression>(?&licenseid)\+? | (?&licenseid) | (?&licenseref))
 75701 
 75702     # compound-expression: 1*(
 75703     #   simple-expression /
 75704     #   simple-expression WITH license-exception-id /
 75705     #   compound-expression AND compound-expression /
 75706     #   compound-expression OR compound-expression
 75707     # ) / ( compound-expression ) )
 75708     (?<compound_head>
 75709         (?&simple_expression) ( \s+ WITH \s+ (?&licenseexceptionid))?
 75710             | \( \s* (?&compound_expression) \s* \)
 75711     )
 75712     (?<compound_expression>
 75713         (?&compound_head) (?: \s+ (?:AND|OR) \s+ (?&compound_expression))?
 75714     )
 75715 
 75716     # license-expression: 1*1(simple-expression / compound-expression)
 75717     (?<license_expression>(?&compound_expression) | (?&simple_expression))
 75718 ) # end of define
 75719 
 75720 ^(NONE | NOASSERTION | (?&license_expression))$
 75721 }xi
 75722 REGEX;
 75723 
 75724 $match = preg_match($regex, $license);
 75725 
 75726 if (0 === $match) {
 75727 return false;
 75728 }
 75729 
 75730 if (false === $match) {
 75731 throw new \RuntimeException('Regex failed to compile/run.');
 75732 }
 75733 
 75734 return true;
 75735 }
 75736 }
 75737 
 75738 MIT License
 75739 
 75740 Copyright (c) 2017 Composer
 75741 
 75742 Permission is hereby granted, free of charge, to any person obtaining a copy
 75743 of this software and associated documentation files (the "Software"), to deal
 75744 in the Software without restriction, including without limitation the rights
 75745 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 75746 copies of the Software, and to permit persons to whom the Software is
 75747 furnished to do so, subject to the following conditions:
 75748 
 75749 The above copyright notice and this permission notice shall be included in all
 75750 copies or substantial portions of the Software.
 75751 
 75752 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 75753 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 75754 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 75755 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 75756 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 75757 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 75758 SOFTWARE.
 75759 
 75760 <?php
 75761 
 75762 
 75763 
 75764 
 75765 
 75766 
 75767 
 75768 
 75769 
 75770 
 75771 namespace Composer\XdebugHandler;
 75772 
 75773 
 75774 
 75775 
 75776 
 75777 
 75778 class PhpConfig
 75779 {
 75780 
 75781 
 75782 
 75783 
 75784 
 75785 public function useOriginal()
 75786 {
 75787 $this->getDataAndReset();
 75788 return array();
 75789 }
 75790 
 75791 
 75792 
 75793 
 75794 
 75795 
 75796 public function useStandard()
 75797 {
 75798 $data = $this->getDataAndReset();
 75799 if ($data !== null) {
 75800 return array('-n', '-c', $data['tmpIni']);
 75801 }
 75802 
 75803 return array();
 75804 }
 75805 
 75806 
 75807 
 75808 
 75809 
 75810 
 75811 public function usePersistent()
 75812 {
 75813 $data = $this->getDataAndReset();
 75814 if ($data !== null) {
 75815 $this->updateEnv('PHPRC', $data['tmpIni']);
 75816 $this->updateEnv('PHP_INI_SCAN_DIR', '');
 75817 }
 75818 
 75819 return array();
 75820 }
 75821 
 75822 
 75823 
 75824 
 75825 
 75826 
 75827 
 75828 private function getDataAndReset()
 75829 {
 75830 $data = XdebugHandler::getRestartSettings();
 75831 if ($data !== null) {
 75832 $this->updateEnv('PHPRC', $data['phprc']);
 75833 $this->updateEnv('PHP_INI_SCAN_DIR', $data['scanDir']);
 75834 }
 75835 
 75836 return $data;
 75837 }
 75838 
 75839 
 75840 
 75841 
 75842 
 75843 
 75844 
 75845 
 75846 
 75847 private function updateEnv($name, $value)
 75848 {
 75849 Process::setEnv($name, false !== $value ? $value : null);
 75850 }
 75851 }
 75852 <?php
 75853 
 75854 
 75855 
 75856 
 75857 
 75858 
 75859 
 75860 
 75861 
 75862 
 75863 namespace Composer\XdebugHandler;
 75864 
 75865 use Composer\Pcre\Preg;
 75866 
 75867 
 75868 
 75869 
 75870 
 75871 
 75872 class Process
 75873 {
 75874 
 75875 
 75876 
 75877 
 75878 
 75879 
 75880 
 75881 
 75882 
 75883 
 75884 
 75885 
 75886 public static function escape($arg, $meta = true, $module = false)
 75887 {
 75888 if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
 75889 return "'".str_replace("'", "'\\''", $arg)."'";
 75890 }
 75891 
 75892 $quote = strpbrk($arg, " \t") !== false || $arg === '';
 75893 
 75894 $arg = Preg::replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes);
 75895 
 75896 if ($meta) {
 75897 $meta = $dquotes || Preg::isMatch('/%[^%]+%/', $arg);
 75898 
 75899 if (!$meta) {
 75900 $quote = $quote || strpbrk($arg, '^&|<>()') !== false;
 75901 } elseif ($module && !$dquotes && $quote) {
 75902 $meta = false;
 75903 }
 75904 }
 75905 
 75906 if ($quote) {
 75907 $arg = '"'.(Preg::replace('/(\\\\*)$/', '$1$1', $arg)).'"';
 75908 }
 75909 
 75910 if ($meta) {
 75911 $arg = Preg::replace('/(["^&|<>()%])/', '^$1', $arg);
 75912 }
 75913 
 75914 return $arg;
 75915 }
 75916 
 75917 
 75918 
 75919 
 75920 
 75921 
 75922 
 75923 
 75924 public static function escapeShellCommand(array $args)
 75925 {
 75926 $command = '';
 75927 $module = array_shift($args);
 75928 
 75929 if ($module !== null) {
 75930 $command = self::escape($module, true, true);
 75931 
 75932 foreach ($args as $arg) {
 75933 $command .= ' '.self::escape($arg);
 75934 }
 75935 }
 75936 
 75937 return $command;
 75938 }
 75939 
 75940 
 75941 
 75942 
 75943 
 75944 
 75945 
 75946 
 75947 
 75948 public static function setEnv($name, $value = null)
 75949 {
 75950 $unset = null === $value;
 75951 
 75952 if (!putenv($unset ? $name : $name.'='.$value)) {
 75953 return false;
 75954 }
 75955 
 75956 if ($unset) {
 75957 unset($_SERVER[$name]);
 75958 } else {
 75959 $_SERVER[$name] = $value;
 75960 }
 75961 
 75962 
 75963 if (false !== stripos((string) ini_get('variables_order'), 'E')) {
 75964 if ($unset) {
 75965 unset($_ENV[$name]);
 75966 } else {
 75967 $_ENV[$name] = $value;
 75968 }
 75969 }
 75970 
 75971 return true;
 75972 }
 75973 }
 75974 <?php
 75975 
 75976 
 75977 
 75978 
 75979 
 75980 
 75981 
 75982 
 75983 
 75984 
 75985 namespace Composer\XdebugHandler;
 75986 
 75987 use Psr\Log\LoggerInterface;
 75988 use Psr\Log\LogLevel;
 75989 
 75990 
 75991 
 75992 
 75993 
 75994 class Status
 75995 {
 75996 const ENV_RESTART = 'XDEBUG_HANDLER_RESTART';
 75997 const CHECK = 'Check';
 75998 const ERROR = 'Error';
 75999 const INFO = 'Info';
 76000 const NORESTART = 'NoRestart';
 76001 const RESTART = 'Restart';
 76002 const RESTARTING = 'Restarting';
 76003 const RESTARTED = 'Restarted';
 76004 
 76005 
 76006 private $debug;
 76007 
 76008 
 76009 private $envAllowXdebug;
 76010 
 76011 
 76012 private $loaded;
 76013 
 76014 
 76015 private $logger;
 76016 
 76017 
 76018 private $modeOff;
 76019 
 76020 
 76021 private $time;
 76022 
 76023 
 76024 
 76025 
 76026 
 76027 
 76028 
 76029 public function __construct($envAllowXdebug, $debug)
 76030 {
 76031 $start = getenv(self::ENV_RESTART);
 76032 Process::setEnv(self::ENV_RESTART);
 76033 $this->time = is_numeric($start) ? round((microtime(true) - $start) * 1000) : 0;
 76034 
 76035 $this->envAllowXdebug = $envAllowXdebug;
 76036 $this->debug = $debug && defined('STDERR');
 76037 $this->modeOff = false;
 76038 }
 76039 
 76040 
 76041 
 76042 
 76043 
 76044 
 76045 public function setLogger(LoggerInterface $logger)
 76046 {
 76047 $this->logger = $logger;
 76048 }
 76049 
 76050 
 76051 
 76052 
 76053 
 76054 
 76055 
 76056 
 76057 
 76058 
 76059 public function report($op, $data)
 76060 {
 76061 if ($this->logger !== null || $this->debug) {
 76062 $callable = array($this, 'report'.$op);
 76063 
 76064 if (!is_callable($callable)) {
 76065 throw new \InvalidArgumentException('Unknown op handler: '.$op);
 76066 }
 76067 
 76068 $params = $data !== null ? $data : array();
 76069 call_user_func_array($callable, array($params));
 76070 }
 76071 }
 76072 
 76073 
 76074 
 76075 
 76076 
 76077 
 76078 
 76079 
 76080 
 76081 private function output($text, $level = null)
 76082 {
 76083 if ($this->logger !== null) {
 76084 $this->logger->log($level !== null ? $level: LogLevel::DEBUG, $text);
 76085 }
 76086 
 76087 if ($this->debug) {
 76088 fwrite(STDERR, sprintf('xdebug-handler[%d] %s', getmypid(), $text.PHP_EOL));
 76089 }
 76090 }
 76091 
 76092 
 76093 
 76094 
 76095 
 76096 
 76097 private function reportCheck($loaded)
 76098 {
 76099 list($version, $mode) = explode('|', $loaded);
 76100 
 76101 if ($version !== '') {
 76102 $this->loaded = '('.$version.')'.($mode !== '' ? ' mode='.$mode : '');
 76103 }
 76104 $this->modeOff = $mode === 'off';
 76105 $this->output('Checking '.$this->envAllowXdebug);
 76106 }
 76107 
 76108 
 76109 
 76110 
 76111 
 76112 
 76113 private function reportError($error)
 76114 {
 76115 $this->output(sprintf('No restart (%s)', $error), LogLevel::WARNING);
 76116 }
 76117 
 76118 
 76119 
 76120 
 76121 
 76122 
 76123 private function reportInfo($info)
 76124 {
 76125 $this->output($info);
 76126 }
 76127 
 76128 
 76129 
 76130 
 76131 private function reportNoRestart()
 76132 {
 76133 $this->output($this->getLoadedMessage());
 76134 
 76135 if ($this->loaded !== null) {
 76136 $text = sprintf('No restart (%s)', $this->getEnvAllow());
 76137 if (!((bool) getenv($this->envAllowXdebug))) {
 76138 $text .= ' Allowed by '.($this->modeOff ? 'mode' : 'application');
 76139 }
 76140 $this->output($text);
 76141 }
 76142 }
 76143 
 76144 
 76145 
 76146 
 76147 private function reportRestart()
 76148 {
 76149 $this->output($this->getLoadedMessage());
 76150 Process::setEnv(self::ENV_RESTART, (string) microtime(true));
 76151 }
 76152 
 76153 
 76154 
 76155 
 76156 private function reportRestarted()
 76157 {
 76158 $loaded = $this->getLoadedMessage();
 76159 $text = sprintf('Restarted (%d ms). %s', $this->time, $loaded);
 76160 $level = $this->loaded !== null ? LogLevel::WARNING : null;
 76161 $this->output($text, $level);
 76162 }
 76163 
 76164 
 76165 
 76166 
 76167 
 76168 
 76169 private function reportRestarting($command)
 76170 {
 76171 $text = sprintf('Process restarting (%s)', $this->getEnvAllow());
 76172 $this->output($text);
 76173 $text = 'Running '.$command;
 76174 $this->output($text);
 76175 }
 76176 
 76177 
 76178 
 76179 
 76180 
 76181 
 76182 private function getEnvAllow()
 76183 {
 76184 return $this->envAllowXdebug.'='.getenv($this->envAllowXdebug);
 76185 }
 76186 
 76187 
 76188 
 76189 
 76190 
 76191 
 76192 private function getLoadedMessage()
 76193 {
 76194 $loaded = $this->loaded !== null ? sprintf('loaded %s', $this->loaded) : 'not loaded';
 76195 return 'The Xdebug extension is '.$loaded;
 76196 }
 76197 }
 76198 <?php
 76199 
 76200 
 76201 
 76202 
 76203 
 76204 
 76205 
 76206 
 76207 
 76208 
 76209 namespace Composer\XdebugHandler;
 76210 
 76211 use Composer\Pcre\Preg;
 76212 use Psr\Log\LoggerInterface;
 76213 
 76214 
 76215 
 76216 
 76217 
 76218 
 76219 class XdebugHandler
 76220 {
 76221 const SUFFIX_ALLOW = '_ALLOW_XDEBUG';
 76222 const SUFFIX_INIS = '_ORIGINAL_INIS';
 76223 const RESTART_ID = 'internal';
 76224 const RESTART_SETTINGS = 'XDEBUG_HANDLER_SETTINGS';
 76225 const DEBUG = 'XDEBUG_HANDLER_DEBUG';
 76226 
 76227 
 76228 protected $tmpIni;
 76229 
 76230 
 76231 private static $inRestart;
 76232 
 76233 
 76234 private static $name;
 76235 
 76236 
 76237 private static $skipped;
 76238 
 76239 
 76240 private static $xdebugActive;
 76241 
 76242 
 76243 private static $xdebugMode;
 76244 
 76245 
 76246 private static $xdebugVersion;
 76247 
 76248 
 76249 private $cli;
 76250 
 76251 
 76252 private $debug;
 76253 
 76254 
 76255 private $envAllowXdebug;
 76256 
 76257 
 76258 private $envOriginalInis;
 76259 
 76260 
 76261 private $persistent;
 76262 
 76263 
 76264 private $script;
 76265 
 76266 
 76267 private $statusWriter;
 76268 
 76269 
 76270 
 76271 
 76272 
 76273 
 76274 
 76275 
 76276 
 76277 
 76278 
 76279 public function __construct($envPrefix)
 76280 {
 76281 if (!is_string($envPrefix) || $envPrefix === '') {
 76282 throw new \RuntimeException('Invalid constructor parameter');
 76283 }
 76284 
 76285 self::$name = strtoupper($envPrefix);
 76286 $this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW;
 76287 $this->envOriginalInis = self::$name.self::SUFFIX_INIS;
 76288 
 76289 self::setXdebugDetails();
 76290 self::$inRestart = false;
 76291 
 76292 if ($this->cli = PHP_SAPI === 'cli') {
 76293 $this->debug = (string) getenv(self::DEBUG);
 76294 }
 76295 
 76296 $this->statusWriter = new Status($this->envAllowXdebug, (bool) $this->debug);
 76297 }
 76298 
 76299 
 76300 
 76301 
 76302 
 76303 
 76304 
 76305 
 76306 public function setLogger(LoggerInterface $logger)
 76307 {
 76308 $this->statusWriter->setLogger($logger);
 76309 return $this;
 76310 }
 76311 
 76312 
 76313 
 76314 
 76315 
 76316 
 76317 
 76318 
 76319 public function setMainScript($script)
 76320 {
 76321 $this->script = $script;
 76322 return $this;
 76323 }
 76324 
 76325 
 76326 
 76327 
 76328 
 76329 
 76330 public function setPersistent()
 76331 {
 76332 $this->persistent = true;
 76333 return $this;
 76334 }
 76335 
 76336 
 76337 
 76338 
 76339 
 76340 
 76341 
 76342 
 76343 
 76344 
 76345 public function check()
 76346 {
 76347 $this->notify(Status::CHECK, self::$xdebugVersion.'|'.self::$xdebugMode);
 76348 $envArgs = explode('|', (string) getenv($this->envAllowXdebug));
 76349 
 76350 if (!((bool) $envArgs[0]) && $this->requiresRestart(self::$xdebugActive)) {
 76351 
 76352 $this->notify(Status::RESTART);
 76353 
 76354 if ($this->prepareRestart()) {
 76355 $command = $this->getCommand();
 76356 $this->restart($command);
 76357 }
 76358 return;
 76359 }
 76360 
 76361 if (self::RESTART_ID === $envArgs[0] && count($envArgs) === 5) {
 76362 
 76363 $this->notify(Status::RESTARTED);
 76364 
 76365 Process::setEnv($this->envAllowXdebug);
 76366 self::$inRestart = true;
 76367 
 76368 if (self::$xdebugVersion === null) {
 76369 
 76370 self::$skipped = $envArgs[1];
 76371 }
 76372 
 76373 $this->tryEnableSignals();
 76374 
 76375 
 76376 $this->setEnvRestartSettings($envArgs);
 76377 return;
 76378 }
 76379 
 76380 $this->notify(Status::NORESTART);
 76381 $settings = self::getRestartSettings();
 76382 
 76383 if ($settings !== null) {
 76384 
 76385 $this->syncSettings($settings);
 76386 }
 76387 }
 76388 
 76389 
 76390 
 76391 
 76392 
 76393 
 76394 
 76395 
 76396 
 76397 public static function getAllIniFiles()
 76398 {
 76399 if (self::$name !== null) {
 76400 $env = getenv(self::$name.self::SUFFIX_INIS);
 76401 
 76402 if (false !== $env) {
 76403 return explode(PATH_SEPARATOR, $env);
 76404 }
 76405 }
 76406 
 76407 $paths = array((string) php_ini_loaded_file());
 76408 $scanned = php_ini_scanned_files();
 76409 
 76410 if ($scanned !== false) {
 76411 $paths = array_merge($paths, array_map('trim', explode(',', $scanned)));
 76412 }
 76413 
 76414 return $paths;
 76415 }
 76416 
 76417 
 76418 
 76419 
 76420 
 76421 
 76422 
 76423 
 76424 
 76425 
 76426 public static function getRestartSettings()
 76427 {
 76428 $envArgs = explode('|', (string) getenv(self::RESTART_SETTINGS));
 76429 
 76430 if (count($envArgs) !== 6
 76431 || (!self::$inRestart && php_ini_loaded_file() !== $envArgs[0])) {
 76432 return null;
 76433 }
 76434 
 76435 return array(
 76436 'tmpIni' => $envArgs[0],
 76437 'scannedInis' => (bool) $envArgs[1],
 76438 'scanDir' => '*' === $envArgs[2] ? false : $envArgs[2],
 76439 'phprc' => '*' === $envArgs[3] ? false : $envArgs[3],
 76440 'inis' => explode(PATH_SEPARATOR, $envArgs[4]),
 76441 'skipped' => $envArgs[5],
 76442 );
 76443 }
 76444 
 76445 
 76446 
 76447 
 76448 
 76449 
 76450 public static function getSkippedVersion()
 76451 {
 76452 return (string) self::$skipped;
 76453 }
 76454 
 76455 
 76456 
 76457 
 76458 
 76459 
 76460 
 76461 
 76462 
 76463 public static function isXdebugActive()
 76464 {
 76465 self::setXdebugDetails();
 76466 return self::$xdebugActive;
 76467 }
 76468 
 76469 
 76470 
 76471 
 76472 
 76473 
 76474 
 76475 
 76476 
 76477 
 76478 
 76479 protected function requiresRestart($default)
 76480 {
 76481 return $default;
 76482 }
 76483 
 76484 
 76485 
 76486 
 76487 
 76488 
 76489 
 76490 
 76491 
 76492 
 76493 protected function restart($command)
 76494 {
 76495 $this->doRestart($command);
 76496 }
 76497 
 76498 
 76499 
 76500 
 76501 
 76502 
 76503 
 76504 
 76505 
 76506 private function doRestart(array $command)
 76507 {
 76508 $this->tryEnableSignals();
 76509 $this->notify(Status::RESTARTING, implode(' ', $command));
 76510 
 76511 if (PHP_VERSION_ID >= 70400) {
 76512 $cmd = $command;
 76513 } else {
 76514 $cmd = Process::escapeShellCommand($command);
 76515 if (defined('PHP_WINDOWS_VERSION_BUILD')) {
 76516 
 76517 $cmd = '"'.$cmd.'"';
 76518 }
 76519 }
 76520 
 76521 $process = proc_open($cmd, array(), $pipes);
 76522 if (is_resource($process)) {
 76523 $exitCode = proc_close($process);
 76524 }
 76525 
 76526 if (!isset($exitCode)) {
 76527 
 76528 $this->notify(Status::ERROR, 'Unable to restart process');
 76529 $exitCode = -1;
 76530 } else {
 76531 $this->notify(Status::INFO, 'Restarted process exited '.$exitCode);
 76532 }
 76533 
 76534 if ($this->debug === '2') {
 76535 $this->notify(Status::INFO, 'Temp ini saved: '.$this->tmpIni);
 76536 } else {
 76537 @unlink((string) $this->tmpIni);
 76538 }
 76539 
 76540 exit($exitCode);
 76541 }
 76542 
 76543 
 76544 
 76545 
 76546 
 76547 
 76548 
 76549 
 76550 
 76551 
 76552 
 76553 private function prepareRestart()
 76554 {
 76555 $error = null;
 76556 $iniFiles = self::getAllIniFiles();
 76557 $scannedInis = count($iniFiles) > 1;
 76558 $tmpDir = sys_get_temp_dir();
 76559 
 76560 if (!$this->cli) {
 76561 $error = 'Unsupported SAPI: '.PHP_SAPI;
 76562 } elseif (!defined('PHP_BINARY')) {
 76563 $error = 'PHP version is too old: '.PHP_VERSION;
 76564 } elseif (!$this->checkConfiguration($info)) {
 76565 $error = $info;
 76566 } elseif (!$this->checkScanDirConfig()) {
 76567 $error = 'PHP version does not report scanned inis: '.PHP_VERSION;
 76568 } elseif (!$this->checkMainScript()) {
 76569 $error = 'Unable to access main script: '.$this->script;
 76570 } elseif (!$this->writeTmpIni($iniFiles, $tmpDir, $error)) {
 76571 $error = $error !== null ? $error : 'Unable to create temp ini file at: '.$tmpDir;
 76572 } elseif (!$this->setEnvironment($scannedInis, $iniFiles)) {
 76573 $error = 'Unable to set environment variables';
 76574 }
 76575 
 76576 if ($error !== null) {
 76577 $this->notify(Status::ERROR, $error);
 76578 }
 76579 
 76580 return $error === null;
 76581 }
 76582 
 76583 
 76584 
 76585 
 76586 
 76587 
 76588 
 76589 
 76590 
 76591 
 76592 private function writeTmpIni(array $iniFiles, $tmpDir, &$error)
 76593 {
 76594 if (($tmpfile = @tempnam($tmpDir, '')) === false) {
 76595 return false;
 76596 }
 76597 
 76598 $this->tmpIni = $tmpfile;
 76599 
 76600 
 76601 if ($iniFiles[0] === '') {
 76602 array_shift($iniFiles);
 76603 }
 76604 
 76605 $content = '';
 76606 $sectionRegex = '/^\s*\[(?:PATH|HOST)\s*=/mi';
 76607 $xdebugRegex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi';
 76608 
 76609 foreach ($iniFiles as $file) {
 76610 
 76611 if (($data = @file_get_contents($file)) === false) {
 76612 $error = 'Unable to read ini: '.$file;
 76613 return false;
 76614 }
 76615 
 76616 if (Preg::isMatchWithOffsets($sectionRegex, $data, $matches, PREG_OFFSET_CAPTURE)) {
 76617 $data = substr($data, 0, $matches[0][1]);
 76618 }
 76619 $content .= Preg::replace($xdebugRegex, ';$1', $data).PHP_EOL;
 76620 }
 76621 
 76622 
 76623 $config = parse_ini_string($content);
 76624 $loaded = ini_get_all(null, false);
 76625 
 76626 if (false === $config || false === $loaded) {
 76627 $error = 'Unable to parse ini data';
 76628 return false;
 76629 }
 76630 
 76631 $content .= $this->mergeLoadedConfig($loaded, $config);
 76632 
 76633 
 76634 $content .= 'opcache.enable_cli=0'.PHP_EOL;
 76635 
 76636 return (bool) @file_put_contents($this->tmpIni, $content);
 76637 }
 76638 
 76639 
 76640 
 76641 
 76642 
 76643 
 76644 private function getCommand()
 76645 {
 76646 $php = array(PHP_BINARY);
 76647 $args = array_slice($_SERVER['argv'], 1);
 76648 
 76649 if (!$this->persistent) {
 76650 
 76651 array_push($php, '-n', '-c', $this->tmpIni);
 76652 }
 76653 
 76654 return array_merge($php, array($this->script), $args);
 76655 }
 76656 
 76657 
 76658 
 76659 
 76660 
 76661 
 76662 
 76663 
 76664 
 76665 
 76666 
 76667 private function setEnvironment($scannedInis, array $iniFiles)
 76668 {
 76669 $scanDir = getenv('PHP_INI_SCAN_DIR');
 76670 $phprc = getenv('PHPRC');
 76671 
 76672 
 76673 if (!putenv($this->envOriginalInis.'='.implode(PATH_SEPARATOR, $iniFiles))) {
 76674 return false;
 76675 }
 76676 
 76677 if ($this->persistent) {
 76678 
 76679 if (!putenv('PHP_INI_SCAN_DIR=') || !putenv('PHPRC='.$this->tmpIni)) {
 76680 return false;
 76681 }
 76682 }
 76683 
 76684 
 76685 $envArgs = array(
 76686 self::RESTART_ID,
 76687 self::$xdebugVersion,
 76688 (int) $scannedInis,
 76689 false === $scanDir ? '*' : $scanDir,
 76690 false === $phprc ? '*' : $phprc,
 76691 );
 76692 
 76693 return putenv($this->envAllowXdebug.'='.implode('|', $envArgs));
 76694 }
 76695 
 76696 
 76697 
 76698 
 76699 
 76700 
 76701 
 76702 
 76703 
 76704 private function notify($op, $data = null)
 76705 {
 76706 $this->statusWriter->report($op, $data);
 76707 }
 76708 
 76709 
 76710 
 76711 
 76712 
 76713 
 76714 
 76715 
 76716 
 76717 private function mergeLoadedConfig(array $loadedConfig, array $iniConfig)
 76718 {
 76719 $content = '';
 76720 
 76721 foreach ($loadedConfig as $name => $value) {
 76722 
 76723 if (!is_string($value)
 76724 || strpos($name, 'xdebug') === 0
 76725 || $name === 'apc.mmap_file_mask') {
 76726 continue;
 76727 }
 76728 
 76729 if (!isset($iniConfig[$name]) || $iniConfig[$name] !== $value) {
 76730 
 76731 $content .= $name.'="'.addcslashes($value, '\\"').'"'.PHP_EOL;
 76732 }
 76733 }
 76734 
 76735 return $content;
 76736 }
 76737 
 76738 
 76739 
 76740 
 76741 
 76742 
 76743 private function checkMainScript()
 76744 {
 76745 if (null !== $this->script) {
 76746 
 76747 return file_exists($this->script) || '--' === $this->script;
 76748 }
 76749 
 76750 if (file_exists($this->script = $_SERVER['argv'][0])) {
 76751 return true;
 76752 }
 76753 
 76754 
 76755 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
 76756 $main = end($trace);
 76757 
 76758 if ($main !== false && isset($main['file'])) {
 76759 return file_exists($this->script = $main['file']);
 76760 }
 76761 
 76762 return false;
 76763 }
 76764 
 76765 
 76766 
 76767 
 76768 
 76769 
 76770 
 76771 
 76772 private function setEnvRestartSettings($envArgs)
 76773 {
 76774 $settings = array(
 76775 php_ini_loaded_file(),
 76776 $envArgs[2],
 76777 $envArgs[3],
 76778 $envArgs[4],
 76779 getenv($this->envOriginalInis),
 76780 self::$skipped,
 76781 );
 76782 
 76783 Process::setEnv(self::RESTART_SETTINGS, implode('|', $settings));
 76784 }
 76785 
 76786 
 76787 
 76788 
 76789 
 76790 
 76791 
 76792 
 76793 
 76794 private function syncSettings(array $settings)
 76795 {
 76796 if (false === getenv($this->envOriginalInis)) {
 76797 
 76798 Process::setEnv($this->envOriginalInis, implode(PATH_SEPARATOR, $settings['inis']));
 76799 }
 76800 
 76801 self::$skipped = $settings['skipped'];
 76802 $this->notify(Status::INFO, 'Process called with existing restart settings');
 76803 }
 76804 
 76805 
 76806 
 76807 
 76808 
 76809 
 76810 
 76811 
 76812 
 76813 private function checkScanDirConfig()
 76814 {
 76815 if (PHP_VERSION_ID >= 70113 && PHP_VERSION_ID !== 70200) {
 76816 return true;
 76817 }
 76818 
 76819 return ((string) getenv('PHP_INI_SCAN_DIR') === '')
 76820 || PHP_CONFIG_FILE_SCAN_DIR !== '';
 76821 }
 76822 
 76823 
 76824 
 76825 
 76826 
 76827 
 76828 
 76829 private function checkConfiguration(&$info)
 76830 {
 76831 if (!function_exists('proc_open')) {
 76832 $info = 'proc_open function is disabled';
 76833 return false;
 76834 }
 76835 
 76836 if (extension_loaded('uopz') && !((bool) ini_get('uopz.disable'))) {
 76837 
 76838 if (function_exists('uopz_allow_exit')) {
 76839 @uopz_allow_exit(true);
 76840 } else {
 76841 $info = 'uopz extension is not compatible';
 76842 return false;
 76843 }
 76844 }
 76845 
 76846 
 76847 if (defined('PHP_WINDOWS_VERSION_BUILD') && PHP_VERSION_ID < 70400) {
 76848 $workingDir = getcwd();
 76849 
 76850 if ($workingDir === false) {
 76851 $info = 'unable to determine working directory';
 76852 return false;
 76853 }
 76854 
 76855 if (0 === strpos($workingDir, '\\\\')) {
 76856 $info = 'cmd.exe does not support UNC paths: '.$workingDir;
 76857 return false;
 76858 }
 76859 }
 76860 
 76861 return true;
 76862 }
 76863 
 76864 
 76865 
 76866 
 76867 
 76868 
 76869 
 76870 
 76871 private function tryEnableSignals()
 76872 {
 76873 if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
 76874 pcntl_async_signals(true);
 76875 $message = 'Async signals enabled';
 76876 
 76877 if (!self::$inRestart) {
 76878 
 76879 pcntl_signal(SIGINT, SIG_IGN);
 76880 } elseif (is_int(pcntl_signal_get_handler(SIGINT))) {
 76881 
 76882 pcntl_signal(SIGINT, SIG_DFL);
 76883 }
 76884 }
 76885 
 76886 if (!self::$inRestart && function_exists('sapi_windows_set_ctrl_handler')) {
 76887 
 76888 
 76889 
 76890 sapi_windows_set_ctrl_handler(function ($evt) {});
 76891 }
 76892 }
 76893 
 76894 
 76895 
 76896 
 76897 
 76898 
 76899 private static function setXdebugDetails()
 76900 {
 76901 if (self::$xdebugActive !== null) {
 76902 return;
 76903 }
 76904 
 76905 self::$xdebugActive = false;
 76906 if (!extension_loaded('xdebug')) {
 76907 return;
 76908 }
 76909 
 76910 $version = phpversion('xdebug');
 76911 self::$xdebugVersion = $version !== false ? $version : 'unknown';
 76912 
 76913 if (version_compare(self::$xdebugVersion, '3.1', '>=')) {
 76914 $modes = xdebug_info('mode');
 76915 self::$xdebugMode = count($modes) === 0 ? 'off' : implode(',', $modes);
 76916 self::$xdebugActive = self::$xdebugMode !== 'off';
 76917 return;
 76918 }
 76919 
 76920 
 76921 $iniMode = ini_get('xdebug.mode');
 76922 if ($iniMode === false) {
 76923 self::$xdebugActive = true;
 76924 return;
 76925 }
 76926 
 76927 
 76928 $envMode = (string) getenv('XDEBUG_MODE');
 76929 if ($envMode !== '') {
 76930 self::$xdebugMode = $envMode;
 76931 } else {
 76932 self::$xdebugMode = $iniMode !== '' ? $iniMode : 'off';
 76933 }
 76934 
 76935 
 76936 if (Preg::isMatch('/^,+$/', str_replace(' ', '', self::$xdebugMode))) {
 76937 self::$xdebugMode = 'off';
 76938 }
 76939 
 76940 self::$xdebugActive = self::$xdebugMode !== 'off';
 76941 }
 76942 }
 76943 
 76944 MIT License
 76945 
 76946 Copyright (c) 2016
 76947 
 76948 Permission is hereby granted, free of charge, to any person obtaining a copy
 76949 of this software and associated documentation files (the "Software"), to deal
 76950 in the Software without restriction, including without limitation the rights
 76951 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 76952 copies of the Software, and to permit persons to whom the Software is
 76953 furnished to do so, subject to the following conditions:
 76954 
 76955 The above copyright notice and this permission notice shall be included in all
 76956 copies or substantial portions of the Software.
 76957 
 76958 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 76959 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 76960 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 76961 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 76962 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 76963 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 76964 SOFTWARE.
 76965 
 76966 <?php
 76967 
 76968 
 76969 
 76970 
 76971 
 76972 
 76973 
 76974 
 76975 namespace JsonSchema\Constraints;
 76976 
 76977 use JsonSchema\Entity\JsonPointer;
 76978 use JsonSchema\Exception\InvalidArgumentException;
 76979 use JsonSchema\Exception\ValidationException;
 76980 use JsonSchema\Validator;
 76981 
 76982 
 76983 
 76984 
 76985 
 76986 class BaseConstraint
 76987 {
 76988 
 76989 
 76990 
 76991 protected $errors = array();
 76992 
 76993 
 76994 
 76995 
 76996 protected $errorMask = Validator::ERROR_NONE;
 76997 
 76998 
 76999 
 77000 
 77001 protected $factory;
 77002 
 77003 
 77004 
 77005 
 77006 public function __construct(Factory $factory = null)
 77007 {
 77008 $this->factory = $factory ?: new Factory();
 77009 }
 77010 
 77011 public function addError(JsonPointer $path = null, $message, $constraint = '', array $more = null)
 77012 {
 77013 $error = array(
 77014 'property' => $this->convertJsonPointerIntoPropertyPath($path ?: new JsonPointer('')),
 77015 'pointer' => ltrim(strval($path ?: new JsonPointer('')), '#'),
 77016 'message' => $message,
 77017 'constraint' => $constraint,
 77018 'context' => $this->factory->getErrorContext(),
 77019 );
 77020 
 77021 if ($this->factory->getConfig(Constraint::CHECK_MODE_EXCEPTIONS)) {
 77022 throw new ValidationException(sprintf('Error validating %s: %s', $error['pointer'], $error['message']));
 77023 }
 77024 
 77025 if (is_array($more) && count($more) > 0) {
 77026 $error += $more;
 77027 }
 77028 
 77029 $this->errors[] = $error;
 77030 $this->errorMask |= $error['context'];
 77031 }
 77032 
 77033 public function addErrors(array $errors)
 77034 {
 77035 if ($errors) {
 77036 $this->errors = array_merge($this->errors, $errors);
 77037 $errorMask = &$this->errorMask;
 77038 array_walk($errors, function ($error) use (&$errorMask) {
 77039 if (isset($error['context'])) {
 77040 $errorMask |= $error['context'];
 77041 }
 77042 });
 77043 }
 77044 }
 77045 
 77046 public function getErrors($errorContext = Validator::ERROR_ALL)
 77047 {
 77048 if ($errorContext === Validator::ERROR_ALL) {
 77049 return $this->errors;
 77050 }
 77051 
 77052 return array_filter($this->errors, function ($error) use ($errorContext) {
 77053 if ($errorContext & $error['context']) {
 77054 return true;
 77055 }
 77056 });
 77057 }
 77058 
 77059 public function numErrors($errorContext = Validator::ERROR_ALL)
 77060 {
 77061 if ($errorContext === Validator::ERROR_ALL) {
 77062 return count($this->errors);
 77063 }
 77064 
 77065 return count($this->getErrors($errorContext));
 77066 }
 77067 
 77068 public function isValid()
 77069 {
 77070 return !$this->getErrors();
 77071 }
 77072 
 77073 
 77074 
 77075 
 77076 
 77077 public function reset()
 77078 {
 77079 $this->errors = array();
 77080 $this->errorMask = Validator::ERROR_NONE;
 77081 }
 77082 
 77083 
 77084 
 77085 
 77086 
 77087 
 77088 public function getErrorMask()
 77089 {
 77090 return $this->errorMask;
 77091 }
 77092 
 77093 
 77094 
 77095 
 77096 
 77097 
 77098 
 77099 
 77100 public static function arrayToObjectRecursive($array)
 77101 {
 77102 $json = json_encode($array);
 77103 if (json_last_error() !== \JSON_ERROR_NONE) {
 77104 $message = 'Unable to encode schema array as JSON';
 77105 if (function_exists('json_last_error_msg')) {
 77106 $message .= ': ' . json_last_error_msg();
 77107 }
 77108 throw new InvalidArgumentException($message);
 77109 }
 77110 
 77111 return (object) json_decode($json);
 77112 }
 77113 }
 77114 <?php
 77115 
 77116 
 77117 
 77118 
 77119 
 77120 
 77121 
 77122 
 77123 namespace JsonSchema\Constraints;
 77124 
 77125 use JsonSchema\Entity\JsonPointer;
 77126 
 77127 
 77128 
 77129 
 77130 
 77131 
 77132 
 77133 class CollectionConstraint extends Constraint
 77134 {
 77135 
 77136 
 77137 
 77138 public function check(&$value, $schema = null, JsonPointer $path = null, $i = null)
 77139 {
 77140 
 77141 if (isset($schema->minItems) && count($value) < $schema->minItems) {
 77142 $this->addError($path, 'There must be a minimum of ' . $schema->minItems . ' items in the array', 'minItems', array('minItems' => $schema->minItems));
 77143 }
 77144 
 77145 
 77146 if (isset($schema->maxItems) && count($value) > $schema->maxItems) {
 77147 $this->addError($path, 'There must be a maximum of ' . $schema->maxItems . ' items in the array', 'maxItems', array('maxItems' => $schema->maxItems));
 77148 }
 77149 
 77150 
 77151 if (isset($schema->uniqueItems) && $schema->uniqueItems) {
 77152 $unique = $value;
 77153 if (is_array($value) && count($value)) {
 77154 $unique = array_map(function ($e) {
 77155 return var_export($e, true);
 77156 }, $value);
 77157 }
 77158 if (count(array_unique($unique)) != count($value)) {
 77159 $this->addError($path, 'There are no duplicates allowed in the array', 'uniqueItems');
 77160 }
 77161 }
 77162 
 77163 
 77164 if (isset($schema->items)) {
 77165 $this->validateItems($value, $schema, $path, $i);
 77166 }
 77167 }
 77168 
 77169 
 77170 
 77171 
 77172 
 77173 
 77174 
 77175 
 77176 
 77177 protected function validateItems(&$value, $schema = null, JsonPointer $path = null, $i = null)
 77178 {
 77179 if (is_object($schema->items)) {
 77180 
 77181 foreach ($value as $k => &$v) {
 77182 $initErrors = $this->getErrors();
 77183 
 77184 
 77185 $this->checkUndefined($v, $schema->items, $path, $k);
 77186 
 77187 
 77188 if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) {
 77189 $secondErrors = $this->getErrors();
 77190 $this->checkUndefined($v, $schema->additionalItems, $path, $k);
 77191 }
 77192 
 77193 
 77194 if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) {
 77195 $this->errors = $secondErrors;
 77196 } elseif (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) {
 77197 $this->errors = $initErrors;
 77198 }
 77199 }
 77200 unset($v); 
 77201 
 77202 } else {
 77203 
 77204 foreach ($value as $k => &$v) {
 77205 if (array_key_exists($k, $schema->items)) {
 77206 $this->checkUndefined($v, $schema->items[$k], $path, $k);
 77207 } else {
 77208 
 77209 if (property_exists($schema, 'additionalItems')) {
 77210 if ($schema->additionalItems !== false) {
 77211 $this->checkUndefined($v, $schema->additionalItems, $path, $k);
 77212 } else {
 77213 $this->addError(
 77214 $path, 'The item ' . $i . '[' . $k . '] is not defined and the definition does not allow additional items', 'additionalItems', array('additionalItems' => $schema->additionalItems));
 77215 }
 77216 } else {
 77217 
 77218 $this->checkUndefined($v, new \stdClass(), $path, $k);
 77219 }
 77220 }
 77221 }
 77222 unset($v); 
 77223 
 77224 
 77225 
 77226 if (count($value) > 0) {
 77227 for ($k = count($value); $k < count($schema->items); $k++) {
 77228 $undefinedInstance = $this->factory->createInstanceFor('undefined');
 77229 $this->checkUndefined($undefinedInstance, $schema->items[$k], $path, $k);
 77230 }
 77231 }
 77232 }
 77233 }
 77234 }
 77235 <?php
 77236 
 77237 
 77238 
 77239 
 77240 
 77241 
 77242 
 77243 
 77244 namespace JsonSchema\Constraints;
 77245 
 77246 use JsonSchema\Entity\JsonPointer;
 77247 
 77248 
 77249 
 77250 
 77251 
 77252 
 77253 
 77254 abstract class Constraint extends BaseConstraint implements ConstraintInterface
 77255 {
 77256 protected $inlineSchemaProperty = '$schema';
 77257 
 77258 const CHECK_MODE_NONE = 0x00000000;
 77259 const CHECK_MODE_NORMAL = 0x00000001;
 77260 const CHECK_MODE_TYPE_CAST = 0x00000002;
 77261 const CHECK_MODE_COERCE_TYPES = 0x00000004;
 77262 const CHECK_MODE_APPLY_DEFAULTS = 0x00000008;
 77263 const CHECK_MODE_EXCEPTIONS = 0x00000010;
 77264 const CHECK_MODE_DISABLE_FORMAT = 0x00000020;
 77265 const CHECK_MODE_ONLY_REQUIRED_DEFAULTS = 0x00000080;
 77266 const CHECK_MODE_VALIDATE_SCHEMA = 0x00000100;
 77267 
 77268 
 77269 
 77270 
 77271 
 77272 
 77273 
 77274 
 77275 
 77276 protected function incrementPath(JsonPointer $path = null, $i)
 77277 {
 77278 $path = $path ?: new JsonPointer('');
 77279 
 77280 if ($i === null || $i === '') {
 77281 return $path;
 77282 }
 77283 
 77284 $path = $path->withPropertyPaths(
 77285 array_merge(
 77286 $path->getPropertyPaths(),
 77287 array($i)
 77288 )
 77289 );
 77290 
 77291 return $path;
 77292 }
 77293 
 77294 
 77295 
 77296 
 77297 
 77298 
 77299 
 77300 
 77301 
 77302 protected function checkArray(&$value, $schema = null, JsonPointer $path = null, $i = null)
 77303 {
 77304 $validator = $this->factory->createInstanceFor('collection');
 77305 $validator->check($value, $schema, $path, $i);
 77306 
 77307 $this->addErrors($validator->getErrors());
 77308 }
 77309 
 77310 
 77311 
 77312 
 77313 
 77314 
 77315 
 77316 
 77317 
 77318 
 77319 
 77320 protected function checkObject(&$value, $schema = null, JsonPointer $path = null, $properties = null,
 77321 $additionalProperties = null, $patternProperties = null, $appliedDefaults = array())
 77322 {
 77323 $validator = $this->factory->createInstanceFor('object');
 77324 $validator->check($value, $schema, $path, $properties, $additionalProperties, $patternProperties, $appliedDefaults);
 77325 
 77326 $this->addErrors($validator->getErrors());
 77327 }
 77328 
 77329 
 77330 
 77331 
 77332 
 77333 
 77334 
 77335 
 77336 
 77337 protected function checkType(&$value, $schema = null, JsonPointer $path = null, $i = null)
 77338 {
 77339 $validator = $this->factory->createInstanceFor('type');
 77340 $validator->check($value, $schema, $path, $i);
 77341 
 77342 $this->addErrors($validator->getErrors());
 77343 }
 77344 
 77345 
 77346 
 77347 
 77348 
 77349 
 77350 
 77351 
 77352 
 77353 protected function checkUndefined(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false)
 77354 {
 77355 $validator = $this->factory->createInstanceFor('undefined');
 77356 
 77357 $validator->check($value, $this->factory->getSchemaStorage()->resolveRefSchema($schema), $path, $i, $fromDefault);
 77358 
 77359 $this->addErrors($validator->getErrors());
 77360 }
 77361 
 77362 
 77363 
 77364 
 77365 
 77366 
 77367 
 77368 
 77369 
 77370 protected function checkString($value, $schema = null, JsonPointer $path = null, $i = null)
 77371 {
 77372 $validator = $this->factory->createInstanceFor('string');
 77373 $validator->check($value, $schema, $path, $i);
 77374 
 77375 $this->addErrors($validator->getErrors());
 77376 }
 77377 
 77378 
 77379 
 77380 
 77381 
 77382 
 77383 
 77384 
 77385 
 77386 protected function checkNumber($value, $schema = null, JsonPointer $path = null, $i = null)
 77387 {
 77388 $validator = $this->factory->createInstanceFor('number');
 77389 $validator->check($value, $schema, $path, $i);
 77390 
 77391 $this->addErrors($validator->getErrors());
 77392 }
 77393 
 77394 
 77395 
 77396 
 77397 
 77398 
 77399 
 77400 
 77401 
 77402 protected function checkEnum($value, $schema = null, JsonPointer $path = null, $i = null)
 77403 {
 77404 $validator = $this->factory->createInstanceFor('enum');
 77405 $validator->check($value, $schema, $path, $i);
 77406 
 77407 $this->addErrors($validator->getErrors());
 77408 }
 77409 
 77410 
 77411 
 77412 
 77413 
 77414 
 77415 
 77416 
 77417 
 77418 protected function checkFormat($value, $schema = null, JsonPointer $path = null, $i = null)
 77419 {
 77420 $validator = $this->factory->createInstanceFor('format');
 77421 $validator->check($value, $schema, $path, $i);
 77422 
 77423 $this->addErrors($validator->getErrors());
 77424 }
 77425 
 77426 
 77427 
 77428 
 77429 
 77430 
 77431 protected function getTypeCheck()
 77432 {
 77433 return $this->factory->getTypeCheck();
 77434 }
 77435 
 77436 
 77437 
 77438 
 77439 
 77440 
 77441 protected function convertJsonPointerIntoPropertyPath(JsonPointer $pointer)
 77442 {
 77443 $result = array_map(
 77444 function ($path) {
 77445 return sprintf(is_numeric($path) ? '[%d]' : '.%s', $path);
 77446 },
 77447 $pointer->getPropertyPaths()
 77448 );
 77449 
 77450 return trim(implode('', $result), '.');
 77451 }
 77452 }
 77453 <?php
 77454 
 77455 
 77456 
 77457 
 77458 
 77459 
 77460 
 77461 
 77462 namespace JsonSchema\Constraints;
 77463 
 77464 use JsonSchema\Entity\JsonPointer;
 77465 
 77466 
 77467 
 77468 
 77469 
 77470 
 77471 interface ConstraintInterface
 77472 {
 77473 
 77474 
 77475 
 77476 
 77477 
 77478 public function getErrors();
 77479 
 77480 
 77481 
 77482 
 77483 
 77484 
 77485 public function addErrors(array $errors);
 77486 
 77487 
 77488 
 77489 
 77490 
 77491 
 77492 
 77493 
 77494 
 77495 public function addError(JsonPointer $path = null, $message, $constraint='', array $more = null);
 77496 
 77497 
 77498 
 77499 
 77500 
 77501 
 77502 public function isValid();
 77503 
 77504 
 77505 
 77506 
 77507 
 77508 
 77509 
 77510 
 77511 
 77512 
 77513 
 77514 
 77515 
 77516 public function check(&$value, $schema = null, JsonPointer $path = null, $i = null);
 77517 }
 77518 <?php
 77519 
 77520 
 77521 
 77522 
 77523 
 77524 
 77525 
 77526 
 77527 namespace JsonSchema\Constraints;
 77528 
 77529 use JsonSchema\Entity\JsonPointer;
 77530 
 77531 
 77532 
 77533 
 77534 
 77535 
 77536 
 77537 class EnumConstraint extends Constraint
 77538 {
 77539 
 77540 
 77541 
 77542 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
 77543 {
 77544 
 77545 if ($element instanceof UndefinedConstraint && (!isset($schema->required) || !$schema->required)) {
 77546 return;
 77547 }
 77548 $type = gettype($element);
 77549 
 77550 foreach ($schema->enum as $enum) {
 77551 $enumType = gettype($enum);
 77552 if ($this->factory->getConfig(self::CHECK_MODE_TYPE_CAST) && $type == 'array' && $enumType == 'object') {
 77553 if ((object) $element == $enum) {
 77554 return;
 77555 }
 77556 }
 77557 
 77558 if ($type === gettype($enum)) {
 77559 if ($type == 'object') {
 77560 if ($element == $enum) {
 77561 return;
 77562 }
 77563 } elseif ($element === $enum) {
 77564 return;
 77565 }
 77566 }
 77567 }
 77568 
 77569 $this->addError($path, 'Does not have a value in the enumeration ' . json_encode($schema->enum), 'enum', array('enum' => $schema->enum));
 77570 }
 77571 }
 77572 <?php
 77573 
 77574 
 77575 
 77576 
 77577 
 77578 
 77579 
 77580 
 77581 namespace JsonSchema\Constraints;
 77582 
 77583 use JsonSchema\Exception\InvalidArgumentException;
 77584 use JsonSchema\SchemaStorage;
 77585 use JsonSchema\SchemaStorageInterface;
 77586 use JsonSchema\Uri\UriRetriever;
 77587 use JsonSchema\UriRetrieverInterface;
 77588 use JsonSchema\Validator;
 77589 
 77590 
 77591 
 77592 
 77593 class Factory
 77594 {
 77595 
 77596 
 77597 
 77598 protected $schemaStorage;
 77599 
 77600 
 77601 
 77602 
 77603 protected $uriRetriever;
 77604 
 77605 
 77606 
 77607 
 77608 private $checkMode = Constraint::CHECK_MODE_NORMAL;
 77609 
 77610 
 77611 
 77612 
 77613 private $typeCheck = array();
 77614 
 77615 
 77616 
 77617 
 77618 protected $errorContext = Validator::ERROR_DOCUMENT_VALIDATION;
 77619 
 77620 
 77621 
 77622 
 77623 protected $constraintMap = array(
 77624 'array' => 'JsonSchema\Constraints\CollectionConstraint',
 77625 'collection' => 'JsonSchema\Constraints\CollectionConstraint',
 77626 'object' => 'JsonSchema\Constraints\ObjectConstraint',
 77627 'type' => 'JsonSchema\Constraints\TypeConstraint',
 77628 'undefined' => 'JsonSchema\Constraints\UndefinedConstraint',
 77629 'string' => 'JsonSchema\Constraints\StringConstraint',
 77630 'number' => 'JsonSchema\Constraints\NumberConstraint',
 77631 'enum' => 'JsonSchema\Constraints\EnumConstraint',
 77632 'format' => 'JsonSchema\Constraints\FormatConstraint',
 77633 'schema' => 'JsonSchema\Constraints\SchemaConstraint',
 77634 'validator' => 'JsonSchema\Validator'
 77635 );
 77636 
 77637 
 77638 
 77639 
 77640 private $instanceCache = array();
 77641 
 77642 
 77643 
 77644 
 77645 
 77646 
 77647 public function __construct(
 77648 SchemaStorageInterface $schemaStorage = null,
 77649 UriRetrieverInterface $uriRetriever = null,
 77650 $checkMode = Constraint::CHECK_MODE_NORMAL
 77651 ) {
 77652 
 77653 $this->setConfig($checkMode);
 77654 
 77655 $this->uriRetriever = $uriRetriever ?: new UriRetriever();
 77656 $this->schemaStorage = $schemaStorage ?: new SchemaStorage($this->uriRetriever);
 77657 }
 77658 
 77659 
 77660 
 77661 
 77662 
 77663 
 77664 public function setConfig($checkMode = Constraint::CHECK_MODE_NORMAL)
 77665 {
 77666 $this->checkMode = $checkMode;
 77667 }
 77668 
 77669 
 77670 
 77671 
 77672 
 77673 
 77674 public function addConfig($options)
 77675 {
 77676 $this->checkMode |= $options;
 77677 }
 77678 
 77679 
 77680 
 77681 
 77682 
 77683 
 77684 public function removeConfig($options)
 77685 {
 77686 $this->checkMode &= ~$options;
 77687 }
 77688 
 77689 
 77690 
 77691 
 77692 
 77693 
 77694 
 77695 
 77696 public function getConfig($options = null)
 77697 {
 77698 if ($options === null) {
 77699 return $this->checkMode;
 77700 }
 77701 
 77702 return $this->checkMode & $options;
 77703 }
 77704 
 77705 
 77706 
 77707 
 77708 public function getUriRetriever()
 77709 {
 77710 return $this->uriRetriever;
 77711 }
 77712 
 77713 public function getSchemaStorage()
 77714 {
 77715 return $this->schemaStorage;
 77716 }
 77717 
 77718 public function getTypeCheck()
 77719 {
 77720 if (!isset($this->typeCheck[$this->checkMode])) {
 77721 $this->typeCheck[$this->checkMode] = ($this->checkMode & Constraint::CHECK_MODE_TYPE_CAST)
 77722 ? new TypeCheck\LooseTypeCheck()
 77723 : new TypeCheck\StrictTypeCheck();
 77724 }
 77725 
 77726 return $this->typeCheck[$this->checkMode];
 77727 }
 77728 
 77729 
 77730 
 77731 
 77732 
 77733 
 77734 
 77735 public function setConstraintClass($name, $class)
 77736 {
 77737 
 77738 if (!class_exists($class)) {
 77739 throw new InvalidArgumentException('Unknown constraint ' . $name);
 77740 }
 77741 
 77742 if (!in_array('JsonSchema\Constraints\ConstraintInterface', class_implements($class))) {
 77743 throw new InvalidArgumentException('Invalid class ' . $name);
 77744 }
 77745 $this->constraintMap[$name] = $class;
 77746 
 77747 return $this;
 77748 }
 77749 
 77750 
 77751 
 77752 
 77753 
 77754 
 77755 
 77756 
 77757 
 77758 
 77759 public function createInstanceFor($constraintName)
 77760 {
 77761 if (!isset($this->constraintMap[$constraintName])) {
 77762 throw new InvalidArgumentException('Unknown constraint ' . $constraintName);
 77763 }
 77764 
 77765 if (!isset($this->instanceCache[$constraintName])) {
 77766 $this->instanceCache[$constraintName] = new $this->constraintMap[$constraintName]($this);
 77767 }
 77768 
 77769 return clone $this->instanceCache[$constraintName];
 77770 }
 77771 
 77772 
 77773 
 77774 
 77775 
 77776 
 77777 public function getErrorContext()
 77778 {
 77779 return $this->errorContext;
 77780 }
 77781 
 77782 
 77783 
 77784 
 77785 
 77786 
 77787 public function setErrorContext($errorContext)
 77788 {
 77789 $this->errorContext = $errorContext;
 77790 }
 77791 }
 77792 <?php
 77793 
 77794 
 77795 
 77796 
 77797 
 77798 
 77799 
 77800 
 77801 namespace JsonSchema\Constraints;
 77802 
 77803 use JsonSchema\Entity\JsonPointer;
 77804 use JsonSchema\Rfc3339;
 77805 
 77806 
 77807 
 77808 
 77809 
 77810 
 77811 
 77812 
 77813 class FormatConstraint extends Constraint
 77814 {
 77815 
 77816 
 77817 
 77818 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
 77819 {
 77820 if (!isset($schema->format) || $this->factory->getConfig(self::CHECK_MODE_DISABLE_FORMAT)) {
 77821 return;
 77822 }
 77823 
 77824 switch ($schema->format) {
 77825 case 'date':
 77826 if (!$date = $this->validateDateTime($element, 'Y-m-d')) {
 77827 $this->addError($path, sprintf('Invalid date %s, expected format YYYY-MM-DD', json_encode($element)), 'format', array('format' => $schema->format));
 77828 }
 77829 break;
 77830 
 77831 case 'time':
 77832 if (!$this->validateDateTime($element, 'H:i:s')) {
 77833 $this->addError($path, sprintf('Invalid time %s, expected format hh:mm:ss', json_encode($element)), 'format', array('format' => $schema->format));
 77834 }
 77835 break;
 77836 
 77837 case 'date-time':
 77838 if (null === Rfc3339::createFromString($element)) {
 77839 $this->addError($path, sprintf('Invalid date-time %s, expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm', json_encode($element)), 'format', array('format' => $schema->format));
 77840 }
 77841 break;
 77842 
 77843 case 'utc-millisec':
 77844 if (!$this->validateDateTime($element, 'U')) {
 77845 $this->addError($path, sprintf('Invalid time %s, expected integer of milliseconds since Epoch', json_encode($element)), 'format', array('format' => $schema->format));
 77846 }
 77847 break;
 77848 
 77849 case 'regex':
 77850 if (!$this->validateRegex($element)) {
 77851 $this->addError($path, 'Invalid regex format ' . $element, 'format', array('format' => $schema->format));
 77852 }
 77853 break;
 77854 
 77855 case 'color':
 77856 if (!$this->validateColor($element)) {
 77857 $this->addError($path, 'Invalid color', 'format', array('format' => $schema->format));
 77858 }
 77859 break;
 77860 
 77861 case 'style':
 77862 if (!$this->validateStyle($element)) {
 77863 $this->addError($path, 'Invalid style', 'format', array('format' => $schema->format));
 77864 }
 77865 break;
 77866 
 77867 case 'phone':
 77868 if (!$this->validatePhone($element)) {
 77869 $this->addError($path, 'Invalid phone number', 'format', array('format' => $schema->format));
 77870 }
 77871 break;
 77872 
 77873 case 'uri':
 77874 if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
 77875 $this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format));
 77876 }
 77877 break;
 77878 
 77879 case 'uriref':
 77880 case 'uri-reference':
 77881 if (null === filter_var($element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE)) {
 77882 
 77883 
 77884 
 77885 if (substr($element, 0, 2) === '//') { 
 77886 $validURL = filter_var('scheme:' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
 77887 } elseif (substr($element, 0, 1) === '/') { 
 77888 $validURL = filter_var('scheme://host' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
 77889 } elseif (strlen($element)) { 
 77890 $pathParts = explode('/', $element, 2);
 77891 if (strpos($pathParts[0], ':') !== false) {
 77892 $validURL = null;
 77893 } else {
 77894 $validURL = filter_var('scheme://host/' . $element, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
 77895 }
 77896 } else {
 77897 $validURL = null;
 77898 }
 77899 if ($validURL === null) {
 77900 $this->addError($path, 'Invalid URL format', 'format', array('format' => $schema->format));
 77901 }
 77902 }
 77903 break;
 77904 
 77905 case 'email':
 77906 $filterFlags = FILTER_NULL_ON_FAILURE;
 77907 if (defined('FILTER_FLAG_EMAIL_UNICODE')) {
 77908 
 77909 $filterFlags |= constant('FILTER_FLAG_EMAIL_UNICODE'); 
 77910 }
 77911 if (null === filter_var($element, FILTER_VALIDATE_EMAIL, $filterFlags)) {
 77912 $this->addError($path, 'Invalid email', 'format', array('format' => $schema->format));
 77913 }
 77914 break;
 77915 
 77916 case 'ip-address':
 77917 case 'ipv4':
 77918 if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV4)) {
 77919 $this->addError($path, 'Invalid IP address', 'format', array('format' => $schema->format));
 77920 }
 77921 break;
 77922 
 77923 case 'ipv6':
 77924 if (null === filter_var($element, FILTER_VALIDATE_IP, FILTER_NULL_ON_FAILURE | FILTER_FLAG_IPV6)) {
 77925 $this->addError($path, 'Invalid IP address', 'format', array('format' => $schema->format));
 77926 }
 77927 break;
 77928 
 77929 case 'host-name':
 77930 case 'hostname':
 77931 if (!$this->validateHostname($element)) {
 77932 $this->addError($path, 'Invalid hostname', 'format', array('format' => $schema->format));
 77933 }
 77934 break;
 77935 
 77936 default:
 77937 
 77938 
 77939 
 77940 
 77941 
 77942 
 77943 break;
 77944 }
 77945 }
 77946 
 77947 protected function validateDateTime($datetime, $format)
 77948 {
 77949 $dt = \DateTime::createFromFormat($format, $datetime);
 77950 
 77951 if (!$dt) {
 77952 return false;
 77953 }
 77954 
 77955 if ($datetime === $dt->format($format)) {
 77956 return true;
 77957 }
 77958 
 77959 
 77960 
 77961 
 77962 
 77963 if ((strpos('u', $format) !== -1) && (preg_match('/\.\d+Z$/', $datetime))) {
 77964 return true;
 77965 }
 77966 
 77967 return false;
 77968 }
 77969 
 77970 protected function validateRegex($regex)
 77971 {
 77972 return false !== @preg_match('/' . $regex . '/u', '');
 77973 }
 77974 
 77975 protected function validateColor($color)
 77976 {
 77977 if (in_array(strtolower($color), array('aqua', 'black', 'blue', 'fuchsia',
 77978 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple',
 77979 'red', 'silver', 'teal', 'white', 'yellow'))) {
 77980 return true;
 77981 }
 77982 
 77983 return preg_match('/^#([a-f0-9]{3}|[a-f0-9]{6})$/i', $color);
 77984 }
 77985 
 77986 protected function validateStyle($style)
 77987 {
 77988 $properties = explode(';', rtrim($style, ';'));
 77989 $invalidEntries = preg_grep('/^\s*[-a-z]+\s*:\s*.+$/i', $properties, PREG_GREP_INVERT);
 77990 
 77991 return empty($invalidEntries);
 77992 }
 77993 
 77994 protected function validatePhone($phone)
 77995 {
 77996 return preg_match('/^\+?(\(\d{3}\)|\d{3}) \d{3} \d{4}$/', $phone);
 77997 }
 77998 
 77999 protected function validateHostname($host)
 78000 {
 78001 $hostnameRegex = '/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/i';
 78002 
 78003 return preg_match($hostnameRegex, $host);
 78004 }
 78005 }
 78006 <?php
 78007 
 78008 
 78009 
 78010 
 78011 
 78012 
 78013 
 78014 
 78015 namespace JsonSchema\Constraints;
 78016 
 78017 use JsonSchema\Entity\JsonPointer;
 78018 
 78019 
 78020 
 78021 
 78022 
 78023 
 78024 
 78025 class NumberConstraint extends Constraint
 78026 {
 78027 
 78028 
 78029 
 78030 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
 78031 {
 78032 
 78033 if (isset($schema->exclusiveMinimum)) {
 78034 if (isset($schema->minimum)) {
 78035 if ($schema->exclusiveMinimum && $element <= $schema->minimum) {
 78036 $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'exclusiveMinimum', array('minimum' => $schema->minimum));
 78037 } elseif ($element < $schema->minimum) {
 78038 $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'minimum', array('minimum' => $schema->minimum));
 78039 }
 78040 } else {
 78041 $this->addError($path, 'Use of exclusiveMinimum requires presence of minimum', 'missingMinimum');
 78042 }
 78043 } elseif (isset($schema->minimum) && $element < $schema->minimum) {
 78044 $this->addError($path, 'Must have a minimum value of ' . $schema->minimum, 'minimum', array('minimum' => $schema->minimum));
 78045 }
 78046 
 78047 
 78048 if (isset($schema->exclusiveMaximum)) {
 78049 if (isset($schema->maximum)) {
 78050 if ($schema->exclusiveMaximum && $element >= $schema->maximum) {
 78051 $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'exclusiveMaximum', array('maximum' => $schema->maximum));
 78052 } elseif ($element > $schema->maximum) {
 78053 $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'maximum', array('maximum' => $schema->maximum));
 78054 }
 78055 } else {
 78056 $this->addError($path, 'Use of exclusiveMaximum requires presence of maximum', 'missingMaximum');
 78057 }
 78058 } elseif (isset($schema->maximum) && $element > $schema->maximum) {
 78059 $this->addError($path, 'Must have a maximum value of ' . $schema->maximum, 'maximum', array('maximum' => $schema->maximum));
 78060 }
 78061 
 78062 
 78063 if (isset($schema->divisibleBy) && $this->fmod($element, $schema->divisibleBy) != 0) {
 78064 $this->addError($path, 'Is not divisible by ' . $schema->divisibleBy, 'divisibleBy', array('divisibleBy' => $schema->divisibleBy));
 78065 }
 78066 
 78067 
 78068 if (isset($schema->multipleOf) && $this->fmod($element, $schema->multipleOf) != 0) {
 78069 $this->addError($path, 'Must be a multiple of ' . $schema->multipleOf, 'multipleOf', array('multipleOf' => $schema->multipleOf));
 78070 }
 78071 
 78072 $this->checkFormat($element, $schema, $path, $i);
 78073 }
 78074 
 78075 private function fmod($number1, $number2)
 78076 {
 78077 $modulus = ($number1 - round($number1 / $number2) * $number2);
 78078 $precision = 0.0000000001;
 78079 
 78080 if (-$precision < $modulus && $modulus < $precision) {
 78081 return 0.0;
 78082 }
 78083 
 78084 return $modulus;
 78085 }
 78086 }
 78087 <?php
 78088 
 78089 
 78090 
 78091 
 78092 
 78093 
 78094 
 78095 
 78096 namespace JsonSchema\Constraints;
 78097 
 78098 use JsonSchema\Entity\JsonPointer;
 78099 
 78100 
 78101 
 78102 
 78103 
 78104 
 78105 
 78106 class ObjectConstraint extends Constraint
 78107 {
 78108 
 78109 
 78110 
 78111 protected $appliedDefaults = array();
 78112 
 78113 
 78114 
 78115 
 78116 public function check(&$element, $schema = null, JsonPointer $path = null, $properties = null,
 78117 $additionalProp = null, $patternProperties = null, $appliedDefaults = array())
 78118 {
 78119 if ($element instanceof UndefinedConstraint) {
 78120 return;
 78121 }
 78122 
 78123 $this->appliedDefaults = $appliedDefaults;
 78124 
 78125 $matches = array();
 78126 if ($patternProperties) {
 78127 
 78128 $matches = $this->validatePatternProperties($element, $path, $patternProperties);
 78129 }
 78130 
 78131 if ($properties) {
 78132 
 78133 $this->validateProperties($element, $properties, $path);
 78134 }
 78135 
 78136 
 78137 $this->validateElement($element, $matches, $schema, $path, $properties, $additionalProp);
 78138 }
 78139 
 78140 public function validatePatternProperties($element, JsonPointer $path = null, $patternProperties)
 78141 {
 78142 $try = array('/', '#', '+', '~', '%');
 78143 $matches = array();
 78144 foreach ($patternProperties as $pregex => $schema) {
 78145 $delimiter = '/';
 78146 
 78147 foreach ($try as $delimiter) {
 78148 if (strpos($pregex, $delimiter) === false) { 
 78149 break;
 78150 }
 78151 }
 78152 
 78153 
 78154 if (@preg_match($delimiter . $pregex . $delimiter . 'u', '') === false) {
 78155 $this->addError($path, 'The pattern "' . $pregex . '" is invalid', 'pregex', array('pregex' => $pregex));
 78156 continue;
 78157 }
 78158 foreach ($element as $i => $value) {
 78159 if (preg_match($delimiter . $pregex . $delimiter . 'u', $i)) {
 78160 $matches[] = $i;
 78161 $this->checkUndefined($value, $schema ?: new \stdClass(), $path, $i, in_array($i, $this->appliedDefaults));
 78162 }
 78163 }
 78164 }
 78165 
 78166 return $matches;
 78167 }
 78168 
 78169 
 78170 
 78171 
 78172 
 78173 
 78174 
 78175 
 78176 
 78177 
 78178 
 78179 public function validateElement($element, $matches, $schema = null, JsonPointer $path = null,
 78180 $properties = null, $additionalProp = null)
 78181 {
 78182 $this->validateMinMaxConstraint($element, $schema, $path);
 78183 
 78184 foreach ($element as $i => $value) {
 78185 $definition = $this->getProperty($properties, $i);
 78186 
 78187 
 78188 if (!in_array($i, $matches) && $additionalProp === false && $this->inlineSchemaProperty !== $i && !$definition) {
 78189 $this->addError($path, 'The property ' . $i . ' is not defined and the definition does not allow additional properties', 'additionalProp');
 78190 }
 78191 
 78192 
 78193 if (!in_array($i, $matches) && $additionalProp && !$definition) {
 78194 if ($additionalProp === true) {
 78195 $this->checkUndefined($value, null, $path, $i, in_array($i, $this->appliedDefaults));
 78196 } else {
 78197 $this->checkUndefined($value, $additionalProp, $path, $i, in_array($i, $this->appliedDefaults));
 78198 }
 78199 }
 78200 
 78201 
 78202 $require = $this->getProperty($definition, 'requires');
 78203 if ($require && !$this->getProperty($element, $require)) {
 78204 $this->addError($path, 'The presence of the property ' . $i . ' requires that ' . $require . ' also be present', 'requires');
 78205 }
 78206 
 78207 $property = $this->getProperty($element, $i, $this->factory->createInstanceFor('undefined'));
 78208 if (is_object($property)) {
 78209 $this->validateMinMaxConstraint(!($property instanceof UndefinedConstraint) ? $property : $element, $definition, $path);
 78210 }
 78211 }
 78212 }
 78213 
 78214 
 78215 
 78216 
 78217 
 78218 
 78219 
 78220 
 78221 public function validateProperties(&$element, $properties = null, JsonPointer $path = null)
 78222 {
 78223 $undefinedConstraint = $this->factory->createInstanceFor('undefined');
 78224 
 78225 foreach ($properties as $i => $value) {
 78226 $property = &$this->getProperty($element, $i, $undefinedConstraint);
 78227 $definition = $this->getProperty($properties, $i);
 78228 
 78229 if (is_object($definition)) {
 78230 
 78231 $this->checkUndefined($property, $definition, $path, $i, in_array($i, $this->appliedDefaults));
 78232 }
 78233 }
 78234 }
 78235 
 78236 
 78237 
 78238 
 78239 
 78240 
 78241 
 78242 
 78243 
 78244 
 78245 protected function &getProperty(&$element, $property, $fallback = null)
 78246 {
 78247 if (is_array($element) && (isset($element[$property]) || array_key_exists($property, $element)) ) {
 78248 return $element[$property];
 78249 } elseif (is_object($element) && property_exists($element, $property)) {
 78250 return $element->$property;
 78251 }
 78252 
 78253 return $fallback;
 78254 }
 78255 
 78256 
 78257 
 78258 
 78259 
 78260 
 78261 
 78262 
 78263 protected function validateMinMaxConstraint($element, $objectDefinition, JsonPointer $path = null)
 78264 {
 78265 
 78266 if (isset($objectDefinition->minProperties) && !is_object($objectDefinition->minProperties)) {
 78267 if ($this->getTypeCheck()->propertyCount($element) < $objectDefinition->minProperties) {
 78268 $this->addError($path, 'Must contain a minimum of ' . $objectDefinition->minProperties . ' properties', 'minProperties', array('minProperties' => $objectDefinition->minProperties));
 78269 }
 78270 }
 78271 
 78272 if (isset($objectDefinition->maxProperties) && !is_object($objectDefinition->maxProperties)) {
 78273 if ($this->getTypeCheck()->propertyCount($element) > $objectDefinition->maxProperties) {
 78274 $this->addError($path, 'Must contain no more than ' . $objectDefinition->maxProperties . ' properties', 'maxProperties', array('maxProperties' => $objectDefinition->maxProperties));
 78275 }
 78276 }
 78277 }
 78278 }
 78279 <?php
 78280 
 78281 
 78282 
 78283 
 78284 
 78285 
 78286 
 78287 
 78288 namespace JsonSchema\Constraints;
 78289 
 78290 use JsonSchema\Entity\JsonPointer;
 78291 use JsonSchema\Exception\InvalidArgumentException;
 78292 use JsonSchema\Exception\InvalidSchemaException;
 78293 use JsonSchema\Exception\RuntimeException;
 78294 use JsonSchema\Validator;
 78295 
 78296 
 78297 
 78298 
 78299 
 78300 
 78301 
 78302 class SchemaConstraint extends Constraint
 78303 {
 78304 const DEFAULT_SCHEMA_SPEC = 'http://json-schema.org/draft-04/schema#';
 78305 
 78306 
 78307 
 78308 
 78309 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
 78310 {
 78311 if ($schema !== null) {
 78312 
 78313 $validationSchema = $schema;
 78314 } elseif ($this->getTypeCheck()->propertyExists($element, $this->inlineSchemaProperty)) {
 78315 
 78316 $validationSchema = $this->getTypeCheck()->propertyGet($element, $this->inlineSchemaProperty);
 78317 } else {
 78318 throw new InvalidArgumentException('no schema found to verify against');
 78319 }
 78320 
 78321 
 78322 if (is_array($validationSchema)) {
 78323 $validationSchema = BaseConstraint::arrayToObjectRecursive($validationSchema);
 78324 }
 78325 
 78326 
 78327 
 78328 if ($this->factory->getConfig(self::CHECK_MODE_VALIDATE_SCHEMA)) {
 78329 if (!$this->getTypeCheck()->isObject($validationSchema)) {
 78330 throw new RuntimeException('Cannot validate the schema of a non-object');
 78331 }
 78332 if ($this->getTypeCheck()->propertyExists($validationSchema, '$schema')) {
 78333 $schemaSpec = $this->getTypeCheck()->propertyGet($validationSchema, '$schema');
 78334 } else {
 78335 $schemaSpec = self::DEFAULT_SCHEMA_SPEC;
 78336 }
 78337 
 78338 
 78339 $schemaStorage = $this->factory->getSchemaStorage();
 78340 if (!$this->getTypeCheck()->isObject($schemaSpec)) {
 78341 $schemaSpec = $schemaStorage->getSchema($schemaSpec);
 78342 }
 78343 
 78344 
 78345 $initialErrorCount = $this->numErrors();
 78346 $initialConfig = $this->factory->getConfig();
 78347 $initialContext = $this->factory->getErrorContext();
 78348 $this->factory->removeConfig(self::CHECK_MODE_VALIDATE_SCHEMA | self::CHECK_MODE_APPLY_DEFAULTS);
 78349 $this->factory->addConfig(self::CHECK_MODE_TYPE_CAST);
 78350 $this->factory->setErrorContext(Validator::ERROR_SCHEMA_VALIDATION);
 78351 
 78352 
 78353 try {
 78354 $this->check($validationSchema, $schemaSpec);
 78355 } catch (\Exception $e) {
 78356 if ($this->factory->getConfig(self::CHECK_MODE_EXCEPTIONS)) {
 78357 throw new InvalidSchemaException('Schema did not pass validation', 0, $e);
 78358 }
 78359 }
 78360 if ($this->numErrors() > $initialErrorCount) {
 78361 $this->addError($path, 'Schema is not valid', 'schema');
 78362 }
 78363 
 78364 
 78365 $this->factory->setConfig($initialConfig);
 78366 $this->factory->setErrorContext($initialContext);
 78367 }
 78368 
 78369 
 78370 $this->checkUndefined($element, $validationSchema, $path, $i);
 78371 }
 78372 }
 78373 <?php
 78374 
 78375 
 78376 
 78377 
 78378 
 78379 
 78380 
 78381 
 78382 namespace JsonSchema\Constraints;
 78383 
 78384 use JsonSchema\Entity\JsonPointer;
 78385 
 78386 
 78387 
 78388 
 78389 
 78390 
 78391 
 78392 class StringConstraint extends Constraint
 78393 {
 78394 
 78395 
 78396 
 78397 public function check(&$element, $schema = null, JsonPointer $path = null, $i = null)
 78398 {
 78399 
 78400 if (isset($schema->maxLength) && $this->strlen($element) > $schema->maxLength) {
 78401 $this->addError($path, 'Must be at most ' . $schema->maxLength . ' characters long', 'maxLength', array(
 78402 'maxLength' => $schema->maxLength,
 78403 ));
 78404 }
 78405 
 78406 
 78407 if (isset($schema->minLength) && $this->strlen($element) < $schema->minLength) {
 78408 $this->addError($path, 'Must be at least ' . $schema->minLength . ' characters long', 'minLength', array(
 78409 'minLength' => $schema->minLength,
 78410 ));
 78411 }
 78412 
 78413 
 78414 if (isset($schema->pattern) && !preg_match('#' . str_replace('#', '\\#', $schema->pattern) . '#u', $element)) {
 78415 $this->addError($path, 'Does not match the regex pattern ' . $schema->pattern, 'pattern', array(
 78416 'pattern' => $schema->pattern,
 78417 ));
 78418 }
 78419 
 78420 $this->checkFormat($element, $schema, $path, $i);
 78421 }
 78422 
 78423 private function strlen($string)
 78424 {
 78425 if (extension_loaded('mbstring')) {
 78426 return mb_strlen($string, mb_detect_encoding($string));
 78427 }
 78428 
 78429 
 78430 return strlen($string); 
 78431 }
 78432 }
 78433 <?php
 78434 
 78435 namespace JsonSchema\Constraints\TypeCheck;
 78436 
 78437 class LooseTypeCheck implements TypeCheckInterface
 78438 {
 78439 public static function isObject($value)
 78440 {
 78441 return
 78442 is_object($value) ||
 78443 (is_array($value) && (count($value) == 0 || self::isAssociativeArray($value)));
 78444 }
 78445 
 78446 public static function isArray($value)
 78447 {
 78448 return
 78449 is_array($value) &&
 78450 (count($value) == 0 || !self::isAssociativeArray($value));
 78451 }
 78452 
 78453 public static function propertyGet($value, $property)
 78454 {
 78455 if (is_object($value)) {
 78456 return $value->{$property};
 78457 }
 78458 
 78459 return $value[$property];
 78460 }
 78461 
 78462 public static function propertySet(&$value, $property, $data)
 78463 {
 78464 if (is_object($value)) {
 78465 $value->{$property} = $data;
 78466 } else {
 78467 $value[$property] = $data;
 78468 }
 78469 }
 78470 
 78471 public static function propertyExists($value, $property)
 78472 {
 78473 if (is_object($value)) {
 78474 return property_exists($value, $property);
 78475 }
 78476 
 78477 return array_key_exists($property, $value);
 78478 }
 78479 
 78480 public static function propertyCount($value)
 78481 {
 78482 if (is_object($value)) {
 78483 return count(get_object_vars($value));
 78484 }
 78485 
 78486 return count($value);
 78487 }
 78488 
 78489 
 78490 
 78491 
 78492 
 78493 
 78494 
 78495 
 78496 private static function isAssociativeArray($arr)
 78497 {
 78498 return array_keys($arr) !== range(0, count($arr) - 1);
 78499 }
 78500 }
 78501 <?php
 78502 
 78503 namespace JsonSchema\Constraints\TypeCheck;
 78504 
 78505 class StrictTypeCheck implements TypeCheckInterface
 78506 {
 78507 public static function isObject($value)
 78508 {
 78509 return is_object($value);
 78510 }
 78511 
 78512 public static function isArray($value)
 78513 {
 78514 return is_array($value);
 78515 }
 78516 
 78517 public static function propertyGet($value, $property)
 78518 {
 78519 return $value->{$property};
 78520 }
 78521 
 78522 public static function propertySet(&$value, $property, $data)
 78523 {
 78524 $value->{$property} = $data;
 78525 }
 78526 
 78527 public static function propertyExists($value, $property)
 78528 {
 78529 return property_exists($value, $property);
 78530 }
 78531 
 78532 public static function propertyCount($value)
 78533 {
 78534 if (!is_object($value)) {
 78535 return 0;
 78536 }
 78537 
 78538 return count(get_object_vars($value));
 78539 }
 78540 }
 78541 <?php
 78542 
 78543 namespace JsonSchema\Constraints\TypeCheck;
 78544 
 78545 interface TypeCheckInterface
 78546 {
 78547 public static function isObject($value);
 78548 
 78549 public static function isArray($value);
 78550 
 78551 public static function propertyGet($value, $property);
 78552 
 78553 public static function propertySet(&$value, $property, $data);
 78554 
 78555 public static function propertyExists($value, $property);
 78556 
 78557 public static function propertyCount($value);
 78558 }
 78559 <?php
 78560 
 78561 
 78562 
 78563 
 78564 
 78565 
 78566 
 78567 
 78568 namespace JsonSchema\Constraints;
 78569 
 78570 use JsonSchema\Entity\JsonPointer;
 78571 use JsonSchema\Exception\InvalidArgumentException;
 78572 use UnexpectedValueException as StandardUnexpectedValueException;
 78573 
 78574 
 78575 
 78576 
 78577 
 78578 
 78579 
 78580 class TypeConstraint extends Constraint
 78581 {
 78582 
 78583 
 78584 
 78585 public static $wording = array(
 78586 'integer' => 'an integer',
 78587 'number' => 'a number',
 78588 'boolean' => 'a boolean',
 78589 'object' => 'an object',
 78590 'array' => 'an array',
 78591 'string' => 'a string',
 78592 'null' => 'a null',
 78593 'any' => null, 
 78594 0 => null, 
 78595 );
 78596 
 78597 
 78598 
 78599 
 78600 public function check(&$value = null, $schema = null, JsonPointer $path = null, $i = null)
 78601 {
 78602 $type = isset($schema->type) ? $schema->type : null;
 78603 $isValid = false;
 78604 $wording = array();
 78605 
 78606 if (is_array($type)) {
 78607 $this->validateTypesArray($value, $type, $wording, $isValid, $path);
 78608 } elseif (is_object($type)) {
 78609 $this->checkUndefined($value, $type, $path);
 78610 
 78611 return;
 78612 } else {
 78613 $isValid = $this->validateType($value, $type);
 78614 }
 78615 
 78616 if ($isValid === false) {
 78617 if (!is_array($type)) {
 78618 $this->validateTypeNameWording($type);
 78619 $wording[] = self::$wording[$type];
 78620 }
 78621 $this->addError($path, ucwords(gettype($value)) . ' value found, but ' .
 78622 $this->implodeWith($wording, ', ', 'or') . ' is required', 'type');
 78623 }
 78624 }
 78625 
 78626 
 78627 
 78628 
 78629 
 78630 
 78631 
 78632 
 78633 
 78634 
 78635 
 78636 
 78637 protected function validateTypesArray(&$value, array $type, &$validTypesWording, &$isValid, $path)
 78638 {
 78639 foreach ($type as $tp) {
 78640 
 78641 
 78642 if (is_object($tp)) {
 78643 if (!$isValid) {
 78644 $validator = $this->factory->createInstanceFor('type');
 78645 $subSchema = new \stdClass();
 78646 $subSchema->type = $tp;
 78647 $validator->check($value, $subSchema, $path, null);
 78648 $error = $validator->getErrors();
 78649 $isValid = !(bool) $error;
 78650 $validTypesWording[] = self::$wording['object'];
 78651 }
 78652 } else {
 78653 $this->validateTypeNameWording($tp);
 78654 $validTypesWording[] = self::$wording[$tp];
 78655 if (!$isValid) {
 78656 $isValid = $this->validateType($value, $tp);
 78657 }
 78658 }
 78659 }
 78660 }
 78661 
 78662 
 78663 
 78664 
 78665 
 78666 
 78667 
 78668 
 78669 
 78670 
 78671 
 78672 
 78673 protected function implodeWith(array $elements, $delimiter = ', ', $listEnd = false)
 78674 {
 78675 if ($listEnd === false || !isset($elements[1])) {
 78676 return implode($delimiter, $elements);
 78677 }
 78678 $lastElement = array_slice($elements, -1);
 78679 $firsElements = join($delimiter, array_slice($elements, 0, -1));
 78680 $implodedElements = array_merge(array($firsElements), $lastElement);
 78681 
 78682 return join(" $listEnd ", $implodedElements);
 78683 }
 78684 
 78685 
 78686 
 78687 
 78688 
 78689 
 78690 
 78691 
 78692 
 78693 protected function validateTypeNameWording($type)
 78694 {
 78695 if (!isset(self::$wording[$type])) {
 78696 throw new StandardUnexpectedValueException(
 78697 sprintf(
 78698 'No wording for %s available, expected wordings are: [%s]',
 78699 var_export($type, true),
 78700 implode(', ', array_filter(self::$wording)))
 78701 );
 78702 }
 78703 }
 78704 
 78705 
 78706 
 78707 
 78708 
 78709 
 78710 
 78711 
 78712 
 78713 
 78714 
 78715 protected function validateType(&$value, $type)
 78716 {
 78717 
 78718 if (!$type) {
 78719 return true;
 78720 }
 78721 
 78722 if ('any' === $type) {
 78723 return true;
 78724 }
 78725 
 78726 if ('object' === $type) {
 78727 return $this->getTypeCheck()->isObject($value);
 78728 }
 78729 
 78730 if ('array' === $type) {
 78731 return $this->getTypeCheck()->isArray($value);
 78732 }
 78733 
 78734 $coerce = $this->factory->getConfig(Constraint::CHECK_MODE_COERCE_TYPES);
 78735 
 78736 if ('integer' === $type) {
 78737 if ($coerce) {
 78738 $value = $this->toInteger($value);
 78739 }
 78740 
 78741 return is_int($value);
 78742 }
 78743 
 78744 if ('number' === $type) {
 78745 if ($coerce) {
 78746 $value = $this->toNumber($value);
 78747 }
 78748 
 78749 return is_numeric($value) && !is_string($value);
 78750 }
 78751 
 78752 if ('boolean' === $type) {
 78753 if ($coerce) {
 78754 $value = $this->toBoolean($value);
 78755 }
 78756 
 78757 return is_bool($value);
 78758 }
 78759 
 78760 if ('string' === $type) {
 78761 return is_string($value);
 78762 }
 78763 
 78764 if ('email' === $type) {
 78765 return is_string($value);
 78766 }
 78767 
 78768 if ('null' === $type) {
 78769 return is_null($value);
 78770 }
 78771 
 78772 throw new InvalidArgumentException((is_object($value) ? 'object' : $value) . ' is an invalid type for ' . $type);
 78773 }
 78774 
 78775 
 78776 
 78777 
 78778 
 78779 
 78780 
 78781 
 78782 protected function toBoolean($value)
 78783 {
 78784 if ($value === 'true') {
 78785 return true;
 78786 }
 78787 
 78788 if ($value === 'false') {
 78789 return false;
 78790 }
 78791 
 78792 return $value;
 78793 }
 78794 
 78795 
 78796 
 78797 
 78798 
 78799 
 78800 
 78801 
 78802 protected function toNumber($value)
 78803 {
 78804 if (is_numeric($value)) {
 78805 return $value + 0; 
 78806 }
 78807 
 78808 return $value;
 78809 }
 78810 
 78811 protected function toInteger($value)
 78812 {
 78813 if (is_numeric($value) && (int) $value == $value) {
 78814 return (int) $value; 
 78815 }
 78816 
 78817 return $value;
 78818 }
 78819 }
 78820 <?php
 78821 
 78822 
 78823 
 78824 
 78825 
 78826 
 78827 
 78828 
 78829 namespace JsonSchema\Constraints;
 78830 
 78831 use JsonSchema\Constraints\TypeCheck\LooseTypeCheck;
 78832 use JsonSchema\Entity\JsonPointer;
 78833 use JsonSchema\Exception\ValidationException;
 78834 use JsonSchema\Uri\UriResolver;
 78835 
 78836 
 78837 
 78838 
 78839 
 78840 
 78841 
 78842 class UndefinedConstraint extends Constraint
 78843 {
 78844 
 78845 
 78846 
 78847 protected $appliedDefaults = array();
 78848 
 78849 
 78850 
 78851 
 78852 public function check(&$value, $schema = null, JsonPointer $path = null, $i = null, $fromDefault = false)
 78853 {
 78854 if (is_null($schema) || !is_object($schema)) {
 78855 return;
 78856 }
 78857 
 78858 $path = $this->incrementPath($path ?: new JsonPointer(''), $i);
 78859 if ($fromDefault) {
 78860 $path->setFromDefault();
 78861 }
 78862 
 78863 
 78864 $this->validateCommonProperties($value, $schema, $path, $i);
 78865 
 78866 
 78867 $this->validateOfProperties($value, $schema, $path, '');
 78868 
 78869 
 78870 $this->validateTypes($value, $schema, $path, $i);
 78871 }
 78872 
 78873 
 78874 
 78875 
 78876 
 78877 
 78878 
 78879 
 78880 
 78881 public function validateTypes(&$value, $schema, JsonPointer $path, $i = null)
 78882 {
 78883 
 78884 if ($this->getTypeCheck()->isArray($value)) {
 78885 $this->checkArray($value, $schema, $path, $i);
 78886 }
 78887 
 78888 
 78889 if (LooseTypeCheck::isObject($value)) { 
 78890 
 78891 
 78892 $this->checkObject(
 78893 $value,
 78894 $schema,
 78895 $path,
 78896 isset($schema->properties) ? $schema->properties : null,
 78897 isset($schema->additionalProperties) ? $schema->additionalProperties : null,
 78898 isset($schema->patternProperties) ? $schema->patternProperties : null,
 78899 $this->appliedDefaults
 78900 );
 78901 }
 78902 
 78903 
 78904 if (is_string($value)) {
 78905 $this->checkString($value, $schema, $path, $i);
 78906 }
 78907 
 78908 
 78909 if (is_numeric($value)) {
 78910 $this->checkNumber($value, $schema, $path, $i);
 78911 }
 78912 
 78913 
 78914 if (isset($schema->enum)) {
 78915 $this->checkEnum($value, $schema, $path, $i);
 78916 }
 78917 }
 78918 
 78919 
 78920 
 78921 
 78922 
 78923 
 78924 
 78925 
 78926 
 78927 protected function validateCommonProperties(&$value, $schema, JsonPointer $path, $i = '')
 78928 {
 78929 
 78930 if (isset($schema->extends)) {
 78931 if (is_string($schema->extends)) {
 78932 $schema->extends = $this->validateUri($schema, $schema->extends);
 78933 }
 78934 if (is_array($schema->extends)) {
 78935 foreach ($schema->extends as $extends) {
 78936 $this->checkUndefined($value, $extends, $path, $i);
 78937 }
 78938 } else {
 78939 $this->checkUndefined($value, $schema->extends, $path, $i);
 78940 }
 78941 }
 78942 
 78943 
 78944 if (!$path->fromDefault()) {
 78945 $this->applyDefaultValues($value, $schema, $path);
 78946 }
 78947 
 78948 
 78949 if ($this->getTypeCheck()->isObject($value)) {
 78950 if (!($value instanceof self) && isset($schema->required) && is_array($schema->required)) {
 78951 
 78952 foreach ($schema->required as $required) {
 78953 if (!$this->getTypeCheck()->propertyExists($value, $required)) {
 78954 $this->addError(
 78955 $this->incrementPath($path ?: new JsonPointer(''), $required),
 78956 'The property ' . $required . ' is required',
 78957 'required'
 78958 );
 78959 }
 78960 }
 78961 } elseif (isset($schema->required) && !is_array($schema->required)) {
 78962 
 78963 if ($schema->required && $value instanceof self) {
 78964 $propertyPaths = $path->getPropertyPaths();
 78965 $propertyName = end($propertyPaths);
 78966 $this->addError(
 78967 $path,
 78968 'The property ' . $propertyName . ' is required',
 78969 'required'
 78970 );
 78971 }
 78972 } else {
 78973 
 78974 
 78975 if ($value instanceof self) {
 78976 return;
 78977 }
 78978 }
 78979 }
 78980 
 78981 
 78982 if (!($value instanceof self)) {
 78983 $this->checkType($value, $schema, $path, $i);
 78984 }
 78985 
 78986 
 78987 if (isset($schema->disallow)) {
 78988 $initErrors = $this->getErrors();
 78989 
 78990 $typeSchema = new \stdClass();
 78991 $typeSchema->type = $schema->disallow;
 78992 $this->checkType($value, $typeSchema, $path);
 78993 
 78994 
 78995 if (count($this->getErrors()) == count($initErrors)) {
 78996 $this->addError($path, 'Disallowed value was matched', 'disallow');
 78997 } else {
 78998 $this->errors = $initErrors;
 78999 }
 79000 }
 79001 
 79002 if (isset($schema->not)) {
 79003 $initErrors = $this->getErrors();
 79004 $this->checkUndefined($value, $schema->not, $path, $i);
 79005 
 79006 
 79007 if (count($this->getErrors()) == count($initErrors)) {
 79008 $this->addError($path, 'Matched a schema which it should not', 'not');
 79009 } else {
 79010 $this->errors = $initErrors;
 79011 }
 79012 }
 79013 
 79014 
 79015 if (isset($schema->dependencies) && $this->getTypeCheck()->isObject($value)) {
 79016 $this->validateDependencies($value, $schema->dependencies, $path);
 79017 }
 79018 }
 79019 
 79020 
 79021 
 79022 
 79023 
 79024 
 79025 
 79026 
 79027 
 79028 
 79029 private function shouldApplyDefaultValue($requiredOnly, $schema, $name = null, $parentSchema = null)
 79030 {
 79031 
 79032 if (!$requiredOnly) {
 79033 return true;
 79034 }
 79035 
 79036 if (
 79037 $name !== null
 79038 && isset($parentSchema->required)
 79039 && is_array($parentSchema->required)
 79040 && in_array($name, $parentSchema->required)
 79041 ) {
 79042 return true;
 79043 }
 79044 
 79045 if (isset($schema->required) && !is_array($schema->required) && $schema->required) {
 79046 return true;
 79047 }
 79048 
 79049 return false;
 79050 }
 79051 
 79052 
 79053 
 79054 
 79055 
 79056 
 79057 
 79058 
 79059 protected function applyDefaultValues(&$value, $schema, $path)
 79060 {
 79061 
 79062 if (!$this->factory->getConfig(self::CHECK_MODE_APPLY_DEFAULTS)) {
 79063 return;
 79064 }
 79065 
 79066 
 79067 $requiredOnly = $this->factory->getConfig(self::CHECK_MODE_ONLY_REQUIRED_DEFAULTS);
 79068 if (isset($schema->properties) && LooseTypeCheck::isObject($value)) {
 79069 
 79070 foreach ($schema->properties as $currentProperty => $propertyDefinition) {
 79071 $propertyDefinition = $this->factory->getSchemaStorage()->resolveRefSchema($propertyDefinition);
 79072 if (
 79073 !LooseTypeCheck::propertyExists($value, $currentProperty)
 79074 && property_exists($propertyDefinition, 'default')
 79075 && $this->shouldApplyDefaultValue($requiredOnly, $propertyDefinition, $currentProperty, $schema)
 79076 ) {
 79077 
 79078 if (is_object($propertyDefinition->default)) {
 79079 LooseTypeCheck::propertySet($value, $currentProperty, clone $propertyDefinition->default);
 79080 } else {
 79081 LooseTypeCheck::propertySet($value, $currentProperty, $propertyDefinition->default);
 79082 }
 79083 $this->appliedDefaults[] = $currentProperty;
 79084 }
 79085 }
 79086 } elseif (isset($schema->items) && LooseTypeCheck::isArray($value)) {
 79087 $items = array();
 79088 if (LooseTypeCheck::isArray($schema->items)) {
 79089 $items = $schema->items;
 79090 } elseif (isset($schema->minItems) && count($value) < $schema->minItems) {
 79091 $items = array_fill(count($value), $schema->minItems - count($value), $schema->items);
 79092 }
 79093 
 79094 foreach ($items as $currentItem => $itemDefinition) {
 79095 $itemDefinition = $this->factory->getSchemaStorage()->resolveRefSchema($itemDefinition);
 79096 if (
 79097 !array_key_exists($currentItem, $value)
 79098 && property_exists($itemDefinition, 'default')
 79099 && $this->shouldApplyDefaultValue($requiredOnly, $itemDefinition)) {
 79100 if (is_object($itemDefinition->default)) {
 79101 $value[$currentItem] = clone $itemDefinition->default;
 79102 } else {
 79103 $value[$currentItem] = $itemDefinition->default;
 79104 }
 79105 }
 79106 $path->setFromDefault();
 79107 }
 79108 } elseif (
 79109 $value instanceof self
 79110 && property_exists($schema, 'default')
 79111 && $this->shouldApplyDefaultValue($requiredOnly, $schema)) {
 79112 
 79113 $value = is_object($schema->default) ? clone $schema->default : $schema->default;
 79114 $path->setFromDefault();
 79115 }
 79116 }
 79117 
 79118 
 79119 
 79120 
 79121 
 79122 
 79123 
 79124 
 79125 
 79126 protected function validateOfProperties(&$value, $schema, JsonPointer $path, $i = '')
 79127 {
 79128 
 79129 if ($value instanceof self) {
 79130 return;
 79131 }
 79132 
 79133 if (isset($schema->allOf)) {
 79134 $isValid = true;
 79135 foreach ($schema->allOf as $allOf) {
 79136 $initErrors = $this->getErrors();
 79137 $this->checkUndefined($value, $allOf, $path, $i);
 79138 $isValid = $isValid && (count($this->getErrors()) == count($initErrors));
 79139 }
 79140 if (!$isValid) {
 79141 $this->addError($path, 'Failed to match all schemas', 'allOf');
 79142 }
 79143 }
 79144 
 79145 if (isset($schema->anyOf)) {
 79146 $isValid = false;
 79147 $startErrors = $this->getErrors();
 79148 $caughtException = null;
 79149 foreach ($schema->anyOf as $anyOf) {
 79150 $initErrors = $this->getErrors();
 79151 try {
 79152 $this->checkUndefined($value, $anyOf, $path, $i);
 79153 if ($isValid = (count($this->getErrors()) == count($initErrors))) {
 79154 break;
 79155 }
 79156 } catch (ValidationException $e) {
 79157 $isValid = false;
 79158 }
 79159 }
 79160 if (!$isValid) {
 79161 $this->addError($path, 'Failed to match at least one schema', 'anyOf');
 79162 } else {
 79163 $this->errors = $startErrors;
 79164 }
 79165 }
 79166 
 79167 if (isset($schema->oneOf)) {
 79168 $allErrors = array();
 79169 $matchedSchemas = 0;
 79170 $startErrors = $this->getErrors();
 79171 foreach ($schema->oneOf as $oneOf) {
 79172 try {
 79173 $this->errors = array();
 79174 $this->checkUndefined($value, $oneOf, $path, $i);
 79175 if (count($this->getErrors()) == 0) {
 79176 $matchedSchemas++;
 79177 }
 79178 $allErrors = array_merge($allErrors, array_values($this->getErrors()));
 79179 } catch (ValidationException $e) {
 79180 
 79181 
 79182 }
 79183 }
 79184 if ($matchedSchemas !== 1) {
 79185 $this->addErrors(array_merge($allErrors, $startErrors));
 79186 $this->addError($path, 'Failed to match exactly one schema', 'oneOf');
 79187 } else {
 79188 $this->errors = $startErrors;
 79189 }
 79190 }
 79191 }
 79192 
 79193 
 79194 
 79195 
 79196 
 79197 
 79198 
 79199 
 79200 
 79201 protected function validateDependencies($value, $dependencies, JsonPointer $path, $i = '')
 79202 {
 79203 foreach ($dependencies as $key => $dependency) {
 79204 if ($this->getTypeCheck()->propertyExists($value, $key)) {
 79205 if (is_string($dependency)) {
 79206 
 79207 if (!$this->getTypeCheck()->propertyExists($value, $dependency)) {
 79208 $this->addError($path, "$key depends on $dependency and $dependency is missing", 'dependencies');
 79209 }
 79210 } elseif (is_array($dependency)) {
 79211 
 79212 foreach ($dependency as $d) {
 79213 if (!$this->getTypeCheck()->propertyExists($value, $d)) {
 79214 $this->addError($path, "$key depends on $d and $d is missing", 'dependencies');
 79215 }
 79216 }
 79217 } elseif (is_object($dependency)) {
 79218 
 79219 $this->checkUndefined($value, $dependency, $path, $i);
 79220 }
 79221 }
 79222 }
 79223 }
 79224 
 79225 protected function validateUri($schema, $schemaUri = null)
 79226 {
 79227 $resolver = new UriResolver();
 79228 $retriever = $this->factory->getUriRetriever();
 79229 
 79230 $jsonSchema = null;
 79231 if ($resolver->isValid($schemaUri)) {
 79232 $schemaId = property_exists($schema, 'id') ? $schema->id : null;
 79233 $jsonSchema = $retriever->retrieve($schemaId, $schemaUri);
 79234 }
 79235 
 79236 return $jsonSchema;
 79237 }
 79238 }
 79239 <?php
 79240 
 79241 
 79242 
 79243 
 79244 
 79245 
 79246 
 79247 
 79248 namespace JsonSchema\Entity;
 79249 
 79250 use JsonSchema\Exception\InvalidArgumentException;
 79251 
 79252 
 79253 
 79254 
 79255 
 79256 
 79257 class JsonPointer
 79258 {
 79259 
 79260 private $filename;
 79261 
 79262 
 79263 private $propertyPaths = array();
 79264 
 79265 
 79266 
 79267 
 79268 private $fromDefault = false;
 79269 
 79270 
 79271 
 79272 
 79273 
 79274 
 79275 public function __construct($value)
 79276 {
 79277 if (!is_string($value)) {
 79278 throw new InvalidArgumentException('Ref value must be a string');
 79279 }
 79280 
 79281 $splitRef = explode('#', $value, 2);
 79282 $this->filename = $splitRef[0];
 79283 if (array_key_exists(1, $splitRef)) {
 79284 $this->propertyPaths = $this->decodePropertyPaths($splitRef[1]);
 79285 }
 79286 }
 79287 
 79288 
 79289 
 79290 
 79291 
 79292 
 79293 private function decodePropertyPaths($propertyPathString)
 79294 {
 79295 $paths = array();
 79296 foreach (explode('/', trim($propertyPathString, '/')) as $path) {
 79297 $path = $this->decodePath($path);
 79298 if (is_string($path) && '' !== $path) {
 79299 $paths[] = $path;
 79300 }
 79301 }
 79302 
 79303 return $paths;
 79304 }
 79305 
 79306 
 79307 
 79308 
 79309 private function encodePropertyPaths()
 79310 {
 79311 return array_map(
 79312 array($this, 'encodePath'),
 79313 $this->getPropertyPaths()
 79314 );
 79315 }
 79316 
 79317 
 79318 
 79319 
 79320 
 79321 
 79322 private function decodePath($path)
 79323 {
 79324 return strtr($path, array('~1' => '/', '~0' => '~', '%25' => '%'));
 79325 }
 79326 
 79327 
 79328 
 79329 
 79330 
 79331 
 79332 private function encodePath($path)
 79333 {
 79334 return strtr($path, array('/' => '~1', '~' => '~0', '%' => '%25'));
 79335 }
 79336 
 79337 
 79338 
 79339 
 79340 public function getFilename()
 79341 {
 79342 return $this->filename;
 79343 }
 79344 
 79345 
 79346 
 79347 
 79348 public function getPropertyPaths()
 79349 {
 79350 return $this->propertyPaths;
 79351 }
 79352 
 79353 
 79354 
 79355 
 79356 
 79357 
 79358 public function withPropertyPaths(array $propertyPaths)
 79359 {
 79360 $new = clone $this;
 79361 $new->propertyPaths = $propertyPaths;
 79362 
 79363 return $new;
 79364 }
 79365 
 79366 
 79367 
 79368 
 79369 public function getPropertyPathAsString()
 79370 {
 79371 return rtrim('#/' . implode('/', $this->encodePropertyPaths()), '/');
 79372 }
 79373 
 79374 
 79375 
 79376 
 79377 public function __toString()
 79378 {
 79379 return $this->getFilename() . $this->getPropertyPathAsString();
 79380 }
 79381 
 79382 
 79383 
 79384 
 79385 public function setFromDefault()
 79386 {
 79387 $this->fromDefault = true;
 79388 }
 79389 
 79390 
 79391 
 79392 
 79393 
 79394 
 79395 public function fromDefault()
 79396 {
 79397 return $this->fromDefault;
 79398 }
 79399 }
 79400 <?php
 79401 
 79402 namespace JsonSchema\Exception;
 79403 
 79404 interface ExceptionInterface
 79405 {
 79406 }
 79407 <?php
 79408 
 79409 
 79410 
 79411 
 79412 
 79413 
 79414 
 79415 
 79416 namespace JsonSchema\Exception;
 79417 
 79418 
 79419 
 79420 
 79421 class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
 79422 {
 79423 }
 79424 <?php
 79425 
 79426 
 79427 
 79428 
 79429 
 79430 
 79431 
 79432 
 79433 namespace JsonSchema\Exception;
 79434 
 79435 
 79436 
 79437 
 79438 class InvalidConfigException extends RuntimeException
 79439 {
 79440 }
 79441 <?php
 79442 
 79443 
 79444 
 79445 
 79446 
 79447 
 79448 
 79449 
 79450 namespace JsonSchema\Exception;
 79451 
 79452 
 79453 
 79454 
 79455 class InvalidSchemaException extends RuntimeException
 79456 {
 79457 }
 79458 <?php
 79459 
 79460 
 79461 
 79462 
 79463 
 79464 
 79465 
 79466 
 79467 namespace JsonSchema\Exception;
 79468 
 79469 
 79470 
 79471 
 79472 class InvalidSchemaMediaTypeException extends RuntimeException
 79473 {
 79474 }
 79475 <?php
 79476 
 79477 
 79478 
 79479 
 79480 
 79481 
 79482 
 79483 
 79484 namespace JsonSchema\Exception;
 79485 
 79486 
 79487 
 79488 
 79489 class InvalidSourceUriException extends InvalidArgumentException
 79490 {
 79491 }
 79492 <?php
 79493 
 79494 
 79495 
 79496 
 79497 
 79498 
 79499 
 79500 
 79501 namespace JsonSchema\Exception;
 79502 
 79503 
 79504 
 79505 
 79506 class JsonDecodingException extends RuntimeException
 79507 {
 79508 public function __construct($code = JSON_ERROR_NONE, \Exception $previous = null)
 79509 {
 79510 switch ($code) {
 79511 case JSON_ERROR_DEPTH:
 79512 $message = 'The maximum stack depth has been exceeded';
 79513 break;
 79514 case JSON_ERROR_STATE_MISMATCH:
 79515 $message = 'Invalid or malformed JSON';
 79516 break;
 79517 case JSON_ERROR_CTRL_CHAR:
 79518 $message = 'Control character error, possibly incorrectly encoded';
 79519 break;
 79520 case JSON_ERROR_UTF8:
 79521 $message = 'Malformed UTF-8 characters, possibly incorrectly encoded';
 79522 break;
 79523 case JSON_ERROR_SYNTAX:
 79524 $message = 'JSON syntax is malformed';
 79525 break;
 79526 default:
 79527 $message = 'Syntax error';
 79528 }
 79529 parent::__construct($message, $code, $previous);
 79530 }
 79531 }
 79532 <?php
 79533 
 79534 
 79535 
 79536 
 79537 
 79538 
 79539 
 79540 
 79541 namespace JsonSchema\Exception;
 79542 
 79543 
 79544 
 79545 
 79546 class ResourceNotFoundException extends RuntimeException
 79547 {
 79548 }
 79549 <?php
 79550 
 79551 
 79552 
 79553 
 79554 
 79555 
 79556 
 79557 
 79558 namespace JsonSchema\Exception;
 79559 
 79560 
 79561 
 79562 
 79563 class RuntimeException extends \RuntimeException implements ExceptionInterface
 79564 {
 79565 }
 79566 <?php
 79567 
 79568 
 79569 
 79570 
 79571 
 79572 
 79573 
 79574 
 79575 namespace JsonSchema\Exception;
 79576 
 79577 
 79578 
 79579 
 79580 
 79581 
 79582 class UnresolvableJsonPointerException extends InvalidArgumentException
 79583 {
 79584 }
 79585 <?php
 79586 
 79587 
 79588 
 79589 
 79590 
 79591 
 79592 
 79593 
 79594 namespace JsonSchema\Exception;
 79595 
 79596 
 79597 
 79598 
 79599 class UriResolverException extends RuntimeException
 79600 {
 79601 }
 79602 <?php
 79603 
 79604 
 79605 
 79606 
 79607 
 79608 
 79609 
 79610 
 79611 namespace JsonSchema\Exception;
 79612 
 79613 class ValidationException extends RuntimeException
 79614 {
 79615 }
 79616 <?php
 79617 
 79618 
 79619 
 79620 
 79621 
 79622 
 79623 
 79624 
 79625 namespace JsonSchema\Iterator;
 79626 
 79627 
 79628 
 79629 
 79630 
 79631 
 79632 class ObjectIterator implements \Iterator, \Countable
 79633 {
 79634 
 79635 private $object;
 79636 
 79637 
 79638 private $position = 0;
 79639 
 79640 
 79641 private $data = array();
 79642 
 79643 
 79644 private $initialized = false;
 79645 
 79646 
 79647 
 79648 
 79649 public function __construct($object)
 79650 {
 79651 $this->object = $object;
 79652 }
 79653 
 79654 
 79655 
 79656 
 79657 public function current()
 79658 {
 79659 $this->initialize();
 79660 
 79661 return $this->data[$this->position];
 79662 }
 79663 
 79664 
 79665 
 79666 
 79667 public function next()
 79668 {
 79669 $this->initialize();
 79670 $this->position++;
 79671 }
 79672 
 79673 
 79674 
 79675 
 79676 public function key()
 79677 {
 79678 $this->initialize();
 79679 
 79680 return $this->position;
 79681 }
 79682 
 79683 
 79684 
 79685 
 79686 public function valid()
 79687 {
 79688 $this->initialize();
 79689 
 79690 return isset($this->data[$this->position]);
 79691 }
 79692 
 79693 
 79694 
 79695 
 79696 public function rewind()
 79697 {
 79698 $this->initialize();
 79699 $this->position = 0;
 79700 }
 79701 
 79702 
 79703 
 79704 
 79705 public function count()
 79706 {
 79707 $this->initialize();
 79708 
 79709 return count($this->data);
 79710 }
 79711 
 79712 
 79713 
 79714 
 79715 private function initialize()
 79716 {
 79717 if (!$this->initialized) {
 79718 $this->data = $this->buildDataFromObject($this->object);
 79719 $this->initialized = true;
 79720 }
 79721 }
 79722 
 79723 
 79724 
 79725 
 79726 
 79727 
 79728 private function buildDataFromObject($object)
 79729 {
 79730 $result = array();
 79731 
 79732 $stack = new \SplStack();
 79733 $stack->push($object);
 79734 
 79735 while (!$stack->isEmpty()) {
 79736 $current = $stack->pop();
 79737 if (is_object($current)) {
 79738 array_push($result, $current);
 79739 }
 79740 
 79741 foreach ($this->getDataFromItem($current) as $propertyName => $propertyValue) {
 79742 if (is_object($propertyValue) || is_array($propertyValue)) {
 79743 $stack->push($propertyValue);
 79744 }
 79745 }
 79746 }
 79747 
 79748 return $result;
 79749 }
 79750 
 79751 
 79752 
 79753 
 79754 
 79755 
 79756 private function getDataFromItem($item)
 79757 {
 79758 if (!is_object($item) && !is_array($item)) {
 79759 return array();
 79760 }
 79761 
 79762 return is_object($item) ? get_object_vars($item) : $item;
 79763 }
 79764 }
 79765 <?php
 79766 
 79767 namespace JsonSchema;
 79768 
 79769 class Rfc3339
 79770 {
 79771 const REGEX = '/^(\d{4}-\d{2}-\d{2}[T ]{1}\d{2}:\d{2}:\d{2})(\.\d+)?(Z|([+-]\d{2}):?(\d{2}))$/';
 79772 
 79773 
 79774 
 79775 
 79776 
 79777 
 79778 
 79779 
 79780 public static function createFromString($string)
 79781 {
 79782 if (!preg_match(self::REGEX, strtoupper($string), $matches)) {
 79783 return null;
 79784 }
 79785 
 79786 $dateAndTime = $matches[1];
 79787 $microseconds = $matches[2] ?: '.000000';
 79788 $timeZone = 'Z' !== $matches[3] ? $matches[4] . ':' . $matches[5] : '+00:00';
 79789 $dateFormat = strpos($dateAndTime, 'T') === false ? 'Y-m-d H:i:s.uP' : 'Y-m-d\TH:i:s.uP';
 79790 $dateTime = \DateTime::createFromFormat($dateFormat, $dateAndTime . $microseconds . $timeZone, new \DateTimeZone('UTC'));
 79791 
 79792 return $dateTime ?: null;
 79793 }
 79794 }
 79795 <?php
 79796 
 79797 namespace JsonSchema;
 79798 
 79799 use JsonSchema\Constraints\BaseConstraint;
 79800 use JsonSchema\Entity\JsonPointer;
 79801 use JsonSchema\Exception\UnresolvableJsonPointerException;
 79802 use JsonSchema\Uri\UriResolver;
 79803 use JsonSchema\Uri\UriRetriever;
 79804 
 79805 class SchemaStorage implements SchemaStorageInterface
 79806 {
 79807 const INTERNAL_PROVIDED_SCHEMA_URI = 'internal://provided-schema/';
 79808 
 79809 protected $uriRetriever;
 79810 protected $uriResolver;
 79811 protected $schemas = array();
 79812 
 79813 public function __construct(
 79814 UriRetrieverInterface $uriRetriever = null,
 79815 UriResolverInterface $uriResolver = null
 79816 ) {
 79817 $this->uriRetriever = $uriRetriever ?: new UriRetriever();
 79818 $this->uriResolver = $uriResolver ?: new UriResolver();
 79819 }
 79820 
 79821 
 79822 
 79823 
 79824 public function getUriRetriever()
 79825 {
 79826 return $this->uriRetriever;
 79827 }
 79828 
 79829 
 79830 
 79831 
 79832 public function getUriResolver()
 79833 {
 79834 return $this->uriResolver;
 79835 }
 79836 
 79837 
 79838 
 79839 
 79840 public function addSchema($id, $schema = null)
 79841 {
 79842 if (is_null($schema) && $id !== self::INTERNAL_PROVIDED_SCHEMA_URI) {
 79843 
 79844 
 79845 
 79846 $schema = $this->uriRetriever->retrieve($id);
 79847 }
 79848 
 79849 
 79850 if (is_array($schema)) {
 79851 $schema = BaseConstraint::arrayToObjectRecursive($schema);
 79852 }
 79853 
 79854 
 79855 
 79856 if (is_object($schema) && property_exists($schema, 'id')) {
 79857 if ($schema->id == 'http://json-schema.org/draft-04/schema#') {
 79858 $schema->properties->id->format = 'uri-reference';
 79859 } elseif ($schema->id == 'http://json-schema.org/draft-03/schema#') {
 79860 $schema->properties->id->format = 'uri-reference';
 79861 $schema->properties->{'$ref'}->format = 'uri-reference';
 79862 }
 79863 }
 79864 
 79865 
 79866 $this->expandRefs($schema, $id);
 79867 
 79868 $this->schemas[$id] = $schema;
 79869 }
 79870 
 79871 
 79872 
 79873 
 79874 
 79875 
 79876 
 79877 private function expandRefs(&$schema, $base = null)
 79878 {
 79879 if (!is_object($schema)) {
 79880 if (is_array($schema)) {
 79881 foreach ($schema as &$member) {
 79882 $this->expandRefs($member, $base);
 79883 }
 79884 }
 79885 
 79886 return;
 79887 }
 79888 
 79889 if (property_exists($schema, 'id') && is_string($schema->id) && $base != $schema->id) {
 79890 $base = $this->uriResolver->resolve($schema->id, $base);
 79891 }
 79892 
 79893 if (property_exists($schema, '$ref') && is_string($schema->{'$ref'})) {
 79894 $refPointer = new JsonPointer($this->uriResolver->resolve($schema->{'$ref'}, $base));
 79895 $schema->{'$ref'} = (string) $refPointer;
 79896 }
 79897 
 79898 foreach ($schema as &$member) {
 79899 $this->expandRefs($member, $base);
 79900 }
 79901 }
 79902 
 79903 
 79904 
 79905 
 79906 public function getSchema($id)
 79907 {
 79908 if (!array_key_exists($id, $this->schemas)) {
 79909 $this->addSchema($id);
 79910 }
 79911 
 79912 return $this->schemas[$id];
 79913 }
 79914 
 79915 
 79916 
 79917 
 79918 public function resolveRef($ref)
 79919 {
 79920 $jsonPointer = new JsonPointer($ref);
 79921 
 79922 
 79923 $fileName = $jsonPointer->getFilename();
 79924 if (!strlen($fileName)) {
 79925 throw new UnresolvableJsonPointerException(sprintf(
 79926 "Could not resolve fragment '%s': no file is defined",
 79927 $jsonPointer->getPropertyPathAsString()
 79928 ));
 79929 }
 79930 
 79931 
 79932 $refSchema = $this->getSchema($fileName);
 79933 foreach ($jsonPointer->getPropertyPaths() as $path) {
 79934 if (is_object($refSchema) && property_exists($refSchema, $path)) {
 79935 $refSchema = $this->resolveRefSchema($refSchema->{$path});
 79936 } elseif (is_array($refSchema) && array_key_exists($path, $refSchema)) {
 79937 $refSchema = $this->resolveRefSchema($refSchema[$path]);
 79938 } else {
 79939 throw new UnresolvableJsonPointerException(sprintf(
 79940 'File: %s is found, but could not resolve fragment: %s',
 79941 $jsonPointer->getFilename(),
 79942 $jsonPointer->getPropertyPathAsString()
 79943 ));
 79944 }
 79945 }
 79946 
 79947 return $refSchema;
 79948 }
 79949 
 79950 
 79951 
 79952 
 79953 public function resolveRefSchema($refSchema)
 79954 {
 79955 if (is_object($refSchema) && property_exists($refSchema, '$ref') && is_string($refSchema->{'$ref'})) {
 79956 $newSchema = $this->resolveRef($refSchema->{'$ref'});
 79957 $refSchema = (object) (get_object_vars($refSchema) + get_object_vars($newSchema));
 79958 unset($refSchema->{'$ref'});
 79959 }
 79960 
 79961 return $refSchema;
 79962 }
 79963 }
 79964 <?php
 79965 
 79966 namespace JsonSchema;
 79967 
 79968 interface SchemaStorageInterface
 79969 {
 79970 
 79971 
 79972 
 79973 
 79974 
 79975 
 79976 public function addSchema($id, $schema = null);
 79977 
 79978 
 79979 
 79980 
 79981 
 79982 
 79983 
 79984 
 79985 public function getSchema($id);
 79986 
 79987 
 79988 
 79989 
 79990 
 79991 
 79992 
 79993 
 79994 public function resolveRef($ref);
 79995 
 79996 
 79997 
 79998 
 79999 
 80000 
 80001 
 80002 
 80003 public function resolveRefSchema($refSchema);
 80004 }
 80005 <?php
 80006 
 80007 
 80008 
 80009 
 80010 
 80011 
 80012 namespace JsonSchema\Uri\Retrievers;
 80013 
 80014 
 80015 
 80016 
 80017 
 80018 
 80019 
 80020 abstract class AbstractRetriever implements UriRetrieverInterface
 80021 {
 80022 
 80023 
 80024 
 80025 
 80026 
 80027 protected $contentType;
 80028 
 80029 
 80030 
 80031 
 80032 
 80033 
 80034 public function getContentType()
 80035 {
 80036 return $this->contentType;
 80037 }
 80038 }
 80039 <?php
 80040 
 80041 
 80042 
 80043 
 80044 
 80045 
 80046 
 80047 
 80048 namespace JsonSchema\Uri\Retrievers;
 80049 
 80050 use JsonSchema\Exception\RuntimeException;
 80051 use JsonSchema\Validator;
 80052 
 80053 
 80054 
 80055 
 80056 
 80057 
 80058 class Curl extends AbstractRetriever
 80059 {
 80060 protected $messageBody;
 80061 
 80062 public function __construct()
 80063 {
 80064 if (!function_exists('curl_init')) {
 80065 
 80066 throw new RuntimeException('cURL not installed'); 
 80067 }
 80068 }
 80069 
 80070 
 80071 
 80072 
 80073 
 80074 
 80075 public function retrieve($uri)
 80076 {
 80077 $ch = curl_init();
 80078 
 80079 curl_setopt($ch, CURLOPT_URL, $uri);
 80080 curl_setopt($ch, CURLOPT_HEADER, true);
 80081 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 80082 curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: ' . Validator::SCHEMA_MEDIA_TYPE));
 80083 
 80084 $response = curl_exec($ch);
 80085 if (false === $response) {
 80086 throw new \JsonSchema\Exception\ResourceNotFoundException('JSON schema not found');
 80087 }
 80088 
 80089 $this->fetchMessageBody($response);
 80090 $this->fetchContentType($response);
 80091 
 80092 curl_close($ch);
 80093 
 80094 return $this->messageBody;
 80095 }
 80096 
 80097 
 80098 
 80099 
 80100 private function fetchMessageBody($response)
 80101 {
 80102 preg_match("/(?:\r\n){2}(.*)$/ms", $response, $match);
 80103 $this->messageBody = $match[1];
 80104 }
 80105 
 80106 
 80107 
 80108 
 80109 
 80110 
 80111 protected function fetchContentType($response)
 80112 {
 80113 if (0 < preg_match("/Content-Type:(\V*)/ims", $response, $match)) {
 80114 $this->contentType = trim($match[1]);
 80115 
 80116 return true;
 80117 }
 80118 
 80119 return false;
 80120 }
 80121 }
 80122 <?php
 80123 
 80124 
 80125 
 80126 
 80127 
 80128 
 80129 
 80130 
 80131 namespace JsonSchema\Uri\Retrievers;
 80132 
 80133 use JsonSchema\Exception\ResourceNotFoundException;
 80134 
 80135 
 80136 
 80137 
 80138 
 80139 
 80140 class FileGetContents extends AbstractRetriever
 80141 {
 80142 protected $messageBody;
 80143 
 80144 
 80145 
 80146 
 80147 
 80148 
 80149 public function retrieve($uri)
 80150 {
 80151 $errorMessage = null;
 80152 set_error_handler(function ($errno, $errstr) use (&$errorMessage) {
 80153 $errorMessage = $errstr;
 80154 });
 80155 $response = file_get_contents($uri);
 80156 restore_error_handler();
 80157 
 80158 if ($errorMessage) {
 80159 throw new ResourceNotFoundException($errorMessage);
 80160 }
 80161 
 80162 if (false === $response) {
 80163 throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
 80164 }
 80165 
 80166 if ($response == ''
 80167 && substr($uri, 0, 7) == 'file://' && substr($uri, -1) == '/'
 80168 ) {
 80169 throw new ResourceNotFoundException('JSON schema not found at ' . $uri);
 80170 }
 80171 
 80172 $this->messageBody = $response;
 80173 if (!empty($http_response_header)) {
 80174 
 80175 
 80176 $this->fetchContentType($http_response_header); 
 80177 } else { 
 80178 
 80179 $this->contentType = null;
 80180 }
 80181 
 80182 return $this->messageBody;
 80183 }
 80184 
 80185 
 80186 
 80187 
 80188 
 80189 
 80190 private function fetchContentType(array $headers)
 80191 {
 80192 foreach ($headers as $header) {
 80193 if ($this->contentType = self::getContentTypeMatchInHeader($header)) {
 80194 return true;
 80195 }
 80196 }
 80197 
 80198 return false;
 80199 }
 80200 
 80201 
 80202 
 80203 
 80204 
 80205 
 80206 protected static function getContentTypeMatchInHeader($header)
 80207 {
 80208 if (0 < preg_match("/Content-Type:(\V*)/ims", $header, $match)) {
 80209 return trim($match[1]);
 80210 }
 80211 
 80212 return null;
 80213 }
 80214 }
 80215 <?php
 80216 
 80217 namespace JsonSchema\Uri\Retrievers;
 80218 
 80219 use JsonSchema\Validator;
 80220 
 80221 
 80222 
 80223 
 80224 
 80225 
 80226 
 80227 
 80228 
 80229 
 80230 
 80231 
 80232 
 80233 class PredefinedArray extends AbstractRetriever
 80234 {
 80235 
 80236 
 80237 
 80238 
 80239 
 80240 private $schemas;
 80241 
 80242 
 80243 
 80244 
 80245 
 80246 
 80247 
 80248 public function __construct(array $schemas, $contentType = Validator::SCHEMA_MEDIA_TYPE)
 80249 {
 80250 $this->schemas = $schemas;
 80251 $this->contentType = $contentType;
 80252 }
 80253 
 80254 
 80255 
 80256 
 80257 
 80258 
 80259 public function retrieve($uri)
 80260 {
 80261 if (!array_key_exists($uri, $this->schemas)) {
 80262 throw new \JsonSchema\Exception\ResourceNotFoundException(sprintf(
 80263 'The JSON schema "%s" was not found.',
 80264 $uri
 80265 ));
 80266 }
 80267 
 80268 return $this->schemas[$uri];
 80269 }
 80270 }
 80271 <?php
 80272 
 80273 
 80274 
 80275 
 80276 
 80277 
 80278 
 80279 
 80280 namespace JsonSchema\Uri\Retrievers;
 80281 
 80282 
 80283 
 80284 
 80285 
 80286 
 80287 interface UriRetrieverInterface
 80288 {
 80289 
 80290 
 80291 
 80292 
 80293 
 80294 
 80295 
 80296 
 80297 
 80298 public function retrieve($uri);
 80299 
 80300 
 80301 
 80302 
 80303 
 80304 
 80305 public function getContentType();
 80306 }
 80307 <?php
 80308 
 80309 
 80310 
 80311 
 80312 
 80313 
 80314 
 80315 
 80316 namespace JsonSchema\Uri;
 80317 
 80318 use JsonSchema\Exception\UriResolverException;
 80319 use JsonSchema\UriResolverInterface;
 80320 
 80321 
 80322 
 80323 
 80324 
 80325 
 80326 class UriResolver implements UriResolverInterface
 80327 {
 80328 
 80329 
 80330 
 80331 
 80332 
 80333 
 80334 
 80335 public function parse($uri)
 80336 {
 80337 preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);
 80338 
 80339 $components = array();
 80340 if (5 < count($match)) {
 80341 $components = array(
 80342 'scheme' => $match[2],
 80343 'authority' => $match[4],
 80344 'path' => $match[5]
 80345 );
 80346 }
 80347 if (7 < count($match)) {
 80348 $components['query'] = $match[7];
 80349 }
 80350 if (9 < count($match)) {
 80351 $components['fragment'] = $match[9];
 80352 }
 80353 
 80354 return $components;
 80355 }
 80356 
 80357 
 80358 
 80359 
 80360 
 80361 
 80362 
 80363 
 80364 public function generate(array $components)
 80365 {
 80366 $uri = $components['scheme'] . '://'
 80367 . $components['authority']
 80368 . $components['path'];
 80369 
 80370 if (array_key_exists('query', $components) && strlen($components['query'])) {
 80371 $uri .= '?' . $components['query'];
 80372 }
 80373 if (array_key_exists('fragment', $components)) {
 80374 $uri .= '#' . $components['fragment'];
 80375 }
 80376 
 80377 return $uri;
 80378 }
 80379 
 80380 
 80381 
 80382 
 80383 public function resolve($uri, $baseUri = null)
 80384 {
 80385 
 80386 if (
 80387 !is_null($baseUri) &&
 80388 !filter_var($baseUri, \FILTER_VALIDATE_URL) &&
 80389 !preg_match('|^[^/]+://|u', $baseUri)
 80390 ) {
 80391 if (is_file($baseUri)) {
 80392 $baseUri = 'file://' . realpath($baseUri);
 80393 } elseif (is_dir($baseUri)) {
 80394 $baseUri = 'file://' . realpath($baseUri) . '/';
 80395 } else {
 80396 $baseUri = 'file://' . getcwd() . '/' . $baseUri;
 80397 }
 80398 }
 80399 
 80400 if ($uri == '') {
 80401 return $baseUri;
 80402 }
 80403 
 80404 $components = $this->parse($uri);
 80405 $path = $components['path'];
 80406 
 80407 if (!empty($components['scheme'])) {
 80408 return $uri;
 80409 }
 80410 $baseComponents = $this->parse($baseUri);
 80411 $basePath = $baseComponents['path'];
 80412 
 80413 $baseComponents['path'] = self::combineRelativePathWithBasePath($path, $basePath);
 80414 if (isset($components['fragment'])) {
 80415 $baseComponents['fragment'] = $components['fragment'];
 80416 }
 80417 
 80418 return $this->generate($baseComponents);
 80419 }
 80420 
 80421 
 80422 
 80423 
 80424 
 80425 
 80426 
 80427 
 80428 
 80429 
 80430 
 80431 public static function combineRelativePathWithBasePath($relativePath, $basePath)
 80432 {
 80433 $relativePath = self::normalizePath($relativePath);
 80434 if ($relativePath == '') {
 80435 return $basePath;
 80436 }
 80437 if ($relativePath[0] == '/') {
 80438 return $relativePath;
 80439 }
 80440 
 80441 $basePathSegments = explode('/', $basePath);
 80442 
 80443 preg_match('|^/?(\.\./(?:\./)*)*|', $relativePath, $match);
 80444 $numLevelUp = strlen($match[0]) /3 + 1;
 80445 if ($numLevelUp >= count($basePathSegments)) {
 80446 throw new UriResolverException(sprintf("Unable to resolve URI '%s' from base '%s'", $relativePath, $basePath));
 80447 }
 80448 
 80449 $basePathSegments = array_slice($basePathSegments, 0, -$numLevelUp);
 80450 $path = preg_replace('|^/?(\.\./(\./)*)*|', '', $relativePath);
 80451 
 80452 return implode('/', $basePathSegments) . '/' . $path;
 80453 }
 80454 
 80455 
 80456 
 80457 
 80458 
 80459 
 80460 
 80461 
 80462 private static function normalizePath($path)
 80463 {
 80464 $path = preg_replace('|((?<!\.)\./)*|', '', $path);
 80465 $path = preg_replace('|//|', '/', $path);
 80466 
 80467 return $path;
 80468 }
 80469 
 80470 
 80471 
 80472 
 80473 
 80474 
 80475 public function isValid($uri)
 80476 {
 80477 $components = $this->parse($uri);
 80478 
 80479 return !empty($components);
 80480 }
 80481 }
 80482 <?php
 80483 
 80484 
 80485 
 80486 
 80487 
 80488 
 80489 
 80490 
 80491 namespace JsonSchema\Uri;
 80492 
 80493 use JsonSchema\Exception\InvalidSchemaMediaTypeException;
 80494 use JsonSchema\Exception\JsonDecodingException;
 80495 use JsonSchema\Exception\ResourceNotFoundException;
 80496 use JsonSchema\Uri\Retrievers\FileGetContents;
 80497 use JsonSchema\Uri\Retrievers\UriRetrieverInterface;
 80498 use JsonSchema\UriRetrieverInterface as BaseUriRetrieverInterface;
 80499 use JsonSchema\Validator;
 80500 
 80501 
 80502 
 80503 
 80504 
 80505 
 80506 class UriRetriever implements BaseUriRetrieverInterface
 80507 {
 80508 
 80509 
 80510 
 80511 protected $translationMap = array(
 80512 
 80513 '|^https?://json-schema.org/draft-(0[34])/schema#?|' => 'package://dist/schema/json-schema-draft-$1.json'
 80514 );
 80515 
 80516 
 80517 
 80518 
 80519 protected $allowedInvalidContentTypeEndpoints = array(
 80520 'http://json-schema.org/',
 80521 'https://json-schema.org/'
 80522 );
 80523 
 80524 
 80525 
 80526 
 80527 protected $uriRetriever = null;
 80528 
 80529 
 80530 
 80531 
 80532 
 80533 
 80534 private $schemaCache = array();
 80535 
 80536 
 80537 
 80538 
 80539 
 80540 
 80541 public function addInvalidContentTypeEndpoint($endpoint)
 80542 {
 80543 $this->allowedInvalidContentTypeEndpoints[] = $endpoint;
 80544 }
 80545 
 80546 
 80547 
 80548 
 80549 
 80550 
 80551 
 80552 
 80553 
 80554 public function confirmMediaType($uriRetriever, $uri)
 80555 {
 80556 $contentType = $uriRetriever->getContentType();
 80557 
 80558 if (is_null($contentType)) {
 80559 
 80560 return;
 80561 }
 80562 
 80563 if (in_array($contentType, array(Validator::SCHEMA_MEDIA_TYPE, 'application/json'))) {
 80564 return;
 80565 }
 80566 
 80567 foreach ($this->allowedInvalidContentTypeEndpoints as $endpoint) {
 80568 if (strpos($uri, $endpoint) === 0) {
 80569 return true;
 80570 }
 80571 }
 80572 
 80573 throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE));
 80574 }
 80575 
 80576 
 80577 
 80578 
 80579 
 80580 
 80581 
 80582 
 80583 
 80584 public function getUriRetriever()
 80585 {
 80586 if (is_null($this->uriRetriever)) {
 80587 $this->setUriRetriever(new FileGetContents());
 80588 }
 80589 
 80590 return $this->uriRetriever;
 80591 }
 80592 
 80593 
 80594 
 80595 
 80596 
 80597 
 80598 
 80599 
 80600 
 80601 
 80602 
 80603 
 80604 
 80605 
 80606 
 80607 public function resolvePointer($jsonSchema, $uri)
 80608 {
 80609 $resolver = new UriResolver();
 80610 $parsed = $resolver->parse($uri);
 80611 if (empty($parsed['fragment'])) {
 80612 return $jsonSchema;
 80613 }
 80614 
 80615 $path = explode('/', $parsed['fragment']);
 80616 while ($path) {
 80617 $pathElement = array_shift($path);
 80618 if (!empty($pathElement)) {
 80619 $pathElement = str_replace('~1', '/', $pathElement);
 80620 $pathElement = str_replace('~0', '~', $pathElement);
 80621 if (!empty($jsonSchema->$pathElement)) {
 80622 $jsonSchema = $jsonSchema->$pathElement;
 80623 } else {
 80624 throw new ResourceNotFoundException(
 80625 'Fragment "' . $parsed['fragment'] . '" not found'
 80626 . ' in ' . $uri
 80627 );
 80628 }
 80629 
 80630 if (!is_object($jsonSchema)) {
 80631 throw new ResourceNotFoundException(
 80632 'Fragment part "' . $pathElement . '" is no object '
 80633 . ' in ' . $uri
 80634 );
 80635 }
 80636 }
 80637 }
 80638 
 80639 return $jsonSchema;
 80640 }
 80641 
 80642 
 80643 
 80644 
 80645 public function retrieve($uri, $baseUri = null, $translate = true)
 80646 {
 80647 $resolver = new UriResolver();
 80648 $resolvedUri = $fetchUri = $resolver->resolve($uri, $baseUri);
 80649 
 80650 
 80651 $arParts = $resolver->parse($resolvedUri);
 80652 if (isset($arParts['fragment'])) {
 80653 unset($arParts['fragment']);
 80654 $fetchUri = $resolver->generate($arParts);
 80655 }
 80656 
 80657 
 80658 if ($translate) {
 80659 $fetchUri = $this->translate($fetchUri);
 80660 }
 80661 
 80662 $jsonSchema = $this->loadSchema($fetchUri);
 80663 
 80664 
 80665 $jsonSchema = $this->resolvePointer($jsonSchema, $resolvedUri);
 80666 
 80667 if ($jsonSchema instanceof \stdClass) {
 80668 $jsonSchema->id = $resolvedUri;
 80669 }
 80670 
 80671 return $jsonSchema;
 80672 }
 80673 
 80674 
 80675 
 80676 
 80677 
 80678 
 80679 
 80680 
 80681 
 80682 protected function loadSchema($fetchUri)
 80683 {
 80684 if (isset($this->schemaCache[$fetchUri])) {
 80685 return $this->schemaCache[$fetchUri];
 80686 }
 80687 
 80688 $uriRetriever = $this->getUriRetriever();
 80689 $contents = $this->uriRetriever->retrieve($fetchUri);
 80690 $this->confirmMediaType($uriRetriever, $fetchUri);
 80691 $jsonSchema = json_decode($contents);
 80692 
 80693 if (JSON_ERROR_NONE < $error = json_last_error()) {
 80694 throw new JsonDecodingException($error);
 80695 }
 80696 
 80697 $this->schemaCache[$fetchUri] = $jsonSchema;
 80698 
 80699 return $jsonSchema;
 80700 }
 80701 
 80702 
 80703 
 80704 
 80705 
 80706 
 80707 
 80708 
 80709 public function setUriRetriever(UriRetrieverInterface $uriRetriever)
 80710 {
 80711 $this->uriRetriever = $uriRetriever;
 80712 
 80713 return $this;
 80714 }
 80715 
 80716 
 80717 
 80718 
 80719 
 80720 
 80721 
 80722 
 80723 public function parse($uri)
 80724 {
 80725 preg_match('|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|', $uri, $match);
 80726 
 80727 $components = array();
 80728 if (5 < count($match)) {
 80729 $components = array(
 80730 'scheme' => $match[2],
 80731 'authority' => $match[4],
 80732 'path' => $match[5]
 80733 );
 80734 }
 80735 
 80736 if (7 < count($match)) {
 80737 $components['query'] = $match[7];
 80738 }
 80739 
 80740 if (9 < count($match)) {
 80741 $components['fragment'] = $match[9];
 80742 }
 80743 
 80744 return $components;
 80745 }
 80746 
 80747 
 80748 
 80749 
 80750 
 80751 
 80752 
 80753 
 80754 public function generate(array $components)
 80755 {
 80756 $uri = $components['scheme'] . '://'
 80757 . $components['authority']
 80758 . $components['path'];
 80759 
 80760 if (array_key_exists('query', $components)) {
 80761 $uri .= $components['query'];
 80762 }
 80763 
 80764 if (array_key_exists('fragment', $components)) {
 80765 $uri .= $components['fragment'];
 80766 }
 80767 
 80768 return $uri;
 80769 }
 80770 
 80771 
 80772 
 80773 
 80774 
 80775 
 80776 
 80777 
 80778 
 80779 public function resolve($uri, $baseUri = null)
 80780 {
 80781 $components = $this->parse($uri);
 80782 $path = $components['path'];
 80783 
 80784 if ((array_key_exists('scheme', $components)) && ('http' === $components['scheme'])) {
 80785 return $uri;
 80786 }
 80787 
 80788 $baseComponents = $this->parse($baseUri);
 80789 $basePath = $baseComponents['path'];
 80790 
 80791 $baseComponents['path'] = UriResolver::combineRelativePathWithBasePath($path, $basePath);
 80792 
 80793 return $this->generate($baseComponents);
 80794 }
 80795 
 80796 
 80797 
 80798 
 80799 
 80800 
 80801 public function isValid($uri)
 80802 {
 80803 $components = $this->parse($uri);
 80804 
 80805 return !empty($components);
 80806 }
 80807 
 80808 
 80809 
 80810 
 80811 public function setTranslation($from, $to)
 80812 {
 80813 $this->translationMap[$from] = $to;
 80814 }
 80815 
 80816 
 80817 
 80818 
 80819 public function translate($uri)
 80820 {
 80821 foreach ($this->translationMap as $from => $to) {
 80822 $uri = preg_replace($from, $to, $uri);
 80823 }
 80824 
 80825 
 80826 $uri = preg_replace('|^package://|', sprintf('file://%s/', realpath(__DIR__ . '/../../..')), $uri);
 80827 
 80828 return $uri;
 80829 }
 80830 }
 80831 <?php
 80832 
 80833 
 80834 
 80835 
 80836 
 80837 
 80838 
 80839 
 80840 namespace JsonSchema;
 80841 
 80842 
 80843 
 80844 
 80845 interface UriResolverInterface
 80846 {
 80847 
 80848 
 80849 
 80850 
 80851 
 80852 
 80853 
 80854 
 80855 public function resolve($uri, $baseUri = null);
 80856 }
 80857 <?php
 80858 
 80859 
 80860 
 80861 
 80862 
 80863 
 80864 
 80865 
 80866 namespace JsonSchema;
 80867 
 80868 
 80869 
 80870 
 80871 interface UriRetrieverInterface
 80872 {
 80873 
 80874 
 80875 
 80876 
 80877 
 80878 
 80879 
 80880 
 80881 public function retrieve($uri, $baseUri = null);
 80882 }
 80883 <?php
 80884 
 80885 
 80886 
 80887 
 80888 
 80889 
 80890 
 80891 
 80892 namespace JsonSchema;
 80893 
 80894 use JsonSchema\Constraints\BaseConstraint;
 80895 use JsonSchema\Constraints\Constraint;
 80896 
 80897 
 80898 
 80899 
 80900 
 80901 
 80902 
 80903 
 80904 
 80905 class Validator extends BaseConstraint
 80906 {
 80907 const SCHEMA_MEDIA_TYPE = 'application/schema+json';
 80908 
 80909 const ERROR_NONE = 0x00000000;
 80910 const ERROR_ALL = 0xFFFFFFFF;
 80911 const ERROR_DOCUMENT_VALIDATION = 0x00000001;
 80912 const ERROR_SCHEMA_VALIDATION = 0x00000002;
 80913 
 80914 
 80915 
 80916 
 80917 
 80918 
 80919 
 80920 
 80921 public function validate(&$value, $schema = null, $checkMode = null)
 80922 {
 80923 
 80924 if (is_array($schema)) {
 80925 $schema = self::arrayToObjectRecursive($schema);
 80926 }
 80927 
 80928 
 80929 $initialCheckMode = $this->factory->getConfig();
 80930 if ($checkMode !== null) {
 80931 $this->factory->setConfig($checkMode);
 80932 }
 80933 
 80934 
 80935 if (is_object($schema) && property_exists($schema, 'id')) {
 80936 $schemaURI = $schema->id;
 80937 } else {
 80938 $schemaURI = SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI;
 80939 }
 80940 $this->factory->getSchemaStorage()->addSchema($schemaURI, $schema);
 80941 
 80942 $validator = $this->factory->createInstanceFor('schema');
 80943 $validator->check(
 80944 $value,
 80945 $this->factory->getSchemaStorage()->getSchema($schemaURI)
 80946 );
 80947 
 80948 $this->factory->setConfig($initialCheckMode);
 80949 
 80950 $this->addErrors(array_unique($validator->getErrors(), SORT_REGULAR));
 80951 
 80952 return $validator->getErrorMask();
 80953 }
 80954 
 80955 
 80956 
 80957 
 80958 public function check($value, $schema)
 80959 {
 80960 return $this->validate($value, $schema);
 80961 }
 80962 
 80963 
 80964 
 80965 
 80966 public function coerce(&$value, $schema)
 80967 {
 80968 return $this->validate($value, $schema, Constraint::CHECK_MODE_COERCE_TYPES);
 80969 }
 80970 }
 80971 
 80972 Copyright (c) 2012 PHP Framework Interoperability Group
 80973 
 80974 Permission is hereby granted, free of charge, to any person obtaining a copy 
 80975 of this software and associated documentation files (the "Software"), to deal
 80976 in the Software without restriction, including without limitation the rights 
 80977 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 80978 copies of the Software, and to permit persons to whom the Software is 
 80979 furnished to do so, subject to the following conditions:
 80980 
 80981 The above copyright notice and this permission notice shall be included in 
 80982 all copies or substantial portions of the Software.
 80983 
 80984 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 80985 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 80986 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 80987 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 80988 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 80989 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 80990 THE SOFTWARE.
 80991 
 80992 <?php
 80993 
 80994 namespace Psr\Log;
 80995 
 80996 
 80997 
 80998 
 80999 
 81000 
 81001 
 81002 
 81003 abstract class AbstractLogger implements LoggerInterface
 81004 {
 81005 
 81006 
 81007 
 81008 
 81009 
 81010 
 81011 
 81012 
 81013 public function emergency($message, array $context = array())
 81014 {
 81015 $this->log(LogLevel::EMERGENCY, $message, $context);
 81016 }
 81017 
 81018 
 81019 
 81020 
 81021 
 81022 
 81023 
 81024 
 81025 
 81026 
 81027 
 81028 
 81029 public function alert($message, array $context = array())
 81030 {
 81031 $this->log(LogLevel::ALERT, $message, $context);
 81032 }
 81033 
 81034 
 81035 
 81036 
 81037 
 81038 
 81039 
 81040 
 81041 
 81042 
 81043 
 81044 public function critical($message, array $context = array())
 81045 {
 81046 $this->log(LogLevel::CRITICAL, $message, $context);
 81047 }
 81048 
 81049 
 81050 
 81051 
 81052 
 81053 
 81054 
 81055 
 81056 
 81057 
 81058 public function error($message, array $context = array())
 81059 {
 81060 $this->log(LogLevel::ERROR, $message, $context);
 81061 }
 81062 
 81063 
 81064 
 81065 
 81066 
 81067 
 81068 
 81069 
 81070 
 81071 
 81072 
 81073 
 81074 public function warning($message, array $context = array())
 81075 {
 81076 $this->log(LogLevel::WARNING, $message, $context);
 81077 }
 81078 
 81079 
 81080 
 81081 
 81082 
 81083 
 81084 
 81085 
 81086 
 81087 public function notice($message, array $context = array())
 81088 {
 81089 $this->log(LogLevel::NOTICE, $message, $context);
 81090 }
 81091 
 81092 
 81093 
 81094 
 81095 
 81096 
 81097 
 81098 
 81099 
 81100 
 81101 
 81102 public function info($message, array $context = array())
 81103 {
 81104 $this->log(LogLevel::INFO, $message, $context);
 81105 }
 81106 
 81107 
 81108 
 81109 
 81110 
 81111 
 81112 
 81113 
 81114 
 81115 public function debug($message, array $context = array())
 81116 {
 81117 $this->log(LogLevel::DEBUG, $message, $context);
 81118 }
 81119 }
 81120 <?php
 81121 
 81122 namespace Psr\Log;
 81123 
 81124 class InvalidArgumentException extends \InvalidArgumentException
 81125 {
 81126 }
 81127 <?php
 81128 
 81129 namespace Psr\Log;
 81130 
 81131 
 81132 
 81133 
 81134 class LogLevel
 81135 {
 81136 const EMERGENCY = 'emergency';
 81137 const ALERT = 'alert';
 81138 const CRITICAL = 'critical';
 81139 const ERROR = 'error';
 81140 const WARNING = 'warning';
 81141 const NOTICE = 'notice';
 81142 const INFO = 'info';
 81143 const DEBUG = 'debug';
 81144 }
 81145 <?php
 81146 
 81147 namespace Psr\Log;
 81148 
 81149 
 81150 
 81151 
 81152 interface LoggerAwareInterface
 81153 {
 81154 
 81155 
 81156 
 81157 
 81158 
 81159 
 81160 
 81161 public function setLogger(LoggerInterface $logger);
 81162 }
 81163 <?php
 81164 
 81165 namespace Psr\Log;
 81166 
 81167 
 81168 
 81169 
 81170 trait LoggerAwareTrait
 81171 {
 81172 
 81173 
 81174 
 81175 
 81176 
 81177 protected $logger;
 81178 
 81179 
 81180 
 81181 
 81182 
 81183 
 81184 public function setLogger(LoggerInterface $logger)
 81185 {
 81186 $this->logger = $logger;
 81187 }
 81188 }
 81189 <?php
 81190 
 81191 namespace Psr\Log;
 81192 
 81193 
 81194 
 81195 
 81196 
 81197 
 81198 
 81199 
 81200 
 81201 
 81202 
 81203 
 81204 
 81205 
 81206 
 81207 
 81208 interface LoggerInterface
 81209 {
 81210 
 81211 
 81212 
 81213 
 81214 
 81215 
 81216 
 81217 
 81218 public function emergency($message, array $context = array());
 81219 
 81220 
 81221 
 81222 
 81223 
 81224 
 81225 
 81226 
 81227 
 81228 
 81229 
 81230 
 81231 public function alert($message, array $context = array());
 81232 
 81233 
 81234 
 81235 
 81236 
 81237 
 81238 
 81239 
 81240 
 81241 
 81242 
 81243 public function critical($message, array $context = array());
 81244 
 81245 
 81246 
 81247 
 81248 
 81249 
 81250 
 81251 
 81252 
 81253 
 81254 public function error($message, array $context = array());
 81255 
 81256 
 81257 
 81258 
 81259 
 81260 
 81261 
 81262 
 81263 
 81264 
 81265 
 81266 
 81267 public function warning($message, array $context = array());
 81268 
 81269 
 81270 
 81271 
 81272 
 81273 
 81274 
 81275 
 81276 
 81277 public function notice($message, array $context = array());
 81278 
 81279 
 81280 
 81281 
 81282 
 81283 
 81284 
 81285 
 81286 
 81287 
 81288 
 81289 public function info($message, array $context = array());
 81290 
 81291 
 81292 
 81293 
 81294 
 81295 
 81296 
 81297 
 81298 
 81299 public function debug($message, array $context = array());
 81300 
 81301 
 81302 
 81303 
 81304 
 81305 
 81306 
 81307 
 81308 
 81309 
 81310 
 81311 
 81312 public function log($level, $message, array $context = array());
 81313 }
 81314 <?php
 81315 
 81316 namespace Psr\Log;
 81317 
 81318 
 81319 
 81320 
 81321 
 81322 
 81323 
 81324 
 81325 
 81326 trait LoggerTrait
 81327 {
 81328 
 81329 
 81330 
 81331 
 81332 
 81333 
 81334 
 81335 
 81336 public function emergency($message, array $context = array())
 81337 {
 81338 $this->log(LogLevel::EMERGENCY, $message, $context);
 81339 }
 81340 
 81341 
 81342 
 81343 
 81344 
 81345 
 81346 
 81347 
 81348 
 81349 
 81350 
 81351 
 81352 public function alert($message, array $context = array())
 81353 {
 81354 $this->log(LogLevel::ALERT, $message, $context);
 81355 }
 81356 
 81357 
 81358 
 81359 
 81360 
 81361 
 81362 
 81363 
 81364 
 81365 
 81366 
 81367 public function critical($message, array $context = array())
 81368 {
 81369 $this->log(LogLevel::CRITICAL, $message, $context);
 81370 }
 81371 
 81372 
 81373 
 81374 
 81375 
 81376 
 81377 
 81378 
 81379 
 81380 
 81381 public function error($message, array $context = array())
 81382 {
 81383 $this->log(LogLevel::ERROR, $message, $context);
 81384 }
 81385 
 81386 
 81387 
 81388 
 81389 
 81390 
 81391 
 81392 
 81393 
 81394 
 81395 
 81396 
 81397 public function warning($message, array $context = array())
 81398 {
 81399 $this->log(LogLevel::WARNING, $message, $context);
 81400 }
 81401 
 81402 
 81403 
 81404 
 81405 
 81406 
 81407 
 81408 
 81409 
 81410 public function notice($message, array $context = array())
 81411 {
 81412 $this->log(LogLevel::NOTICE, $message, $context);
 81413 }
 81414 
 81415 
 81416 
 81417 
 81418 
 81419 
 81420 
 81421 
 81422 
 81423 
 81424 
 81425 public function info($message, array $context = array())
 81426 {
 81427 $this->log(LogLevel::INFO, $message, $context);
 81428 }
 81429 
 81430 
 81431 
 81432 
 81433 
 81434 
 81435 
 81436 
 81437 
 81438 public function debug($message, array $context = array())
 81439 {
 81440 $this->log(LogLevel::DEBUG, $message, $context);
 81441 }
 81442 
 81443 
 81444 
 81445 
 81446 
 81447 
 81448 
 81449 
 81450 
 81451 
 81452 
 81453 
 81454 abstract public function log($level, $message, array $context = array());
 81455 }
 81456 <?php
 81457 
 81458 namespace Psr\Log;
 81459 
 81460 
 81461 
 81462 
 81463 
 81464 
 81465 
 81466 
 81467 
 81468 class NullLogger extends AbstractLogger
 81469 {
 81470 
 81471 
 81472 
 81473 
 81474 
 81475 
 81476 
 81477 
 81478 
 81479 
 81480 
 81481 public function log($level, $message, array $context = array())
 81482 {
 81483 
 81484 }
 81485 }
 81486 <?php
 81487 
 81488 namespace Psr\Log\Test;
 81489 
 81490 
 81491 
 81492 
 81493 
 81494 
 81495 
 81496 
 81497 class DummyTest
 81498 {
 81499 public function __toString()
 81500 {
 81501 return 'DummyTest';
 81502 }
 81503 }
 81504 <?php
 81505 
 81506 namespace Psr\Log\Test;
 81507 
 81508 use Psr\Log\LoggerInterface;
 81509 use Psr\Log\LogLevel;
 81510 use PHPUnit\Framework\TestCase;
 81511 
 81512 
 81513 
 81514 
 81515 
 81516 
 81517 
 81518 abstract class LoggerInterfaceTest extends TestCase
 81519 {
 81520 
 81521 
 81522 
 81523 abstract public function getLogger();
 81524 
 81525 
 81526 
 81527 
 81528 
 81529 
 81530 
 81531 
 81532 
 81533 
 81534 abstract public function getLogs();
 81535 
 81536 public function testImplements()
 81537 {
 81538 $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
 81539 }
 81540 
 81541 
 81542 
 81543 
 81544 public function testLogsAtAllLevels($level, $message)
 81545 {
 81546 $logger = $this->getLogger();
 81547 $logger->{$level}($message, array('user' => 'Bob'));
 81548 $logger->log($level, $message, array('user' => 'Bob'));
 81549 
 81550 $expected = array(
 81551 $level.' message of level '.$level.' with context: Bob',
 81552 $level.' message of level '.$level.' with context: Bob',
 81553 );
 81554 $this->assertEquals($expected, $this->getLogs());
 81555 }
 81556 
 81557 public function provideLevelsAndMessages()
 81558 {
 81559 return array(
 81560 LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
 81561 LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
 81562 LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
 81563 LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
 81564 LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
 81565 LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
 81566 LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
 81567 LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
 81568 );
 81569 }
 81570 
 81571 
 81572 
 81573 
 81574 public function testThrowsOnInvalidLevel()
 81575 {
 81576 $logger = $this->getLogger();
 81577 $logger->log('invalid level', 'Foo');
 81578 }
 81579 
 81580 public function testContextReplacement()
 81581 {
 81582 $logger = $this->getLogger();
 81583 $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
 81584 
 81585 $expected = array('info {Message {nothing} Bob Bar a}');
 81586 $this->assertEquals($expected, $this->getLogs());
 81587 }
 81588 
 81589 public function testObjectCastToString()
 81590 {
 81591 if (method_exists($this, 'createPartialMock')) {
 81592 $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString'));
 81593 } else {
 81594 $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
 81595 }
 81596 $dummy->expects($this->once())
 81597 ->method('__toString')
 81598 ->will($this->returnValue('DUMMY'));
 81599 
 81600 $this->getLogger()->warning($dummy);
 81601 
 81602 $expected = array('warning DUMMY');
 81603 $this->assertEquals($expected, $this->getLogs());
 81604 }
 81605 
 81606 public function testContextCanContainAnything()
 81607 {
 81608 $closed = fopen('php://memory', 'r');
 81609 fclose($closed);
 81610 
 81611 $context = array(
 81612 'bool' => true,
 81613 'null' => null,
 81614 'string' => 'Foo',
 81615 'int' => 0,
 81616 'float' => 0.5,
 81617 'nested' => array('with object' => new DummyTest),
 81618 'object' => new \DateTime,
 81619 'resource' => fopen('php://memory', 'r'),
 81620 'closed' => $closed,
 81621 );
 81622 
 81623 $this->getLogger()->warning('Crazy context data', $context);
 81624 
 81625 $expected = array('warning Crazy context data');
 81626 $this->assertEquals($expected, $this->getLogs());
 81627 }
 81628 
 81629 public function testContextExceptionKeyCanBeExceptionOrOtherValues()
 81630 {
 81631 $logger = $this->getLogger();
 81632 $logger->warning('Random message', array('exception' => 'oops'));
 81633 $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
 81634 
 81635 $expected = array(
 81636 'warning Random message',
 81637 'critical Uncaught Exception!'
 81638 );
 81639 $this->assertEquals($expected, $this->getLogs());
 81640 }
 81641 }
 81642 <?php
 81643 
 81644 namespace Psr\Log\Test;
 81645 
 81646 use Psr\Log\AbstractLogger;
 81647 
 81648 
 81649 
 81650 
 81651 
 81652 
 81653 
 81654 
 81655 
 81656 
 81657 
 81658 
 81659 
 81660 
 81661 
 81662 
 81663 
 81664 
 81665 
 81666 
 81667 
 81668 
 81669 
 81670 
 81671 
 81672 
 81673 
 81674 
 81675 
 81676 
 81677 
 81678 
 81679 
 81680 
 81681 
 81682 
 81683 
 81684 
 81685 
 81686 
 81687 
 81688 
 81689 
 81690 
 81691 
 81692 
 81693 
 81694 
 81695 
 81696 
 81697 
 81698 class TestLogger extends AbstractLogger
 81699 {
 81700 
 81701 
 81702 
 81703 public $records = [];
 81704 
 81705 public $recordsByLevel = [];
 81706 
 81707 
 81708 
 81709 
 81710 public function log($level, $message, array $context = [])
 81711 {
 81712 $record = [
 81713 'level' => $level,
 81714 'message' => $message,
 81715 'context' => $context,
 81716 ];
 81717 
 81718 $this->recordsByLevel[$record['level']][] = $record;
 81719 $this->records[] = $record;
 81720 }
 81721 
 81722 public function hasRecords($level)
 81723 {
 81724 return isset($this->recordsByLevel[$level]);
 81725 }
 81726 
 81727 public function hasRecord($record, $level)
 81728 {
 81729 if (is_string($record)) {
 81730 $record = ['message' => $record];
 81731 }
 81732 return $this->hasRecordThatPasses(function ($rec) use ($record) {
 81733 if ($rec['message'] !== $record['message']) {
 81734 return false;
 81735 }
 81736 if (isset($record['context']) && $rec['context'] !== $record['context']) {
 81737 return false;
 81738 }
 81739 return true;
 81740 }, $level);
 81741 }
 81742 
 81743 public function hasRecordThatContains($message, $level)
 81744 {
 81745 return $this->hasRecordThatPasses(function ($rec) use ($message) {
 81746 return strpos($rec['message'], $message) !== false;
 81747 }, $level);
 81748 }
 81749 
 81750 public function hasRecordThatMatches($regex, $level)
 81751 {
 81752 return $this->hasRecordThatPasses(function ($rec) use ($regex) {
 81753 return preg_match($regex, $rec['message']) > 0;
 81754 }, $level);
 81755 }
 81756 
 81757 public function hasRecordThatPasses(callable $predicate, $level)
 81758 {
 81759 if (!isset($this->recordsByLevel[$level])) {
 81760 return false;
 81761 }
 81762 foreach ($this->recordsByLevel[$level] as $i => $rec) {
 81763 if (call_user_func($predicate, $rec, $i)) {
 81764 return true;
 81765 }
 81766 }
 81767 return false;
 81768 }
 81769 
 81770 public function __call($method, $args)
 81771 {
 81772 if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) {
 81773 $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3];
 81774 $level = strtolower($matches[2]);
 81775 if (method_exists($this, $genericMethod)) {
 81776 $args[] = $level;
 81777 return call_user_func_array([$this, $genericMethod], $args);
 81778 }
 81779 }
 81780 throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()');
 81781 }
 81782 
 81783 public function reset()
 81784 {
 81785 $this->records = [];
 81786 $this->recordsByLevel = [];
 81787 }
 81788 }
 81789 
 81790 Copyright (c) 2012-2016 Jan Sorgalla
 81791 
 81792 Permission is hereby granted, free of charge, to any person
 81793 obtaining a copy of this software and associated documentation
 81794 files (the "Software"), to deal in the Software without
 81795 restriction, including without limitation the rights to use,
 81796 copy, modify, merge, publish, distribute, sublicense, and/or sell
 81797 copies of the Software, and to permit persons to whom the
 81798 Software is furnished to do so, subject to the following
 81799 conditions:
 81800 
 81801 The above copyright notice and this permission notice shall be
 81802 included in all copies or substantial portions of the Software.
 81803 
 81804 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 81805 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 81806 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 81807 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 81808 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 81809 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 81810 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 81811 OTHER DEALINGS IN THE SOFTWARE.
 81812 
 81813 <?php
 81814 
 81815 namespace React\Promise;
 81816 
 81817 interface CancellablePromiseInterface extends PromiseInterface
 81818 {
 81819 
 81820 
 81821 
 81822 public function cancel();
 81823 }
 81824 <?php
 81825 
 81826 namespace React\Promise;
 81827 
 81828 class Deferred implements PromiseInterface, ResolverInterface, PromisorInterface, CancellablePromiseInterface
 81829 {
 81830 private $completed;
 81831 private $promise;
 81832 private $resolver;
 81833 private $handlers = array();
 81834 private $progressHandlers = array();
 81835 private $canceller;
 81836 
 81837 private $requiredCancelRequests = 0;
 81838 private $cancelRequests = 0;
 81839 
 81840 public function __construct($canceller = null)
 81841 {
 81842 if ($canceller !== null && !is_callable($canceller)) {
 81843 throw new \InvalidArgumentException(
 81844 sprintf(
 81845 'The canceller argument must be null or of type callable, %s given.',
 81846 gettype($canceller)
 81847 )
 81848 );
 81849 }
 81850 
 81851 $this->canceller = $canceller;
 81852 }
 81853 
 81854 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 81855 {
 81856 if (null !== $this->completed) {
 81857 return $this->completed->then($fulfilledHandler, $errorHandler, $progressHandler);
 81858 }
 81859 
 81860 $canceller = null;
 81861 if ($this->canceller !== null) {
 81862 $this->requiredCancelRequests++;
 81863 
 81864 $that = $this;
 81865 $current =& $this->cancelRequests;
 81866 $required =& $this->requiredCancelRequests;
 81867 
 81868 $canceller = function () use ($that, &$current, &$required) {
 81869 if (++$current < $required) {
 81870 return;
 81871 }
 81872 
 81873 $that->cancel();
 81874 };
 81875 }
 81876 
 81877 $deferred = new static($canceller);
 81878 
 81879 if (is_callable($progressHandler)) {
 81880 $progHandler = function ($update) use ($deferred, $progressHandler) {
 81881 try {
 81882 $deferred->progress(call_user_func($progressHandler, $update));
 81883 } catch (\Exception $e) {
 81884 $deferred->progress($e);
 81885 }
 81886 };
 81887 } else {
 81888 if (null !== $progressHandler) {
 81889 trigger_error('Invalid $progressHandler argument passed to then(), must be null or callable.', E_USER_NOTICE);
 81890 }
 81891 
 81892 $progHandler = array($deferred, 'progress');
 81893 }
 81894 
 81895 $this->handlers[] = function ($promise) use ($fulfilledHandler, $errorHandler, $deferred, $progHandler) {
 81896 $promise
 81897 ->then($fulfilledHandler, $errorHandler)
 81898 ->then(
 81899 array($deferred, 'resolve'),
 81900 array($deferred, 'reject'),
 81901 $progHandler
 81902 );
 81903 };
 81904 
 81905 $this->progressHandlers[] = $progHandler;
 81906 
 81907 return $deferred->promise();
 81908 }
 81909 
 81910 public function resolve($result = null)
 81911 {
 81912 if (null !== $this->completed) {
 81913 return resolve($result);
 81914 }
 81915 
 81916 $this->completed = resolve($result);
 81917 
 81918 $this->processQueue($this->handlers, $this->completed);
 81919 
 81920 $this->progressHandlers = $this->handlers = array();
 81921 
 81922 return $this->completed;
 81923 }
 81924 
 81925 public function reject($reason = null)
 81926 {
 81927 return $this->resolve(reject($reason));
 81928 }
 81929 
 81930 public function progress($update = null)
 81931 {
 81932 if (null !== $this->completed) {
 81933 return;
 81934 }
 81935 
 81936 $this->processQueue($this->progressHandlers, $update);
 81937 }
 81938 
 81939 public function promise()
 81940 {
 81941 if (null === $this->promise) {
 81942 $this->promise = new DeferredPromise($this);
 81943 }
 81944 
 81945 return $this->promise;
 81946 }
 81947 
 81948 public function resolver()
 81949 {
 81950 if (null === $this->resolver) {
 81951 $this->resolver = new DeferredResolver($this);
 81952 }
 81953 
 81954 return $this->resolver;
 81955 }
 81956 
 81957 public function cancel()
 81958 {
 81959 if (null === $this->canceller || null !== $this->completed) {
 81960 return;
 81961 }
 81962 
 81963 $canceller = $this->canceller;
 81964 $this->canceller = null;
 81965 
 81966 try {
 81967 $that = $this;
 81968 
 81969 call_user_func(
 81970 $canceller,
 81971 function ($value = null) use ($that) {
 81972 $that->resolve($value);
 81973 },
 81974 function ($reason = null) use ($that) {
 81975 $that->reject($reason);
 81976 },
 81977 function ($update = null) use ($that) {
 81978 $that->progress($update);
 81979 }
 81980 );
 81981 } catch (\Exception $e) {
 81982 $this->reject($e);
 81983 }
 81984 }
 81985 
 81986 protected function processQueue($queue, $value)
 81987 {
 81988 foreach ($queue as $handler) {
 81989 call_user_func($handler, $value);
 81990 }
 81991 }
 81992 }
 81993 <?php
 81994 
 81995 namespace React\Promise;
 81996 
 81997 class DeferredPromise implements PromiseInterface, CancellablePromiseInterface
 81998 {
 81999 private $deferred;
 82000 
 82001 public function __construct(Deferred $deferred)
 82002 {
 82003 $this->deferred = $deferred;
 82004 }
 82005 
 82006 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82007 {
 82008 return $this->deferred->then($fulfilledHandler, $errorHandler, $progressHandler);
 82009 }
 82010 
 82011 public function cancel()
 82012 {
 82013 $this->deferred->cancel();
 82014 }
 82015 }
 82016 <?php
 82017 
 82018 namespace React\Promise;
 82019 
 82020 class DeferredResolver implements ResolverInterface
 82021 {
 82022 private $deferred;
 82023 
 82024 public function __construct(Deferred $deferred)
 82025 {
 82026 $this->deferred = $deferred;
 82027 }
 82028 
 82029 public function resolve($result = null)
 82030 {
 82031 return $this->deferred->resolve($result);
 82032 }
 82033 
 82034 public function reject($reason = null)
 82035 {
 82036 return $this->deferred->reject($reason);
 82037 }
 82038 
 82039 public function progress($update = null)
 82040 {
 82041 return $this->deferred->progress($update);
 82042 }
 82043 }
 82044 <?php
 82045 
 82046 namespace React\Promise;
 82047 
 82048 class FulfilledPromise implements PromiseInterface, CancellablePromiseInterface
 82049 {
 82050 private $result;
 82051 
 82052 public function __construct($result = null)
 82053 {
 82054 $this->result = $result;
 82055 }
 82056 
 82057 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82058 {
 82059 try {
 82060 $result = $this->result;
 82061 
 82062 if (is_callable($fulfilledHandler)) {
 82063 $result = call_user_func($fulfilledHandler, $result);
 82064 } elseif (null !== $fulfilledHandler) {
 82065 trigger_error('Invalid $fulfilledHandler argument passed to then(), must be null or callable.', E_USER_NOTICE);
 82066 }
 82067 
 82068 return resolve($result);
 82069 } catch (\Exception $exception) {
 82070 return new RejectedPromise($exception);
 82071 }
 82072 }
 82073 
 82074 public function cancel()
 82075 {
 82076 }
 82077 }
 82078 <?php
 82079 
 82080 namespace React\Promise;
 82081 
 82082 class LazyPromise implements PromiseInterface, CancellablePromiseInterface
 82083 {
 82084 private $factory;
 82085 private $promise;
 82086 
 82087 public function __construct($factory)
 82088 {
 82089 $this->factory = $factory;
 82090 }
 82091 
 82092 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82093 {
 82094 return $this->promise()->then($fulfilledHandler, $errorHandler, $progressHandler);
 82095 }
 82096 
 82097 public function cancel()
 82098 {
 82099 $promise = $this->promise();
 82100 if ($promise instanceof CancellablePromiseInterface) {
 82101 $promise->cancel();
 82102 }
 82103 }
 82104 
 82105 private function promise()
 82106 {
 82107 if (null === $this->promise) {
 82108 try {
 82109 $this->promise = resolve(call_user_func($this->factory));
 82110 } catch (\Exception $exception) {
 82111 $this->promise = new RejectedPromise($exception);
 82112 }
 82113 }
 82114 return $this->promise;
 82115 }
 82116 }
 82117 <?php
 82118 
 82119 namespace React\Promise;
 82120 
 82121 class Promise implements PromiseInterface, CancellablePromiseInterface
 82122 {
 82123 private $deferred;
 82124 
 82125 public function __construct($resolver, $canceller = null)
 82126 {
 82127 if (!is_callable($resolver)) {
 82128 throw new \InvalidArgumentException(
 82129 sprintf(
 82130 'The resolver argument must be of type callable, %s given.',
 82131 gettype($resolver)
 82132 )
 82133 );
 82134 }
 82135 
 82136 $this->deferred = new Deferred($canceller);
 82137 $this->call($resolver);
 82138 }
 82139 
 82140 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82141 {
 82142 return $this->deferred->then($fulfilledHandler, $errorHandler, $progressHandler);
 82143 }
 82144 
 82145 public function cancel()
 82146 {
 82147 $this->deferred->cancel();
 82148 }
 82149 
 82150 private function call($callback)
 82151 {
 82152 $deferred = $this->deferred;
 82153 
 82154 try {
 82155 call_user_func(
 82156 $callback,
 82157 function ($result = null) use ($deferred) {
 82158 $deferred->resolve($result);
 82159 },
 82160 function ($reason = null) use ($deferred) {
 82161 $deferred->reject($reason);
 82162 },
 82163 function ($update = null) use ($deferred) {
 82164 $deferred->progress($update);
 82165 }
 82166 );
 82167 } catch (\Exception $e) {
 82168 $this->deferred->reject($e);
 82169 }
 82170 }
 82171 }
 82172 <?php
 82173 
 82174 namespace React\Promise;
 82175 
 82176 interface PromiseInterface
 82177 {
 82178 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null);
 82179 }
 82180 <?php
 82181 
 82182 namespace React\Promise;
 82183 
 82184 interface PromisorInterface
 82185 {
 82186 public function promise();
 82187 }
 82188 <?php
 82189 
 82190 namespace React\Promise;
 82191 
 82192 class RejectedPromise implements PromiseInterface, CancellablePromiseInterface
 82193 {
 82194 private $reason;
 82195 
 82196 public function __construct($reason = null)
 82197 {
 82198 $this->reason = $reason;
 82199 }
 82200 
 82201 public function then($fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82202 {
 82203 try {
 82204 if (!is_callable($errorHandler)) {
 82205 if (null !== $errorHandler) {
 82206 trigger_error('Invalid $errorHandler argument passed to then(), must be null or callable.', E_USER_NOTICE);
 82207 }
 82208 
 82209 return new RejectedPromise($this->reason);
 82210 }
 82211 
 82212 return resolve(call_user_func($errorHandler, $this->reason));
 82213 } catch (\Exception $exception) {
 82214 return new RejectedPromise($exception);
 82215 }
 82216 }
 82217 
 82218 public function cancel()
 82219 {
 82220 }
 82221 }
 82222 <?php
 82223 
 82224 namespace React\Promise;
 82225 
 82226 interface ResolverInterface
 82227 {
 82228 public function resolve($result = null);
 82229 public function reject($reason = null);
 82230 public function progress($update = null);
 82231 }
 82232 <?php
 82233 
 82234 namespace React\Promise;
 82235 
 82236 class Util
 82237 {
 82238 public static function promiseFor($promiseOrValue)
 82239 {
 82240 return resolve($promiseOrValue);
 82241 }
 82242 
 82243 public static function rejectedPromiseFor($promiseOrValue)
 82244 {
 82245 return reject($promiseOrValue);
 82246 }
 82247 }
 82248 <?php
 82249 
 82250 namespace React\Promise;
 82251 
 82252 class When
 82253 {
 82254 public static function resolve($promiseOrValue = null)
 82255 {
 82256 return resolve($promiseOrValue);
 82257 }
 82258 
 82259 public static function reject($promiseOrValue = null)
 82260 {
 82261 return reject($promiseOrValue);
 82262 }
 82263 
 82264 public static function lazy($factory)
 82265 {
 82266 return new LazyPromise($factory);
 82267 }
 82268 
 82269 public static function all($promisesOrValues, $fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82270 {
 82271 return all($promisesOrValues)->then($fulfilledHandler, $errorHandler, $progressHandler);
 82272 }
 82273 
 82274 public static function any($promisesOrValues, $fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82275 {
 82276 return any($promisesOrValues)->then($fulfilledHandler, $errorHandler, $progressHandler);
 82277 }
 82278 
 82279 public static function some($promisesOrValues, $howMany, $fulfilledHandler = null, $errorHandler = null, $progressHandler = null)
 82280 {
 82281 return some($promisesOrValues, $howMany)->then($fulfilledHandler, $errorHandler, $progressHandler);
 82282 }
 82283 
 82284 public static function map($promisesOrValues, $mapFunc)
 82285 {
 82286 return map($promisesOrValues, $mapFunc);
 82287 }
 82288 
 82289 public static function reduce($promisesOrValues, $reduceFunc , $initialValue = null)
 82290 {
 82291 return reduce($promisesOrValues, $reduceFunc, $initialValue);
 82292 }
 82293 }
 82294 <?php
 82295 
 82296 namespace React\Promise;
 82297 
 82298 function resolve($promiseOrValue = null)
 82299 {
 82300 if ($promiseOrValue instanceof PromiseInterface) {
 82301 return $promiseOrValue;
 82302 }
 82303 
 82304 return new FulfilledPromise($promiseOrValue);
 82305 }
 82306 
 82307 function reject($promiseOrValue = null)
 82308 {
 82309 if ($promiseOrValue instanceof PromiseInterface) {
 82310 return $promiseOrValue->then(function ($value) {
 82311 return new RejectedPromise($value);
 82312 });
 82313 }
 82314 
 82315 return new RejectedPromise($promiseOrValue);
 82316 }
 82317 
 82318 function all($promisesOrValues)
 82319 {
 82320 return map($promisesOrValues, function ($val) {
 82321 return $val;
 82322 });
 82323 }
 82324 
 82325 function any($promisesOrValues)
 82326 {
 82327 return some($promisesOrValues, 1)->then(function($val) {
 82328 return array_shift($val);
 82329 });
 82330 }
 82331 
 82332 function some($promisesOrValues, $howMany)
 82333 {
 82334 return resolve($promisesOrValues)->then(function ($array) use ($howMany) {
 82335 if (!is_array($array)) {
 82336 $array = array();
 82337 }
 82338 
 82339 $len = count($array);
 82340 $toResolve = max(0, min($howMany, $len));
 82341 $values = array();
 82342 $deferred = new Deferred();
 82343 
 82344 if (!$toResolve) {
 82345 $deferred->resolve($values);
 82346 } else {
 82347 $toReject = ($len - $toResolve) + 1;
 82348 $reasons = array();
 82349 
 82350 $progress = array($deferred, 'progress');
 82351 
 82352 $fulfillOne = function ($val, $i) use (&$values, &$toResolve, $deferred) {
 82353 $values[$i] = $val;
 82354 
 82355 if (0 === --$toResolve) {
 82356 $deferred->resolve($values);
 82357 
 82358 return true;
 82359 }
 82360 };
 82361 
 82362 $rejectOne = function ($reason, $i) use (&$reasons, &$toReject, $deferred) {
 82363 $reasons[$i] = $reason;
 82364 
 82365 if (0 === --$toReject) {
 82366 $deferred->reject($reasons);
 82367 
 82368 return true;
 82369 }
 82370 };
 82371 
 82372 foreach ($array as $i => $promiseOrValue) {
 82373 $fulfiller = function ($val) use ($i, &$fulfillOne, &$rejectOne) {
 82374 $reset = $fulfillOne($val, $i);
 82375 
 82376 if (true === $reset) {
 82377 $fulfillOne = $rejectOne = function () {};
 82378 }
 82379 };
 82380 
 82381 $rejecter = function ($val) use ($i, &$fulfillOne, &$rejectOne) {
 82382 $reset = $rejectOne($val, $i);
 82383 
 82384 if (true === $reset) {
 82385 $fulfillOne = $rejectOne = function () {};
 82386 }
 82387 };
 82388 
 82389 resolve($promiseOrValue)->then($fulfiller, $rejecter, $progress);
 82390 }
 82391 }
 82392 
 82393 return $deferred->promise();
 82394 });
 82395 }
 82396 
 82397 function map($promisesOrValues, $mapFunc)
 82398 {
 82399 return resolve($promisesOrValues)->then(function ($array) use ($mapFunc) {
 82400 if (!is_array($array)) {
 82401 $array = array();
 82402 }
 82403 
 82404 $toResolve = count($array);
 82405 $results = array();
 82406 $deferred = new Deferred();
 82407 
 82408 if (!$toResolve) {
 82409 $deferred->resolve($results);
 82410 } else {
 82411 $resolve = function ($item, $i) use ($mapFunc, &$results, &$toResolve, $deferred) {
 82412 resolve($item)
 82413 ->then($mapFunc)
 82414 ->then(
 82415 function ($mapped) use (&$results, $i, &$toResolve, $deferred) {
 82416 $results[$i] = $mapped;
 82417 
 82418 if (0 === --$toResolve) {
 82419 $deferred->resolve($results);
 82420 }
 82421 },
 82422 array($deferred, 'reject')
 82423 );
 82424 };
 82425 
 82426 foreach ($array as $i => $item) {
 82427 $resolve($item, $i);
 82428 }
 82429 }
 82430 
 82431 return $deferred->promise();
 82432 });
 82433 }
 82434 
 82435 function reduce($promisesOrValues, $reduceFunc , $initialValue = null)
 82436 {
 82437 return resolve($promisesOrValues)->then(function ($array) use ($reduceFunc, $initialValue) {
 82438 if (!is_array($array)) {
 82439 $array = array();
 82440 }
 82441 
 82442 $total = count($array);
 82443 $i = 0;
 82444 
 82445 
 82446 
 82447 $wrappedReduceFunc = function ($current, $val) use ($reduceFunc, $total, &$i) {
 82448 return resolve($current)->then(function ($c) use ($reduceFunc, $total, &$i, $val) {
 82449 return resolve($val)->then(function ($value) use ($reduceFunc, $total, &$i, $c) {
 82450 return call_user_func($reduceFunc, $c, $value, $i++, $total);
 82451 });
 82452 });
 82453 };
 82454 
 82455 return array_reduce($array, $wrappedReduceFunc, $initialValue);
 82456 });
 82457 }
 82458 <?php
 82459 
 82460 if (!function_exists('React\Promise\resolve')) {
 82461 require __DIR__.'/functions.php';
 82462 }
 82463 
 82464 Copyright (c) 2011 Jordi Boggiano
 82465 
 82466 Permission is hereby granted, free of charge, to any person obtaining a copy
 82467 of this software and associated documentation files (the "Software"), to deal
 82468 in the Software without restriction, including without limitation the rights
 82469 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 82470 copies of the Software, and to permit persons to whom the Software is furnished
 82471 to do so, subject to the following conditions:
 82472 
 82473 The above copyright notice and this permission notice shall be included in all
 82474 copies or substantial portions of the Software.
 82475 
 82476 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 82477 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 82478 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 82479 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 82480 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 82481 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 82482 THE SOFTWARE.
 82483 
 82484 <?php
 82485 
 82486 
 82487 
 82488 
 82489 
 82490 
 82491 
 82492 
 82493 
 82494 
 82495 namespace Seld\JsonLint;
 82496 
 82497 class DuplicateKeyException extends ParsingException
 82498 {
 82499 
 82500 
 82501 
 82502 
 82503 
 82504 public function __construct($message, $key, array $details = array())
 82505 {
 82506 $details['key'] = $key;
 82507 parent::__construct($message, $details);
 82508 }
 82509 
 82510 public function getKey()
 82511 {
 82512 return $this->details['key'];
 82513 }
 82514 
 82515 
 82516 
 82517 
 82518 public function getDetails()
 82519 {
 82520 return $this->details;
 82521 }
 82522 }
 82523 <?php
 82524 
 82525 
 82526 
 82527 
 82528 
 82529 
 82530 
 82531 
 82532 
 82533 
 82534 namespace Seld\JsonLint;
 82535 use stdClass;
 82536 
 82537 
 82538 
 82539 
 82540 
 82541 
 82542 
 82543 
 82544 
 82545 
 82546 
 82547 
 82548 
 82549 
 82550 class JsonParser
 82551 {
 82552 const DETECT_KEY_CONFLICTS = 1;
 82553 const ALLOW_DUPLICATE_KEYS = 2;
 82554 const PARSE_TO_ASSOC = 4;
 82555 
 82556 private $lexer;
 82557 
 82558 private $flags;
 82559 private $stack;
 82560 private $vstack; 
 82561 private $lstack; 
 82562 
 82563 
 82564 
 82565 
 82566 private $symbols = array(
 82567 'error' => 2,
 82568 'JSONString' => 3,
 82569 'STRING' => 4,
 82570 'JSONNumber' => 5,
 82571 'NUMBER' => 6,
 82572 'JSONNullLiteral' => 7,
 82573 'NULL' => 8,
 82574 'JSONBooleanLiteral' => 9,
 82575 'TRUE' => 10,
 82576 'FALSE' => 11,
 82577 'JSONText' => 12,
 82578 'JSONValue' => 13,
 82579 'EOF' => 14,
 82580 'JSONObject' => 15,
 82581 'JSONArray' => 16,
 82582 '{' => 17,
 82583 '}' => 18,
 82584 'JSONMemberList' => 19,
 82585 'JSONMember' => 20,
 82586 ':' => 21,
 82587 ',' => 22,
 82588 '[' => 23,
 82589 ']' => 24,
 82590 'JSONElementList' => 25,
 82591 '$accept' => 0,
 82592 '$end' => 1,
 82593 );
 82594 
 82595 
 82596 
 82597 
 82598 private $terminals_ = array(
 82599 2 => "error",
 82600 4 => "STRING",
 82601 6 => "NUMBER",
 82602 8 => "NULL",
 82603 10 => "TRUE",
 82604 11 => "FALSE",
 82605 14 => "EOF",
 82606 17 => "{",
 82607 18 => "}",
 82608 21 => ":",
 82609 22 => ",",
 82610 23 => "[",
 82611 24 => "]",
 82612 );
 82613 
 82614 private $productions_ = array(
 82615 0,
 82616 array(3, 1),
 82617 array(5, 1),
 82618 array(7, 1),
 82619 array(9, 1),
 82620 array(9, 1),
 82621 array(12, 2),
 82622 array(13, 1),
 82623 array(13, 1),
 82624 array(13, 1),
 82625 array(13, 1),
 82626 array(13, 1),
 82627 array(13, 1),
 82628 array(15, 2),
 82629 array(15, 3),
 82630 array(20, 3),
 82631 array(19, 1),
 82632 array(19, 3),
 82633 array(16, 2),
 82634 array(16, 3),
 82635 array(25, 1),
 82636 array(25, 3)
 82637 );
 82638 
 82639 private $table = array(array(3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 12 => 1, 13 => 2, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15)), array( 1 => array(3)), array( 14 => array(1,16)), array( 14 => array(2,7), 18 => array(2,7), 22 => array(2,7), 24 => array(2,7)), array( 14 => array(2,8), 18 => array(2,8), 22 => array(2,8), 24 => array(2,8)), array( 14 => array(2,9), 18 => array(2,9), 22 => array(2,9), 24 => array(2,9)), array( 14 => array(2,10), 18 => array(2,10), 22 => array(2,10), 24 => array(2,10)), array( 14 => array(2,11), 18 => array(2,11), 22 => array(2,11), 24 => array(2,11)), array( 14 => array(2,12), 18 => array(2,12), 22 => array(2,12), 24 => array(2,12)), array( 14 => array(2,3), 18 => array(2,3), 22 => array(2,3), 24 => array(2,3)), array( 14 => array(2,4), 18 => array(2,4), 22 => array(2,4), 24 => array(2,4)), array( 14 => array(2,5), 18 => array(2,5), 22 => array(2,5), 24 => array(2,5)), array( 14 => array(2,1), 18 => array(2,1), 21 => array(2,1), 22 => array(2,1), 24 => array(2,1)), array( 14 => array(2,2), 18 => array(2,2), 22 => array(2,2), 24 => array(2,2)), array( 3 => 20, 4 => array(1,12), 18 => array(1,17), 19 => 18, 20 => 19 ), array( 3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 13 => 23, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15), 24 => array(1,21), 25 => 22 ), array( 1 => array(2,6)), array( 14 => array(2,13), 18 => array(2,13), 22 => array(2,13), 24 => array(2,13)), array( 18 => array(1,24), 22 => array(1,25)), array( 18 => array(2,16), 22 => array(2,16)), array( 21 => array(1,26)), array( 14 => array(2,18), 18 => array(2,18), 22 => array(2,18), 24 => array(2,18)), array( 22 => array(1,28), 24 => array(1,27)), array( 22 => array(2,20), 24 => array(2,20)), array( 14 => array(2,14), 18 => array(2,14), 22 => array(2,14), 24 => array(2,14)), array( 3 => 20, 4 => array(1,12), 20 => 29 ), array( 3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 13 => 30, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15)), array( 14 => array(2,19), 18 => array(2,19), 22 => array(2,19), 24 => array(2,19)), array( 3 => 5, 4 => array(1,12), 5 => 6, 6 => array(1,13), 7 => 3, 8 => array(1,9), 9 => 4, 10 => array(1,10), 11 => array(1,11), 13 => 31, 15 => 7, 16 => 8, 17 => array(1,14), 23 => array(1,15)), array( 18 => array(2,17), 22 => array(2,17)), array( 18 => array(2,15), 22 => array(2,15)), array( 22 => array(2,21), 24 => array(2,21)),
 82640 );
 82641 
 82642 private $defaultActions = array(
 82643 16 => array(2, 6)
 82644 );
 82645 
 82646 
 82647 
 82648 
 82649 
 82650 
 82651 public function lint($input, $flags = 0)
 82652 {
 82653 try {
 82654 $this->parse($input, $flags);
 82655 } catch (ParsingException $e) {
 82656 return $e;
 82657 }
 82658 return null;
 82659 }
 82660 
 82661 
 82662 
 82663 
 82664 
 82665 
 82666 
 82667 public function parse($input, $flags = 0)
 82668 {
 82669 $this->failOnBOM($input);
 82670 
 82671 $this->flags = $flags;
 82672 
 82673 $this->stack = array(0);
 82674 $this->vstack = array(null);
 82675 $this->lstack = array();
 82676 
 82677 $yytext = '';
 82678 $yylineno = 0;
 82679 $yyleng = 0;
 82680 $recovering = 0;
 82681 $TERROR = 2;
 82682 $EOF = 1;
 82683 
 82684 $this->lexer = new Lexer();
 82685 $this->lexer->setInput($input);
 82686 
 82687 $yyloc = $this->lexer->yylloc;
 82688 $this->lstack[] = $yyloc;
 82689 
 82690 $symbol = null;
 82691 $preErrorSymbol = null;
 82692 $state = null;
 82693 $action = null;
 82694 $a = null;
 82695 $r = null;
 82696 $yyval = new stdClass;
 82697 $p = null;
 82698 $len = null;
 82699 $newState = null;
 82700 $expected = null;
 82701 $errStr = null;
 82702 
 82703 while (true) {
 82704 
 82705 $state = $this->stack[\count($this->stack)-1];
 82706 
 82707 
 82708 if (isset($this->defaultActions[$state])) {
 82709 $action = $this->defaultActions[$state];
 82710 } else {
 82711 if ($symbol == null) {
 82712 $symbol = $this->lex();
 82713 }
 82714 
 82715 $action = isset($this->table[$state][$symbol]) ? $this->table[$state][$symbol] : false;
 82716 }
 82717 
 82718 
 82719 if (!$action || !$action[0]) {
 82720 if (!$recovering) {
 82721 
 82722 $expected = array();
 82723 foreach ($this->table[$state] as $p => $ignore) {
 82724 if (isset($this->terminals_[$p]) && $p > 2) {
 82725 $expected[] = "'" . $this->terminals_[$p] . "'";
 82726 }
 82727 }
 82728 
 82729 $message = null;
 82730 if (\in_array("'STRING'", $expected) && \in_array(substr($this->lexer->match, 0, 1), array('"', "'"))) {
 82731 $message = "Invalid string";
 82732 if ("'" === substr($this->lexer->match, 0, 1)) {
 82733 $message .= ", it appears you used single quotes instead of double quotes";
 82734 } elseif (preg_match('{".+?(\\\\[^"bfnrt/\\\\u](...)?)}', $this->lexer->getFullUpcomingInput(), $match)) {
 82735 $message .= ", it appears you have an unescaped backslash at: ".$match[1];
 82736 } elseif (preg_match('{"(?:[^"]+|\\\\")*$}m', $this->lexer->getFullUpcomingInput())) {
 82737 $message .= ", it appears you forgot to terminate a string, or attempted to write a multiline string which is invalid";
 82738 }
 82739 }
 82740 
 82741 $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n";
 82742 $errStr .= $this->lexer->showPosition() . "\n";
 82743 if ($message) {
 82744 $errStr .= $message;
 82745 } else {
 82746 $errStr .= (\count($expected) > 1) ? "Expected one of: " : "Expected: ";
 82747 $errStr .= implode(', ', $expected);
 82748 }
 82749 
 82750 if (',' === substr(trim($this->lexer->getPastInput()), -1)) {
 82751 $errStr .= " - It appears you have an extra trailing comma";
 82752 }
 82753 
 82754 $this->parseError($errStr, array(
 82755 'text' => $this->lexer->match,
 82756 'token' => !empty($this->terminals_[$symbol]) ? $this->terminals_[$symbol] : $symbol,
 82757 'line' => $this->lexer->yylineno,
 82758 'loc' => $yyloc,
 82759 'expected' => $expected,
 82760 ));
 82761 }
 82762 
 82763 
 82764 if ($recovering == 3) {
 82765 if ($symbol == $EOF) {
 82766 throw new ParsingException($errStr ?: 'Parsing halted.');
 82767 }
 82768 
 82769 
 82770 $yyleng = $this->lexer->yyleng;
 82771 $yytext = $this->lexer->yytext;
 82772 $yylineno = $this->lexer->yylineno;
 82773 $yyloc = $this->lexer->yylloc;
 82774 $symbol = $this->lex();
 82775 }
 82776 
 82777 
 82778 while (true) {
 82779 
 82780 if (\array_key_exists($TERROR, $this->table[$state])) {
 82781 break;
 82782 }
 82783 if ($state == 0) {
 82784 throw new ParsingException($errStr ?: 'Parsing halted.');
 82785 }
 82786 $this->popStack(1);
 82787 $state = $this->stack[\count($this->stack)-1];
 82788 }
 82789 
 82790 $preErrorSymbol = $symbol; 
 82791 $symbol = $TERROR; 
 82792 $state = $this->stack[\count($this->stack)-1];
 82793 $action = isset($this->table[$state][$TERROR]) ? $this->table[$state][$TERROR] : false;
 82794 $recovering = 3; 
 82795 }
 82796 
 82797 
 82798 if (\is_array($action[0]) && \count($action) > 1) {
 82799 throw new ParsingException('Parse Error: multiple actions possible at state: ' . $state . ', token: ' . $symbol);
 82800 }
 82801 
 82802 switch ($action[0]) {
 82803 case 1: 
 82804 $this->stack[] = $symbol;
 82805 $this->vstack[] = $this->lexer->yytext;
 82806 $this->lstack[] = $this->lexer->yylloc;
 82807 $this->stack[] = $action[1]; 
 82808 $symbol = null;
 82809 if (!$preErrorSymbol) { 
 82810 $yyleng = $this->lexer->yyleng;
 82811 $yytext = $this->lexer->yytext;
 82812 $yylineno = $this->lexer->yylineno;
 82813 $yyloc = $this->lexer->yylloc;
 82814 if ($recovering > 0) {
 82815 $recovering--;
 82816 }
 82817 } else { 
 82818 $symbol = $preErrorSymbol;
 82819 $preErrorSymbol = null;
 82820 }
 82821 break;
 82822 
 82823 case 2: 
 82824 $len = $this->productions_[$action[1]][1];
 82825 
 82826 
 82827 $yyval->token = $this->vstack[\count($this->vstack) - $len]; 
 82828 
 82829 $yyval->store = array( 
 82830 'first_line' => $this->lstack[\count($this->lstack) - ($len ?: 1)]['first_line'],
 82831 'last_line' => $this->lstack[\count($this->lstack) - 1]['last_line'],
 82832 'first_column' => $this->lstack[\count($this->lstack) - ($len ?: 1)]['first_column'],
 82833 'last_column' => $this->lstack[\count($this->lstack) - 1]['last_column'],
 82834 );
 82835 $r = $this->performAction($yyval, $yytext, $yyleng, $yylineno, $action[1], $this->vstack);
 82836 
 82837 if (!$r instanceof Undefined) {
 82838 return $r;
 82839 }
 82840 
 82841 if ($len) {
 82842 $this->popStack($len);
 82843 }
 82844 
 82845 $this->stack[] = $this->productions_[$action[1]][0]; 
 82846 $this->vstack[] = $yyval->token;
 82847 $this->lstack[] = $yyval->store;
 82848 $newState = $this->table[$this->stack[\count($this->stack)-2]][$this->stack[\count($this->stack)-1]];
 82849 $this->stack[] = $newState;
 82850 break;
 82851 
 82852 case 3: 
 82853 
 82854 return true;
 82855 }
 82856 }
 82857 }
 82858 
 82859 protected function parseError($str, $hash)
 82860 {
 82861 throw new ParsingException($str, $hash);
 82862 }
 82863 
 82864 
 82865 
 82866 
 82867 private function performAction(stdClass $yyval, $yytext, $yyleng, $yylineno, $yystate, &$tokens)
 82868 {
 82869 
 82870 $len = \count($tokens) - 1;
 82871 switch ($yystate) {
 82872 case 1:
 82873 $yytext = preg_replace_callback('{(?:\\\\["bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4})}', array($this, 'stringInterpolation'), $yytext);
 82874 $yyval->token = $yytext;
 82875 break;
 82876 case 2:
 82877 if (strpos($yytext, 'e') !== false || strpos($yytext, 'E') !== false) {
 82878 $yyval->token = \floatval($yytext);
 82879 } else {
 82880 $yyval->token = strpos($yytext, '.') === false ? \intval($yytext) : \floatval($yytext);
 82881 }
 82882 break;
 82883 case 3:
 82884 $yyval->token = null;
 82885 break;
 82886 case 4:
 82887 $yyval->token = true;
 82888 break;
 82889 case 5:
 82890 $yyval->token = false;
 82891 break;
 82892 case 6:
 82893 return $yyval->token = $tokens[$len-1];
 82894 case 13:
 82895 if ($this->flags & self::PARSE_TO_ASSOC) {
 82896 $yyval->token = array();
 82897 } else {
 82898 $yyval->token = new stdClass;
 82899 }
 82900 break;
 82901 case 14:
 82902 $yyval->token = $tokens[$len-1];
 82903 break;
 82904 case 15:
 82905 $yyval->token = array($tokens[$len-2], $tokens[$len]);
 82906 break;
 82907 case 16:
 82908 if (PHP_VERSION_ID < 70100) {
 82909 $property = $tokens[$len][0] === '' ? '_empty_' : $tokens[$len][0];
 82910 } else {
 82911 $property = $tokens[$len][0];
 82912 }
 82913 if ($this->flags & self::PARSE_TO_ASSOC) {
 82914 $yyval->token = array();
 82915 $yyval->token[$property] = $tokens[$len][1];
 82916 } else {
 82917 $yyval->token = new stdClass;
 82918 $yyval->token->$property = $tokens[$len][1];
 82919 }
 82920 break;
 82921 case 17:
 82922 if ($this->flags & self::PARSE_TO_ASSOC) {
 82923 $yyval->token =& $tokens[$len-2];
 82924 $key = $tokens[$len][0];
 82925 if (($this->flags & self::DETECT_KEY_CONFLICTS) && isset($tokens[$len-2][$key])) {
 82926 $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n";
 82927 $errStr .= $this->lexer->showPosition() . "\n";
 82928 $errStr .= "Duplicate key: ".$tokens[$len][0];
 82929 throw new DuplicateKeyException($errStr, $tokens[$len][0], array('line' => $yylineno+1));
 82930 } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($tokens[$len-2][$key])) {
 82931 $duplicateCount = 1;
 82932 do {
 82933 $duplicateKey = $key . '.' . $duplicateCount++;
 82934 } while (isset($tokens[$len-2][$duplicateKey]));
 82935 $key = $duplicateKey;
 82936 }
 82937 $tokens[$len-2][$key] = $tokens[$len][1];
 82938 } else {
 82939 $yyval->token = $tokens[$len-2];
 82940 if (PHP_VERSION_ID < 70100) {
 82941 $key = $tokens[$len][0] === '' ? '_empty_' : $tokens[$len][0];
 82942 } else {
 82943 $key = $tokens[$len][0];
 82944 }
 82945 if (($this->flags & self::DETECT_KEY_CONFLICTS) && isset($tokens[$len-2]->{$key})) {
 82946 $errStr = 'Parse error on line ' . ($yylineno+1) . ":\n";
 82947 $errStr .= $this->lexer->showPosition() . "\n";
 82948 $errStr .= "Duplicate key: ".$tokens[$len][0];
 82949 throw new DuplicateKeyException($errStr, $tokens[$len][0], array('line' => $yylineno+1));
 82950 } elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && isset($tokens[$len-2]->{$key})) {
 82951 $duplicateCount = 1;
 82952 do {
 82953 $duplicateKey = $key . '.' . $duplicateCount++;
 82954 } while (isset($tokens[$len-2]->$duplicateKey));
 82955 $key = $duplicateKey;
 82956 }
 82957 $tokens[$len-2]->$key = $tokens[$len][1];
 82958 }
 82959 break;
 82960 case 18:
 82961 $yyval->token = array();
 82962 break;
 82963 case 19:
 82964 $yyval->token = $tokens[$len-1];
 82965 break;
 82966 case 20:
 82967 $yyval->token = array($tokens[$len]);
 82968 break;
 82969 case 21:
 82970 $tokens[$len-2][] = $tokens[$len];
 82971 $yyval->token = $tokens[$len-2];
 82972 break;
 82973 }
 82974 
 82975 return new Undefined();
 82976 }
 82977 
 82978 private function stringInterpolation($match)
 82979 {
 82980 switch ($match[0]) {
 82981 case '\\\\':
 82982 return '\\';
 82983 case '\"':
 82984 return '"';
 82985 case '\b':
 82986 return \chr(8);
 82987 case '\f':
 82988 return \chr(12);
 82989 case '\n':
 82990 return "\n";
 82991 case '\r':
 82992 return "\r";
 82993 case '\t':
 82994 return "\t";
 82995 case '\/':
 82996 return "/";
 82997 default:
 82998 return html_entity_decode('&#x'.ltrim(substr($match[0], 2), '0').';', ENT_QUOTES, 'UTF-8');
 82999 }
 83000 }
 83001 
 83002 private function popStack($n)
 83003 {
 83004 $this->stack = \array_slice($this->stack, 0, - (2 * $n));
 83005 $this->vstack = \array_slice($this->vstack, 0, - $n);
 83006 $this->lstack = \array_slice($this->lstack, 0, - $n);
 83007 }
 83008 
 83009 private function lex()
 83010 {
 83011 $token = $this->lexer->lex() ?: 1; 
 83012 
 83013 if (!is_numeric($token)) {
 83014 $token = isset($this->symbols[$token]) ? $this->symbols[$token] : $token;
 83015 }
 83016 
 83017 return $token;
 83018 }
 83019 
 83020 private function failOnBOM($input)
 83021 {
 83022 
 83023 $bom = "\xEF\xBB\xBF";
 83024 
 83025 if (substr($input, 0, 3) === $bom) {
 83026 $this->parseError("BOM detected, make sure your input does not include a Unicode Byte-Order-Mark", array());
 83027 }
 83028 }
 83029 }
 83030 <?php
 83031 
 83032 
 83033 
 83034 
 83035 
 83036 
 83037 
 83038 
 83039 
 83040 
 83041 namespace Seld\JsonLint;
 83042 
 83043 
 83044 
 83045 
 83046 
 83047 
 83048 class Lexer
 83049 {
 83050 private $EOF = 1;
 83051 
 83052 
 83053 
 83054 private $rules = array(
 83055 0 => '/\G\s+/',
 83056 1 => '/\G-?([0-9]|[1-9][0-9]+)(\.[0-9]+)?([eE][+-]?[0-9]+)?\b/',
 83057 2 => '{\G"(?>\\\\["bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\0-\x1f\\\\"]++)*+"}',
 83058 3 => '/\G\{/',
 83059 4 => '/\G\}/',
 83060 5 => '/\G\[/',
 83061 6 => '/\G\]/',
 83062 7 => '/\G,/',
 83063 8 => '/\G:/',
 83064 9 => '/\Gtrue\b/',
 83065 10 => '/\Gfalse\b/',
 83066 11 => '/\Gnull\b/',
 83067 12 => '/\G$/',
 83068 13 => '/\G./',
 83069 );
 83070 
 83071 private $conditions = array(
 83072 "INITIAL" => array(
 83073 "rules" => array(0,1,2,3,4,5,6,7,8,9,10,11,12,13),
 83074 "inclusive" => true,
 83075 ),
 83076 );
 83077 
 83078 private $conditionStack;
 83079 private $input;
 83080 private $more;
 83081 private $done;
 83082 private $offset;
 83083 
 83084 public $match;
 83085 public $yylineno;
 83086 public $yyleng;
 83087 public $yytext;
 83088 public $yylloc;
 83089 
 83090 public function lex()
 83091 {
 83092 $r = $this->next();
 83093 if (!$r instanceof Undefined) {
 83094 return $r;
 83095 }
 83096 
 83097 return $this->lex();
 83098 }
 83099 
 83100 public function setInput($input)
 83101 {
 83102 $this->input = $input;
 83103 $this->more = false;
 83104 $this->done = false;
 83105 $this->offset = 0;
 83106 $this->yylineno = $this->yyleng = 0;
 83107 $this->yytext = $this->match = '';
 83108 $this->conditionStack = array('INITIAL');
 83109 $this->yylloc = array('first_line' => 1, 'first_column' => 0, 'last_line' => 1, 'last_column' => 0);
 83110 
 83111 return $this;
 83112 }
 83113 
 83114 public function showPosition()
 83115 {
 83116 $pre = str_replace("\n", '', $this->getPastInput());
 83117 $c = str_repeat('-', max(0, \strlen($pre) - 1)); 
 83118 
 83119 return $pre . str_replace("\n", '', $this->getUpcomingInput()) . "\n" . $c . "^";
 83120 }
 83121 
 83122 public function getPastInput()
 83123 {
 83124 $pastLength = $this->offset - \strlen($this->match);
 83125 
 83126 return ($pastLength > 20 ? '...' : '') . substr($this->input, max(0, $pastLength - 20), min(20, $pastLength));
 83127 }
 83128 
 83129 public function getUpcomingInput()
 83130 {
 83131 $next = $this->match;
 83132 if (\strlen($next) < 20) {
 83133 $next .= substr($this->input, $this->offset, 20 - \strlen($next));
 83134 }
 83135 
 83136 return substr($next, 0, 20) . (\strlen($next) > 20 ? '...' : '');
 83137 }
 83138 
 83139 public function getFullUpcomingInput()
 83140 {
 83141 $next = $this->match;
 83142 if (substr($next, 0, 1) === '"' && substr_count($next, '"') === 1) {
 83143 $len = \strlen($this->input);
 83144 $strEnd = min(strpos($this->input, '"', $this->offset + 1) ?: $len, strpos($this->input, "\n", $this->offset + 1) ?: $len);
 83145 $next .= substr($this->input, $this->offset, $strEnd - $this->offset);
 83146 } elseif (\strlen($next) < 20) {
 83147 $next .= substr($this->input, $this->offset, 20 - \strlen($next));
 83148 }
 83149 
 83150 return $next;
 83151 }
 83152 
 83153 protected function parseError($str, $hash)
 83154 {
 83155 throw new \Exception($str);
 83156 }
 83157 
 83158 private function next()
 83159 {
 83160 if ($this->done) {
 83161 return $this->EOF;
 83162 }
 83163 if ($this->offset === \strlen($this->input)) {
 83164 $this->done = true;
 83165 }
 83166 
 83167 $token = null;
 83168 $match = null;
 83169 $col = null;
 83170 $lines = null;
 83171 
 83172 if (!$this->more) {
 83173 $this->yytext = '';
 83174 $this->match = '';
 83175 }
 83176 
 83177 $rules = $this->getCurrentRules();
 83178 $rulesLen = \count($rules);
 83179 
 83180 for ($i=0; $i < $rulesLen; $i++) {
 83181 if (preg_match($this->rules[$rules[$i]], $this->input, $match, 0, $this->offset)) {
 83182 preg_match_all('/\n.*/', $match[0], $lines);
 83183 $lines = $lines[0];
 83184 if ($lines) {
 83185 $this->yylineno += \count($lines);
 83186 }
 83187 
 83188 $this->yylloc = array(
 83189 'first_line' => $this->yylloc['last_line'],
 83190 'last_line' => $this->yylineno+1,
 83191 'first_column' => $this->yylloc['last_column'],
 83192 'last_column' => $lines ? \strlen($lines[\count($lines) - 1]) - 1 : $this->yylloc['last_column'] + \strlen($match[0]),
 83193 );
 83194 $this->yytext .= $match[0];
 83195 $this->match .= $match[0];
 83196 $this->yyleng = \strlen($this->yytext);
 83197 $this->more = false;
 83198 $this->offset += \strlen($match[0]);
 83199 $token = $this->performAction($rules[$i], $this->conditionStack[\count($this->conditionStack)-1]);
 83200 if ($token) {
 83201 return $token;
 83202 }
 83203 
 83204 return new Undefined();
 83205 }
 83206 }
 83207 
 83208 if ($this->offset === \strlen($this->input)) {
 83209 return $this->EOF;
 83210 }
 83211 
 83212 $this->parseError(
 83213 'Lexical error on line ' . ($this->yylineno+1) . ". Unrecognized text.\n" . $this->showPosition(),
 83214 array(
 83215 'text' => "",
 83216 'token' => null,
 83217 'line' => $this->yylineno,
 83218 )
 83219 );
 83220 }
 83221 
 83222 private function getCurrentRules()
 83223 {
 83224 return $this->conditions[$this->conditionStack[\count($this->conditionStack)-1]]['rules'];
 83225 }
 83226 
 83227 private function performAction($avoiding_name_collisions, $YY_START)
 83228 {
 83229 switch ($avoiding_name_collisions) {
 83230 case 0:
 83231 break;
 83232 case 1:
 83233 return 6;
 83234 case 2:
 83235 $this->yytext = substr($this->yytext, 1, $this->yyleng-2);
 83236 
 83237 return 4;
 83238 case 3:
 83239 return 17;
 83240 case 4:
 83241 return 18;
 83242 case 5:
 83243 return 23;
 83244 case 6:
 83245 return 24;
 83246 case 7:
 83247 return 22;
 83248 case 8:
 83249 return 21;
 83250 case 9:
 83251 return 10;
 83252 case 10:
 83253 return 11;
 83254 case 11:
 83255 return 8;
 83256 case 12:
 83257 return 14;
 83258 case 13:
 83259 return 'INVALID';
 83260 }
 83261 }
 83262 }
 83263 <?php
 83264 
 83265 
 83266 
 83267 
 83268 
 83269 
 83270 
 83271 
 83272 
 83273 
 83274 namespace Seld\JsonLint;
 83275 
 83276 class ParsingException extends \Exception
 83277 {
 83278 protected $details;
 83279 
 83280 
 83281 
 83282 
 83283 
 83284 public function __construct($message, $details = array())
 83285 {
 83286 $this->details = $details;
 83287 parent::__construct($message);
 83288 }
 83289 
 83290 
 83291 
 83292 
 83293 public function getDetails()
 83294 {
 83295 return $this->details;
 83296 }
 83297 }
 83298 <?php
 83299 
 83300 
 83301 
 83302 
 83303 
 83304 
 83305 
 83306 
 83307 
 83308 
 83309 namespace Seld\JsonLint;
 83310 
 83311 class Undefined
 83312 {
 83313 }
 83314 
 83315 Copyright (c) 2015 Jordi Boggiano
 83316 
 83317 Permission is hereby granted, free of charge, to any person obtaining a copy
 83318 of this software and associated documentation files (the "Software"), to deal
 83319 in the Software without restriction, including without limitation the rights
 83320 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 83321 copies of the Software, and to permit persons to whom the Software is furnished
 83322 to do so, subject to the following conditions:
 83323 
 83324 The above copyright notice and this permission notice shall be included in all
 83325 copies or substantial portions of the Software.
 83326 
 83327 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 83328 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 83329 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 83330 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 83331 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 83332 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 83333 THE SOFTWARE.
 83334 
 83335 <?php
 83336 
 83337 
 83338 
 83339 
 83340 
 83341 
 83342 
 83343 
 83344 
 83345 
 83346 namespace Seld\PharUtils;
 83347 
 83348 class Linter
 83349 {
 83350 
 83351 
 83352 
 83353 
 83354 
 83355 
 83356 public static function lint($path, array $excludedPaths = array())
 83357 {
 83358 $php = defined('PHP_BINARY') ? PHP_BINARY : 'php';
 83359 
 83360 if ($isWindows = defined('PHP_WINDOWS_VERSION_BUILD')) {
 83361 $tmpFile = @tempnam(sys_get_temp_dir(), '');
 83362 
 83363 if (!$tmpFile || !is_writable($tmpFile)) {
 83364 throw new \RuntimeException('Unable to create temp file');
 83365 }
 83366 
 83367 $php = self::escapeWindowsPath($php);
 83368 $tmpFile = self::escapeWindowsPath($tmpFile);
 83369 
 83370 
 83371 if (PHP_VERSION_ID >= 80000) {
 83372 $format = '%s -l %s';
 83373 } else {
 83374 $format = '"%s -l %s"';
 83375 }
 83376 
 83377 $command = sprintf($format, $php, $tmpFile);
 83378 } else {
 83379 $command = "'".$php."' -l";
 83380 }
 83381 
 83382 $descriptorspec = array(
 83383 0 => array('pipe', 'r'),
 83384 1 => array('pipe', 'w'),
 83385 2 => array('pipe', 'w')
 83386 );
 83387 
 83388 
 83389 $baseLen = strlen(realpath($path)) + 7 + 1;
 83390 foreach (new \RecursiveIteratorIterator(new \Phar($path)) as $file) {
 83391 if ($file->isDir()) {
 83392 continue;
 83393 }
 83394 if (substr($file, -4) === '.php') {
 83395 $filename = (string) $file;
 83396 if (in_array(substr($filename, $baseLen), $excludedPaths, true)) {
 83397 continue;
 83398 }
 83399 if ($isWindows) {
 83400 file_put_contents($tmpFile, file_get_contents($filename));
 83401 }
 83402 
 83403 $process = proc_open($command, $descriptorspec, $pipes);
 83404 if (is_resource($process)) {
 83405 if (!$isWindows) {
 83406 fwrite($pipes[0], file_get_contents($filename));
 83407 }
 83408 fclose($pipes[0]);
 83409 
 83410 $stdout = stream_get_contents($pipes[1]);
 83411 fclose($pipes[1]);
 83412 $stderr = stream_get_contents($pipes[2]);
 83413 fclose($pipes[2]);
 83414 
 83415 $exitCode = proc_close($process);
 83416 
 83417 if ($exitCode !== 0) {
 83418 if ($isWindows) {
 83419 $stderr = str_replace($tmpFile, $filename, $stderr);
 83420 }
 83421 throw new \UnexpectedValueException('Failed linting '.$file.': '.$stderr);
 83422 }
 83423 } else {
 83424 throw new \RuntimeException('Could not start linter process');
 83425 }
 83426 }
 83427 }
 83428 
 83429 if ($isWindows) {
 83430 @unlink($tmpFile);
 83431 }
 83432 }
 83433 
 83434 
 83435 
 83436 
 83437 
 83438 
 83439 
 83440 private static function escapeWindowsPath($path)
 83441 {
 83442 
 83443 if (strpbrk($path, " ()") !== false) {
 83444 $path = '"'.$path.'"';
 83445 }
 83446 
 83447 return $path;
 83448 }
 83449 }
 83450 <?php
 83451 
 83452 
 83453 
 83454 
 83455 
 83456 
 83457 
 83458 
 83459 
 83460 
 83461 namespace Seld\PharUtils;
 83462 
 83463 class Timestamps
 83464 {
 83465 private $contents;
 83466 
 83467 
 83468 
 83469 
 83470 public function __construct($file)
 83471 {
 83472 $this->contents = file_get_contents($file);
 83473 }
 83474 
 83475 
 83476 
 83477 
 83478 
 83479 
 83480 
 83481 
 83482 public function updateTimestamps($timestamp = null)
 83483 {
 83484 if ($timestamp instanceof \DateTime || $timestamp instanceof \DateTimeInterface) {
 83485 $timestamp = $timestamp->getTimestamp();
 83486 } elseif (is_string($timestamp)) {
 83487 $timestamp = strtotime($timestamp);
 83488 } elseif (!is_int($timestamp)) {
 83489 $timestamp = strtotime('1984-12-24T00:00:00Z');
 83490 }
 83491 
 83492 
 83493 if (!preg_match('{__HALT_COMPILER\(\);(?: +\?>)?\r?\n}', $this->contents, $match, PREG_OFFSET_CAPTURE)) {
 83494 throw new \RuntimeException('Could not detect the stub\'s end in the phar');
 83495 }
 83496 
 83497 
 83498 $pos = $match[0][1] + strlen($match[0][0]);
 83499 $stubEnd = $pos + $this->readUint($pos, 4);
 83500 $pos += 4;
 83501 
 83502 $numFiles = $this->readUint($pos, 4);
 83503 $pos += 4;
 83504 
 83505 
 83506 $pos += 2;
 83507 
 83508 
 83509 $pos += 4;
 83510 
 83511 $aliasLength = $this->readUint($pos, 4);
 83512 $pos += 4 + $aliasLength;
 83513 
 83514 $metadataLength = $this->readUint($pos, 4);
 83515 $pos += 4 + $metadataLength;
 83516 
 83517 while ($pos < $stubEnd) {
 83518 $filenameLength = $this->readUint($pos, 4);
 83519 $pos += 4 + $filenameLength;
 83520 
 83521 
 83522 $pos += 4;
 83523 
 83524 
 83525 $this->contents = substr_replace($this->contents, pack('L', $timestamp), $pos, 4);
 83526 
 83527 
 83528 $pos += 4*4;
 83529 
 83530 $metadataLength = $this->readUint($pos, 4);
 83531 $pos += 4 + $metadataLength;
 83532 
 83533 $numFiles--;
 83534 }
 83535 
 83536 if ($numFiles !== 0) {
 83537 throw new \LogicException('All files were not processed, something must have gone wrong');
 83538 }
 83539 }
 83540 
 83541 
 83542 
 83543 
 83544 
 83545 
 83546 
 83547 
 83548 public function save($path, $signatureAlgo)
 83549 {
 83550 $pos = $this->determineSignatureBegin();
 83551 
 83552 $algos = array(
 83553 \Phar::MD5 => 'md5',
 83554 \Phar::SHA1 => 'sha1',
 83555 \Phar::SHA256 => 'sha256',
 83556 \Phar::SHA512 => 'sha512',
 83557 );
 83558 
 83559 if (!isset($algos[$signatureAlgo])) {
 83560 throw new \UnexpectedValueException('Invalid hash algorithm given: '.$signatureAlgo.' expected one of Phar::MD5, Phar::SHA1, Phar::SHA256 or Phar::SHA512');
 83561 }
 83562 $algo = $algos[$signatureAlgo];
 83563 
 83564 
 83565 
 83566 $signature = hash($algo, substr($this->contents, 0, $pos), true)
 83567 
 83568 . pack('L', $signatureAlgo)
 83569 
 83570 . 'GBMB';
 83571 
 83572 $this->contents = substr($this->contents, 0, $pos) . $signature;
 83573 
 83574 return file_put_contents($path, $this->contents);
 83575 }
 83576 
 83577 private function readUint($pos, $bytes)
 83578 {
 83579 $res = unpack('V', substr($this->contents, $pos, $bytes));
 83580 
 83581 return $res[1];
 83582 }
 83583 
 83584 
 83585 
 83586 
 83587 
 83588 
 83589 private function determineSignatureBegin()
 83590 {
 83591 
 83592 if (!preg_match('{__HALT_COMPILER\(\);(?: +\?>)?\r?\n}', $this->contents, $match, PREG_OFFSET_CAPTURE)) {
 83593 throw new \RuntimeException('Could not detect the stub\'s end in the phar');
 83594 }
 83595 
 83596 
 83597 $pos = $match[0][1] + strlen($match[0][0]);
 83598 $manifestEnd = $pos + 4 + $this->readUint($pos, 4);
 83599 
 83600 $pos += 4;
 83601 $numFiles = $this->readUint($pos, 4);
 83602 
 83603 $pos += 4;
 83604 
 83605 
 83606 $pos += 2;
 83607 
 83608 
 83609 $pos += 4;
 83610 
 83611 $aliasLength = $this->readUint($pos, 4);
 83612 $pos += 4 + $aliasLength;
 83613 
 83614 $metadataLength = $this->readUint($pos, 4);
 83615 $pos += 4 + $metadataLength;
 83616 
 83617 $compressedSizes = 0;
 83618 while (($numFiles > 0) && ($pos < $manifestEnd - 24)) {
 83619 $filenameLength = $this->readUint($pos, 4);
 83620 $pos += 4 + $filenameLength;
 83621 
 83622 
 83623 $pos += 2*4;
 83624 
 83625 $compressedSizes += $this->readUint($pos, 4);
 83626 
 83627 $pos += 3*4;
 83628 
 83629 $metadataLength = $this->readUint($pos, 4);
 83630 $pos += 4 + $metadataLength;
 83631 
 83632 $numFiles--;
 83633 }
 83634 
 83635 if ($numFiles !== 0) {
 83636 throw new \LogicException('All files were not processed, something must have gone wrong');
 83637 }
 83638 
 83639 return $manifestEnd + $compressedSizes;
 83640 }
 83641 }
 83642 <?php
 83643 
 83644 
 83645 
 83646 
 83647 
 83648 
 83649 
 83650 
 83651 
 83652 
 83653 namespace Symfony\Component\Console;
 83654 
 83655 use Symfony\Component\Console\Command\Command;
 83656 use Symfony\Component\Console\Command\HelpCommand;
 83657 use Symfony\Component\Console\Command\ListCommand;
 83658 use Symfony\Component\Console\Descriptor\TextDescriptor;
 83659 use Symfony\Component\Console\Descriptor\XmlDescriptor;
 83660 use Symfony\Component\Console\Event\ConsoleCommandEvent;
 83661 use Symfony\Component\Console\Event\ConsoleExceptionEvent;
 83662 use Symfony\Component\Console\Event\ConsoleTerminateEvent;
 83663 use Symfony\Component\Console\Exception\CommandNotFoundException;
 83664 use Symfony\Component\Console\Exception\ExceptionInterface;
 83665 use Symfony\Component\Console\Exception\LogicException;
 83666 use Symfony\Component\Console\Formatter\OutputFormatter;
 83667 use Symfony\Component\Console\Helper\DebugFormatterHelper;
 83668 use Symfony\Component\Console\Helper\DialogHelper;
 83669 use Symfony\Component\Console\Helper\FormatterHelper;
 83670 use Symfony\Component\Console\Helper\Helper;
 83671 use Symfony\Component\Console\Helper\HelperSet;
 83672 use Symfony\Component\Console\Helper\ProcessHelper;
 83673 use Symfony\Component\Console\Helper\ProgressHelper;
 83674 use Symfony\Component\Console\Helper\QuestionHelper;
 83675 use Symfony\Component\Console\Helper\TableHelper;
 83676 use Symfony\Component\Console\Input\ArgvInput;
 83677 use Symfony\Component\Console\Input\ArrayInput;
 83678 use Symfony\Component\Console\Input\InputArgument;
 83679 use Symfony\Component\Console\Input\InputAwareInterface;
 83680 use Symfony\Component\Console\Input\InputDefinition;
 83681 use Symfony\Component\Console\Input\InputInterface;
 83682 use Symfony\Component\Console\Input\InputOption;
 83683 use Symfony\Component\Console\Output\BufferedOutput;
 83684 use Symfony\Component\Console\Output\ConsoleOutput;
 83685 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 83686 use Symfony\Component\Console\Output\OutputInterface;
 83687 use Symfony\Component\Debug\Exception\FatalThrowableError;
 83688 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 83689 
 83690 
 83691 
 83692 
 83693 
 83694 
 83695 
 83696 
 83697 
 83698 
 83699 
 83700 
 83701 
 83702 
 83703 
 83704 
 83705 class Application
 83706 {
 83707 private $commands = array();
 83708 private $wantHelps = false;
 83709 private $runningCommand;
 83710 private $name;
 83711 private $version;
 83712 private $catchExceptions = true;
 83713 private $autoExit = true;
 83714 private $definition;
 83715 private $helperSet;
 83716 private $dispatcher;
 83717 private $terminalDimensions;
 83718 private $defaultCommand;
 83719 private $initialized;
 83720 
 83721 
 83722 
 83723 
 83724 
 83725 public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
 83726 {
 83727 $this->name = $name;
 83728 $this->version = $version;
 83729 $this->defaultCommand = 'list';
 83730 }
 83731 
 83732 public function setDispatcher(EventDispatcherInterface $dispatcher)
 83733 {
 83734 $this->dispatcher = $dispatcher;
 83735 }
 83736 
 83737 
 83738 
 83739 
 83740 
 83741 
 83742 
 83743 
 83744 public function run(InputInterface $input = null, OutputInterface $output = null)
 83745 {
 83746 if (null === $input) {
 83747 $input = new ArgvInput();
 83748 }
 83749 
 83750 if (null === $output) {
 83751 $output = new ConsoleOutput();
 83752 }
 83753 
 83754 $this->configureIO($input, $output);
 83755 
 83756 try {
 83757 $e = null;
 83758 $exitCode = $this->doRun($input, $output);
 83759 } catch (\Exception $e) {
 83760 }
 83761 
 83762 if (null !== $e) {
 83763 if (!$this->catchExceptions) {
 83764 throw $e;
 83765 }
 83766 
 83767 if ($output instanceof ConsoleOutputInterface) {
 83768 $this->renderException($e, $output->getErrorOutput());
 83769 } else {
 83770 $this->renderException($e, $output);
 83771 }
 83772 
 83773 $exitCode = $this->getExitCodeForThrowable($e);
 83774 }
 83775 
 83776 if ($this->autoExit) {
 83777 if ($exitCode > 255) {
 83778 $exitCode = 255;
 83779 }
 83780 
 83781 exit($exitCode);
 83782 }
 83783 
 83784 return $exitCode;
 83785 }
 83786 
 83787 
 83788 
 83789 
 83790 
 83791 
 83792 public function doRun(InputInterface $input, OutputInterface $output)
 83793 {
 83794 if (true === $input->hasParameterOption(array('--version', '-V'))) {
 83795 $output->writeln($this->getLongVersion());
 83796 
 83797 return 0;
 83798 }
 83799 
 83800 $name = $this->getCommandName($input);
 83801 if (true === $input->hasParameterOption(array('--help', '-h'))) {
 83802 if (!$name) {
 83803 $name = 'help';
 83804 $input = new ArrayInput(array('command' => 'help'));
 83805 } else {
 83806 $this->wantHelps = true;
 83807 }
 83808 }
 83809 
 83810 if (!$name) {
 83811 $name = $this->defaultCommand;
 83812 $definition = $this->getDefinition();
 83813 $definition->setArguments(array_merge(
 83814 $definition->getArguments(),
 83815 array(
 83816 'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name),
 83817 )
 83818 ));
 83819 }
 83820 
 83821 $this->runningCommand = null;
 83822 
 83823 $command = $this->find($name);
 83824 
 83825 $this->runningCommand = $command;
 83826 $exitCode = $this->doRunCommand($command, $input, $output);
 83827 $this->runningCommand = null;
 83828 
 83829 return $exitCode;
 83830 }
 83831 
 83832 public function setHelperSet(HelperSet $helperSet)
 83833 {
 83834 $this->helperSet = $helperSet;
 83835 }
 83836 
 83837 
 83838 
 83839 
 83840 
 83841 
 83842 public function getHelperSet()
 83843 {
 83844 if (!$this->helperSet) {
 83845 $this->helperSet = $this->getDefaultHelperSet();
 83846 }
 83847 
 83848 return $this->helperSet;
 83849 }
 83850 
 83851 public function setDefinition(InputDefinition $definition)
 83852 {
 83853 $this->definition = $definition;
 83854 }
 83855 
 83856 
 83857 
 83858 
 83859 
 83860 
 83861 public function getDefinition()
 83862 {
 83863 if (!$this->definition) {
 83864 $this->definition = $this->getDefaultInputDefinition();
 83865 }
 83866 
 83867 return $this->definition;
 83868 }
 83869 
 83870 
 83871 
 83872 
 83873 
 83874 
 83875 public function getHelp()
 83876 {
 83877 return $this->getLongVersion();
 83878 }
 83879 
 83880 
 83881 
 83882 
 83883 
 83884 
 83885 public function setCatchExceptions($boolean)
 83886 {
 83887 $this->catchExceptions = (bool) $boolean;
 83888 }
 83889 
 83890 
 83891 
 83892 
 83893 
 83894 
 83895 public function setAutoExit($boolean)
 83896 {
 83897 $this->autoExit = (bool) $boolean;
 83898 }
 83899 
 83900 
 83901 
 83902 
 83903 
 83904 
 83905 public function getName()
 83906 {
 83907 return $this->name;
 83908 }
 83909 
 83910 
 83911 
 83912 
 83913 
 83914 
 83915 public function setName($name)
 83916 {
 83917 $this->name = $name;
 83918 }
 83919 
 83920 
 83921 
 83922 
 83923 
 83924 
 83925 public function getVersion()
 83926 {
 83927 return $this->version;
 83928 }
 83929 
 83930 
 83931 
 83932 
 83933 
 83934 
 83935 public function setVersion($version)
 83936 {
 83937 $this->version = $version;
 83938 }
 83939 
 83940 
 83941 
 83942 
 83943 
 83944 
 83945 public function getLongVersion()
 83946 {
 83947 if ('UNKNOWN' !== $this->getName()) {
 83948 if ('UNKNOWN' !== $this->getVersion()) {
 83949 return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
 83950 }
 83951 
 83952 return sprintf('<info>%s</info>', $this->getName());
 83953 }
 83954 
 83955 return '<info>Console Tool</info>';
 83956 }
 83957 
 83958 
 83959 
 83960 
 83961 
 83962 
 83963 
 83964 
 83965 public function register($name)
 83966 {
 83967 return $this->add(new Command($name));
 83968 }
 83969 
 83970 
 83971 
 83972 
 83973 
 83974 
 83975 
 83976 
 83977 public function addCommands(array $commands)
 83978 {
 83979 foreach ($commands as $command) {
 83980 $this->add($command);
 83981 }
 83982 }
 83983 
 83984 
 83985 
 83986 
 83987 
 83988 
 83989 
 83990 
 83991 
 83992 public function add(Command $command)
 83993 {
 83994 $this->init();
 83995 
 83996 $command->setApplication($this);
 83997 
 83998 if (!$command->isEnabled()) {
 83999 $command->setApplication(null);
 84000 
 84001 return;
 84002 }
 84003 
 84004 if (null === $command->getDefinition()) {
 84005 throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', \get_class($command)));
 84006 }
 84007 
 84008 $this->commands[$command->getName()] = $command;
 84009 
 84010 foreach ($command->getAliases() as $alias) {
 84011 $this->commands[$alias] = $command;
 84012 }
 84013 
 84014 return $command;
 84015 }
 84016 
 84017 
 84018 
 84019 
 84020 
 84021 
 84022 
 84023 
 84024 
 84025 
 84026 public function get($name)
 84027 {
 84028 $this->init();
 84029 
 84030 if (!isset($this->commands[$name])) {
 84031 throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
 84032 }
 84033 
 84034 $command = $this->commands[$name];
 84035 
 84036 if ($this->wantHelps) {
 84037 $this->wantHelps = false;
 84038 
 84039 $helpCommand = $this->get('help');
 84040 $helpCommand->setCommand($command);
 84041 
 84042 return $helpCommand;
 84043 }
 84044 
 84045 return $command;
 84046 }
 84047 
 84048 
 84049 
 84050 
 84051 
 84052 
 84053 
 84054 
 84055 public function has($name)
 84056 {
 84057 $this->init();
 84058 
 84059 return isset($this->commands[$name]);
 84060 }
 84061 
 84062 
 84063 
 84064 
 84065 
 84066 
 84067 
 84068 
 84069 public function getNamespaces()
 84070 {
 84071 $namespaces = array();
 84072 foreach ($this->all() as $command) {
 84073 $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
 84074 
 84075 foreach ($command->getAliases() as $alias) {
 84076 $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
 84077 }
 84078 }
 84079 
 84080 return array_values(array_unique(array_filter($namespaces)));
 84081 }
 84082 
 84083 
 84084 
 84085 
 84086 
 84087 
 84088 
 84089 
 84090 
 84091 
 84092 public function findNamespace($namespace)
 84093 {
 84094 $allNamespaces = $this->getNamespaces();
 84095 $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace);
 84096 $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces);
 84097 
 84098 if (empty($namespaces)) {
 84099 $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
 84100 
 84101 if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
 84102 if (1 == \count($alternatives)) {
 84103 $message .= "\n\nDid you mean this?\n    ";
 84104 } else {
 84105 $message .= "\n\nDid you mean one of these?\n    ";
 84106 }
 84107 
 84108 $message .= implode("\n    ", $alternatives);
 84109 }
 84110 
 84111 throw new CommandNotFoundException($message, $alternatives);
 84112 }
 84113 
 84114 $exact = \in_array($namespace, $namespaces, true);
 84115 if (\count($namespaces) > 1 && !$exact) {
 84116 throw new CommandNotFoundException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
 84117 }
 84118 
 84119 return $exact ? $namespace : reset($namespaces);
 84120 }
 84121 
 84122 
 84123 
 84124 
 84125 
 84126 
 84127 
 84128 
 84129 
 84130 
 84131 
 84132 
 84133 
 84134 public function find($name)
 84135 {
 84136 $this->init();
 84137 $aliases = array();
 84138 $allCommands = array_keys($this->commands);
 84139 $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
 84140 $commands = preg_grep('{^'.$expr.'}', $allCommands);
 84141 
 84142 if (empty($commands) || \count(preg_grep('{^'.$expr.'$}', $commands)) < 1) {
 84143 if (false !== $pos = strrpos($name, ':')) {
 84144 
 84145 $this->findNamespace(substr($name, 0, $pos));
 84146 }
 84147 
 84148 $message = sprintf('Command "%s" is not defined.', $name);
 84149 
 84150 if ($alternatives = $this->findAlternatives($name, $allCommands)) {
 84151 if (1 == \count($alternatives)) {
 84152 $message .= "\n\nDid you mean this?\n    ";
 84153 } else {
 84154 $message .= "\n\nDid you mean one of these?\n    ";
 84155 }
 84156 $message .= implode("\n    ", $alternatives);
 84157 }
 84158 
 84159 throw new CommandNotFoundException($message, $alternatives);
 84160 }
 84161 
 84162 
 84163 if (\count($commands) > 1) {
 84164 $commandList = $this->commands;
 84165 $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands, &$aliases) {
 84166 $commandName = $commandList[$nameOrAlias]->getName();
 84167 $aliases[$nameOrAlias] = $commandName;
 84168 
 84169 return $commandName === $nameOrAlias || !\in_array($commandName, $commands);
 84170 });
 84171 }
 84172 
 84173 $exact = \in_array($name, $commands, true) || isset($aliases[$name]);
 84174 if (!$exact && \count($commands) > 1) {
 84175 $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
 84176 
 84177 throw new CommandNotFoundException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions), array_values($commands));
 84178 }
 84179 
 84180 return $this->get($exact ? $name : reset($commands));
 84181 }
 84182 
 84183 
 84184 
 84185 
 84186 
 84187 
 84188 
 84189 
 84190 
 84191 
 84192 public function all($namespace = null)
 84193 {
 84194 $this->init();
 84195 
 84196 if (null === $namespace) {
 84197 return $this->commands;
 84198 }
 84199 
 84200 $commands = array();
 84201 foreach ($this->commands as $name => $command) {
 84202 if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
 84203 $commands[$name] = $command;
 84204 }
 84205 }
 84206 
 84207 return $commands;
 84208 }
 84209 
 84210 
 84211 
 84212 
 84213 
 84214 
 84215 
 84216 
 84217 public static function getAbbreviations($names)
 84218 {
 84219 $abbrevs = array();
 84220 foreach ($names as $name) {
 84221 for ($len = \strlen($name); $len > 0; --$len) {
 84222 $abbrev = substr($name, 0, $len);
 84223 $abbrevs[$abbrev][] = $name;
 84224 }
 84225 }
 84226 
 84227 return $abbrevs;
 84228 }
 84229 
 84230 
 84231 
 84232 
 84233 
 84234 
 84235 
 84236 
 84237 
 84238 
 84239 
 84240 public function asText($namespace = null, $raw = false)
 84241 {
 84242 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
 84243 
 84244 $descriptor = new TextDescriptor();
 84245 $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, !$raw);
 84246 $descriptor->describe($output, $this, array('namespace' => $namespace, 'raw_output' => true));
 84247 
 84248 return $output->fetch();
 84249 }
 84250 
 84251 
 84252 
 84253 
 84254 
 84255 
 84256 
 84257 
 84258 
 84259 
 84260 
 84261 public function asXml($namespace = null, $asDom = false)
 84262 {
 84263 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
 84264 
 84265 $descriptor = new XmlDescriptor();
 84266 
 84267 if ($asDom) {
 84268 return $descriptor->getApplicationDocument($this, $namespace);
 84269 }
 84270 
 84271 $output = new BufferedOutput();
 84272 $descriptor->describe($output, $this, array('namespace' => $namespace));
 84273 
 84274 return $output->fetch();
 84275 }
 84276 
 84277 
 84278 
 84279 
 84280 public function renderException($e, $output)
 84281 {
 84282 $output->writeln('', OutputInterface::VERBOSITY_QUIET);
 84283 
 84284 do {
 84285 $title = sprintf('  [%s]  ', \get_class($e));
 84286 
 84287 $len = Helper::strlen($title);
 84288 
 84289 $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
 84290 
 84291 if (\defined('HHVM_VERSION') && $width > 1 << 31) {
 84292 $width = 1 << 31;
 84293 }
 84294 $lines = array();
 84295 foreach (preg_split('/\r?\n/', trim($e->getMessage())) as $line) {
 84296 foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
 84297 
 84298 $lineLength = Helper::strlen($line) + 4;
 84299 $lines[] = array($line, $lineLength);
 84300 
 84301 $len = max($lineLength, $len);
 84302 }
 84303 }
 84304 
 84305 $messages = array();
 84306 $messages[] = $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $len));
 84307 $messages[] = sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - Helper::strlen($title))));
 84308 foreach ($lines as $line) {
 84309 $messages[] = sprintf('<error>  %s  %s</error>', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1]));
 84310 }
 84311 $messages[] = $emptyLine;
 84312 $messages[] = '';
 84313 
 84314 $output->writeln($messages, OutputInterface::VERBOSITY_QUIET);
 84315 
 84316 if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
 84317 $output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);
 84318 
 84319 
 84320 $trace = $e->getTrace();
 84321 array_unshift($trace, array(
 84322 'function' => '',
 84323 'file' => null !== $e->getFile() ? $e->getFile() : 'n/a',
 84324 'line' => null !== $e->getLine() ? $e->getLine() : 'n/a',
 84325 'args' => array(),
 84326 ));
 84327 
 84328 for ($i = 0, $count = \count($trace); $i < $count; ++$i) {
 84329 $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
 84330 $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
 84331 $function = $trace[$i]['function'];
 84332 $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
 84333 $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
 84334 
 84335 $output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line), OutputInterface::VERBOSITY_QUIET);
 84336 }
 84337 
 84338 $output->writeln('', OutputInterface::VERBOSITY_QUIET);
 84339 }
 84340 } while ($e = $e->getPrevious());
 84341 
 84342 if (null !== $this->runningCommand) {
 84343 $output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
 84344 $output->writeln('', OutputInterface::VERBOSITY_QUIET);
 84345 }
 84346 }
 84347 
 84348 
 84349 
 84350 
 84351 
 84352 
 84353 protected function getTerminalWidth()
 84354 {
 84355 $dimensions = $this->getTerminalDimensions();
 84356 
 84357 return $dimensions[0];
 84358 }
 84359 
 84360 
 84361 
 84362 
 84363 
 84364 
 84365 protected function getTerminalHeight()
 84366 {
 84367 $dimensions = $this->getTerminalDimensions();
 84368 
 84369 return $dimensions[1];
 84370 }
 84371 
 84372 
 84373 
 84374 
 84375 
 84376 
 84377 public function getTerminalDimensions()
 84378 {
 84379 if ($this->terminalDimensions) {
 84380 return $this->terminalDimensions;
 84381 }
 84382 
 84383 if ('\\' === \DIRECTORY_SEPARATOR) {
 84384 
 84385 if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
 84386 return array((int) $matches[1], (int) $matches[2]);
 84387 }
 84388 
 84389 if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
 84390 return array((int) $matches[1], (int) $matches[2]);
 84391 }
 84392 }
 84393 
 84394 if ($sttyString = $this->getSttyColumns()) {
 84395 
 84396 if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
 84397 return array((int) $matches[2], (int) $matches[1]);
 84398 }
 84399 
 84400 if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
 84401 return array((int) $matches[2], (int) $matches[1]);
 84402 }
 84403 }
 84404 
 84405 return array(null, null);
 84406 }
 84407 
 84408 
 84409 
 84410 
 84411 
 84412 
 84413 
 84414 
 84415 
 84416 
 84417 
 84418 public function setTerminalDimensions($width, $height)
 84419 {
 84420 $this->terminalDimensions = array($width, $height);
 84421 
 84422 return $this;
 84423 }
 84424 
 84425 
 84426 
 84427 
 84428 protected function configureIO(InputInterface $input, OutputInterface $output)
 84429 {
 84430 if (true === $input->hasParameterOption(array('--ansi'))) {
 84431 $output->setDecorated(true);
 84432 } elseif (true === $input->hasParameterOption(array('--no-ansi'))) {
 84433 $output->setDecorated(false);
 84434 }
 84435 
 84436 if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
 84437 $input->setInteractive(false);
 84438 } elseif (\function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
 84439 $inputStream = $this->getHelperSet()->get('question')->getInputStream();
 84440 if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
 84441 $input->setInteractive(false);
 84442 }
 84443 }
 84444 
 84445 if (true === $input->hasParameterOption(array('--quiet', '-q'))) {
 84446 $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
 84447 $input->setInteractive(false);
 84448 } else {
 84449 if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || 3 === $input->getParameterOption('--verbose')) {
 84450 $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
 84451 } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || 2 === $input->getParameterOption('--verbose')) {
 84452 $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
 84453 } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {
 84454 $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
 84455 }
 84456 }
 84457 }
 84458 
 84459 
 84460 
 84461 
 84462 
 84463 
 84464 
 84465 
 84466 
 84467 protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
 84468 {
 84469 foreach ($command->getHelperSet() as $helper) {
 84470 if ($helper instanceof InputAwareInterface) {
 84471 $helper->setInput($input);
 84472 }
 84473 }
 84474 
 84475 if (null === $this->dispatcher) {
 84476 return $command->run($input, $output);
 84477 }
 84478 
 84479 
 84480 try {
 84481 $command->mergeApplicationDefinition();
 84482 $input->bind($command->getDefinition());
 84483 } catch (ExceptionInterface $e) {
 84484 
 84485 }
 84486 
 84487 $event = new ConsoleCommandEvent($command, $input, $output);
 84488 $e = null;
 84489 
 84490 try {
 84491 $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
 84492 
 84493 if ($event->commandShouldRun()) {
 84494 $exitCode = $command->run($input, $output);
 84495 } else {
 84496 $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
 84497 }
 84498 } catch (\Exception $e) {
 84499 } catch (\Throwable $e) {
 84500 }
 84501 if (null !== $e) {
 84502 $x = $e instanceof \Exception ? $e : new FatalThrowableError($e);
 84503 $event = new ConsoleExceptionEvent($command, $input, $output, $x, $x->getCode());
 84504 $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
 84505 
 84506 if ($x !== $event->getException()) {
 84507 $e = $event->getException();
 84508 }
 84509 
 84510 $exitCode = $this->getExitCodeForThrowable($e);
 84511 }
 84512 
 84513 $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
 84514 $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
 84515 
 84516 if (null !== $e) {
 84517 throw $e;
 84518 }
 84519 
 84520 return $event->getExitCode();
 84521 }
 84522 
 84523 
 84524 
 84525 
 84526 
 84527 
 84528 protected function getCommandName(InputInterface $input)
 84529 {
 84530 return $input->getFirstArgument();
 84531 }
 84532 
 84533 
 84534 
 84535 
 84536 
 84537 
 84538 protected function getDefaultInputDefinition()
 84539 {
 84540 return new InputDefinition(array(
 84541 new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
 84542 
 84543 new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
 84544 new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
 84545 new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
 84546 new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
 84547 new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
 84548 new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
 84549 new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
 84550 ));
 84551 }
 84552 
 84553 
 84554 
 84555 
 84556 
 84557 
 84558 protected function getDefaultCommands()
 84559 {
 84560 return array(new HelpCommand(), new ListCommand());
 84561 }
 84562 
 84563 
 84564 
 84565 
 84566 
 84567 
 84568 protected function getDefaultHelperSet()
 84569 {
 84570 return new HelperSet(array(
 84571 new FormatterHelper(),
 84572 new DialogHelper(false),
 84573 new ProgressHelper(false),
 84574 new TableHelper(false),
 84575 new DebugFormatterHelper(),
 84576 new ProcessHelper(),
 84577 new QuestionHelper(),
 84578 ));
 84579 }
 84580 
 84581 
 84582 
 84583 
 84584 
 84585 
 84586 private function getSttyColumns()
 84587 {
 84588 if (!\function_exists('proc_open')) {
 84589 return;
 84590 }
 84591 
 84592 $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
 84593 $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
 84594 if (\is_resource($process)) {
 84595 $info = stream_get_contents($pipes[1]);
 84596 fclose($pipes[1]);
 84597 fclose($pipes[2]);
 84598 proc_close($process);
 84599 
 84600 return $info;
 84601 }
 84602 }
 84603 
 84604 
 84605 
 84606 
 84607 
 84608 
 84609 private function getConsoleMode()
 84610 {
 84611 if (!\function_exists('proc_open')) {
 84612 return;
 84613 }
 84614 
 84615 $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
 84616 $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
 84617 if (\is_resource($process)) {
 84618 $info = stream_get_contents($pipes[1]);
 84619 fclose($pipes[1]);
 84620 fclose($pipes[2]);
 84621 proc_close($process);
 84622 
 84623 if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
 84624 return $matches[2].'x'.$matches[1];
 84625 }
 84626 }
 84627 }
 84628 
 84629 
 84630 
 84631 
 84632 
 84633 
 84634 
 84635 
 84636 private function getAbbreviationSuggestions($abbrevs)
 84637 {
 84638 return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], \count($abbrevs) > 2 ? sprintf(' and %d more', \count($abbrevs) - 2) : '');
 84639 }
 84640 
 84641 
 84642 
 84643 
 84644 
 84645 
 84646 
 84647 
 84648 
 84649 
 84650 
 84651 public function extractNamespace($name, $limit = null)
 84652 {
 84653 $parts = explode(':', $name);
 84654 array_pop($parts);
 84655 
 84656 return implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit));
 84657 }
 84658 
 84659 
 84660 
 84661 
 84662 
 84663 
 84664 
 84665 
 84666 
 84667 
 84668 private function findAlternatives($name, $collection)
 84669 {
 84670 $threshold = 1e3;
 84671 $alternatives = array();
 84672 
 84673 $collectionParts = array();
 84674 foreach ($collection as $item) {
 84675 $collectionParts[$item] = explode(':', $item);
 84676 }
 84677 
 84678 foreach (explode(':', $name) as $i => $subname) {
 84679 foreach ($collectionParts as $collectionName => $parts) {
 84680 $exists = isset($alternatives[$collectionName]);
 84681 if (!isset($parts[$i]) && $exists) {
 84682 $alternatives[$collectionName] += $threshold;
 84683 continue;
 84684 } elseif (!isset($parts[$i])) {
 84685 continue;
 84686 }
 84687 
 84688 $lev = levenshtein($subname, $parts[$i]);
 84689 if ($lev <= \strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
 84690 $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
 84691 } elseif ($exists) {
 84692 $alternatives[$collectionName] += $threshold;
 84693 }
 84694 }
 84695 }
 84696 
 84697 foreach ($collection as $item) {
 84698 $lev = levenshtein($name, $item);
 84699 if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) {
 84700 $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
 84701 }
 84702 }
 84703 
 84704 $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
 84705 asort($alternatives);
 84706 
 84707 return array_keys($alternatives);
 84708 }
 84709 
 84710 
 84711 
 84712 
 84713 
 84714 
 84715 public function setDefaultCommand($commandName)
 84716 {
 84717 $this->defaultCommand = $commandName;
 84718 }
 84719 
 84720 private function splitStringByWidth($string, $width)
 84721 {
 84722 
 84723 
 84724 
 84725 if (false === $encoding = mb_detect_encoding($string, null, true)) {
 84726 return str_split($string, $width);
 84727 }
 84728 
 84729 $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
 84730 $lines = array();
 84731 $line = '';
 84732 foreach (preg_split('//u', $utf8String) as $char) {
 84733 
 84734 if (mb_strwidth($line.$char, 'utf8') <= $width) {
 84735 $line .= $char;
 84736 continue;
 84737 }
 84738 
 84739 $lines[] = str_pad($line, $width);
 84740 $line = $char;
 84741 }
 84742 
 84743 $lines[] = \count($lines) ? str_pad($line, $width) : $line;
 84744 
 84745 mb_convert_variables($encoding, 'utf8', $lines);
 84746 
 84747 return $lines;
 84748 }
 84749 
 84750 
 84751 
 84752 
 84753 
 84754 
 84755 
 84756 
 84757 private function extractAllNamespaces($name)
 84758 {
 84759 
 84760 $parts = explode(':', $name, -1);
 84761 $namespaces = array();
 84762 
 84763 foreach ($parts as $part) {
 84764 if (\count($namespaces)) {
 84765 $namespaces[] = end($namespaces).':'.$part;
 84766 } else {
 84767 $namespaces[] = $part;
 84768 }
 84769 }
 84770 
 84771 return $namespaces;
 84772 }
 84773 
 84774 private function init()
 84775 {
 84776 if ($this->initialized) {
 84777 return;
 84778 }
 84779 $this->initialized = true;
 84780 
 84781 foreach ($this->getDefaultCommands() as $command) {
 84782 $this->add($command);
 84783 }
 84784 }
 84785 
 84786 
 84787 
 84788 
 84789 
 84790 
 84791 private function getExitCodeForThrowable($throwable)
 84792 {
 84793 $exitCode = $throwable->getCode();
 84794 if (is_numeric($exitCode)) {
 84795 $exitCode = (int) $exitCode;
 84796 if (0 === $exitCode) {
 84797 $exitCode = 1;
 84798 }
 84799 } else {
 84800 $exitCode = 1;
 84801 }
 84802 
 84803 return $exitCode;
 84804 }
 84805 }
 84806 <?php
 84807 
 84808 
 84809 
 84810 
 84811 
 84812 
 84813 
 84814 
 84815 
 84816 
 84817 namespace Symfony\Component\Console\Command;
 84818 
 84819 use Symfony\Component\Console\Application;
 84820 use Symfony\Component\Console\Descriptor\TextDescriptor;
 84821 use Symfony\Component\Console\Descriptor\XmlDescriptor;
 84822 use Symfony\Component\Console\Exception\ExceptionInterface;
 84823 use Symfony\Component\Console\Exception\InvalidArgumentException;
 84824 use Symfony\Component\Console\Exception\LogicException;
 84825 use Symfony\Component\Console\Helper\HelperSet;
 84826 use Symfony\Component\Console\Input\InputArgument;
 84827 use Symfony\Component\Console\Input\InputDefinition;
 84828 use Symfony\Component\Console\Input\InputInterface;
 84829 use Symfony\Component\Console\Input\InputOption;
 84830 use Symfony\Component\Console\Output\BufferedOutput;
 84831 use Symfony\Component\Console\Output\OutputInterface;
 84832 
 84833 
 84834 
 84835 
 84836 
 84837 
 84838 class Command
 84839 {
 84840 private $application;
 84841 private $name;
 84842 private $processTitle;
 84843 private $aliases = array();
 84844 private $definition;
 84845 private $help;
 84846 private $description;
 84847 private $ignoreValidationErrors = false;
 84848 private $applicationDefinitionMerged = false;
 84849 private $applicationDefinitionMergedWithArgs = false;
 84850 private $code;
 84851 private $synopsis = array();
 84852 private $usages = array();
 84853 private $helperSet;
 84854 
 84855 
 84856 
 84857 
 84858 
 84859 
 84860 public function __construct($name = null)
 84861 {
 84862 $this->definition = new InputDefinition();
 84863 
 84864 if (null !== $name) {
 84865 $this->setName($name);
 84866 }
 84867 
 84868 $this->configure();
 84869 
 84870 if (!$this->name) {
 84871 throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', \get_class($this)));
 84872 }
 84873 }
 84874 
 84875 
 84876 
 84877 
 84878 
 84879 
 84880 public function ignoreValidationErrors()
 84881 {
 84882 $this->ignoreValidationErrors = true;
 84883 }
 84884 
 84885 public function setApplication(Application $application = null)
 84886 {
 84887 $this->application = $application;
 84888 if ($application) {
 84889 $this->setHelperSet($application->getHelperSet());
 84890 } else {
 84891 $this->helperSet = null;
 84892 }
 84893 }
 84894 
 84895 public function setHelperSet(HelperSet $helperSet)
 84896 {
 84897 $this->helperSet = $helperSet;
 84898 }
 84899 
 84900 
 84901 
 84902 
 84903 
 84904 
 84905 public function getHelperSet()
 84906 {
 84907 return $this->helperSet;
 84908 }
 84909 
 84910 
 84911 
 84912 
 84913 
 84914 
 84915 public function getApplication()
 84916 {
 84917 return $this->application;
 84918 }
 84919 
 84920 
 84921 
 84922 
 84923 
 84924 
 84925 
 84926 
 84927 
 84928 public function isEnabled()
 84929 {
 84930 return true;
 84931 }
 84932 
 84933 
 84934 
 84935 
 84936 protected function configure()
 84937 {
 84938 }
 84939 
 84940 
 84941 
 84942 
 84943 
 84944 
 84945 
 84946 
 84947 
 84948 
 84949 
 84950 
 84951 
 84952 
 84953 
 84954 protected function execute(InputInterface $input, OutputInterface $output)
 84955 {
 84956 throw new LogicException('You must override the execute() method in the concrete command class.');
 84957 }
 84958 
 84959 
 84960 
 84961 
 84962 
 84963 
 84964 
 84965 
 84966 protected function interact(InputInterface $input, OutputInterface $output)
 84967 {
 84968 }
 84969 
 84970 
 84971 
 84972 
 84973 
 84974 
 84975 
 84976 
 84977 
 84978 
 84979 
 84980 protected function initialize(InputInterface $input, OutputInterface $output)
 84981 {
 84982 }
 84983 
 84984 
 84985 
 84986 
 84987 
 84988 
 84989 
 84990 
 84991 
 84992 
 84993 
 84994 
 84995 
 84996 
 84997 
 84998 public function run(InputInterface $input, OutputInterface $output)
 84999 {
 85000 
 85001 $this->getSynopsis(true);
 85002 $this->getSynopsis(false);
 85003 
 85004 
 85005 $this->mergeApplicationDefinition();
 85006 
 85007 
 85008 try {
 85009 $input->bind($this->definition);
 85010 } catch (ExceptionInterface $e) {
 85011 if (!$this->ignoreValidationErrors) {
 85012 throw $e;
 85013 }
 85014 }
 85015 
 85016 $this->initialize($input, $output);
 85017 
 85018 if (null !== $this->processTitle) {
 85019 if (\function_exists('cli_set_process_title')) {
 85020 if (!@cli_set_process_title($this->processTitle)) {
 85021 if ('Darwin' === PHP_OS) {
 85022 $output->writeln('<comment>Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.</comment>', OutputInterface::VERBOSITY_VERY_VERBOSE);
 85023 } else {
 85024 cli_set_process_title($this->processTitle);
 85025 }
 85026 }
 85027 } elseif (\function_exists('setproctitle')) {
 85028 setproctitle($this->processTitle);
 85029 } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
 85030 $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
 85031 }
 85032 }
 85033 
 85034 if ($input->isInteractive()) {
 85035 $this->interact($input, $output);
 85036 }
 85037 
 85038 
 85039 
 85040 
 85041 if ($input->hasArgument('command') && null === $input->getArgument('command')) {
 85042 $input->setArgument('command', $this->getName());
 85043 }
 85044 
 85045 $input->validate();
 85046 
 85047 if ($this->code) {
 85048 $statusCode = \call_user_func($this->code, $input, $output);
 85049 } else {
 85050 $statusCode = $this->execute($input, $output);
 85051 }
 85052 
 85053 return is_numeric($statusCode) ? (int) $statusCode : 0;
 85054 }
 85055 
 85056 
 85057 
 85058 
 85059 
 85060 
 85061 
 85062 
 85063 
 85064 
 85065 
 85066 
 85067 
 85068 
 85069 
 85070 public function setCode($code)
 85071 {
 85072 if (!\is_callable($code)) {
 85073 throw new InvalidArgumentException('Invalid callable provided to Command::setCode.');
 85074 }
 85075 
 85076 if (\PHP_VERSION_ID >= 50400 && $code instanceof \Closure) {
 85077 $r = new \ReflectionFunction($code);
 85078 if (null === $r->getClosureThis()) {
 85079 if (\PHP_VERSION_ID < 70000) {
 85080 
 85081 
 85082 
 85083 
 85084 $code = @\Closure::bind($code, $this);
 85085 } else {
 85086 $code = \Closure::bind($code, $this);
 85087 }
 85088 }
 85089 }
 85090 
 85091 $this->code = $code;
 85092 
 85093 return $this;
 85094 }
 85095 
 85096 
 85097 
 85098 
 85099 
 85100 
 85101 
 85102 
 85103 public function mergeApplicationDefinition($mergeArgs = true)
 85104 {
 85105 if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
 85106 return;
 85107 }
 85108 
 85109 $this->definition->addOptions($this->application->getDefinition()->getOptions());
 85110 
 85111 $this->applicationDefinitionMerged = true;
 85112 
 85113 if ($mergeArgs) {
 85114 $currentArguments = $this->definition->getArguments();
 85115 $this->definition->setArguments($this->application->getDefinition()->getArguments());
 85116 $this->definition->addArguments($currentArguments);
 85117 
 85118 $this->applicationDefinitionMergedWithArgs = true;
 85119 }
 85120 }
 85121 
 85122 
 85123 
 85124 
 85125 
 85126 
 85127 
 85128 
 85129 public function setDefinition($definition)
 85130 {
 85131 if ($definition instanceof InputDefinition) {
 85132 $this->definition = $definition;
 85133 } else {
 85134 $this->definition->setDefinition($definition);
 85135 }
 85136 
 85137 $this->applicationDefinitionMerged = false;
 85138 
 85139 return $this;
 85140 }
 85141 
 85142 
 85143 
 85144 
 85145 
 85146 
 85147 public function getDefinition()
 85148 {
 85149 return $this->definition;
 85150 }
 85151 
 85152 
 85153 
 85154 
 85155 
 85156 
 85157 
 85158 
 85159 
 85160 
 85161 
 85162 public function getNativeDefinition()
 85163 {
 85164 return $this->getDefinition();
 85165 }
 85166 
 85167 
 85168 
 85169 
 85170 
 85171 
 85172 
 85173 
 85174 
 85175 
 85176 
 85177 
 85178 
 85179 public function addArgument($name, $mode = null, $description = '', $default = null)
 85180 {
 85181 $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
 85182 
 85183 return $this;
 85184 }
 85185 
 85186 
 85187 
 85188 
 85189 
 85190 
 85191 
 85192 
 85193 
 85194 
 85195 
 85196 
 85197 
 85198 
 85199 public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
 85200 {
 85201 $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
 85202 
 85203 return $this;
 85204 }
 85205 
 85206 
 85207 
 85208 
 85209 
 85210 
 85211 
 85212 
 85213 
 85214 
 85215 
 85216 
 85217 
 85218 
 85219 
 85220 public function setName($name)
 85221 {
 85222 $this->validateName($name);
 85223 
 85224 $this->name = $name;
 85225 
 85226 return $this;
 85227 }
 85228 
 85229 
 85230 
 85231 
 85232 
 85233 
 85234 
 85235 
 85236 
 85237 
 85238 
 85239 
 85240 
 85241 public function setProcessTitle($title)
 85242 {
 85243 $this->processTitle = $title;
 85244 
 85245 return $this;
 85246 }
 85247 
 85248 
 85249 
 85250 
 85251 
 85252 
 85253 public function getName()
 85254 {
 85255 return $this->name;
 85256 }
 85257 
 85258 
 85259 
 85260 
 85261 
 85262 
 85263 
 85264 
 85265 public function setDescription($description)
 85266 {
 85267 $this->description = $description;
 85268 
 85269 return $this;
 85270 }
 85271 
 85272 
 85273 
 85274 
 85275 
 85276 
 85277 public function getDescription()
 85278 {
 85279 return $this->description;
 85280 }
 85281 
 85282 
 85283 
 85284 
 85285 
 85286 
 85287 
 85288 
 85289 public function setHelp($help)
 85290 {
 85291 $this->help = $help;
 85292 
 85293 return $this;
 85294 }
 85295 
 85296 
 85297 
 85298 
 85299 
 85300 
 85301 public function getHelp()
 85302 {
 85303 return $this->help;
 85304 }
 85305 
 85306 
 85307 
 85308 
 85309 
 85310 
 85311 
 85312 public function getProcessedHelp()
 85313 {
 85314 $name = $this->name;
 85315 
 85316 $placeholders = array(
 85317 '%command.name%',
 85318 '%command.full_name%',
 85319 );
 85320 $replacements = array(
 85321 $name,
 85322 $_SERVER['PHP_SELF'].' '.$name,
 85323 );
 85324 
 85325 return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
 85326 }
 85327 
 85328 
 85329 
 85330 
 85331 
 85332 
 85333 
 85334 
 85335 
 85336 
 85337 public function setAliases($aliases)
 85338 {
 85339 if (!\is_array($aliases) && !$aliases instanceof \Traversable) {
 85340 throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
 85341 }
 85342 
 85343 foreach ($aliases as $alias) {
 85344 $this->validateName($alias);
 85345 }
 85346 
 85347 $this->aliases = $aliases;
 85348 
 85349 return $this;
 85350 }
 85351 
 85352 
 85353 
 85354 
 85355 
 85356 
 85357 public function getAliases()
 85358 {
 85359 return $this->aliases;
 85360 }
 85361 
 85362 
 85363 
 85364 
 85365 
 85366 
 85367 
 85368 
 85369 public function getSynopsis($short = false)
 85370 {
 85371 $key = $short ? 'short' : 'long';
 85372 
 85373 if (!isset($this->synopsis[$key])) {
 85374 $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
 85375 }
 85376 
 85377 return $this->synopsis[$key];
 85378 }
 85379 
 85380 
 85381 
 85382 
 85383 
 85384 
 85385 
 85386 
 85387 public function addUsage($usage)
 85388 {
 85389 if (0 !== strpos($usage, $this->name)) {
 85390 $usage = sprintf('%s %s', $this->name, $usage);
 85391 }
 85392 
 85393 $this->usages[] = $usage;
 85394 
 85395 return $this;
 85396 }
 85397 
 85398 
 85399 
 85400 
 85401 
 85402 
 85403 public function getUsages()
 85404 {
 85405 return $this->usages;
 85406 }
 85407 
 85408 
 85409 
 85410 
 85411 
 85412 
 85413 
 85414 
 85415 
 85416 
 85417 
 85418 public function getHelper($name)
 85419 {
 85420 if (null === $this->helperSet) {
 85421 throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
 85422 }
 85423 
 85424 return $this->helperSet->get($name);
 85425 }
 85426 
 85427 
 85428 
 85429 
 85430 
 85431 
 85432 
 85433 
 85434 public function asText()
 85435 {
 85436 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
 85437 
 85438 $descriptor = new TextDescriptor();
 85439 $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
 85440 $descriptor->describe($output, $this, array('raw_output' => true));
 85441 
 85442 return $output->fetch();
 85443 }
 85444 
 85445 
 85446 
 85447 
 85448 
 85449 
 85450 
 85451 
 85452 
 85453 
 85454 public function asXml($asDom = false)
 85455 {
 85456 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
 85457 
 85458 $descriptor = new XmlDescriptor();
 85459 
 85460 if ($asDom) {
 85461 return $descriptor->getCommandDocument($this);
 85462 }
 85463 
 85464 $output = new BufferedOutput();
 85465 $descriptor->describe($output, $this);
 85466 
 85467 return $output->fetch();
 85468 }
 85469 
 85470 
 85471 
 85472 
 85473 
 85474 
 85475 
 85476 
 85477 
 85478 
 85479 private function validateName($name)
 85480 {
 85481 if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
 85482 throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
 85483 }
 85484 }
 85485 }
 85486 <?php
 85487 
 85488 
 85489 
 85490 
 85491 
 85492 
 85493 
 85494 
 85495 
 85496 
 85497 namespace Symfony\Component\Console\Command;
 85498 
 85499 use Symfony\Component\Console\Helper\DescriptorHelper;
 85500 use Symfony\Component\Console\Input\InputArgument;
 85501 use Symfony\Component\Console\Input\InputInterface;
 85502 use Symfony\Component\Console\Input\InputOption;
 85503 use Symfony\Component\Console\Output\OutputInterface;
 85504 
 85505 
 85506 
 85507 
 85508 
 85509 
 85510 class HelpCommand extends Command
 85511 {
 85512 private $command;
 85513 
 85514 
 85515 
 85516 
 85517 protected function configure()
 85518 {
 85519 $this->ignoreValidationErrors();
 85520 
 85521 $this
 85522 ->setName('help')
 85523 ->setDefinition(array(
 85524 new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
 85525 new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
 85526 new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
 85527 new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
 85528 ))
 85529 ->setDescription('Displays help for a command')
 85530 ->setHelp(<<<'EOF'
 85531 The <info>%command.name%</info> command displays help for a given command:
 85532 
 85533   <info>php %command.full_name% list</info>
 85534 
 85535 You can also output the help in other formats by using the <comment>--format</comment> option:
 85536 
 85537   <info>php %command.full_name% --format=xml list</info>
 85538 
 85539 To display the list of available commands, please use the <info>list</info> command.
 85540 EOF
 85541 )
 85542 ;
 85543 }
 85544 
 85545 public function setCommand(Command $command)
 85546 {
 85547 $this->command = $command;
 85548 }
 85549 
 85550 
 85551 
 85552 
 85553 protected function execute(InputInterface $input, OutputInterface $output)
 85554 {
 85555 if (null === $this->command) {
 85556 $this->command = $this->getApplication()->find($input->getArgument('command_name'));
 85557 }
 85558 
 85559 if ($input->getOption('xml')) {
 85560 @trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED);
 85561 
 85562 $input->setOption('format', 'xml');
 85563 }
 85564 
 85565 $helper = new DescriptorHelper();
 85566 $helper->describe($output, $this->command, array(
 85567 'format' => $input->getOption('format'),
 85568 'raw_text' => $input->getOption('raw'),
 85569 ));
 85570 
 85571 $this->command = null;
 85572 }
 85573 }
 85574 <?php
 85575 
 85576 
 85577 
 85578 
 85579 
 85580 
 85581 
 85582 
 85583 
 85584 
 85585 namespace Symfony\Component\Console\Command;
 85586 
 85587 use Symfony\Component\Console\Helper\DescriptorHelper;
 85588 use Symfony\Component\Console\Input\InputArgument;
 85589 use Symfony\Component\Console\Input\InputDefinition;
 85590 use Symfony\Component\Console\Input\InputInterface;
 85591 use Symfony\Component\Console\Input\InputOption;
 85592 use Symfony\Component\Console\Output\OutputInterface;
 85593 
 85594 
 85595 
 85596 
 85597 
 85598 
 85599 class ListCommand extends Command
 85600 {
 85601 
 85602 
 85603 
 85604 protected function configure()
 85605 {
 85606 $this
 85607 ->setName('list')
 85608 ->setDefinition($this->createDefinition())
 85609 ->setDescription('Lists commands')
 85610 ->setHelp(<<<'EOF'
 85611 The <info>%command.name%</info> command lists all commands:
 85612 
 85613   <info>php %command.full_name%</info>
 85614 
 85615 You can also display the commands for a specific namespace:
 85616 
 85617   <info>php %command.full_name% test</info>
 85618 
 85619 You can also output the information in other formats by using the <comment>--format</comment> option:
 85620 
 85621   <info>php %command.full_name% --format=xml</info>
 85622 
 85623 It's also possible to get raw list of commands (useful for embedding command runner):
 85624 
 85625   <info>php %command.full_name% --raw</info>
 85626 EOF
 85627 )
 85628 ;
 85629 }
 85630 
 85631 
 85632 
 85633 
 85634 public function getNativeDefinition()
 85635 {
 85636 return $this->createDefinition();
 85637 }
 85638 
 85639 
 85640 
 85641 
 85642 protected function execute(InputInterface $input, OutputInterface $output)
 85643 {
 85644 if ($input->getOption('xml')) {
 85645 @trigger_error('The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead.', E_USER_DEPRECATED);
 85646 
 85647 $input->setOption('format', 'xml');
 85648 }
 85649 
 85650 $helper = new DescriptorHelper();
 85651 $helper->describe($output, $this->getApplication(), array(
 85652 'format' => $input->getOption('format'),
 85653 'raw_text' => $input->getOption('raw'),
 85654 'namespace' => $input->getArgument('namespace'),
 85655 ));
 85656 }
 85657 
 85658 
 85659 
 85660 
 85661 private function createDefinition()
 85662 {
 85663 return new InputDefinition(array(
 85664 new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
 85665 new InputOption('xml', null, InputOption::VALUE_NONE, 'To output list as XML'),
 85666 new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
 85667 new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
 85668 ));
 85669 }
 85670 }
 85671 <?php
 85672 
 85673 
 85674 
 85675 
 85676 
 85677 
 85678 
 85679 
 85680 
 85681 
 85682 namespace Symfony\Component\Console;
 85683 
 85684 
 85685 
 85686 
 85687 
 85688 
 85689 final class ConsoleEvents
 85690 {
 85691 
 85692 
 85693 
 85694 
 85695 
 85696 
 85697 
 85698 
 85699 
 85700 
 85701 const COMMAND = 'console.command';
 85702 
 85703 
 85704 
 85705 
 85706 
 85707 
 85708 
 85709 
 85710 
 85711 
 85712 const TERMINATE = 'console.terminate';
 85713 
 85714 
 85715 
 85716 
 85717 
 85718 
 85719 
 85720 
 85721 
 85722 
 85723 
 85724 const EXCEPTION = 'console.exception';
 85725 }
 85726 <?php
 85727 
 85728 
 85729 
 85730 
 85731 
 85732 
 85733 
 85734 
 85735 
 85736 
 85737 namespace Symfony\Component\Console\Descriptor;
 85738 
 85739 use Symfony\Component\Console\Application;
 85740 use Symfony\Component\Console\Command\Command;
 85741 use Symfony\Component\Console\Exception\CommandNotFoundException;
 85742 
 85743 
 85744 
 85745 
 85746 
 85747 
 85748 class ApplicationDescription
 85749 {
 85750 const GLOBAL_NAMESPACE = '_global';
 85751 
 85752 private $application;
 85753 private $namespace;
 85754 
 85755 
 85756 
 85757 
 85758 private $namespaces;
 85759 
 85760 
 85761 
 85762 
 85763 private $commands;
 85764 
 85765 
 85766 
 85767 
 85768 private $aliases;
 85769 
 85770 public function __construct(Application $application, $namespace = null)
 85771 {
 85772 $this->application = $application;
 85773 $this->namespace = $namespace;
 85774 }
 85775 
 85776 
 85777 
 85778 
 85779 public function getNamespaces()
 85780 {
 85781 if (null === $this->namespaces) {
 85782 $this->inspectApplication();
 85783 }
 85784 
 85785 return $this->namespaces;
 85786 }
 85787 
 85788 
 85789 
 85790 
 85791 public function getCommands()
 85792 {
 85793 if (null === $this->commands) {
 85794 $this->inspectApplication();
 85795 }
 85796 
 85797 return $this->commands;
 85798 }
 85799 
 85800 
 85801 
 85802 
 85803 
 85804 
 85805 
 85806 
 85807 public function getCommand($name)
 85808 {
 85809 if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
 85810 throw new CommandNotFoundException(sprintf('Command %s does not exist.', $name));
 85811 }
 85812 
 85813 return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
 85814 }
 85815 
 85816 private function inspectApplication()
 85817 {
 85818 $this->commands = array();
 85819 $this->namespaces = array();
 85820 
 85821 $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
 85822 foreach ($this->sortCommands($all) as $namespace => $commands) {
 85823 $names = array();
 85824 
 85825 
 85826 foreach ($commands as $name => $command) {
 85827 if (!$command->getName()) {
 85828 continue;
 85829 }
 85830 
 85831 if ($command->getName() === $name) {
 85832 $this->commands[$name] = $command;
 85833 } else {
 85834 $this->aliases[$name] = $command;
 85835 }
 85836 
 85837 $names[] = $name;
 85838 }
 85839 
 85840 $this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
 85841 }
 85842 }
 85843 
 85844 
 85845 
 85846 
 85847 private function sortCommands(array $commands)
 85848 {
 85849 $namespacedCommands = array();
 85850 $globalCommands = array();
 85851 foreach ($commands as $name => $command) {
 85852 $key = $this->application->extractNamespace($name, 1);
 85853 if (!$key) {
 85854 $globalCommands['_global'][$name] = $command;
 85855 } else {
 85856 $namespacedCommands[$key][$name] = $command;
 85857 }
 85858 }
 85859 ksort($namespacedCommands);
 85860 $namespacedCommands = array_merge($globalCommands, $namespacedCommands);
 85861 
 85862 foreach ($namespacedCommands as &$commandsSet) {
 85863 ksort($commandsSet);
 85864 }
 85865 
 85866 unset($commandsSet);
 85867 
 85868 return $namespacedCommands;
 85869 }
 85870 }
 85871 <?php
 85872 
 85873 
 85874 
 85875 
 85876 
 85877 
 85878 
 85879 
 85880 
 85881 
 85882 namespace Symfony\Component\Console\Descriptor;
 85883 
 85884 use Symfony\Component\Console\Application;
 85885 use Symfony\Component\Console\Command\Command;
 85886 use Symfony\Component\Console\Exception\InvalidArgumentException;
 85887 use Symfony\Component\Console\Input\InputArgument;
 85888 use Symfony\Component\Console\Input\InputDefinition;
 85889 use Symfony\Component\Console\Input\InputOption;
 85890 use Symfony\Component\Console\Output\OutputInterface;
 85891 
 85892 
 85893 
 85894 
 85895 
 85896 
 85897 abstract class Descriptor implements DescriptorInterface
 85898 {
 85899 
 85900 
 85901 
 85902 private $output;
 85903 
 85904 
 85905 
 85906 
 85907 public function describe(OutputInterface $output, $object, array $options = array())
 85908 {
 85909 $this->output = $output;
 85910 
 85911 switch (true) {
 85912 case $object instanceof InputArgument:
 85913 $this->describeInputArgument($object, $options);
 85914 break;
 85915 case $object instanceof InputOption:
 85916 $this->describeInputOption($object, $options);
 85917 break;
 85918 case $object instanceof InputDefinition:
 85919 $this->describeInputDefinition($object, $options);
 85920 break;
 85921 case $object instanceof Command:
 85922 $this->describeCommand($object, $options);
 85923 break;
 85924 case $object instanceof Application:
 85925 $this->describeApplication($object, $options);
 85926 break;
 85927 default:
 85928 throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', \get_class($object)));
 85929 }
 85930 }
 85931 
 85932 
 85933 
 85934 
 85935 
 85936 
 85937 
 85938 protected function write($content, $decorated = false)
 85939 {
 85940 $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
 85941 }
 85942 
 85943 
 85944 
 85945 
 85946 
 85947 
 85948 abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
 85949 
 85950 
 85951 
 85952 
 85953 
 85954 
 85955 abstract protected function describeInputOption(InputOption $option, array $options = array());
 85956 
 85957 
 85958 
 85959 
 85960 
 85961 
 85962 abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
 85963 
 85964 
 85965 
 85966 
 85967 
 85968 
 85969 abstract protected function describeCommand(Command $command, array $options = array());
 85970 
 85971 
 85972 
 85973 
 85974 
 85975 
 85976 abstract protected function describeApplication(Application $application, array $options = array());
 85977 }
 85978 <?php
 85979 
 85980 
 85981 
 85982 
 85983 
 85984 
 85985 
 85986 
 85987 
 85988 
 85989 namespace Symfony\Component\Console\Descriptor;
 85990 
 85991 use Symfony\Component\Console\Output\OutputInterface;
 85992 
 85993 
 85994 
 85995 
 85996 
 85997 
 85998 interface DescriptorInterface
 85999 {
 86000 
 86001 
 86002 
 86003 
 86004 
 86005 
 86006 
 86007 public function describe(OutputInterface $output, $object, array $options = array());
 86008 }
 86009 <?php
 86010 
 86011 
 86012 
 86013 
 86014 
 86015 
 86016 
 86017 
 86018 
 86019 
 86020 namespace Symfony\Component\Console\Descriptor;
 86021 
 86022 use Symfony\Component\Console\Application;
 86023 use Symfony\Component\Console\Command\Command;
 86024 use Symfony\Component\Console\Input\InputArgument;
 86025 use Symfony\Component\Console\Input\InputDefinition;
 86026 use Symfony\Component\Console\Input\InputOption;
 86027 
 86028 
 86029 
 86030 
 86031 
 86032 
 86033 
 86034 
 86035 class JsonDescriptor extends Descriptor
 86036 {
 86037 
 86038 
 86039 
 86040 protected function describeInputArgument(InputArgument $argument, array $options = array())
 86041 {
 86042 $this->writeData($this->getInputArgumentData($argument), $options);
 86043 }
 86044 
 86045 
 86046 
 86047 
 86048 protected function describeInputOption(InputOption $option, array $options = array())
 86049 {
 86050 $this->writeData($this->getInputOptionData($option), $options);
 86051 }
 86052 
 86053 
 86054 
 86055 
 86056 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
 86057 {
 86058 $this->writeData($this->getInputDefinitionData($definition), $options);
 86059 }
 86060 
 86061 
 86062 
 86063 
 86064 protected function describeCommand(Command $command, array $options = array())
 86065 {
 86066 $this->writeData($this->getCommandData($command), $options);
 86067 }
 86068 
 86069 
 86070 
 86071 
 86072 protected function describeApplication(Application $application, array $options = array())
 86073 {
 86074 $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
 86075 $description = new ApplicationDescription($application, $describedNamespace);
 86076 $commands = array();
 86077 
 86078 foreach ($description->getCommands() as $command) {
 86079 $commands[] = $this->getCommandData($command);
 86080 }
 86081 
 86082 $data = $describedNamespace
 86083 ? array('commands' => $commands, 'namespace' => $describedNamespace)
 86084 : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));
 86085 
 86086 $this->writeData($data, $options);
 86087 }
 86088 
 86089 
 86090 
 86091 
 86092 
 86093 
 86094 private function writeData(array $data, array $options)
 86095 {
 86096 $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0));
 86097 }
 86098 
 86099 
 86100 
 86101 
 86102 private function getInputArgumentData(InputArgument $argument)
 86103 {
 86104 return array(
 86105 'name' => $argument->getName(),
 86106 'is_required' => $argument->isRequired(),
 86107 'is_array' => $argument->isArray(),
 86108 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
 86109 'default' => INF === $argument->getDefault() ? 'INF' : $argument->getDefault(),
 86110 );
 86111 }
 86112 
 86113 
 86114 
 86115 
 86116 private function getInputOptionData(InputOption $option)
 86117 {
 86118 return array(
 86119 'name' => '--'.$option->getName(),
 86120 'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '',
 86121 'accept_value' => $option->acceptValue(),
 86122 'is_value_required' => $option->isValueRequired(),
 86123 'is_multiple' => $option->isArray(),
 86124 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
 86125 'default' => INF === $option->getDefault() ? 'INF' : $option->getDefault(),
 86126 );
 86127 }
 86128 
 86129 
 86130 
 86131 
 86132 private function getInputDefinitionData(InputDefinition $definition)
 86133 {
 86134 $inputArguments = array();
 86135 foreach ($definition->getArguments() as $name => $argument) {
 86136 $inputArguments[$name] = $this->getInputArgumentData($argument);
 86137 }
 86138 
 86139 $inputOptions = array();
 86140 foreach ($definition->getOptions() as $name => $option) {
 86141 $inputOptions[$name] = $this->getInputOptionData($option);
 86142 }
 86143 
 86144 return array('arguments' => $inputArguments, 'options' => $inputOptions);
 86145 }
 86146 
 86147 
 86148 
 86149 
 86150 private function getCommandData(Command $command)
 86151 {
 86152 $command->getSynopsis();
 86153 $command->mergeApplicationDefinition(false);
 86154 
 86155 return array(
 86156 'name' => $command->getName(),
 86157 'usage' => array_merge(array($command->getSynopsis()), $command->getUsages(), $command->getAliases()),
 86158 'description' => $command->getDescription(),
 86159 'help' => $command->getProcessedHelp(),
 86160 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
 86161 );
 86162 }
 86163 }
 86164 <?php
 86165 
 86166 
 86167 
 86168 
 86169 
 86170 
 86171 
 86172 
 86173 
 86174 
 86175 namespace Symfony\Component\Console\Descriptor;
 86176 
 86177 use Symfony\Component\Console\Application;
 86178 use Symfony\Component\Console\Command\Command;
 86179 use Symfony\Component\Console\Helper\Helper;
 86180 use Symfony\Component\Console\Input\InputArgument;
 86181 use Symfony\Component\Console\Input\InputDefinition;
 86182 use Symfony\Component\Console\Input\InputOption;
 86183 
 86184 
 86185 
 86186 
 86187 
 86188 
 86189 
 86190 
 86191 class MarkdownDescriptor extends Descriptor
 86192 {
 86193 
 86194 
 86195 
 86196 protected function describeInputArgument(InputArgument $argument, array $options = array())
 86197 {
 86198 $this->write(
 86199 '**'.$argument->getName().':**'."\n\n"
 86200 .'* Name: '.($argument->getName() ?: '<none>')."\n"
 86201 .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
 86202 .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
 86203 .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n  ", $argument->getDescription() ?: '<none>')."\n"
 86204 .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
 86205 );
 86206 }
 86207 
 86208 
 86209 
 86210 
 86211 protected function describeInputOption(InputOption $option, array $options = array())
 86212 {
 86213 $this->write(
 86214 '**'.$option->getName().':**'."\n\n"
 86215 .'* Name: `--'.$option->getName().'`'."\n"
 86216 .'* Shortcut: '.($option->getShortcut() ? '`-'.str_replace('|', '|-', $option->getShortcut()).'`' : '<none>')."\n"
 86217 .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
 86218 .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
 86219 .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
 86220 .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n  ", $option->getDescription() ?: '<none>')."\n"
 86221 .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
 86222 );
 86223 }
 86224 
 86225 
 86226 
 86227 
 86228 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
 86229 {
 86230 if ($showArguments = \count($definition->getArguments()) > 0) {
 86231 $this->write('### Arguments:');
 86232 foreach ($definition->getArguments() as $argument) {
 86233 $this->write("\n\n");
 86234 $this->write($this->describeInputArgument($argument));
 86235 }
 86236 }
 86237 
 86238 if (\count($definition->getOptions()) > 0) {
 86239 if ($showArguments) {
 86240 $this->write("\n\n");
 86241 }
 86242 
 86243 $this->write('### Options:');
 86244 foreach ($definition->getOptions() as $option) {
 86245 $this->write("\n\n");
 86246 $this->write($this->describeInputOption($option));
 86247 }
 86248 }
 86249 }
 86250 
 86251 
 86252 
 86253 
 86254 protected function describeCommand(Command $command, array $options = array())
 86255 {
 86256 $command->getSynopsis();
 86257 $command->mergeApplicationDefinition(false);
 86258 
 86259 $this->write(
 86260 $command->getName()."\n"
 86261 .str_repeat('-', Helper::strlen($command->getName()))."\n\n"
 86262 .'* Description: '.($command->getDescription() ?: '<none>')."\n"
 86263 .'* Usage:'."\n\n"
 86264 .array_reduce(array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
 86265 return $carry.'  * `'.$usage.'`'."\n";
 86266 })
 86267 );
 86268 
 86269 if ($help = $command->getProcessedHelp()) {
 86270 $this->write("\n");
 86271 $this->write($help);
 86272 }
 86273 
 86274 if ($command->getNativeDefinition()) {
 86275 $this->write("\n\n");
 86276 $this->describeInputDefinition($command->getNativeDefinition());
 86277 }
 86278 }
 86279 
 86280 
 86281 
 86282 
 86283 protected function describeApplication(Application $application, array $options = array())
 86284 {
 86285 $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
 86286 $description = new ApplicationDescription($application, $describedNamespace);
 86287 
 86288 $this->write($application->getName()."\n".str_repeat('=', Helper::strlen($application->getName())));
 86289 
 86290 foreach ($description->getNamespaces() as $namespace) {
 86291 if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
 86292 $this->write("\n\n");
 86293 $this->write('**'.$namespace['id'].':**');
 86294 }
 86295 
 86296 $this->write("\n\n");
 86297 $this->write(implode("\n", array_map(function ($commandName) {
 86298 return '* '.$commandName;
 86299 }, $namespace['commands'])));
 86300 }
 86301 
 86302 foreach ($description->getCommands() as $command) {
 86303 $this->write("\n\n");
 86304 $this->write($this->describeCommand($command));
 86305 }
 86306 }
 86307 }
 86308 <?php
 86309 
 86310 
 86311 
 86312 
 86313 
 86314 
 86315 
 86316 
 86317 
 86318 
 86319 namespace Symfony\Component\Console\Descriptor;
 86320 
 86321 use Symfony\Component\Console\Application;
 86322 use Symfony\Component\Console\Command\Command;
 86323 use Symfony\Component\Console\Formatter\OutputFormatter;
 86324 use Symfony\Component\Console\Helper\Helper;
 86325 use Symfony\Component\Console\Input\InputArgument;
 86326 use Symfony\Component\Console\Input\InputDefinition;
 86327 use Symfony\Component\Console\Input\InputOption;
 86328 
 86329 
 86330 
 86331 
 86332 
 86333 
 86334 
 86335 
 86336 class TextDescriptor extends Descriptor
 86337 {
 86338 
 86339 
 86340 
 86341 protected function describeInputArgument(InputArgument $argument, array $options = array())
 86342 {
 86343 if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
 86344 $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
 86345 } else {
 86346 $default = '';
 86347 }
 86348 
 86349 $totalWidth = isset($options['total_width']) ? $options['total_width'] : Helper::strlen($argument->getName());
 86350 $spacingWidth = $totalWidth - \strlen($argument->getName());
 86351 
 86352 $this->writeText(sprintf('  <info>%s</info>  %s%s%s',
 86353 $argument->getName(),
 86354 str_repeat(' ', $spacingWidth),
 86355 
 86356 preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
 86357 $default
 86358 ), $options);
 86359 }
 86360 
 86361 
 86362 
 86363 
 86364 protected function describeInputOption(InputOption $option, array $options = array())
 86365 {
 86366 if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
 86367 $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
 86368 } else {
 86369 $default = '';
 86370 }
 86371 
 86372 $value = '';
 86373 if ($option->acceptValue()) {
 86374 $value = '='.strtoupper($option->getName());
 86375 
 86376 if ($option->isValueOptional()) {
 86377 $value = '['.$value.']';
 86378 }
 86379 }
 86380 
 86381 $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions(array($option));
 86382 $synopsis = sprintf('%s%s',
 86383 $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ',
 86384 sprintf('--%s%s', $option->getName(), $value)
 86385 );
 86386 
 86387 $spacingWidth = $totalWidth - Helper::strlen($synopsis);
 86388 
 86389 $this->writeText(sprintf('  <info>%s</info>  %s%s%s%s',
 86390 $synopsis,
 86391 str_repeat(' ', $spacingWidth),
 86392 
 86393 preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()),
 86394 $default,
 86395 $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
 86396 ), $options);
 86397 }
 86398 
 86399 
 86400 
 86401 
 86402 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
 86403 {
 86404 $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
 86405 foreach ($definition->getArguments() as $argument) {
 86406 $totalWidth = max($totalWidth, Helper::strlen($argument->getName()));
 86407 }
 86408 
 86409 if ($definition->getArguments()) {
 86410 $this->writeText('<comment>Arguments:</comment>', $options);
 86411 $this->writeText("\n");
 86412 foreach ($definition->getArguments() as $argument) {
 86413 $this->describeInputArgument($argument, array_merge($options, array('total_width' => $totalWidth)));
 86414 $this->writeText("\n");
 86415 }
 86416 }
 86417 
 86418 if ($definition->getArguments() && $definition->getOptions()) {
 86419 $this->writeText("\n");
 86420 }
 86421 
 86422 if ($definition->getOptions()) {
 86423 $laterOptions = array();
 86424 
 86425 $this->writeText('<comment>Options:</comment>', $options);
 86426 foreach ($definition->getOptions() as $option) {
 86427 if (\strlen($option->getShortcut()) > 1) {
 86428 $laterOptions[] = $option;
 86429 continue;
 86430 }
 86431 $this->writeText("\n");
 86432 $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
 86433 }
 86434 foreach ($laterOptions as $option) {
 86435 $this->writeText("\n");
 86436 $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
 86437 }
 86438 }
 86439 }
 86440 
 86441 
 86442 
 86443 
 86444 protected function describeCommand(Command $command, array $options = array())
 86445 {
 86446 $command->getSynopsis(true);
 86447 $command->getSynopsis(false);
 86448 $command->mergeApplicationDefinition(false);
 86449 
 86450 $this->writeText('<comment>Usage:</comment>', $options);
 86451 foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
 86452 $this->writeText("\n");
 86453 $this->writeText('  '.OutputFormatter::escape($usage), $options);
 86454 }
 86455 $this->writeText("\n");
 86456 
 86457 $definition = $command->getNativeDefinition();
 86458 if ($definition->getOptions() || $definition->getArguments()) {
 86459 $this->writeText("\n");
 86460 $this->describeInputDefinition($definition, $options);
 86461 $this->writeText("\n");
 86462 }
 86463 
 86464 if ($help = $command->getProcessedHelp()) {
 86465 $this->writeText("\n");
 86466 $this->writeText('<comment>Help:</comment>', $options);
 86467 $this->writeText("\n");
 86468 $this->writeText('  '.str_replace("\n", "\n  ", $help), $options);
 86469 $this->writeText("\n");
 86470 }
 86471 }
 86472 
 86473 
 86474 
 86475 
 86476 protected function describeApplication(Application $application, array $options = array())
 86477 {
 86478 $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
 86479 $description = new ApplicationDescription($application, $describedNamespace);
 86480 
 86481 if (isset($options['raw_text']) && $options['raw_text']) {
 86482 $width = $this->getColumnWidth($description->getCommands());
 86483 
 86484 foreach ($description->getCommands() as $command) {
 86485 $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
 86486 $this->writeText("\n");
 86487 }
 86488 } else {
 86489 if ('' != $help = $application->getHelp()) {
 86490 $this->writeText("$help\n\n", $options);
 86491 }
 86492 
 86493 $this->writeText("<comment>Usage:</comment>\n", $options);
 86494 $this->writeText("  command [options] [arguments]\n\n", $options);
 86495 
 86496 $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);
 86497 
 86498 $this->writeText("\n");
 86499 $this->writeText("\n");
 86500 
 86501 $width = $this->getColumnWidth($description->getCommands());
 86502 
 86503 if ($describedNamespace) {
 86504 $this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
 86505 } else {
 86506 $this->writeText('<comment>Available commands:</comment>', $options);
 86507 }
 86508 
 86509 
 86510 foreach ($description->getNamespaces() as $namespace) {
 86511 if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
 86512 $this->writeText("\n");
 86513 $this->writeText(' <comment>'.$namespace['id'].'</comment>', $options);
 86514 }
 86515 
 86516 foreach ($namespace['commands'] as $name) {
 86517 $this->writeText("\n");
 86518 $spacingWidth = $width - Helper::strlen($name);
 86519 $this->writeText(sprintf('  <info>%s</info>%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
 86520 }
 86521 }
 86522 
 86523 $this->writeText("\n");
 86524 }
 86525 }
 86526 
 86527 
 86528 
 86529 
 86530 private function writeText($content, array $options = array())
 86531 {
 86532 $this->write(
 86533 isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
 86534 isset($options['raw_output']) ? !$options['raw_output'] : true
 86535 );
 86536 }
 86537 
 86538 
 86539 
 86540 
 86541 
 86542 
 86543 
 86544 
 86545 private function formatDefaultValue($default)
 86546 {
 86547 if (INF === $default) {
 86548 return 'INF';
 86549 }
 86550 
 86551 if (\is_string($default)) {
 86552 $default = OutputFormatter::escape($default);
 86553 } elseif (\is_array($default)) {
 86554 foreach ($default as $key => $value) {
 86555 if (\is_string($value)) {
 86556 $default[$key] = OutputFormatter::escape($value);
 86557 }
 86558 }
 86559 }
 86560 
 86561 if (\PHP_VERSION_ID < 50400) {
 86562 return str_replace(array('\/', '\\\\'), array('/', '\\'), json_encode($default));
 86563 }
 86564 
 86565 return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
 86566 }
 86567 
 86568 
 86569 
 86570 
 86571 
 86572 
 86573 private function getColumnWidth(array $commands)
 86574 {
 86575 $widths = array();
 86576 
 86577 foreach ($commands as $command) {
 86578 $widths[] = Helper::strlen($command->getName());
 86579 foreach ($command->getAliases() as $alias) {
 86580 $widths[] = Helper::strlen($alias);
 86581 }
 86582 }
 86583 
 86584 return max($widths) + 2;
 86585 }
 86586 
 86587 
 86588 
 86589 
 86590 
 86591 
 86592 private function calculateTotalWidthForOptions(array $options)
 86593 {
 86594 $totalWidth = 0;
 86595 foreach ($options as $option) {
 86596 
 86597 $nameLength = 1 + max(\strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName());
 86598 
 86599 if ($option->acceptValue()) {
 86600 $valueLength = 1 + Helper::strlen($option->getName()); 
 86601 $valueLength += $option->isValueOptional() ? 2 : 0; 
 86602 
 86603 $nameLength += $valueLength;
 86604 }
 86605 $totalWidth = max($totalWidth, $nameLength);
 86606 }
 86607 
 86608 return $totalWidth;
 86609 }
 86610 }
 86611 <?php
 86612 
 86613 
 86614 
 86615 
 86616 
 86617 
 86618 
 86619 
 86620 
 86621 
 86622 namespace Symfony\Component\Console\Descriptor;
 86623 
 86624 use Symfony\Component\Console\Application;
 86625 use Symfony\Component\Console\Command\Command;
 86626 use Symfony\Component\Console\Input\InputArgument;
 86627 use Symfony\Component\Console\Input\InputDefinition;
 86628 use Symfony\Component\Console\Input\InputOption;
 86629 
 86630 
 86631 
 86632 
 86633 
 86634 
 86635 
 86636 
 86637 class XmlDescriptor extends Descriptor
 86638 {
 86639 
 86640 
 86641 
 86642 public function getInputDefinitionDocument(InputDefinition $definition)
 86643 {
 86644 $dom = new \DOMDocument('1.0', 'UTF-8');
 86645 $dom->appendChild($definitionXML = $dom->createElement('definition'));
 86646 
 86647 $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
 86648 foreach ($definition->getArguments() as $argument) {
 86649 $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
 86650 }
 86651 
 86652 $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
 86653 foreach ($definition->getOptions() as $option) {
 86654 $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
 86655 }
 86656 
 86657 return $dom;
 86658 }
 86659 
 86660 
 86661 
 86662 
 86663 public function getCommandDocument(Command $command)
 86664 {
 86665 $dom = new \DOMDocument('1.0', 'UTF-8');
 86666 $dom->appendChild($commandXML = $dom->createElement('command'));
 86667 
 86668 $command->getSynopsis();
 86669 $command->mergeApplicationDefinition(false);
 86670 
 86671 $commandXML->setAttribute('id', $command->getName());
 86672 $commandXML->setAttribute('name', $command->getName());
 86673 
 86674 $commandXML->appendChild($usagesXML = $dom->createElement('usages'));
 86675 
 86676 foreach (array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()) as $usage) {
 86677 $usagesXML->appendChild($dom->createElement('usage', $usage));
 86678 }
 86679 
 86680 $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
 86681 $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));
 86682 
 86683 $commandXML->appendChild($helpXML = $dom->createElement('help'));
 86684 $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));
 86685 
 86686 $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition());
 86687 $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
 86688 
 86689 return $dom;
 86690 }
 86691 
 86692 
 86693 
 86694 
 86695 
 86696 
 86697 
 86698 public function getApplicationDocument(Application $application, $namespace = null)
 86699 {
 86700 $dom = new \DOMDocument('1.0', 'UTF-8');
 86701 $dom->appendChild($rootXml = $dom->createElement('symfony'));
 86702 
 86703 if ('UNKNOWN' !== $application->getName()) {
 86704 $rootXml->setAttribute('name', $application->getName());
 86705 if ('UNKNOWN' !== $application->getVersion()) {
 86706 $rootXml->setAttribute('version', $application->getVersion());
 86707 }
 86708 }
 86709 
 86710 $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
 86711 
 86712 $description = new ApplicationDescription($application, $namespace);
 86713 
 86714 if ($namespace) {
 86715 $commandsXML->setAttribute('namespace', $namespace);
 86716 }
 86717 
 86718 foreach ($description->getCommands() as $command) {
 86719 $this->appendDocument($commandsXML, $this->getCommandDocument($command));
 86720 }
 86721 
 86722 if (!$namespace) {
 86723 $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
 86724 
 86725 foreach ($description->getNamespaces() as $namespaceDescription) {
 86726 $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
 86727 $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);
 86728 
 86729 foreach ($namespaceDescription['commands'] as $name) {
 86730 $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
 86731 $commandXML->appendChild($dom->createTextNode($name));
 86732 }
 86733 }
 86734 }
 86735 
 86736 return $dom;
 86737 }
 86738 
 86739 
 86740 
 86741 
 86742 protected function describeInputArgument(InputArgument $argument, array $options = array())
 86743 {
 86744 $this->writeDocument($this->getInputArgumentDocument($argument));
 86745 }
 86746 
 86747 
 86748 
 86749 
 86750 protected function describeInputOption(InputOption $option, array $options = array())
 86751 {
 86752 $this->writeDocument($this->getInputOptionDocument($option));
 86753 }
 86754 
 86755 
 86756 
 86757 
 86758 protected function describeInputDefinition(InputDefinition $definition, array $options = array())
 86759 {
 86760 $this->writeDocument($this->getInputDefinitionDocument($definition));
 86761 }
 86762 
 86763 
 86764 
 86765 
 86766 protected function describeCommand(Command $command, array $options = array())
 86767 {
 86768 $this->writeDocument($this->getCommandDocument($command));
 86769 }
 86770 
 86771 
 86772 
 86773 
 86774 protected function describeApplication(Application $application, array $options = array())
 86775 {
 86776 $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null));
 86777 }
 86778 
 86779 
 86780 
 86781 
 86782 private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
 86783 {
 86784 foreach ($importedParent->childNodes as $childNode) {
 86785 $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
 86786 }
 86787 }
 86788 
 86789 
 86790 
 86791 
 86792 
 86793 
 86794 private function writeDocument(\DOMDocument $dom)
 86795 {
 86796 $dom->formatOutput = true;
 86797 $this->write($dom->saveXML());
 86798 }
 86799 
 86800 
 86801 
 86802 
 86803 private function getInputArgumentDocument(InputArgument $argument)
 86804 {
 86805 $dom = new \DOMDocument('1.0', 'UTF-8');
 86806 
 86807 $dom->appendChild($objectXML = $dom->createElement('argument'));
 86808 $objectXML->setAttribute('name', $argument->getName());
 86809 $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
 86810 $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
 86811 $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
 86812 $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
 86813 
 86814 $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
 86815 $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
 86816 foreach ($defaults as $default) {
 86817 $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
 86818 $defaultXML->appendChild($dom->createTextNode($default));
 86819 }
 86820 
 86821 return $dom;
 86822 }
 86823 
 86824 
 86825 
 86826 
 86827 private function getInputOptionDocument(InputOption $option)
 86828 {
 86829 $dom = new \DOMDocument('1.0', 'UTF-8');
 86830 
 86831 $dom->appendChild($objectXML = $dom->createElement('option'));
 86832 $objectXML->setAttribute('name', '--'.$option->getName());
 86833 $pos = strpos($option->getShortcut(), '|');
 86834 if (false !== $pos) {
 86835 $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
 86836 $objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut()));
 86837 } else {
 86838 $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
 86839 }
 86840 $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
 86841 $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
 86842 $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
 86843 $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
 86844 $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
 86845 
 86846 if ($option->acceptValue()) {
 86847 $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
 86848 $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
 86849 
 86850 if (!empty($defaults)) {
 86851 foreach ($defaults as $default) {
 86852 $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
 86853 $defaultXML->appendChild($dom->createTextNode($default));
 86854 }
 86855 }
 86856 }
 86857 
 86858 return $dom;
 86859 }
 86860 }
 86861 <?php
 86862 
 86863 
 86864 
 86865 
 86866 
 86867 
 86868 
 86869 
 86870 
 86871 
 86872 namespace Symfony\Component\Console\Event;
 86873 
 86874 
 86875 
 86876 
 86877 
 86878 
 86879 class ConsoleCommandEvent extends ConsoleEvent
 86880 {
 86881 
 86882 
 86883 
 86884 const RETURN_CODE_DISABLED = 113;
 86885 
 86886 
 86887 
 86888 
 86889 private $commandShouldRun = true;
 86890 
 86891 
 86892 
 86893 
 86894 
 86895 
 86896 public function disableCommand()
 86897 {
 86898 return $this->commandShouldRun = false;
 86899 }
 86900 
 86901 
 86902 
 86903 
 86904 
 86905 
 86906 public function enableCommand()
 86907 {
 86908 return $this->commandShouldRun = true;
 86909 }
 86910 
 86911 
 86912 
 86913 
 86914 
 86915 
 86916 public function commandShouldRun()
 86917 {
 86918 return $this->commandShouldRun;
 86919 }
 86920 }
 86921 <?php
 86922 
 86923 
 86924 
 86925 
 86926 
 86927 
 86928 
 86929 
 86930 
 86931 
 86932 namespace Symfony\Component\Console\Event;
 86933 
 86934 use Symfony\Component\Console\Command\Command;
 86935 use Symfony\Component\Console\Input\InputInterface;
 86936 use Symfony\Component\Console\Output\OutputInterface;
 86937 use Symfony\Component\EventDispatcher\Event;
 86938 
 86939 
 86940 
 86941 
 86942 
 86943 
 86944 class ConsoleEvent extends Event
 86945 {
 86946 protected $command;
 86947 
 86948 private $input;
 86949 private $output;
 86950 
 86951 public function __construct(Command $command, InputInterface $input, OutputInterface $output)
 86952 {
 86953 $this->command = $command;
 86954 $this->input = $input;
 86955 $this->output = $output;
 86956 }
 86957 
 86958 
 86959 
 86960 
 86961 
 86962 
 86963 public function getCommand()
 86964 {
 86965 return $this->command;
 86966 }
 86967 
 86968 
 86969 
 86970 
 86971 
 86972 
 86973 public function getInput()
 86974 {
 86975 return $this->input;
 86976 }
 86977 
 86978 
 86979 
 86980 
 86981 
 86982 
 86983 public function getOutput()
 86984 {
 86985 return $this->output;
 86986 }
 86987 }
 86988 <?php
 86989 
 86990 
 86991 
 86992 
 86993 
 86994 
 86995 
 86996 
 86997 
 86998 
 86999 namespace Symfony\Component\Console\Event;
 87000 
 87001 use Symfony\Component\Console\Command\Command;
 87002 use Symfony\Component\Console\Input\InputInterface;
 87003 use Symfony\Component\Console\Output\OutputInterface;
 87004 
 87005 
 87006 
 87007 
 87008 
 87009 
 87010 class ConsoleExceptionEvent extends ConsoleEvent
 87011 {
 87012 private $exception;
 87013 private $exitCode;
 87014 
 87015 public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
 87016 {
 87017 parent::__construct($command, $input, $output);
 87018 
 87019 $this->setException($exception);
 87020 $this->exitCode = (int) $exitCode;
 87021 }
 87022 
 87023 
 87024 
 87025 
 87026 
 87027 
 87028 public function getException()
 87029 {
 87030 return $this->exception;
 87031 }
 87032 
 87033 
 87034 
 87035 
 87036 
 87037 
 87038 
 87039 
 87040 public function setException(\Exception $exception)
 87041 {
 87042 $this->exception = $exception;
 87043 }
 87044 
 87045 
 87046 
 87047 
 87048 
 87049 
 87050 public function getExitCode()
 87051 {
 87052 return $this->exitCode;
 87053 }
 87054 }
 87055 <?php
 87056 
 87057 
 87058 
 87059 
 87060 
 87061 
 87062 
 87063 
 87064 
 87065 
 87066 namespace Symfony\Component\Console\Event;
 87067 
 87068 use Symfony\Component\Console\Command\Command;
 87069 use Symfony\Component\Console\Input\InputInterface;
 87070 use Symfony\Component\Console\Output\OutputInterface;
 87071 
 87072 
 87073 
 87074 
 87075 
 87076 
 87077 class ConsoleTerminateEvent extends ConsoleEvent
 87078 {
 87079 
 87080 
 87081 
 87082 
 87083 
 87084 private $exitCode;
 87085 
 87086 public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
 87087 {
 87088 parent::__construct($command, $input, $output);
 87089 
 87090 $this->setExitCode($exitCode);
 87091 }
 87092 
 87093 
 87094 
 87095 
 87096 
 87097 
 87098 public function setExitCode($exitCode)
 87099 {
 87100 $this->exitCode = (int) $exitCode;
 87101 }
 87102 
 87103 
 87104 
 87105 
 87106 
 87107 
 87108 public function getExitCode()
 87109 {
 87110 return $this->exitCode;
 87111 }
 87112 }
 87113 <?php
 87114 
 87115 
 87116 
 87117 
 87118 
 87119 
 87120 
 87121 
 87122 
 87123 
 87124 namespace Symfony\Component\Console\Exception;
 87125 
 87126 
 87127 
 87128 
 87129 
 87130 
 87131 class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
 87132 {
 87133 private $alternatives;
 87134 
 87135 
 87136 
 87137 
 87138 
 87139 
 87140 
 87141 public function __construct($message, array $alternatives = array(), $code = 0, \Exception $previous = null)
 87142 {
 87143 parent::__construct($message, $code, $previous);
 87144 
 87145 $this->alternatives = $alternatives;
 87146 }
 87147 
 87148 
 87149 
 87150 
 87151 public function getAlternatives()
 87152 {
 87153 return $this->alternatives;
 87154 }
 87155 }
 87156 <?php
 87157 
 87158 
 87159 
 87160 
 87161 
 87162 
 87163 
 87164 
 87165 
 87166 
 87167 namespace Symfony\Component\Console\Exception;
 87168 
 87169 
 87170 
 87171 
 87172 
 87173 
 87174 interface ExceptionInterface
 87175 {
 87176 }
 87177 <?php
 87178 
 87179 
 87180 
 87181 
 87182 
 87183 
 87184 
 87185 
 87186 
 87187 
 87188 namespace Symfony\Component\Console\Exception;
 87189 
 87190 
 87191 
 87192 
 87193 class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
 87194 {
 87195 }
 87196 <?php
 87197 
 87198 
 87199 
 87200 
 87201 
 87202 
 87203 
 87204 
 87205 
 87206 
 87207 namespace Symfony\Component\Console\Exception;
 87208 
 87209 
 87210 
 87211 
 87212 
 87213 
 87214 class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
 87215 {
 87216 }
 87217 <?php
 87218 
 87219 
 87220 
 87221 
 87222 
 87223 
 87224 
 87225 
 87226 
 87227 
 87228 namespace Symfony\Component\Console\Exception;
 87229 
 87230 
 87231 
 87232 
 87233 class LogicException extends \LogicException implements ExceptionInterface
 87234 {
 87235 }
 87236 <?php
 87237 
 87238 
 87239 
 87240 
 87241 
 87242 
 87243 
 87244 
 87245 
 87246 
 87247 namespace Symfony\Component\Console\Exception;
 87248 
 87249 
 87250 
 87251 
 87252 class RuntimeException extends \RuntimeException implements ExceptionInterface
 87253 {
 87254 }
 87255 <?php
 87256 
 87257 
 87258 
 87259 
 87260 
 87261 
 87262 
 87263 
 87264 
 87265 
 87266 namespace Symfony\Component\Console\Formatter;
 87267 
 87268 use Symfony\Component\Console\Exception\InvalidArgumentException;
 87269 
 87270 
 87271 
 87272 
 87273 
 87274 
 87275 class OutputFormatter implements OutputFormatterInterface
 87276 {
 87277 private $decorated;
 87278 private $styles = array();
 87279 private $styleStack;
 87280 
 87281 
 87282 
 87283 
 87284 
 87285 
 87286 
 87287 
 87288 public static function escape($text)
 87289 {
 87290 $text = preg_replace('/([^\\\\]?)</', '$1\\<', $text);
 87291 
 87292 return self::escapeTrailingBackslash($text);
 87293 }
 87294 
 87295 
 87296 
 87297 
 87298 
 87299 
 87300 
 87301 
 87302 
 87303 
 87304 public static function escapeTrailingBackslash($text)
 87305 {
 87306 if ('\\' === substr($text, -1)) {
 87307 $len = \strlen($text);
 87308 $text = rtrim($text, '\\');
 87309 $text = str_replace("\0", '', $text);
 87310 $text .= str_repeat("\0", $len - \strlen($text));
 87311 }
 87312 
 87313 return $text;
 87314 }
 87315 
 87316 
 87317 
 87318 
 87319 
 87320 
 87321 
 87322 public function __construct($decorated = false, array $styles = array())
 87323 {
 87324 $this->decorated = (bool) $decorated;
 87325 
 87326 $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
 87327 $this->setStyle('info', new OutputFormatterStyle('green'));
 87328 $this->setStyle('comment', new OutputFormatterStyle('yellow'));
 87329 $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
 87330 
 87331 foreach ($styles as $name => $style) {
 87332 $this->setStyle($name, $style);
 87333 }
 87334 
 87335 $this->styleStack = new OutputFormatterStyleStack();
 87336 }
 87337 
 87338 
 87339 
 87340 
 87341 public function setDecorated($decorated)
 87342 {
 87343 $this->decorated = (bool) $decorated;
 87344 }
 87345 
 87346 
 87347 
 87348 
 87349 public function isDecorated()
 87350 {
 87351 return $this->decorated;
 87352 }
 87353 
 87354 
 87355 
 87356 
 87357 public function setStyle($name, OutputFormatterStyleInterface $style)
 87358 {
 87359 $this->styles[strtolower($name)] = $style;
 87360 }
 87361 
 87362 
 87363 
 87364 
 87365 public function hasStyle($name)
 87366 {
 87367 return isset($this->styles[strtolower($name)]);
 87368 }
 87369 
 87370 
 87371 
 87372 
 87373 public function getStyle($name)
 87374 {
 87375 if (!$this->hasStyle($name)) {
 87376 throw new InvalidArgumentException(sprintf('Undefined style: %s', $name));
 87377 }
 87378 
 87379 return $this->styles[strtolower($name)];
 87380 }
 87381 
 87382 
 87383 
 87384 
 87385 public function format($message)
 87386 {
 87387 $message = (string) $message;
 87388 $offset = 0;
 87389 $output = '';
 87390 $tagRegex = '[a-z][a-z0-9_=;-]*+';
 87391 preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
 87392 foreach ($matches[0] as $i => $match) {
 87393 $pos = $match[1];
 87394 $text = $match[0];
 87395 
 87396 if (0 != $pos && '\\' == $message[$pos - 1]) {
 87397 continue;
 87398 }
 87399 
 87400 
 87401 $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
 87402 $offset = $pos + \strlen($text);
 87403 
 87404 
 87405 if ($open = '/' != $text[1]) {
 87406 $tag = $matches[1][$i][0];
 87407 } else {
 87408 $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
 87409 }
 87410 
 87411 if (!$open && !$tag) {
 87412 
 87413 $this->styleStack->pop();
 87414 } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
 87415 $output .= $this->applyCurrentStyle($text);
 87416 } elseif ($open) {
 87417 $this->styleStack->push($style);
 87418 } else {
 87419 $this->styleStack->pop($style);
 87420 }
 87421 }
 87422 
 87423 $output .= $this->applyCurrentStyle(substr($message, $offset));
 87424 
 87425 if (false !== strpos($output, "\0")) {
 87426 return strtr($output, array("\0" => '\\', '\\<' => '<'));
 87427 }
 87428 
 87429 return str_replace('\\<', '<', $output);
 87430 }
 87431 
 87432 
 87433 
 87434 
 87435 public function getStyleStack()
 87436 {
 87437 return $this->styleStack;
 87438 }
 87439 
 87440 
 87441 
 87442 
 87443 
 87444 
 87445 
 87446 
 87447 private function createStyleFromString($string)
 87448 {
 87449 if (isset($this->styles[$string])) {
 87450 return $this->styles[$string];
 87451 }
 87452 
 87453 if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
 87454 return false;
 87455 }
 87456 
 87457 $style = new OutputFormatterStyle();
 87458 foreach ($matches as $match) {
 87459 array_shift($match);
 87460 
 87461 if ('fg' == $match[0]) {
 87462 $style->setForeground($match[1]);
 87463 } elseif ('bg' == $match[0]) {
 87464 $style->setBackground($match[1]);
 87465 } else {
 87466 try {
 87467 $style->setOption($match[1]);
 87468 } catch (\InvalidArgumentException $e) {
 87469 return false;
 87470 }
 87471 }
 87472 }
 87473 
 87474 return $style;
 87475 }
 87476 
 87477 
 87478 
 87479 
 87480 
 87481 
 87482 
 87483 
 87484 private function applyCurrentStyle($text)
 87485 {
 87486 return $this->isDecorated() && \strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
 87487 }
 87488 }
 87489 <?php
 87490 
 87491 
 87492 
 87493 
 87494 
 87495 
 87496 
 87497 
 87498 
 87499 
 87500 namespace Symfony\Component\Console\Formatter;
 87501 
 87502 
 87503 
 87504 
 87505 
 87506 
 87507 interface OutputFormatterInterface
 87508 {
 87509 
 87510 
 87511 
 87512 
 87513 
 87514 public function setDecorated($decorated);
 87515 
 87516 
 87517 
 87518 
 87519 
 87520 
 87521 public function isDecorated();
 87522 
 87523 
 87524 
 87525 
 87526 
 87527 
 87528 
 87529 public function setStyle($name, OutputFormatterStyleInterface $style);
 87530 
 87531 
 87532 
 87533 
 87534 
 87535 
 87536 
 87537 
 87538 public function hasStyle($name);
 87539 
 87540 
 87541 
 87542 
 87543 
 87544 
 87545 
 87546 
 87547 
 87548 
 87549 public function getStyle($name);
 87550 
 87551 
 87552 
 87553 
 87554 
 87555 
 87556 
 87557 
 87558 public function format($message);
 87559 }
 87560 <?php
 87561 
 87562 
 87563 
 87564 
 87565 
 87566 
 87567 
 87568 
 87569 
 87570 
 87571 namespace Symfony\Component\Console\Formatter;
 87572 
 87573 use Symfony\Component\Console\Exception\InvalidArgumentException;
 87574 
 87575 
 87576 
 87577 
 87578 
 87579 
 87580 class OutputFormatterStyle implements OutputFormatterStyleInterface
 87581 {
 87582 private static $availableForegroundColors = array(
 87583 'black' => array('set' => 30, 'unset' => 39),
 87584 'red' => array('set' => 31, 'unset' => 39),
 87585 'green' => array('set' => 32, 'unset' => 39),
 87586 'yellow' => array('set' => 33, 'unset' => 39),
 87587 'blue' => array('set' => 34, 'unset' => 39),
 87588 'magenta' => array('set' => 35, 'unset' => 39),
 87589 'cyan' => array('set' => 36, 'unset' => 39),
 87590 'white' => array('set' => 37, 'unset' => 39),
 87591 'default' => array('set' => 39, 'unset' => 39),
 87592 );
 87593 private static $availableBackgroundColors = array(
 87594 'black' => array('set' => 40, 'unset' => 49),
 87595 'red' => array('set' => 41, 'unset' => 49),
 87596 'green' => array('set' => 42, 'unset' => 49),
 87597 'yellow' => array('set' => 43, 'unset' => 49),
 87598 'blue' => array('set' => 44, 'unset' => 49),
 87599 'magenta' => array('set' => 45, 'unset' => 49),
 87600 'cyan' => array('set' => 46, 'unset' => 49),
 87601 'white' => array('set' => 47, 'unset' => 49),
 87602 'default' => array('set' => 49, 'unset' => 49),
 87603 );
 87604 private static $availableOptions = array(
 87605 'bold' => array('set' => 1, 'unset' => 22),
 87606 'underscore' => array('set' => 4, 'unset' => 24),
 87607 'blink' => array('set' => 5, 'unset' => 25),
 87608 'reverse' => array('set' => 7, 'unset' => 27),
 87609 'conceal' => array('set' => 8, 'unset' => 28),
 87610 );
 87611 
 87612 private $foreground;
 87613 private $background;
 87614 private $options = array();
 87615 
 87616 
 87617 
 87618 
 87619 
 87620 
 87621 
 87622 
 87623 public function __construct($foreground = null, $background = null, array $options = array())
 87624 {
 87625 if (null !== $foreground) {
 87626 $this->setForeground($foreground);
 87627 }
 87628 if (null !== $background) {
 87629 $this->setBackground($background);
 87630 }
 87631 if (\count($options)) {
 87632 $this->setOptions($options);
 87633 }
 87634 }
 87635 
 87636 
 87637 
 87638 
 87639 
 87640 
 87641 
 87642 
 87643 public function setForeground($color = null)
 87644 {
 87645 if (null === $color) {
 87646 $this->foreground = null;
 87647 
 87648 return;
 87649 }
 87650 
 87651 if (!isset(static::$availableForegroundColors[$color])) {
 87652 throw new InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors))));
 87653 }
 87654 
 87655 $this->foreground = static::$availableForegroundColors[$color];
 87656 }
 87657 
 87658 
 87659 
 87660 
 87661 
 87662 
 87663 
 87664 
 87665 public function setBackground($color = null)
 87666 {
 87667 if (null === $color) {
 87668 $this->background = null;
 87669 
 87670 return;
 87671 }
 87672 
 87673 if (!isset(static::$availableBackgroundColors[$color])) {
 87674 throw new InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors))));
 87675 }
 87676 
 87677 $this->background = static::$availableBackgroundColors[$color];
 87678 }
 87679 
 87680 
 87681 
 87682 
 87683 
 87684 
 87685 
 87686 
 87687 public function setOption($option)
 87688 {
 87689 if (!isset(static::$availableOptions[$option])) {
 87690 throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
 87691 }
 87692 
 87693 if (!\in_array(static::$availableOptions[$option], $this->options)) {
 87694 $this->options[] = static::$availableOptions[$option];
 87695 }
 87696 }
 87697 
 87698 
 87699 
 87700 
 87701 
 87702 
 87703 
 87704 
 87705 public function unsetOption($option)
 87706 {
 87707 if (!isset(static::$availableOptions[$option])) {
 87708 throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
 87709 }
 87710 
 87711 $pos = array_search(static::$availableOptions[$option], $this->options);
 87712 if (false !== $pos) {
 87713 unset($this->options[$pos]);
 87714 }
 87715 }
 87716 
 87717 
 87718 
 87719 
 87720 public function setOptions(array $options)
 87721 {
 87722 $this->options = array();
 87723 
 87724 foreach ($options as $option) {
 87725 $this->setOption($option);
 87726 }
 87727 }
 87728 
 87729 
 87730 
 87731 
 87732 
 87733 
 87734 
 87735 
 87736 public function apply($text)
 87737 {
 87738 $setCodes = array();
 87739 $unsetCodes = array();
 87740 
 87741 if (null !== $this->foreground) {
 87742 $setCodes[] = $this->foreground['set'];
 87743 $unsetCodes[] = $this->foreground['unset'];
 87744 }
 87745 if (null !== $this->background) {
 87746 $setCodes[] = $this->background['set'];
 87747 $unsetCodes[] = $this->background['unset'];
 87748 }
 87749 if (\count($this->options)) {
 87750 foreach ($this->options as $option) {
 87751 $setCodes[] = $option['set'];
 87752 $unsetCodes[] = $option['unset'];
 87753 }
 87754 }
 87755 
 87756 if (0 === \count($setCodes)) {
 87757 return $text;
 87758 }
 87759 
 87760 return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
 87761 }
 87762 }
 87763 <?php
 87764 
 87765 
 87766 
 87767 
 87768 
 87769 
 87770 
 87771 
 87772 
 87773 
 87774 namespace Symfony\Component\Console\Formatter;
 87775 
 87776 
 87777 
 87778 
 87779 
 87780 
 87781 interface OutputFormatterStyleInterface
 87782 {
 87783 
 87784 
 87785 
 87786 
 87787 
 87788 public function setForeground($color = null);
 87789 
 87790 
 87791 
 87792 
 87793 
 87794 
 87795 public function setBackground($color = null);
 87796 
 87797 
 87798 
 87799 
 87800 
 87801 
 87802 public function setOption($option);
 87803 
 87804 
 87805 
 87806 
 87807 
 87808 
 87809 public function unsetOption($option);
 87810 
 87811 
 87812 
 87813 
 87814 public function setOptions(array $options);
 87815 
 87816 
 87817 
 87818 
 87819 
 87820 
 87821 
 87822 
 87823 public function apply($text);
 87824 }
 87825 <?php
 87826 
 87827 
 87828 
 87829 
 87830 
 87831 
 87832 
 87833 
 87834 
 87835 
 87836 namespace Symfony\Component\Console\Formatter;
 87837 
 87838 use Symfony\Component\Console\Exception\InvalidArgumentException;
 87839 
 87840 
 87841 
 87842 
 87843 class OutputFormatterStyleStack
 87844 {
 87845 
 87846 
 87847 
 87848 private $styles;
 87849 
 87850 private $emptyStyle;
 87851 
 87852 public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
 87853 {
 87854 $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
 87855 $this->reset();
 87856 }
 87857 
 87858 
 87859 
 87860 
 87861 public function reset()
 87862 {
 87863 $this->styles = array();
 87864 }
 87865 
 87866 
 87867 
 87868 
 87869 public function push(OutputFormatterStyleInterface $style)
 87870 {
 87871 $this->styles[] = $style;
 87872 }
 87873 
 87874 
 87875 
 87876 
 87877 
 87878 
 87879 
 87880 
 87881 public function pop(OutputFormatterStyleInterface $style = null)
 87882 {
 87883 if (empty($this->styles)) {
 87884 return $this->emptyStyle;
 87885 }
 87886 
 87887 if (null === $style) {
 87888 return array_pop($this->styles);
 87889 }
 87890 
 87891 foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
 87892 if ($style->apply('') === $stackedStyle->apply('')) {
 87893 $this->styles = \array_slice($this->styles, 0, $index);
 87894 
 87895 return $stackedStyle;
 87896 }
 87897 }
 87898 
 87899 throw new InvalidArgumentException('Incorrectly nested style tag found.');
 87900 }
 87901 
 87902 
 87903 
 87904 
 87905 
 87906 
 87907 public function getCurrent()
 87908 {
 87909 if (empty($this->styles)) {
 87910 return $this->emptyStyle;
 87911 }
 87912 
 87913 return $this->styles[\count($this->styles) - 1];
 87914 }
 87915 
 87916 
 87917 
 87918 
 87919 public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
 87920 {
 87921 $this->emptyStyle = $emptyStyle;
 87922 
 87923 return $this;
 87924 }
 87925 
 87926 
 87927 
 87928 
 87929 public function getEmptyStyle()
 87930 {
 87931 return $this->emptyStyle;
 87932 }
 87933 }
 87934 <?php
 87935 
 87936 
 87937 
 87938 
 87939 
 87940 
 87941 
 87942 
 87943 
 87944 
 87945 namespace Symfony\Component\Console\Helper;
 87946 
 87947 
 87948 
 87949 
 87950 
 87951 
 87952 
 87953 
 87954 class DebugFormatterHelper extends Helper
 87955 {
 87956 private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default');
 87957 private $started = array();
 87958 private $count = -1;
 87959 
 87960 
 87961 
 87962 
 87963 
 87964 
 87965 
 87966 
 87967 
 87968 
 87969 public function start($id, $message, $prefix = 'RUN')
 87970 {
 87971 $this->started[$id] = array('border' => ++$this->count % \count($this->colors));
 87972 
 87973 return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
 87974 }
 87975 
 87976 
 87977 
 87978 
 87979 
 87980 
 87981 
 87982 
 87983 
 87984 
 87985 
 87986 
 87987 public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR')
 87988 {
 87989 $message = '';
 87990 
 87991 if ($error) {
 87992 if (isset($this->started[$id]['out'])) {
 87993 $message .= "\n";
 87994 unset($this->started[$id]['out']);
 87995 }
 87996 if (!isset($this->started[$id]['err'])) {
 87997 $message .= sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix);
 87998 $this->started[$id]['err'] = true;
 87999 }
 88000 
 88001 $message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
 88002 } else {
 88003 if (isset($this->started[$id]['err'])) {
 88004 $message .= "\n";
 88005 unset($this->started[$id]['err']);
 88006 }
 88007 if (!isset($this->started[$id]['out'])) {
 88008 $message .= sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix);
 88009 $this->started[$id]['out'] = true;
 88010 }
 88011 
 88012 $message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
 88013 }
 88014 
 88015 return $message;
 88016 }
 88017 
 88018 
 88019 
 88020 
 88021 
 88022 
 88023 
 88024 
 88025 
 88026 
 88027 
 88028 public function stop($id, $message, $successful, $prefix = 'RES')
 88029 {
 88030 $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
 88031 
 88032 if ($successful) {
 88033 return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
 88034 }
 88035 
 88036 $message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
 88037 
 88038 unset($this->started[$id]['out'], $this->started[$id]['err']);
 88039 
 88040 return $message;
 88041 }
 88042 
 88043 
 88044 
 88045 
 88046 
 88047 
 88048 private function getBorder($id)
 88049 {
 88050 return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]);
 88051 }
 88052 
 88053 
 88054 
 88055 
 88056 public function getName()
 88057 {
 88058 return 'debug_formatter';
 88059 }
 88060 }
 88061 <?php
 88062 
 88063 
 88064 
 88065 
 88066 
 88067 
 88068 
 88069 
 88070 
 88071 
 88072 namespace Symfony\Component\Console\Helper;
 88073 
 88074 use Symfony\Component\Console\Descriptor\DescriptorInterface;
 88075 use Symfony\Component\Console\Descriptor\JsonDescriptor;
 88076 use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
 88077 use Symfony\Component\Console\Descriptor\TextDescriptor;
 88078 use Symfony\Component\Console\Descriptor\XmlDescriptor;
 88079 use Symfony\Component\Console\Exception\InvalidArgumentException;
 88080 use Symfony\Component\Console\Output\OutputInterface;
 88081 
 88082 
 88083 
 88084 
 88085 
 88086 
 88087 class DescriptorHelper extends Helper
 88088 {
 88089 
 88090 
 88091 
 88092 private $descriptors = array();
 88093 
 88094 public function __construct()
 88095 {
 88096 $this
 88097 ->register('txt', new TextDescriptor())
 88098 ->register('xml', new XmlDescriptor())
 88099 ->register('json', new JsonDescriptor())
 88100 ->register('md', new MarkdownDescriptor())
 88101 ;
 88102 }
 88103 
 88104 
 88105 
 88106 
 88107 
 88108 
 88109 
 88110 
 88111 
 88112 
 88113 
 88114 
 88115 
 88116 
 88117 public function describe(OutputInterface $output, $object, array $options = array())
 88118 {
 88119 $options = array_merge(array(
 88120 'raw_text' => false,
 88121 'format' => 'txt',
 88122 ), $options);
 88123 
 88124 if (!isset($this->descriptors[$options['format']])) {
 88125 throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
 88126 }
 88127 
 88128 $descriptor = $this->descriptors[$options['format']];
 88129 $descriptor->describe($output, $object, $options);
 88130 }
 88131 
 88132 
 88133 
 88134 
 88135 
 88136 
 88137 
 88138 
 88139 
 88140 public function register($format, DescriptorInterface $descriptor)
 88141 {
 88142 $this->descriptors[$format] = $descriptor;
 88143 
 88144 return $this;
 88145 }
 88146 
 88147 
 88148 
 88149 
 88150 public function getName()
 88151 {
 88152 return 'descriptor';
 88153 }
 88154 }
 88155 <?php
 88156 
 88157 
 88158 
 88159 
 88160 
 88161 
 88162 
 88163 
 88164 
 88165 
 88166 namespace Symfony\Component\Console\Helper;
 88167 
 88168 use Symfony\Component\Console\Exception\InvalidArgumentException;
 88169 use Symfony\Component\Console\Exception\RuntimeException;
 88170 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
 88171 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 88172 use Symfony\Component\Console\Output\OutputInterface;
 88173 
 88174 
 88175 
 88176 
 88177 
 88178 
 88179 
 88180 
 88181 
 88182 class DialogHelper extends InputAwareHelper
 88183 {
 88184 private $inputStream;
 88185 private static $shell;
 88186 private static $stty;
 88187 
 88188 public function __construct($triggerDeprecationError = true)
 88189 {
 88190 if ($triggerDeprecationError) {
 88191 @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since Symfony 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
 88192 }
 88193 }
 88194 
 88195 
 88196 
 88197 
 88198 
 88199 
 88200 
 88201 
 88202 
 88203 
 88204 
 88205 
 88206 
 88207 
 88208 
 88209 
 88210 public function select(OutputInterface $output, $question, $choices, $default = null, $attempts = false, $errorMessage = 'Value "%s" is invalid', $multiselect = false)
 88211 {
 88212 if ($output instanceof ConsoleOutputInterface) {
 88213 $output = $output->getErrorOutput();
 88214 }
 88215 
 88216 $width = max(array_map('strlen', array_keys($choices)));
 88217 
 88218 $messages = (array) $question;
 88219 foreach ($choices as $key => $value) {
 88220 $messages[] = sprintf("  [<info>%-{$width}s</info>] %s", $key, $value);
 88221 }
 88222 
 88223 $output->writeln($messages);
 88224 
 88225 $result = $this->askAndValidate($output, '> ', function ($picked) use ($choices, $errorMessage, $multiselect) {
 88226 
 88227 $selectedChoices = str_replace(' ', '', $picked);
 88228 
 88229 if ($multiselect) {
 88230 
 88231 if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
 88232 throw new InvalidArgumentException(sprintf($errorMessage, $picked));
 88233 }
 88234 $selectedChoices = explode(',', $selectedChoices);
 88235 } else {
 88236 $selectedChoices = array($picked);
 88237 }
 88238 
 88239 $multiselectChoices = array();
 88240 
 88241 foreach ($selectedChoices as $value) {
 88242 if (empty($choices[$value])) {
 88243 throw new InvalidArgumentException(sprintf($errorMessage, $value));
 88244 }
 88245 $multiselectChoices[] = $value;
 88246 }
 88247 
 88248 if ($multiselect) {
 88249 return $multiselectChoices;
 88250 }
 88251 
 88252 return $picked;
 88253 }, $attempts, $default);
 88254 
 88255 return $result;
 88256 }
 88257 
 88258 
 88259 
 88260 
 88261 
 88262 
 88263 
 88264 
 88265 
 88266 
 88267 
 88268 
 88269 
 88270 public function ask(OutputInterface $output, $question, $default = null, array $autocomplete = null)
 88271 {
 88272 if ($this->input && !$this->input->isInteractive()) {
 88273 return $default;
 88274 }
 88275 
 88276 if ($output instanceof ConsoleOutputInterface) {
 88277 $output = $output->getErrorOutput();
 88278 }
 88279 
 88280 $output->write($question);
 88281 
 88282 $inputStream = $this->inputStream ?: STDIN;
 88283 
 88284 if (null === $autocomplete || !$this->hasSttyAvailable()) {
 88285 $ret = fgets($inputStream, 4096);
 88286 if (false === $ret) {
 88287 throw new RuntimeException('Aborted');
 88288 }
 88289 $ret = trim($ret);
 88290 } else {
 88291 $ret = '';
 88292 
 88293 $i = 0;
 88294 $ofs = -1;
 88295 $matches = $autocomplete;
 88296 $numMatches = \count($matches);
 88297 
 88298 $sttyMode = shell_exec('stty -g');
 88299 
 88300 
 88301 shell_exec('stty -icanon -echo');
 88302 
 88303 
 88304 $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
 88305 
 88306 
 88307 while (!feof($inputStream)) {
 88308 $c = fread($inputStream, 1);
 88309 
 88310 
 88311 if ("\177" === $c) {
 88312 if (0 === $numMatches && 0 !== $i) {
 88313 --$i;
 88314 
 88315 $output->write("\033[1D");
 88316 }
 88317 
 88318 if (0 === $i) {
 88319 $ofs = -1;
 88320 $matches = $autocomplete;
 88321 $numMatches = \count($matches);
 88322 } else {
 88323 $numMatches = 0;
 88324 }
 88325 
 88326 
 88327 $ret = substr($ret, 0, $i);
 88328 } elseif ("\033" === $c) {
 88329 
 88330 $c .= fread($inputStream, 2);
 88331 
 88332 
 88333 if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
 88334 if ('A' === $c[2] && -1 === $ofs) {
 88335 $ofs = 0;
 88336 }
 88337 
 88338 if (0 === $numMatches) {
 88339 continue;
 88340 }
 88341 
 88342 $ofs += ('A' === $c[2]) ? -1 : 1;
 88343 $ofs = ($numMatches + $ofs) % $numMatches;
 88344 }
 88345 } elseif (\ord($c) < 32) {
 88346 if ("\t" === $c || "\n" === $c) {
 88347 if ($numMatches > 0 && -1 !== $ofs) {
 88348 $ret = $matches[$ofs];
 88349 
 88350 $output->write(substr($ret, $i));
 88351 $i = \strlen($ret);
 88352 }
 88353 
 88354 if ("\n" === $c) {
 88355 $output->write($c);
 88356 break;
 88357 }
 88358 
 88359 $numMatches = 0;
 88360 }
 88361 
 88362 continue;
 88363 } else {
 88364 $output->write($c);
 88365 $ret .= $c;
 88366 ++$i;
 88367 
 88368 $numMatches = 0;
 88369 $ofs = 0;
 88370 
 88371 foreach ($autocomplete as $value) {
 88372 
 88373 if (0 === strpos($value, $ret) && $i !== \strlen($value)) {
 88374 $matches[$numMatches++] = $value;
 88375 }
 88376 }
 88377 }
 88378 
 88379 
 88380 $output->write("\033[K");
 88381 
 88382 if ($numMatches > 0 && -1 !== $ofs) {
 88383 
 88384 $output->write("\0337");
 88385 
 88386 $output->write('<hl>'.substr($matches[$ofs], $i).'</hl>');
 88387 
 88388 $output->write("\0338");
 88389 }
 88390 }
 88391 
 88392 
 88393 shell_exec(sprintf('stty %s', $sttyMode));
 88394 }
 88395 
 88396 return \strlen($ret) > 0 ? $ret : $default;
 88397 }
 88398 
 88399 
 88400 
 88401 
 88402 
 88403 
 88404 
 88405 
 88406 
 88407 
 88408 
 88409 
 88410 public function askConfirmation(OutputInterface $output, $question, $default = true)
 88411 {
 88412 $answer = 'z';
 88413 while ($answer && !\in_array(strtolower($answer[0]), array('y', 'n'))) {
 88414 $answer = $this->ask($output, $question);
 88415 }
 88416 
 88417 if (false === $default) {
 88418 return $answer && 'y' == strtolower($answer[0]);
 88419 }
 88420 
 88421 return !$answer || 'y' == strtolower($answer[0]);
 88422 }
 88423 
 88424 
 88425 
 88426 
 88427 
 88428 
 88429 
 88430 
 88431 
 88432 
 88433 
 88434 
 88435 public function askHiddenResponse(OutputInterface $output, $question, $fallback = true)
 88436 {
 88437 if ($output instanceof ConsoleOutputInterface) {
 88438 $output = $output->getErrorOutput();
 88439 }
 88440 
 88441 if ('\\' === \DIRECTORY_SEPARATOR) {
 88442 $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
 88443 
 88444 
 88445 if ('phar:' === substr(__FILE__, 0, 5)) {
 88446 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
 88447 copy($exe, $tmpExe);
 88448 $exe = $tmpExe;
 88449 }
 88450 
 88451 $output->write($question);
 88452 $value = rtrim(shell_exec($exe));
 88453 $output->writeln('');
 88454 
 88455 if (isset($tmpExe)) {
 88456 unlink($tmpExe);
 88457 }
 88458 
 88459 return $value;
 88460 }
 88461 
 88462 if ($this->hasSttyAvailable()) {
 88463 $output->write($question);
 88464 
 88465 $sttyMode = shell_exec('stty -g');
 88466 
 88467 shell_exec('stty -echo');
 88468 $value = fgets($this->inputStream ?: STDIN, 4096);
 88469 shell_exec(sprintf('stty %s', $sttyMode));
 88470 
 88471 if (false === $value) {
 88472 throw new RuntimeException('Aborted');
 88473 }
 88474 
 88475 $value = trim($value);
 88476 $output->writeln('');
 88477 
 88478 return $value;
 88479 }
 88480 
 88481 if (false !== $shell = $this->getShell()) {
 88482 $output->write($question);
 88483 $readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
 88484 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
 88485 $value = rtrim(shell_exec($command));
 88486 $output->writeln('');
 88487 
 88488 return $value;
 88489 }
 88490 
 88491 if ($fallback) {
 88492 return $this->ask($output, $question);
 88493 }
 88494 
 88495 throw new RuntimeException('Unable to hide the response');
 88496 }
 88497 
 88498 
 88499 
 88500 
 88501 
 88502 
 88503 
 88504 
 88505 
 88506 
 88507 
 88508 
 88509 
 88510 
 88511 
 88512 
 88513 
 88514 
 88515 
 88516 public function askAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $default = null, array $autocomplete = null)
 88517 {
 88518 $that = $this;
 88519 
 88520 $interviewer = function () use ($output, $question, $default, $autocomplete, $that) {
 88521 return $that->ask($output, $question, $default, $autocomplete);
 88522 };
 88523 
 88524 return $this->validateAttempts($interviewer, $output, $validator, $attempts);
 88525 }
 88526 
 88527 
 88528 
 88529 
 88530 
 88531 
 88532 
 88533 
 88534 
 88535 
 88536 
 88537 
 88538 
 88539 
 88540 
 88541 
 88542 
 88543 
 88544 
 88545 public function askHiddenResponseAndValidate(OutputInterface $output, $question, $validator, $attempts = false, $fallback = true)
 88546 {
 88547 $that = $this;
 88548 
 88549 $interviewer = function () use ($output, $question, $fallback, $that) {
 88550 return $that->askHiddenResponse($output, $question, $fallback);
 88551 };
 88552 
 88553 return $this->validateAttempts($interviewer, $output, $validator, $attempts);
 88554 }
 88555 
 88556 
 88557 
 88558 
 88559 
 88560 
 88561 
 88562 
 88563 public function setInputStream($stream)
 88564 {
 88565 $this->inputStream = $stream;
 88566 }
 88567 
 88568 
 88569 
 88570 
 88571 
 88572 
 88573 public function getInputStream()
 88574 {
 88575 return $this->inputStream;
 88576 }
 88577 
 88578 
 88579 
 88580 
 88581 public function getName()
 88582 {
 88583 return 'dialog';
 88584 }
 88585 
 88586 
 88587 
 88588 
 88589 
 88590 
 88591 private function getShell()
 88592 {
 88593 if (null !== self::$shell) {
 88594 return self::$shell;
 88595 }
 88596 
 88597 self::$shell = false;
 88598 
 88599 if (file_exists('/usr/bin/env')) {
 88600 
 88601 $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
 88602 foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
 88603 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
 88604 self::$shell = $sh;
 88605 break;
 88606 }
 88607 }
 88608 }
 88609 
 88610 return self::$shell;
 88611 }
 88612 
 88613 private function hasSttyAvailable()
 88614 {
 88615 if (null !== self::$stty) {
 88616 return self::$stty;
 88617 }
 88618 
 88619 exec('stty 2>&1', $output, $exitcode);
 88620 
 88621 return self::$stty = 0 === $exitcode;
 88622 }
 88623 
 88624 
 88625 
 88626 
 88627 
 88628 
 88629 
 88630 
 88631 
 88632 
 88633 
 88634 
 88635 
 88636 private function validateAttempts($interviewer, OutputInterface $output, $validator, $attempts)
 88637 {
 88638 if ($output instanceof ConsoleOutputInterface) {
 88639 $output = $output->getErrorOutput();
 88640 }
 88641 
 88642 $e = null;
 88643 while (false === $attempts || $attempts--) {
 88644 if (null !== $e) {
 88645 $output->writeln($this->getHelperSet()->get('formatter')->formatBlock($e->getMessage(), 'error'));
 88646 }
 88647 
 88648 try {
 88649 return \call_user_func($validator, $interviewer());
 88650 } catch (\Exception $e) {
 88651 }
 88652 }
 88653 
 88654 throw $e;
 88655 }
 88656 }
 88657 <?php
 88658 
 88659 
 88660 
 88661 
 88662 
 88663 
 88664 
 88665 
 88666 
 88667 
 88668 namespace Symfony\Component\Console\Helper;
 88669 
 88670 use Symfony\Component\Console\Formatter\OutputFormatter;
 88671 
 88672 
 88673 
 88674 
 88675 
 88676 
 88677 class FormatterHelper extends Helper
 88678 {
 88679 
 88680 
 88681 
 88682 
 88683 
 88684 
 88685 
 88686 
 88687 
 88688 public function formatSection($section, $message, $style = 'info')
 88689 {
 88690 return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
 88691 }
 88692 
 88693 
 88694 
 88695 
 88696 
 88697 
 88698 
 88699 
 88700 
 88701 
 88702 public function formatBlock($messages, $style, $large = false)
 88703 {
 88704 if (!\is_array($messages)) {
 88705 $messages = array($messages);
 88706 }
 88707 
 88708 $len = 0;
 88709 $lines = array();
 88710 foreach ($messages as $message) {
 88711 $message = OutputFormatter::escape($message);
 88712 $lines[] = sprintf($large ? '  %s  ' : ' %s ', $message);
 88713 $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
 88714 }
 88715 
 88716 $messages = $large ? array(str_repeat(' ', $len)) : array();
 88717 for ($i = 0; isset($lines[$i]); ++$i) {
 88718 $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
 88719 }
 88720 if ($large) {
 88721 $messages[] = str_repeat(' ', $len);
 88722 }
 88723 
 88724 for ($i = 0; isset($messages[$i]); ++$i) {
 88725 $messages[$i] = sprintf('<%s>%s</%s>', $style, $messages[$i], $style);
 88726 }
 88727 
 88728 return implode("\n", $messages);
 88729 }
 88730 
 88731 
 88732 
 88733 
 88734 public function getName()
 88735 {
 88736 return 'formatter';
 88737 }
 88738 }
 88739 <?php
 88740 
 88741 
 88742 
 88743 
 88744 
 88745 
 88746 
 88747 
 88748 
 88749 
 88750 namespace Symfony\Component\Console\Helper;
 88751 
 88752 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 88753 
 88754 
 88755 
 88756 
 88757 
 88758 
 88759 abstract class Helper implements HelperInterface
 88760 {
 88761 protected $helperSet = null;
 88762 
 88763 
 88764 
 88765 
 88766 public function setHelperSet(HelperSet $helperSet = null)
 88767 {
 88768 $this->helperSet = $helperSet;
 88769 }
 88770 
 88771 
 88772 
 88773 
 88774 public function getHelperSet()
 88775 {
 88776 return $this->helperSet;
 88777 }
 88778 
 88779 
 88780 
 88781 
 88782 
 88783 
 88784 
 88785 
 88786 public static function strlen($string)
 88787 {
 88788 if (false === $encoding = mb_detect_encoding($string, null, true)) {
 88789 return \strlen($string);
 88790 }
 88791 
 88792 return mb_strwidth($string, $encoding);
 88793 }
 88794 
 88795 public static function formatTime($secs)
 88796 {
 88797 static $timeFormats = array(
 88798 array(0, '< 1 sec'),
 88799 array(1, '1 sec'),
 88800 array(2, 'secs', 1),
 88801 array(60, '1 min'),
 88802 array(120, 'mins', 60),
 88803 array(3600, '1 hr'),
 88804 array(7200, 'hrs', 3600),
 88805 array(86400, '1 day'),
 88806 array(172800, 'days', 86400),
 88807 );
 88808 
 88809 foreach ($timeFormats as $index => $format) {
 88810 if ($secs >= $format[0]) {
 88811 if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
 88812 || $index == \count($timeFormats) - 1
 88813 ) {
 88814 if (2 == \count($format)) {
 88815 return $format[1];
 88816 }
 88817 
 88818 return floor($secs / $format[2]).' '.$format[1];
 88819 }
 88820 }
 88821 }
 88822 }
 88823 
 88824 public static function formatMemory($memory)
 88825 {
 88826 if ($memory >= 1024 * 1024 * 1024) {
 88827 return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
 88828 }
 88829 
 88830 if ($memory >= 1024 * 1024) {
 88831 return sprintf('%.1f MiB', $memory / 1024 / 1024);
 88832 }
 88833 
 88834 if ($memory >= 1024) {
 88835 return sprintf('%d KiB', $memory / 1024);
 88836 }
 88837 
 88838 return sprintf('%d B', $memory);
 88839 }
 88840 
 88841 public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string)
 88842 {
 88843 return self::strlen(self::removeDecoration($formatter, $string));
 88844 }
 88845 
 88846 public static function removeDecoration(OutputFormatterInterface $formatter, $string)
 88847 {
 88848 $isDecorated = $formatter->isDecorated();
 88849 $formatter->setDecorated(false);
 88850 
 88851 $string = $formatter->format($string);
 88852 
 88853 $string = preg_replace("/\033\[[^m]*m/", '', $string);
 88854 $formatter->setDecorated($isDecorated);
 88855 
 88856 return $string;
 88857 }
 88858 }
 88859 <?php
 88860 
 88861 
 88862 
 88863 
 88864 
 88865 
 88866 
 88867 
 88868 
 88869 
 88870 namespace Symfony\Component\Console\Helper;
 88871 
 88872 
 88873 
 88874 
 88875 
 88876 
 88877 interface HelperInterface
 88878 {
 88879 
 88880 
 88881 
 88882 public function setHelperSet(HelperSet $helperSet = null);
 88883 
 88884 
 88885 
 88886 
 88887 
 88888 
 88889 public function getHelperSet();
 88890 
 88891 
 88892 
 88893 
 88894 
 88895 
 88896 public function getName();
 88897 }
 88898 <?php
 88899 
 88900 
 88901 
 88902 
 88903 
 88904 
 88905 
 88906 
 88907 
 88908 
 88909 namespace Symfony\Component\Console\Helper;
 88910 
 88911 use Symfony\Component\Console\Command\Command;
 88912 use Symfony\Component\Console\Exception\InvalidArgumentException;
 88913 
 88914 
 88915 
 88916 
 88917 
 88918 
 88919 class HelperSet implements \IteratorAggregate
 88920 {
 88921 
 88922 
 88923 
 88924 private $helpers = array();
 88925 private $command;
 88926 
 88927 
 88928 
 88929 
 88930 public function __construct(array $helpers = array())
 88931 {
 88932 foreach ($helpers as $alias => $helper) {
 88933 $this->set($helper, \is_int($alias) ? null : $alias);
 88934 }
 88935 }
 88936 
 88937 
 88938 
 88939 
 88940 
 88941 
 88942 
 88943 public function set(HelperInterface $helper, $alias = null)
 88944 {
 88945 $this->helpers[$helper->getName()] = $helper;
 88946 if (null !== $alias) {
 88947 $this->helpers[$alias] = $helper;
 88948 }
 88949 
 88950 $helper->setHelperSet($this);
 88951 }
 88952 
 88953 
 88954 
 88955 
 88956 
 88957 
 88958 
 88959 
 88960 public function has($name)
 88961 {
 88962 return isset($this->helpers[$name]);
 88963 }
 88964 
 88965 
 88966 
 88967 
 88968 
 88969 
 88970 
 88971 
 88972 
 88973 
 88974 public function get($name)
 88975 {
 88976 if (!$this->has($name)) {
 88977 throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
 88978 }
 88979 
 88980 if ('dialog' === $name && $this->helpers[$name] instanceof DialogHelper) {
 88981 @trigger_error('"Symfony\Component\Console\Helper\DialogHelper" is deprecated since Symfony 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\QuestionHelper" instead.', E_USER_DEPRECATED);
 88982 } elseif ('progress' === $name && $this->helpers[$name] instanceof ProgressHelper) {
 88983 @trigger_error('"Symfony\Component\Console\Helper\ProgressHelper" is deprecated since Symfony 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\ProgressBar" instead.', E_USER_DEPRECATED);
 88984 } elseif ('table' === $name && $this->helpers[$name] instanceof TableHelper) {
 88985 @trigger_error('"Symfony\Component\Console\Helper\TableHelper" is deprecated since Symfony 2.5 and will be removed in 3.0. Use "Symfony\Component\Console\Helper\Table" instead.', E_USER_DEPRECATED);
 88986 }
 88987 
 88988 return $this->helpers[$name];
 88989 }
 88990 
 88991 public function setCommand(Command $command = null)
 88992 {
 88993 $this->command = $command;
 88994 }
 88995 
 88996 
 88997 
 88998 
 88999 
 89000 
 89001 public function getCommand()
 89002 {
 89003 return $this->command;
 89004 }
 89005 
 89006 
 89007 
 89008 
 89009 public function getIterator()
 89010 {
 89011 return new \ArrayIterator($this->helpers);
 89012 }
 89013 }
 89014 <?php
 89015 
 89016 
 89017 
 89018 
 89019 
 89020 
 89021 
 89022 
 89023 
 89024 
 89025 namespace Symfony\Component\Console\Helper;
 89026 
 89027 use Symfony\Component\Console\Input\InputAwareInterface;
 89028 use Symfony\Component\Console\Input\InputInterface;
 89029 
 89030 
 89031 
 89032 
 89033 
 89034 
 89035 abstract class InputAwareHelper extends Helper implements InputAwareInterface
 89036 {
 89037 protected $input;
 89038 
 89039 
 89040 
 89041 
 89042 public function setInput(InputInterface $input)
 89043 {
 89044 $this->input = $input;
 89045 }
 89046 }
 89047 <?php
 89048 
 89049 
 89050 
 89051 
 89052 
 89053 
 89054 
 89055 
 89056 
 89057 
 89058 namespace Symfony\Component\Console\Helper;
 89059 
 89060 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 89061 use Symfony\Component\Console\Output\OutputInterface;
 89062 use Symfony\Component\Process\Exception\ProcessFailedException;
 89063 use Symfony\Component\Process\Process;
 89064 use Symfony\Component\Process\ProcessBuilder;
 89065 
 89066 
 89067 
 89068 
 89069 
 89070 
 89071 class ProcessHelper extends Helper
 89072 {
 89073 
 89074 
 89075 
 89076 
 89077 
 89078 
 89079 
 89080 
 89081 
 89082 
 89083 
 89084 
 89085 public function run(OutputInterface $output, $cmd, $error = null, $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE)
 89086 {
 89087 if ($output instanceof ConsoleOutputInterface) {
 89088 $output = $output->getErrorOutput();
 89089 }
 89090 
 89091 $formatter = $this->getHelperSet()->get('debug_formatter');
 89092 
 89093 if (\is_array($cmd)) {
 89094 $process = ProcessBuilder::create($cmd)->getProcess();
 89095 } elseif ($cmd instanceof Process) {
 89096 $process = $cmd;
 89097 } else {
 89098 $process = new Process($cmd);
 89099 }
 89100 
 89101 if ($verbosity <= $output->getVerbosity()) {
 89102 $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine())));
 89103 }
 89104 
 89105 if ($output->isDebug()) {
 89106 $callback = $this->wrapCallback($output, $process, $callback);
 89107 }
 89108 
 89109 $process->run($callback);
 89110 
 89111 if ($verbosity <= $output->getVerbosity()) {
 89112 $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
 89113 $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
 89114 }
 89115 
 89116 if (!$process->isSuccessful() && null !== $error) {
 89117 $output->writeln(sprintf('<error>%s</error>', $this->escapeString($error)));
 89118 }
 89119 
 89120 return $process;
 89121 }
 89122 
 89123 
 89124 
 89125 
 89126 
 89127 
 89128 
 89129 
 89130 
 89131 
 89132 
 89133 
 89134 
 89135 
 89136 
 89137 
 89138 
 89139 
 89140 
 89141 public function mustRun(OutputInterface $output, $cmd, $error = null, $callback = null)
 89142 {
 89143 $process = $this->run($output, $cmd, $error, $callback);
 89144 
 89145 if (!$process->isSuccessful()) {
 89146 throw new ProcessFailedException($process);
 89147 }
 89148 
 89149 return $process;
 89150 }
 89151 
 89152 
 89153 
 89154 
 89155 
 89156 
 89157 
 89158 
 89159 
 89160 
 89161 public function wrapCallback(OutputInterface $output, Process $process, $callback = null)
 89162 {
 89163 if ($output instanceof ConsoleOutputInterface) {
 89164 $output = $output->getErrorOutput();
 89165 }
 89166 
 89167 $formatter = $this->getHelperSet()->get('debug_formatter');
 89168 
 89169 $that = $this;
 89170 
 89171 return function ($type, $buffer) use ($output, $process, $callback, $formatter, $that) {
 89172 $output->write($formatter->progress(spl_object_hash($process), $that->escapeString($buffer), Process::ERR === $type));
 89173 
 89174 if (null !== $callback) {
 89175 \call_user_func($callback, $type, $buffer);
 89176 }
 89177 };
 89178 }
 89179 
 89180 
 89181 
 89182 
 89183 
 89184 
 89185 public function escapeString($str)
 89186 {
 89187 return str_replace('<', '\\<', $str);
 89188 }
 89189 
 89190 
 89191 
 89192 
 89193 public function getName()
 89194 {
 89195 return 'process';
 89196 }
 89197 }
 89198 <?php
 89199 
 89200 
 89201 
 89202 
 89203 
 89204 
 89205 
 89206 
 89207 
 89208 
 89209 namespace Symfony\Component\Console\Helper;
 89210 
 89211 use Symfony\Component\Console\Exception\LogicException;
 89212 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 89213 use Symfony\Component\Console\Output\OutputInterface;
 89214 
 89215 
 89216 
 89217 
 89218 
 89219 
 89220 
 89221 class ProgressBar
 89222 {
 89223 private $barWidth = 28;
 89224 private $barChar;
 89225 private $emptyBarChar = '-';
 89226 private $progressChar = '>';
 89227 private $format;
 89228 private $internalFormat;
 89229 private $redrawFreq = 1;
 89230 private $output;
 89231 private $step = 0;
 89232 private $max;
 89233 private $startTime;
 89234 private $stepWidth;
 89235 private $percent = 0.0;
 89236 private $formatLineCount;
 89237 private $messages = array();
 89238 private $overwrite = true;
 89239 private $firstRun = true;
 89240 
 89241 private static $formatters;
 89242 private static $formats;
 89243 
 89244 
 89245 
 89246 
 89247 
 89248 public function __construct(OutputInterface $output, $max = 0)
 89249 {
 89250 if ($output instanceof ConsoleOutputInterface) {
 89251 $output = $output->getErrorOutput();
 89252 }
 89253 
 89254 $this->output = $output;
 89255 $this->setMaxSteps($max);
 89256 
 89257 if (!$this->output->isDecorated()) {
 89258 
 89259 $this->overwrite = false;
 89260 
 89261 
 89262 $this->setRedrawFrequency($max / 10);
 89263 }
 89264 
 89265 $this->startTime = time();
 89266 }
 89267 
 89268 
 89269 
 89270 
 89271 
 89272 
 89273 
 89274 
 89275 
 89276 public static function setPlaceholderFormatterDefinition($name, $callable)
 89277 {
 89278 if (!self::$formatters) {
 89279 self::$formatters = self::initPlaceholderFormatters();
 89280 }
 89281 
 89282 self::$formatters[$name] = $callable;
 89283 }
 89284 
 89285 
 89286 
 89287 
 89288 
 89289 
 89290 
 89291 
 89292 public static function getPlaceholderFormatterDefinition($name)
 89293 {
 89294 if (!self::$formatters) {
 89295 self::$formatters = self::initPlaceholderFormatters();
 89296 }
 89297 
 89298 return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
 89299 }
 89300 
 89301 
 89302 
 89303 
 89304 
 89305 
 89306 
 89307 
 89308 
 89309 public static function setFormatDefinition($name, $format)
 89310 {
 89311 if (!self::$formats) {
 89312 self::$formats = self::initFormats();
 89313 }
 89314 
 89315 self::$formats[$name] = $format;
 89316 }
 89317 
 89318 
 89319 
 89320 
 89321 
 89322 
 89323 
 89324 
 89325 public static function getFormatDefinition($name)
 89326 {
 89327 if (!self::$formats) {
 89328 self::$formats = self::initFormats();
 89329 }
 89330 
 89331 return isset(self::$formats[$name]) ? self::$formats[$name] : null;
 89332 }
 89333 
 89334 
 89335 
 89336 
 89337 
 89338 
 89339 
 89340 
 89341 
 89342 
 89343 
 89344 public function setMessage($message, $name = 'message')
 89345 {
 89346 $this->messages[$name] = $message;
 89347 }
 89348 
 89349 public function getMessage($name = 'message')
 89350 {
 89351 return $this->messages[$name];
 89352 }
 89353 
 89354 
 89355 
 89356 
 89357 
 89358 
 89359 public function getStartTime()
 89360 {
 89361 return $this->startTime;
 89362 }
 89363 
 89364 
 89365 
 89366 
 89367 
 89368 
 89369 public function getMaxSteps()
 89370 {
 89371 return $this->max;
 89372 }
 89373 
 89374 
 89375 
 89376 
 89377 
 89378 
 89379 
 89380 
 89381 public function getStep()
 89382 {
 89383 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the getProgress() method instead.', E_USER_DEPRECATED);
 89384 
 89385 return $this->getProgress();
 89386 }
 89387 
 89388 
 89389 
 89390 
 89391 
 89392 
 89393 public function getProgress()
 89394 {
 89395 return $this->step;
 89396 }
 89397 
 89398 
 89399 
 89400 
 89401 
 89402 
 89403 
 89404 
 89405 public function getStepWidth()
 89406 {
 89407 return $this->stepWidth;
 89408 }
 89409 
 89410 
 89411 
 89412 
 89413 
 89414 
 89415 public function getProgressPercent()
 89416 {
 89417 return $this->percent;
 89418 }
 89419 
 89420 
 89421 
 89422 
 89423 
 89424 
 89425 public function setBarWidth($size)
 89426 {
 89427 $this->barWidth = (int) $size;
 89428 }
 89429 
 89430 
 89431 
 89432 
 89433 
 89434 
 89435 public function getBarWidth()
 89436 {
 89437 return $this->barWidth;
 89438 }
 89439 
 89440 
 89441 
 89442 
 89443 
 89444 
 89445 public function setBarCharacter($char)
 89446 {
 89447 $this->barChar = $char;
 89448 }
 89449 
 89450 
 89451 
 89452 
 89453 
 89454 
 89455 public function getBarCharacter()
 89456 {
 89457 if (null === $this->barChar) {
 89458 return $this->max ? '=' : $this->emptyBarChar;
 89459 }
 89460 
 89461 return $this->barChar;
 89462 }
 89463 
 89464 
 89465 
 89466 
 89467 
 89468 
 89469 public function setEmptyBarCharacter($char)
 89470 {
 89471 $this->emptyBarChar = $char;
 89472 }
 89473 
 89474 
 89475 
 89476 
 89477 
 89478 
 89479 public function getEmptyBarCharacter()
 89480 {
 89481 return $this->emptyBarChar;
 89482 }
 89483 
 89484 
 89485 
 89486 
 89487 
 89488 
 89489 public function setProgressCharacter($char)
 89490 {
 89491 $this->progressChar = $char;
 89492 }
 89493 
 89494 
 89495 
 89496 
 89497 
 89498 
 89499 public function getProgressCharacter()
 89500 {
 89501 return $this->progressChar;
 89502 }
 89503 
 89504 
 89505 
 89506 
 89507 
 89508 
 89509 public function setFormat($format)
 89510 {
 89511 $this->format = null;
 89512 $this->internalFormat = $format;
 89513 }
 89514 
 89515 
 89516 
 89517 
 89518 
 89519 
 89520 public function setRedrawFrequency($freq)
 89521 {
 89522 $this->redrawFreq = max((int) $freq, 1);
 89523 }
 89524 
 89525 
 89526 
 89527 
 89528 
 89529 
 89530 public function start($max = null)
 89531 {
 89532 $this->startTime = time();
 89533 $this->step = 0;
 89534 $this->percent = 0.0;
 89535 
 89536 if (null !== $max) {
 89537 $this->setMaxSteps($max);
 89538 }
 89539 
 89540 $this->display();
 89541 }
 89542 
 89543 
 89544 
 89545 
 89546 
 89547 
 89548 
 89549 
 89550 public function advance($step = 1)
 89551 {
 89552 $this->setProgress($this->step + $step);
 89553 }
 89554 
 89555 
 89556 
 89557 
 89558 
 89559 
 89560 
 89561 
 89562 
 89563 
 89564 public function setCurrent($step)
 89565 {
 89566 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the setProgress() method instead.', E_USER_DEPRECATED);
 89567 
 89568 $this->setProgress($step);
 89569 }
 89570 
 89571 
 89572 
 89573 
 89574 
 89575 
 89576 public function setOverwrite($overwrite)
 89577 {
 89578 $this->overwrite = (bool) $overwrite;
 89579 }
 89580 
 89581 
 89582 
 89583 
 89584 
 89585 
 89586 
 89587 
 89588 public function setProgress($step)
 89589 {
 89590 $step = (int) $step;
 89591 if ($step < $this->step) {
 89592 throw new LogicException('You can\'t regress the progress bar.');
 89593 }
 89594 
 89595 if ($this->max && $step > $this->max) {
 89596 $this->max = $step;
 89597 }
 89598 
 89599 $prevPeriod = (int) ($this->step / $this->redrawFreq);
 89600 $currPeriod = (int) ($step / $this->redrawFreq);
 89601 $this->step = $step;
 89602 $this->percent = $this->max ? (float) $this->step / $this->max : 0;
 89603 if ($prevPeriod !== $currPeriod || $this->max === $step) {
 89604 $this->display();
 89605 }
 89606 }
 89607 
 89608 
 89609 
 89610 
 89611 public function finish()
 89612 {
 89613 if (!$this->max) {
 89614 $this->max = $this->step;
 89615 }
 89616 
 89617 if ($this->step === $this->max && !$this->overwrite) {
 89618 
 89619 return;
 89620 }
 89621 
 89622 $this->setProgress($this->max);
 89623 }
 89624 
 89625 
 89626 
 89627 
 89628 public function display()
 89629 {
 89630 if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
 89631 return;
 89632 }
 89633 
 89634 if (null === $this->format) {
 89635 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
 89636 }
 89637 
 89638 
 89639 $self = $this;
 89640 $output = $this->output;
 89641 $messages = $this->messages;
 89642 $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self, $output, $messages) {
 89643 if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
 89644 $text = \call_user_func($formatter, $self, $output);
 89645 } elseif (isset($messages[$matches[1]])) {
 89646 $text = $messages[$matches[1]];
 89647 } else {
 89648 return $matches[0];
 89649 }
 89650 
 89651 if (isset($matches[2])) {
 89652 $text = sprintf('%'.$matches[2], $text);
 89653 }
 89654 
 89655 return $text;
 89656 }, $this->format));
 89657 }
 89658 
 89659 
 89660 
 89661 
 89662 
 89663 
 89664 
 89665 
 89666 public function clear()
 89667 {
 89668 if (!$this->overwrite) {
 89669 return;
 89670 }
 89671 
 89672 if (null === $this->format) {
 89673 $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
 89674 }
 89675 
 89676 $this->overwrite('');
 89677 }
 89678 
 89679 
 89680 
 89681 
 89682 
 89683 
 89684 private function setRealFormat($format)
 89685 {
 89686 
 89687 if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
 89688 $this->format = self::getFormatDefinition($format.'_nomax');
 89689 } elseif (null !== self::getFormatDefinition($format)) {
 89690 $this->format = self::getFormatDefinition($format);
 89691 } else {
 89692 $this->format = $format;
 89693 }
 89694 
 89695 $this->formatLineCount = substr_count($this->format, "\n");
 89696 }
 89697 
 89698 
 89699 
 89700 
 89701 
 89702 
 89703 private function setMaxSteps($max)
 89704 {
 89705 $this->max = max(0, (int) $max);
 89706 $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
 89707 }
 89708 
 89709 
 89710 
 89711 
 89712 
 89713 
 89714 private function overwrite($message)
 89715 {
 89716 if ($this->overwrite) {
 89717 if (!$this->firstRun) {
 89718 
 89719 $this->output->write("\x0D");
 89720 
 89721 
 89722 $this->output->write("\x1B[2K");
 89723 
 89724 
 89725 if ($this->formatLineCount > 0) {
 89726 $this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
 89727 }
 89728 }
 89729 } elseif ($this->step > 0) {
 89730 $this->output->writeln('');
 89731 }
 89732 
 89733 $this->firstRun = false;
 89734 
 89735 $this->output->write($message);
 89736 }
 89737 
 89738 private function determineBestFormat()
 89739 {
 89740 switch ($this->output->getVerbosity()) {
 89741 
 89742 case OutputInterface::VERBOSITY_VERBOSE:
 89743 return $this->max ? 'verbose' : 'verbose_nomax';
 89744 case OutputInterface::VERBOSITY_VERY_VERBOSE:
 89745 return $this->max ? 'very_verbose' : 'very_verbose_nomax';
 89746 case OutputInterface::VERBOSITY_DEBUG:
 89747 return $this->max ? 'debug' : 'debug_nomax';
 89748 default:
 89749 return $this->max ? 'normal' : 'normal_nomax';
 89750 }
 89751 }
 89752 
 89753 private static function initPlaceholderFormatters()
 89754 {
 89755 return array(
 89756 'bar' => function (ProgressBar $bar, OutputInterface $output) {
 89757 $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
 89758 $display = str_repeat($bar->getBarCharacter(), $completeBars);
 89759 if ($completeBars < $bar->getBarWidth()) {
 89760 $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
 89761 $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
 89762 }
 89763 
 89764 return $display;
 89765 },
 89766 'elapsed' => function (ProgressBar $bar) {
 89767 return Helper::formatTime(time() - $bar->getStartTime());
 89768 },
 89769 'remaining' => function (ProgressBar $bar) {
 89770 if (!$bar->getMaxSteps()) {
 89771 throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
 89772 }
 89773 
 89774 if (!$bar->getProgress()) {
 89775 $remaining = 0;
 89776 } else {
 89777 $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
 89778 }
 89779 
 89780 return Helper::formatTime($remaining);
 89781 },
 89782 'estimated' => function (ProgressBar $bar) {
 89783 if (!$bar->getMaxSteps()) {
 89784 throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
 89785 }
 89786 
 89787 if (!$bar->getProgress()) {
 89788 $estimated = 0;
 89789 } else {
 89790 $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
 89791 }
 89792 
 89793 return Helper::formatTime($estimated);
 89794 },
 89795 'memory' => function (ProgressBar $bar) {
 89796 return Helper::formatMemory(memory_get_usage(true));
 89797 },
 89798 'current' => function (ProgressBar $bar) {
 89799 return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
 89800 },
 89801 'max' => function (ProgressBar $bar) {
 89802 return $bar->getMaxSteps();
 89803 },
 89804 'percent' => function (ProgressBar $bar) {
 89805 return floor($bar->getProgressPercent() * 100);
 89806 },
 89807 );
 89808 }
 89809 
 89810 private static function initFormats()
 89811 {
 89812 return array(
 89813 'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
 89814 'normal_nomax' => ' %current% [%bar%]',
 89815 
 89816 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
 89817 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
 89818 
 89819 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
 89820 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
 89821 
 89822 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
 89823 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
 89824 );
 89825 }
 89826 }
 89827 <?php
 89828 
 89829 
 89830 
 89831 
 89832 
 89833 
 89834 
 89835 
 89836 
 89837 
 89838 namespace Symfony\Component\Console\Helper;
 89839 
 89840 use Symfony\Component\Console\Exception\LogicException;
 89841 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 89842 use Symfony\Component\Console\Output\NullOutput;
 89843 use Symfony\Component\Console\Output\OutputInterface;
 89844 
 89845 
 89846 
 89847 
 89848 
 89849 
 89850 
 89851 
 89852 
 89853 
 89854 class ProgressHelper extends Helper
 89855 {
 89856 const FORMAT_QUIET = ' %percent%%';
 89857 const FORMAT_NORMAL = ' %current%/%max% [%bar%] %percent%%';
 89858 const FORMAT_VERBOSE = ' %current%/%max% [%bar%] %percent%% Elapsed: %elapsed%';
 89859 const FORMAT_QUIET_NOMAX = ' %current%';
 89860 const FORMAT_NORMAL_NOMAX = ' %current% [%bar%]';
 89861 const FORMAT_VERBOSE_NOMAX = ' %current% [%bar%] Elapsed: %elapsed%';
 89862 
 89863 
 89864 private $barWidth = 28;
 89865 private $barChar = '=';
 89866 private $emptyBarChar = '-';
 89867 private $progressChar = '>';
 89868 private $format = null;
 89869 private $redrawFreq = 1;
 89870 
 89871 private $lastMessagesLength;
 89872 private $barCharOriginal;
 89873 
 89874 
 89875 
 89876 
 89877 private $output;
 89878 
 89879 
 89880 
 89881 
 89882 
 89883 
 89884 private $current;
 89885 
 89886 
 89887 
 89888 
 89889 
 89890 
 89891 private $max;
 89892 
 89893 
 89894 
 89895 
 89896 
 89897 
 89898 private $startTime;
 89899 
 89900 
 89901 
 89902 
 89903 
 89904 
 89905 private $defaultFormatVars = array(
 89906 'current',
 89907 'max',
 89908 'bar',
 89909 'percent',
 89910 'elapsed',
 89911 );
 89912 
 89913 
 89914 
 89915 
 89916 
 89917 
 89918 private $formatVars;
 89919 
 89920 
 89921 
 89922 
 89923 
 89924 
 89925 private $widths = array(
 89926 'current' => 4,
 89927 'max' => 4,
 89928 'percent' => 3,
 89929 'elapsed' => 6,
 89930 );
 89931 
 89932 
 89933 
 89934 
 89935 
 89936 
 89937 private $timeFormats = array(
 89938 array(0, '???'),
 89939 array(2, '1 sec'),
 89940 array(59, 'secs', 1),
 89941 array(60, '1 min'),
 89942 array(3600, 'mins', 60),
 89943 array(5400, '1 hr'),
 89944 array(86400, 'hrs', 3600),
 89945 array(129600, '1 day'),
 89946 array(604800, 'days', 86400),
 89947 );
 89948 
 89949 public function __construct($triggerDeprecationError = true)
 89950 {
 89951 if ($triggerDeprecationError) {
 89952 @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\ProgressBar class instead.', E_USER_DEPRECATED);
 89953 }
 89954 }
 89955 
 89956 
 89957 
 89958 
 89959 
 89960 
 89961 public function setBarWidth($size)
 89962 {
 89963 $this->barWidth = (int) $size;
 89964 }
 89965 
 89966 
 89967 
 89968 
 89969 
 89970 
 89971 public function setBarCharacter($char)
 89972 {
 89973 $this->barChar = $char;
 89974 }
 89975 
 89976 
 89977 
 89978 
 89979 
 89980 
 89981 public function setEmptyBarCharacter($char)
 89982 {
 89983 $this->emptyBarChar = $char;
 89984 }
 89985 
 89986 
 89987 
 89988 
 89989 
 89990 
 89991 public function setProgressCharacter($char)
 89992 {
 89993 $this->progressChar = $char;
 89994 }
 89995 
 89996 
 89997 
 89998 
 89999 
 90000 
 90001 public function setFormat($format)
 90002 {
 90003 $this->format = $format;
 90004 }
 90005 
 90006 
 90007 
 90008 
 90009 
 90010 
 90011 public function setRedrawFrequency($freq)
 90012 {
 90013 $this->redrawFreq = (int) $freq;
 90014 }
 90015 
 90016 
 90017 
 90018 
 90019 
 90020 
 90021 
 90022 public function start(OutputInterface $output, $max = null)
 90023 {
 90024 if ($output instanceof ConsoleOutputInterface) {
 90025 $output = $output->getErrorOutput();
 90026 }
 90027 
 90028 $this->startTime = time();
 90029 $this->current = 0;
 90030 $this->max = (int) $max;
 90031 
 90032 
 90033 $this->output = $output->isDecorated() ? $output : new NullOutput();
 90034 $this->lastMessagesLength = 0;
 90035 $this->barCharOriginal = '';
 90036 
 90037 if (null === $this->format) {
 90038 switch ($output->getVerbosity()) {
 90039 case OutputInterface::VERBOSITY_QUIET:
 90040 $this->format = self::FORMAT_QUIET_NOMAX;
 90041 if ($this->max > 0) {
 90042 $this->format = self::FORMAT_QUIET;
 90043 }
 90044 break;
 90045 case OutputInterface::VERBOSITY_VERBOSE:
 90046 case OutputInterface::VERBOSITY_VERY_VERBOSE:
 90047 case OutputInterface::VERBOSITY_DEBUG:
 90048 $this->format = self::FORMAT_VERBOSE_NOMAX;
 90049 if ($this->max > 0) {
 90050 $this->format = self::FORMAT_VERBOSE;
 90051 }
 90052 break;
 90053 default:
 90054 $this->format = self::FORMAT_NORMAL_NOMAX;
 90055 if ($this->max > 0) {
 90056 $this->format = self::FORMAT_NORMAL;
 90057 }
 90058 break;
 90059 }
 90060 }
 90061 
 90062 $this->initialize();
 90063 }
 90064 
 90065 
 90066 
 90067 
 90068 
 90069 
 90070 
 90071 
 90072 
 90073 public function advance($step = 1, $redraw = false)
 90074 {
 90075 $this->setCurrent($this->current + $step, $redraw);
 90076 }
 90077 
 90078 
 90079 
 90080 
 90081 
 90082 
 90083 
 90084 
 90085 
 90086 public function setCurrent($current, $redraw = false)
 90087 {
 90088 if (null === $this->startTime) {
 90089 throw new LogicException('You must start the progress bar before calling setCurrent().');
 90090 }
 90091 
 90092 $current = (int) $current;
 90093 
 90094 if ($current < $this->current) {
 90095 throw new LogicException('You can\'t regress the progress bar');
 90096 }
 90097 
 90098 if (0 === $this->current) {
 90099 $redraw = true;
 90100 }
 90101 
 90102 $prevPeriod = (int) ($this->current / $this->redrawFreq);
 90103 
 90104 $this->current = $current;
 90105 
 90106 $currPeriod = (int) ($this->current / $this->redrawFreq);
 90107 if ($redraw || $prevPeriod !== $currPeriod || $this->max === $this->current) {
 90108 $this->display();
 90109 }
 90110 }
 90111 
 90112 
 90113 
 90114 
 90115 
 90116 
 90117 
 90118 
 90119 public function display($finish = false)
 90120 {
 90121 if (null === $this->startTime) {
 90122 throw new LogicException('You must start the progress bar before calling display().');
 90123 }
 90124 
 90125 $message = $this->format;
 90126 foreach ($this->generate($finish) as $name => $value) {
 90127 $message = str_replace("%{$name}%", $value, $message);
 90128 }
 90129 $this->overwrite($this->output, $message);
 90130 }
 90131 
 90132 
 90133 
 90134 
 90135 
 90136 
 90137 
 90138 
 90139 public function clear()
 90140 {
 90141 $this->overwrite($this->output, '');
 90142 }
 90143 
 90144 
 90145 
 90146 
 90147 public function finish()
 90148 {
 90149 if (null === $this->startTime) {
 90150 throw new LogicException('You must start the progress bar before calling finish().');
 90151 }
 90152 
 90153 if (null !== $this->startTime) {
 90154 if (!$this->max) {
 90155 $this->barChar = $this->barCharOriginal;
 90156 $this->display(true);
 90157 }
 90158 $this->startTime = null;
 90159 $this->output->writeln('');
 90160 $this->output = null;
 90161 }
 90162 }
 90163 
 90164 
 90165 
 90166 
 90167 private function initialize()
 90168 {
 90169 $this->formatVars = array();
 90170 foreach ($this->defaultFormatVars as $var) {
 90171 if (false !== strpos($this->format, "%{$var}%")) {
 90172 $this->formatVars[$var] = true;
 90173 }
 90174 }
 90175 
 90176 if ($this->max > 0) {
 90177 $this->widths['max'] = $this->strlen($this->max);
 90178 $this->widths['current'] = $this->widths['max'];
 90179 } else {
 90180 $this->barCharOriginal = $this->barChar;
 90181 $this->barChar = $this->emptyBarChar;
 90182 }
 90183 }
 90184 
 90185 
 90186 
 90187 
 90188 
 90189 
 90190 
 90191 
 90192 private function generate($finish = false)
 90193 {
 90194 $vars = array();
 90195 $percent = 0;
 90196 if ($this->max > 0) {
 90197 $percent = (float) $this->current / $this->max;
 90198 }
 90199 
 90200 if (isset($this->formatVars['bar'])) {
 90201 if ($this->max > 0) {
 90202 $completeBars = floor($percent * $this->barWidth);
 90203 } else {
 90204 if (!$finish) {
 90205 $completeBars = floor($this->current % $this->barWidth);
 90206 } else {
 90207 $completeBars = $this->barWidth;
 90208 }
 90209 }
 90210 
 90211 $emptyBars = $this->barWidth - $completeBars - $this->strlen($this->progressChar);
 90212 $bar = str_repeat($this->barChar, $completeBars);
 90213 if ($completeBars < $this->barWidth) {
 90214 $bar .= $this->progressChar;
 90215 $bar .= str_repeat($this->emptyBarChar, $emptyBars);
 90216 }
 90217 
 90218 $vars['bar'] = $bar;
 90219 }
 90220 
 90221 if (isset($this->formatVars['elapsed'])) {
 90222 $elapsed = time() - $this->startTime;
 90223 $vars['elapsed'] = str_pad($this->humaneTime($elapsed), $this->widths['elapsed'], ' ', STR_PAD_LEFT);
 90224 }
 90225 
 90226 if (isset($this->formatVars['current'])) {
 90227 $vars['current'] = str_pad($this->current, $this->widths['current'], ' ', STR_PAD_LEFT);
 90228 }
 90229 
 90230 if (isset($this->formatVars['max'])) {
 90231 $vars['max'] = $this->max;
 90232 }
 90233 
 90234 if (isset($this->formatVars['percent'])) {
 90235 $vars['percent'] = str_pad(floor($percent * 100), $this->widths['percent'], ' ', STR_PAD_LEFT);
 90236 }
 90237 
 90238 return $vars;
 90239 }
 90240 
 90241 
 90242 
 90243 
 90244 
 90245 
 90246 
 90247 
 90248 private function humaneTime($secs)
 90249 {
 90250 $text = '';
 90251 foreach ($this->timeFormats as $format) {
 90252 if ($secs < $format[0]) {
 90253 if (2 == \count($format)) {
 90254 $text = $format[1];
 90255 break;
 90256 } else {
 90257 $text = ceil($secs / $format[2]).' '.$format[1];
 90258 break;
 90259 }
 90260 }
 90261 }
 90262 
 90263 return $text;
 90264 }
 90265 
 90266 
 90267 
 90268 
 90269 
 90270 
 90271 
 90272 private function overwrite(OutputInterface $output, $message)
 90273 {
 90274 $length = $this->strlen($message);
 90275 
 90276 
 90277 if (null !== $this->lastMessagesLength && $this->lastMessagesLength > $length) {
 90278 $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
 90279 }
 90280 
 90281 
 90282 $output->write("\x0D");
 90283 $output->write($message);
 90284 
 90285 $this->lastMessagesLength = $this->strlen($message);
 90286 }
 90287 
 90288 
 90289 
 90290 
 90291 public function getName()
 90292 {
 90293 return 'progress';
 90294 }
 90295 }
 90296 <?php
 90297 
 90298 
 90299 
 90300 
 90301 
 90302 
 90303 
 90304 
 90305 
 90306 
 90307 namespace Symfony\Component\Console\Helper;
 90308 
 90309 use Symfony\Component\Console\Exception\InvalidArgumentException;
 90310 use Symfony\Component\Console\Exception\LogicException;
 90311 use Symfony\Component\Console\Output\OutputInterface;
 90312 
 90313 
 90314 
 90315 
 90316 class ProgressIndicator
 90317 {
 90318 private $output;
 90319 private $startTime;
 90320 private $format;
 90321 private $message;
 90322 private $indicatorValues;
 90323 private $indicatorCurrent;
 90324 private $indicatorChangeInterval;
 90325 private $indicatorUpdateTime;
 90326 private $started = false;
 90327 
 90328 private static $formatters;
 90329 private static $formats;
 90330 
 90331 
 90332 
 90333 
 90334 
 90335 
 90336 
 90337 public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
 90338 {
 90339 $this->output = $output;
 90340 
 90341 if (null === $format) {
 90342 $format = $this->determineBestFormat();
 90343 }
 90344 
 90345 if (null === $indicatorValues) {
 90346 $indicatorValues = array('-', '\\', '|', '/');
 90347 }
 90348 
 90349 $indicatorValues = array_values($indicatorValues);
 90350 
 90351 if (2 > \count($indicatorValues)) {
 90352 throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
 90353 }
 90354 
 90355 $this->format = self::getFormatDefinition($format);
 90356 $this->indicatorChangeInterval = $indicatorChangeInterval;
 90357 $this->indicatorValues = $indicatorValues;
 90358 $this->startTime = time();
 90359 }
 90360 
 90361 
 90362 
 90363 
 90364 
 90365 
 90366 public function setMessage($message)
 90367 {
 90368 $this->message = $message;
 90369 
 90370 $this->display();
 90371 }
 90372 
 90373 
 90374 
 90375 
 90376 
 90377 
 90378 
 90379 
 90380 public function getMessage()
 90381 {
 90382 return $this->message;
 90383 }
 90384 
 90385 
 90386 
 90387 
 90388 
 90389 
 90390 
 90391 
 90392 public function getStartTime()
 90393 {
 90394 return $this->startTime;
 90395 }
 90396 
 90397 
 90398 
 90399 
 90400 
 90401 
 90402 
 90403 
 90404 public function getCurrentValue()
 90405 {
 90406 return $this->indicatorValues[$this->indicatorCurrent % \count($this->indicatorValues)];
 90407 }
 90408 
 90409 
 90410 
 90411 
 90412 
 90413 
 90414 public function start($message)
 90415 {
 90416 if ($this->started) {
 90417 throw new LogicException('Progress indicator already started.');
 90418 }
 90419 
 90420 $this->message = $message;
 90421 $this->started = true;
 90422 $this->startTime = time();
 90423 $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
 90424 $this->indicatorCurrent = 0;
 90425 
 90426 $this->display();
 90427 }
 90428 
 90429 
 90430 
 90431 
 90432 public function advance()
 90433 {
 90434 if (!$this->started) {
 90435 throw new LogicException('Progress indicator has not yet been started.');
 90436 }
 90437 
 90438 if (!$this->output->isDecorated()) {
 90439 return;
 90440 }
 90441 
 90442 $currentTime = $this->getCurrentTimeInMilliseconds();
 90443 
 90444 if ($currentTime < $this->indicatorUpdateTime) {
 90445 return;
 90446 }
 90447 
 90448 $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
 90449 ++$this->indicatorCurrent;
 90450 
 90451 $this->display();
 90452 }
 90453 
 90454 
 90455 
 90456 
 90457 
 90458 
 90459 public function finish($message)
 90460 {
 90461 if (!$this->started) {
 90462 throw new LogicException('Progress indicator has not yet been started.');
 90463 }
 90464 
 90465 $this->message = $message;
 90466 $this->display();
 90467 $this->output->writeln('');
 90468 $this->started = false;
 90469 }
 90470 
 90471 
 90472 
 90473 
 90474 
 90475 
 90476 
 90477 
 90478 public static function getFormatDefinition($name)
 90479 {
 90480 if (!self::$formats) {
 90481 self::$formats = self::initFormats();
 90482 }
 90483 
 90484 return isset(self::$formats[$name]) ? self::$formats[$name] : null;
 90485 }
 90486 
 90487 
 90488 
 90489 
 90490 
 90491 
 90492 
 90493 
 90494 
 90495 public static function setPlaceholderFormatterDefinition($name, $callable)
 90496 {
 90497 if (!self::$formatters) {
 90498 self::$formatters = self::initPlaceholderFormatters();
 90499 }
 90500 
 90501 self::$formatters[$name] = $callable;
 90502 }
 90503 
 90504 
 90505 
 90506 
 90507 
 90508 
 90509 
 90510 
 90511 public static function getPlaceholderFormatterDefinition($name)
 90512 {
 90513 if (!self::$formatters) {
 90514 self::$formatters = self::initPlaceholderFormatters();
 90515 }
 90516 
 90517 return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
 90518 }
 90519 
 90520 private function display()
 90521 {
 90522 if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
 90523 return;
 90524 }
 90525 
 90526 $self = $this;
 90527 
 90528 $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
 90529 if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
 90530 return \call_user_func($formatter, $self);
 90531 }
 90532 
 90533 return $matches[0];
 90534 }, $this->format));
 90535 }
 90536 
 90537 private function determineBestFormat()
 90538 {
 90539 switch ($this->output->getVerbosity()) {
 90540 
 90541 case OutputInterface::VERBOSITY_VERBOSE:
 90542 return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
 90543 case OutputInterface::VERBOSITY_VERY_VERBOSE:
 90544 case OutputInterface::VERBOSITY_DEBUG:
 90545 return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
 90546 default:
 90547 return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
 90548 }
 90549 }
 90550 
 90551 
 90552 
 90553 
 90554 
 90555 
 90556 private function overwrite($message)
 90557 {
 90558 if ($this->output->isDecorated()) {
 90559 $this->output->write("\x0D\x1B[2K");
 90560 $this->output->write($message);
 90561 } else {
 90562 $this->output->writeln($message);
 90563 }
 90564 }
 90565 
 90566 private function getCurrentTimeInMilliseconds()
 90567 {
 90568 return round(microtime(true) * 1000);
 90569 }
 90570 
 90571 private static function initPlaceholderFormatters()
 90572 {
 90573 return array(
 90574 'indicator' => function (ProgressIndicator $indicator) {
 90575 return $indicator->getCurrentValue();
 90576 },
 90577 'message' => function (ProgressIndicator $indicator) {
 90578 return $indicator->getMessage();
 90579 },
 90580 'elapsed' => function (ProgressIndicator $indicator) {
 90581 return Helper::formatTime(time() - $indicator->getStartTime());
 90582 },
 90583 'memory' => function () {
 90584 return Helper::formatMemory(memory_get_usage(true));
 90585 },
 90586 );
 90587 }
 90588 
 90589 private static function initFormats()
 90590 {
 90591 return array(
 90592 'normal' => ' %indicator% %message%',
 90593 'normal_no_ansi' => ' %message%',
 90594 
 90595 'verbose' => ' %indicator% %message% (%elapsed:6s%)',
 90596 'verbose_no_ansi' => ' %message% (%elapsed:6s%)',
 90597 
 90598 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
 90599 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
 90600 );
 90601 }
 90602 }
 90603 <?php
 90604 
 90605 
 90606 
 90607 
 90608 
 90609 
 90610 
 90611 
 90612 
 90613 
 90614 namespace Symfony\Component\Console\Helper;
 90615 
 90616 use Symfony\Component\Console\Exception\InvalidArgumentException;
 90617 use Symfony\Component\Console\Exception\RuntimeException;
 90618 use Symfony\Component\Console\Formatter\OutputFormatter;
 90619 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
 90620 use Symfony\Component\Console\Input\InputInterface;
 90621 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 90622 use Symfony\Component\Console\Output\OutputInterface;
 90623 use Symfony\Component\Console\Question\ChoiceQuestion;
 90624 use Symfony\Component\Console\Question\Question;
 90625 
 90626 
 90627 
 90628 
 90629 
 90630 
 90631 class QuestionHelper extends Helper
 90632 {
 90633 private $inputStream;
 90634 private static $shell;
 90635 private static $stty;
 90636 
 90637 
 90638 
 90639 
 90640 
 90641 
 90642 
 90643 
 90644 public function ask(InputInterface $input, OutputInterface $output, Question $question)
 90645 {
 90646 if ($output instanceof ConsoleOutputInterface) {
 90647 $output = $output->getErrorOutput();
 90648 }
 90649 
 90650 if (!$input->isInteractive()) {
 90651 $default = $question->getDefault();
 90652 
 90653 if (null !== $default && $question instanceof ChoiceQuestion) {
 90654 $choices = $question->getChoices();
 90655 
 90656 if (!$question->isMultiselect()) {
 90657 return isset($choices[$default]) ? $choices[$default] : $default;
 90658 }
 90659 
 90660 $default = explode(',', $default);
 90661 foreach ($default as $k => $v) {
 90662 $v = trim($v);
 90663 $default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
 90664 }
 90665 }
 90666 
 90667 return $default;
 90668 }
 90669 
 90670 if (!$question->getValidator()) {
 90671 return $this->doAsk($output, $question);
 90672 }
 90673 
 90674 $that = $this;
 90675 
 90676 $interviewer = function () use ($output, $question, $that) {
 90677 return $that->doAsk($output, $question);
 90678 };
 90679 
 90680 return $this->validateAttempts($interviewer, $output, $question);
 90681 }
 90682 
 90683 
 90684 
 90685 
 90686 
 90687 
 90688 
 90689 
 90690 
 90691 
 90692 public function setInputStream($stream)
 90693 {
 90694 if (!\is_resource($stream)) {
 90695 throw new InvalidArgumentException('Input stream must be a valid resource.');
 90696 }
 90697 
 90698 $this->inputStream = $stream;
 90699 }
 90700 
 90701 
 90702 
 90703 
 90704 
 90705 
 90706 public function getInputStream()
 90707 {
 90708 return $this->inputStream;
 90709 }
 90710 
 90711 
 90712 
 90713 
 90714 public function getName()
 90715 {
 90716 return 'question';
 90717 }
 90718 
 90719 
 90720 
 90721 
 90722 
 90723 
 90724 
 90725 
 90726 
 90727 
 90728 public function doAsk(OutputInterface $output, Question $question)
 90729 {
 90730 $this->writePrompt($output, $question);
 90731 
 90732 $inputStream = $this->inputStream ?: STDIN;
 90733 $autocomplete = $question->getAutocompleterValues();
 90734 
 90735 if (null === $autocomplete || !$this->hasSttyAvailable()) {
 90736 $ret = false;
 90737 if ($question->isHidden()) {
 90738 try {
 90739 $ret = trim($this->getHiddenResponse($output, $inputStream));
 90740 } catch (RuntimeException $e) {
 90741 if (!$question->isHiddenFallback()) {
 90742 throw $e;
 90743 }
 90744 }
 90745 }
 90746 
 90747 if (false === $ret) {
 90748 $ret = fgets($inputStream, 4096);
 90749 if (false === $ret) {
 90750 throw new RuntimeException('Aborted');
 90751 }
 90752 $ret = trim($ret);
 90753 }
 90754 } else {
 90755 $ret = trim($this->autocomplete($output, $question, $inputStream, \is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false)));
 90756 }
 90757 
 90758 $ret = \strlen($ret) > 0 ? $ret : $question->getDefault();
 90759 
 90760 if ($normalizer = $question->getNormalizer()) {
 90761 return $normalizer($ret);
 90762 }
 90763 
 90764 return $ret;
 90765 }
 90766 
 90767 
 90768 
 90769 
 90770 protected function writePrompt(OutputInterface $output, Question $question)
 90771 {
 90772 $message = $question->getQuestion();
 90773 
 90774 if ($question instanceof ChoiceQuestion) {
 90775 $maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));
 90776 
 90777 $messages = (array) $question->getQuestion();
 90778 foreach ($question->getChoices() as $key => $value) {
 90779 $width = $maxWidth - $this->strlen($key);
 90780 $messages[] = '  [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
 90781 }
 90782 
 90783 $output->writeln($messages);
 90784 
 90785 $message = $question->getPrompt();
 90786 }
 90787 
 90788 $output->write($message);
 90789 }
 90790 
 90791 
 90792 
 90793 
 90794 protected function writeError(OutputInterface $output, \Exception $error)
 90795 {
 90796 if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
 90797 $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
 90798 } else {
 90799 $message = '<error>'.$error->getMessage().'</error>';
 90800 }
 90801 
 90802 $output->writeln($message);
 90803 }
 90804 
 90805 
 90806 
 90807 
 90808 
 90809 
 90810 
 90811 
 90812 
 90813 
 90814 
 90815 private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete)
 90816 {
 90817 $ret = '';
 90818 
 90819 $i = 0;
 90820 $ofs = -1;
 90821 $matches = $autocomplete;
 90822 $numMatches = \count($matches);
 90823 
 90824 $sttyMode = shell_exec('stty -g');
 90825 
 90826 
 90827 shell_exec('stty -icanon -echo');
 90828 
 90829 
 90830 $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
 90831 
 90832 
 90833 while (!feof($inputStream)) {
 90834 $c = fread($inputStream, 1);
 90835 
 90836 
 90837 if ("\177" === $c) {
 90838 if (0 === $numMatches && 0 !== $i) {
 90839 --$i;
 90840 
 90841 $output->write("\033[1D");
 90842 }
 90843 
 90844 if (0 === $i) {
 90845 $ofs = -1;
 90846 $matches = $autocomplete;
 90847 $numMatches = \count($matches);
 90848 } else {
 90849 $numMatches = 0;
 90850 }
 90851 
 90852 
 90853 $ret = substr($ret, 0, $i);
 90854 } elseif ("\033" === $c) {
 90855 
 90856 $c .= fread($inputStream, 2);
 90857 
 90858 
 90859 if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
 90860 if ('A' === $c[2] && -1 === $ofs) {
 90861 $ofs = 0;
 90862 }
 90863 
 90864 if (0 === $numMatches) {
 90865 continue;
 90866 }
 90867 
 90868 $ofs += ('A' === $c[2]) ? -1 : 1;
 90869 $ofs = ($numMatches + $ofs) % $numMatches;
 90870 }
 90871 } elseif (\ord($c) < 32) {
 90872 if ("\t" === $c || "\n" === $c) {
 90873 if ($numMatches > 0 && -1 !== $ofs) {
 90874 $ret = $matches[$ofs];
 90875 
 90876 $output->write(substr($ret, $i));
 90877 $i = \strlen($ret);
 90878 }
 90879 
 90880 if ("\n" === $c) {
 90881 $output->write($c);
 90882 break;
 90883 }
 90884 
 90885 $numMatches = 0;
 90886 }
 90887 
 90888 continue;
 90889 } else {
 90890 $output->write($c);
 90891 $ret .= $c;
 90892 ++$i;
 90893 
 90894 $numMatches = 0;
 90895 $ofs = 0;
 90896 
 90897 foreach ($autocomplete as $value) {
 90898 
 90899 if (0 === strpos($value, $ret)) {
 90900 $matches[$numMatches++] = $value;
 90901 }
 90902 }
 90903 }
 90904 
 90905 
 90906 $output->write("\033[K");
 90907 
 90908 if ($numMatches > 0 && -1 !== $ofs) {
 90909 
 90910 $output->write("\0337");
 90911 
 90912 $output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).'</hl>');
 90913 
 90914 $output->write("\0338");
 90915 }
 90916 }
 90917 
 90918 
 90919 shell_exec(sprintf('stty %s', $sttyMode));
 90920 
 90921 return $ret;
 90922 }
 90923 
 90924 
 90925 
 90926 
 90927 
 90928 
 90929 
 90930 
 90931 
 90932 
 90933 
 90934 private function getHiddenResponse(OutputInterface $output, $inputStream)
 90935 {
 90936 if ('\\' === \DIRECTORY_SEPARATOR) {
 90937 $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
 90938 
 90939 
 90940 if ('phar:' === substr(__FILE__, 0, 5)) {
 90941 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
 90942 copy($exe, $tmpExe);
 90943 $exe = $tmpExe;
 90944 }
 90945 
 90946 $value = rtrim(shell_exec($exe));
 90947 $output->writeln('');
 90948 
 90949 if (isset($tmpExe)) {
 90950 unlink($tmpExe);
 90951 }
 90952 
 90953 return $value;
 90954 }
 90955 
 90956 if ($this->hasSttyAvailable()) {
 90957 $sttyMode = shell_exec('stty -g');
 90958 
 90959 shell_exec('stty -echo');
 90960 $value = fgets($inputStream, 4096);
 90961 shell_exec(sprintf('stty %s', $sttyMode));
 90962 
 90963 if (false === $value) {
 90964 throw new RuntimeException('Aborted');
 90965 }
 90966 
 90967 $value = trim($value);
 90968 $output->writeln('');
 90969 
 90970 return $value;
 90971 }
 90972 
 90973 if (false !== $shell = $this->getShell()) {
 90974 $readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword';
 90975 $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
 90976 $value = rtrim(shell_exec($command));
 90977 $output->writeln('');
 90978 
 90979 return $value;
 90980 }
 90981 
 90982 throw new RuntimeException('Unable to hide the response.');
 90983 }
 90984 
 90985 
 90986 
 90987 
 90988 
 90989 
 90990 
 90991 
 90992 
 90993 
 90994 
 90995 
 90996 private function validateAttempts($interviewer, OutputInterface $output, Question $question)
 90997 {
 90998 $error = null;
 90999 $attempts = $question->getMaxAttempts();
 91000 while (null === $attempts || $attempts--) {
 91001 if (null !== $error) {
 91002 $this->writeError($output, $error);
 91003 }
 91004 
 91005 try {
 91006 return \call_user_func($question->getValidator(), $interviewer());
 91007 } catch (RuntimeException $e) {
 91008 throw $e;
 91009 } catch (\Exception $error) {
 91010 }
 91011 }
 91012 
 91013 throw $error;
 91014 }
 91015 
 91016 
 91017 
 91018 
 91019 
 91020 
 91021 private function getShell()
 91022 {
 91023 if (null !== self::$shell) {
 91024 return self::$shell;
 91025 }
 91026 
 91027 self::$shell = false;
 91028 
 91029 if (file_exists('/usr/bin/env')) {
 91030 
 91031 $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
 91032 foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
 91033 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
 91034 self::$shell = $sh;
 91035 break;
 91036 }
 91037 }
 91038 }
 91039 
 91040 return self::$shell;
 91041 }
 91042 
 91043 
 91044 
 91045 
 91046 
 91047 
 91048 private function hasSttyAvailable()
 91049 {
 91050 if (null !== self::$stty) {
 91051 return self::$stty;
 91052 }
 91053 
 91054 exec('stty 2>&1', $output, $exitcode);
 91055 
 91056 return self::$stty = 0 === $exitcode;
 91057 }
 91058 }
 91059 <?php
 91060 
 91061 
 91062 
 91063 
 91064 
 91065 
 91066 
 91067 
 91068 
 91069 
 91070 namespace Symfony\Component\Console\Helper;
 91071 
 91072 use Symfony\Component\Console\Exception\LogicException;
 91073 use Symfony\Component\Console\Formatter\OutputFormatter;
 91074 use Symfony\Component\Console\Input\InputInterface;
 91075 use Symfony\Component\Console\Output\OutputInterface;
 91076 use Symfony\Component\Console\Question\ChoiceQuestion;
 91077 use Symfony\Component\Console\Question\ConfirmationQuestion;
 91078 use Symfony\Component\Console\Question\Question;
 91079 use Symfony\Component\Console\Style\SymfonyStyle;
 91080 
 91081 
 91082 
 91083 
 91084 
 91085 
 91086 class SymfonyQuestionHelper extends QuestionHelper
 91087 {
 91088 
 91089 
 91090 
 91091 public function ask(InputInterface $input, OutputInterface $output, Question $question)
 91092 {
 91093 $validator = $question->getValidator();
 91094 $question->setValidator(function ($value) use ($validator) {
 91095 if (null !== $validator) {
 91096 $value = $validator($value);
 91097 } else {
 91098 
 91099 if (!\is_array($value) && !\is_bool($value) && 0 === \strlen($value)) {
 91100 throw new LogicException('A value is required.');
 91101 }
 91102 }
 91103 
 91104 return $value;
 91105 });
 91106 
 91107 return parent::ask($input, $output, $question);
 91108 }
 91109 
 91110 
 91111 
 91112 
 91113 protected function writePrompt(OutputInterface $output, Question $question)
 91114 {
 91115 $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
 91116 $default = $question->getDefault();
 91117 
 91118 switch (true) {
 91119 case null === $default:
 91120 $text = sprintf(' <info>%s</info>:', $text);
 91121 
 91122 break;
 91123 
 91124 case $question instanceof ConfirmationQuestion:
 91125 $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');
 91126 
 91127 break;
 91128 
 91129 case $question instanceof ChoiceQuestion && $question->isMultiselect():
 91130 $choices = $question->getChoices();
 91131 $default = explode(',', $default);
 91132 
 91133 foreach ($default as $key => $value) {
 91134 $default[$key] = $choices[trim($value)];
 91135 }
 91136 
 91137 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(implode(', ', $default)));
 91138 
 91139 break;
 91140 
 91141 case $question instanceof ChoiceQuestion:
 91142 $choices = $question->getChoices();
 91143 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(isset($choices[$default]) ? $choices[$default] : $default));
 91144 
 91145 break;
 91146 
 91147 default:
 91148 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default));
 91149 }
 91150 
 91151 $output->writeln($text);
 91152 
 91153 if ($question instanceof ChoiceQuestion) {
 91154 $width = max(array_map('strlen', array_keys($question->getChoices())));
 91155 
 91156 foreach ($question->getChoices() as $key => $value) {
 91157 $output->writeln(sprintf("  [<comment>%-${width}s</comment>] %s", $key, $value));
 91158 }
 91159 }
 91160 
 91161 $output->write(' > ');
 91162 }
 91163 
 91164 
 91165 
 91166 
 91167 protected function writeError(OutputInterface $output, \Exception $error)
 91168 {
 91169 if ($output instanceof SymfonyStyle) {
 91170 $output->newLine();
 91171 $output->error($error->getMessage());
 91172 
 91173 return;
 91174 }
 91175 
 91176 parent::writeError($output, $error);
 91177 }
 91178 }
 91179 <?php
 91180 
 91181 
 91182 
 91183 
 91184 
 91185 
 91186 
 91187 
 91188 
 91189 
 91190 namespace Symfony\Component\Console\Helper;
 91191 
 91192 use Symfony\Component\Console\Exception\InvalidArgumentException;
 91193 use Symfony\Component\Console\Output\OutputInterface;
 91194 
 91195 
 91196 
 91197 
 91198 
 91199 
 91200 
 91201 
 91202 
 91203 class Table
 91204 {
 91205 
 91206 
 91207 
 91208 private $headers = array();
 91209 
 91210 
 91211 
 91212 
 91213 private $rows = array();
 91214 
 91215 
 91216 
 91217 
 91218 private $columnWidths = array();
 91219 
 91220 
 91221 
 91222 
 91223 
 91224 
 91225 private $numberOfColumns;
 91226 
 91227 
 91228 
 91229 
 91230 private $output;
 91231 
 91232 
 91233 
 91234 
 91235 private $style;
 91236 
 91237 
 91238 
 91239 
 91240 private $columnStyles = array();
 91241 
 91242 private static $styles;
 91243 
 91244 public function __construct(OutputInterface $output)
 91245 {
 91246 $this->output = $output;
 91247 
 91248 if (!self::$styles) {
 91249 self::$styles = self::initStyles();
 91250 }
 91251 
 91252 $this->setStyle('default');
 91253 }
 91254 
 91255 
 91256 
 91257 
 91258 
 91259 
 91260 
 91261 public static function setStyleDefinition($name, TableStyle $style)
 91262 {
 91263 if (!self::$styles) {
 91264 self::$styles = self::initStyles();
 91265 }
 91266 
 91267 self::$styles[$name] = $style;
 91268 }
 91269 
 91270 
 91271 
 91272 
 91273 
 91274 
 91275 
 91276 
 91277 public static function getStyleDefinition($name)
 91278 {
 91279 if (!self::$styles) {
 91280 self::$styles = self::initStyles();
 91281 }
 91282 
 91283 if (isset(self::$styles[$name])) {
 91284 return self::$styles[$name];
 91285 }
 91286 
 91287 throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
 91288 }
 91289 
 91290 
 91291 
 91292 
 91293 
 91294 
 91295 
 91296 
 91297 public function setStyle($name)
 91298 {
 91299 $this->style = $this->resolveStyle($name);
 91300 
 91301 return $this;
 91302 }
 91303 
 91304 
 91305 
 91306 
 91307 
 91308 
 91309 public function getStyle()
 91310 {
 91311 return $this->style;
 91312 }
 91313 
 91314 
 91315 
 91316 
 91317 
 91318 
 91319 
 91320 
 91321 
 91322 public function setColumnStyle($columnIndex, $name)
 91323 {
 91324 $columnIndex = (int) $columnIndex;
 91325 
 91326 $this->columnStyles[$columnIndex] = $this->resolveStyle($name);
 91327 
 91328 return $this;
 91329 }
 91330 
 91331 
 91332 
 91333 
 91334 
 91335 
 91336 
 91337 
 91338 
 91339 
 91340 public function getColumnStyle($columnIndex)
 91341 {
 91342 if (isset($this->columnStyles[$columnIndex])) {
 91343 return $this->columnStyles[$columnIndex];
 91344 }
 91345 
 91346 return $this->getStyle();
 91347 }
 91348 
 91349 public function setHeaders(array $headers)
 91350 {
 91351 $headers = array_values($headers);
 91352 if (!empty($headers) && !\is_array($headers[0])) {
 91353 $headers = array($headers);
 91354 }
 91355 
 91356 $this->headers = $headers;
 91357 
 91358 return $this;
 91359 }
 91360 
 91361 public function setRows(array $rows)
 91362 {
 91363 $this->rows = array();
 91364 
 91365 return $this->addRows($rows);
 91366 }
 91367 
 91368 public function addRows(array $rows)
 91369 {
 91370 foreach ($rows as $row) {
 91371 $this->addRow($row);
 91372 }
 91373 
 91374 return $this;
 91375 }
 91376 
 91377 public function addRow($row)
 91378 {
 91379 if ($row instanceof TableSeparator) {
 91380 $this->rows[] = $row;
 91381 
 91382 return $this;
 91383 }
 91384 
 91385 if (!\is_array($row)) {
 91386 throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
 91387 }
 91388 
 91389 $this->rows[] = array_values($row);
 91390 
 91391 return $this;
 91392 }
 91393 
 91394 public function setRow($column, array $row)
 91395 {
 91396 $this->rows[$column] = $row;
 91397 
 91398 return $this;
 91399 }
 91400 
 91401 
 91402 
 91403 
 91404 
 91405 
 91406 
 91407 
 91408 
 91409 
 91410 
 91411 
 91412 
 91413 
 91414 public function render()
 91415 {
 91416 $this->calculateNumberOfColumns();
 91417 $rows = $this->buildTableRows($this->rows);
 91418 $headers = $this->buildTableRows($this->headers);
 91419 
 91420 $this->calculateColumnsWidth(array_merge($headers, $rows));
 91421 
 91422 $this->renderRowSeparator();
 91423 if (!empty($headers)) {
 91424 foreach ($headers as $header) {
 91425 $this->renderRow($header, $this->style->getCellHeaderFormat());
 91426 $this->renderRowSeparator();
 91427 }
 91428 }
 91429 foreach ($rows as $row) {
 91430 if ($row instanceof TableSeparator) {
 91431 $this->renderRowSeparator();
 91432 } else {
 91433 $this->renderRow($row, $this->style->getCellRowFormat());
 91434 }
 91435 }
 91436 if (!empty($rows)) {
 91437 $this->renderRowSeparator();
 91438 }
 91439 
 91440 $this->cleanup();
 91441 }
 91442 
 91443 
 91444 
 91445 
 91446 
 91447 
 91448 
 91449 
 91450 private function renderRowSeparator()
 91451 {
 91452 if (0 === $count = $this->numberOfColumns) {
 91453 return;
 91454 }
 91455 
 91456 if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
 91457 return;
 91458 }
 91459 
 91460 $markup = $this->style->getCrossingChar();
 91461 for ($column = 0; $column < $count; ++$column) {
 91462 $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->columnWidths[$column]).$this->style->getCrossingChar();
 91463 }
 91464 
 91465 $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
 91466 }
 91467 
 91468 
 91469 
 91470 
 91471 private function renderColumnSeparator()
 91472 {
 91473 return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
 91474 }
 91475 
 91476 
 91477 
 91478 
 91479 
 91480 
 91481 
 91482 
 91483 
 91484 
 91485 
 91486 private function renderRow(array $row, $cellFormat)
 91487 {
 91488 if (empty($row)) {
 91489 return;
 91490 }
 91491 
 91492 $rowContent = $this->renderColumnSeparator();
 91493 foreach ($this->getRowColumns($row) as $column) {
 91494 $rowContent .= $this->renderCell($row, $column, $cellFormat);
 91495 $rowContent .= $this->renderColumnSeparator();
 91496 }
 91497 $this->output->writeln($rowContent);
 91498 }
 91499 
 91500 
 91501 
 91502 
 91503 
 91504 
 91505 
 91506 
 91507 private function renderCell(array $row, $column, $cellFormat)
 91508 {
 91509 $cell = isset($row[$column]) ? $row[$column] : '';
 91510 $width = $this->columnWidths[$column];
 91511 if ($cell instanceof TableCell && $cell->getColspan() > 1) {
 91512 
 91513 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
 91514 $width += $this->getColumnSeparatorWidth() + $this->columnWidths[$nextColumn];
 91515 }
 91516 }
 91517 
 91518 
 91519 if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
 91520 $width += \strlen($cell) - mb_strwidth($cell, $encoding);
 91521 }
 91522 
 91523 $style = $this->getColumnStyle($column);
 91524 
 91525 if ($cell instanceof TableSeparator) {
 91526 return sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width));
 91527 }
 91528 
 91529 $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
 91530 $content = sprintf($style->getCellRowContentFormat(), $cell);
 91531 
 91532 return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType()));
 91533 }
 91534 
 91535 
 91536 
 91537 
 91538 private function calculateNumberOfColumns()
 91539 {
 91540 if (null !== $this->numberOfColumns) {
 91541 return;
 91542 }
 91543 
 91544 $columns = array(0);
 91545 foreach (array_merge($this->headers, $this->rows) as $row) {
 91546 if ($row instanceof TableSeparator) {
 91547 continue;
 91548 }
 91549 
 91550 $columns[] = $this->getNumberOfColumns($row);
 91551 }
 91552 
 91553 $this->numberOfColumns = max($columns);
 91554 }
 91555 
 91556 private function buildTableRows($rows)
 91557 {
 91558 $unmergedRows = array();
 91559 for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) {
 91560 $rows = $this->fillNextRows($rows, $rowKey);
 91561 
 91562 
 91563 foreach ($rows[$rowKey] as $column => $cell) {
 91564 if (!strstr($cell, "\n")) {
 91565 continue;
 91566 }
 91567 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
 91568 foreach ($lines as $lineKey => $line) {
 91569 if ($cell instanceof TableCell) {
 91570 $line = new TableCell($line, array('colspan' => $cell->getColspan()));
 91571 }
 91572 if (0 === $lineKey) {
 91573 $rows[$rowKey][$column] = $line;
 91574 } else {
 91575 $unmergedRows[$rowKey][$lineKey][$column] = $line;
 91576 }
 91577 }
 91578 }
 91579 }
 91580 
 91581 $tableRows = array();
 91582 foreach ($rows as $rowKey => $row) {
 91583 $tableRows[] = $this->fillCells($row);
 91584 if (isset($unmergedRows[$rowKey])) {
 91585 $tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
 91586 }
 91587 }
 91588 
 91589 return $tableRows;
 91590 }
 91591 
 91592 
 91593 
 91594 
 91595 
 91596 
 91597 
 91598 
 91599 
 91600 private function fillNextRows(array $rows, $line)
 91601 {
 91602 $unmergedRows = array();
 91603 foreach ($rows[$line] as $column => $cell) {
 91604 if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
 91605 $nbLines = $cell->getRowspan() - 1;
 91606 $lines = array($cell);
 91607 if (strstr($cell, "\n")) {
 91608 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
 91609 $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
 91610 
 91611 $rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
 91612 unset($lines[0]);
 91613 }
 91614 
 91615 
 91616 $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows);
 91617 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
 91618 $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
 91619 $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
 91620 if ($nbLines === $unmergedRowKey - $line) {
 91621 break;
 91622 }
 91623 }
 91624 }
 91625 }
 91626 
 91627 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
 91628 
 91629 if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
 91630 foreach ($unmergedRow as $cellKey => $cell) {
 91631 
 91632 array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell));
 91633 }
 91634 } else {
 91635 $row = $this->copyRow($rows, $unmergedRowKey - 1);
 91636 foreach ($unmergedRow as $column => $cell) {
 91637 if (!empty($cell)) {
 91638 $row[$column] = $unmergedRow[$column];
 91639 }
 91640 }
 91641 array_splice($rows, $unmergedRowKey, 0, array($row));
 91642 }
 91643 }
 91644 
 91645 return $rows;
 91646 }
 91647 
 91648 
 91649 
 91650 
 91651 
 91652 
 91653 private function fillCells($row)
 91654 {
 91655 $newRow = array();
 91656 foreach ($row as $column => $cell) {
 91657 $newRow[] = $cell;
 91658 if ($cell instanceof TableCell && $cell->getColspan() > 1) {
 91659 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {
 91660 
 91661 $newRow[] = '';
 91662 }
 91663 }
 91664 }
 91665 
 91666 return $newRow ?: $row;
 91667 }
 91668 
 91669 
 91670 
 91671 
 91672 
 91673 
 91674 
 91675 private function copyRow(array $rows, $line)
 91676 {
 91677 $row = $rows[$line];
 91678 foreach ($row as $cellKey => $cellValue) {
 91679 $row[$cellKey] = '';
 91680 if ($cellValue instanceof TableCell) {
 91681 $row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan()));
 91682 }
 91683 }
 91684 
 91685 return $row;
 91686 }
 91687 
 91688 
 91689 
 91690 
 91691 
 91692 
 91693 private function getNumberOfColumns(array $row)
 91694 {
 91695 $columns = \count($row);
 91696 foreach ($row as $column) {
 91697 $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0;
 91698 }
 91699 
 91700 return $columns;
 91701 }
 91702 
 91703 
 91704 
 91705 
 91706 
 91707 
 91708 private function getRowColumns(array $row)
 91709 {
 91710 $columns = range(0, $this->numberOfColumns - 1);
 91711 foreach ($row as $cellKey => $cell) {
 91712 if ($cell instanceof TableCell && $cell->getColspan() > 1) {
 91713 
 91714 $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
 91715 }
 91716 }
 91717 
 91718 return $columns;
 91719 }
 91720 
 91721 
 91722 
 91723 
 91724 
 91725 
 91726 private function calculateColumnsWidth($rows)
 91727 {
 91728 for ($column = 0; $column < $this->numberOfColumns; ++$column) {
 91729 $lengths = array();
 91730 foreach ($rows as $row) {
 91731 if ($row instanceof TableSeparator) {
 91732 continue;
 91733 }
 91734 
 91735 foreach ($row as $i => $cell) {
 91736 if ($cell instanceof TableCell) {
 91737 $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
 91738 $textLength = Helper::strlen($textContent);
 91739 if ($textLength > 0) {
 91740 $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan()));
 91741 foreach ($contentColumns as $position => $content) {
 91742 $row[$i + $position] = $content;
 91743 }
 91744 }
 91745 }
 91746 }
 91747 
 91748 $lengths[] = $this->getCellWidth($row, $column);
 91749 }
 91750 
 91751 $this->columnWidths[$column] = max($lengths) + Helper::strlen($this->style->getCellRowContentFormat()) - 2;
 91752 }
 91753 }
 91754 
 91755 
 91756 
 91757 
 91758 
 91759 
 91760 private function getColumnSeparatorWidth()
 91761 {
 91762 return Helper::strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
 91763 }
 91764 
 91765 
 91766 
 91767 
 91768 
 91769 
 91770 
 91771 
 91772 
 91773 private function getCellWidth(array $row, $column)
 91774 {
 91775 if (isset($row[$column])) {
 91776 $cell = $row[$column];
 91777 $cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
 91778 
 91779 return $cellWidth;
 91780 }
 91781 
 91782 return 0;
 91783 }
 91784 
 91785 
 91786 
 91787 
 91788 private function cleanup()
 91789 {
 91790 $this->columnWidths = array();
 91791 $this->numberOfColumns = null;
 91792 }
 91793 
 91794 private static function initStyles()
 91795 {
 91796 $borderless = new TableStyle();
 91797 $borderless
 91798 ->setHorizontalBorderChar('=')
 91799 ->setVerticalBorderChar(' ')
 91800 ->setCrossingChar(' ')
 91801 ;
 91802 
 91803 $compact = new TableStyle();
 91804 $compact
 91805 ->setHorizontalBorderChar('')
 91806 ->setVerticalBorderChar(' ')
 91807 ->setCrossingChar('')
 91808 ->setCellRowContentFormat('%s')
 91809 ;
 91810 
 91811 $styleGuide = new TableStyle();
 91812 $styleGuide
 91813 ->setHorizontalBorderChar('-')
 91814 ->setVerticalBorderChar(' ')
 91815 ->setCrossingChar(' ')
 91816 ->setCellHeaderFormat('%s')
 91817 ;
 91818 
 91819 return array(
 91820 'default' => new TableStyle(),
 91821 'borderless' => $borderless,
 91822 'compact' => $compact,
 91823 'symfony-style-guide' => $styleGuide,
 91824 );
 91825 }
 91826 
 91827 private function resolveStyle($name)
 91828 {
 91829 if ($name instanceof TableStyle) {
 91830 return $name;
 91831 }
 91832 
 91833 if (isset(self::$styles[$name])) {
 91834 return self::$styles[$name];
 91835 }
 91836 
 91837 throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
 91838 }
 91839 }
 91840 <?php
 91841 
 91842 
 91843 
 91844 
 91845 
 91846 
 91847 
 91848 
 91849 
 91850 
 91851 namespace Symfony\Component\Console\Helper;
 91852 
 91853 use Symfony\Component\Console\Exception\InvalidArgumentException;
 91854 
 91855 
 91856 
 91857 
 91858 class TableCell
 91859 {
 91860 private $value;
 91861 private $options = array(
 91862 'rowspan' => 1,
 91863 'colspan' => 1,
 91864 );
 91865 
 91866 
 91867 
 91868 
 91869 
 91870 public function __construct($value = '', array $options = array())
 91871 {
 91872 if (is_numeric($value) && !\is_string($value)) {
 91873 $value = (string) $value;
 91874 }
 91875 
 91876 $this->value = $value;
 91877 
 91878 
 91879 if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
 91880 throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff)));
 91881 }
 91882 
 91883 $this->options = array_merge($this->options, $options);
 91884 }
 91885 
 91886 
 91887 
 91888 
 91889 
 91890 
 91891 public function __toString()
 91892 {
 91893 return $this->value;
 91894 }
 91895 
 91896 
 91897 
 91898 
 91899 
 91900 
 91901 public function getColspan()
 91902 {
 91903 return (int) $this->options['colspan'];
 91904 }
 91905 
 91906 
 91907 
 91908 
 91909 
 91910 
 91911 public function getRowspan()
 91912 {
 91913 return (int) $this->options['rowspan'];
 91914 }
 91915 }
 91916 <?php
 91917 
 91918 
 91919 
 91920 
 91921 
 91922 
 91923 
 91924 
 91925 
 91926 
 91927 namespace Symfony\Component\Console\Helper;
 91928 
 91929 use Symfony\Component\Console\Exception\InvalidArgumentException;
 91930 use Symfony\Component\Console\Output\NullOutput;
 91931 use Symfony\Component\Console\Output\OutputInterface;
 91932 
 91933 
 91934 
 91935 
 91936 
 91937 
 91938 
 91939 
 91940 
 91941 
 91942 class TableHelper extends Helper
 91943 {
 91944 const LAYOUT_DEFAULT = 0;
 91945 const LAYOUT_BORDERLESS = 1;
 91946 const LAYOUT_COMPACT = 2;
 91947 
 91948 private $table;
 91949 
 91950 public function __construct($triggerDeprecationError = true)
 91951 {
 91952 if ($triggerDeprecationError) {
 91953 @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.5 and will be removed in 3.0. Use the Symfony\Component\Console\Helper\Table class instead.', E_USER_DEPRECATED);
 91954 }
 91955 
 91956 $this->table = new Table(new NullOutput());
 91957 }
 91958 
 91959 
 91960 
 91961 
 91962 
 91963 
 91964 
 91965 
 91966 
 91967 
 91968 public function setLayout($layout)
 91969 {
 91970 switch ($layout) {
 91971 case self::LAYOUT_BORDERLESS:
 91972 $this->table->setStyle('borderless');
 91973 break;
 91974 
 91975 case self::LAYOUT_COMPACT:
 91976 $this->table->setStyle('compact');
 91977 break;
 91978 
 91979 case self::LAYOUT_DEFAULT:
 91980 $this->table->setStyle('default');
 91981 break;
 91982 
 91983 default:
 91984 throw new InvalidArgumentException(sprintf('Invalid table layout "%s".', $layout));
 91985 }
 91986 
 91987 return $this;
 91988 }
 91989 
 91990 public function setHeaders(array $headers)
 91991 {
 91992 $this->table->setHeaders($headers);
 91993 
 91994 return $this;
 91995 }
 91996 
 91997 public function setRows(array $rows)
 91998 {
 91999 $this->table->setRows($rows);
 92000 
 92001 return $this;
 92002 }
 92003 
 92004 public function addRows(array $rows)
 92005 {
 92006 $this->table->addRows($rows);
 92007 
 92008 return $this;
 92009 }
 92010 
 92011 public function addRow(array $row)
 92012 {
 92013 $this->table->addRow($row);
 92014 
 92015 return $this;
 92016 }
 92017 
 92018 public function setRow($column, array $row)
 92019 {
 92020 $this->table->setRow($column, $row);
 92021 
 92022 return $this;
 92023 }
 92024 
 92025 
 92026 
 92027 
 92028 
 92029 
 92030 
 92031 
 92032 public function setPaddingChar($paddingChar)
 92033 {
 92034 $this->table->getStyle()->setPaddingChar($paddingChar);
 92035 
 92036 return $this;
 92037 }
 92038 
 92039 
 92040 
 92041 
 92042 
 92043 
 92044 
 92045 
 92046 public function setHorizontalBorderChar($horizontalBorderChar)
 92047 {
 92048 $this->table->getStyle()->setHorizontalBorderChar($horizontalBorderChar);
 92049 
 92050 return $this;
 92051 }
 92052 
 92053 
 92054 
 92055 
 92056 
 92057 
 92058 
 92059 
 92060 public function setVerticalBorderChar($verticalBorderChar)
 92061 {
 92062 $this->table->getStyle()->setVerticalBorderChar($verticalBorderChar);
 92063 
 92064 return $this;
 92065 }
 92066 
 92067 
 92068 
 92069 
 92070 
 92071 
 92072 
 92073 
 92074 public function setCrossingChar($crossingChar)
 92075 {
 92076 $this->table->getStyle()->setCrossingChar($crossingChar);
 92077 
 92078 return $this;
 92079 }
 92080 
 92081 
 92082 
 92083 
 92084 
 92085 
 92086 
 92087 
 92088 public function setCellHeaderFormat($cellHeaderFormat)
 92089 {
 92090 $this->table->getStyle()->setCellHeaderFormat($cellHeaderFormat);
 92091 
 92092 return $this;
 92093 }
 92094 
 92095 
 92096 
 92097 
 92098 
 92099 
 92100 
 92101 
 92102 public function setCellRowFormat($cellRowFormat)
 92103 {
 92104 $this->table->getStyle()->setCellHeaderFormat($cellRowFormat);
 92105 
 92106 return $this;
 92107 }
 92108 
 92109 
 92110 
 92111 
 92112 
 92113 
 92114 
 92115 
 92116 public function setCellRowContentFormat($cellRowContentFormat)
 92117 {
 92118 $this->table->getStyle()->setCellRowContentFormat($cellRowContentFormat);
 92119 
 92120 return $this;
 92121 }
 92122 
 92123 
 92124 
 92125 
 92126 
 92127 
 92128 
 92129 
 92130 public function setBorderFormat($borderFormat)
 92131 {
 92132 $this->table->getStyle()->setBorderFormat($borderFormat);
 92133 
 92134 return $this;
 92135 }
 92136 
 92137 
 92138 
 92139 
 92140 
 92141 
 92142 
 92143 
 92144 public function setPadType($padType)
 92145 {
 92146 $this->table->getStyle()->setPadType($padType);
 92147 
 92148 return $this;
 92149 }
 92150 
 92151 
 92152 
 92153 
 92154 
 92155 
 92156 
 92157 
 92158 
 92159 
 92160 
 92161 
 92162 
 92163 public function render(OutputInterface $output)
 92164 {
 92165 $p = new \ReflectionProperty($this->table, 'output');
 92166 $p->setAccessible(true);
 92167 $p->setValue($this->table, $output);
 92168 
 92169 $this->table->render();
 92170 }
 92171 
 92172 
 92173 
 92174 
 92175 public function getName()
 92176 {
 92177 return 'table';
 92178 }
 92179 }
 92180 <?php
 92181 
 92182 
 92183 
 92184 
 92185 
 92186 
 92187 
 92188 
 92189 
 92190 
 92191 namespace Symfony\Component\Console\Helper;
 92192 
 92193 
 92194 
 92195 
 92196 
 92197 
 92198 class TableSeparator extends TableCell
 92199 {
 92200 public function __construct(array $options = array())
 92201 {
 92202 parent::__construct('', $options);
 92203 }
 92204 }
 92205 <?php
 92206 
 92207 
 92208 
 92209 
 92210 
 92211 
 92212 
 92213 
 92214 
 92215 
 92216 namespace Symfony\Component\Console\Helper;
 92217 
 92218 use Symfony\Component\Console\Exception\InvalidArgumentException;
 92219 use Symfony\Component\Console\Exception\LogicException;
 92220 
 92221 
 92222 
 92223 
 92224 
 92225 
 92226 
 92227 class TableStyle
 92228 {
 92229 private $paddingChar = ' ';
 92230 private $horizontalBorderChar = '-';
 92231 private $verticalBorderChar = '|';
 92232 private $crossingChar = '+';
 92233 private $cellHeaderFormat = '<info>%s</info>';
 92234 private $cellRowFormat = '%s';
 92235 private $cellRowContentFormat = ' %s ';
 92236 private $borderFormat = '%s';
 92237 private $padType = STR_PAD_RIGHT;
 92238 
 92239 
 92240 
 92241 
 92242 
 92243 
 92244 
 92245 
 92246 public function setPaddingChar($paddingChar)
 92247 {
 92248 if (!$paddingChar) {
 92249 throw new LogicException('The padding char must not be empty');
 92250 }
 92251 
 92252 $this->paddingChar = $paddingChar;
 92253 
 92254 return $this;
 92255 }
 92256 
 92257 
 92258 
 92259 
 92260 
 92261 
 92262 public function getPaddingChar()
 92263 {
 92264 return $this->paddingChar;
 92265 }
 92266 
 92267 
 92268 
 92269 
 92270 
 92271 
 92272 
 92273 
 92274 public function setHorizontalBorderChar($horizontalBorderChar)
 92275 {
 92276 $this->horizontalBorderChar = $horizontalBorderChar;
 92277 
 92278 return $this;
 92279 }
 92280 
 92281 
 92282 
 92283 
 92284 
 92285 
 92286 public function getHorizontalBorderChar()
 92287 {
 92288 return $this->horizontalBorderChar;
 92289 }
 92290 
 92291 
 92292 
 92293 
 92294 
 92295 
 92296 
 92297 
 92298 public function setVerticalBorderChar($verticalBorderChar)
 92299 {
 92300 $this->verticalBorderChar = $verticalBorderChar;
 92301 
 92302 return $this;
 92303 }
 92304 
 92305 
 92306 
 92307 
 92308 
 92309 
 92310 public function getVerticalBorderChar()
 92311 {
 92312 return $this->verticalBorderChar;
 92313 }
 92314 
 92315 
 92316 
 92317 
 92318 
 92319 
 92320 
 92321 
 92322 public function setCrossingChar($crossingChar)
 92323 {
 92324 $this->crossingChar = $crossingChar;
 92325 
 92326 return $this;
 92327 }
 92328 
 92329 
 92330 
 92331 
 92332 
 92333 
 92334 public function getCrossingChar()
 92335 {
 92336 return $this->crossingChar;
 92337 }
 92338 
 92339 
 92340 
 92341 
 92342 
 92343 
 92344 
 92345 
 92346 public function setCellHeaderFormat($cellHeaderFormat)
 92347 {
 92348 $this->cellHeaderFormat = $cellHeaderFormat;
 92349 
 92350 return $this;
 92351 }
 92352 
 92353 
 92354 
 92355 
 92356 
 92357 
 92358 public function getCellHeaderFormat()
 92359 {
 92360 return $this->cellHeaderFormat;
 92361 }
 92362 
 92363 
 92364 
 92365 
 92366 
 92367 
 92368 
 92369 
 92370 public function setCellRowFormat($cellRowFormat)
 92371 {
 92372 $this->cellRowFormat = $cellRowFormat;
 92373 
 92374 return $this;
 92375 }
 92376 
 92377 
 92378 
 92379 
 92380 
 92381 
 92382 public function getCellRowFormat()
 92383 {
 92384 return $this->cellRowFormat;
 92385 }
 92386 
 92387 
 92388 
 92389 
 92390 
 92391 
 92392 
 92393 
 92394 public function setCellRowContentFormat($cellRowContentFormat)
 92395 {
 92396 $this->cellRowContentFormat = $cellRowContentFormat;
 92397 
 92398 return $this;
 92399 }
 92400 
 92401 
 92402 
 92403 
 92404 
 92405 
 92406 public function getCellRowContentFormat()
 92407 {
 92408 return $this->cellRowContentFormat;
 92409 }
 92410 
 92411 
 92412 
 92413 
 92414 
 92415 
 92416 
 92417 
 92418 public function setBorderFormat($borderFormat)
 92419 {
 92420 $this->borderFormat = $borderFormat;
 92421 
 92422 return $this;
 92423 }
 92424 
 92425 
 92426 
 92427 
 92428 
 92429 
 92430 public function getBorderFormat()
 92431 {
 92432 return $this->borderFormat;
 92433 }
 92434 
 92435 
 92436 
 92437 
 92438 
 92439 
 92440 
 92441 
 92442 public function setPadType($padType)
 92443 {
 92444 if (!\in_array($padType, array(STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH), true)) {
 92445 throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
 92446 }
 92447 
 92448 $this->padType = $padType;
 92449 
 92450 return $this;
 92451 }
 92452 
 92453 
 92454 
 92455 
 92456 
 92457 
 92458 public function getPadType()
 92459 {
 92460 return $this->padType;
 92461 }
 92462 }
 92463 <?php
 92464 
 92465 
 92466 
 92467 
 92468 
 92469 
 92470 
 92471 
 92472 
 92473 
 92474 namespace Symfony\Component\Console\Input;
 92475 
 92476 use Symfony\Component\Console\Exception\RuntimeException;
 92477 
 92478 
 92479 
 92480 
 92481 
 92482 
 92483 
 92484 
 92485 
 92486 
 92487 
 92488 
 92489 
 92490 
 92491 
 92492 
 92493 
 92494 
 92495 
 92496 
 92497 
 92498 
 92499 
 92500 
 92501 
 92502 
 92503 class ArgvInput extends Input
 92504 {
 92505 private $tokens;
 92506 private $parsed;
 92507 
 92508 
 92509 
 92510 
 92511 
 92512 public function __construct(array $argv = null, InputDefinition $definition = null)
 92513 {
 92514 if (null === $argv) {
 92515 $argv = $_SERVER['argv'];
 92516 }
 92517 
 92518 
 92519 array_shift($argv);
 92520 
 92521 $this->tokens = $argv;
 92522 
 92523 parent::__construct($definition);
 92524 }
 92525 
 92526 protected function setTokens(array $tokens)
 92527 {
 92528 $this->tokens = $tokens;
 92529 }
 92530 
 92531 
 92532 
 92533 
 92534 protected function parse()
 92535 {
 92536 $parseOptions = true;
 92537 $this->parsed = $this->tokens;
 92538 while (null !== $token = array_shift($this->parsed)) {
 92539 if ($parseOptions && '' == $token) {
 92540 $this->parseArgument($token);
 92541 } elseif ($parseOptions && '--' == $token) {
 92542 $parseOptions = false;
 92543 } elseif ($parseOptions && 0 === strpos($token, '--')) {
 92544 $this->parseLongOption($token);
 92545 } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
 92546 $this->parseShortOption($token);
 92547 } else {
 92548 $this->parseArgument($token);
 92549 }
 92550 }
 92551 }
 92552 
 92553 
 92554 
 92555 
 92556 
 92557 
 92558 private function parseShortOption($token)
 92559 {
 92560 $name = substr($token, 1);
 92561 
 92562 if (\strlen($name) > 1) {
 92563 if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
 92564 
 92565 $this->addShortOption($name[0], substr($name, 1));
 92566 } else {
 92567 $this->parseShortOptionSet($name);
 92568 }
 92569 } else {
 92570 $this->addShortOption($name, null);
 92571 }
 92572 }
 92573 
 92574 
 92575 
 92576 
 92577 
 92578 
 92579 
 92580 
 92581 private function parseShortOptionSet($name)
 92582 {
 92583 $len = \strlen($name);
 92584 for ($i = 0; $i < $len; ++$i) {
 92585 if (!$this->definition->hasShortcut($name[$i])) {
 92586 $encoding = mb_detect_encoding($name, null, true);
 92587 throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding)));
 92588 }
 92589 
 92590 $option = $this->definition->getOptionForShortcut($name[$i]);
 92591 if ($option->acceptValue()) {
 92592 $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
 92593 
 92594 break;
 92595 } else {
 92596 $this->addLongOption($option->getName(), null);
 92597 }
 92598 }
 92599 }
 92600 
 92601 
 92602 
 92603 
 92604 
 92605 
 92606 private function parseLongOption($token)
 92607 {
 92608 $name = substr($token, 2);
 92609 
 92610 if (false !== $pos = strpos($name, '=')) {
 92611 if (0 === \strlen($value = substr($name, $pos + 1))) {
 92612 array_unshift($this->parsed, null);
 92613 }
 92614 $this->addLongOption(substr($name, 0, $pos), $value);
 92615 } else {
 92616 $this->addLongOption($name, null);
 92617 }
 92618 }
 92619 
 92620 
 92621 
 92622 
 92623 
 92624 
 92625 
 92626 
 92627 private function parseArgument($token)
 92628 {
 92629 $c = \count($this->arguments);
 92630 
 92631 
 92632 if ($this->definition->hasArgument($c)) {
 92633 $arg = $this->definition->getArgument($c);
 92634 $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;
 92635 
 92636 
 92637 } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
 92638 $arg = $this->definition->getArgument($c - 1);
 92639 $this->arguments[$arg->getName()][] = $token;
 92640 
 92641 
 92642 } else {
 92643 $all = $this->definition->getArguments();
 92644 if (\count($all)) {
 92645 throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))));
 92646 }
 92647 
 92648 throw new RuntimeException(sprintf('No arguments expected, got "%s".', $token));
 92649 }
 92650 }
 92651 
 92652 
 92653 
 92654 
 92655 
 92656 
 92657 
 92658 
 92659 
 92660 private function addShortOption($shortcut, $value)
 92661 {
 92662 if (!$this->definition->hasShortcut($shortcut)) {
 92663 throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
 92664 }
 92665 
 92666 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
 92667 }
 92668 
 92669 
 92670 
 92671 
 92672 
 92673 
 92674 
 92675 
 92676 
 92677 private function addLongOption($name, $value)
 92678 {
 92679 if (!$this->definition->hasOption($name)) {
 92680 throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
 92681 }
 92682 
 92683 $option = $this->definition->getOption($name);
 92684 
 92685 
 92686 if (!isset($value[0])) {
 92687 $value = null;
 92688 }
 92689 
 92690 if (null !== $value && !$option->acceptValue()) {
 92691 throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
 92692 }
 92693 
 92694 if (null === $value && $option->acceptValue() && \count($this->parsed)) {
 92695 
 92696 
 92697 $next = array_shift($this->parsed);
 92698 if (isset($next[0]) && '-' !== $next[0]) {
 92699 $value = $next;
 92700 } elseif (empty($next)) {
 92701 $value = null;
 92702 } else {
 92703 array_unshift($this->parsed, $next);
 92704 }
 92705 }
 92706 
 92707 if (null === $value) {
 92708 if ($option->isValueRequired()) {
 92709 throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
 92710 }
 92711 
 92712 if (!$option->isArray()) {
 92713 $value = $option->isValueOptional() ? $option->getDefault() : true;
 92714 }
 92715 }
 92716 
 92717 if ($option->isArray()) {
 92718 $this->options[$name][] = $value;
 92719 } else {
 92720 $this->options[$name] = $value;
 92721 }
 92722 }
 92723 
 92724 
 92725 
 92726 
 92727 public function getFirstArgument()
 92728 {
 92729 foreach ($this->tokens as $token) {
 92730 if ($token && '-' === $token[0]) {
 92731 continue;
 92732 }
 92733 
 92734 return $token;
 92735 }
 92736 }
 92737 
 92738 
 92739 
 92740 
 92741 public function hasParameterOption($values)
 92742 {
 92743 $values = (array) $values;
 92744 
 92745 foreach ($this->tokens as $token) {
 92746 foreach ($values as $value) {
 92747 
 92748 
 92749 
 92750 $leading = 0 === strpos($value, '--') ? $value.'=' : $value;
 92751 if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) {
 92752 return true;
 92753 }
 92754 }
 92755 }
 92756 
 92757 return false;
 92758 }
 92759 
 92760 
 92761 
 92762 
 92763 public function getParameterOption($values, $default = false)
 92764 {
 92765 $values = (array) $values;
 92766 $tokens = $this->tokens;
 92767 
 92768 while (0 < \count($tokens)) {
 92769 $token = array_shift($tokens);
 92770 
 92771 foreach ($values as $value) {
 92772 if ($token === $value) {
 92773 return array_shift($tokens);
 92774 }
 92775 
 92776 
 92777 
 92778 $leading = 0 === strpos($value, '--') ? $value.'=' : $value;
 92779 if ('' !== $leading && 0 === strpos($token, $leading)) {
 92780 return substr($token, \strlen($leading));
 92781 }
 92782 }
 92783 }
 92784 
 92785 return $default;
 92786 }
 92787 
 92788 
 92789 
 92790 
 92791 
 92792 
 92793 public function __toString()
 92794 {
 92795 $self = $this;
 92796 $tokens = array_map(function ($token) use ($self) {
 92797 if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
 92798 return $match[1].$self->escapeToken($match[2]);
 92799 }
 92800 
 92801 if ($token && '-' !== $token[0]) {
 92802 return $self->escapeToken($token);
 92803 }
 92804 
 92805 return $token;
 92806 }, $this->tokens);
 92807 
 92808 return implode(' ', $tokens);
 92809 }
 92810 }
 92811 <?php
 92812 
 92813 
 92814 
 92815 
 92816 
 92817 
 92818 
 92819 
 92820 
 92821 
 92822 namespace Symfony\Component\Console\Input;
 92823 
 92824 use Symfony\Component\Console\Exception\InvalidArgumentException;
 92825 use Symfony\Component\Console\Exception\InvalidOptionException;
 92826 
 92827 
 92828 
 92829 
 92830 
 92831 
 92832 
 92833 
 92834 
 92835 
 92836 class ArrayInput extends Input
 92837 {
 92838 private $parameters;
 92839 
 92840 public function __construct(array $parameters, InputDefinition $definition = null)
 92841 {
 92842 $this->parameters = $parameters;
 92843 
 92844 parent::__construct($definition);
 92845 }
 92846 
 92847 
 92848 
 92849 
 92850 public function getFirstArgument()
 92851 {
 92852 foreach ($this->parameters as $key => $value) {
 92853 if ($key && '-' === $key[0]) {
 92854 continue;
 92855 }
 92856 
 92857 return $value;
 92858 }
 92859 }
 92860 
 92861 
 92862 
 92863 
 92864 public function hasParameterOption($values)
 92865 {
 92866 $values = (array) $values;
 92867 
 92868 foreach ($this->parameters as $k => $v) {
 92869 if (!\is_int($k)) {
 92870 $v = $k;
 92871 }
 92872 
 92873 if (\in_array($v, $values)) {
 92874 return true;
 92875 }
 92876 }
 92877 
 92878 return false;
 92879 }
 92880 
 92881 
 92882 
 92883 
 92884 public function getParameterOption($values, $default = false)
 92885 {
 92886 $values = (array) $values;
 92887 
 92888 foreach ($this->parameters as $k => $v) {
 92889 if (\is_int($k)) {
 92890 if (\in_array($v, $values)) {
 92891 return true;
 92892 }
 92893 } elseif (\in_array($k, $values)) {
 92894 return $v;
 92895 }
 92896 }
 92897 
 92898 return $default;
 92899 }
 92900 
 92901 
 92902 
 92903 
 92904 
 92905 
 92906 public function __toString()
 92907 {
 92908 $params = array();
 92909 foreach ($this->parameters as $param => $val) {
 92910 if ($param && '-' === $param[0]) {
 92911 if (\is_array($val)) {
 92912 foreach ($val as $v) {
 92913 $params[] = $param.('' != $v ? '='.$this->escapeToken($v) : '');
 92914 }
 92915 } else {
 92916 $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
 92917 }
 92918 } else {
 92919 $params[] = \is_array($val) ? implode(' ', array_map(array($this, 'escapeToken'), $val)) : $this->escapeToken($val);
 92920 }
 92921 }
 92922 
 92923 return implode(' ', $params);
 92924 }
 92925 
 92926 
 92927 
 92928 
 92929 protected function parse()
 92930 {
 92931 foreach ($this->parameters as $key => $value) {
 92932 if (0 === strpos($key, '--')) {
 92933 $this->addLongOption(substr($key, 2), $value);
 92934 } elseif ('-' === $key[0]) {
 92935 $this->addShortOption(substr($key, 1), $value);
 92936 } else {
 92937 $this->addArgument($key, $value);
 92938 }
 92939 }
 92940 }
 92941 
 92942 
 92943 
 92944 
 92945 
 92946 
 92947 
 92948 
 92949 
 92950 private function addShortOption($shortcut, $value)
 92951 {
 92952 if (!$this->definition->hasShortcut($shortcut)) {
 92953 throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
 92954 }
 92955 
 92956 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
 92957 }
 92958 
 92959 
 92960 
 92961 
 92962 
 92963 
 92964 
 92965 
 92966 
 92967 
 92968 private function addLongOption($name, $value)
 92969 {
 92970 if (!$this->definition->hasOption($name)) {
 92971 throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name));
 92972 }
 92973 
 92974 $option = $this->definition->getOption($name);
 92975 
 92976 if (null === $value) {
 92977 if ($option->isValueRequired()) {
 92978 throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
 92979 }
 92980 
 92981 $value = $option->isValueOptional() ? $option->getDefault() : true;
 92982 }
 92983 
 92984 $this->options[$name] = $value;
 92985 }
 92986 
 92987 
 92988 
 92989 
 92990 
 92991 
 92992 
 92993 
 92994 
 92995 private function addArgument($name, $value)
 92996 {
 92997 if (!$this->definition->hasArgument($name)) {
 92998 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
 92999 }
 93000 
 93001 $this->arguments[$name] = $value;
 93002 }
 93003 }
 93004 <?php
 93005 
 93006 
 93007 
 93008 
 93009 
 93010 
 93011 
 93012 
 93013 
 93014 
 93015 namespace Symfony\Component\Console\Input;
 93016 
 93017 use Symfony\Component\Console\Exception\InvalidArgumentException;
 93018 use Symfony\Component\Console\Exception\RuntimeException;
 93019 
 93020 
 93021 
 93022 
 93023 
 93024 
 93025 
 93026 
 93027 
 93028 
 93029 
 93030 
 93031 abstract class Input implements InputInterface
 93032 {
 93033 protected $definition;
 93034 protected $options = array();
 93035 protected $arguments = array();
 93036 protected $interactive = true;
 93037 
 93038 public function __construct(InputDefinition $definition = null)
 93039 {
 93040 if (null === $definition) {
 93041 $this->definition = new InputDefinition();
 93042 } else {
 93043 $this->bind($definition);
 93044 $this->validate();
 93045 }
 93046 }
 93047 
 93048 
 93049 
 93050 
 93051 public function bind(InputDefinition $definition)
 93052 {
 93053 $this->arguments = array();
 93054 $this->options = array();
 93055 $this->definition = $definition;
 93056 
 93057 $this->parse();
 93058 }
 93059 
 93060 
 93061 
 93062 
 93063 abstract protected function parse();
 93064 
 93065 
 93066 
 93067 
 93068 public function validate()
 93069 {
 93070 $definition = $this->definition;
 93071 $givenArguments = $this->arguments;
 93072 
 93073 $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {
 93074 return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
 93075 });
 93076 
 93077 if (\count($missingArguments) > 0) {
 93078 throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
 93079 }
 93080 }
 93081 
 93082 
 93083 
 93084 
 93085 public function isInteractive()
 93086 {
 93087 return $this->interactive;
 93088 }
 93089 
 93090 
 93091 
 93092 
 93093 public function setInteractive($interactive)
 93094 {
 93095 $this->interactive = (bool) $interactive;
 93096 }
 93097 
 93098 
 93099 
 93100 
 93101 public function getArguments()
 93102 {
 93103 return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
 93104 }
 93105 
 93106 
 93107 
 93108 
 93109 public function getArgument($name)
 93110 {
 93111 if (!$this->definition->hasArgument($name)) {
 93112 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
 93113 }
 93114 
 93115 return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
 93116 }
 93117 
 93118 
 93119 
 93120 
 93121 public function setArgument($name, $value)
 93122 {
 93123 if (!$this->definition->hasArgument($name)) {
 93124 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
 93125 }
 93126 
 93127 $this->arguments[$name] = $value;
 93128 }
 93129 
 93130 
 93131 
 93132 
 93133 public function hasArgument($name)
 93134 {
 93135 return $this->definition->hasArgument($name);
 93136 }
 93137 
 93138 
 93139 
 93140 
 93141 public function getOptions()
 93142 {
 93143 return array_merge($this->definition->getOptionDefaults(), $this->options);
 93144 }
 93145 
 93146 
 93147 
 93148 
 93149 public function getOption($name)
 93150 {
 93151 if (!$this->definition->hasOption($name)) {
 93152 throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
 93153 }
 93154 
 93155 return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
 93156 }
 93157 
 93158 
 93159 
 93160 
 93161 public function setOption($name, $value)
 93162 {
 93163 if (!$this->definition->hasOption($name)) {
 93164 throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
 93165 }
 93166 
 93167 $this->options[$name] = $value;
 93168 }
 93169 
 93170 
 93171 
 93172 
 93173 public function hasOption($name)
 93174 {
 93175 return $this->definition->hasOption($name);
 93176 }
 93177 
 93178 
 93179 
 93180 
 93181 
 93182 
 93183 
 93184 
 93185 public function escapeToken($token)
 93186 {
 93187 return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
 93188 }
 93189 }
 93190 <?php
 93191 
 93192 
 93193 
 93194 
 93195 
 93196 
 93197 
 93198 
 93199 
 93200 
 93201 namespace Symfony\Component\Console\Input;
 93202 
 93203 use Symfony\Component\Console\Exception\InvalidArgumentException;
 93204 use Symfony\Component\Console\Exception\LogicException;
 93205 
 93206 
 93207 
 93208 
 93209 
 93210 
 93211 class InputArgument
 93212 {
 93213 const REQUIRED = 1;
 93214 const OPTIONAL = 2;
 93215 const IS_ARRAY = 4;
 93216 
 93217 private $name;
 93218 private $mode;
 93219 private $default;
 93220 private $description;
 93221 
 93222 
 93223 
 93224 
 93225 
 93226 
 93227 
 93228 
 93229 
 93230 public function __construct($name, $mode = null, $description = '', $default = null)
 93231 {
 93232 if (null === $mode) {
 93233 $mode = self::OPTIONAL;
 93234 } elseif (!\is_int($mode) || $mode > 7 || $mode < 1) {
 93235 throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
 93236 }
 93237 
 93238 $this->name = $name;
 93239 $this->mode = $mode;
 93240 $this->description = $description;
 93241 
 93242 $this->setDefault($default);
 93243 }
 93244 
 93245 
 93246 
 93247 
 93248 
 93249 
 93250 public function getName()
 93251 {
 93252 return $this->name;
 93253 }
 93254 
 93255 
 93256 
 93257 
 93258 
 93259 
 93260 public function isRequired()
 93261 {
 93262 return self::REQUIRED === (self::REQUIRED & $this->mode);
 93263 }
 93264 
 93265 
 93266 
 93267 
 93268 
 93269 
 93270 public function isArray()
 93271 {
 93272 return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
 93273 }
 93274 
 93275 
 93276 
 93277 
 93278 
 93279 
 93280 
 93281 
 93282 public function setDefault($default = null)
 93283 {
 93284 if (self::REQUIRED === $this->mode && null !== $default) {
 93285 throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
 93286 }
 93287 
 93288 if ($this->isArray()) {
 93289 if (null === $default) {
 93290 $default = array();
 93291 } elseif (!\is_array($default)) {
 93292 throw new LogicException('A default value for an array argument must be an array.');
 93293 }
 93294 }
 93295 
 93296 $this->default = $default;
 93297 }
 93298 
 93299 
 93300 
 93301 
 93302 
 93303 
 93304 public function getDefault()
 93305 {
 93306 return $this->default;
 93307 }
 93308 
 93309 
 93310 
 93311 
 93312 
 93313 
 93314 public function getDescription()
 93315 {
 93316 return $this->description;
 93317 }
 93318 }
 93319 <?php
 93320 
 93321 
 93322 
 93323 
 93324 
 93325 
 93326 
 93327 
 93328 
 93329 
 93330 namespace Symfony\Component\Console\Input;
 93331 
 93332 
 93333 
 93334 
 93335 
 93336 
 93337 
 93338 interface InputAwareInterface
 93339 {
 93340 
 93341 
 93342 
 93343 public function setInput(InputInterface $input);
 93344 }
 93345 <?php
 93346 
 93347 
 93348 
 93349 
 93350 
 93351 
 93352 
 93353 
 93354 
 93355 
 93356 namespace Symfony\Component\Console\Input;
 93357 
 93358 use Symfony\Component\Console\Descriptor\TextDescriptor;
 93359 use Symfony\Component\Console\Descriptor\XmlDescriptor;
 93360 use Symfony\Component\Console\Exception\InvalidArgumentException;
 93361 use Symfony\Component\Console\Exception\LogicException;
 93362 use Symfony\Component\Console\Output\BufferedOutput;
 93363 
 93364 
 93365 
 93366 
 93367 
 93368 
 93369 
 93370 
 93371 
 93372 
 93373 
 93374 
 93375 
 93376 class InputDefinition
 93377 {
 93378 private $arguments;
 93379 private $requiredCount;
 93380 private $hasAnArrayArgument = false;
 93381 private $hasOptional;
 93382 private $options;
 93383 private $shortcuts;
 93384 
 93385 
 93386 
 93387 
 93388 public function __construct(array $definition = array())
 93389 {
 93390 $this->setDefinition($definition);
 93391 }
 93392 
 93393 
 93394 
 93395 
 93396 public function setDefinition(array $definition)
 93397 {
 93398 $arguments = array();
 93399 $options = array();
 93400 foreach ($definition as $item) {
 93401 if ($item instanceof InputOption) {
 93402 $options[] = $item;
 93403 } else {
 93404 $arguments[] = $item;
 93405 }
 93406 }
 93407 
 93408 $this->setArguments($arguments);
 93409 $this->setOptions($options);
 93410 }
 93411 
 93412 
 93413 
 93414 
 93415 
 93416 
 93417 public function setArguments($arguments = array())
 93418 {
 93419 $this->arguments = array();
 93420 $this->requiredCount = 0;
 93421 $this->hasOptional = false;
 93422 $this->hasAnArrayArgument = false;
 93423 $this->addArguments($arguments);
 93424 }
 93425 
 93426 
 93427 
 93428 
 93429 
 93430 
 93431 public function addArguments($arguments = array())
 93432 {
 93433 if (null !== $arguments) {
 93434 foreach ($arguments as $argument) {
 93435 $this->addArgument($argument);
 93436 }
 93437 }
 93438 }
 93439 
 93440 
 93441 
 93442 
 93443 public function addArgument(InputArgument $argument)
 93444 {
 93445 if (isset($this->arguments[$argument->getName()])) {
 93446 throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
 93447 }
 93448 
 93449 if ($this->hasAnArrayArgument) {
 93450 throw new LogicException('Cannot add an argument after an array argument.');
 93451 }
 93452 
 93453 if ($argument->isRequired() && $this->hasOptional) {
 93454 throw new LogicException('Cannot add a required argument after an optional one.');
 93455 }
 93456 
 93457 if ($argument->isArray()) {
 93458 $this->hasAnArrayArgument = true;
 93459 }
 93460 
 93461 if ($argument->isRequired()) {
 93462 ++$this->requiredCount;
 93463 } else {
 93464 $this->hasOptional = true;
 93465 }
 93466 
 93467 $this->arguments[$argument->getName()] = $argument;
 93468 }
 93469 
 93470 
 93471 
 93472 
 93473 
 93474 
 93475 
 93476 
 93477 
 93478 
 93479 public function getArgument($name)
 93480 {
 93481 if (!$this->hasArgument($name)) {
 93482 throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
 93483 }
 93484 
 93485 $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
 93486 
 93487 return $arguments[$name];
 93488 }
 93489 
 93490 
 93491 
 93492 
 93493 
 93494 
 93495 
 93496 
 93497 public function hasArgument($name)
 93498 {
 93499 $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments;
 93500 
 93501 return isset($arguments[$name]);
 93502 }
 93503 
 93504 
 93505 
 93506 
 93507 
 93508 
 93509 public function getArguments()
 93510 {
 93511 return $this->arguments;
 93512 }
 93513 
 93514 
 93515 
 93516 
 93517 
 93518 
 93519 public function getArgumentCount()
 93520 {
 93521 return $this->hasAnArrayArgument ? PHP_INT_MAX : \count($this->arguments);
 93522 }
 93523 
 93524 
 93525 
 93526 
 93527 
 93528 
 93529 public function getArgumentRequiredCount()
 93530 {
 93531 return $this->requiredCount;
 93532 }
 93533 
 93534 
 93535 
 93536 
 93537 
 93538 
 93539 public function getArgumentDefaults()
 93540 {
 93541 $values = array();
 93542 foreach ($this->arguments as $argument) {
 93543 $values[$argument->getName()] = $argument->getDefault();
 93544 }
 93545 
 93546 return $values;
 93547 }
 93548 
 93549 
 93550 
 93551 
 93552 
 93553 
 93554 public function setOptions($options = array())
 93555 {
 93556 $this->options = array();
 93557 $this->shortcuts = array();
 93558 $this->addOptions($options);
 93559 }
 93560 
 93561 
 93562 
 93563 
 93564 
 93565 
 93566 public function addOptions($options = array())
 93567 {
 93568 foreach ($options as $option) {
 93569 $this->addOption($option);
 93570 }
 93571 }
 93572 
 93573 
 93574 
 93575 
 93576 public function addOption(InputOption $option)
 93577 {
 93578 if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
 93579 throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
 93580 }
 93581 
 93582 if ($option->getShortcut()) {
 93583 foreach (explode('|', $option->getShortcut()) as $shortcut) {
 93584 if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
 93585 throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
 93586 }
 93587 }
 93588 }
 93589 
 93590 $this->options[$option->getName()] = $option;
 93591 if ($option->getShortcut()) {
 93592 foreach (explode('|', $option->getShortcut()) as $shortcut) {
 93593 $this->shortcuts[$shortcut] = $option->getName();
 93594 }
 93595 }
 93596 }
 93597 
 93598 
 93599 
 93600 
 93601 
 93602 
 93603 
 93604 
 93605 
 93606 
 93607 public function getOption($name)
 93608 {
 93609 if (!$this->hasOption($name)) {
 93610 throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
 93611 }
 93612 
 93613 return $this->options[$name];
 93614 }
 93615 
 93616 
 93617 
 93618 
 93619 
 93620 
 93621 
 93622 
 93623 
 93624 
 93625 
 93626 public function hasOption($name)
 93627 {
 93628 return isset($this->options[$name]);
 93629 }
 93630 
 93631 
 93632 
 93633 
 93634 
 93635 
 93636 public function getOptions()
 93637 {
 93638 return $this->options;
 93639 }
 93640 
 93641 
 93642 
 93643 
 93644 
 93645 
 93646 
 93647 
 93648 public function hasShortcut($name)
 93649 {
 93650 return isset($this->shortcuts[$name]);
 93651 }
 93652 
 93653 
 93654 
 93655 
 93656 
 93657 
 93658 
 93659 
 93660 public function getOptionForShortcut($shortcut)
 93661 {
 93662 return $this->getOption($this->shortcutToName($shortcut));
 93663 }
 93664 
 93665 
 93666 
 93667 
 93668 
 93669 
 93670 public function getOptionDefaults()
 93671 {
 93672 $values = array();
 93673 foreach ($this->options as $option) {
 93674 $values[$option->getName()] = $option->getDefault();
 93675 }
 93676 
 93677 return $values;
 93678 }
 93679 
 93680 
 93681 
 93682 
 93683 
 93684 
 93685 
 93686 
 93687 
 93688 
 93689 private function shortcutToName($shortcut)
 93690 {
 93691 if (!isset($this->shortcuts[$shortcut])) {
 93692 throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
 93693 }
 93694 
 93695 return $this->shortcuts[$shortcut];
 93696 }
 93697 
 93698 
 93699 
 93700 
 93701 
 93702 
 93703 
 93704 
 93705 public function getSynopsis($short = false)
 93706 {
 93707 $elements = array();
 93708 
 93709 if ($short && $this->getOptions()) {
 93710 $elements[] = '[options]';
 93711 } elseif (!$short) {
 93712 foreach ($this->getOptions() as $option) {
 93713 $value = '';
 93714 if ($option->acceptValue()) {
 93715 $value = sprintf(
 93716 ' %s%s%s',
 93717 $option->isValueOptional() ? '[' : '',
 93718 strtoupper($option->getName()),
 93719 $option->isValueOptional() ? ']' : ''
 93720 );
 93721 }
 93722 
 93723 $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
 93724 $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
 93725 }
 93726 }
 93727 
 93728 if (\count($elements) && $this->getArguments()) {
 93729 $elements[] = '[--]';
 93730 }
 93731 
 93732 foreach ($this->getArguments() as $argument) {
 93733 $element = '<'.$argument->getName().'>';
 93734 if (!$argument->isRequired()) {
 93735 $element = '['.$element.']';
 93736 } elseif ($argument->isArray()) {
 93737 $element .= ' ('.$element.')';
 93738 }
 93739 
 93740 if ($argument->isArray()) {
 93741 $element .= '...';
 93742 }
 93743 
 93744 $elements[] = $element;
 93745 }
 93746 
 93747 return implode(' ', $elements);
 93748 }
 93749 
 93750 
 93751 
 93752 
 93753 
 93754 
 93755 
 93756 
 93757 public function asText()
 93758 {
 93759 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
 93760 
 93761 $descriptor = new TextDescriptor();
 93762 $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
 93763 $descriptor->describe($output, $this, array('raw_output' => true));
 93764 
 93765 return $output->fetch();
 93766 }
 93767 
 93768 
 93769 
 93770 
 93771 
 93772 
 93773 
 93774 
 93775 
 93776 
 93777 public function asXml($asDom = false)
 93778 {
 93779 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.3 and will be removed in 3.0.', E_USER_DEPRECATED);
 93780 
 93781 $descriptor = new XmlDescriptor();
 93782 
 93783 if ($asDom) {
 93784 return $descriptor->getInputDefinitionDocument($this);
 93785 }
 93786 
 93787 $output = new BufferedOutput();
 93788 $descriptor->describe($output, $this);
 93789 
 93790 return $output->fetch();
 93791 }
 93792 }
 93793 <?php
 93794 
 93795 
 93796 
 93797 
 93798 
 93799 
 93800 
 93801 
 93802 
 93803 
 93804 namespace Symfony\Component\Console\Input;
 93805 
 93806 use Symfony\Component\Console\Exception\InvalidArgumentException;
 93807 use Symfony\Component\Console\Exception\RuntimeException;
 93808 
 93809 
 93810 
 93811 
 93812 
 93813 
 93814 interface InputInterface
 93815 {
 93816 
 93817 
 93818 
 93819 
 93820 
 93821 public function getFirstArgument();
 93822 
 93823 
 93824 
 93825 
 93826 
 93827 
 93828 
 93829 
 93830 
 93831 
 93832 
 93833 
 93834 
 93835 public function hasParameterOption($values);
 93836 
 93837 
 93838 
 93839 
 93840 
 93841 
 93842 
 93843 
 93844 
 93845 
 93846 
 93847 
 93848 
 93849 
 93850 public function getParameterOption($values, $default = false);
 93851 
 93852 
 93853 
 93854 
 93855 
 93856 
 93857 public function bind(InputDefinition $definition);
 93858 
 93859 
 93860 
 93861 
 93862 
 93863 
 93864 public function validate();
 93865 
 93866 
 93867 
 93868 
 93869 
 93870 
 93871 public function getArguments();
 93872 
 93873 
 93874 
 93875 
 93876 
 93877 
 93878 
 93879 
 93880 
 93881 
 93882 public function getArgument($name);
 93883 
 93884 
 93885 
 93886 
 93887 
 93888 
 93889 
 93890 
 93891 
 93892 public function setArgument($name, $value);
 93893 
 93894 
 93895 
 93896 
 93897 
 93898 
 93899 
 93900 
 93901 public function hasArgument($name);
 93902 
 93903 
 93904 
 93905 
 93906 
 93907 
 93908 public function getOptions();
 93909 
 93910 
 93911 
 93912 
 93913 
 93914 
 93915 
 93916 
 93917 
 93918 
 93919 public function getOption($name);
 93920 
 93921 
 93922 
 93923 
 93924 
 93925 
 93926 
 93927 
 93928 
 93929 public function setOption($name, $value);
 93930 
 93931 
 93932 
 93933 
 93934 
 93935 
 93936 
 93937 
 93938 public function hasOption($name);
 93939 
 93940 
 93941 
 93942 
 93943 
 93944 
 93945 public function isInteractive();
 93946 
 93947 
 93948 
 93949 
 93950 
 93951 
 93952 public function setInteractive($interactive);
 93953 }
 93954 <?php
 93955 
 93956 
 93957 
 93958 
 93959 
 93960 
 93961 
 93962 
 93963 
 93964 
 93965 namespace Symfony\Component\Console\Input;
 93966 
 93967 use Symfony\Component\Console\Exception\InvalidArgumentException;
 93968 use Symfony\Component\Console\Exception\LogicException;
 93969 
 93970 
 93971 
 93972 
 93973 
 93974 
 93975 class InputOption
 93976 {
 93977 const VALUE_NONE = 1;
 93978 const VALUE_REQUIRED = 2;
 93979 const VALUE_OPTIONAL = 4;
 93980 const VALUE_IS_ARRAY = 8;
 93981 
 93982 private $name;
 93983 private $shortcut;
 93984 private $mode;
 93985 private $default;
 93986 private $description;
 93987 
 93988 
 93989 
 93990 
 93991 
 93992 
 93993 
 93994 
 93995 
 93996 
 93997 public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
 93998 {
 93999 if (0 === strpos($name, '--')) {
 94000 $name = substr($name, 2);
 94001 }
 94002 
 94003 if (empty($name)) {
 94004 throw new InvalidArgumentException('An option name cannot be empty.');
 94005 }
 94006 
 94007 if (empty($shortcut)) {
 94008 $shortcut = null;
 94009 }
 94010 
 94011 if (null !== $shortcut) {
 94012 if (\is_array($shortcut)) {
 94013 $shortcut = implode('|', $shortcut);
 94014 }
 94015 $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
 94016 $shortcuts = array_filter($shortcuts);
 94017 $shortcut = implode('|', $shortcuts);
 94018 
 94019 if (empty($shortcut)) {
 94020 throw new InvalidArgumentException('An option shortcut cannot be empty.');
 94021 }
 94022 }
 94023 
 94024 if (null === $mode) {
 94025 $mode = self::VALUE_NONE;
 94026 } elseif (!\is_int($mode) || $mode > 15 || $mode < 1) {
 94027 throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
 94028 }
 94029 
 94030 $this->name = $name;
 94031 $this->shortcut = $shortcut;
 94032 $this->mode = $mode;
 94033 $this->description = $description;
 94034 
 94035 if ($this->isArray() && !$this->acceptValue()) {
 94036 throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
 94037 }
 94038 
 94039 $this->setDefault($default);
 94040 }
 94041 
 94042 
 94043 
 94044 
 94045 
 94046 
 94047 public function getShortcut()
 94048 {
 94049 return $this->shortcut;
 94050 }
 94051 
 94052 
 94053 
 94054 
 94055 
 94056 
 94057 public function getName()
 94058 {
 94059 return $this->name;
 94060 }
 94061 
 94062 
 94063 
 94064 
 94065 
 94066 
 94067 public function acceptValue()
 94068 {
 94069 return $this->isValueRequired() || $this->isValueOptional();
 94070 }
 94071 
 94072 
 94073 
 94074 
 94075 
 94076 
 94077 public function isValueRequired()
 94078 {
 94079 return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
 94080 }
 94081 
 94082 
 94083 
 94084 
 94085 
 94086 
 94087 public function isValueOptional()
 94088 {
 94089 return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
 94090 }
 94091 
 94092 
 94093 
 94094 
 94095 
 94096 
 94097 public function isArray()
 94098 {
 94099 return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
 94100 }
 94101 
 94102 
 94103 
 94104 
 94105 
 94106 
 94107 
 94108 
 94109 public function setDefault($default = null)
 94110 {
 94111 if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
 94112 throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
 94113 }
 94114 
 94115 if ($this->isArray()) {
 94116 if (null === $default) {
 94117 $default = array();
 94118 } elseif (!\is_array($default)) {
 94119 throw new LogicException('A default value for an array option must be an array.');
 94120 }
 94121 }
 94122 
 94123 $this->default = $this->acceptValue() ? $default : false;
 94124 }
 94125 
 94126 
 94127 
 94128 
 94129 
 94130 
 94131 public function getDefault()
 94132 {
 94133 return $this->default;
 94134 }
 94135 
 94136 
 94137 
 94138 
 94139 
 94140 
 94141 public function getDescription()
 94142 {
 94143 return $this->description;
 94144 }
 94145 
 94146 
 94147 
 94148 
 94149 
 94150 
 94151 public function equals(self $option)
 94152 {
 94153 return $option->getName() === $this->getName()
 94154 && $option->getShortcut() === $this->getShortcut()
 94155 && $option->getDefault() === $this->getDefault()
 94156 && $option->isArray() === $this->isArray()
 94157 && $option->isValueRequired() === $this->isValueRequired()
 94158 && $option->isValueOptional() === $this->isValueOptional()
 94159 ;
 94160 }
 94161 }
 94162 <?php
 94163 
 94164 
 94165 
 94166 
 94167 
 94168 
 94169 
 94170 
 94171 
 94172 
 94173 namespace Symfony\Component\Console\Input;
 94174 
 94175 use Symfony\Component\Console\Exception\InvalidArgumentException;
 94176 
 94177 
 94178 
 94179 
 94180 
 94181 
 94182 
 94183 
 94184 
 94185 
 94186 class StringInput extends ArgvInput
 94187 {
 94188 const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
 94189 const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
 94190 
 94191 
 94192 
 94193 
 94194 
 94195 
 94196 
 94197 public function __construct($input, InputDefinition $definition = null)
 94198 {
 94199 if ($definition) {
 94200 @trigger_error('The $definition argument of the '.__METHOD__.' method is deprecated and will be removed in 3.0. Set this parameter with the bind() method instead.', E_USER_DEPRECATED);
 94201 }
 94202 
 94203 parent::__construct(array(), null);
 94204 
 94205 $this->setTokens($this->tokenize($input));
 94206 
 94207 if (null !== $definition) {
 94208 $this->bind($definition);
 94209 }
 94210 }
 94211 
 94212 
 94213 
 94214 
 94215 
 94216 
 94217 
 94218 
 94219 
 94220 
 94221 private function tokenize($input)
 94222 {
 94223 $tokens = array();
 94224 $length = \strlen($input);
 94225 $cursor = 0;
 94226 while ($cursor < $length) {
 94227 if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
 94228 } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
 94229 $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, \strlen($match[3]) - 2)));
 94230 } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
 94231 $tokens[] = stripcslashes(substr($match[0], 1, \strlen($match[0]) - 2));
 94232 } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
 94233 $tokens[] = stripcslashes($match[1]);
 94234 } else {
 94235 
 94236 throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
 94237 }
 94238 
 94239 $cursor += \strlen($match[0]);
 94240 }
 94241 
 94242 return $tokens;
 94243 }
 94244 }
 94245 
 94246 Copyright (c) 2004-2018 Fabien Potencier
 94247 
 94248 Permission is hereby granted, free of charge, to any person obtaining a copy
 94249 of this software and associated documentation files (the "Software"), to deal
 94250 in the Software without restriction, including without limitation the rights
 94251 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 94252 copies of the Software, and to permit persons to whom the Software is furnished
 94253 to do so, subject to the following conditions:
 94254 
 94255 The above copyright notice and this permission notice shall be included in all
 94256 copies or substantial portions of the Software.
 94257 
 94258 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 94259 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 94260 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 94261 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 94262 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 94263 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 94264 THE SOFTWARE.
 94265 
 94266 <?php
 94267 
 94268 
 94269 
 94270 
 94271 
 94272 
 94273 
 94274 
 94275 
 94276 
 94277 namespace Symfony\Component\Console\Logger;
 94278 
 94279 use Psr\Log\AbstractLogger;
 94280 use Psr\Log\InvalidArgumentException;
 94281 use Psr\Log\LogLevel;
 94282 use Symfony\Component\Console\Output\ConsoleOutputInterface;
 94283 use Symfony\Component\Console\Output\OutputInterface;
 94284 
 94285 
 94286 
 94287 
 94288 
 94289 
 94290 
 94291 
 94292 class ConsoleLogger extends AbstractLogger
 94293 {
 94294 const INFO = 'info';
 94295 const ERROR = 'error';
 94296 
 94297 private $output;
 94298 private $verbosityLevelMap = array(
 94299 LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
 94300 LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
 94301 LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
 94302 LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
 94303 LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
 94304 LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
 94305 LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
 94306 LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
 94307 );
 94308 private $formatLevelMap = array(
 94309 LogLevel::EMERGENCY => self::ERROR,
 94310 LogLevel::ALERT => self::ERROR,
 94311 LogLevel::CRITICAL => self::ERROR,
 94312 LogLevel::ERROR => self::ERROR,
 94313 LogLevel::WARNING => self::INFO,
 94314 LogLevel::NOTICE => self::INFO,
 94315 LogLevel::INFO => self::INFO,
 94316 LogLevel::DEBUG => self::INFO,
 94317 );
 94318 
 94319 public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
 94320 {
 94321 $this->output = $output;
 94322 $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
 94323 $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
 94324 }
 94325 
 94326 
 94327 
 94328 
 94329 public function log($level, $message, array $context = array())
 94330 {
 94331 if (!isset($this->verbosityLevelMap[$level])) {
 94332 throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
 94333 }
 94334 
 94335 
 94336 if (self::ERROR === $this->formatLevelMap[$level] && $this->output instanceof ConsoleOutputInterface) {
 94337 $output = $this->output->getErrorOutput();
 94338 } else {
 94339 $output = $this->output;
 94340 }
 94341 
 94342 if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
 94343 $output->writeln(sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)));
 94344 }
 94345 }
 94346 
 94347 
 94348 
 94349 
 94350 
 94351 
 94352 
 94353 
 94354 
 94355 
 94356 
 94357 private function interpolate($message, array $context)
 94358 {
 94359 
 94360 $replace = array();
 94361 foreach ($context as $key => $val) {
 94362 if (!\is_array($val) && (!\is_object($val) || method_exists($val, '__toString'))) {
 94363 $replace[sprintf('{%s}', $key)] = $val;
 94364 }
 94365 }
 94366 
 94367 
 94368 return strtr($message, $replace);
 94369 }
 94370 }
 94371 <?php
 94372 
 94373 
 94374 
 94375 
 94376 
 94377 
 94378 
 94379 
 94380 
 94381 
 94382 namespace Symfony\Component\Console\Output;
 94383 
 94384 
 94385 
 94386 
 94387 class BufferedOutput extends Output
 94388 {
 94389 private $buffer = '';
 94390 
 94391 
 94392 
 94393 
 94394 
 94395 
 94396 public function fetch()
 94397 {
 94398 $content = $this->buffer;
 94399 $this->buffer = '';
 94400 
 94401 return $content;
 94402 }
 94403 
 94404 
 94405 
 94406 
 94407 protected function doWrite($message, $newline)
 94408 {
 94409 $this->buffer .= $message;
 94410 
 94411 if ($newline) {
 94412 $this->buffer .= PHP_EOL;
 94413 }
 94414 }
 94415 }
 94416 <?php
 94417 
 94418 
 94419 
 94420 
 94421 
 94422 
 94423 
 94424 
 94425 
 94426 
 94427 namespace Symfony\Component\Console\Output;
 94428 
 94429 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 94430 
 94431 
 94432 
 94433 
 94434 
 94435 
 94436 
 94437 
 94438 
 94439 
 94440 
 94441 
 94442 
 94443 
 94444 class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
 94445 {
 94446 private $stderr;
 94447 
 94448 
 94449 
 94450 
 94451 
 94452 
 94453 public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
 94454 {
 94455 parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
 94456 
 94457 $actualDecorated = $this->isDecorated();
 94458 $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
 94459 
 94460 if (null === $decorated) {
 94461 $this->setDecorated($actualDecorated && $this->stderr->isDecorated());
 94462 }
 94463 }
 94464 
 94465 
 94466 
 94467 
 94468 public function setDecorated($decorated)
 94469 {
 94470 parent::setDecorated($decorated);
 94471 $this->stderr->setDecorated($decorated);
 94472 }
 94473 
 94474 
 94475 
 94476 
 94477 public function setFormatter(OutputFormatterInterface $formatter)
 94478 {
 94479 parent::setFormatter($formatter);
 94480 $this->stderr->setFormatter($formatter);
 94481 }
 94482 
 94483 
 94484 
 94485 
 94486 public function setVerbosity($level)
 94487 {
 94488 parent::setVerbosity($level);
 94489 $this->stderr->setVerbosity($level);
 94490 }
 94491 
 94492 
 94493 
 94494 
 94495 public function getErrorOutput()
 94496 {
 94497 return $this->stderr;
 94498 }
 94499 
 94500 
 94501 
 94502 
 94503 public function setErrorOutput(OutputInterface $error)
 94504 {
 94505 $this->stderr = $error;
 94506 }
 94507 
 94508 
 94509 
 94510 
 94511 
 94512 
 94513 
 94514 protected function hasStdoutSupport()
 94515 {
 94516 return false === $this->isRunningOS400();
 94517 }
 94518 
 94519 
 94520 
 94521 
 94522 
 94523 
 94524 
 94525 protected function hasStderrSupport()
 94526 {
 94527 return false === $this->isRunningOS400();
 94528 }
 94529 
 94530 
 94531 
 94532 
 94533 
 94534 
 94535 
 94536 private function isRunningOS400()
 94537 {
 94538 $checks = array(
 94539 \function_exists('php_uname') ? php_uname('s') : '',
 94540 getenv('OSTYPE'),
 94541 PHP_OS,
 94542 );
 94543 
 94544 return false !== stripos(implode(';', $checks), 'OS400');
 94545 }
 94546 
 94547 
 94548 
 94549 
 94550 private function openOutputStream()
 94551 {
 94552 $outputStream = $this->hasStdoutSupport() ? 'php://stdout' : 'php://output';
 94553 
 94554 return @fopen($outputStream, 'w') ?: fopen('php://output', 'w');
 94555 }
 94556 
 94557 
 94558 
 94559 
 94560 private function openErrorStream()
 94561 {
 94562 $errorStream = $this->hasStderrSupport() ? 'php://stderr' : 'php://output';
 94563 
 94564 return fopen($errorStream, 'w');
 94565 }
 94566 }
 94567 <?php
 94568 
 94569 
 94570 
 94571 
 94572 
 94573 
 94574 
 94575 
 94576 
 94577 
 94578 namespace Symfony\Component\Console\Output;
 94579 
 94580 
 94581 
 94582 
 94583 
 94584 
 94585 
 94586 interface ConsoleOutputInterface extends OutputInterface
 94587 {
 94588 
 94589 
 94590 
 94591 
 94592 
 94593 public function getErrorOutput();
 94594 
 94595 public function setErrorOutput(OutputInterface $error);
 94596 }
 94597 <?php
 94598 
 94599 
 94600 
 94601 
 94602 
 94603 
 94604 
 94605 
 94606 
 94607 
 94608 namespace Symfony\Component\Console\Output;
 94609 
 94610 use Symfony\Component\Console\Formatter\OutputFormatter;
 94611 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 94612 
 94613 
 94614 
 94615 
 94616 
 94617 
 94618 
 94619 
 94620 
 94621 class NullOutput implements OutputInterface
 94622 {
 94623 
 94624 
 94625 
 94626 public function setFormatter(OutputFormatterInterface $formatter)
 94627 {
 94628 
 94629 }
 94630 
 94631 
 94632 
 94633 
 94634 public function getFormatter()
 94635 {
 94636 
 94637 return new OutputFormatter();
 94638 }
 94639 
 94640 
 94641 
 94642 
 94643 public function setDecorated($decorated)
 94644 {
 94645 
 94646 }
 94647 
 94648 
 94649 
 94650 
 94651 public function isDecorated()
 94652 {
 94653 return false;
 94654 }
 94655 
 94656 
 94657 
 94658 
 94659 public function setVerbosity($level)
 94660 {
 94661 
 94662 }
 94663 
 94664 
 94665 
 94666 
 94667 public function getVerbosity()
 94668 {
 94669 return self::VERBOSITY_QUIET;
 94670 }
 94671 
 94672 
 94673 
 94674 
 94675 public function isQuiet()
 94676 {
 94677 return true;
 94678 }
 94679 
 94680 
 94681 
 94682 
 94683 public function isVerbose()
 94684 {
 94685 return false;
 94686 }
 94687 
 94688 
 94689 
 94690 
 94691 public function isVeryVerbose()
 94692 {
 94693 return false;
 94694 }
 94695 
 94696 
 94697 
 94698 
 94699 public function isDebug()
 94700 {
 94701 return false;
 94702 }
 94703 
 94704 
 94705 
 94706 
 94707 public function writeln($messages, $options = self::OUTPUT_NORMAL)
 94708 {
 94709 
 94710 }
 94711 
 94712 
 94713 
 94714 
 94715 public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
 94716 {
 94717 
 94718 }
 94719 }
 94720 <?php
 94721 
 94722 
 94723 
 94724 
 94725 
 94726 
 94727 
 94728 
 94729 
 94730 
 94731 namespace Symfony\Component\Console\Output;
 94732 
 94733 use Symfony\Component\Console\Formatter\OutputFormatter;
 94734 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 94735 
 94736 
 94737 
 94738 
 94739 
 94740 
 94741 
 94742 
 94743 
 94744 
 94745 
 94746 
 94747 
 94748 
 94749 abstract class Output implements OutputInterface
 94750 {
 94751 private $verbosity;
 94752 private $formatter;
 94753 
 94754 
 94755 
 94756 
 94757 
 94758 
 94759 public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
 94760 {
 94761 $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
 94762 $this->formatter = $formatter ?: new OutputFormatter();
 94763 $this->formatter->setDecorated($decorated);
 94764 }
 94765 
 94766 
 94767 
 94768 
 94769 public function setFormatter(OutputFormatterInterface $formatter)
 94770 {
 94771 $this->formatter = $formatter;
 94772 }
 94773 
 94774 
 94775 
 94776 
 94777 public function getFormatter()
 94778 {
 94779 return $this->formatter;
 94780 }
 94781 
 94782 
 94783 
 94784 
 94785 public function setDecorated($decorated)
 94786 {
 94787 $this->formatter->setDecorated($decorated);
 94788 }
 94789 
 94790 
 94791 
 94792 
 94793 public function isDecorated()
 94794 {
 94795 return $this->formatter->isDecorated();
 94796 }
 94797 
 94798 
 94799 
 94800 
 94801 public function setVerbosity($level)
 94802 {
 94803 $this->verbosity = (int) $level;
 94804 }
 94805 
 94806 
 94807 
 94808 
 94809 public function getVerbosity()
 94810 {
 94811 return $this->verbosity;
 94812 }
 94813 
 94814 
 94815 
 94816 
 94817 public function isQuiet()
 94818 {
 94819 return self::VERBOSITY_QUIET === $this->verbosity;
 94820 }
 94821 
 94822 
 94823 
 94824 
 94825 public function isVerbose()
 94826 {
 94827 return self::VERBOSITY_VERBOSE <= $this->verbosity;
 94828 }
 94829 
 94830 
 94831 
 94832 
 94833 public function isVeryVerbose()
 94834 {
 94835 return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
 94836 }
 94837 
 94838 
 94839 
 94840 
 94841 public function isDebug()
 94842 {
 94843 return self::VERBOSITY_DEBUG <= $this->verbosity;
 94844 }
 94845 
 94846 
 94847 
 94848 
 94849 public function writeln($messages, $options = self::OUTPUT_NORMAL)
 94850 {
 94851 $this->write($messages, true, $options);
 94852 }
 94853 
 94854 
 94855 
 94856 
 94857 public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
 94858 {
 94859 $messages = (array) $messages;
 94860 
 94861 $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
 94862 $type = $types & $options ?: self::OUTPUT_NORMAL;
 94863 
 94864 $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
 94865 $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;
 94866 
 94867 if ($verbosity > $this->getVerbosity()) {
 94868 return;
 94869 }
 94870 
 94871 foreach ($messages as $message) {
 94872 switch ($type) {
 94873 case OutputInterface::OUTPUT_NORMAL:
 94874 $message = $this->formatter->format($message);
 94875 break;
 94876 case OutputInterface::OUTPUT_RAW:
 94877 break;
 94878 case OutputInterface::OUTPUT_PLAIN:
 94879 $message = strip_tags($this->formatter->format($message));
 94880 break;
 94881 }
 94882 
 94883 $this->doWrite($message, $newline);
 94884 }
 94885 }
 94886 
 94887 
 94888 
 94889 
 94890 
 94891 
 94892 
 94893 abstract protected function doWrite($message, $newline);
 94894 }
 94895 <?php
 94896 
 94897 
 94898 
 94899 
 94900 
 94901 
 94902 
 94903 
 94904 
 94905 
 94906 namespace Symfony\Component\Console\Output;
 94907 
 94908 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 94909 
 94910 
 94911 
 94912 
 94913 
 94914 
 94915 interface OutputInterface
 94916 {
 94917 const VERBOSITY_QUIET = 16;
 94918 const VERBOSITY_NORMAL = 32;
 94919 const VERBOSITY_VERBOSE = 64;
 94920 const VERBOSITY_VERY_VERBOSE = 128;
 94921 const VERBOSITY_DEBUG = 256;
 94922 
 94923 const OUTPUT_NORMAL = 1;
 94924 const OUTPUT_RAW = 2;
 94925 const OUTPUT_PLAIN = 4;
 94926 
 94927 
 94928 
 94929 
 94930 
 94931 
 94932 
 94933 
 94934 public function write($messages, $newline = false, $options = 0);
 94935 
 94936 
 94937 
 94938 
 94939 
 94940 
 94941 
 94942 public function writeln($messages, $options = 0);
 94943 
 94944 
 94945 
 94946 
 94947 
 94948 
 94949 public function setVerbosity($level);
 94950 
 94951 
 94952 
 94953 
 94954 
 94955 
 94956 public function getVerbosity();
 94957 
 94958 
 94959 
 94960 
 94961 
 94962 
 94963 public function setDecorated($decorated);
 94964 
 94965 
 94966 
 94967 
 94968 
 94969 
 94970 public function isDecorated();
 94971 
 94972 public function setFormatter(OutputFormatterInterface $formatter);
 94973 
 94974 
 94975 
 94976 
 94977 
 94978 
 94979 public function getFormatter();
 94980 }
 94981 <?php
 94982 
 94983 
 94984 
 94985 
 94986 
 94987 
 94988 
 94989 
 94990 
 94991 
 94992 namespace Symfony\Component\Console\Output;
 94993 
 94994 use Symfony\Component\Console\Exception\InvalidArgumentException;
 94995 use Symfony\Component\Console\Exception\RuntimeException;
 94996 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 94997 
 94998 
 94999 
 95000 
 95001 
 95002 
 95003 
 95004 
 95005 
 95006 
 95007 
 95008 
 95009 
 95010 
 95011 class StreamOutput extends Output
 95012 {
 95013 private $stream;
 95014 
 95015 
 95016 
 95017 
 95018 
 95019 
 95020 
 95021 
 95022 
 95023 public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
 95024 {
 95025 if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
 95026 throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
 95027 }
 95028 
 95029 $this->stream = $stream;
 95030 
 95031 if (null === $decorated) {
 95032 $decorated = $this->hasColorSupport();
 95033 }
 95034 
 95035 parent::__construct($verbosity, $decorated, $formatter);
 95036 }
 95037 
 95038 
 95039 
 95040 
 95041 
 95042 
 95043 public function getStream()
 95044 {
 95045 return $this->stream;
 95046 }
 95047 
 95048 
 95049 
 95050 
 95051 protected function doWrite($message, $newline)
 95052 {
 95053 if ($newline) {
 95054 $message .= PHP_EOL;
 95055 }
 95056 
 95057 if (false === @fwrite($this->stream, $message)) {
 95058 
 95059 throw new RuntimeException('Unable to write output.');
 95060 }
 95061 
 95062 fflush($this->stream);
 95063 }
 95064 
 95065 
 95066 
 95067 
 95068 
 95069 
 95070 
 95071 
 95072 
 95073 
 95074 
 95075 
 95076 
 95077 
 95078 protected function hasColorSupport()
 95079 {
 95080 if ('Hyper' === getenv('TERM_PROGRAM')) {
 95081 return true;
 95082 }
 95083 
 95084 if (\DIRECTORY_SEPARATOR === '\\') {
 95085 return (\function_exists('sapi_windows_vt100_support')
 95086 && @sapi_windows_vt100_support($this->stream))
 95087 || false !== getenv('ANSICON')
 95088 || 'ON' === getenv('ConEmuANSI')
 95089 || 'xterm' === getenv('TERM');
 95090 }
 95091 
 95092 if (\function_exists('stream_isatty')) {
 95093 return @stream_isatty($this->stream);
 95094 }
 95095 
 95096 if (\function_exists('posix_isatty')) {
 95097 return @posix_isatty($this->stream);
 95098 }
 95099 
 95100 $stat = @fstat($this->stream);
 95101 
 95102 return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
 95103 }
 95104 }
 95105 <?php
 95106 
 95107 
 95108 
 95109 
 95110 
 95111 
 95112 
 95113 
 95114 
 95115 
 95116 namespace Symfony\Component\Console\Question;
 95117 
 95118 use Symfony\Component\Console\Exception\InvalidArgumentException;
 95119 
 95120 
 95121 
 95122 
 95123 
 95124 
 95125 class ChoiceQuestion extends Question
 95126 {
 95127 private $choices;
 95128 private $multiselect = false;
 95129 private $prompt = ' > ';
 95130 private $errorMessage = 'Value "%s" is invalid';
 95131 
 95132 
 95133 
 95134 
 95135 
 95136 
 95137 public function __construct($question, array $choices, $default = null)
 95138 {
 95139 if (!$choices) {
 95140 throw new \LogicException('Choice question must have at least 1 choice available.');
 95141 }
 95142 
 95143 parent::__construct($question, $default);
 95144 
 95145 $this->choices = $choices;
 95146 $this->setValidator($this->getDefaultValidator());
 95147 $this->setAutocompleterValues($choices);
 95148 }
 95149 
 95150 
 95151 
 95152 
 95153 
 95154 
 95155 public function getChoices()
 95156 {
 95157 return $this->choices;
 95158 }
 95159 
 95160 
 95161 
 95162 
 95163 
 95164 
 95165 
 95166 
 95167 
 95168 
 95169 public function setMultiselect($multiselect)
 95170 {
 95171 $this->multiselect = $multiselect;
 95172 $this->setValidator($this->getDefaultValidator());
 95173 
 95174 return $this;
 95175 }
 95176 
 95177 
 95178 
 95179 
 95180 
 95181 
 95182 public function isMultiselect()
 95183 {
 95184 return $this->multiselect;
 95185 }
 95186 
 95187 
 95188 
 95189 
 95190 
 95191 
 95192 public function getPrompt()
 95193 {
 95194 return $this->prompt;
 95195 }
 95196 
 95197 
 95198 
 95199 
 95200 
 95201 
 95202 
 95203 
 95204 public function setPrompt($prompt)
 95205 {
 95206 $this->prompt = $prompt;
 95207 
 95208 return $this;
 95209 }
 95210 
 95211 
 95212 
 95213 
 95214 
 95215 
 95216 
 95217 
 95218 
 95219 
 95220 public function setErrorMessage($errorMessage)
 95221 {
 95222 $this->errorMessage = $errorMessage;
 95223 $this->setValidator($this->getDefaultValidator());
 95224 
 95225 return $this;
 95226 }
 95227 
 95228 
 95229 
 95230 
 95231 
 95232 
 95233 private function getDefaultValidator()
 95234 {
 95235 $choices = $this->choices;
 95236 $errorMessage = $this->errorMessage;
 95237 $multiselect = $this->multiselect;
 95238 $isAssoc = $this->isAssoc($choices);
 95239 
 95240 return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
 95241 
 95242 $selectedChoices = str_replace(' ', '', $selected);
 95243 
 95244 if ($multiselect) {
 95245 
 95246 if (!preg_match('/^[^,]+(?:,[^,]+)*$/', $selectedChoices, $matches)) {
 95247 throw new InvalidArgumentException(sprintf($errorMessage, $selected));
 95248 }
 95249 $selectedChoices = explode(',', $selectedChoices);
 95250 } else {
 95251 $selectedChoices = array($selected);
 95252 }
 95253 
 95254 $multiselectChoices = array();
 95255 foreach ($selectedChoices as $value) {
 95256 $results = array();
 95257 foreach ($choices as $key => $choice) {
 95258 if ($choice === $value) {
 95259 $results[] = $key;
 95260 }
 95261 }
 95262 
 95263 if (\count($results) > 1) {
 95264 throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
 95265 }
 95266 
 95267 $result = array_search($value, $choices);
 95268 
 95269 if (!$isAssoc) {
 95270 if (false !== $result) {
 95271 $result = $choices[$result];
 95272 } elseif (isset($choices[$value])) {
 95273 $result = $choices[$value];
 95274 }
 95275 } elseif (false === $result && isset($choices[$value])) {
 95276 $result = $value;
 95277 }
 95278 
 95279 if (false === $result) {
 95280 throw new InvalidArgumentException(sprintf($errorMessage, $value));
 95281 }
 95282 
 95283 $multiselectChoices[] = (string) $result;
 95284 }
 95285 
 95286 if ($multiselect) {
 95287 return $multiselectChoices;
 95288 }
 95289 
 95290 return current($multiselectChoices);
 95291 };
 95292 }
 95293 }
 95294 <?php
 95295 
 95296 
 95297 
 95298 
 95299 
 95300 
 95301 
 95302 
 95303 
 95304 
 95305 namespace Symfony\Component\Console\Question;
 95306 
 95307 
 95308 
 95309 
 95310 
 95311 
 95312 class ConfirmationQuestion extends Question
 95313 {
 95314 private $trueAnswerRegex;
 95315 
 95316 
 95317 
 95318 
 95319 
 95320 
 95321 public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')
 95322 {
 95323 parent::__construct($question, (bool) $default);
 95324 
 95325 $this->trueAnswerRegex = $trueAnswerRegex;
 95326 $this->setNormalizer($this->getDefaultNormalizer());
 95327 }
 95328 
 95329 
 95330 
 95331 
 95332 
 95333 
 95334 private function getDefaultNormalizer()
 95335 {
 95336 $default = $this->getDefault();
 95337 $regex = $this->trueAnswerRegex;
 95338 
 95339 return function ($answer) use ($default, $regex) {
 95340 if (\is_bool($answer)) {
 95341 return $answer;
 95342 }
 95343 
 95344 $answerIsTrue = (bool) preg_match($regex, $answer);
 95345 if (false === $default) {
 95346 return $answer && $answerIsTrue;
 95347 }
 95348 
 95349 return !$answer || $answerIsTrue;
 95350 };
 95351 }
 95352 }
 95353 <?php
 95354 
 95355 
 95356 
 95357 
 95358 
 95359 
 95360 
 95361 
 95362 
 95363 
 95364 namespace Symfony\Component\Console\Question;
 95365 
 95366 use Symfony\Component\Console\Exception\InvalidArgumentException;
 95367 use Symfony\Component\Console\Exception\LogicException;
 95368 
 95369 
 95370 
 95371 
 95372 
 95373 
 95374 class Question
 95375 {
 95376 private $question;
 95377 private $attempts;
 95378 private $hidden = false;
 95379 private $hiddenFallback = true;
 95380 private $autocompleterValues;
 95381 private $validator;
 95382 private $default;
 95383 private $normalizer;
 95384 
 95385 
 95386 
 95387 
 95388 
 95389 public function __construct($question, $default = null)
 95390 {
 95391 $this->question = $question;
 95392 $this->default = $default;
 95393 }
 95394 
 95395 
 95396 
 95397 
 95398 
 95399 
 95400 public function getQuestion()
 95401 {
 95402 return $this->question;
 95403 }
 95404 
 95405 
 95406 
 95407 
 95408 
 95409 
 95410 public function getDefault()
 95411 {
 95412 return $this->default;
 95413 }
 95414 
 95415 
 95416 
 95417 
 95418 
 95419 
 95420 public function isHidden()
 95421 {
 95422 return $this->hidden;
 95423 }
 95424 
 95425 
 95426 
 95427 
 95428 
 95429 
 95430 
 95431 
 95432 
 95433 
 95434 public function setHidden($hidden)
 95435 {
 95436 if ($this->autocompleterValues) {
 95437 throw new LogicException('A hidden question cannot use the autocompleter.');
 95438 }
 95439 
 95440 $this->hidden = (bool) $hidden;
 95441 
 95442 return $this;
 95443 }
 95444 
 95445 
 95446 
 95447 
 95448 
 95449 
 95450 public function isHiddenFallback()
 95451 {
 95452 return $this->hiddenFallback;
 95453 }
 95454 
 95455 
 95456 
 95457 
 95458 
 95459 
 95460 
 95461 
 95462 public function setHiddenFallback($fallback)
 95463 {
 95464 $this->hiddenFallback = (bool) $fallback;
 95465 
 95466 return $this;
 95467 }
 95468 
 95469 
 95470 
 95471 
 95472 
 95473 
 95474 public function getAutocompleterValues()
 95475 {
 95476 return $this->autocompleterValues;
 95477 }
 95478 
 95479 
 95480 
 95481 
 95482 
 95483 
 95484 
 95485 
 95486 
 95487 
 95488 
 95489 public function setAutocompleterValues($values)
 95490 {
 95491 if (\is_array($values)) {
 95492 $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
 95493 }
 95494 
 95495 if (null !== $values && !\is_array($values) && !$values instanceof \Traversable) {
 95496 throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or a `Traversable` object.');
 95497 }
 95498 
 95499 if ($this->hidden) {
 95500 throw new LogicException('A hidden question cannot use the autocompleter.');
 95501 }
 95502 
 95503 $this->autocompleterValues = $values;
 95504 
 95505 return $this;
 95506 }
 95507 
 95508 
 95509 
 95510 
 95511 
 95512 
 95513 
 95514 
 95515 public function setValidator($validator)
 95516 {
 95517 $this->validator = $validator;
 95518 
 95519 return $this;
 95520 }
 95521 
 95522 
 95523 
 95524 
 95525 
 95526 
 95527 public function getValidator()
 95528 {
 95529 return $this->validator;
 95530 }
 95531 
 95532 
 95533 
 95534 
 95535 
 95536 
 95537 
 95538 
 95539 
 95540 
 95541 
 95542 
 95543 public function setMaxAttempts($attempts)
 95544 {
 95545 if (null !== $attempts && $attempts < 1) {
 95546 throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
 95547 }
 95548 
 95549 $this->attempts = $attempts;
 95550 
 95551 return $this;
 95552 }
 95553 
 95554 
 95555 
 95556 
 95557 
 95558 
 95559 
 95560 
 95561 public function getMaxAttempts()
 95562 {
 95563 return $this->attempts;
 95564 }
 95565 
 95566 
 95567 
 95568 
 95569 
 95570 
 95571 
 95572 
 95573 
 95574 
 95575 public function setNormalizer($normalizer)
 95576 {
 95577 $this->normalizer = $normalizer;
 95578 
 95579 return $this;
 95580 }
 95581 
 95582 
 95583 
 95584 
 95585 
 95586 
 95587 
 95588 
 95589 public function getNormalizer()
 95590 {
 95591 return $this->normalizer;
 95592 }
 95593 
 95594 protected function isAssoc($array)
 95595 {
 95596 return (bool) \count(array_filter(array_keys($array), 'is_string'));
 95597 }
 95598 }
 95599 MZ����@���  �!�L�!This program cannot be run in DOS mode.
 95600 
 95601 $�,�;�B�;�B�;�B�2�מ:�B�2���-�B�2�ƞ9�B�2�ў?�B�a9�8�B�;�C��B�2�Ȟ:�B�2�֞:�B�2�Ӟ:�B�Rich;�B�PEL�MoO�    
 95602 8 @`?�@��"P@ Pp!8!@ �.text     
 95603  `.rdata�  
 95604 @@.data�0@�.rsrc @@@.reloc�P"@Bj$��@�xj�� @�e����E�PV� @�EЃ��PV� @�M��X @�e��E�P�5H @�L @YY�5\ @�E�P�5` @�D @YY���P @�M���M��T @3��H�;
 95605 0@u���h�@��l3@�$40@�5h3@�40@h$0@h(0@h 0@�� @���00@��}j�Y�jh"@�3ۉ]�d��p�]俀3@SVW�0 @;�t;�u3�F�u��h��4 @��3�F�|3@;�u
 95606 j�\Y�;�|3@��u,�5|3@h� @h� @�YY��t�E����������5<0@�|3@;�uh� @h� @�lYY�|3@9]�uSW�8 @9�3@th�3@�Y��t
 95607 SjS��3@�$0@�
 95608 � @��5$0@�5(0@�5 0@�������80@9,0@u7P�� @�E��       �M�PQ�YYËe�E�80@3�9,0@uP�h @9<0@u�� @�E������80@��øMZf9@t3��M�<@��@�8PEu��H��t��uՃ��v�3�9����xtv�3�9������j�,0@�p @j��l @YY��3@��3@�� @�
 95609 t3@��� @�
 95610 p3@��� @��x3@�V��=0@uh�@�� @Y�g�=0@�u   j��� @Y3���{������U���(�H1@�
 95611 D1@�@1@�<1@�581@�=41@f�`1@f�
 95612 T1@f�01@f�,1@f�%(1@f�-$1@��X1@�E�L1@�E�P1@�E�\1@��������0@�P1@�L0@�@0@ ��D0@�0@�������0@������� @��0@j�?Yj�  @h!@�$ @�=�0@uj�Yh     ��( @P�, @�Ë�U��E��8csm�u*�xu$�@= �t=!�t="�t=@�u��3�]�hH@�  @3���%� @jh("@�b�5�3@�5� @��Y�E���u�u�� @Y�gj�Y�e��5�3@�։E��5�3@��YY�E��E�P�E�P�u�5l @��YP�U�E��u��֣�3@�u��փ���3@�E������        �E���j�YË�U���u�N��������YH]Ë�V��!@��!@W��;�s���t�Ѓ�;�r�_^Ë�V�"@�"@W��;�s���t�Ѓ�;�r�_^��%� @���̋�U��M�MZf9t3�]ËA<��8PEu�3ҹf9H�‹�]�����������̋�U��E�H<��ASV�q3�W�D��v�}�H;�r       �X�;�r
 95613 B��(;�r�3�_^[]������������̋�U��j�hH"@he@d�P��SVW�0@1E�3�P�E�d��e��E�h@�*�������tU�E-@Ph@�P�������t;�@$���Ѓ��E������M�d�
 95614 Y_^[��]ËE��3�=��‹�Ëe��E�����3��M�d�
 95615 Y_^[��]���%� @�%� @��he@d�5�D$�l$�l$+�SVW�0@1E�3�P�e��u��E��E������E��E�d�ËM�d�
 95616 Y__^[��]Q�U���u�u�u�uh�@h0@����]�Vhh3�V������t
 95617 VVVVV����^�3��U����0@�e��e�SW�N�@����;�t
 95618 ��t     �У0@�`V�E�P�< @�u�3u�� @3�� @3�� @3��E�P� @�E�3E�3�;�u�O�@����u������50@�։50@^_[���%t @�%x @�%| @�%� @�%� @�%� @�%� @�%� @�%� @Pd�5�D$+d$SVW�(��0@3�P�E��u��E������E�d�ËM�d�
 95619 Y__^[��]QËM�3�����������M��%T @�T$�B�J�3������J�3������l"@�s����#�#�#�)r)b)H)4))�(�(�(�(�(�(�)�#�$%�%&d&�&�$('�'�'�'�'(((6(�'H(Z(t(�('''�'�'l'^'R'F'>'>(0'�'�)�@W@�@�MoOl�!�@0@�0@bad allocationH0@�!@RSDSь���J�!���LZc:\users\seld\documents\visual studio 2010\Projects\hiddeninp\Release\hiddeninp.pdbe�������������@@������������:@�������������@�@�����@"�d"@�"�# $#�&D H#(h �#�#�#�)r)b)H)4))�(�(�(�(�(�(�)�#�$%�%&d&�&�$('�'�'�'�'(((6(�'H(Z(t(�('''�'�'l'^'R'F'>'>(0'�'�)�GetConsoleMode�SetConsoleMode;GetStdHandleKERNEL32.dll??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z�?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@AJ?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A�??$getline@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@AAV10@AAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ{??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ�?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@ZMSVCP90.dll_amsg_exit�__getmainargs,_cexit|_exitf_XcptFilter�exit�__initenv_initterm_initterm_e<_configthreadlocale�__setusermatherr_adjust_fdiv�__p__commode�__p__fmodej_encode_pointer�__set_app_typeK_crt_debugger_hookC?terminate@@YAXXZMSVCR90.dll�_unlock�__dllonexitv_lock_onexit`_decode_pointers_except_handler4_common_invoke_watson?_controlfp_s�InterlockedExchange!Sleep�InterlockedCompareExchange-TerminateProcess�GetCurrentProcess>UnhandledExceptionFilterSetUnhandledExceptionFilter�IsDebuggerPresentTQueryPerformanceCounterfGetTickCount�GetCurrentThreadId�GetCurrentProcessIdOGetSystemTimeAsFileTimes__CxxFrameHandler3N�@���D������������$!@ �8�P�h�     � ��@(��CV�(4VS_VERSION_INFO����StringFileInfob040904b0�QFileDescriptionReads from stdin without leaking info to the terminal and outputs back to stdout6FileVersion1, 0, 0, 08InternalNamehiddeninputPLegalCopyrightJordi Boggiano - 2012HOriginalFilenamehiddeninput.exe:
 95620 ProductNameHidden Input:ProductVersion1, 0, 0, 0DVarFileInfo$Translation   �<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
 95621   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
 95622     <security>
 95623       <requestedPrivileges>
 95624         <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
 95625       </requestedPrivileges>
 95626     </security>
 95627   </trustInfo>
 95628   <dependency>
 95629     <dependentAssembly>
 95630       <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
 95631     </dependentAssembly>
 95632   </dependency>
 95633 </assembly>PAPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING@00!0/080F0L0T0^0d0n0{0�0�0�0�0�0�0�0�0�0�0�0�0�01#1-1@1J1O1T1v1{1�1�1�1�1�1�1�1�1�1�1�1�1�1�12"2*23292A2M2_2j2p2�2�2�2�2�2�2�2�2�2�2�2333%303N3T3Z3`3f3l3s3z3�3�3�3�3�3�3�3�3�3�3�3�3�3�3�3�34444%4;4B4�4�4�4�4�4�4�4�4�4�45!5^5c5�5�5�5H6M6_6}6�6�677
 95634 7*7w7|7�7�7�7�78
 95635 88=8E8P8V8\8b8h8n8t8z8�8�8�89 $�0�0�01 1t1x12 2@2\2`2h2t200<?php
 95636 
 95637 
 95638 
 95639 
 95640 
 95641 
 95642 
 95643 
 95644 
 95645 
 95646 namespace Symfony\Component\Console;
 95647 
 95648 use Symfony\Component\Console\Exception\RuntimeException;
 95649 use Symfony\Component\Console\Input\StringInput;
 95650 use Symfony\Component\Console\Output\ConsoleOutput;
 95651 use Symfony\Component\Process\PhpExecutableFinder;
 95652 use Symfony\Component\Process\ProcessBuilder;
 95653 
 95654 
 95655 
 95656 
 95657 
 95658 
 95659 
 95660 
 95661 
 95662 
 95663 
 95664 
 95665 class Shell
 95666 {
 95667 private $application;
 95668 private $history;
 95669 private $output;
 95670 private $hasReadline;
 95671 private $processIsolation = false;
 95672 
 95673 
 95674 
 95675 
 95676 
 95677 public function __construct(Application $application)
 95678 {
 95679 @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 95680 
 95681 $this->hasReadline = \function_exists('readline');
 95682 $this->application = $application;
 95683 $this->history = getenv('HOME').'/.history_'.$application->getName();
 95684 $this->output = new ConsoleOutput();
 95685 }
 95686 
 95687 
 95688 
 95689 
 95690 public function run()
 95691 {
 95692 $this->application->setAutoExit(false);
 95693 $this->application->setCatchExceptions(true);
 95694 
 95695 if ($this->hasReadline) {
 95696 readline_read_history($this->history);
 95697 readline_completion_function(array($this, 'autocompleter'));
 95698 }
 95699 
 95700 $this->output->writeln($this->getHeader());
 95701 $php = null;
 95702 if ($this->processIsolation) {
 95703 $finder = new PhpExecutableFinder();
 95704 $php = $finder->find();
 95705 $this->output->writeln(<<<'EOF'
 95706 <info>Running with process isolation, you should consider this:</info>
 95707   * each command is executed as separate process,
 95708   * commands don't support interactivity, all params must be passed explicitly,
 95709   * commands output is not colorized.
 95710 
 95711 EOF
 95712 );
 95713 }
 95714 
 95715 while (true) {
 95716 $command = $this->readline();
 95717 
 95718 if (false === $command) {
 95719 $this->output->writeln("\n");
 95720 
 95721 break;
 95722 }
 95723 
 95724 if ($this->hasReadline) {
 95725 readline_add_history($command);
 95726 readline_write_history($this->history);
 95727 }
 95728 
 95729 if ($this->processIsolation) {
 95730 $pb = new ProcessBuilder();
 95731 
 95732 $process = $pb
 95733 ->add($php)
 95734 ->add($_SERVER['argv'][0])
 95735 ->add($command)
 95736 ->inheritEnvironmentVariables(true)
 95737 ->getProcess()
 95738 ;
 95739 
 95740 $output = $this->output;
 95741 $process->run(function ($type, $data) use ($output) {
 95742 $output->writeln($data);
 95743 });
 95744 
 95745 $ret = $process->getExitCode();
 95746 } else {
 95747 $ret = $this->application->run(new StringInput($command), $this->output);
 95748 }
 95749 
 95750 if (0 !== $ret) {
 95751 $this->output->writeln(sprintf('<error>The command terminated with an error status (%s)</error>', $ret));
 95752 }
 95753 }
 95754 }
 95755 
 95756 
 95757 
 95758 
 95759 
 95760 
 95761 protected function getHeader()
 95762 {
 95763 return <<<EOF
 95764 
 95765 Welcome to the <info>{$this->application->getName()}</info> shell (<comment>{$this->application->getVersion()}</comment>).
 95766 
 95767 At the prompt, type <comment>help</comment> for some help,
 95768 or <comment>list</comment> to get a list of available commands.
 95769 
 95770 To exit the shell, type <comment>^D</comment>.
 95771 
 95772 EOF;
 95773 }
 95774 
 95775 
 95776 
 95777 
 95778 
 95779 
 95780 protected function getPrompt()
 95781 {
 95782 
 95783 return $this->output->getFormatter()->format($this->application->getName().' > ');
 95784 }
 95785 
 95786 protected function getOutput()
 95787 {
 95788 return $this->output;
 95789 }
 95790 
 95791 protected function getApplication()
 95792 {
 95793 return $this->application;
 95794 }
 95795 
 95796 
 95797 
 95798 
 95799 
 95800 
 95801 
 95802 
 95803 private function autocompleter($text)
 95804 {
 95805 $info = readline_info();
 95806 $text = substr($info['line_buffer'], 0, $info['end']);
 95807 
 95808 if ($info['point'] !== $info['end']) {
 95809 return true;
 95810 }
 95811 
 95812 
 95813 if (false === strpos($text, ' ') || !$text) {
 95814 return array_keys($this->application->all());
 95815 }
 95816 
 95817 
 95818 try {
 95819 $command = $this->application->find(substr($text, 0, strpos($text, ' ')));
 95820 } catch (\Exception $e) {
 95821 return true;
 95822 }
 95823 
 95824 $list = array('--help');
 95825 foreach ($command->getDefinition()->getOptions() as $option) {
 95826 $list[] = '--'.$option->getName();
 95827 }
 95828 
 95829 return $list;
 95830 }
 95831 
 95832 
 95833 
 95834 
 95835 
 95836 
 95837 private function readline()
 95838 {
 95839 if ($this->hasReadline) {
 95840 $line = readline($this->getPrompt());
 95841 } else {
 95842 $this->output->write($this->getPrompt());
 95843 $line = fgets(STDIN, 1024);
 95844 $line = (false === $line || '' === $line) ? false : rtrim($line);
 95845 }
 95846 
 95847 return $line;
 95848 }
 95849 
 95850 public function getProcessIsolation()
 95851 {
 95852 return $this->processIsolation;
 95853 }
 95854 
 95855 public function setProcessIsolation($processIsolation)
 95856 {
 95857 $this->processIsolation = (bool) $processIsolation;
 95858 
 95859 if ($this->processIsolation && !class_exists('Symfony\\Component\\Process\\Process')) {
 95860 throw new RuntimeException('Unable to isolate processes as the Symfony Process Component is not installed.');
 95861 }
 95862 }
 95863 }
 95864 <?php
 95865 
 95866 
 95867 
 95868 
 95869 
 95870 
 95871 
 95872 
 95873 
 95874 
 95875 namespace Symfony\Component\Console\Style;
 95876 
 95877 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
 95878 use Symfony\Component\Console\Helper\ProgressBar;
 95879 use Symfony\Component\Console\Output\OutputInterface;
 95880 
 95881 
 95882 
 95883 
 95884 
 95885 
 95886 abstract class OutputStyle implements OutputInterface, StyleInterface
 95887 {
 95888 private $output;
 95889 
 95890 public function __construct(OutputInterface $output)
 95891 {
 95892 $this->output = $output;
 95893 }
 95894 
 95895 
 95896 
 95897 
 95898 public function newLine($count = 1)
 95899 {
 95900 $this->output->write(str_repeat(PHP_EOL, $count));
 95901 }
 95902 
 95903 
 95904 
 95905 
 95906 
 95907 
 95908 public function createProgressBar($max = 0)
 95909 {
 95910 return new ProgressBar($this->output, $max);
 95911 }
 95912 
 95913 
 95914 
 95915 
 95916 public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
 95917 {
 95918 $this->output->write($messages, $newline, $type);
 95919 }
 95920 
 95921 
 95922 
 95923 
 95924 public function writeln($messages, $type = self::OUTPUT_NORMAL)
 95925 {
 95926 $this->output->writeln($messages, $type);
 95927 }
 95928 
 95929 
 95930 
 95931 
 95932 public function setVerbosity($level)
 95933 {
 95934 $this->output->setVerbosity($level);
 95935 }
 95936 
 95937 
 95938 
 95939 
 95940 public function getVerbosity()
 95941 {
 95942 return $this->output->getVerbosity();
 95943 }
 95944 
 95945 
 95946 
 95947 
 95948 public function setDecorated($decorated)
 95949 {
 95950 $this->output->setDecorated($decorated);
 95951 }
 95952 
 95953 
 95954 
 95955 
 95956 public function isDecorated()
 95957 {
 95958 return $this->output->isDecorated();
 95959 }
 95960 
 95961 
 95962 
 95963 
 95964 public function setFormatter(OutputFormatterInterface $formatter)
 95965 {
 95966 $this->output->setFormatter($formatter);
 95967 }
 95968 
 95969 
 95970 
 95971 
 95972 public function getFormatter()
 95973 {
 95974 return $this->output->getFormatter();
 95975 }
 95976 }
 95977 <?php
 95978 
 95979 
 95980 
 95981 
 95982 
 95983 
 95984 
 95985 
 95986 
 95987 
 95988 namespace Symfony\Component\Console\Style;
 95989 
 95990 
 95991 
 95992 
 95993 
 95994 
 95995 interface StyleInterface
 95996 {
 95997 
 95998 
 95999 
 96000 
 96001 
 96002 public function title($message);
 96003 
 96004 
 96005 
 96006 
 96007 
 96008 
 96009 public function section($message);
 96010 
 96011 
 96012 
 96013 
 96014 public function listing(array $elements);
 96015 
 96016 
 96017 
 96018 
 96019 
 96020 
 96021 public function text($message);
 96022 
 96023 
 96024 
 96025 
 96026 
 96027 
 96028 public function success($message);
 96029 
 96030 
 96031 
 96032 
 96033 
 96034 
 96035 public function error($message);
 96036 
 96037 
 96038 
 96039 
 96040 
 96041 
 96042 public function warning($message);
 96043 
 96044 
 96045 
 96046 
 96047 
 96048 
 96049 public function note($message);
 96050 
 96051 
 96052 
 96053 
 96054 
 96055 
 96056 public function caution($message);
 96057 
 96058 
 96059 
 96060 
 96061 public function table(array $headers, array $rows);
 96062 
 96063 
 96064 
 96065 
 96066 
 96067 
 96068 
 96069 
 96070 
 96071 
 96072 public function ask($question, $default = null, $validator = null);
 96073 
 96074 
 96075 
 96076 
 96077 
 96078 
 96079 
 96080 
 96081 
 96082 public function askHidden($question, $validator = null);
 96083 
 96084 
 96085 
 96086 
 96087 
 96088 
 96089 
 96090 
 96091 
 96092 public function confirm($question, $default = true);
 96093 
 96094 
 96095 
 96096 
 96097 
 96098 
 96099 
 96100 
 96101 
 96102 
 96103 public function choice($question, array $choices, $default = null);
 96104 
 96105 
 96106 
 96107 
 96108 
 96109 
 96110 public function newLine($count = 1);
 96111 
 96112 
 96113 
 96114 
 96115 
 96116 
 96117 public function progressStart($max = 0);
 96118 
 96119 
 96120 
 96121 
 96122 
 96123 
 96124 public function progressAdvance($step = 1);
 96125 
 96126 
 96127 
 96128 
 96129 public function progressFinish();
 96130 }
 96131 <?php
 96132 
 96133 
 96134 
 96135 
 96136 
 96137 
 96138 
 96139 
 96140 
 96141 
 96142 namespace Symfony\Component\Console\Style;
 96143 
 96144 use Symfony\Component\Console\Application;
 96145 use Symfony\Component\Console\Exception\RuntimeException;
 96146 use Symfony\Component\Console\Formatter\OutputFormatter;
 96147 use Symfony\Component\Console\Helper\Helper;
 96148 use Symfony\Component\Console\Helper\ProgressBar;
 96149 use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
 96150 use Symfony\Component\Console\Helper\Table;
 96151 use Symfony\Component\Console\Input\InputInterface;
 96152 use Symfony\Component\Console\Output\BufferedOutput;
 96153 use Symfony\Component\Console\Output\OutputInterface;
 96154 use Symfony\Component\Console\Question\ChoiceQuestion;
 96155 use Symfony\Component\Console\Question\ConfirmationQuestion;
 96156 use Symfony\Component\Console\Question\Question;
 96157 
 96158 
 96159 
 96160 
 96161 
 96162 
 96163 class SymfonyStyle extends OutputStyle
 96164 {
 96165 const MAX_LINE_LENGTH = 120;
 96166 
 96167 private $input;
 96168 private $questionHelper;
 96169 private $progressBar;
 96170 private $lineLength;
 96171 private $bufferedOutput;
 96172 
 96173 public function __construct(InputInterface $input, OutputInterface $output)
 96174 {
 96175 $this->input = $input;
 96176 $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
 96177 
 96178 $this->lineLength = min($this->getTerminalWidth() - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
 96179 
 96180 parent::__construct($output);
 96181 }
 96182 
 96183 
 96184 
 96185 
 96186 
 96187 
 96188 
 96189 
 96190 
 96191 
 96192 public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
 96193 {
 96194 $messages = \is_array($messages) ? array_values($messages) : array($messages);
 96195 
 96196 $this->autoPrependBlock();
 96197 $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, true));
 96198 $this->newLine();
 96199 }
 96200 
 96201 
 96202 
 96203 
 96204 public function title($message)
 96205 {
 96206 $this->autoPrependBlock();
 96207 $this->writeln(array(
 96208 sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
 96209 sprintf('<comment>%s</>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
 96210 ));
 96211 $this->newLine();
 96212 }
 96213 
 96214 
 96215 
 96216 
 96217 public function section($message)
 96218 {
 96219 $this->autoPrependBlock();
 96220 $this->writeln(array(
 96221 sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)),
 96222 sprintf('<comment>%s</>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
 96223 ));
 96224 $this->newLine();
 96225 }
 96226 
 96227 
 96228 
 96229 
 96230 public function listing(array $elements)
 96231 {
 96232 $this->autoPrependText();
 96233 $elements = array_map(function ($element) {
 96234 return sprintf(' * %s', $element);
 96235 }, $elements);
 96236 
 96237 $this->writeln($elements);
 96238 $this->newLine();
 96239 }
 96240 
 96241 
 96242 
 96243 
 96244 public function text($message)
 96245 {
 96246 $this->autoPrependText();
 96247 
 96248 $messages = \is_array($message) ? array_values($message) : array($message);
 96249 foreach ($messages as $message) {
 96250 $this->writeln(sprintf(' %s', $message));
 96251 }
 96252 }
 96253 
 96254 
 96255 
 96256 
 96257 
 96258 
 96259 public function comment($message)
 96260 {
 96261 $messages = \is_array($message) ? array_values($message) : array($message);
 96262 
 96263 $this->autoPrependBlock();
 96264 $this->writeln($this->createBlock($messages, null, null, '<fg=default;bg=default> // </>'));
 96265 $this->newLine();
 96266 }
 96267 
 96268 
 96269 
 96270 
 96271 public function success($message)
 96272 {
 96273 $this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
 96274 }
 96275 
 96276 
 96277 
 96278 
 96279 public function error($message)
 96280 {
 96281 $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
 96282 }
 96283 
 96284 
 96285 
 96286 
 96287 public function warning($message)
 96288 {
 96289 $this->block($message, 'WARNING', 'fg=white;bg=red', ' ', true);
 96290 }
 96291 
 96292 
 96293 
 96294 
 96295 public function note($message)
 96296 {
 96297 $this->block($message, 'NOTE', 'fg=yellow', ' ! ');
 96298 }
 96299 
 96300 
 96301 
 96302 
 96303 public function caution($message)
 96304 {
 96305 $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
 96306 }
 96307 
 96308 
 96309 
 96310 
 96311 public function table(array $headers, array $rows)
 96312 {
 96313 $style = clone Table::getStyleDefinition('symfony-style-guide');
 96314 $style->setCellHeaderFormat('<info>%s</info>');
 96315 
 96316 $table = new Table($this);
 96317 $table->setHeaders($headers);
 96318 $table->setRows($rows);
 96319 $table->setStyle($style);
 96320 
 96321 $table->render();
 96322 $this->newLine();
 96323 }
 96324 
 96325 
 96326 
 96327 
 96328 public function ask($question, $default = null, $validator = null)
 96329 {
 96330 $question = new Question($question, $default);
 96331 $question->setValidator($validator);
 96332 
 96333 return $this->askQuestion($question);
 96334 }
 96335 
 96336 
 96337 
 96338 
 96339 public function askHidden($question, $validator = null)
 96340 {
 96341 $question = new Question($question);
 96342 
 96343 $question->setHidden(true);
 96344 $question->setValidator($validator);
 96345 
 96346 return $this->askQuestion($question);
 96347 }
 96348 
 96349 
 96350 
 96351 
 96352 public function confirm($question, $default = true)
 96353 {
 96354 return $this->askQuestion(new ConfirmationQuestion($question, $default));
 96355 }
 96356 
 96357 
 96358 
 96359 
 96360 public function choice($question, array $choices, $default = null)
 96361 {
 96362 if (null !== $default) {
 96363 $values = array_flip($choices);
 96364 $default = $values[$default];
 96365 }
 96366 
 96367 return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
 96368 }
 96369 
 96370 
 96371 
 96372 
 96373 public function progressStart($max = 0)
 96374 {
 96375 $this->progressBar = $this->createProgressBar($max);
 96376 $this->progressBar->start();
 96377 }
 96378 
 96379 
 96380 
 96381 
 96382 public function progressAdvance($step = 1)
 96383 {
 96384 $this->getProgressBar()->advance($step);
 96385 }
 96386 
 96387 
 96388 
 96389 
 96390 public function progressFinish()
 96391 {
 96392 $this->getProgressBar()->finish();
 96393 $this->newLine(2);
 96394 $this->progressBar = null;
 96395 }
 96396 
 96397 
 96398 
 96399 
 96400 public function createProgressBar($max = 0)
 96401 {
 96402 $progressBar = parent::createProgressBar($max);
 96403 
 96404 if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) {
 96405 $progressBar->setEmptyBarCharacter('░'); 
 96406 $progressBar->setProgressCharacter('');
 96407 $progressBar->setBarCharacter('▓'); 
 96408 }
 96409 
 96410 return $progressBar;
 96411 }
 96412 
 96413 
 96414 
 96415 
 96416 public function askQuestion(Question $question)
 96417 {
 96418 if ($this->input->isInteractive()) {
 96419 $this->autoPrependBlock();
 96420 }
 96421 
 96422 if (!$this->questionHelper) {
 96423 $this->questionHelper = new SymfonyQuestionHelper();
 96424 }
 96425 
 96426 $answer = $this->questionHelper->ask($this->input, $this, $question);
 96427 
 96428 if ($this->input->isInteractive()) {
 96429 $this->newLine();
 96430 $this->bufferedOutput->write("\n");
 96431 }
 96432 
 96433 return $answer;
 96434 }
 96435 
 96436 
 96437 
 96438 
 96439 public function writeln($messages, $type = self::OUTPUT_NORMAL)
 96440 {
 96441 parent::writeln($messages, $type);
 96442 $this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
 96443 }
 96444 
 96445 
 96446 
 96447 
 96448 public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
 96449 {
 96450 parent::write($messages, $newline, $type);
 96451 $this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
 96452 }
 96453 
 96454 
 96455 
 96456 
 96457 public function newLine($count = 1)
 96458 {
 96459 parent::newLine($count);
 96460 $this->bufferedOutput->write(str_repeat("\n", $count));
 96461 }
 96462 
 96463 
 96464 
 96465 
 96466 private function getProgressBar()
 96467 {
 96468 if (!$this->progressBar) {
 96469 throw new RuntimeException('The ProgressBar is not started.');
 96470 }
 96471 
 96472 return $this->progressBar;
 96473 }
 96474 
 96475 private function getTerminalWidth()
 96476 {
 96477 $application = new Application();
 96478 $dimensions = $application->getTerminalDimensions();
 96479 
 96480 return $dimensions[0] ?: self::MAX_LINE_LENGTH;
 96481 }
 96482 
 96483 private function autoPrependBlock()
 96484 {
 96485 $chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
 96486 
 96487 if (!isset($chars[0])) {
 96488 return $this->newLine(); 
 96489 }
 96490 
 96491 $this->newLine(2 - substr_count($chars, "\n"));
 96492 }
 96493 
 96494 private function autoPrependText()
 96495 {
 96496 $fetched = $this->bufferedOutput->fetch();
 96497 
 96498 if ("\n" !== substr($fetched, -1)) {
 96499 $this->newLine();
 96500 }
 96501 }
 96502 
 96503 private function reduceBuffer($messages)
 96504 {
 96505 
 96506 
 96507 return array_map(function ($value) {
 96508 return substr($value, -4);
 96509 }, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
 96510 }
 96511 
 96512 private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
 96513 {
 96514 $indentLength = 0;
 96515 $prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
 96516 $lines = array();
 96517 
 96518 if (null !== $type) {
 96519 $type = sprintf('[%s] ', $type);
 96520 $indentLength = \strlen($type);
 96521 $lineIndentation = str_repeat(' ', $indentLength);
 96522 }
 96523 
 96524 
 96525 foreach ($messages as $key => $message) {
 96526 if ($escape) {
 96527 $message = OutputFormatter::escape($message);
 96528 }
 96529 
 96530 $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true)));
 96531 
 96532 if (\count($messages) > 1 && $key < \count($messages) - 1) {
 96533 $lines[] = '';
 96534 }
 96535 }
 96536 
 96537 $firstLineIndex = 0;
 96538 if ($padding && $this->isDecorated()) {
 96539 $firstLineIndex = 1;
 96540 array_unshift($lines, '');
 96541 $lines[] = '';
 96542 }
 96543 
 96544 foreach ($lines as $i => &$line) {
 96545 if (null !== $type) {
 96546 $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
 96547 }
 96548 
 96549 $line = $prefix.$line;
 96550 $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
 96551 
 96552 if ($style) {
 96553 $line = sprintf('<%s>%s</>', $style, $line);
 96554 }
 96555 }
 96556 
 96557 return $lines;
 96558 }
 96559 }
 96560 <?php
 96561 
 96562 
 96563 
 96564 
 96565 
 96566 
 96567 
 96568 
 96569 
 96570 
 96571 namespace Symfony\Component\Console\Tester;
 96572 
 96573 use Symfony\Component\Console\Application;
 96574 use Symfony\Component\Console\Input\ArrayInput;
 96575 use Symfony\Component\Console\Input\InputInterface;
 96576 use Symfony\Component\Console\Output\OutputInterface;
 96577 use Symfony\Component\Console\Output\StreamOutput;
 96578 
 96579 
 96580 
 96581 
 96582 
 96583 
 96584 
 96585 
 96586 
 96587 
 96588 
 96589 class ApplicationTester
 96590 {
 96591 private $application;
 96592 private $input;
 96593 private $output;
 96594 private $statusCode;
 96595 
 96596 public function __construct(Application $application)
 96597 {
 96598 $this->application = $application;
 96599 }
 96600 
 96601 
 96602 
 96603 
 96604 
 96605 
 96606 
 96607 
 96608 
 96609 
 96610 
 96611 
 96612 
 96613 
 96614 
 96615 public function run(array $input, $options = array())
 96616 {
 96617 $this->input = new ArrayInput($input);
 96618 if (isset($options['interactive'])) {
 96619 $this->input->setInteractive($options['interactive']);
 96620 }
 96621 
 96622 $this->output = new StreamOutput(fopen('php://memory', 'w', false));
 96623 if (isset($options['decorated'])) {
 96624 $this->output->setDecorated($options['decorated']);
 96625 }
 96626 if (isset($options['verbosity'])) {
 96627 $this->output->setVerbosity($options['verbosity']);
 96628 }
 96629 
 96630 return $this->statusCode = $this->application->run($this->input, $this->output);
 96631 }
 96632 
 96633 
 96634 
 96635 
 96636 
 96637 
 96638 
 96639 
 96640 public function getDisplay($normalize = false)
 96641 {
 96642 rewind($this->output->getStream());
 96643 
 96644 $display = stream_get_contents($this->output->getStream());
 96645 
 96646 if ($normalize) {
 96647 $display = str_replace(PHP_EOL, "\n", $display);
 96648 }
 96649 
 96650 return $display;
 96651 }
 96652 
 96653 
 96654 
 96655 
 96656 
 96657 
 96658 public function getInput()
 96659 {
 96660 return $this->input;
 96661 }
 96662 
 96663 
 96664 
 96665 
 96666 
 96667 
 96668 public function getOutput()
 96669 {
 96670 return $this->output;
 96671 }
 96672 
 96673 
 96674 
 96675 
 96676 
 96677 
 96678 public function getStatusCode()
 96679 {
 96680 return $this->statusCode;
 96681 }
 96682 }
 96683 <?php
 96684 
 96685 
 96686 
 96687 
 96688 
 96689 
 96690 
 96691 
 96692 
 96693 
 96694 namespace Symfony\Component\Console\Tester;
 96695 
 96696 use Symfony\Component\Console\Command\Command;
 96697 use Symfony\Component\Console\Input\ArrayInput;
 96698 use Symfony\Component\Console\Input\InputInterface;
 96699 use Symfony\Component\Console\Output\OutputInterface;
 96700 use Symfony\Component\Console\Output\StreamOutput;
 96701 
 96702 
 96703 
 96704 
 96705 
 96706 
 96707 class CommandTester
 96708 {
 96709 private $command;
 96710 private $input;
 96711 private $output;
 96712 private $statusCode;
 96713 
 96714 public function __construct(Command $command)
 96715 {
 96716 $this->command = $command;
 96717 }
 96718 
 96719 
 96720 
 96721 
 96722 
 96723 
 96724 
 96725 
 96726 
 96727 
 96728 
 96729 
 96730 
 96731 
 96732 
 96733 public function execute(array $input, array $options = array())
 96734 {
 96735 
 96736 
 96737 if (!isset($input['command'])
 96738 && (null !== $application = $this->command->getApplication())
 96739 && $application->getDefinition()->hasArgument('command')
 96740 ) {
 96741 $input = array_merge(array('command' => $this->command->getName()), $input);
 96742 }
 96743 
 96744 $this->input = new ArrayInput($input);
 96745 if (isset($options['interactive'])) {
 96746 $this->input->setInteractive($options['interactive']);
 96747 }
 96748 
 96749 $this->output = new StreamOutput(fopen('php://memory', 'w', false));
 96750 $this->output->setDecorated(isset($options['decorated']) ? $options['decorated'] : false);
 96751 if (isset($options['verbosity'])) {
 96752 $this->output->setVerbosity($options['verbosity']);
 96753 }
 96754 
 96755 return $this->statusCode = $this->command->run($this->input, $this->output);
 96756 }
 96757 
 96758 
 96759 
 96760 
 96761 
 96762 
 96763 
 96764 
 96765 public function getDisplay($normalize = false)
 96766 {
 96767 rewind($this->output->getStream());
 96768 
 96769 $display = stream_get_contents($this->output->getStream());
 96770 
 96771 if ($normalize) {
 96772 $display = str_replace(PHP_EOL, "\n", $display);
 96773 }
 96774 
 96775 return $display;
 96776 }
 96777 
 96778 
 96779 
 96780 
 96781 
 96782 
 96783 public function getInput()
 96784 {
 96785 return $this->input;
 96786 }
 96787 
 96788 
 96789 
 96790 
 96791 
 96792 
 96793 public function getOutput()
 96794 {
 96795 return $this->output;
 96796 }
 96797 
 96798 
 96799 
 96800 
 96801 
 96802 
 96803 public function getStatusCode()
 96804 {
 96805 return $this->statusCode;
 96806 }
 96807 }
 96808 <?php
 96809 
 96810 
 96811 
 96812 
 96813 
 96814 
 96815 
 96816 
 96817 
 96818 
 96819 namespace Symfony\Component\Debug;
 96820 
 96821 use Psr\Log\AbstractLogger;
 96822 
 96823 
 96824 
 96825 
 96826 
 96827 
 96828 class BufferingLogger extends AbstractLogger
 96829 {
 96830 private $logs = array();
 96831 
 96832 public function log($level, $message, array $context = array())
 96833 {
 96834 $this->logs[] = array($level, $message, $context);
 96835 }
 96836 
 96837 public function cleanLogs()
 96838 {
 96839 $logs = $this->logs;
 96840 $this->logs = array();
 96841 
 96842 return $logs;
 96843 }
 96844 }
 96845 <?php
 96846 
 96847 
 96848 
 96849 
 96850 
 96851 
 96852 
 96853 
 96854 
 96855 
 96856 namespace Symfony\Component\Debug;
 96857 
 96858 
 96859 
 96860 
 96861 
 96862 
 96863 class Debug
 96864 {
 96865 private static $enabled = false;
 96866 
 96867 
 96868 
 96869 
 96870 
 96871 
 96872 
 96873 
 96874 
 96875 public static function enable($errorReportingLevel = null, $displayErrors = true)
 96876 {
 96877 if (static::$enabled) {
 96878 return;
 96879 }
 96880 
 96881 static::$enabled = true;
 96882 
 96883 if (null !== $errorReportingLevel) {
 96884 error_reporting($errorReportingLevel);
 96885 } else {
 96886 error_reporting(-1);
 96887 }
 96888 
 96889 if (!\in_array(\PHP_SAPI, array('cli', 'phpdbg'), true)) {
 96890 ini_set('display_errors', 0);
 96891 ExceptionHandler::register();
 96892 } elseif ($displayErrors && (!filter_var(ini_get('log_errors'), FILTER_VALIDATE_BOOLEAN) || ini_get('error_log'))) {
 96893 
 96894 ini_set('display_errors', 1);
 96895 }
 96896 if ($displayErrors) {
 96897 ErrorHandler::register(new ErrorHandler(new BufferingLogger()));
 96898 } else {
 96899 ErrorHandler::register()->throwAt(0, true);
 96900 }
 96901 
 96902 DebugClassLoader::enable();
 96903 }
 96904 }
 96905 <?php
 96906 
 96907 
 96908 
 96909 
 96910 
 96911 
 96912 
 96913 
 96914 
 96915 
 96916 namespace Symfony\Component\Debug;
 96917 
 96918 
 96919 
 96920 
 96921 
 96922 
 96923 
 96924 
 96925 
 96926 
 96927 
 96928 
 96929 class DebugClassLoader
 96930 {
 96931 private $classLoader;
 96932 private $isFinder;
 96933 private $loaded = array();
 96934 private $wasFinder;
 96935 private static $caseCheck;
 96936 private static $deprecated = array();
 96937 private static $php7Reserved = array('int', 'float', 'bool', 'string', 'true', 'false', 'null');
 96938 private static $darwinCache = array('/' => array('/', array()));
 96939 
 96940 
 96941 
 96942 
 96943 public function __construct($classLoader)
 96944 {
 96945 $this->wasFinder = \is_object($classLoader) && method_exists($classLoader, 'findFile');
 96946 
 96947 if ($this->wasFinder) {
 96948 @trigger_error('The '.__METHOD__.' method will no longer support receiving an object into its $classLoader argument in 3.0.', E_USER_DEPRECATED);
 96949 $this->classLoader = array($classLoader, 'loadClass');
 96950 $this->isFinder = true;
 96951 } else {
 96952 $this->classLoader = $classLoader;
 96953 $this->isFinder = \is_array($classLoader) && method_exists($classLoader[0], 'findFile');
 96954 }
 96955 
 96956 if (!isset(self::$caseCheck)) {
 96957 $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), \DIRECTORY_SEPARATOR);
 96958 $i = strrpos($file, \DIRECTORY_SEPARATOR);
 96959 $dir = substr($file, 0, 1 + $i);
 96960 $file = substr($file, 1 + $i);
 96961 $test = strtoupper($file) === $file ? strtolower($file) : strtoupper($file);
 96962 $test = realpath($dir.$test);
 96963 
 96964 if (false === $test || false === $i) {
 96965 
 96966 self::$caseCheck = 0;
 96967 } elseif (substr($test, -\strlen($file)) === $file) {
 96968 
 96969 self::$caseCheck = 1;
 96970 } elseif (false !== stripos(PHP_OS, 'darwin')) {
 96971 
 96972 self::$caseCheck = 2;
 96973 } else {
 96974 
 96975 self::$caseCheck = 0;
 96976 }
 96977 }
 96978 }
 96979 
 96980 
 96981 
 96982 
 96983 
 96984 
 96985 public function getClassLoader()
 96986 {
 96987 return $this->wasFinder ? $this->classLoader[0] : $this->classLoader;
 96988 }
 96989 
 96990 
 96991 
 96992 
 96993 public static function enable()
 96994 {
 96995 
 96996 class_exists('Symfony\Component\Debug\ErrorHandler');
 96997 class_exists('Psr\Log\LogLevel');
 96998 
 96999 if (!\is_array($functions = spl_autoload_functions())) {
 97000 return;
 97001 }
 97002 
 97003 foreach ($functions as $function) {
 97004 spl_autoload_unregister($function);
 97005 }
 97006 
 97007 foreach ($functions as $function) {
 97008 if (!\is_array($function) || !$function[0] instanceof self) {
 97009 $function = array(new static($function), 'loadClass');
 97010 }
 97011 
 97012 spl_autoload_register($function);
 97013 }
 97014 }
 97015 
 97016 
 97017 
 97018 
 97019 public static function disable()
 97020 {
 97021 if (!\is_array($functions = spl_autoload_functions())) {
 97022 return;
 97023 }
 97024 
 97025 foreach ($functions as $function) {
 97026 spl_autoload_unregister($function);
 97027 }
 97028 
 97029 foreach ($functions as $function) {
 97030 if (\is_array($function) && $function[0] instanceof self) {
 97031 $function = $function[0]->getClassLoader();
 97032 }
 97033 
 97034 spl_autoload_register($function);
 97035 }
 97036 }
 97037 
 97038 
 97039 
 97040 
 97041 
 97042 
 97043 
 97044 
 97045 
 97046 
 97047 public function findFile($class)
 97048 {
 97049 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
 97050 
 97051 if ($this->wasFinder) {
 97052 return $this->classLoader[0]->findFile($class);
 97053 }
 97054 }
 97055 
 97056 
 97057 
 97058 
 97059 
 97060 
 97061 
 97062 
 97063 
 97064 
 97065 public function loadClass($class)
 97066 {
 97067 ErrorHandler::stackErrors();
 97068 
 97069 try {
 97070 if ($this->isFinder && !isset($this->loaded[$class])) {
 97071 $this->loaded[$class] = true;
 97072 if ($file = $this->classLoader[0]->findFile($class)) {
 97073 require $file;
 97074 }
 97075 } else {
 97076 \call_user_func($this->classLoader, $class);
 97077 $file = false;
 97078 }
 97079 } catch (\Exception $e) {
 97080 ErrorHandler::unstackErrors();
 97081 
 97082 throw $e;
 97083 } catch (\Throwable $e) {
 97084 ErrorHandler::unstackErrors();
 97085 
 97086 throw $e;
 97087 }
 97088 
 97089 ErrorHandler::unstackErrors();
 97090 
 97091 $exists = class_exists($class, false) || interface_exists($class, false) || (\function_exists('trait_exists') && trait_exists($class, false));
 97092 
 97093 if ($class && '\\' === $class[0]) {
 97094 $class = substr($class, 1);
 97095 }
 97096 
 97097 if ($exists) {
 97098 $refl = new \ReflectionClass($class);
 97099 $name = $refl->getName();
 97100 
 97101 if ($name !== $class && 0 === strcasecmp($name, $class)) {
 97102 throw new \RuntimeException(sprintf('Case mismatch between loaded and declared class names: %s vs %s', $class, $name));
 97103 }
 97104 
 97105 if (\in_array(strtolower($refl->getShortName()), self::$php7Reserved)) {
 97106 @trigger_error(sprintf('%s uses a reserved class name (%s) that will break on PHP 7 and higher', $name, $refl->getShortName()), E_USER_DEPRECATED);
 97107 } elseif (preg_match('#\n \* @deprecated (.*?)\r?\n \*(?: @|/$)#s', $refl->getDocComment(), $notice)) {
 97108 self::$deprecated[$name] = preg_replace('#\s*\r?\n \* +#', ' ', $notice[1]);
 97109 } else {
 97110 if (2 > $len = 1 + (strpos($name, '\\') ?: strpos($name, '_'))) {
 97111 $len = 0;
 97112 $ns = '';
 97113 } else {
 97114 $ns = substr($name, 0, $len);
 97115 }
 97116 $parent = get_parent_class($class);
 97117 
 97118 if (!$parent || strncmp($ns, $parent, $len)) {
 97119 if ($parent && isset(self::$deprecated[$parent]) && strncmp($ns, $parent, $len)) {
 97120 @trigger_error(sprintf('The %s class extends %s that is deprecated %s', $name, $parent, self::$deprecated[$parent]), E_USER_DEPRECATED);
 97121 }
 97122 
 97123 $parentInterfaces = array();
 97124 $deprecatedInterfaces = array();
 97125 if ($parent) {
 97126 foreach (class_implements($parent) as $interface) {
 97127 $parentInterfaces[$interface] = 1;
 97128 }
 97129 }
 97130 
 97131 foreach ($refl->getInterfaceNames() as $interface) {
 97132 if (isset(self::$deprecated[$interface]) && strncmp($ns, $interface, $len)) {
 97133 $deprecatedInterfaces[] = $interface;
 97134 }
 97135 foreach (class_implements($interface) as $interface) {
 97136 $parentInterfaces[$interface] = 1;
 97137 }
 97138 }
 97139 
 97140 foreach ($deprecatedInterfaces as $interface) {
 97141 if (!isset($parentInterfaces[$interface])) {
 97142 @trigger_error(sprintf('The %s %s %s that is deprecated %s', $name, $refl->isInterface() ? 'interface extends' : 'class implements', $interface, self::$deprecated[$interface]), E_USER_DEPRECATED);
 97143 }
 97144 }
 97145 }
 97146 }
 97147 }
 97148 
 97149 if ($file) {
 97150 if (!$exists) {
 97151 if (false !== strpos($class, '/')) {
 97152 throw new \RuntimeException(sprintf('Trying to autoload a class with an invalid name "%s". Be careful that the namespace separator is "\" in PHP, not "/".', $class));
 97153 }
 97154 
 97155 throw new \RuntimeException(sprintf('The autoloader expected class "%s" to be defined in file "%s". The file was found but the class was not in it, the class name or namespace probably has a typo.', $class, $file));
 97156 }
 97157 if (self::$caseCheck) {
 97158 $real = explode('\\', $class.strrchr($file, '.'));
 97159 $tail = explode(\DIRECTORY_SEPARATOR, str_replace('/', \DIRECTORY_SEPARATOR, $file));
 97160 
 97161 $i = \count($tail) - 1;
 97162 $j = \count($real) - 1;
 97163 
 97164 while (isset($tail[$i], $real[$j]) && $tail[$i] === $real[$j]) {
 97165 --$i;
 97166 --$j;
 97167 }
 97168 
 97169 array_splice($tail, 0, $i + 1);
 97170 }
 97171 if (self::$caseCheck && $tail) {
 97172 $tail = \DIRECTORY_SEPARATOR.implode(\DIRECTORY_SEPARATOR, $tail);
 97173 $tailLen = \strlen($tail);
 97174 $real = $refl->getFileName();
 97175 
 97176 if (2 === self::$caseCheck) {
 97177 
 97178 
 97179 $i = 1 + strrpos($real, '/');
 97180 $file = substr($real, $i);
 97181 $real = substr($real, 0, $i);
 97182 
 97183 if (isset(self::$darwinCache[$real])) {
 97184 $kDir = $real;
 97185 } else {
 97186 $kDir = strtolower($real);
 97187 
 97188 if (isset(self::$darwinCache[$kDir])) {
 97189 $real = self::$darwinCache[$kDir][0];
 97190 } else {
 97191 $dir = getcwd();
 97192 chdir($real);
 97193 $real = getcwd().'/';
 97194 chdir($dir);
 97195 
 97196 $dir = $real;
 97197 $k = $kDir;
 97198 $i = \strlen($dir) - 1;
 97199 while (!isset(self::$darwinCache[$k])) {
 97200 self::$darwinCache[$k] = array($dir, array());
 97201 self::$darwinCache[$dir] = &self::$darwinCache[$k];
 97202 
 97203 while ('/' !== $dir[--$i]) {
 97204 }
 97205 $k = substr($k, 0, ++$i);
 97206 $dir = substr($dir, 0, $i--);
 97207 }
 97208 }
 97209 }
 97210 
 97211 $dirFiles = self::$darwinCache[$kDir][1];
 97212 
 97213 if (isset($dirFiles[$file])) {
 97214 $kFile = $file;
 97215 } else {
 97216 $kFile = strtolower($file);
 97217 
 97218 if (!isset($dirFiles[$kFile])) {
 97219 foreach (scandir($real, 2) as $f) {
 97220 if ('.' !== $f[0]) {
 97221 $dirFiles[$f] = $f;
 97222 if ($f === $file) {
 97223 $kFile = $k = $file;
 97224 } elseif ($f !== $k = strtolower($f)) {
 97225 $dirFiles[$k] = $f;
 97226 }
 97227 }
 97228 }
 97229 self::$darwinCache[$kDir][1] = $dirFiles;
 97230 }
 97231 }
 97232 
 97233 $real .= $dirFiles[$kFile];
 97234 }
 97235 
 97236 if (0 === substr_compare($real, $tail, -$tailLen, $tailLen, true)
 97237 && 0 !== substr_compare($real, $tail, -$tailLen, $tailLen, false)
 97238 ) {
 97239 throw new \RuntimeException(sprintf('Case mismatch between class and real file names: %s vs %s in %s', substr($tail, -$tailLen + 1), substr($real, -$tailLen + 1), substr($real, 0, -$tailLen + 1)));
 97240 }
 97241 }
 97242 
 97243 return true;
 97244 }
 97245 }
 97246 }
 97247 <?php
 97248 
 97249 
 97250 
 97251 
 97252 
 97253 
 97254 
 97255 
 97256 
 97257 
 97258 namespace Symfony\Component\Debug;
 97259 
 97260 use Psr\Log\LoggerInterface;
 97261 use Psr\Log\LogLevel;
 97262 use Symfony\Component\Debug\Exception\ContextErrorException;
 97263 use Symfony\Component\Debug\Exception\FatalErrorException;
 97264 use Symfony\Component\Debug\Exception\FatalThrowableError;
 97265 use Symfony\Component\Debug\Exception\OutOfMemoryException;
 97266 use Symfony\Component\Debug\FatalErrorHandler\ClassNotFoundFatalErrorHandler;
 97267 use Symfony\Component\Debug\FatalErrorHandler\FatalErrorHandlerInterface;
 97268 use Symfony\Component\Debug\FatalErrorHandler\UndefinedFunctionFatalErrorHandler;
 97269 use Symfony\Component\Debug\FatalErrorHandler\UndefinedMethodFatalErrorHandler;
 97270 
 97271 
 97272 
 97273 
 97274 
 97275 
 97276 
 97277 
 97278 
 97279 
 97280 
 97281 
 97282 
 97283 
 97284 
 97285 
 97286 
 97287 
 97288 
 97289 
 97290 
 97291 
 97292 
 97293 class ErrorHandler
 97294 {
 97295 
 97296 
 97297 
 97298 const TYPE_DEPRECATION = -100;
 97299 
 97300 private $levels = array(
 97301 E_DEPRECATED => 'Deprecated',
 97302 E_USER_DEPRECATED => 'User Deprecated',
 97303 E_NOTICE => 'Notice',
 97304 E_USER_NOTICE => 'User Notice',
 97305 E_STRICT => 'Runtime Notice',
 97306 E_WARNING => 'Warning',
 97307 E_USER_WARNING => 'User Warning',
 97308 E_COMPILE_WARNING => 'Compile Warning',
 97309 E_CORE_WARNING => 'Core Warning',
 97310 E_USER_ERROR => 'User Error',
 97311 E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
 97312 E_COMPILE_ERROR => 'Compile Error',
 97313 E_PARSE => 'Parse Error',
 97314 E_ERROR => 'Error',
 97315 E_CORE_ERROR => 'Core Error',
 97316 );
 97317 
 97318 private $loggers = array(
 97319 E_DEPRECATED => array(null, LogLevel::INFO),
 97320 E_USER_DEPRECATED => array(null, LogLevel::INFO),
 97321 E_NOTICE => array(null, LogLevel::WARNING),
 97322 E_USER_NOTICE => array(null, LogLevel::WARNING),
 97323 E_STRICT => array(null, LogLevel::WARNING),
 97324 E_WARNING => array(null, LogLevel::WARNING),
 97325 E_USER_WARNING => array(null, LogLevel::WARNING),
 97326 E_COMPILE_WARNING => array(null, LogLevel::WARNING),
 97327 E_CORE_WARNING => array(null, LogLevel::WARNING),
 97328 E_USER_ERROR => array(null, LogLevel::CRITICAL),
 97329 E_RECOVERABLE_ERROR => array(null, LogLevel::CRITICAL),
 97330 E_COMPILE_ERROR => array(null, LogLevel::CRITICAL),
 97331 E_PARSE => array(null, LogLevel::CRITICAL),
 97332 E_ERROR => array(null, LogLevel::CRITICAL),
 97333 E_CORE_ERROR => array(null, LogLevel::CRITICAL),
 97334 );
 97335 
 97336 private $thrownErrors = 0x1FFF; 
 97337 private $scopedErrors = 0x1FFF; 
 97338 private $tracedErrors = 0x77FB; 
 97339 private $screamedErrors = 0x55; 
 97340 private $loggedErrors = 0;
 97341 
 97342 private $loggedTraces = array();
 97343 private $isRecursive = 0;
 97344 private $isRoot = false;
 97345 private $exceptionHandler;
 97346 private $bootstrappingLogger;
 97347 
 97348 private static $reservedMemory;
 97349 private static $stackedErrors = array();
 97350 private static $stackedErrorLevels = array();
 97351 private static $toStringException = null;
 97352 private static $exitCode = 0;
 97353 
 97354 
 97355 
 97356 
 97357 
 97358 
 97359 private $displayErrors = 0x1FFF;
 97360 
 97361 
 97362 
 97363 
 97364 
 97365 
 97366 
 97367 
 97368 
 97369 public static function register($handler = null, $replace = true)
 97370 {
 97371 if (null === self::$reservedMemory) {
 97372 self::$reservedMemory = str_repeat('x', 10240);
 97373 register_shutdown_function(__CLASS__.'::handleFatalError');
 97374 }
 97375 
 97376 $levels = -1;
 97377 
 97378 if ($handlerIsNew = !$handler instanceof self) {
 97379 
 97380 if (null !== $handler) {
 97381 $levels = $replace ? $handler : 0;
 97382 $replace = true;
 97383 }
 97384 $handler = new static();
 97385 }
 97386 
 97387 if (null === $prev = set_error_handler(array($handler, 'handleError'))) {
 97388 restore_error_handler();
 97389 
 97390 set_error_handler(array($handler, 'handleError'), $handler->thrownErrors | $handler->loggedErrors);
 97391 $handler->isRoot = true;
 97392 }
 97393 
 97394 if ($handlerIsNew && \is_array($prev) && $prev[0] instanceof self) {
 97395 $handler = $prev[0];
 97396 $replace = false;
 97397 }
 97398 if (!$replace && $prev) {
 97399 restore_error_handler();
 97400 $handlerIsRegistered = \is_array($prev) && $handler === $prev[0];
 97401 } else {
 97402 $handlerIsRegistered = true;
 97403 }
 97404 if (\is_array($prev = set_exception_handler(array($handler, 'handleException'))) && $prev[0] instanceof self) {
 97405 restore_exception_handler();
 97406 if (!$handlerIsRegistered) {
 97407 $handler = $prev[0];
 97408 } elseif ($handler !== $prev[0] && $replace) {
 97409 set_exception_handler(array($handler, 'handleException'));
 97410 $p = $prev[0]->setExceptionHandler(null);
 97411 $handler->setExceptionHandler($p);
 97412 $prev[0]->setExceptionHandler($p);
 97413 }
 97414 } else {
 97415 $handler->setExceptionHandler($prev);
 97416 }
 97417 
 97418 $handler->throwAt($levels & $handler->thrownErrors, true);
 97419 
 97420 return $handler;
 97421 }
 97422 
 97423 public function __construct(BufferingLogger $bootstrappingLogger = null)
 97424 {
 97425 if ($bootstrappingLogger) {
 97426 $this->bootstrappingLogger = $bootstrappingLogger;
 97427 $this->setDefaultLogger($bootstrappingLogger);
 97428 }
 97429 }
 97430 
 97431 
 97432 
 97433 
 97434 
 97435 
 97436 
 97437 
 97438 public function setDefaultLogger(LoggerInterface $logger, $levels = null, $replace = false)
 97439 {
 97440 $loggers = array();
 97441 
 97442 if (\is_array($levels)) {
 97443 foreach ($levels as $type => $logLevel) {
 97444 if (empty($this->loggers[$type][0]) || $replace || $this->loggers[$type][0] === $this->bootstrappingLogger) {
 97445 $loggers[$type] = array($logger, $logLevel);
 97446 }
 97447 }
 97448 } else {
 97449 if (null === $levels) {
 97450 $levels = E_ALL | E_STRICT;
 97451 }
 97452 foreach ($this->loggers as $type => $log) {
 97453 if (($type & $levels) && (empty($log[0]) || $replace || $log[0] === $this->bootstrappingLogger)) {
 97454 $log[0] = $logger;
 97455 $loggers[$type] = $log;
 97456 }
 97457 }
 97458 }
 97459 
 97460 $this->setLoggers($loggers);
 97461 }
 97462 
 97463 
 97464 
 97465 
 97466 
 97467 
 97468 
 97469 
 97470 
 97471 
 97472 public function setLoggers(array $loggers)
 97473 {
 97474 $prevLogged = $this->loggedErrors;
 97475 $prev = $this->loggers;
 97476 $flush = array();
 97477 
 97478 foreach ($loggers as $type => $log) {
 97479 if (!isset($prev[$type])) {
 97480 throw new \InvalidArgumentException('Unknown error type: '.$type);
 97481 }
 97482 if (!\is_array($log)) {
 97483 $log = array($log);
 97484 } elseif (!array_key_exists(0, $log)) {
 97485 throw new \InvalidArgumentException('No logger provided');
 97486 }
 97487 if (null === $log[0]) {
 97488 $this->loggedErrors &= ~$type;
 97489 } elseif ($log[0] instanceof LoggerInterface) {
 97490 $this->loggedErrors |= $type;
 97491 } else {
 97492 throw new \InvalidArgumentException('Invalid logger provided');
 97493 }
 97494 $this->loggers[$type] = $log + $prev[$type];
 97495 
 97496 if ($this->bootstrappingLogger && $prev[$type][0] === $this->bootstrappingLogger) {
 97497 $flush[$type] = $type;
 97498 }
 97499 }
 97500 $this->reRegister($prevLogged | $this->thrownErrors);
 97501 
 97502 if ($flush) {
 97503 foreach ($this->bootstrappingLogger->cleanLogs() as $log) {
 97504 $type = $log[2]['type'];
 97505 if (!isset($flush[$type])) {
 97506 $this->bootstrappingLogger->log($log[0], $log[1], $log[2]);
 97507 } elseif ($this->loggers[$type][0]) {
 97508 $this->loggers[$type][0]->log($this->loggers[$type][1], $log[1], $log[2]);
 97509 }
 97510 }
 97511 }
 97512 
 97513 return $prev;
 97514 }
 97515 
 97516 
 97517 
 97518 
 97519 
 97520 
 97521 
 97522 
 97523 
 97524 
 97525 public function setExceptionHandler($handler)
 97526 {
 97527 if (null !== $handler && !\is_callable($handler)) {
 97528 throw new \LogicException('The exception handler must be a valid PHP callable.');
 97529 }
 97530 $prev = $this->exceptionHandler;
 97531 $this->exceptionHandler = $handler;
 97532 
 97533 return $prev;
 97534 }
 97535 
 97536 
 97537 
 97538 
 97539 
 97540 
 97541 
 97542 
 97543 
 97544 public function throwAt($levels, $replace = false)
 97545 {
 97546 $prev = $this->thrownErrors;
 97547 $this->thrownErrors = ($levels | E_RECOVERABLE_ERROR | E_USER_ERROR) & ~E_USER_DEPRECATED & ~E_DEPRECATED;
 97548 if (!$replace) {
 97549 $this->thrownErrors |= $prev;
 97550 }
 97551 $this->reRegister($prev | $this->loggedErrors);
 97552 
 97553 
 97554 $this->displayErrors = $this->thrownErrors;
 97555 
 97556 return $prev;
 97557 }
 97558 
 97559 
 97560 
 97561 
 97562 
 97563 
 97564 
 97565 
 97566 
 97567 public function scopeAt($levels, $replace = false)
 97568 {
 97569 $prev = $this->scopedErrors;
 97570 $this->scopedErrors = (int) $levels;
 97571 if (!$replace) {
 97572 $this->scopedErrors |= $prev;
 97573 }
 97574 
 97575 return $prev;
 97576 }
 97577 
 97578 
 97579 
 97580 
 97581 
 97582 
 97583 
 97584 
 97585 
 97586 public function traceAt($levels, $replace = false)
 97587 {
 97588 $prev = $this->tracedErrors;
 97589 $this->tracedErrors = (int) $levels;
 97590 if (!$replace) {
 97591 $this->tracedErrors |= $prev;
 97592 }
 97593 
 97594 return $prev;
 97595 }
 97596 
 97597 
 97598 
 97599 
 97600 
 97601 
 97602 
 97603 
 97604 
 97605 public function screamAt($levels, $replace = false)
 97606 {
 97607 $prev = $this->screamedErrors;
 97608 $this->screamedErrors = (int) $levels;
 97609 if (!$replace) {
 97610 $this->screamedErrors |= $prev;
 97611 }
 97612 
 97613 return $prev;
 97614 }
 97615 
 97616 
 97617 
 97618 
 97619 private function reRegister($prev)
 97620 {
 97621 if ($prev !== $this->thrownErrors | $this->loggedErrors) {
 97622 $handler = set_error_handler('var_dump');
 97623 $handler = \is_array($handler) ? $handler[0] : null;
 97624 restore_error_handler();
 97625 if ($handler === $this) {
 97626 restore_error_handler();
 97627 if ($this->isRoot) {
 97628 set_error_handler(array($this, 'handleError'), $this->thrownErrors | $this->loggedErrors);
 97629 } else {
 97630 set_error_handler(array($this, 'handleError'));
 97631 }
 97632 }
 97633 }
 97634 }
 97635 
 97636 
 97637 
 97638 
 97639 
 97640 
 97641 
 97642 
 97643 
 97644 
 97645 
 97646 
 97647 
 97648 
 97649 
 97650 public function handleError($type, $message, $file, $line)
 97651 {
 97652 $level = error_reporting();
 97653 $silenced = 0 === ($level & $type);
 97654 $level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
 97655 $log = $this->loggedErrors & $type;
 97656 $throw = $this->thrownErrors & $type & $level;
 97657 $type &= $level | $this->screamedErrors;
 97658 
 97659 if (!$type || (!$log && !$throw)) {
 97660 return !$silenced && $type && $log;
 97661 }
 97662 $scope = $this->scopedErrors & $type;
 97663 
 97664 if (4 < $numArgs = \func_num_args()) {
 97665 $context = $scope ? (func_get_arg(4) ?: array()) : array();
 97666 $backtrace = 5 < $numArgs ? func_get_arg(5) : null; 
 97667 } else {
 97668 $context = array();
 97669 $backtrace = null;
 97670 }
 97671 
 97672 if (isset($context['GLOBALS']) && $scope) {
 97673 $e = $context; 
 97674 unset($e['GLOBALS'], $context); 
 97675 $context = $e;
 97676 }
 97677 
 97678 if (null !== $backtrace && $type & E_ERROR) {
 97679 
 97680 
 97681 
 97682 $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace'));
 97683 
 97684 return true;
 97685 }
 97686 
 97687 if ($throw) {
 97688 if (null !== self::$toStringException) {
 97689 $throw = self::$toStringException;
 97690 self::$toStringException = null;
 97691 } elseif ($scope && class_exists('Symfony\Component\Debug\Exception\ContextErrorException')) {
 97692 
 97693 $throw = new ContextErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line, $context);
 97694 } else {
 97695 $throw = new \ErrorException($this->levels[$type].': '.$message, 0, $type, $file, $line);
 97696 }
 97697 
 97698 if (\PHP_VERSION_ID <= 50407 && (\PHP_VERSION_ID >= 50400 || \PHP_VERSION_ID <= 50317)) {
 97699 
 97700 
 97701 
 97702 
 97703 $throw->errorHandlerCanary = new ErrorHandlerCanary();
 97704 }
 97705 
 97706 if (E_USER_ERROR & $type) {
 97707 $backtrace = $backtrace ?: $throw->getTrace();
 97708 
 97709 for ($i = 1; isset($backtrace[$i]); ++$i) {
 97710 if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])
 97711 && '__toString' === $backtrace[$i]['function']
 97712 && '->' === $backtrace[$i]['type']
 97713 && !isset($backtrace[$i - 1]['class'])
 97714 && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])
 97715 ) {
 97716 
 97717 
 97718 
 97719 
 97720 
 97721 
 97722 
 97723 foreach ($context as $e) {
 97724 if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) {
 97725 if (1 === $i) {
 97726 
 97727 $throw = $e;
 97728 break;
 97729 }
 97730 self::$toStringException = $e;
 97731 
 97732 return true;
 97733 }
 97734 }
 97735 
 97736 if (1 < $i) {
 97737 
 97738 $this->handleException($throw);
 97739 
 97740 
 97741 return false;
 97742 }
 97743 }
 97744 }
 97745 }
 97746 
 97747 throw $throw;
 97748 }
 97749 
 97750 
 97751 $e = md5("{$type}/{$line}/{$file}\x00{$message}", true);
 97752 $trace = true;
 97753 
 97754 if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) {
 97755 $trace = false;
 97756 } else {
 97757 $this->loggedTraces[$e] = 1;
 97758 }
 97759 
 97760 $e = compact('type', 'file', 'line', 'level');
 97761 
 97762 if ($type & $level) {
 97763 if ($scope) {
 97764 $e['scope_vars'] = $context;
 97765 if ($trace) {
 97766 $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
 97767 }
 97768 } elseif ($trace) {
 97769 if (null === $backtrace) {
 97770 $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
 97771 } else {
 97772 foreach ($backtrace as &$frame) {
 97773 unset($frame['args'], $frame);
 97774 }
 97775 $e['stack'] = $backtrace;
 97776 }
 97777 }
 97778 }
 97779 
 97780 if ($this->isRecursive) {
 97781 $log = 0;
 97782 } elseif (self::$stackedErrorLevels) {
 97783 self::$stackedErrors[] = array($this->loggers[$type][0], ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
 97784 } else {
 97785 try {
 97786 $this->isRecursive = true;
 97787 $this->loggers[$type][0]->log(($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e);
 97788 $this->isRecursive = false;
 97789 } catch (\Exception $e) {
 97790 $this->isRecursive = false;
 97791 
 97792 throw $e;
 97793 } catch (\Throwable $e) {
 97794 $this->isRecursive = false;
 97795 
 97796 throw $e;
 97797 }
 97798 }
 97799 
 97800 return !$silenced && $type && $log;
 97801 }
 97802 
 97803 
 97804 
 97805 
 97806 
 97807 
 97808 
 97809 
 97810 
 97811 public function handleException($exception, array $error = null)
 97812 {
 97813 if (null === $error) {
 97814 self::$exitCode = 255;
 97815 }
 97816 if (!$exception instanceof \Exception) {
 97817 $exception = new FatalThrowableError($exception);
 97818 }
 97819 $type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
 97820 $handlerException = null;
 97821 
 97822 if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
 97823 $e = array(
 97824 'type' => $type,
 97825 'file' => $exception->getFile(),
 97826 'line' => $exception->getLine(),
 97827 'level' => error_reporting(),
 97828 'stack' => $exception->getTrace(),
 97829 );
 97830 if ($exception instanceof FatalErrorException) {
 97831 if ($exception instanceof FatalThrowableError) {
 97832 $error = array(
 97833 'type' => $type,
 97834 'message' => $message = $exception->getMessage(),
 97835 'file' => $e['file'],
 97836 'line' => $e['line'],
 97837 );
 97838 } else {
 97839 $message = 'Fatal '.$exception->getMessage();
 97840 }
 97841 } elseif ($exception instanceof \ErrorException) {
 97842 $message = 'Uncaught '.$exception->getMessage();
 97843 if ($exception instanceof ContextErrorException) {
 97844 $e['context'] = $exception->getContext();
 97845 }
 97846 } else {
 97847 $message = 'Uncaught Exception: '.$exception->getMessage();
 97848 }
 97849 }
 97850 if ($this->loggedErrors & $type) {
 97851 try {
 97852 $this->loggers[$type][0]->log($this->loggers[$type][1], $message, $e);
 97853 } catch (\Exception $handlerException) {
 97854 } catch (\Throwable $handlerException) {
 97855 }
 97856 }
 97857 if ($exception instanceof FatalErrorException && !$exception instanceof OutOfMemoryException && $error) {
 97858 foreach ($this->getFatalErrorHandlers() as $handler) {
 97859 if ($e = $handler->handleError($error, $exception)) {
 97860 $exception = $e;
 97861 break;
 97862 }
 97863 }
 97864 }
 97865 $exceptionHandler = $this->exceptionHandler;
 97866 $this->exceptionHandler = null;
 97867 try {
 97868 if (null !== $exceptionHandler) {
 97869 return \call_user_func($exceptionHandler, $exception);
 97870 }
 97871 $handlerException = $handlerException ?: $exception;
 97872 } catch (\Exception $handlerException) {
 97873 } catch (\Throwable $handlerException) {
 97874 }
 97875 if ($exception === $handlerException) {
 97876 self::$reservedMemory = null; 
 97877 throw $exception; 
 97878 }
 97879 $this->handleException($handlerException);
 97880 }
 97881 
 97882 
 97883 
 97884 
 97885 
 97886 
 97887 
 97888 
 97889 public static function handleFatalError(array $error = null)
 97890 {
 97891 if (null === self::$reservedMemory) {
 97892 return;
 97893 }
 97894 
 97895 $handler = self::$reservedMemory = null;
 97896 $handlers = array();
 97897 $previousHandler = null;
 97898 $sameHandlerLimit = 10;
 97899 
 97900 while (!\is_array($handler) || !$handler[0] instanceof self) {
 97901 $handler = set_exception_handler('var_dump');
 97902 restore_exception_handler();
 97903 
 97904 if (!$handler) {
 97905 break;
 97906 }
 97907 restore_exception_handler();
 97908 
 97909 if ($handler !== $previousHandler) {
 97910 array_unshift($handlers, $handler);
 97911 $previousHandler = $handler;
 97912 } elseif (0 === --$sameHandlerLimit) {
 97913 $handler = null;
 97914 break;
 97915 }
 97916 }
 97917 foreach ($handlers as $h) {
 97918 set_exception_handler($h);
 97919 }
 97920 if (!$handler) {
 97921 return;
 97922 }
 97923 if ($handler !== $h) {
 97924 $handler[0]->setExceptionHandler($h);
 97925 }
 97926 $handler = $handler[0];
 97927 $handlers = array();
 97928 
 97929 if ($exit = null === $error) {
 97930 $error = error_get_last();
 97931 }
 97932 
 97933 try {
 97934 while (self::$stackedErrorLevels) {
 97935 static::unstackErrors();
 97936 }
 97937 } catch (\Exception $exception) {
 97938 
 97939 } catch (\Throwable $exception) {
 97940 
 97941 }
 97942 
 97943 if ($error && $error['type'] &= E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR) {
 97944 
 97945 $handler->throwAt(0, true);
 97946 $trace = isset($error['backtrace']) ? $error['backtrace'] : null;
 97947 
 97948 if (0 === strpos($error['message'], 'Allowed memory') || 0 === strpos($error['message'], 'Out of memory')) {
 97949 $exception = new OutOfMemoryException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, false, $trace);
 97950 } else {
 97951 $exception = new FatalErrorException($handler->levels[$error['type']].': '.$error['message'], 0, $error['type'], $error['file'], $error['line'], 2, true, $trace);
 97952 }
 97953 }
 97954 
 97955 try {
 97956 if (isset($exception)) {
 97957 self::$exitCode = 255;
 97958 $handler->handleException($exception, $error);
 97959 }
 97960 } catch (FatalErrorException $e) {
 97961 
 97962 }
 97963 
 97964 if ($exit && self::$exitCode) {
 97965 $exitCode = self::$exitCode;
 97966 register_shutdown_function('register_shutdown_function', function () use ($exitCode) { exit($exitCode); });
 97967 }
 97968 }
 97969 
 97970 
 97971 
 97972 
 97973 
 97974 
 97975 
 97976 
 97977 
 97978 
 97979 
 97980 
 97981 public static function stackErrors()
 97982 {
 97983 self::$stackedErrorLevels[] = error_reporting(error_reporting() | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
 97984 }
 97985 
 97986 
 97987 
 97988 
 97989 public static function unstackErrors()
 97990 {
 97991 $level = array_pop(self::$stackedErrorLevels);
 97992 
 97993 if (null !== $level) {
 97994 $e = error_reporting($level);
 97995 if ($e !== ($level | E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR)) {
 97996 
 97997 error_reporting($e);
 97998 }
 97999 }
 98000 
 98001 if (empty(self::$stackedErrorLevels)) {
 98002 $errors = self::$stackedErrors;
 98003 self::$stackedErrors = array();
 98004 
 98005 foreach ($errors as $e) {
 98006 $e[0]->log($e[1], $e[2], $e[3]);
 98007 }
 98008 }
 98009 }
 98010 
 98011 
 98012 
 98013 
 98014 
 98015 
 98016 
 98017 
 98018 protected function getFatalErrorHandlers()
 98019 {
 98020 return array(
 98021 new UndefinedFunctionFatalErrorHandler(),
 98022 new UndefinedMethodFatalErrorHandler(),
 98023 new ClassNotFoundFatalErrorHandler(),
 98024 );
 98025 }
 98026 
 98027 
 98028 
 98029 
 98030 
 98031 
 98032 
 98033 
 98034 public function setLevel($level)
 98035 {
 98036 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
 98037 
 98038 $level = null === $level ? error_reporting() : $level;
 98039 $this->throwAt($level, true);
 98040 }
 98041 
 98042 
 98043 
 98044 
 98045 
 98046 
 98047 
 98048 
 98049 public function setDisplayErrors($displayErrors)
 98050 {
 98051 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the throwAt() method instead.', E_USER_DEPRECATED);
 98052 
 98053 if ($displayErrors) {
 98054 $this->throwAt($this->displayErrors, true);
 98055 } else {
 98056 $displayErrors = $this->displayErrors;
 98057 $this->throwAt(0, true);
 98058 $this->displayErrors = $displayErrors;
 98059 }
 98060 }
 98061 
 98062 
 98063 
 98064 
 98065 
 98066 
 98067 
 98068 
 98069 
 98070 public static function setLogger(LoggerInterface $logger, $channel = 'deprecation')
 98071 {
 98072 @trigger_error('The '.__METHOD__.' static method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the setLoggers() or setDefaultLogger() methods instead.', E_USER_DEPRECATED);
 98073 
 98074 $handler = set_error_handler('var_dump');
 98075 $handler = \is_array($handler) ? $handler[0] : null;
 98076 restore_error_handler();
 98077 if (!$handler instanceof self) {
 98078 return;
 98079 }
 98080 if ('deprecation' === $channel) {
 98081 $handler->setDefaultLogger($logger, E_DEPRECATED | E_USER_DEPRECATED, true);
 98082 $handler->screamAt(E_DEPRECATED | E_USER_DEPRECATED);
 98083 } elseif ('scream' === $channel) {
 98084 $handler->setDefaultLogger($logger, E_ALL | E_STRICT, false);
 98085 $handler->screamAt(E_ALL | E_STRICT);
 98086 } elseif ('emergency' === $channel) {
 98087 $handler->setDefaultLogger($logger, E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR, true);
 98088 $handler->screamAt(E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR);
 98089 }
 98090 }
 98091 
 98092 
 98093 
 98094 
 98095 public function handle($level, $message, $file = 'unknown', $line = 0, $context = array())
 98096 {
 98097 $this->handleError(E_USER_DEPRECATED, 'The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the handleError() method instead.', __FILE__, __LINE__, array());
 98098 
 98099 return $this->handleError($level, $message, $file, $line, (array) $context);
 98100 }
 98101 
 98102 
 98103 
 98104 
 98105 
 98106 
 98107 public function handleFatal()
 98108 {
 98109 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0. Use the handleFatalError() method instead.', E_USER_DEPRECATED);
 98110 
 98111 static::handleFatalError();
 98112 }
 98113 }
 98114 
 98115 
 98116 
 98117 
 98118 
 98119 
 98120 
 98121 
 98122 class ErrorHandlerCanary
 98123 {
 98124 private static $displayErrors = null;
 98125 
 98126 public function __construct()
 98127 {
 98128 if (null === self::$displayErrors) {
 98129 self::$displayErrors = ini_set('display_errors', 1);
 98130 }
 98131 }
 98132 
 98133 public function __destruct()
 98134 {
 98135 if (null !== self::$displayErrors) {
 98136 ini_set('display_errors', self::$displayErrors);
 98137 self::$displayErrors = null;
 98138 }
 98139 }
 98140 }
 98141 <?php
 98142 
 98143 
 98144 
 98145 
 98146 
 98147 
 98148 
 98149 
 98150 
 98151 
 98152 namespace Symfony\Component\Debug\Exception;
 98153 
 98154 
 98155 
 98156 
 98157 
 98158 
 98159 class ClassNotFoundException extends FatalErrorException
 98160 {
 98161 public function __construct($message, \ErrorException $previous)
 98162 {
 98163 parent::__construct(
 98164 $message,
 98165 $previous->getCode(),
 98166 $previous->getSeverity(),
 98167 $previous->getFile(),
 98168 $previous->getLine(),
 98169 null,
 98170 true,
 98171 null,
 98172 $previous->getPrevious()
 98173 );
 98174 $this->setTrace($previous->getTrace());
 98175 }
 98176 }
 98177 <?php
 98178 
 98179 
 98180 
 98181 
 98182 
 98183 
 98184 
 98185 
 98186 
 98187 
 98188 namespace Symfony\Component\Debug\Exception;
 98189 
 98190 
 98191 
 98192 
 98193 
 98194 
 98195 class ContextErrorException extends \ErrorException
 98196 {
 98197 private $context = array();
 98198 
 98199 public function __construct($message, $code, $severity, $filename, $lineno, $context = array())
 98200 {
 98201 parent::__construct($message, $code, $severity, $filename, $lineno);
 98202 $this->context = $context;
 98203 }
 98204 
 98205 
 98206 
 98207 
 98208 public function getContext()
 98209 {
 98210 return $this->context;
 98211 }
 98212 }
 98213 <?php
 98214 
 98215 
 98216 
 98217 
 98218 
 98219 
 98220 
 98221 
 98222 
 98223 
 98224 namespace Symfony\Component\Debug\Exception;
 98225 
 98226 @trigger_error('The '.__NAMESPACE__.'\DummyException class is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
 98227 
 98228 
 98229 
 98230 
 98231 
 98232 
 98233 class DummyException extends \ErrorException
 98234 {
 98235 }
 98236 <?php
 98237 
 98238 
 98239 
 98240 
 98241 
 98242 
 98243 
 98244 
 98245 
 98246 
 98247 namespace Symfony\Component\HttpKernel\Exception;
 98248 
 98249 
 98250 
 98251 
 98252 
 98253 
 98254 
 98255 
 98256 
 98257 
 98258 class FatalErrorException extends \ErrorException
 98259 {
 98260 }
 98261 
 98262 namespace Symfony\Component\Debug\Exception;
 98263 
 98264 use Symfony\Component\HttpKernel\Exception\FatalErrorException as LegacyFatalErrorException;
 98265 
 98266 
 98267 
 98268 
 98269 
 98270 
 98271 class FatalErrorException extends LegacyFatalErrorException
 98272 {
 98273 public function __construct($message, $code, $severity, $filename, $lineno, $traceOffset = null, $traceArgs = true, array $trace = null, $previous = null)
 98274 {
 98275 parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
 98276 
 98277 if (null !== $trace) {
 98278 if (!$traceArgs) {
 98279 foreach ($trace as &$frame) {
 98280 unset($frame['args'], $frame['this'], $frame);
 98281 }
 98282 }
 98283 
 98284 $this->setTrace($trace);
 98285 } elseif (null !== $traceOffset) {
 98286 if (\function_exists('xdebug_get_function_stack')) {
 98287 $trace = xdebug_get_function_stack();
 98288 if (0 < $traceOffset) {
 98289 array_splice($trace, -$traceOffset);
 98290 }
 98291 
 98292 foreach ($trace as &$frame) {
 98293 if (!isset($frame['type'])) {
 98294 
 98295 if (isset($frame['class'])) {
 98296 $frame['type'] = '::';
 98297 }
 98298 } elseif ('dynamic' === $frame['type']) {
 98299 $frame['type'] = '->';
 98300 } elseif ('static' === $frame['type']) {
 98301 $frame['type'] = '::';
 98302 }
 98303 
 98304 
 98305 if (!$traceArgs) {
 98306 unset($frame['params'], $frame['args']);
 98307 } elseif (isset($frame['params']) && !isset($frame['args'])) {
 98308 $frame['args'] = $frame['params'];
 98309 unset($frame['params']);
 98310 }
 98311 }
 98312 
 98313 unset($frame);
 98314 $trace = array_reverse($trace);
 98315 } elseif (\function_exists('symfony_debug_backtrace')) {
 98316 $trace = symfony_debug_backtrace();
 98317 if (0 < $traceOffset) {
 98318 array_splice($trace, 0, $traceOffset);
 98319 }
 98320 } else {
 98321 $trace = array();
 98322 }
 98323 
 98324 $this->setTrace($trace);
 98325 }
 98326 }
 98327 
 98328 protected function setTrace($trace)
 98329 {
 98330 $traceReflector = new \ReflectionProperty('Exception', 'trace');
 98331 $traceReflector->setAccessible(true);
 98332 $traceReflector->setValue($this, $trace);
 98333 }
 98334 }
 98335 <?php
 98336 
 98337 
 98338 
 98339 
 98340 
 98341 
 98342 
 98343 
 98344 
 98345 
 98346 namespace Symfony\Component\Debug\Exception;
 98347 
 98348 
 98349 
 98350 
 98351 
 98352 
 98353 class FatalThrowableError extends FatalErrorException
 98354 {
 98355 public function __construct(\Throwable $e)
 98356 {
 98357 if ($e instanceof \ParseError) {
 98358 $message = 'Parse error: '.$e->getMessage();
 98359 $severity = E_PARSE;
 98360 } elseif ($e instanceof \TypeError) {
 98361 $message = 'Type error: '.$e->getMessage();
 98362 $severity = E_RECOVERABLE_ERROR;
 98363 } else {
 98364 $message = $e->getMessage();
 98365 $severity = E_ERROR;
 98366 }
 98367 
 98368 \ErrorException::__construct(
 98369 $message,
 98370 $e->getCode(),
 98371 $severity,
 98372 $e->getFile(),
 98373 $e->getLine(),
 98374 $e->getPrevious()
 98375 );
 98376 
 98377 $this->setTrace($e->getTrace());
 98378 }
 98379 }
 98380 <?php
 98381 
 98382 
 98383 
 98384 
 98385 
 98386 
 98387 
 98388 
 98389 
 98390 
 98391 namespace Symfony\Component\HttpKernel\Exception;
 98392 
 98393 use Symfony\Component\Debug\Exception\FlattenException as DebugFlattenException;
 98394 
 98395 
 98396 
 98397 
 98398 
 98399 
 98400 
 98401 
 98402 
 98403 
 98404 class FlattenException
 98405 {
 98406 private $handler;
 98407 
 98408 public static function __callStatic($method, $args)
 98409 {
 98410 if (!method_exists('Symfony\Component\Debug\Exception\FlattenException', $method)) {
 98411 throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', \get_called_class(), $method));
 98412 }
 98413 
 98414 return \call_user_func_array(array('Symfony\Component\Debug\Exception\FlattenException', $method), $args);
 98415 }
 98416 
 98417 public function __call($method, $args)
 98418 {
 98419 if (!isset($this->handler)) {
 98420 $this->handler = new DebugFlattenException();
 98421 }
 98422 
 98423 if (!method_exists($this->handler, $method)) {
 98424 throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', \get_class($this), $method));
 98425 }
 98426 
 98427 return \call_user_func_array(array($this->handler, $method), $args);
 98428 }
 98429 }
 98430 
 98431 namespace Symfony\Component\Debug\Exception;
 98432 
 98433 use Symfony\Component\HttpKernel\Exception\FlattenException as LegacyFlattenException;
 98434 use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
 98435 
 98436 
 98437 
 98438 
 98439 
 98440 
 98441 
 98442 
 98443 class FlattenException extends LegacyFlattenException
 98444 {
 98445 private $message;
 98446 private $code;
 98447 private $previous;
 98448 private $trace;
 98449 private $class;
 98450 private $statusCode;
 98451 private $headers;
 98452 private $file;
 98453 private $line;
 98454 
 98455 public static function create(\Exception $exception, $statusCode = null, array $headers = array())
 98456 {
 98457 $e = new static();
 98458 $e->setMessage($exception->getMessage());
 98459 $e->setCode($exception->getCode());
 98460 
 98461 if ($exception instanceof HttpExceptionInterface) {
 98462 $statusCode = $exception->getStatusCode();
 98463 $headers = array_merge($headers, $exception->getHeaders());
 98464 }
 98465 
 98466 if (null === $statusCode) {
 98467 $statusCode = 500;
 98468 }
 98469 
 98470 $e->setStatusCode($statusCode);
 98471 $e->setHeaders($headers);
 98472 $e->setTraceFromException($exception);
 98473 $e->setClass(\get_class($exception));
 98474 $e->setFile($exception->getFile());
 98475 $e->setLine($exception->getLine());
 98476 
 98477 $previous = $exception->getPrevious();
 98478 
 98479 if ($previous instanceof \Exception) {
 98480 $e->setPrevious(static::create($previous));
 98481 } elseif ($previous instanceof \Throwable) {
 98482 $e->setPrevious(static::create(new FatalThrowableError($previous)));
 98483 }
 98484 
 98485 return $e;
 98486 }
 98487 
 98488 public function toArray()
 98489 {
 98490 $exceptions = array();
 98491 foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) {
 98492 $exceptions[] = array(
 98493 'message' => $exception->getMessage(),
 98494 'class' => $exception->getClass(),
 98495 'trace' => $exception->getTrace(),
 98496 );
 98497 }
 98498 
 98499 return $exceptions;
 98500 }
 98501 
 98502 public function getStatusCode()
 98503 {
 98504 return $this->statusCode;
 98505 }
 98506 
 98507 public function setStatusCode($code)
 98508 {
 98509 $this->statusCode = $code;
 98510 }
 98511 
 98512 public function getHeaders()
 98513 {
 98514 return $this->headers;
 98515 }
 98516 
 98517 public function setHeaders(array $headers)
 98518 {
 98519 $this->headers = $headers;
 98520 }
 98521 
 98522 public function getClass()
 98523 {
 98524 return $this->class;
 98525 }
 98526 
 98527 public function setClass($class)
 98528 {
 98529 $this->class = $class;
 98530 }
 98531 
 98532 public function getFile()
 98533 {
 98534 return $this->file;
 98535 }
 98536 
 98537 public function setFile($file)
 98538 {
 98539 $this->file = $file;
 98540 }
 98541 
 98542 public function getLine()
 98543 {
 98544 return $this->line;
 98545 }
 98546 
 98547 public function setLine($line)
 98548 {
 98549 $this->line = $line;
 98550 }
 98551 
 98552 public function getMessage()
 98553 {
 98554 return $this->message;
 98555 }
 98556 
 98557 public function setMessage($message)
 98558 {
 98559 $this->message = $message;
 98560 }
 98561 
 98562 public function getCode()
 98563 {
 98564 return $this->code;
 98565 }
 98566 
 98567 public function setCode($code)
 98568 {
 98569 $this->code = $code;
 98570 }
 98571 
 98572 public function getPrevious()
 98573 {
 98574 return $this->previous;
 98575 }
 98576 
 98577 public function setPrevious(FlattenException $previous)
 98578 {
 98579 $this->previous = $previous;
 98580 }
 98581 
 98582 public function getAllPrevious()
 98583 {
 98584 $exceptions = array();
 98585 $e = $this;
 98586 while ($e = $e->getPrevious()) {
 98587 $exceptions[] = $e;
 98588 }
 98589 
 98590 return $exceptions;
 98591 }
 98592 
 98593 public function getTrace()
 98594 {
 98595 return $this->trace;
 98596 }
 98597 
 98598 public function setTraceFromException(\Exception $exception)
 98599 {
 98600 $this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
 98601 }
 98602 
 98603 public function setTrace($trace, $file, $line)
 98604 {
 98605 $this->trace = array();
 98606 $this->trace[] = array(
 98607 'namespace' => '',
 98608 'short_class' => '',
 98609 'class' => '',
 98610 'type' => '',
 98611 'function' => '',
 98612 'file' => $file,
 98613 'line' => $line,
 98614 'args' => array(),
 98615 );
 98616 foreach ($trace as $entry) {
 98617 $class = '';
 98618 $namespace = '';
 98619 if (isset($entry['class'])) {
 98620 $parts = explode('\\', $entry['class']);
 98621 $class = array_pop($parts);
 98622 $namespace = implode('\\', $parts);
 98623 }
 98624 
 98625 $this->trace[] = array(
 98626 'namespace' => $namespace,
 98627 'short_class' => $class,
 98628 'class' => isset($entry['class']) ? $entry['class'] : '',
 98629 'type' => isset($entry['type']) ? $entry['type'] : '',
 98630 'function' => isset($entry['function']) ? $entry['function'] : null,
 98631 'file' => isset($entry['file']) ? $entry['file'] : null,
 98632 'line' => isset($entry['line']) ? $entry['line'] : null,
 98633 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(),
 98634 );
 98635 }
 98636 }
 98637 
 98638 private function flattenArgs($args, $level = 0, &$count = 0)
 98639 {
 98640 $result = array();
 98641 foreach ($args as $key => $value) {
 98642 if (++$count > 1e4) {
 98643 return array('array', '*SKIPPED over 10000 entries*');
 98644 }
 98645 if ($value instanceof \__PHP_Incomplete_Class) {
 98646 
 98647 $result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value));
 98648 } elseif (\is_object($value)) {
 98649 $result[$key] = array('object', \get_class($value));
 98650 } elseif (\is_array($value)) {
 98651 if ($level > 10) {
 98652 $result[$key] = array('array', '*DEEP NESTED ARRAY*');
 98653 } else {
 98654 $result[$key] = array('array', $this->flattenArgs($value, $level + 1, $count));
 98655 }
 98656 } elseif (null === $value) {
 98657 $result[$key] = array('null', null);
 98658 } elseif (\is_bool($value)) {
 98659 $result[$key] = array('boolean', $value);
 98660 } elseif (\is_resource($value)) {
 98661 $result[$key] = array('resource', get_resource_type($value));
 98662 } else {
 98663 $result[$key] = array('string', (string) $value);
 98664 }
 98665 }
 98666 
 98667 return $result;
 98668 }
 98669 
 98670 private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
 98671 {
 98672 $array = new \ArrayObject($value);
 98673 
 98674 return $array['__PHP_Incomplete_Class_Name'];
 98675 }
 98676 }
 98677 <?php
 98678 
 98679 
 98680 
 98681 
 98682 
 98683 
 98684 
 98685 
 98686 
 98687 
 98688 namespace Symfony\Component\Debug\Exception;
 98689 
 98690 
 98691 
 98692 
 98693 
 98694 
 98695 class OutOfMemoryException extends FatalErrorException
 98696 {
 98697 }
 98698 <?php
 98699 
 98700 
 98701 
 98702 
 98703 
 98704 
 98705 
 98706 
 98707 
 98708 
 98709 namespace Symfony\Component\Debug\Exception;
 98710 
 98711 
 98712 
 98713 
 98714 
 98715 
 98716 class UndefinedFunctionException extends FatalErrorException
 98717 {
 98718 public function __construct($message, \ErrorException $previous)
 98719 {
 98720 parent::__construct(
 98721 $message,
 98722 $previous->getCode(),
 98723 $previous->getSeverity(),
 98724 $previous->getFile(),
 98725 $previous->getLine(),
 98726 null,
 98727 true,
 98728 null,
 98729 $previous->getPrevious()
 98730 );
 98731 $this->setTrace($previous->getTrace());
 98732 }
 98733 }
 98734 <?php
 98735 
 98736 
 98737 
 98738 
 98739 
 98740 
 98741 
 98742 
 98743 
 98744 
 98745 namespace Symfony\Component\Debug\Exception;
 98746 
 98747 
 98748 
 98749 
 98750 
 98751 
 98752 class UndefinedMethodException extends FatalErrorException
 98753 {
 98754 public function __construct($message, \ErrorException $previous)
 98755 {
 98756 parent::__construct(
 98757 $message,
 98758 $previous->getCode(),
 98759 $previous->getSeverity(),
 98760 $previous->getFile(),
 98761 $previous->getLine(),
 98762 null,
 98763 true,
 98764 null,
 98765 $previous->getPrevious()
 98766 );
 98767 $this->setTrace($previous->getTrace());
 98768 }
 98769 }
 98770 <?php
 98771 
 98772 
 98773 
 98774 
 98775 
 98776 
 98777 
 98778 
 98779 
 98780 
 98781 namespace Symfony\Component\Debug;
 98782 
 98783 use Symfony\Component\Debug\Exception\FlattenException;
 98784 use Symfony\Component\Debug\Exception\OutOfMemoryException;
 98785 use Symfony\Component\HttpFoundation\Response;
 98786 
 98787 
 98788 
 98789 
 98790 
 98791 
 98792 
 98793 
 98794 
 98795 
 98796 
 98797 
 98798 
 98799 class ExceptionHandler
 98800 {
 98801 private $debug;
 98802 private $charset;
 98803 private $handler;
 98804 private $caughtBuffer;
 98805 private $caughtLength;
 98806 private $fileLinkFormat;
 98807 
 98808 public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
 98809 {
 98810 if (false !== strpos($charset, '%')) {
 98811 @trigger_error('Providing $fileLinkFormat as second argument to '.__METHOD__.' is deprecated since Symfony 2.8 and will be unsupported in 3.0. Please provide it as third argument, after $charset.', E_USER_DEPRECATED);
 98812 
 98813 
 98814 $pivot = $fileLinkFormat;
 98815 $fileLinkFormat = $charset;
 98816 $charset = $pivot;
 98817 }
 98818 $this->debug = $debug;
 98819 $this->charset = $charset ?: ini_get('default_charset') ?: 'UTF-8';
 98820 $this->fileLinkFormat = $fileLinkFormat ?: ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
 98821 }
 98822 
 98823 
 98824 
 98825 
 98826 
 98827 
 98828 
 98829 
 98830 
 98831 
 98832 public static function register($debug = true, $charset = null, $fileLinkFormat = null)
 98833 {
 98834 $handler = new static($debug, $charset, $fileLinkFormat);
 98835 
 98836 $prev = set_exception_handler(array($handler, 'handle'));
 98837 if (\is_array($prev) && $prev[0] instanceof ErrorHandler) {
 98838 restore_exception_handler();
 98839 $prev[0]->setExceptionHandler(array($handler, 'handle'));
 98840 }
 98841 
 98842 return $handler;
 98843 }
 98844 
 98845 
 98846 
 98847 
 98848 
 98849 
 98850 
 98851 
 98852 public function setHandler($handler)
 98853 {
 98854 if (null !== $handler && !\is_callable($handler)) {
 98855 throw new \LogicException('The exception handler must be a valid PHP callable.');
 98856 }
 98857 $old = $this->handler;
 98858 $this->handler = $handler;
 98859 
 98860 return $old;
 98861 }
 98862 
 98863 
 98864 
 98865 
 98866 
 98867 
 98868 
 98869 
 98870 public function setFileLinkFormat($format)
 98871 {
 98872 $old = $this->fileLinkFormat;
 98873 $this->fileLinkFormat = $format;
 98874 
 98875 return $old;
 98876 }
 98877 
 98878 
 98879 
 98880 
 98881 
 98882 
 98883 
 98884 
 98885 
 98886 public function handle(\Exception $exception)
 98887 {
 98888 if (null === $this->handler || $exception instanceof OutOfMemoryException) {
 98889 $this->failSafeHandle($exception);
 98890 
 98891 return;
 98892 }
 98893 
 98894 $caughtLength = $this->caughtLength = 0;
 98895 
 98896 ob_start(array($this, 'catchOutput'));
 98897 $this->failSafeHandle($exception);
 98898 while (null === $this->caughtBuffer && ob_end_flush()) {
 98899 
 98900 }
 98901 if (isset($this->caughtBuffer[0])) {
 98902 ob_start(array($this, 'cleanOutput'));
 98903 echo $this->caughtBuffer;
 98904 $caughtLength = ob_get_length();
 98905 }
 98906 $this->caughtBuffer = null;
 98907 
 98908 try {
 98909 \call_user_func($this->handler, $exception);
 98910 $this->caughtLength = $caughtLength;
 98911 } catch (\Exception $e) {
 98912 if (!$caughtLength) {
 98913 
 98914 throw $exception;
 98915 }
 98916 }
 98917 }
 98918 
 98919 
 98920 
 98921 
 98922 
 98923 
 98924 
 98925 
 98926 private function failSafeHandle(\Exception $exception)
 98927 {
 98928 if (class_exists('Symfony\Component\HttpFoundation\Response', false)
 98929 && __CLASS__ !== \get_class($this)
 98930 && ($reflector = new \ReflectionMethod($this, 'createResponse'))
 98931 && __CLASS__ !== $reflector->class
 98932 ) {
 98933 $response = $this->createResponse($exception);
 98934 $response->sendHeaders();
 98935 $response->sendContent();
 98936 @trigger_error(sprintf("The %s::createResponse method is deprecated since Symfony 2.8 and won't be called anymore when handling an exception in 3.0.", $reflector->class), E_USER_DEPRECATED);
 98937 
 98938 return;
 98939 }
 98940 
 98941 $this->sendPhpResponse($exception);
 98942 }
 98943 
 98944 
 98945 
 98946 
 98947 
 98948 
 98949 
 98950 
 98951 
 98952 public function sendPhpResponse($exception)
 98953 {
 98954 if (!$exception instanceof FlattenException) {
 98955 $exception = FlattenException::create($exception);
 98956 }
 98957 
 98958 if (!headers_sent()) {
 98959 header(sprintf('HTTP/1.0 %s', $exception->getStatusCode()));
 98960 foreach ($exception->getHeaders() as $name => $value) {
 98961 header($name.': '.$value, false);
 98962 }
 98963 header('Content-Type: text/html; charset='.$this->charset);
 98964 }
 98965 
 98966 echo $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
 98967 }
 98968 
 98969 
 98970 
 98971 
 98972 
 98973 
 98974 
 98975 
 98976 
 98977 
 98978 public function createResponse($exception)
 98979 {
 98980 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 98981 
 98982 if (!$exception instanceof FlattenException) {
 98983 $exception = FlattenException::create($exception);
 98984 }
 98985 
 98986 return Response::create($this->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders())->setCharset($this->charset);
 98987 }
 98988 
 98989 
 98990 
 98991 
 98992 
 98993 
 98994 
 98995 
 98996 public function getHtml($exception)
 98997 {
 98998 if (!$exception instanceof FlattenException) {
 98999 $exception = FlattenException::create($exception);
 99000 }
 99001 
 99002 return $this->decorate($this->getContent($exception), $this->getStylesheet($exception));
 99003 }
 99004 
 99005 
 99006 
 99007 
 99008 
 99009 
 99010 public function getContent(FlattenException $exception)
 99011 {
 99012 switch ($exception->getStatusCode()) {
 99013 case 404:
 99014 $title = 'Sorry, the page you are looking for could not be found.';
 99015 break;
 99016 default:
 99017 $title = 'Whoops, looks like something went wrong.';
 99018 }
 99019 
 99020 $content = '';
 99021 if ($this->debug) {
 99022 try {
 99023 $count = \count($exception->getAllPrevious());
 99024 $total = $count + 1;
 99025 foreach ($exception->toArray() as $position => $e) {
 99026 $ind = $count - $position + 1;
 99027 $class = $this->formatClass($e['class']);
 99028 $message = nl2br($this->escapeHtml($e['message']));
 99029 $content .= sprintf(<<<'EOF'
 99030                         <h2 class="block_exception clear_fix">
 99031                             <span class="exception_counter">%d/%d</span>
 99032                             <span class="exception_title">%s%s:</span>
 99033                             <span class="exception_message">%s</span>
 99034                         </h2>
 99035                         <div class="block">
 99036                             <ol class="traces list_exception">
 99037 
 99038 EOF
 99039 , $ind, $total, $class, $this->formatPath($e['trace'][0]['file'], $e['trace'][0]['line']), $message);
 99040 foreach ($e['trace'] as $trace) {
 99041 $content .= '       <li>';
 99042 if ($trace['function']) {
 99043 $content .= sprintf('at %s%s%s(%s)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
 99044 }
 99045 if (isset($trace['file']) && isset($trace['line'])) {
 99046 $content .= $this->formatPath($trace['file'], $trace['line']);
 99047 }
 99048 $content .= "</li>\n";
 99049 }
 99050 
 99051 $content .= "    </ol>\n</div>\n";
 99052 }
 99053 } catch (\Exception $e) {
 99054 
 99055 if ($this->debug) {
 99056 $title = sprintf('Exception thrown when handling an exception (%s: %s)', \get_class($e), $this->escapeHtml($e->getMessage()));
 99057 } else {
 99058 $title = 'Whoops, looks like something went wrong.';
 99059 }
 99060 }
 99061 }
 99062 
 99063 return <<<EOF
 99064             <div id="sf-resetcontent" class="sf-reset">
 99065                 <h1>$title</h1>
 99066                 $content
 99067             </div>
 99068 EOF;
 99069 }
 99070 
 99071 
 99072 
 99073 
 99074 
 99075 
 99076 public function getStylesheet(FlattenException $exception)
 99077 {
 99078 return <<<'EOF'
 99079             .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }
 99080             .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }
 99081             .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }
 99082             .sf-reset .clear_fix { display:inline-block; }
 99083             .sf-reset * html .clear_fix { height:1%; }
 99084             .sf-reset .clear_fix { display:block; }
 99085             .sf-reset, .sf-reset .block { margin: auto }
 99086             .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }
 99087             .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }
 99088             .sf-reset strong { font-weight:bold; }
 99089             .sf-reset a { color:#6c6159; cursor: default; }
 99090             .sf-reset a img { border:none; }
 99091             .sf-reset a:hover { text-decoration:underline; }
 99092             .sf-reset em { font-style:italic; }
 99093             .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }
 99094             .sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; }
 99095             .sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; }
 99096             .sf-reset .exception_message { margin-left: 3em; display: block; }
 99097             .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }
 99098             .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;
 99099                 -webkit-border-bottom-right-radius: 16px;
 99100                 -webkit-border-bottom-left-radius: 16px;
 99101                 -moz-border-radius-bottomright: 16px;
 99102                 -moz-border-radius-bottomleft: 16px;
 99103                 border-bottom-right-radius: 16px;
 99104                 border-bottom-left-radius: 16px;
 99105                 border-bottom:1px solid #ccc;
 99106                 border-right:1px solid #ccc;
 99107                 border-left:1px solid #ccc;
 99108                 word-wrap: break-word;
 99109             }
 99110             .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;
 99111                 -webkit-border-top-left-radius: 16px;
 99112                 -webkit-border-top-right-radius: 16px;
 99113                 -moz-border-radius-topleft: 16px;
 99114                 -moz-border-radius-topright: 16px;
 99115                 border-top-left-radius: 16px;
 99116                 border-top-right-radius: 16px;
 99117                 border-top:1px solid #ccc;
 99118                 border-right:1px solid #ccc;
 99119                 border-left:1px solid #ccc;
 99120                 overflow: hidden;
 99121                 word-wrap: break-word;
 99122             }
 99123             .sf-reset a { background:none; color:#868686; text-decoration:none; }
 99124             .sf-reset a:hover { background:none; color:#313131; text-decoration:underline; }
 99125             .sf-reset ol { padding: 10px 0; }
 99126             .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;
 99127                 -webkit-border-radius: 10px;
 99128                 -moz-border-radius: 10px;
 99129                 border-radius: 10px;
 99130                 border: 1px solid #ccc;
 99131             }
 99132 EOF;
 99133 }
 99134 
 99135 private function decorate($content, $css)
 99136 {
 99137 return <<<EOF
 99138 <!DOCTYPE html>
 99139 <html>
 99140     <head>
 99141         <meta charset="{$this->charset}" />
 99142         <meta name="robots" content="noindex,nofollow" />
 99143         <style>
 99144             /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
 99145             html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}
 99146 
 99147             html { background: #eee; padding: 10px }
 99148             img { border: 0; }
 99149             #sf-resetcontent { width:970px; margin:0 auto; }
 99150             $css
 99151         </style>
 99152     </head>
 99153     <body>
 99154         $content
 99155     </body>
 99156 </html>
 99157 EOF;
 99158 }
 99159 
 99160 private function formatClass($class)
 99161 {
 99162 $parts = explode('\\', $class);
 99163 
 99164 return sprintf('<abbr title="%s">%s</abbr>', $class, array_pop($parts));
 99165 }
 99166 
 99167 private function formatPath($path, $line)
 99168 {
 99169 $path = $this->escapeHtml($path);
 99170 $file = preg_match('#[^/\\\\]*$#', $path, $file) ? $file[0] : $path;
 99171 
 99172 if ($linkFormat = $this->fileLinkFormat) {
 99173 $link = strtr($this->escapeHtml($linkFormat), array('%f' => $path, '%l' => (int) $line));
 99174 
 99175 return sprintf(' in <a href="%s" title="Go to source">%s line %d</a>', $link, $file, $line);
 99176 }
 99177 
 99178 return sprintf(' in <a title="%s line %3$d" ondblclick="var f=this.innerHTML;this.innerHTML=this.title;this.title=f;">%s line %d</a>', $path, $file, $line);
 99179 }
 99180 
 99181 
 99182 
 99183 
 99184 
 99185 
 99186 
 99187 
 99188 private function formatArgs(array $args)
 99189 {
 99190 $result = array();
 99191 foreach ($args as $key => $item) {
 99192 if ('object' === $item[0]) {
 99193 $formattedValue = sprintf('<em>object</em>(%s)', $this->formatClass($item[1]));
 99194 } elseif ('array' === $item[0]) {
 99195 $formattedValue = sprintf('<em>array</em>(%s)', \is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
 99196 } elseif ('string' === $item[0]) {
 99197 $formattedValue = sprintf("'%s'", $this->escapeHtml($item[1]));
 99198 } elseif ('null' === $item[0]) {
 99199 $formattedValue = '<em>null</em>';
 99200 } elseif ('boolean' === $item[0]) {
 99201 $formattedValue = '<em>'.strtolower(var_export($item[1], true)).'</em>';
 99202 } elseif ('resource' === $item[0]) {
 99203 $formattedValue = '<em>resource</em>';
 99204 } else {
 99205 $formattedValue = str_replace("\n", '', var_export($this->escapeHtml((string) $item[1]), true));
 99206 }
 99207 
 99208 $result[] = \is_int($key) ? $formattedValue : sprintf("'%s' => %s", $this->escapeHtml($key), $formattedValue);
 99209 }
 99210 
 99211 return implode(', ', $result);
 99212 }
 99213 
 99214 
 99215 
 99216 
 99217 
 99218 
 99219 protected static function utf8Htmlize($str)
 99220 {
 99221 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
 99222 
 99223 return htmlspecialchars($str, ENT_QUOTES | (\PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), 'UTF-8');
 99224 }
 99225 
 99226 
 99227 
 99228 
 99229 private function escapeHtml($str)
 99230 {
 99231 return htmlspecialchars($str, ENT_QUOTES | (\PHP_VERSION_ID >= 50400 ? ENT_SUBSTITUTE : 0), $this->charset);
 99232 }
 99233 
 99234 
 99235 
 99236 
 99237 public function catchOutput($buffer)
 99238 {
 99239 $this->caughtBuffer = $buffer;
 99240 
 99241 return '';
 99242 }
 99243 
 99244 
 99245 
 99246 
 99247 public function cleanOutput($buffer)
 99248 {
 99249 if ($this->caughtLength) {
 99250 
 99251 $cleanBuffer = substr_replace($buffer, '', 0, $this->caughtLength);
 99252 if (isset($cleanBuffer[0])) {
 99253 $buffer = $cleanBuffer;
 99254 }
 99255 }
 99256 
 99257 return $buffer;
 99258 }
 99259 }
 99260 <?php
 99261 
 99262 
 99263 
 99264 
 99265 
 99266 
 99267 
 99268 
 99269 
 99270 
 99271 namespace Symfony\Component\Debug\FatalErrorHandler;
 99272 
 99273 use Composer\Autoload\ClassLoader as ComposerClassLoader;
 99274 use Symfony\Component\ClassLoader\ClassLoader as SymfonyClassLoader;
 99275 use Symfony\Component\ClassLoader\UniversalClassLoader as SymfonyUniversalClassLoader;
 99276 use Symfony\Component\Debug\DebugClassLoader;
 99277 use Symfony\Component\Debug\Exception\ClassNotFoundException;
 99278 use Symfony\Component\Debug\Exception\FatalErrorException;
 99279 
 99280 
 99281 
 99282 
 99283 
 99284 
 99285 class ClassNotFoundFatalErrorHandler implements FatalErrorHandlerInterface
 99286 {
 99287 
 99288 
 99289 
 99290 public function handleError(array $error, FatalErrorException $exception)
 99291 {
 99292 $messageLen = \strlen($error['message']);
 99293 $notFoundSuffix = '\' not found';
 99294 $notFoundSuffixLen = \strlen($notFoundSuffix);
 99295 if ($notFoundSuffixLen > $messageLen) {
 99296 return;
 99297 }
 99298 
 99299 if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
 99300 return;
 99301 }
 99302 
 99303 foreach (array('class', 'interface', 'trait') as $typeName) {
 99304 $prefix = ucfirst($typeName).' \'';
 99305 $prefixLen = \strlen($prefix);
 99306 if (0 !== strpos($error['message'], $prefix)) {
 99307 continue;
 99308 }
 99309 
 99310 $fullyQualifiedClassName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
 99311 if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedClassName, '\\')) {
 99312 $className = substr($fullyQualifiedClassName, $namespaceSeparatorIndex + 1);
 99313 $namespacePrefix = substr($fullyQualifiedClassName, 0, $namespaceSeparatorIndex);
 99314 $message = sprintf('Attempted to load %s "%s" from namespace "%s".', $typeName, $className, $namespacePrefix);
 99315 $tail = ' for another namespace?';
 99316 } else {
 99317 $className = $fullyQualifiedClassName;
 99318 $message = sprintf('Attempted to load %s "%s" from the global namespace.', $typeName, $className);
 99319 $tail = '?';
 99320 }
 99321 
 99322 if ($candidates = $this->getClassCandidates($className)) {
 99323 $tail = array_pop($candidates).'"?';
 99324 if ($candidates) {
 99325 $tail = ' for e.g. "'.implode('", "', $candidates).'" or "'.$tail;
 99326 } else {
 99327 $tail = ' for "'.$tail;
 99328 }
 99329 }
 99330 $message .= "\nDid you forget a \"use\" statement".$tail;
 99331 
 99332 return new ClassNotFoundException($message, $exception);
 99333 }
 99334 }
 99335 
 99336 
 99337 
 99338 
 99339 
 99340 
 99341 
 99342 
 99343 
 99344 
 99345 
 99346 private function getClassCandidates($class)
 99347 {
 99348 if (!\is_array($functions = spl_autoload_functions())) {
 99349 return array();
 99350 }
 99351 
 99352 
 99353 $classes = array();
 99354 
 99355 foreach ($functions as $function) {
 99356 if (!\is_array($function)) {
 99357 continue;
 99358 }
 99359 
 99360 if ($function[0] instanceof DebugClassLoader) {
 99361 $function = $function[0]->getClassLoader();
 99362 
 99363 
 99364 if (\is_object($function)) {
 99365 $function = array($function);
 99366 }
 99367 
 99368 if (!\is_array($function)) {
 99369 continue;
 99370 }
 99371 }
 99372 
 99373 if ($function[0] instanceof ComposerClassLoader || $function[0] instanceof SymfonyClassLoader || $function[0] instanceof SymfonyUniversalClassLoader) {
 99374 foreach ($function[0]->getPrefixes() as $prefix => $paths) {
 99375 foreach ($paths as $path) {
 99376 $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
 99377 }
 99378 }
 99379 }
 99380 if ($function[0] instanceof ComposerClassLoader) {
 99381 foreach ($function[0]->getPrefixesPsr4() as $prefix => $paths) {
 99382 foreach ($paths as $path) {
 99383 $classes = array_merge($classes, $this->findClassInPath($path, $class, $prefix));
 99384 }
 99385 }
 99386 }
 99387 }
 99388 
 99389 return array_unique($classes);
 99390 }
 99391 
 99392 
 99393 
 99394 
 99395 
 99396 
 99397 
 99398 
 99399 private function findClassInPath($path, $class, $prefix)
 99400 {
 99401 if (!$path = realpath($path.'/'.strtr($prefix, '\\_', '//')) ?: realpath($path.'/'.\dirname(strtr($prefix, '\\_', '//'))) ?: realpath($path)) {
 99402 return array();
 99403 }
 99404 
 99405 $classes = array();
 99406 $filename = $class.'.php';
 99407 foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
 99408 if ($filename == $file->getFileName() && $class = $this->convertFileToClass($path, $file->getPathName(), $prefix)) {
 99409 $classes[] = $class;
 99410 }
 99411 }
 99412 
 99413 return $classes;
 99414 }
 99415 
 99416 
 99417 
 99418 
 99419 
 99420 
 99421 
 99422 
 99423 private function convertFileToClass($path, $file, $prefix)
 99424 {
 99425 $candidates = array(
 99426 
 99427 $namespacedClass = str_replace(array($path.\DIRECTORY_SEPARATOR, '.php', '/'), array('', '', '\\'), $file),
 99428 
 99429 $prefix.$namespacedClass,
 99430 
 99431 $prefix.'\\'.$namespacedClass,
 99432 
 99433 str_replace('\\', '_', $namespacedClass),
 99434 
 99435 str_replace('\\', '_', $prefix.$namespacedClass),
 99436 
 99437 str_replace('\\', '_', $prefix.'\\'.$namespacedClass),
 99438 );
 99439 
 99440 if ($prefix) {
 99441 $candidates = array_filter($candidates, function ($candidate) use ($prefix) { return 0 === strpos($candidate, $prefix); });
 99442 }
 99443 
 99444 
 99445 
 99446 
 99447 foreach ($candidates as $candidate) {
 99448 if ($this->classExists($candidate)) {
 99449 return $candidate;
 99450 }
 99451 }
 99452 
 99453 require_once $file;
 99454 
 99455 foreach ($candidates as $candidate) {
 99456 if ($this->classExists($candidate)) {
 99457 return $candidate;
 99458 }
 99459 }
 99460 }
 99461 
 99462 
 99463 
 99464 
 99465 
 99466 
 99467 private function classExists($class)
 99468 {
 99469 return class_exists($class, false) || interface_exists($class, false) || (\function_exists('trait_exists') && trait_exists($class, false));
 99470 }
 99471 }
 99472 <?php
 99473 
 99474 
 99475 
 99476 
 99477 
 99478 
 99479 
 99480 
 99481 
 99482 
 99483 namespace Symfony\Component\Debug\FatalErrorHandler;
 99484 
 99485 use Symfony\Component\Debug\Exception\FatalErrorException;
 99486 
 99487 
 99488 
 99489 
 99490 
 99491 
 99492 interface FatalErrorHandlerInterface
 99493 {
 99494 
 99495 
 99496 
 99497 
 99498 
 99499 
 99500 
 99501 
 99502 public function handleError(array $error, FatalErrorException $exception);
 99503 }
 99504 <?php
 99505 
 99506 
 99507 
 99508 
 99509 
 99510 
 99511 
 99512 
 99513 
 99514 
 99515 namespace Symfony\Component\Debug\FatalErrorHandler;
 99516 
 99517 use Symfony\Component\Debug\Exception\FatalErrorException;
 99518 use Symfony\Component\Debug\Exception\UndefinedFunctionException;
 99519 
 99520 
 99521 
 99522 
 99523 
 99524 
 99525 class UndefinedFunctionFatalErrorHandler implements FatalErrorHandlerInterface
 99526 {
 99527 
 99528 
 99529 
 99530 public function handleError(array $error, FatalErrorException $exception)
 99531 {
 99532 $messageLen = \strlen($error['message']);
 99533 $notFoundSuffix = '()';
 99534 $notFoundSuffixLen = \strlen($notFoundSuffix);
 99535 if ($notFoundSuffixLen > $messageLen) {
 99536 return;
 99537 }
 99538 
 99539 if (0 !== substr_compare($error['message'], $notFoundSuffix, -$notFoundSuffixLen)) {
 99540 return;
 99541 }
 99542 
 99543 $prefix = 'Call to undefined function ';
 99544 $prefixLen = \strlen($prefix);
 99545 if (0 !== strpos($error['message'], $prefix)) {
 99546 return;
 99547 }
 99548 
 99549 $fullyQualifiedFunctionName = substr($error['message'], $prefixLen, -$notFoundSuffixLen);
 99550 if (false !== $namespaceSeparatorIndex = strrpos($fullyQualifiedFunctionName, '\\')) {
 99551 $functionName = substr($fullyQualifiedFunctionName, $namespaceSeparatorIndex + 1);
 99552 $namespacePrefix = substr($fullyQualifiedFunctionName, 0, $namespaceSeparatorIndex);
 99553 $message = sprintf('Attempted to call function "%s" from namespace "%s".', $functionName, $namespacePrefix);
 99554 } else {
 99555 $functionName = $fullyQualifiedFunctionName;
 99556 $message = sprintf('Attempted to call function "%s" from the global namespace.', $functionName);
 99557 }
 99558 
 99559 $candidates = array();
 99560 foreach (get_defined_functions() as $type => $definedFunctionNames) {
 99561 foreach ($definedFunctionNames as $definedFunctionName) {
 99562 if (false !== $namespaceSeparatorIndex = strrpos($definedFunctionName, '\\')) {
 99563 $definedFunctionNameBasename = substr($definedFunctionName, $namespaceSeparatorIndex + 1);
 99564 } else {
 99565 $definedFunctionNameBasename = $definedFunctionName;
 99566 }
 99567 
 99568 if ($definedFunctionNameBasename === $functionName) {
 99569 $candidates[] = '\\'.$definedFunctionName;
 99570 }
 99571 }
 99572 }
 99573 
 99574 if ($candidates) {
 99575 sort($candidates);
 99576 $last = array_pop($candidates).'"?';
 99577 if ($candidates) {
 99578 $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
 99579 } else {
 99580 $candidates = '"'.$last;
 99581 }
 99582 $message .= "\nDid you mean to call ".$candidates;
 99583 }
 99584 
 99585 return new UndefinedFunctionException($message, $exception);
 99586 }
 99587 }
 99588 <?php
 99589 
 99590 
 99591 
 99592 
 99593 
 99594 
 99595 
 99596 
 99597 
 99598 
 99599 namespace Symfony\Component\Debug\FatalErrorHandler;
 99600 
 99601 use Symfony\Component\Debug\Exception\FatalErrorException;
 99602 use Symfony\Component\Debug\Exception\UndefinedMethodException;
 99603 
 99604 
 99605 
 99606 
 99607 
 99608 
 99609 class UndefinedMethodFatalErrorHandler implements FatalErrorHandlerInterface
 99610 {
 99611 
 99612 
 99613 
 99614 public function handleError(array $error, FatalErrorException $exception)
 99615 {
 99616 preg_match('/^Call to undefined method (.*)::(.*)\(\)$/', $error['message'], $matches);
 99617 if (!$matches) {
 99618 return;
 99619 }
 99620 
 99621 $className = $matches[1];
 99622 $methodName = $matches[2];
 99623 
 99624 $message = sprintf('Attempted to call an undefined method named "%s" of class "%s".', $methodName, $className);
 99625 
 99626 if (!class_exists($className) || null === $methods = get_class_methods($className)) {
 99627 
 99628 return new UndefinedMethodException($message, $exception);
 99629 }
 99630 
 99631 $candidates = array();
 99632 foreach ($methods as $definedMethodName) {
 99633 $lev = levenshtein($methodName, $definedMethodName);
 99634 if ($lev <= \strlen($methodName) / 3 || false !== strpos($definedMethodName, $methodName)) {
 99635 $candidates[] = $definedMethodName;
 99636 }
 99637 }
 99638 
 99639 if ($candidates) {
 99640 sort($candidates);
 99641 $last = array_pop($candidates).'"?';
 99642 if ($candidates) {
 99643 $candidates = 'e.g. "'.implode('", "', $candidates).'" or "'.$last;
 99644 } else {
 99645 $candidates = '"'.$last;
 99646 }
 99647 
 99648 $message .= "\nDid you mean to call ".$candidates;
 99649 }
 99650 
 99651 return new UndefinedMethodException($message, $exception);
 99652 }
 99653 }
 99654 
 99655 Copyright (c) 2004-2018 Fabien Potencier
 99656 
 99657 Permission is hereby granted, free of charge, to any person obtaining a copy
 99658 of this software and associated documentation files (the "Software"), to deal
 99659 in the Software without restriction, including without limitation the rights
 99660 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 99661 copies of the Software, and to permit persons to whom the Software is furnished
 99662 to do so, subject to the following conditions:
 99663 
 99664 The above copyright notice and this permission notice shall be included in all
 99665 copies or substantial portions of the Software.
 99666 
 99667 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 99668 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 99669 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 99670 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 99671 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 99672 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 99673 THE SOFTWARE.
 99674 
 99675 <?php
 99676 
 99677 
 99678 
 99679 
 99680 
 99681 
 99682 
 99683 
 99684 
 99685 
 99686 namespace Symfony\Component\Filesystem\Exception;
 99687 
 99688 
 99689 
 99690 
 99691 
 99692 
 99693 interface ExceptionInterface
 99694 {
 99695 }
 99696 <?php
 99697 
 99698 
 99699 
 99700 
 99701 
 99702 
 99703 
 99704 
 99705 
 99706 
 99707 namespace Symfony\Component\Filesystem\Exception;
 99708 
 99709 
 99710 
 99711 
 99712 
 99713 
 99714 
 99715 class FileNotFoundException extends IOException
 99716 {
 99717 public function __construct($message = null, $code = 0, \Exception $previous = null, $path = null)
 99718 {
 99719 if (null === $message) {
 99720 if (null === $path) {
 99721 $message = 'File could not be found.';
 99722 } else {
 99723 $message = sprintf('File "%s" could not be found.', $path);
 99724 }
 99725 }
 99726 
 99727 parent::__construct($message, $code, $previous, $path);
 99728 }
 99729 }
 99730 <?php
 99731 
 99732 
 99733 
 99734 
 99735 
 99736 
 99737 
 99738 
 99739 
 99740 
 99741 namespace Symfony\Component\Filesystem\Exception;
 99742 
 99743 
 99744 
 99745 
 99746 
 99747 
 99748 
 99749 
 99750 class IOException extends \RuntimeException implements IOExceptionInterface
 99751 {
 99752 private $path;
 99753 
 99754 public function __construct($message, $code = 0, \Exception $previous = null, $path = null)
 99755 {
 99756 $this->path = $path;
 99757 
 99758 parent::__construct($message, $code, $previous);
 99759 }
 99760 
 99761 
 99762 
 99763 
 99764 public function getPath()
 99765 {
 99766 return $this->path;
 99767 }
 99768 }
 99769 <?php
 99770 
 99771 
 99772 
 99773 
 99774 
 99775 
 99776 
 99777 
 99778 
 99779 
 99780 namespace Symfony\Component\Filesystem\Exception;
 99781 
 99782 
 99783 
 99784 
 99785 
 99786 
 99787 interface IOExceptionInterface extends ExceptionInterface
 99788 {
 99789 
 99790 
 99791 
 99792 
 99793 
 99794 public function getPath();
 99795 }
 99796 <?php
 99797 
 99798 
 99799 
 99800 
 99801 
 99802 
 99803 
 99804 
 99805 
 99806 
 99807 namespace Symfony\Component\Filesystem;
 99808 
 99809 use Symfony\Component\Filesystem\Exception\FileNotFoundException;
 99810 use Symfony\Component\Filesystem\Exception\IOException;
 99811 
 99812 
 99813 
 99814 
 99815 
 99816 
 99817 class Filesystem
 99818 {
 99819 private static $lastError;
 99820 
 99821 
 99822 
 99823 
 99824 
 99825 
 99826 
 99827 
 99828 
 99829 
 99830 
 99831 
 99832 
 99833 
 99834 
 99835 public function copy($originFile, $targetFile, $overwriteNewerFiles = false)
 99836 {
 99837 $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
 99838 if ($originIsLocal && !is_file($originFile)) {
 99839 throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
 99840 }
 99841 
 99842 $this->mkdir(\dirname($targetFile));
 99843 
 99844 $doCopy = true;
 99845 if (!$overwriteNewerFiles && null === parse_url($originFile, PHP_URL_HOST) && is_file($targetFile)) {
 99846 $doCopy = filemtime($originFile) > filemtime($targetFile);
 99847 }
 99848 
 99849 if ($doCopy) {
 99850 
 99851 if (false === $source = @fopen($originFile, 'r')) {
 99852 throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading.', $originFile, $targetFile), 0, null, $originFile);
 99853 }
 99854 
 99855 
 99856 if (false === $target = @fopen($targetFile, 'w', null, stream_context_create(array('ftp' => array('overwrite' => true))))) {
 99857 throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing.', $originFile, $targetFile), 0, null, $originFile);
 99858 }
 99859 
 99860 $bytesCopied = stream_copy_to_stream($source, $target);
 99861 fclose($source);
 99862 fclose($target);
 99863 unset($source, $target);
 99864 
 99865 if (!is_file($targetFile)) {
 99866 throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
 99867 }
 99868 
 99869 if ($originIsLocal) {
 99870 
 99871 @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));
 99872 
 99873 if ($bytesCopied !== $bytesOrigin = filesize($originFile)) {
 99874 throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
 99875 }
 99876 }
 99877 }
 99878 }
 99879 
 99880 
 99881 
 99882 
 99883 
 99884 
 99885 
 99886 
 99887 
 99888 public function mkdir($dirs, $mode = 0777)
 99889 {
 99890 foreach ($this->toIterator($dirs) as $dir) {
 99891 if (is_dir($dir)) {
 99892 continue;
 99893 }
 99894 
 99895 if (!self::box('mkdir', $dir, $mode, true)) {
 99896 if (!is_dir($dir)) {
 99897 
 99898 if (self::$lastError) {
 99899 throw new IOException(sprintf('Failed to create "%s": %s.', $dir, self::$lastError), 0, null, $dir);
 99900 }
 99901 throw new IOException(sprintf('Failed to create "%s"', $dir), 0, null, $dir);
 99902 }
 99903 }
 99904 }
 99905 }
 99906 
 99907 
 99908 
 99909 
 99910 
 99911 
 99912 
 99913 
 99914 public function exists($files)
 99915 {
 99916 $maxPathLength = PHP_MAXPATHLEN - 2;
 99917 
 99918 foreach ($this->toIterator($files) as $file) {
 99919 if (\strlen($file) > $maxPathLength) {
 99920 throw new IOException(sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file);
 99921 }
 99922 
 99923 if (!file_exists($file)) {
 99924 return false;
 99925 }
 99926 }
 99927 
 99928 return true;
 99929 }
 99930 
 99931 
 99932 
 99933 
 99934 
 99935 
 99936 
 99937 
 99938 
 99939 
 99940 public function touch($files, $time = null, $atime = null)
 99941 {
 99942 foreach ($this->toIterator($files) as $file) {
 99943 $touch = $time ? @touch($file, $time, $atime) : @touch($file);
 99944 if (true !== $touch) {
 99945 throw new IOException(sprintf('Failed to touch "%s".', $file), 0, null, $file);
 99946 }
 99947 }
 99948 }
 99949 
 99950 
 99951 
 99952 
 99953 
 99954 
 99955 
 99956 
 99957 public function remove($files)
 99958 {
 99959 if ($files instanceof \Traversable) {
 99960 $files = iterator_to_array($files, false);
 99961 } elseif (!\is_array($files)) {
 99962 $files = array($files);
 99963 }
 99964 $files = array_reverse($files);
 99965 foreach ($files as $file) {
 99966 if (is_link($file)) {
 99967 
 99968 if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) {
 99969 throw new IOException(sprintf('Failed to remove symlink "%s": %s.', $file, self::$lastError));
 99970 }
 99971 } elseif (is_dir($file)) {
 99972 $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS));
 99973 
 99974 if (!self::box('rmdir', $file) && file_exists($file)) {
 99975 throw new IOException(sprintf('Failed to remove directory "%s": %s.', $file, self::$lastError));
 99976 }
 99977 } elseif (!self::box('unlink', $file) && file_exists($file)) {
 99978 throw new IOException(sprintf('Failed to remove file "%s": %s.', $file, self::$lastError));
 99979 }
 99980 }
 99981 }
 99982 
 99983 
 99984 
 99985 
 99986 
 99987 
 99988 
 99989 
 99990 
 99991 
 99992 
 99993 public function chmod($files, $mode, $umask = 0000, $recursive = false)
 99994 {
 99995 foreach ($this->toIterator($files) as $file) {
 99996 if (true !== @chmod($file, $mode & ~$umask)) {
 99997 throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file);
 99998 }
 99999 if ($recursive && is_dir($file) && !is_link($file)) {
100000 $this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
100001 }
100002 }
100003 }
100004 
100005 
100006 
100007 
100008 
100009 
100010 
100011 
100012 
100013 
100014 public function chown($files, $user, $recursive = false)
100015 {
100016 foreach ($this->toIterator($files) as $file) {
100017 if ($recursive && is_dir($file) && !is_link($file)) {
100018 $this->chown(new \FilesystemIterator($file), $user, true);
100019 }
100020 if (is_link($file) && \function_exists('lchown')) {
100021 if (true !== @lchown($file, $user)) {
100022 throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
100023 }
100024 } else {
100025 if (true !== @chown($file, $user)) {
100026 throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file);
100027 }
100028 }
100029 }
100030 }
100031 
100032 
100033 
100034 
100035 
100036 
100037 
100038 
100039 
100040 
100041 public function chgrp($files, $group, $recursive = false)
100042 {
100043 foreach ($this->toIterator($files) as $file) {
100044 if ($recursive && is_dir($file) && !is_link($file)) {
100045 $this->chgrp(new \FilesystemIterator($file), $group, true);
100046 }
100047 if (is_link($file) && \function_exists('lchgrp')) {
100048 if (true !== @lchgrp($file, $group) || (\defined('HHVM_VERSION') && !posix_getgrnam($group))) {
100049 throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
100050 }
100051 } else {
100052 if (true !== @chgrp($file, $group)) {
100053 throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file);
100054 }
100055 }
100056 }
100057 }
100058 
100059 
100060 
100061 
100062 
100063 
100064 
100065 
100066 
100067 
100068 
100069 public function rename($origin, $target, $overwrite = false)
100070 {
100071 
100072 if (!$overwrite && $this->isReadable($target)) {
100073 throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
100074 }
100075 
100076 if (true !== @rename($origin, $target)) {
100077 if (is_dir($origin)) {
100078 
100079 $this->mirror($origin, $target, null, array('override' => $overwrite, 'delete' => $overwrite));
100080 $this->remove($origin);
100081 
100082 return;
100083 }
100084 throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target);
100085 }
100086 }
100087 
100088 
100089 
100090 
100091 
100092 
100093 
100094 
100095 
100096 
100097 private function isReadable($filename)
100098 {
100099 $maxPathLength = PHP_MAXPATHLEN - 2;
100100 
100101 if (\strlen($filename) > $maxPathLength) {
100102 throw new IOException(sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename);
100103 }
100104 
100105 return is_readable($filename);
100106 }
100107 
100108 
100109 
100110 
100111 
100112 
100113 
100114 
100115 
100116 
100117 public function symlink($originDir, $targetDir, $copyOnWindows = false)
100118 {
100119 if ('\\' === \DIRECTORY_SEPARATOR) {
100120 $originDir = strtr($originDir, '/', '\\');
100121 $targetDir = strtr($targetDir, '/', '\\');
100122 
100123 if ($copyOnWindows) {
100124 $this->mirror($originDir, $targetDir);
100125 
100126 return;
100127 }
100128 }
100129 
100130 $this->mkdir(\dirname($targetDir));
100131 
100132 if (is_link($targetDir)) {
100133 if (readlink($targetDir) === $originDir) {
100134 return;
100135 }
100136 $this->remove($targetDir);
100137 }
100138 
100139 if (!self::box('symlink', $originDir, $targetDir)) {
100140 if (null !== self::$lastError) {
100141 if ('\\' === \DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) {
100142 throw new IOException('Unable to create symlink due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', 0, null, $targetDir);
100143 }
100144 }
100145 throw new IOException(sprintf('Failed to create symbolic link from "%s" to "%s".', $originDir, $targetDir), 0, null, $targetDir);
100146 }
100147 }
100148 
100149 
100150 
100151 
100152 
100153 
100154 
100155 
100156 
100157 public function makePathRelative($endPath, $startPath)
100158 {
100159 
100160 if ('\\' === \DIRECTORY_SEPARATOR) {
100161 $endPath = str_replace('\\', '/', $endPath);
100162 $startPath = str_replace('\\', '/', $startPath);
100163 }
100164 
100165 $stripDriveLetter = function ($path) {
100166 if (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) {
100167 return substr($path, 2);
100168 }
100169 
100170 return $path;
100171 };
100172 
100173 $endPath = $stripDriveLetter($endPath);
100174 $startPath = $stripDriveLetter($startPath);
100175 
100176 
100177 $startPathArr = explode('/', trim($startPath, '/'));
100178 $endPathArr = explode('/', trim($endPath, '/'));
100179 
100180 $normalizePathArray = function ($pathSegments, $absolute) {
100181 $result = array();
100182 
100183 foreach ($pathSegments as $segment) {
100184 if ('..' === $segment && ($absolute || \count($result))) {
100185 array_pop($result);
100186 } elseif ('.' !== $segment) {
100187 $result[] = $segment;
100188 }
100189 }
100190 
100191 return $result;
100192 };
100193 
100194 $startPathArr = $normalizePathArray($startPathArr, static::isAbsolutePath($startPath));
100195 $endPathArr = $normalizePathArray($endPathArr, static::isAbsolutePath($endPath));
100196 
100197 
100198 $index = 0;
100199 while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
100200 ++$index;
100201 }
100202 
100203 
100204 if (1 === \count($startPathArr) && '' === $startPathArr[0]) {
100205 $depth = 0;
100206 } else {
100207 $depth = \count($startPathArr) - $index;
100208 }
100209 
100210 
100211 $traverser = str_repeat('../', $depth);
100212 
100213 $endPathRemainder = implode('/', \array_slice($endPathArr, $index));
100214 
100215 
100216 $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : '');
100217 
100218 return '' === $relativePath ? './' : $relativePath;
100219 }
100220 
100221 
100222 
100223 
100224 
100225 
100226 
100227 
100228 
100229 
100230 
100231 
100232 
100233 
100234 
100235 
100236 
100237 
100238 
100239 
100240 public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array())
100241 {
100242 $targetDir = rtrim($targetDir, '/\\');
100243 $originDir = rtrim($originDir, '/\\');
100244 $originDirLen = \strlen($originDir);
100245 
100246 
100247 if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
100248 $deleteIterator = $iterator;
100249 if (null === $deleteIterator) {
100250 $flags = \FilesystemIterator::SKIP_DOTS;
100251 $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
100252 }
100253 $targetDirLen = \strlen($targetDir);
100254 foreach ($deleteIterator as $file) {
100255 $origin = $originDir.substr($file->getPathname(), $targetDirLen);
100256 if (!$this->exists($origin)) {
100257 $this->remove($file);
100258 }
100259 }
100260 }
100261 
100262 $copyOnWindows = false;
100263 if (isset($options['copy_on_windows'])) {
100264 $copyOnWindows = $options['copy_on_windows'];
100265 }
100266 
100267 if (null === $iterator) {
100268 $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
100269 $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
100270 }
100271 
100272 if ($this->exists($originDir)) {
100273 $this->mkdir($targetDir);
100274 }
100275 
100276 foreach ($iterator as $file) {
100277 $target = $targetDir.substr($file->getPathname(), $originDirLen);
100278 
100279 if ($copyOnWindows) {
100280 if (is_file($file)) {
100281 $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
100282 } elseif (is_dir($file)) {
100283 $this->mkdir($target);
100284 } else {
100285 throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
100286 }
100287 } else {
100288 if (is_link($file)) {
100289 $this->symlink($file->getLinkTarget(), $target);
100290 } elseif (is_dir($file)) {
100291 $this->mkdir($target);
100292 } elseif (is_file($file)) {
100293 $this->copy($file, $target, isset($options['override']) ? $options['override'] : false);
100294 } else {
100295 throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
100296 }
100297 }
100298 }
100299 }
100300 
100301 
100302 
100303 
100304 
100305 
100306 
100307 
100308 public function isAbsolutePath($file)
100309 {
100310 return strspn($file, '/\\', 0, 1)
100311 || (\strlen($file) > 3 && ctype_alpha($file[0])
100312 && ':' === substr($file, 1, 1)
100313 && strspn($file, '/\\', 2, 1)
100314 )
100315 || null !== parse_url($file, PHP_URL_SCHEME)
100316 ;
100317 }
100318 
100319 
100320 
100321 
100322 
100323 
100324 
100325 
100326 
100327 
100328 public function tempnam($dir, $prefix)
100329 {
100330 list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir);
100331 
100332 
100333 if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) {
100334 $tmpFile = @tempnam($hierarchy, $prefix);
100335 
100336 
100337 if (false !== $tmpFile) {
100338 if (null !== $scheme && 'gs' !== $scheme) {
100339 return $scheme.'://'.$tmpFile;
100340 }
100341 
100342 return $tmpFile;
100343 }
100344 
100345 throw new IOException('A temporary file could not be created.');
100346 }
100347 
100348 
100349 for ($i = 0; $i < 10; ++$i) {
100350 
100351 $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true);
100352 
100353 
100354 
100355 $handle = @fopen($tmpFile, 'x+');
100356 
100357 
100358 if (false === $handle) {
100359 continue;
100360 }
100361 
100362 
100363 @fclose($handle);
100364 
100365 return $tmpFile;
100366 }
100367 
100368 throw new IOException('A temporary file could not be created.');
100369 }
100370 
100371 
100372 
100373 
100374 
100375 
100376 
100377 
100378 
100379 
100380 
100381 public function dumpFile($filename, $content, $mode = 0666)
100382 {
100383 $dir = \dirname($filename);
100384 
100385 if (!is_dir($dir)) {
100386 $this->mkdir($dir);
100387 }
100388 
100389 if (!is_writable($dir)) {
100390 throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir);
100391 }
100392 
100393 $tmpFile = $this->tempnam($dir, basename($filename));
100394 
100395 if (false === @file_put_contents($tmpFile, $content)) {
100396 throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename);
100397 }
100398 
100399 if (null !== $mode) {
100400 if (\func_num_args() > 2) {
100401 @trigger_error('Support for modifying file permissions is deprecated since Symfony 2.3.12 and will be removed in 3.0.', E_USER_DEPRECATED);
100402 }
100403 
100404 $this->chmod($tmpFile, $mode);
100405 } elseif (file_exists($filename)) {
100406 @chmod($tmpFile, fileperms($filename));
100407 }
100408 
100409 $this->rename($tmpFile, $filename, true);
100410 }
100411 
100412 
100413 
100414 
100415 
100416 
100417 private function toIterator($files)
100418 {
100419 if (!$files instanceof \Traversable) {
100420 $files = new \ArrayObject(\is_array($files) ? $files : array($files));
100421 }
100422 
100423 return $files;
100424 }
100425 
100426 
100427 
100428 
100429 
100430 
100431 
100432 
100433 private function getSchemeAndHierarchy($filename)
100434 {
100435 $components = explode('://', $filename, 2);
100436 
100437 return 2 === \count($components) ? array($components[0], $components[1]) : array(null, $components[0]);
100438 }
100439 
100440 private static function box($func)
100441 {
100442 self::$lastError = null;
100443 \set_error_handler(__CLASS__.'::handleError');
100444 try {
100445 $result = \call_user_func_array($func, \array_slice(\func_get_args(), 1));
100446 \restore_error_handler();
100447 
100448 return $result;
100449 } catch (\Throwable $e) {
100450 } catch (\Exception $e) {
100451 }
100452 \restore_error_handler();
100453 
100454 throw $e;
100455 }
100456 
100457 
100458 
100459 
100460 public static function handleError($type, $msg)
100461 {
100462 self::$lastError = $msg;
100463 }
100464 }
100465 
100466 Copyright (c) 2004-2018 Fabien Potencier
100467 
100468 Permission is hereby granted, free of charge, to any person obtaining a copy
100469 of this software and associated documentation files (the "Software"), to deal
100470 in the Software without restriction, including without limitation the rights
100471 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
100472 copies of the Software, and to permit persons to whom the Software is furnished
100473 to do so, subject to the following conditions:
100474 
100475 The above copyright notice and this permission notice shall be included in all
100476 copies or substantial portions of the Software.
100477 
100478 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
100479 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
100480 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
100481 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
100482 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
100483 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
100484 THE SOFTWARE.
100485 
100486 <?php
100487 
100488 
100489 
100490 
100491 
100492 
100493 
100494 
100495 
100496 
100497 namespace Symfony\Component\Filesystem;
100498 
100499 use Symfony\Component\Filesystem\Exception\IOException;
100500 
100501 
100502 
100503 
100504 
100505 
100506 
100507 
100508 
100509 
100510 
100511 
100512 
100513 
100514 class LockHandler
100515 {
100516 private $file;
100517 private $handle;
100518 
100519 
100520 
100521 
100522 
100523 
100524 
100525 public function __construct($name, $lockPath = null)
100526 {
100527 $lockPath = $lockPath ?: sys_get_temp_dir();
100528 
100529 if (!is_dir($lockPath)) {
100530 $fs = new Filesystem();
100531 $fs->mkdir($lockPath);
100532 }
100533 
100534 if (!is_writable($lockPath)) {
100535 throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath);
100536 }
100537 
100538 $this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name));
100539 }
100540 
100541 
100542 
100543 
100544 
100545 
100546 
100547 
100548 
100549 
100550 public function lock($blocking = false)
100551 {
100552 if ($this->handle) {
100553 return true;
100554 }
100555 
100556 $error = null;
100557 
100558 
100559 set_error_handler(function ($errno, $msg) use (&$error) {
100560 $error = $msg;
100561 });
100562 
100563 if (!$this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r')) {
100564 if ($this->handle = fopen($this->file, 'x')) {
100565 chmod($this->file, 0666);
100566 } elseif (!$this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r')) {
100567 usleep(100); 
100568 $this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r');
100569 }
100570 }
100571 restore_error_handler();
100572 
100573 if (!$this->handle) {
100574 throw new IOException($error, 0, null, $this->file);
100575 }
100576 
100577 
100578 
100579 if (!flock($this->handle, LOCK_EX | ($blocking ? 0 : LOCK_NB))) {
100580 fclose($this->handle);
100581 $this->handle = null;
100582 
100583 return false;
100584 }
100585 
100586 return true;
100587 }
100588 
100589 
100590 
100591 
100592 public function release()
100593 {
100594 if ($this->handle) {
100595 flock($this->handle, LOCK_UN | LOCK_NB);
100596 fclose($this->handle);
100597 $this->handle = null;
100598 }
100599 }
100600 }
100601 <?php
100602 
100603 
100604 
100605 
100606 
100607 
100608 
100609 
100610 
100611 
100612 namespace Symfony\Component\Finder\Adapter;
100613 
100614 @trigger_error('The '.__NAMESPACE__.'\AbstractAdapter class is deprecated since Symfony 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
100615 
100616 
100617 
100618 
100619 
100620 
100621 
100622 
100623 abstract class AbstractAdapter implements AdapterInterface
100624 {
100625 protected $followLinks = false;
100626 protected $mode = 0;
100627 protected $minDepth = 0;
100628 protected $maxDepth = PHP_INT_MAX;
100629 protected $exclude = array();
100630 protected $names = array();
100631 protected $notNames = array();
100632 protected $contains = array();
100633 protected $notContains = array();
100634 protected $sizes = array();
100635 protected $dates = array();
100636 protected $filters = array();
100637 protected $sort = false;
100638 protected $paths = array();
100639 protected $notPaths = array();
100640 protected $ignoreUnreadableDirs = false;
100641 
100642 private static $areSupported = array();
100643 
100644 
100645 
100646 
100647 public function isSupported()
100648 {
100649 $name = $this->getName();
100650 
100651 if (!array_key_exists($name, self::$areSupported)) {
100652 self::$areSupported[$name] = $this->canBeUsed();
100653 }
100654 
100655 return self::$areSupported[$name];
100656 }
100657 
100658 
100659 
100660 
100661 public function setFollowLinks($followLinks)
100662 {
100663 $this->followLinks = $followLinks;
100664 
100665 return $this;
100666 }
100667 
100668 
100669 
100670 
100671 public function setMode($mode)
100672 {
100673 $this->mode = $mode;
100674 
100675 return $this;
100676 }
100677 
100678 
100679 
100680 
100681 public function setDepths(array $depths)
100682 {
100683 $this->minDepth = 0;
100684 $this->maxDepth = PHP_INT_MAX;
100685 
100686 foreach ($depths as $comparator) {
100687 switch ($comparator->getOperator()) {
100688 case '>':
100689 $this->minDepth = $comparator->getTarget() + 1;
100690 break;
100691 case '>=':
100692 $this->minDepth = $comparator->getTarget();
100693 break;
100694 case '<':
100695 $this->maxDepth = $comparator->getTarget() - 1;
100696 break;
100697 case '<=':
100698 $this->maxDepth = $comparator->getTarget();
100699 break;
100700 default:
100701 $this->minDepth = $this->maxDepth = $comparator->getTarget();
100702 }
100703 }
100704 
100705 return $this;
100706 }
100707 
100708 
100709 
100710 
100711 public function setExclude(array $exclude)
100712 {
100713 $this->exclude = $exclude;
100714 
100715 return $this;
100716 }
100717 
100718 
100719 
100720 
100721 public function setNames(array $names)
100722 {
100723 $this->names = $names;
100724 
100725 return $this;
100726 }
100727 
100728 
100729 
100730 
100731 public function setNotNames(array $notNames)
100732 {
100733 $this->notNames = $notNames;
100734 
100735 return $this;
100736 }
100737 
100738 
100739 
100740 
100741 public function setContains(array $contains)
100742 {
100743 $this->contains = $contains;
100744 
100745 return $this;
100746 }
100747 
100748 
100749 
100750 
100751 public function setNotContains(array $notContains)
100752 {
100753 $this->notContains = $notContains;
100754 
100755 return $this;
100756 }
100757 
100758 
100759 
100760 
100761 public function setSizes(array $sizes)
100762 {
100763 $this->sizes = $sizes;
100764 
100765 return $this;
100766 }
100767 
100768 
100769 
100770 
100771 public function setDates(array $dates)
100772 {
100773 $this->dates = $dates;
100774 
100775 return $this;
100776 }
100777 
100778 
100779 
100780 
100781 public function setFilters(array $filters)
100782 {
100783 $this->filters = $filters;
100784 
100785 return $this;
100786 }
100787 
100788 
100789 
100790 
100791 public function setSort($sort)
100792 {
100793 $this->sort = $sort;
100794 
100795 return $this;
100796 }
100797 
100798 
100799 
100800 
100801 public function setPath(array $paths)
100802 {
100803 $this->paths = $paths;
100804 
100805 return $this;
100806 }
100807 
100808 
100809 
100810 
100811 public function setNotPath(array $notPaths)
100812 {
100813 $this->notPaths = $notPaths;
100814 
100815 return $this;
100816 }
100817 
100818 
100819 
100820 
100821 public function ignoreUnreadableDirs($ignore = true)
100822 {
100823 $this->ignoreUnreadableDirs = (bool) $ignore;
100824 
100825 return $this;
100826 }
100827 
100828 
100829 
100830 
100831 
100832 
100833 
100834 
100835 
100836 
100837 
100838 
100839 abstract protected function canBeUsed();
100840 }
100841 <?php
100842 
100843 
100844 
100845 
100846 
100847 
100848 
100849 
100850 
100851 
100852 namespace Symfony\Component\Finder\Adapter;
100853 
100854 @trigger_error('The '.__NAMESPACE__.'\AbstractFindAdapter class is deprecated since Symfony 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
100855 
100856 use Symfony\Component\Finder\Comparator\DateComparator;
100857 use Symfony\Component\Finder\Comparator\NumberComparator;
100858 use Symfony\Component\Finder\Exception\AccessDeniedException;
100859 use Symfony\Component\Finder\Expression\Expression;
100860 use Symfony\Component\Finder\Iterator;
100861 use Symfony\Component\Finder\Shell\Command;
100862 use Symfony\Component\Finder\Shell\Shell;
100863 
100864 
100865 
100866 
100867 
100868 
100869 
100870 
100871 abstract class AbstractFindAdapter extends AbstractAdapter
100872 {
100873 protected $shell;
100874 
100875 public function __construct()
100876 {
100877 $this->shell = new Shell();
100878 }
100879 
100880 
100881 
100882 
100883 public function searchInDirectory($dir)
100884 {
100885 
100886 $dir = realpath($dir);
100887 
100888 
100889 if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
100890 return new Iterator\FilePathsIterator(array(), $dir);
100891 }
100892 
100893 $command = Command::create();
100894 $find = $this->buildFindCommand($command, $dir);
100895 
100896 if ($this->followLinks) {
100897 $find->add('-follow');
100898 }
100899 
100900 $find->add('-mindepth')->add($this->minDepth + 1);
100901 
100902 if (PHP_INT_MAX !== $this->maxDepth) {
100903 $find->add('-maxdepth')->add($this->maxDepth + 1);
100904 }
100905 
100906 if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
100907 $find->add('-type d');
100908 } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
100909 $find->add('-type f');
100910 }
100911 
100912 $this->buildNamesFiltering($find, $this->names);
100913 $this->buildNamesFiltering($find, $this->notNames, true);
100914 $this->buildPathsFiltering($find, $dir, $this->paths);
100915 $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
100916 $this->buildSizesFiltering($find, $this->sizes);
100917 $this->buildDatesFiltering($find, $this->dates);
100918 
100919 $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
100920 $useSort = \is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
100921 
100922 if ($useGrep && ($this->contains || $this->notContains)) {
100923 $grep = $command->ins('grep');
100924 $this->buildContentFiltering($grep, $this->contains);
100925 $this->buildContentFiltering($grep, $this->notContains, true);
100926 }
100927 
100928 if ($useSort) {
100929 $this->buildSorting($command, $this->sort);
100930 }
100931 
100932 $command->setErrorHandler(
100933 $this->ignoreUnreadableDirs
100934 
100935 ? function ($stderr) { }
100936 : function ($stderr) { throw new AccessDeniedException($stderr); }
100937 );
100938 
100939 $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
100940 $iterator = new Iterator\FilePathsIterator($paths, $dir);
100941 
100942 if ($this->exclude) {
100943 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
100944 }
100945 
100946 if (!$useGrep && ($this->contains || $this->notContains)) {
100947 $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
100948 }
100949 
100950 if ($this->filters) {
100951 $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
100952 }
100953 
100954 if (!$useSort && $this->sort) {
100955 $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
100956 $iterator = $iteratorAggregate->getIterator();
100957 }
100958 
100959 return $iterator;
100960 }
100961 
100962 
100963 
100964 
100965 protected function canBeUsed()
100966 {
100967 return $this->shell->testCommand('find');
100968 }
100969 
100970 
100971 
100972 
100973 
100974 
100975 
100976 protected function buildFindCommand(Command $command, $dir)
100977 {
100978 return $command
100979 ->ins('find')
100980 ->add('find ')
100981 ->arg($dir)
100982 ->add('-noleaf'); 
100983 }
100984 
100985 
100986 
100987 
100988 
100989 
100990 private function buildNamesFiltering(Command $command, array $names, $not = false)
100991 {
100992 if (0 === \count($names)) {
100993 return;
100994 }
100995 
100996 $command->add($not ? '-not' : null)->cmd('(');
100997 
100998 foreach ($names as $i => $name) {
100999 $expr = Expression::create($name);
101000 
101001 
101002 if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
101003 $expr = Expression::create($expr->getGlob()->toRegex(false));
101004 }
101005 
101006 
101007 
101008 
101009 if ($expr->isRegex()) {
101010 $regex = $expr->getRegex();
101011 $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
101012 ->setStartFlag(false)
101013 ->setStartJoker(true)
101014 ->replaceJokers('[^/]');
101015 if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
101016 $regex->setEndJoker(false)->append('[^/]*');
101017 }
101018 }
101019 
101020 $command
101021 ->add($i > 0 ? '-or' : null)
101022 ->add($expr->isRegex()
101023 ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
101024 : ($expr->isCaseSensitive() ? '-name' : '-iname')
101025 )
101026 ->arg($expr->renderPattern());
101027 }
101028 
101029 $command->cmd(')');
101030 }
101031 
101032 
101033 
101034 
101035 
101036 
101037 
101038 private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
101039 {
101040 if (0 === \count($paths)) {
101041 return;
101042 }
101043 
101044 $command->add($not ? '-not' : null)->cmd('(');
101045 
101046 foreach ($paths as $i => $path) {
101047 $expr = Expression::create($path);
101048 
101049 
101050 if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
101051 $expr = Expression::create($expr->getGlob()->toRegex(false));
101052 }
101053 
101054 
101055 if ($expr->isRegex()) {
101056 $regex = $expr->getRegex();
101057 $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).\DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
101058 } else {
101059 $expr->prepend('*')->append('*');
101060 }
101061 
101062 $command
101063 ->add($i > 0 ? '-or' : null)
101064 ->add($expr->isRegex()
101065 ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
101066 : ($expr->isCaseSensitive() ? '-path' : '-ipath')
101067 )
101068 ->arg($expr->renderPattern());
101069 }
101070 
101071 $command->cmd(')');
101072 }
101073 
101074 
101075 
101076 
101077 
101078 private function buildSizesFiltering(Command $command, array $sizes)
101079 {
101080 foreach ($sizes as $i => $size) {
101081 $command->add($i > 0 ? '-and' : null);
101082 
101083 switch ($size->getOperator()) {
101084 case '<=':
101085 $command->add('-size -'.($size->getTarget() + 1).'c');
101086 break;
101087 case '>=':
101088 $command->add('-size +'.($size->getTarget() - 1).'c');
101089 break;
101090 case '>':
101091 $command->add('-size +'.$size->getTarget().'c');
101092 break;
101093 case '!=':
101094 $command->add('-size -'.$size->getTarget().'c');
101095 $command->add('-size +'.$size->getTarget().'c');
101096 break;
101097 case '<':
101098 default:
101099 $command->add('-size -'.$size->getTarget().'c');
101100 }
101101 }
101102 }
101103 
101104 
101105 
101106 
101107 
101108 private function buildDatesFiltering(Command $command, array $dates)
101109 {
101110 foreach ($dates as $i => $date) {
101111 $command->add($i > 0 ? '-and' : null);
101112 
101113 $mins = (int) round((time() - $date->getTarget()) / 60);
101114 
101115 if (0 > $mins) {
101116 
101117 $command->add(' -mmin -0');
101118 
101119 return;
101120 }
101121 
101122 switch ($date->getOperator()) {
101123 case '<=':
101124 $command->add('-mmin +'.($mins - 1));
101125 break;
101126 case '>=':
101127 $command->add('-mmin -'.($mins + 1));
101128 break;
101129 case '>':
101130 $command->add('-mmin -'.$mins);
101131 break;
101132 case '!=':
101133 $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
101134 break;
101135 case '<':
101136 default:
101137 $command->add('-mmin +'.$mins);
101138 }
101139 }
101140 }
101141 
101142 
101143 
101144 
101145 
101146 
101147 
101148 private function buildSorting(Command $command, $sort)
101149 {
101150 $this->buildFormatSorting($command, $sort);
101151 }
101152 
101153 
101154 
101155 
101156 
101157 abstract protected function buildFormatSorting(Command $command, $sort);
101158 
101159 
101160 
101161 
101162 
101163 
101164 abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
101165 }
101166 <?php
101167 
101168 
101169 
101170 
101171 
101172 
101173 
101174 
101175 
101176 
101177 namespace Symfony\Component\Finder\Adapter;
101178 
101179 
101180 
101181 
101182 
101183 
101184 interface AdapterInterface
101185 {
101186 
101187 
101188 
101189 
101190 
101191 public function setFollowLinks($followLinks);
101192 
101193 
101194 
101195 
101196 
101197 
101198 public function setMode($mode);
101199 
101200 
101201 
101202 
101203 public function setExclude(array $exclude);
101204 
101205 
101206 
101207 
101208 public function setDepths(array $depths);
101209 
101210 
101211 
101212 
101213 public function setNames(array $names);
101214 
101215 
101216 
101217 
101218 public function setNotNames(array $notNames);
101219 
101220 
101221 
101222 
101223 public function setContains(array $contains);
101224 
101225 
101226 
101227 
101228 public function setNotContains(array $notContains);
101229 
101230 
101231 
101232 
101233 public function setSizes(array $sizes);
101234 
101235 
101236 
101237 
101238 public function setDates(array $dates);
101239 
101240 
101241 
101242 
101243 public function setFilters(array $filters);
101244 
101245 
101246 
101247 
101248 
101249 
101250 public function setSort($sort);
101251 
101252 
101253 
101254 
101255 public function setPath(array $paths);
101256 
101257 
101258 
101259 
101260 public function setNotPath(array $notPaths);
101261 
101262 
101263 
101264 
101265 
101266 
101267 public function ignoreUnreadableDirs($ignore = true);
101268 
101269 
101270 
101271 
101272 
101273 
101274 public function searchInDirectory($dir);
101275 
101276 
101277 
101278 
101279 
101280 
101281 public function isSupported();
101282 
101283 
101284 
101285 
101286 
101287 
101288 public function getName();
101289 }
101290 <?php
101291 
101292 
101293 
101294 
101295 
101296 
101297 
101298 
101299 
101300 
101301 namespace Symfony\Component\Finder\Adapter;
101302 
101303 @trigger_error('The '.__NAMESPACE__.'\BsdFindAdapter class is deprecated since Symfony 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
101304 
101305 use Symfony\Component\Finder\Expression\Expression;
101306 use Symfony\Component\Finder\Iterator\SortableIterator;
101307 use Symfony\Component\Finder\Shell\Command;
101308 use Symfony\Component\Finder\Shell\Shell;
101309 
101310 
101311 
101312 
101313 
101314 
101315 
101316 
101317 class BsdFindAdapter extends AbstractFindAdapter
101318 {
101319 
101320 
101321 
101322 public function getName()
101323 {
101324 return 'bsd_find';
101325 }
101326 
101327 
101328 
101329 
101330 protected function canBeUsed()
101331 {
101332 return \in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
101333 }
101334 
101335 
101336 
101337 
101338 protected function buildFormatSorting(Command $command, $sort)
101339 {
101340 switch ($sort) {
101341 case SortableIterator::SORT_BY_NAME:
101342 $command->ins('sort')->add('| sort');
101343 
101344 return;
101345 case SortableIterator::SORT_BY_TYPE:
101346 $format = '%HT';
101347 break;
101348 case SortableIterator::SORT_BY_ACCESSED_TIME:
101349 $format = '%a';
101350 break;
101351 case SortableIterator::SORT_BY_CHANGED_TIME:
101352 $format = '%c';
101353 break;
101354 case SortableIterator::SORT_BY_MODIFIED_TIME:
101355 $format = '%m';
101356 break;
101357 default:
101358 throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
101359 }
101360 
101361 $command
101362 ->add('-print0 | xargs -0 stat -f')
101363 ->arg($format.'%t%N')
101364 ->add('| sort | cut -f 2');
101365 }
101366 
101367 
101368 
101369 
101370 protected function buildFindCommand(Command $command, $dir)
101371 {
101372 parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);
101373 
101374 return $command;
101375 }
101376 
101377 
101378 
101379 
101380 protected function buildContentFiltering(Command $command, array $contains, $not = false)
101381 {
101382 foreach ($contains as $contain) {
101383 $expr = Expression::create($contain);
101384 
101385 
101386 $command
101387 ->add('| grep -v \'^$\'')
101388 ->add('| xargs -I{} grep -I')
101389 ->add($expr->isCaseSensitive() ? null : '-i')
101390 ->add($not ? '-L' : '-l')
101391 ->add('-Ee')->arg($expr->renderPattern())
101392 ->add('{}')
101393 ;
101394 }
101395 }
101396 }
101397 <?php
101398 
101399 
101400 
101401 
101402 
101403 
101404 
101405 
101406 
101407 
101408 namespace Symfony\Component\Finder\Adapter;
101409 
101410 @trigger_error('The '.__NAMESPACE__.'\GnuFindAdapter class is deprecated since Symfony 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
101411 
101412 use Symfony\Component\Finder\Expression\Expression;
101413 use Symfony\Component\Finder\Iterator\SortableIterator;
101414 use Symfony\Component\Finder\Shell\Command;
101415 use Symfony\Component\Finder\Shell\Shell;
101416 
101417 
101418 
101419 
101420 
101421 
101422 
101423 
101424 class GnuFindAdapter extends AbstractFindAdapter
101425 {
101426 
101427 
101428 
101429 public function getName()
101430 {
101431 return 'gnu_find';
101432 }
101433 
101434 
101435 
101436 
101437 protected function buildFormatSorting(Command $command, $sort)
101438 {
101439 switch ($sort) {
101440 case SortableIterator::SORT_BY_NAME:
101441 $command->ins('sort')->add('| sort');
101442 
101443 return;
101444 case SortableIterator::SORT_BY_TYPE:
101445 $format = '%y';
101446 break;
101447 case SortableIterator::SORT_BY_ACCESSED_TIME:
101448 $format = '%A@';
101449 break;
101450 case SortableIterator::SORT_BY_CHANGED_TIME:
101451 $format = '%C@';
101452 break;
101453 case SortableIterator::SORT_BY_MODIFIED_TIME:
101454 $format = '%T@';
101455 break;
101456 default:
101457 throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
101458 }
101459 
101460 $command
101461 ->get('find')
101462 ->add('-printf')
101463 ->arg($format.' %h/%f\\n')
101464 ->add('| sort | cut')
101465 ->arg('-d ')
101466 ->arg('-f2-')
101467 ;
101468 }
101469 
101470 
101471 
101472 
101473 protected function canBeUsed()
101474 {
101475 return Shell::TYPE_UNIX === $this->shell->getType() && parent::canBeUsed();
101476 }
101477 
101478 
101479 
101480 
101481 protected function buildFindCommand(Command $command, $dir)
101482 {
101483 return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
101484 }
101485 
101486 
101487 
101488 
101489 protected function buildContentFiltering(Command $command, array $contains, $not = false)
101490 {
101491 foreach ($contains as $contain) {
101492 $expr = Expression::create($contain);
101493 
101494 
101495 $command
101496 ->add('| xargs -I{} -r grep -I')
101497 ->add($expr->isCaseSensitive() ? null : '-i')
101498 ->add($not ? '-L' : '-l')
101499 ->add('-Ee')->arg($expr->renderPattern())
101500 ->add('{}')
101501 ;
101502 }
101503 }
101504 }
101505 <?php
101506 
101507 
101508 
101509 
101510 
101511 
101512 
101513 
101514 
101515 
101516 namespace Symfony\Component\Finder\Adapter;
101517 
101518 @trigger_error('The '.__NAMESPACE__.'\PhpAdapter class is deprecated since Symfony 2.8 and will be removed in 3.0. Use directly the Finder class instead.', E_USER_DEPRECATED);
101519 
101520 use Symfony\Component\Finder\Iterator;
101521 
101522 
101523 
101524 
101525 
101526 
101527 
101528 
101529 class PhpAdapter extends AbstractAdapter
101530 {
101531 
101532 
101533 
101534 public function searchInDirectory($dir)
101535 {
101536 $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
101537 
101538 if ($this->followLinks) {
101539 $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
101540 }
101541 
101542 $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
101543 
101544 if ($this->exclude) {
101545 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
101546 }
101547 
101548 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
101549 
101550 if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
101551 $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
101552 }
101553 
101554 if ($this->mode) {
101555 $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
101556 }
101557 
101558 if ($this->names || $this->notNames) {
101559 $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
101560 }
101561 
101562 if ($this->contains || $this->notContains) {
101563 $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
101564 }
101565 
101566 if ($this->sizes) {
101567 $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
101568 }
101569 
101570 if ($this->dates) {
101571 $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
101572 }
101573 
101574 if ($this->filters) {
101575 $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
101576 }
101577 
101578 if ($this->paths || $this->notPaths) {
101579 $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
101580 }
101581 
101582 if ($this->sort) {
101583 $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
101584 $iterator = $iteratorAggregate->getIterator();
101585 }
101586 
101587 return $iterator;
101588 }
101589 
101590 
101591 
101592 
101593 public function getName()
101594 {
101595 return 'php';
101596 }
101597 
101598 
101599 
101600 
101601 protected function canBeUsed()
101602 {
101603 return true;
101604 }
101605 }
101606 <?php
101607 
101608 
101609 
101610 
101611 
101612 
101613 
101614 
101615 
101616 
101617 namespace Symfony\Component\Finder\Comparator;
101618 
101619 
101620 
101621 
101622 
101623 
101624 class Comparator
101625 {
101626 private $target;
101627 private $operator = '==';
101628 
101629 
101630 
101631 
101632 
101633 
101634 public function getTarget()
101635 {
101636 return $this->target;
101637 }
101638 
101639 
101640 
101641 
101642 
101643 
101644 public function setTarget($target)
101645 {
101646 $this->target = $target;
101647 }
101648 
101649 
101650 
101651 
101652 
101653 
101654 public function getOperator()
101655 {
101656 return $this->operator;
101657 }
101658 
101659 
101660 
101661 
101662 
101663 
101664 
101665 
101666 public function setOperator($operator)
101667 {
101668 if (!$operator) {
101669 $operator = '==';
101670 }
101671 
101672 if (!\in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) {
101673 throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
101674 }
101675 
101676 $this->operator = $operator;
101677 }
101678 
101679 
101680 
101681 
101682 
101683 
101684 
101685 
101686 public function test($test)
101687 {
101688 switch ($this->operator) {
101689 case '>':
101690 return $test > $this->target;
101691 case '>=':
101692 return $test >= $this->target;
101693 case '<':
101694 return $test < $this->target;
101695 case '<=':
101696 return $test <= $this->target;
101697 case '!=':
101698 return $test != $this->target;
101699 }
101700 
101701 return $test == $this->target;
101702 }
101703 }
101704 <?php
101705 
101706 
101707 
101708 
101709 
101710 
101711 
101712 
101713 
101714 
101715 namespace Symfony\Component\Finder\Comparator;
101716 
101717 
101718 
101719 
101720 
101721 
101722 class DateComparator extends Comparator
101723 {
101724 
101725 
101726 
101727 
101728 
101729 public function __construct($test)
101730 {
101731 if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
101732 throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
101733 }
101734 
101735 try {
101736 $date = new \DateTime($matches[2]);
101737 $target = $date->format('U');
101738 } catch (\Exception $e) {
101739 throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
101740 }
101741 
101742 $operator = isset($matches[1]) ? $matches[1] : '==';
101743 if ('since' === $operator || 'after' === $operator) {
101744 $operator = '>';
101745 }
101746 
101747 if ('until' === $operator || 'before' === $operator) {
101748 $operator = '<';
101749 }
101750 
101751 $this->setOperator($operator);
101752 $this->setTarget($target);
101753 }
101754 }
101755 <?php
101756 
101757 
101758 
101759 
101760 
101761 
101762 
101763 
101764 
101765 
101766 namespace Symfony\Component\Finder\Comparator;
101767 
101768 
101769 
101770 
101771 
101772 
101773 
101774 
101775 
101776 
101777 
101778 
101779 
101780 
101781 
101782 
101783 
101784 
101785 
101786 
101787 
101788 
101789 class NumberComparator extends Comparator
101790 {
101791 
101792 
101793 
101794 
101795 
101796 public function __construct($test)
101797 {
101798 if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
101799 throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test));
101800 }
101801 
101802 $target = $matches[2];
101803 if (!is_numeric($target)) {
101804 throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
101805 }
101806 if (isset($matches[3])) {
101807 
101808 switch (strtolower($matches[3])) {
101809 case 'k':
101810 $target *= 1000;
101811 break;
101812 case 'ki':
101813 $target *= 1024;
101814 break;
101815 case 'm':
101816 $target *= 1000000;
101817 break;
101818 case 'mi':
101819 $target *= 1024 * 1024;
101820 break;
101821 case 'g':
101822 $target *= 1000000000;
101823 break;
101824 case 'gi':
101825 $target *= 1024 * 1024 * 1024;
101826 break;
101827 }
101828 }
101829 
101830 $this->setTarget($target);
101831 $this->setOperator(isset($matches[1]) ? $matches[1] : '==');
101832 }
101833 }
101834 <?php
101835 
101836 
101837 
101838 
101839 
101840 
101841 
101842 
101843 
101844 
101845 namespace Symfony\Component\Finder\Exception;
101846 
101847 
101848 
101849 
101850 class AccessDeniedException extends \UnexpectedValueException
101851 {
101852 }
101853 <?php
101854 
101855 
101856 
101857 
101858 
101859 
101860 
101861 
101862 
101863 
101864 namespace Symfony\Component\Finder\Exception;
101865 
101866 @trigger_error('The '.__NAMESPACE__.'\AdapterFailureException class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
101867 
101868 use Symfony\Component\Finder\Adapter\AdapterInterface;
101869 
101870 
101871 
101872 
101873 
101874 
101875 
101876 
101877 class AdapterFailureException extends \RuntimeException implements ExceptionInterface
101878 {
101879 private $adapter;
101880 
101881 
101882 
101883 
101884 
101885 
101886 public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
101887 {
101888 $this->adapter = $adapter;
101889 parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
101890 }
101891 
101892 
101893 
101894 
101895 public function getAdapter()
101896 {
101897 return $this->adapter;
101898 }
101899 }
101900 <?php
101901 
101902 
101903 
101904 
101905 
101906 
101907 
101908 
101909 
101910 
101911 namespace Symfony\Component\Finder\Exception;
101912 
101913 
101914 
101915 
101916 interface ExceptionInterface
101917 {
101918 
101919 
101920 
101921 public function getAdapter();
101922 }
101923 <?php
101924 
101925 
101926 
101927 
101928 
101929 
101930 
101931 
101932 
101933 
101934 namespace Symfony\Component\Finder\Exception;
101935 
101936 @trigger_error('The '.__NAMESPACE__.'\OperationNotPermitedException class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
101937 
101938 
101939 
101940 
101941 
101942 
101943 class OperationNotPermitedException extends AdapterFailureException
101944 {
101945 }
101946 <?php
101947 
101948 
101949 
101950 
101951 
101952 
101953 
101954 
101955 
101956 
101957 namespace Symfony\Component\Finder\Exception;
101958 
101959 @trigger_error('The '.__NAMESPACE__.'\ShellCommandFailureException class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
101960 
101961 use Symfony\Component\Finder\Adapter\AdapterInterface;
101962 use Symfony\Component\Finder\Shell\Command;
101963 
101964 
101965 
101966 
101967 
101968 
101969 class ShellCommandFailureException extends AdapterFailureException
101970 {
101971 private $command;
101972 
101973 public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
101974 {
101975 $this->command = $command;
101976 parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
101977 }
101978 
101979 
101980 
101981 
101982 public function getCommand()
101983 {
101984 return $this->command;
101985 }
101986 }
101987 <?php
101988 
101989 
101990 
101991 
101992 
101993 
101994 
101995 
101996 
101997 
101998 namespace Symfony\Component\Finder\Expression;
101999 
102000 @trigger_error('The '.__NAMESPACE__.'\Expression class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102001 
102002 
102003 
102004 
102005 class Expression implements ValueInterface
102006 {
102007 const TYPE_REGEX = 1;
102008 const TYPE_GLOB = 2;
102009 
102010 
102011 
102012 
102013 private $value;
102014 
102015 
102016 
102017 
102018 
102019 
102020 public static function create($expr)
102021 {
102022 return new self($expr);
102023 }
102024 
102025 
102026 
102027 
102028 public function __construct($expr)
102029 {
102030 try {
102031 $this->value = Regex::create($expr);
102032 } catch (\InvalidArgumentException $e) {
102033 $this->value = new Glob($expr);
102034 }
102035 }
102036 
102037 
102038 
102039 
102040 public function __toString()
102041 {
102042 return $this->render();
102043 }
102044 
102045 
102046 
102047 
102048 public function render()
102049 {
102050 return $this->value->render();
102051 }
102052 
102053 
102054 
102055 
102056 public function renderPattern()
102057 {
102058 return $this->value->renderPattern();
102059 }
102060 
102061 
102062 
102063 
102064 public function isCaseSensitive()
102065 {
102066 return $this->value->isCaseSensitive();
102067 }
102068 
102069 
102070 
102071 
102072 public function getType()
102073 {
102074 return $this->value->getType();
102075 }
102076 
102077 
102078 
102079 
102080 public function prepend($expr)
102081 {
102082 $this->value->prepend($expr);
102083 
102084 return $this;
102085 }
102086 
102087 
102088 
102089 
102090 public function append($expr)
102091 {
102092 $this->value->append($expr);
102093 
102094 return $this;
102095 }
102096 
102097 
102098 
102099 
102100 public function isRegex()
102101 {
102102 return self::TYPE_REGEX === $this->value->getType();
102103 }
102104 
102105 
102106 
102107 
102108 public function isGlob()
102109 {
102110 return self::TYPE_GLOB === $this->value->getType();
102111 }
102112 
102113 
102114 
102115 
102116 
102117 
102118 public function getGlob()
102119 {
102120 if (self::TYPE_GLOB !== $this->value->getType()) {
102121 throw new \LogicException('Regex can\'t be transformed to glob.');
102122 }
102123 
102124 return $this->value;
102125 }
102126 
102127 
102128 
102129 
102130 public function getRegex()
102131 {
102132 return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
102133 }
102134 }
102135 <?php
102136 
102137 
102138 
102139 
102140 
102141 
102142 
102143 
102144 
102145 
102146 namespace Symfony\Component\Finder\Expression;
102147 
102148 @trigger_error('The '.__NAMESPACE__.'\Glob class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102149 
102150 use Symfony\Component\Finder\Glob as FinderGlob;
102151 
102152 
102153 
102154 
102155 class Glob implements ValueInterface
102156 {
102157 private $pattern;
102158 
102159 
102160 
102161 
102162 public function __construct($pattern)
102163 {
102164 $this->pattern = $pattern;
102165 }
102166 
102167 
102168 
102169 
102170 public function render()
102171 {
102172 return $this->pattern;
102173 }
102174 
102175 
102176 
102177 
102178 public function renderPattern()
102179 {
102180 return $this->pattern;
102181 }
102182 
102183 
102184 
102185 
102186 public function getType()
102187 {
102188 return Expression::TYPE_GLOB;
102189 }
102190 
102191 
102192 
102193 
102194 public function isCaseSensitive()
102195 {
102196 return true;
102197 }
102198 
102199 
102200 
102201 
102202 public function prepend($expr)
102203 {
102204 $this->pattern = $expr.$this->pattern;
102205 
102206 return $this;
102207 }
102208 
102209 
102210 
102211 
102212 public function append($expr)
102213 {
102214 $this->pattern .= $expr;
102215 
102216 return $this;
102217 }
102218 
102219 
102220 
102221 
102222 
102223 
102224 public function isExpandable()
102225 {
102226 return false !== strpos($this->pattern, '{')
102227 && false !== strpos($this->pattern, '}');
102228 }
102229 
102230 
102231 
102232 
102233 
102234 
102235 
102236 public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
102237 {
102238 $regex = FinderGlob::toRegex($this->pattern, $strictLeadingDot, $strictWildcardSlash, '');
102239 
102240 return new Regex($regex);
102241 }
102242 }
102243 <?php
102244 
102245 
102246 
102247 
102248 
102249 
102250 
102251 
102252 
102253 
102254 namespace Symfony\Component\Finder\Expression;
102255 
102256 @trigger_error('The '.__NAMESPACE__.'\Regex class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102257 
102258 
102259 
102260 
102261 class Regex implements ValueInterface
102262 {
102263 const START_FLAG = '^';
102264 const END_FLAG = '$';
102265 const BOUNDARY = '~';
102266 const JOKER = '.*';
102267 const ESCAPING = '\\';
102268 
102269 
102270 
102271 
102272 private $pattern;
102273 
102274 
102275 
102276 
102277 private $options;
102278 
102279 
102280 
102281 
102282 private $startFlag;
102283 
102284 
102285 
102286 
102287 private $endFlag;
102288 
102289 
102290 
102291 
102292 private $startJoker;
102293 
102294 
102295 
102296 
102297 private $endJoker;
102298 
102299 
102300 
102301 
102302 
102303 
102304 
102305 
102306 public static function create($expr)
102307 {
102308 if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
102309 $start = substr($m[1], 0, 1);
102310 $end = substr($m[1], -1);
102311 
102312 if (
102313 ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
102314 || ('{' === $start && '}' === $end)
102315 || ('(' === $start && ')' === $end)
102316 ) {
102317 return new self(substr($m[1], 1, -1), $m[2], $end);
102318 }
102319 }
102320 
102321 throw new \InvalidArgumentException('Given expression is not a regex.');
102322 }
102323 
102324 
102325 
102326 
102327 
102328 
102329 public function __construct($pattern, $options = '', $delimiter = null)
102330 {
102331 if (null !== $delimiter) {
102332 
102333 $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
102334 }
102335 
102336 $this->parsePattern($pattern);
102337 $this->options = $options;
102338 }
102339 
102340 
102341 
102342 
102343 public function __toString()
102344 {
102345 return $this->render();
102346 }
102347 
102348 
102349 
102350 
102351 public function render()
102352 {
102353 return self::BOUNDARY
102354 .$this->renderPattern()
102355 .self::BOUNDARY
102356 .$this->options;
102357 }
102358 
102359 
102360 
102361 
102362 public function renderPattern()
102363 {
102364 return ($this->startFlag ? self::START_FLAG : '')
102365 .($this->startJoker ? self::JOKER : '')
102366 .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
102367 .($this->endJoker ? self::JOKER : '')
102368 .($this->endFlag ? self::END_FLAG : '');
102369 }
102370 
102371 
102372 
102373 
102374 public function isCaseSensitive()
102375 {
102376 return !$this->hasOption('i');
102377 }
102378 
102379 
102380 
102381 
102382 public function getType()
102383 {
102384 return Expression::TYPE_REGEX;
102385 }
102386 
102387 
102388 
102389 
102390 public function prepend($expr)
102391 {
102392 $this->pattern = $expr.$this->pattern;
102393 
102394 return $this;
102395 }
102396 
102397 
102398 
102399 
102400 public function append($expr)
102401 {
102402 $this->pattern .= $expr;
102403 
102404 return $this;
102405 }
102406 
102407 
102408 
102409 
102410 
102411 
102412 public function hasOption($option)
102413 {
102414 return false !== strpos($this->options, $option);
102415 }
102416 
102417 
102418 
102419 
102420 
102421 
102422 public function addOption($option)
102423 {
102424 if (!$this->hasOption($option)) {
102425 $this->options .= $option;
102426 }
102427 
102428 return $this;
102429 }
102430 
102431 
102432 
102433 
102434 
102435 
102436 public function removeOption($option)
102437 {
102438 $this->options = str_replace($option, '', $this->options);
102439 
102440 return $this;
102441 }
102442 
102443 
102444 
102445 
102446 
102447 
102448 public function setStartFlag($startFlag)
102449 {
102450 $this->startFlag = $startFlag;
102451 
102452 return $this;
102453 }
102454 
102455 
102456 
102457 
102458 public function hasStartFlag()
102459 {
102460 return $this->startFlag;
102461 }
102462 
102463 
102464 
102465 
102466 
102467 
102468 public function setEndFlag($endFlag)
102469 {
102470 $this->endFlag = (bool) $endFlag;
102471 
102472 return $this;
102473 }
102474 
102475 
102476 
102477 
102478 public function hasEndFlag()
102479 {
102480 return $this->endFlag;
102481 }
102482 
102483 
102484 
102485 
102486 
102487 
102488 public function setStartJoker($startJoker)
102489 {
102490 $this->startJoker = $startJoker;
102491 
102492 return $this;
102493 }
102494 
102495 
102496 
102497 
102498 public function hasStartJoker()
102499 {
102500 return $this->startJoker;
102501 }
102502 
102503 
102504 
102505 
102506 
102507 
102508 public function setEndJoker($endJoker)
102509 {
102510 $this->endJoker = (bool) $endJoker;
102511 
102512 return $this;
102513 }
102514 
102515 
102516 
102517 
102518 public function hasEndJoker()
102519 {
102520 return $this->endJoker;
102521 }
102522 
102523 
102524 
102525 
102526 public function replaceJokers($replacement)
102527 {
102528 $replace = function ($subject) use ($replacement) {
102529 $subject = $subject[0];
102530 $replace = 0 === substr_count($subject, '\\') % 2;
102531 
102532 return $replace ? str_replace('.', $replacement, $subject) : $subject;
102533 };
102534 
102535 $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
102536 
102537 return $this;
102538 }
102539 
102540 
102541 
102542 
102543 private function parsePattern($pattern)
102544 {
102545 if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
102546 $pattern = substr($pattern, 1);
102547 }
102548 
102549 if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
102550 $pattern = substr($pattern, 2);
102551 }
102552 
102553 if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
102554 $pattern = substr($pattern, 0, -1);
102555 }
102556 
102557 if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
102558 $pattern = substr($pattern, 0, -2);
102559 }
102560 
102561 $this->pattern = $pattern;
102562 }
102563 }
102564 <?php
102565 
102566 
102567 
102568 
102569 
102570 
102571 
102572 
102573 
102574 
102575 namespace Symfony\Component\Finder\Expression;
102576 
102577 @trigger_error('The '.__NAMESPACE__.'\ValueInterface interface is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102578 
102579 
102580 
102581 
102582 interface ValueInterface
102583 {
102584 
102585 
102586 
102587 
102588 
102589 public function render();
102590 
102591 
102592 
102593 
102594 
102595 
102596 public function renderPattern();
102597 
102598 
102599 
102600 
102601 
102602 
102603 public function isCaseSensitive();
102604 
102605 
102606 
102607 
102608 
102609 
102610 public function getType();
102611 
102612 
102613 
102614 
102615 
102616 
102617 public function prepend($expr);
102618 
102619 
102620 
102621 
102622 
102623 
102624 public function append($expr);
102625 }
102626 <?php
102627 
102628 
102629 
102630 
102631 
102632 
102633 
102634 
102635 
102636 
102637 namespace Symfony\Component\Finder;
102638 
102639 use Symfony\Component\Finder\Adapter\AdapterInterface;
102640 use Symfony\Component\Finder\Adapter\BsdFindAdapter;
102641 use Symfony\Component\Finder\Adapter\GnuFindAdapter;
102642 use Symfony\Component\Finder\Adapter\PhpAdapter;
102643 use Symfony\Component\Finder\Comparator\DateComparator;
102644 use Symfony\Component\Finder\Comparator\NumberComparator;
102645 use Symfony\Component\Finder\Exception\ExceptionInterface;
102646 use Symfony\Component\Finder\Iterator\CustomFilterIterator;
102647 use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
102648 use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
102649 use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
102650 use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
102651 use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
102652 use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
102653 use Symfony\Component\Finder\Iterator\SortableIterator;
102654 
102655 
102656 
102657 
102658 
102659 
102660 
102661 
102662 
102663 
102664 
102665 
102666 
102667 
102668 class Finder implements \IteratorAggregate, \Countable
102669 {
102670 const IGNORE_VCS_FILES = 1;
102671 const IGNORE_DOT_FILES = 2;
102672 
102673 private $mode = 0;
102674 private $names = array();
102675 private $notNames = array();
102676 private $exclude = array();
102677 private $filters = array();
102678 private $depths = array();
102679 private $sizes = array();
102680 private $followLinks = false;
102681 private $sort = false;
102682 private $ignore = 0;
102683 private $dirs = array();
102684 private $dates = array();
102685 private $iterators = array();
102686 private $contains = array();
102687 private $notContains = array();
102688 private $adapters = null;
102689 private $paths = array();
102690 private $notPaths = array();
102691 private $ignoreUnreadableDirs = false;
102692 
102693 private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
102694 
102695 public function __construct()
102696 {
102697 $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
102698 }
102699 
102700 
102701 
102702 
102703 
102704 
102705 public static function create()
102706 {
102707 return new static();
102708 }
102709 
102710 
102711 
102712 
102713 
102714 
102715 
102716 
102717 
102718 
102719 
102720 public function addAdapter(AdapterInterface $adapter, $priority = 0)
102721 {
102722 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102723 
102724 $this->initDefaultAdapters();
102725 
102726 $this->adapters[$adapter->getName()] = array(
102727 'adapter' => $adapter,
102728 'priority' => $priority,
102729 'selected' => false,
102730 );
102731 
102732 return $this->sortAdapters();
102733 }
102734 
102735 
102736 
102737 
102738 
102739 
102740 
102741 
102742 public function useBestAdapter()
102743 {
102744 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102745 
102746 $this->initDefaultAdapters();
102747 
102748 $this->resetAdapterSelection();
102749 
102750 return $this->sortAdapters();
102751 }
102752 
102753 
102754 
102755 
102756 
102757 
102758 
102759 
102760 
102761 
102762 
102763 
102764 public function setAdapter($name)
102765 {
102766 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102767 
102768 $this->initDefaultAdapters();
102769 
102770 if (!isset($this->adapters[$name])) {
102771 throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
102772 }
102773 
102774 $this->resetAdapterSelection();
102775 $this->adapters[$name]['selected'] = true;
102776 
102777 return $this->sortAdapters();
102778 }
102779 
102780 
102781 
102782 
102783 
102784 
102785 
102786 
102787 public function removeAdapters()
102788 {
102789 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102790 
102791 $this->adapters = array();
102792 
102793 return $this;
102794 }
102795 
102796 
102797 
102798 
102799 
102800 
102801 
102802 
102803 public function getAdapters()
102804 {
102805 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
102806 
102807 $this->initDefaultAdapters();
102808 
102809 return array_values(array_map(function (array $adapter) {
102810 return $adapter['adapter'];
102811 }, $this->adapters));
102812 }
102813 
102814 
102815 
102816 
102817 
102818 
102819 public function directories()
102820 {
102821 $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
102822 
102823 return $this;
102824 }
102825 
102826 
102827 
102828 
102829 
102830 
102831 public function files()
102832 {
102833 $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
102834 
102835 return $this;
102836 }
102837 
102838 
102839 
102840 
102841 
102842 
102843 
102844 
102845 
102846 
102847 
102848 
102849 
102850 
102851 
102852 
102853 public function depth($level)
102854 {
102855 $this->depths[] = new Comparator\NumberComparator($level);
102856 
102857 return $this;
102858 }
102859 
102860 
102861 
102862 
102863 
102864 
102865 
102866 
102867 
102868 
102869 
102870 
102871 
102872 
102873 
102874 
102875 
102876 
102877 
102878 public function date($date)
102879 {
102880 $this->dates[] = new Comparator\DateComparator($date);
102881 
102882 return $this;
102883 }
102884 
102885 
102886 
102887 
102888 
102889 
102890 
102891 
102892 
102893 
102894 
102895 
102896 
102897 
102898 
102899 
102900 public function name($pattern)
102901 {
102902 $this->names[] = $pattern;
102903 
102904 return $this;
102905 }
102906 
102907 
102908 
102909 
102910 
102911 
102912 
102913 
102914 
102915 
102916 public function notName($pattern)
102917 {
102918 $this->notNames[] = $pattern;
102919 
102920 return $this;
102921 }
102922 
102923 
102924 
102925 
102926 
102927 
102928 
102929 
102930 
102931 
102932 
102933 
102934 
102935 
102936 
102937 public function contains($pattern)
102938 {
102939 $this->contains[] = $pattern;
102940 
102941 return $this;
102942 }
102943 
102944 
102945 
102946 
102947 
102948 
102949 
102950 
102951 
102952 
102953 
102954 
102955 
102956 
102957 
102958 public function notContains($pattern)
102959 {
102960 $this->notContains[] = $pattern;
102961 
102962 return $this;
102963 }
102964 
102965 
102966 
102967 
102968 
102969 
102970 
102971 
102972 
102973 
102974 
102975 
102976 
102977 
102978 
102979 
102980 
102981 public function path($pattern)
102982 {
102983 $this->paths[] = $pattern;
102984 
102985 return $this;
102986 }
102987 
102988 
102989 
102990 
102991 
102992 
102993 
102994 
102995 
102996 
102997 
102998 
102999 
103000 
103001 
103002 
103003 
103004 public function notPath($pattern)
103005 {
103006 $this->notPaths[] = $pattern;
103007 
103008 return $this;
103009 }
103010 
103011 
103012 
103013 
103014 
103015 
103016 
103017 
103018 
103019 
103020 
103021 
103022 
103023 
103024 
103025 public function size($size)
103026 {
103027 $this->sizes[] = new Comparator\NumberComparator($size);
103028 
103029 return $this;
103030 }
103031 
103032 
103033 
103034 
103035 
103036 
103037 
103038 
103039 
103040 
103041 
103042 
103043 
103044 
103045 public function exclude($dirs)
103046 {
103047 $this->exclude = array_merge($this->exclude, (array) $dirs);
103048 
103049 return $this;
103050 }
103051 
103052 
103053 
103054 
103055 
103056 
103057 
103058 
103059 
103060 
103061 
103062 
103063 public function ignoreDotFiles($ignoreDotFiles)
103064 {
103065 if ($ignoreDotFiles) {
103066 $this->ignore |= static::IGNORE_DOT_FILES;
103067 } else {
103068 $this->ignore &= ~static::IGNORE_DOT_FILES;
103069 }
103070 
103071 return $this;
103072 }
103073 
103074 
103075 
103076 
103077 
103078 
103079 
103080 
103081 
103082 
103083 
103084 
103085 public function ignoreVCS($ignoreVCS)
103086 {
103087 if ($ignoreVCS) {
103088 $this->ignore |= static::IGNORE_VCS_FILES;
103089 } else {
103090 $this->ignore &= ~static::IGNORE_VCS_FILES;
103091 }
103092 
103093 return $this;
103094 }
103095 
103096 
103097 
103098 
103099 
103100 
103101 
103102 
103103 public static function addVCSPattern($pattern)
103104 {
103105 foreach ((array) $pattern as $p) {
103106 self::$vcsPatterns[] = $p;
103107 }
103108 
103109 self::$vcsPatterns = array_unique(self::$vcsPatterns);
103110 }
103111 
103112 
103113 
103114 
103115 
103116 
103117 
103118 
103119 
103120 
103121 
103122 
103123 public function sort(\Closure $closure)
103124 {
103125 $this->sort = $closure;
103126 
103127 return $this;
103128 }
103129 
103130 
103131 
103132 
103133 
103134 
103135 
103136 
103137 
103138 
103139 public function sortByName()
103140 {
103141 $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
103142 
103143 return $this;
103144 }
103145 
103146 
103147 
103148 
103149 
103150 
103151 
103152 
103153 
103154 
103155 public function sortByType()
103156 {
103157 $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
103158 
103159 return $this;
103160 }
103161 
103162 
103163 
103164 
103165 
103166 
103167 
103168 
103169 
103170 
103171 
103172 
103173 public function sortByAccessedTime()
103174 {
103175 $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
103176 
103177 return $this;
103178 }
103179 
103180 
103181 
103182 
103183 
103184 
103185 
103186 
103187 
103188 
103189 
103190 
103191 
103192 
103193 public function sortByChangedTime()
103194 {
103195 $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
103196 
103197 return $this;
103198 }
103199 
103200 
103201 
103202 
103203 
103204 
103205 
103206 
103207 
103208 
103209 
103210 
103211 public function sortByModifiedTime()
103212 {
103213 $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
103214 
103215 return $this;
103216 }
103217 
103218 
103219 
103220 
103221 
103222 
103223 
103224 
103225 
103226 
103227 
103228 public function filter(\Closure $closure)
103229 {
103230 $this->filters[] = $closure;
103231 
103232 return $this;
103233 }
103234 
103235 
103236 
103237 
103238 
103239 
103240 public function followLinks()
103241 {
103242 $this->followLinks = true;
103243 
103244 return $this;
103245 }
103246 
103247 
103248 
103249 
103250 
103251 
103252 
103253 
103254 
103255 
103256 public function ignoreUnreadableDirs($ignore = true)
103257 {
103258 $this->ignoreUnreadableDirs = (bool) $ignore;
103259 
103260 return $this;
103261 }
103262 
103263 
103264 
103265 
103266 
103267 
103268 
103269 
103270 
103271 
103272 public function in($dirs)
103273 {
103274 $resolvedDirs = array();
103275 
103276 foreach ((array) $dirs as $dir) {
103277 if (is_dir($dir)) {
103278 $resolvedDirs[] = $this->normalizeDir($dir);
103279 } elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) {
103280 $resolvedDirs = array_merge($resolvedDirs, array_map(array($this, 'normalizeDir'), $glob));
103281 } else {
103282 throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
103283 }
103284 }
103285 
103286 $this->dirs = array_merge($this->dirs, $resolvedDirs);
103287 
103288 return $this;
103289 }
103290 
103291 
103292 
103293 
103294 
103295 
103296 
103297 
103298 
103299 
103300 public function getIterator()
103301 {
103302 if (0 === \count($this->dirs) && 0 === \count($this->iterators)) {
103303 throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
103304 }
103305 
103306 if (1 === \count($this->dirs) && 0 === \count($this->iterators)) {
103307 return $this->searchInDirectory($this->dirs[0]);
103308 }
103309 
103310 $iterator = new \AppendIterator();
103311 foreach ($this->dirs as $dir) {
103312 $iterator->append($this->searchInDirectory($dir));
103313 }
103314 
103315 foreach ($this->iterators as $it) {
103316 $iterator->append($it);
103317 }
103318 
103319 return $iterator;
103320 }
103321 
103322 
103323 
103324 
103325 
103326 
103327 
103328 
103329 
103330 
103331 
103332 
103333 public function append($iterator)
103334 {
103335 if ($iterator instanceof \IteratorAggregate) {
103336 $this->iterators[] = $iterator->getIterator();
103337 } elseif ($iterator instanceof \Iterator) {
103338 $this->iterators[] = $iterator;
103339 } elseif ($iterator instanceof \Traversable || \is_array($iterator)) {
103340 $it = new \ArrayIterator();
103341 foreach ($iterator as $file) {
103342 $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
103343 }
103344 $this->iterators[] = $it;
103345 } else {
103346 throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
103347 }
103348 
103349 return $this;
103350 }
103351 
103352 
103353 
103354 
103355 
103356 
103357 public function count()
103358 {
103359 return iterator_count($this->getIterator());
103360 }
103361 
103362 
103363 
103364 
103365 private function sortAdapters()
103366 {
103367 uasort($this->adapters, function (array $a, array $b) {
103368 if ($a['selected'] || $b['selected']) {
103369 return $a['selected'] ? -1 : 1;
103370 }
103371 
103372 return $a['priority'] > $b['priority'] ? -1 : 1;
103373 });
103374 
103375 return $this;
103376 }
103377 
103378 
103379 
103380 
103381 
103382 
103383 private function searchInDirectory($dir)
103384 {
103385 if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
103386 $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
103387 }
103388 
103389 if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
103390 $this->notPaths[] = '#(^|/)\..+(/|$)#';
103391 }
103392 
103393 if ($this->adapters) {
103394 foreach ($this->adapters as $adapter) {
103395 if ($adapter['adapter']->isSupported()) {
103396 try {
103397 return $this
103398 ->buildAdapter($adapter['adapter'])
103399 ->searchInDirectory($dir);
103400 } catch (ExceptionInterface $e) {
103401 }
103402 }
103403 }
103404 }
103405 
103406 $minDepth = 0;
103407 $maxDepth = PHP_INT_MAX;
103408 
103409 foreach ($this->depths as $comparator) {
103410 switch ($comparator->getOperator()) {
103411 case '>':
103412 $minDepth = $comparator->getTarget() + 1;
103413 break;
103414 case '>=':
103415 $minDepth = $comparator->getTarget();
103416 break;
103417 case '<':
103418 $maxDepth = $comparator->getTarget() - 1;
103419 break;
103420 case '<=':
103421 $maxDepth = $comparator->getTarget();
103422 break;
103423 default:
103424 $minDepth = $maxDepth = $comparator->getTarget();
103425 }
103426 }
103427 
103428 $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
103429 
103430 if ($this->followLinks) {
103431 $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
103432 }
103433 
103434 $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);
103435 
103436 if ($this->exclude) {
103437 $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
103438 }
103439 
103440 $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
103441 
103442 if ($minDepth > 0 || $maxDepth < PHP_INT_MAX) {
103443 $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth);
103444 }
103445 
103446 if ($this->mode) {
103447 $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
103448 }
103449 
103450 if ($this->names || $this->notNames) {
103451 $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
103452 }
103453 
103454 if ($this->contains || $this->notContains) {
103455 $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
103456 }
103457 
103458 if ($this->sizes) {
103459 $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
103460 }
103461 
103462 if ($this->dates) {
103463 $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
103464 }
103465 
103466 if ($this->filters) {
103467 $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
103468 }
103469 
103470 if ($this->paths || $this->notPaths) {
103471 $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
103472 }
103473 
103474 if ($this->sort) {
103475 $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
103476 $iterator = $iteratorAggregate->getIterator();
103477 }
103478 
103479 return $iterator;
103480 }
103481 
103482 
103483 
103484 
103485 private function buildAdapter(AdapterInterface $adapter)
103486 {
103487 return $adapter
103488 ->setFollowLinks($this->followLinks)
103489 ->setDepths($this->depths)
103490 ->setMode($this->mode)
103491 ->setExclude($this->exclude)
103492 ->setNames($this->names)
103493 ->setNotNames($this->notNames)
103494 ->setContains($this->contains)
103495 ->setNotContains($this->notContains)
103496 ->setSizes($this->sizes)
103497 ->setDates($this->dates)
103498 ->setFilters($this->filters)
103499 ->setSort($this->sort)
103500 ->setPath($this->paths)
103501 ->setNotPath($this->notPaths)
103502 ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
103503 }
103504 
103505 
103506 
103507 
103508 private function resetAdapterSelection()
103509 {
103510 $this->adapters = array_map(function (array $properties) {
103511 $properties['selected'] = false;
103512 
103513 return $properties;
103514 }, $this->adapters);
103515 }
103516 
103517 private function initDefaultAdapters()
103518 {
103519 if (null === $this->adapters) {
103520 $this->adapters = array();
103521 $this
103522 ->addAdapter(new GnuFindAdapter())
103523 ->addAdapter(new BsdFindAdapter())
103524 ->addAdapter(new PhpAdapter(), -50)
103525 ->setAdapter('php')
103526 ;
103527 }
103528 }
103529 
103530 
103531 
103532 
103533 
103534 
103535 
103536 
103537 private function normalizeDir($dir)
103538 {
103539 return rtrim($dir, '/'.\DIRECTORY_SEPARATOR);
103540 }
103541 }
103542 <?php
103543 
103544 
103545 
103546 
103547 
103548 
103549 
103550 
103551 
103552 
103553 namespace Symfony\Component\Finder;
103554 
103555 
103556 
103557 
103558 
103559 
103560 
103561 
103562 
103563 
103564 
103565 
103566 
103567 
103568 
103569 
103570 
103571 
103572 
103573 
103574 
103575 
103576 
103577 class Glob
103578 {
103579 
103580 
103581 
103582 
103583 
103584 
103585 
103586 
103587 
103588 
103589 public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true, $delimiter = '#')
103590 {
103591 $firstByte = true;
103592 $escaping = false;
103593 $inCurlies = 0;
103594 $regex = '';
103595 $sizeGlob = \strlen($glob);
103596 for ($i = 0; $i < $sizeGlob; ++$i) {
103597 $car = $glob[$i];
103598 if ($firstByte) {
103599 if ($strictLeadingDot && '.' !== $car) {
103600 $regex .= '(?=[^\.])';
103601 }
103602 
103603 $firstByte = false;
103604 }
103605 
103606 if ('/' === $car) {
103607 $firstByte = true;
103608 }
103609 
103610 if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
103611 $regex .= "\\$car";
103612 } elseif ('*' === $car) {
103613 $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
103614 } elseif ('?' === $car) {
103615 $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
103616 } elseif ('{' === $car) {
103617 $regex .= $escaping ? '\\{' : '(';
103618 if (!$escaping) {
103619 ++$inCurlies;
103620 }
103621 } elseif ('}' === $car && $inCurlies) {
103622 $regex .= $escaping ? '}' : ')';
103623 if (!$escaping) {
103624 --$inCurlies;
103625 }
103626 } elseif (',' === $car && $inCurlies) {
103627 $regex .= $escaping ? ',' : '|';
103628 } elseif ('\\' === $car) {
103629 if ($escaping) {
103630 $regex .= '\\\\';
103631 $escaping = false;
103632 } else {
103633 $escaping = true;
103634 }
103635 
103636 continue;
103637 } else {
103638 $regex .= $car;
103639 }
103640 $escaping = false;
103641 }
103642 
103643 return $delimiter.'^'.$regex.'$'.$delimiter;
103644 }
103645 }
103646 <?php
103647 
103648 
103649 
103650 
103651 
103652 
103653 
103654 
103655 
103656 
103657 namespace Symfony\Component\Finder\Iterator;
103658 
103659 
103660 
103661 
103662 
103663 
103664 
103665 
103666 
103667 class CustomFilterIterator extends FilterIterator
103668 {
103669 private $filters = array();
103670 
103671 
103672 
103673 
103674 
103675 
103676 
103677 public function __construct(\Iterator $iterator, array $filters)
103678 {
103679 foreach ($filters as $filter) {
103680 if (!\is_callable($filter)) {
103681 throw new \InvalidArgumentException('Invalid PHP callback.');
103682 }
103683 }
103684 $this->filters = $filters;
103685 
103686 parent::__construct($iterator);
103687 }
103688 
103689 
103690 
103691 
103692 
103693 
103694 public function accept()
103695 {
103696 $fileinfo = $this->current();
103697 
103698 foreach ($this->filters as $filter) {
103699 if (false === \call_user_func($filter, $fileinfo)) {
103700 return false;
103701 }
103702 }
103703 
103704 return true;
103705 }
103706 }
103707 <?php
103708 
103709 
103710 
103711 
103712 
103713 
103714 
103715 
103716 
103717 
103718 namespace Symfony\Component\Finder\Iterator;
103719 
103720 use Symfony\Component\Finder\Comparator\DateComparator;
103721 
103722 
103723 
103724 
103725 
103726 
103727 class DateRangeFilterIterator extends FilterIterator
103728 {
103729 private $comparators = array();
103730 
103731 
103732 
103733 
103734 
103735 public function __construct(\Iterator $iterator, array $comparators)
103736 {
103737 $this->comparators = $comparators;
103738 
103739 parent::__construct($iterator);
103740 }
103741 
103742 
103743 
103744 
103745 
103746 
103747 public function accept()
103748 {
103749 $fileinfo = $this->current();
103750 
103751 if (!file_exists($fileinfo->getPathname())) {
103752 return false;
103753 }
103754 
103755 $filedate = $fileinfo->getMTime();
103756 foreach ($this->comparators as $compare) {
103757 if (!$compare->test($filedate)) {
103758 return false;
103759 }
103760 }
103761 
103762 return true;
103763 }
103764 }
103765 <?php
103766 
103767 
103768 
103769 
103770 
103771 
103772 
103773 
103774 
103775 
103776 namespace Symfony\Component\Finder\Iterator;
103777 
103778 
103779 
103780 
103781 
103782 
103783 class DepthRangeFilterIterator extends FilterIterator
103784 {
103785 private $minDepth = 0;
103786 
103787 
103788 
103789 
103790 
103791 
103792 public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX)
103793 {
103794 $this->minDepth = $minDepth;
103795 $iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);
103796 
103797 parent::__construct($iterator);
103798 }
103799 
103800 
103801 
103802 
103803 
103804 
103805 public function accept()
103806 {
103807 return $this->getInnerIterator()->getDepth() >= $this->minDepth;
103808 }
103809 }
103810 <?php
103811 
103812 
103813 
103814 
103815 
103816 
103817 
103818 
103819 
103820 
103821 namespace Symfony\Component\Finder\Iterator;
103822 
103823 
103824 
103825 
103826 
103827 
103828 class ExcludeDirectoryFilterIterator extends FilterIterator implements \RecursiveIterator
103829 {
103830 private $iterator;
103831 private $isRecursive;
103832 private $excludedDirs = array();
103833 private $excludedPattern;
103834 
103835 
103836 
103837 
103838 
103839 public function __construct(\Iterator $iterator, array $directories)
103840 {
103841 $this->iterator = $iterator;
103842 $this->isRecursive = $iterator instanceof \RecursiveIterator;
103843 $patterns = array();
103844 foreach ($directories as $directory) {
103845 $directory = rtrim($directory, '/');
103846 if (!$this->isRecursive || false !== strpos($directory, '/')) {
103847 $patterns[] = preg_quote($directory, '#');
103848 } else {
103849 $this->excludedDirs[$directory] = true;
103850 }
103851 }
103852 if ($patterns) {
103853 $this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#';
103854 }
103855 
103856 parent::__construct($iterator);
103857 }
103858 
103859 
103860 
103861 
103862 
103863 
103864 public function accept()
103865 {
103866 if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) {
103867 return false;
103868 }
103869 
103870 if ($this->excludedPattern) {
103871 $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
103872 $path = str_replace('\\', '/', $path);
103873 
103874 return !preg_match($this->excludedPattern, $path);
103875 }
103876 
103877 return true;
103878 }
103879 
103880 public function hasChildren()
103881 {
103882 return $this->isRecursive && $this->iterator->hasChildren();
103883 }
103884 
103885 public function getChildren()
103886 {
103887 $children = new self($this->iterator->getChildren(), array());
103888 $children->excludedDirs = $this->excludedDirs;
103889 $children->excludedPattern = $this->excludedPattern;
103890 
103891 return $children;
103892 }
103893 }
103894 <?php
103895 
103896 
103897 
103898 
103899 
103900 
103901 
103902 
103903 
103904 
103905 namespace Symfony\Component\Finder\Iterator;
103906 
103907 @trigger_error('The '.__NAMESPACE__.'\FilePathsIterator class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
103908 
103909 use Symfony\Component\Finder\SplFileInfo;
103910 
103911 
103912 
103913 
103914 
103915 
103916 
103917 
103918 class FilePathsIterator extends \ArrayIterator
103919 {
103920 
103921 
103922 
103923 private $baseDir;
103924 
103925 
103926 
103927 
103928 private $baseDirLength;
103929 
103930 
103931 
103932 
103933 private $subPath;
103934 
103935 
103936 
103937 
103938 private $subPathname;
103939 
103940 
103941 
103942 
103943 private $current;
103944 
103945 
103946 
103947 
103948 
103949 public function __construct(array $paths, $baseDir)
103950 {
103951 $this->baseDir = $baseDir;
103952 $this->baseDirLength = \strlen($baseDir);
103953 
103954 parent::__construct($paths);
103955 }
103956 
103957 
103958 
103959 
103960 
103961 
103962 
103963 public function __call($name, array $arguments)
103964 {
103965 return \call_user_func_array(array($this->current(), $name), $arguments);
103966 }
103967 
103968 
103969 
103970 
103971 
103972 
103973 public function current()
103974 {
103975 return $this->current;
103976 }
103977 
103978 
103979 
103980 
103981 public function key()
103982 {
103983 return $this->current->getPathname();
103984 }
103985 
103986 public function next()
103987 {
103988 parent::next();
103989 $this->buildProperties();
103990 }
103991 
103992 public function rewind()
103993 {
103994 parent::rewind();
103995 $this->buildProperties();
103996 }
103997 
103998 
103999 
104000 
104001 public function getSubPath()
104002 {
104003 return $this->subPath;
104004 }
104005 
104006 
104007 
104008 
104009 public function getSubPathname()
104010 {
104011 return $this->subPathname;
104012 }
104013 
104014 private function buildProperties()
104015 {
104016 $absolutePath = parent::current();
104017 
104018 if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
104019 $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
104020 $dir = \dirname($this->subPathname);
104021 $this->subPath = '.' === $dir ? '' : $dir;
104022 } else {
104023 $this->subPath = $this->subPathname = '';
104024 }
104025 
104026 $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
104027 }
104028 }
104029 <?php
104030 
104031 
104032 
104033 
104034 
104035 
104036 
104037 
104038 
104039 
104040 namespace Symfony\Component\Finder\Iterator;
104041 
104042 
104043 
104044 
104045 
104046 
104047 class FileTypeFilterIterator extends FilterIterator
104048 {
104049 const ONLY_FILES = 1;
104050 const ONLY_DIRECTORIES = 2;
104051 
104052 private $mode;
104053 
104054 
104055 
104056 
104057 
104058 public function __construct(\Iterator $iterator, $mode)
104059 {
104060 $this->mode = $mode;
104061 
104062 parent::__construct($iterator);
104063 }
104064 
104065 
104066 
104067 
104068 
104069 
104070 public function accept()
104071 {
104072 $fileinfo = $this->current();
104073 if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
104074 return false;
104075 } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
104076 return false;
104077 }
104078 
104079 return true;
104080 }
104081 }
104082 <?php
104083 
104084 
104085 
104086 
104087 
104088 
104089 
104090 
104091 
104092 
104093 namespace Symfony\Component\Finder\Iterator;
104094 
104095 
104096 
104097 
104098 
104099 
104100 
104101 class FilecontentFilterIterator extends MultiplePcreFilterIterator
104102 {
104103 
104104 
104105 
104106 
104107 
104108 public function accept()
104109 {
104110 if (!$this->matchRegexps && !$this->noMatchRegexps) {
104111 return true;
104112 }
104113 
104114 $fileinfo = $this->current();
104115 
104116 if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
104117 return false;
104118 }
104119 
104120 $content = $fileinfo->getContents();
104121 if (!$content) {
104122 return false;
104123 }
104124 
104125 return $this->isAccepted($content);
104126 }
104127 
104128 
104129 
104130 
104131 
104132 
104133 
104134 
104135 protected function toRegex($str)
104136 {
104137 return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
104138 }
104139 }
104140 <?php
104141 
104142 
104143 
104144 
104145 
104146 
104147 
104148 
104149 
104150 
104151 namespace Symfony\Component\Finder\Iterator;
104152 
104153 use Symfony\Component\Finder\Glob;
104154 
104155 
104156 
104157 
104158 
104159 
104160 class FilenameFilterIterator extends MultiplePcreFilterIterator
104161 {
104162 
104163 
104164 
104165 
104166 
104167 public function accept()
104168 {
104169 return $this->isAccepted($this->current()->getFilename());
104170 }
104171 
104172 
104173 
104174 
104175 
104176 
104177 
104178 
104179 
104180 
104181 
104182 protected function toRegex($str)
104183 {
104184 return $this->isRegex($str) ? $str : Glob::toRegex($str);
104185 }
104186 }
104187 <?php
104188 
104189 
104190 
104191 
104192 
104193 
104194 
104195 
104196 
104197 
104198 namespace Symfony\Component\Finder\Iterator;
104199 
104200 
104201 
104202 
104203 
104204 
104205 
104206 
104207 
104208 abstract class FilterIterator extends \FilterIterator
104209 {
104210 
104211 
104212 
104213 
104214 
104215 
104216 public function rewind()
104217 {
104218 if (\PHP_VERSION_ID > 50607 || (\PHP_VERSION_ID > 50523 && \PHP_VERSION_ID < 50600)) {
104219 parent::rewind();
104220 
104221 return;
104222 }
104223 
104224 $iterator = $this;
104225 while ($iterator instanceof \OuterIterator) {
104226 $innerIterator = $iterator->getInnerIterator();
104227 
104228 if ($innerIterator instanceof RecursiveDirectoryIterator) {
104229 
104230 if ($innerIterator->isRewindable()) {
104231 $innerIterator->next();
104232 $innerIterator->rewind();
104233 }
104234 } elseif ($innerIterator instanceof \FilesystemIterator) {
104235 $innerIterator->next();
104236 $innerIterator->rewind();
104237 }
104238 
104239 $iterator = $innerIterator;
104240 }
104241 
104242 parent::rewind();
104243 }
104244 }
104245 <?php
104246 
104247 
104248 
104249 
104250 
104251 
104252 
104253 
104254 
104255 
104256 namespace Symfony\Component\Finder\Iterator;
104257 
104258 
104259 
104260 
104261 
104262 
104263 abstract class MultiplePcreFilterIterator extends FilterIterator
104264 {
104265 protected $matchRegexps = array();
104266 protected $noMatchRegexps = array();
104267 
104268 
104269 
104270 
104271 
104272 
104273 public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
104274 {
104275 foreach ($matchPatterns as $pattern) {
104276 $this->matchRegexps[] = $this->toRegex($pattern);
104277 }
104278 
104279 foreach ($noMatchPatterns as $pattern) {
104280 $this->noMatchRegexps[] = $this->toRegex($pattern);
104281 }
104282 
104283 parent::__construct($iterator);
104284 }
104285 
104286 
104287 
104288 
104289 
104290 
104291 
104292 
104293 
104294 
104295 
104296 
104297 protected function isAccepted($string)
104298 {
104299 
104300 foreach ($this->noMatchRegexps as $regex) {
104301 if (preg_match($regex, $string)) {
104302 return false;
104303 }
104304 }
104305 
104306 
104307 if ($this->matchRegexps) {
104308 foreach ($this->matchRegexps as $regex) {
104309 if (preg_match($regex, $string)) {
104310 return true;
104311 }
104312 }
104313 
104314 return false;
104315 }
104316 
104317 
104318 return true;
104319 }
104320 
104321 
104322 
104323 
104324 
104325 
104326 
104327 
104328 protected function isRegex($str)
104329 {
104330 if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
104331 $start = substr($m[1], 0, 1);
104332 $end = substr($m[1], -1);
104333 
104334 if ($start === $end) {
104335 return !preg_match('/[*?[:alnum:] \\\\]/', $start);
104336 }
104337 
104338 foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) {
104339 if ($start === $delimiters[0] && $end === $delimiters[1]) {
104340 return true;
104341 }
104342 }
104343 }
104344 
104345 return false;
104346 }
104347 
104348 
104349 
104350 
104351 
104352 
104353 
104354 
104355 abstract protected function toRegex($str);
104356 }
104357 <?php
104358 
104359 
104360 
104361 
104362 
104363 
104364 
104365 
104366 
104367 
104368 namespace Symfony\Component\Finder\Iterator;
104369 
104370 
104371 
104372 
104373 
104374 
104375 
104376 class PathFilterIterator extends MultiplePcreFilterIterator
104377 {
104378 
104379 
104380 
104381 
104382 
104383 public function accept()
104384 {
104385 $filename = $this->current()->getRelativePathname();
104386 
104387 if ('\\' === \DIRECTORY_SEPARATOR) {
104388 $filename = str_replace('\\', '/', $filename);
104389 }
104390 
104391 return $this->isAccepted($filename);
104392 }
104393 
104394 
104395 
104396 
104397 
104398 
104399 
104400 
104401 
104402 
104403 
104404 
104405 
104406 
104407 
104408 protected function toRegex($str)
104409 {
104410 return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
104411 }
104412 }
104413 <?php
104414 
104415 
104416 
104417 
104418 
104419 
104420 
104421 
104422 
104423 
104424 namespace Symfony\Component\Finder\Iterator;
104425 
104426 use Symfony\Component\Finder\Exception\AccessDeniedException;
104427 use Symfony\Component\Finder\SplFileInfo;
104428 
104429 
104430 
104431 
104432 
104433 
104434 class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
104435 {
104436 
104437 
104438 
104439 private $ignoreUnreadableDirs;
104440 
104441 
104442 
104443 
104444 private $rewindable;
104445 
104446 
104447 private $rootPath;
104448 private $subPath;
104449 private $directorySeparator = '/';
104450 
104451 
104452 
104453 
104454 
104455 
104456 
104457 
104458 public function __construct($path, $flags, $ignoreUnreadableDirs = false)
104459 {
104460 if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
104461 throw new \RuntimeException('This iterator only support returning current as fileinfo.');
104462 }
104463 
104464 parent::__construct($path, $flags);
104465 $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
104466 $this->rootPath = (string) $path;
104467 if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) {
104468 $this->directorySeparator = \DIRECTORY_SEPARATOR;
104469 }
104470 }
104471 
104472 
104473 
104474 
104475 
104476 
104477 public function current()
104478 {
104479 
104480 
104481 if (null === $subPathname = $this->subPath) {
104482 $subPathname = $this->subPath = (string) $this->getSubPath();
104483 }
104484 if ('' !== $subPathname) {
104485 $subPathname .= $this->directorySeparator;
104486 }
104487 $subPathname .= $this->getFilename();
104488 
104489 return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
104490 }
104491 
104492 
104493 
104494 
104495 
104496 
104497 public function getChildren()
104498 {
104499 try {
104500 $children = parent::getChildren();
104501 
104502 if ($children instanceof self) {
104503 
104504 $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
104505 
104506 
104507 $children->rewindable = &$this->rewindable;
104508 $children->rootPath = $this->rootPath;
104509 }
104510 
104511 return $children;
104512 } catch (\UnexpectedValueException $e) {
104513 if ($this->ignoreUnreadableDirs) {
104514 
104515 return new \RecursiveArrayIterator(array());
104516 } else {
104517 throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
104518 }
104519 }
104520 }
104521 
104522 
104523 
104524 
104525 public function rewind()
104526 {
104527 if (false === $this->isRewindable()) {
104528 return;
104529 }
104530 
104531 
104532 if (\PHP_VERSION_ID < 50523 || \PHP_VERSION_ID >= 50600 && \PHP_VERSION_ID < 50607) {
104533 parent::next();
104534 }
104535 
104536 parent::rewind();
104537 }
104538 
104539 
104540 
104541 
104542 
104543 
104544 public function isRewindable()
104545 {
104546 if (null !== $this->rewindable) {
104547 return $this->rewindable;
104548 }
104549 
104550 
104551 if ('' === $this->getPath()) {
104552 return $this->rewindable = false;
104553 }
104554 
104555 if (false !== $stream = @opendir($this->getPath())) {
104556 $infos = stream_get_meta_data($stream);
104557 closedir($stream);
104558 
104559 if ($infos['seekable']) {
104560 return $this->rewindable = true;
104561 }
104562 }
104563 
104564 return $this->rewindable = false;
104565 }
104566 }
104567 <?php
104568 
104569 
104570 
104571 
104572 
104573 
104574 
104575 
104576 
104577 
104578 namespace Symfony\Component\Finder\Iterator;
104579 
104580 use Symfony\Component\Finder\Comparator\NumberComparator;
104581 
104582 
104583 
104584 
104585 
104586 
104587 class SizeRangeFilterIterator extends FilterIterator
104588 {
104589 private $comparators = array();
104590 
104591 
104592 
104593 
104594 
104595 public function __construct(\Iterator $iterator, array $comparators)
104596 {
104597 $this->comparators = $comparators;
104598 
104599 parent::__construct($iterator);
104600 }
104601 
104602 
104603 
104604 
104605 
104606 
104607 public function accept()
104608 {
104609 $fileinfo = $this->current();
104610 if (!$fileinfo->isFile()) {
104611 return true;
104612 }
104613 
104614 $filesize = $fileinfo->getSize();
104615 foreach ($this->comparators as $compare) {
104616 if (!$compare->test($filesize)) {
104617 return false;
104618 }
104619 }
104620 
104621 return true;
104622 }
104623 }
104624 <?php
104625 
104626 
104627 
104628 
104629 
104630 
104631 
104632 
104633 
104634 
104635 namespace Symfony\Component\Finder\Iterator;
104636 
104637 
104638 
104639 
104640 
104641 
104642 class SortableIterator implements \IteratorAggregate
104643 {
104644 const SORT_BY_NAME = 1;
104645 const SORT_BY_TYPE = 2;
104646 const SORT_BY_ACCESSED_TIME = 3;
104647 const SORT_BY_CHANGED_TIME = 4;
104648 const SORT_BY_MODIFIED_TIME = 5;
104649 
104650 private $iterator;
104651 private $sort;
104652 
104653 
104654 
104655 
104656 
104657 
104658 
104659 public function __construct(\Traversable $iterator, $sort)
104660 {
104661 $this->iterator = $iterator;
104662 
104663 if (self::SORT_BY_NAME === $sort) {
104664 $this->sort = function ($a, $b) {
104665 return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
104666 };
104667 } elseif (self::SORT_BY_TYPE === $sort) {
104668 $this->sort = function ($a, $b) {
104669 if ($a->isDir() && $b->isFile()) {
104670 return -1;
104671 } elseif ($a->isFile() && $b->isDir()) {
104672 return 1;
104673 }
104674 
104675 return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
104676 };
104677 } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
104678 $this->sort = function ($a, $b) {
104679 return $a->getATime() - $b->getATime();
104680 };
104681 } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
104682 $this->sort = function ($a, $b) {
104683 return $a->getCTime() - $b->getCTime();
104684 };
104685 } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
104686 $this->sort = function ($a, $b) {
104687 return $a->getMTime() - $b->getMTime();
104688 };
104689 } elseif (\is_callable($sort)) {
104690 $this->sort = $sort;
104691 } else {
104692 throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
104693 }
104694 }
104695 
104696 public function getIterator()
104697 {
104698 $array = iterator_to_array($this->iterator, true);
104699 uasort($array, $this->sort);
104700 
104701 return new \ArrayIterator($array);
104702 }
104703 }
104704 
104705 Copyright (c) 2004-2018 Fabien Potencier
104706 
104707 Permission is hereby granted, free of charge, to any person obtaining a copy
104708 of this software and associated documentation files (the "Software"), to deal
104709 in the Software without restriction, including without limitation the rights
104710 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
104711 copies of the Software, and to permit persons to whom the Software is furnished
104712 to do so, subject to the following conditions:
104713 
104714 The above copyright notice and this permission notice shall be included in all
104715 copies or substantial portions of the Software.
104716 
104717 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
104718 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
104719 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
104720 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
104721 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
104722 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
104723 THE SOFTWARE.
104724 
104725 <?php
104726 
104727 
104728 
104729 
104730 
104731 
104732 
104733 
104734 
104735 
104736 namespace Symfony\Component\Finder\Shell;
104737 
104738 @trigger_error('The '.__NAMESPACE__.'\Command class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
104739 
104740 
104741 
104742 
104743 
104744 
104745 class Command
104746 {
104747 private $parent;
104748 private $bits = array();
104749 private $labels = array();
104750 
104751 
104752 
104753 
104754 private $errorHandler;
104755 
104756 public function __construct(Command $parent = null)
104757 {
104758 $this->parent = $parent;
104759 }
104760 
104761 
104762 
104763 
104764 
104765 
104766 public function __toString()
104767 {
104768 return $this->join();
104769 }
104770 
104771 
104772 
104773 
104774 
104775 
104776 public static function create(Command $parent = null)
104777 {
104778 return new self($parent);
104779 }
104780 
104781 
104782 
104783 
104784 
104785 
104786 
104787 
104788 public static function escape($input)
104789 {
104790 return escapeshellcmd($input);
104791 }
104792 
104793 
104794 
104795 
104796 
104797 
104798 
104799 
104800 public static function quote($input)
104801 {
104802 return escapeshellarg($input);
104803 }
104804 
104805 
104806 
104807 
104808 
104809 
104810 
104811 
104812 public function add($bit)
104813 {
104814 $this->bits[] = $bit;
104815 
104816 return $this;
104817 }
104818 
104819 
104820 
104821 
104822 
104823 
104824 
104825 
104826 public function top($bit)
104827 {
104828 array_unshift($this->bits, $bit);
104829 
104830 foreach ($this->labels as $label => $index) {
104831 ++$this->labels[$label];
104832 }
104833 
104834 return $this;
104835 }
104836 
104837 
104838 
104839 
104840 
104841 
104842 
104843 
104844 public function arg($arg)
104845 {
104846 $this->bits[] = self::quote($arg);
104847 
104848 return $this;
104849 }
104850 
104851 
104852 
104853 
104854 
104855 
104856 
104857 
104858 public function cmd($esc)
104859 {
104860 $this->bits[] = self::escape($esc);
104861 
104862 return $this;
104863 }
104864 
104865 
104866 
104867 
104868 
104869 
104870 
104871 
104872 
104873 
104874 public function ins($label)
104875 {
104876 if (isset($this->labels[$label])) {
104877 throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
104878 }
104879 
104880 $this->bits[] = self::create($this);
104881 $this->labels[$label] = \count($this->bits) - 1;
104882 
104883 return $this->bits[$this->labels[$label]];
104884 }
104885 
104886 
104887 
104888 
104889 
104890 
104891 
104892 
104893 
104894 
104895 public function get($label)
104896 {
104897 if (!isset($this->labels[$label])) {
104898 throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
104899 }
104900 
104901 return $this->bits[$this->labels[$label]];
104902 }
104903 
104904 
104905 
104906 
104907 
104908 
104909 
104910 
104911 public function end()
104912 {
104913 if (null === $this->parent) {
104914 throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
104915 }
104916 
104917 return $this->parent;
104918 }
104919 
104920 
104921 
104922 
104923 
104924 
104925 public function length()
104926 {
104927 return \count($this->bits);
104928 }
104929 
104930 
104931 
104932 
104933 public function setErrorHandler(\Closure $errorHandler)
104934 {
104935 $this->errorHandler = $errorHandler;
104936 
104937 return $this;
104938 }
104939 
104940 
104941 
104942 
104943 public function getErrorHandler()
104944 {
104945 return $this->errorHandler;
104946 }
104947 
104948 
104949 
104950 
104951 
104952 
104953 
104954 
104955 public function execute()
104956 {
104957 if (null === $errorHandler = $this->errorHandler) {
104958 exec($this->join(), $output);
104959 } else {
104960 $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
104961 $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
104962 
104963 if ($error = stream_get_contents($pipes[2])) {
104964 $errorHandler($error);
104965 }
104966 
104967 proc_close($process);
104968 }
104969 
104970 return $output ?: array();
104971 }
104972 
104973 
104974 
104975 
104976 
104977 
104978 public function join()
104979 {
104980 return implode(' ', array_filter(
104981 array_map(function ($bit) {
104982 return $bit instanceof Command ? $bit->join() : ($bit ?: null);
104983 }, $this->bits),
104984 function ($bit) { return null !== $bit; }
104985 ));
104986 }
104987 
104988 
104989 
104990 
104991 
104992 
104993 
104994 
104995 
104996 public function addAtIndex($bit, $index)
104997 {
104998 array_splice($this->bits, $index, 0, $bit instanceof self ? array($bit) : $bit);
104999 
105000 return $this;
105001 }
105002 }
105003 <?php
105004 
105005 
105006 
105007 
105008 
105009 
105010 
105011 
105012 
105013 
105014 namespace Symfony\Component\Finder\Shell;
105015 
105016 @trigger_error('The '.__NAMESPACE__.'\Shell class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
105017 
105018 
105019 
105020 
105021 
105022 
105023 class Shell
105024 {
105025 const TYPE_UNIX = 1;
105026 const TYPE_DARWIN = 2;
105027 const TYPE_CYGWIN = 3;
105028 const TYPE_WINDOWS = 4;
105029 const TYPE_BSD = 5;
105030 
105031 
105032 
105033 
105034 private $type;
105035 
105036 
105037 
105038 
105039 
105040 
105041 public function getType()
105042 {
105043 if (null === $this->type) {
105044 $this->type = $this->guessType();
105045 }
105046 
105047 return $this->type;
105048 }
105049 
105050 
105051 
105052 
105053 
105054 
105055 
105056 
105057 public function testCommand($command)
105058 {
105059 if (!\function_exists('exec')) {
105060 return false;
105061 }
105062 
105063 
105064 $testCommand = 'which ';
105065 if (self::TYPE_WINDOWS === $this->type) {
105066 $testCommand = 'where ';
105067 }
105068 
105069 $command = escapeshellcmd($command);
105070 
105071 exec($testCommand.$command, $output, $code);
105072 
105073 return 0 === $code && \count($output) > 0;
105074 }
105075 
105076 
105077 
105078 
105079 
105080 
105081 private function guessType()
105082 {
105083 $os = strtolower(PHP_OS);
105084 
105085 if (false !== strpos($os, 'cygwin')) {
105086 return self::TYPE_CYGWIN;
105087 }
105088 
105089 if (false !== strpos($os, 'darwin')) {
105090 return self::TYPE_DARWIN;
105091 }
105092 
105093 if (false !== strpos($os, 'bsd')) {
105094 return self::TYPE_BSD;
105095 }
105096 
105097 if (0 === strpos($os, 'win')) {
105098 return self::TYPE_WINDOWS;
105099 }
105100 
105101 return self::TYPE_UNIX;
105102 }
105103 }
105104 <?php
105105 
105106 
105107 
105108 
105109 
105110 
105111 
105112 
105113 
105114 
105115 namespace Symfony\Component\Finder;
105116 
105117 
105118 
105119 
105120 
105121 
105122 class SplFileInfo extends \SplFileInfo
105123 {
105124 private $relativePath;
105125 private $relativePathname;
105126 
105127 
105128 
105129 
105130 
105131 
105132 public function __construct($file, $relativePath, $relativePathname)
105133 {
105134 parent::__construct($file);
105135 $this->relativePath = $relativePath;
105136 $this->relativePathname = $relativePathname;
105137 }
105138 
105139 
105140 
105141 
105142 
105143 
105144 
105145 
105146 public function getRelativePath()
105147 {
105148 return $this->relativePath;
105149 }
105150 
105151 
105152 
105153 
105154 
105155 
105156 
105157 
105158 public function getRelativePathname()
105159 {
105160 return $this->relativePathname;
105161 }
105162 
105163 
105164 
105165 
105166 
105167 
105168 
105169 
105170 public function getContents()
105171 {
105172 set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
105173 $content = file_get_contents($this->getPathname());
105174 restore_error_handler();
105175 if (false === $content) {
105176 throw new \RuntimeException($error);
105177 }
105178 
105179 return $content;
105180 }
105181 }
105182 <?php
105183 
105184 
105185 
105186 
105187 
105188 
105189 
105190 
105191 
105192 
105193 namespace Symfony\Polyfill\Ctype;
105194 
105195 
105196 
105197 
105198 
105199 
105200 
105201 
105202 final class Ctype
105203 {
105204 
105205 
105206 
105207 
105208 
105209 
105210 
105211 
105212 
105213 public static function ctype_alnum($text)
105214 {
105215 $text = self::convert_int_to_char_for_ctype($text);
105216 
105217 return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
105218 }
105219 
105220 
105221 
105222 
105223 
105224 
105225 
105226 
105227 
105228 
105229 public static function ctype_alpha($text)
105230 {
105231 $text = self::convert_int_to_char_for_ctype($text);
105232 
105233 return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
105234 }
105235 
105236 
105237 
105238 
105239 
105240 
105241 
105242 
105243 
105244 
105245 public static function ctype_cntrl($text)
105246 {
105247 $text = self::convert_int_to_char_for_ctype($text);
105248 
105249 return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
105250 }
105251 
105252 
105253 
105254 
105255 
105256 
105257 
105258 
105259 
105260 
105261 public static function ctype_digit($text)
105262 {
105263 $text = self::convert_int_to_char_for_ctype($text);
105264 
105265 return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
105266 }
105267 
105268 
105269 
105270 
105271 
105272 
105273 
105274 
105275 
105276 
105277 public static function ctype_graph($text)
105278 {
105279 $text = self::convert_int_to_char_for_ctype($text);
105280 
105281 return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
105282 }
105283 
105284 
105285 
105286 
105287 
105288 
105289 
105290 
105291 
105292 
105293 public static function ctype_lower($text)
105294 {
105295 $text = self::convert_int_to_char_for_ctype($text);
105296 
105297 return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
105298 }
105299 
105300 
105301 
105302 
105303 
105304 
105305 
105306 
105307 
105308 
105309 public static function ctype_print($text)
105310 {
105311 $text = self::convert_int_to_char_for_ctype($text);
105312 
105313 return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
105314 }
105315 
105316 
105317 
105318 
105319 
105320 
105321 
105322 
105323 
105324 
105325 public static function ctype_punct($text)
105326 {
105327 $text = self::convert_int_to_char_for_ctype($text);
105328 
105329 return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
105330 }
105331 
105332 
105333 
105334 
105335 
105336 
105337 
105338 
105339 
105340 
105341 public static function ctype_space($text)
105342 {
105343 $text = self::convert_int_to_char_for_ctype($text);
105344 
105345 return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
105346 }
105347 
105348 
105349 
105350 
105351 
105352 
105353 
105354 
105355 
105356 
105357 public static function ctype_upper($text)
105358 {
105359 $text = self::convert_int_to_char_for_ctype($text);
105360 
105361 return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
105362 }
105363 
105364 
105365 
105366 
105367 
105368 
105369 
105370 
105371 
105372 
105373 public static function ctype_xdigit($text)
105374 {
105375 $text = self::convert_int_to_char_for_ctype($text);
105376 
105377 return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
105378 }
105379 
105380 
105381 
105382 
105383 
105384 
105385 
105386 
105387 
105388 
105389 
105390 
105391 
105392 private static function convert_int_to_char_for_ctype($int)
105393 {
105394 if (!\is_int($int)) {
105395 return $int;
105396 }
105397 
105398 if ($int < -128 || $int > 255) {
105399 return (string) $int;
105400 }
105401 
105402 if ($int < 0) {
105403 $int += 256;
105404 }
105405 
105406 return \chr($int);
105407 }
105408 }
105409 
105410 Copyright (c) 2018-2019 Fabien Potencier
105411 
105412 Permission is hereby granted, free of charge, to any person obtaining a copy
105413 of this software and associated documentation files (the "Software"), to deal
105414 in the Software without restriction, including without limitation the rights
105415 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
105416 copies of the Software, and to permit persons to whom the Software is furnished
105417 to do so, subject to the following conditions:
105418 
105419 The above copyright notice and this permission notice shall be included in all
105420 copies or substantial portions of the Software.
105421 
105422 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105423 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
105424 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
105425 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
105426 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
105427 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
105428 THE SOFTWARE.
105429 
105430 <?php
105431 
105432 
105433 
105434 
105435 
105436 
105437 
105438 
105439 
105440 
105441 use Symfony\Polyfill\Ctype as p;
105442 
105443 if (!function_exists('ctype_alnum')) {
105444 function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); }
105445 }
105446 if (!function_exists('ctype_alpha')) {
105447 function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); }
105448 }
105449 if (!function_exists('ctype_cntrl')) {
105450 function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); }
105451 }
105452 if (!function_exists('ctype_digit')) {
105453 function ctype_digit($input) { return p\Ctype::ctype_digit($input); }
105454 }
105455 if (!function_exists('ctype_graph')) {
105456 function ctype_graph($input) { return p\Ctype::ctype_graph($input); }
105457 }
105458 if (!function_exists('ctype_lower')) {
105459 function ctype_lower($input) { return p\Ctype::ctype_lower($input); }
105460 }
105461 if (!function_exists('ctype_print')) {
105462 function ctype_print($input) { return p\Ctype::ctype_print($input); }
105463 }
105464 if (!function_exists('ctype_punct')) {
105465 function ctype_punct($input) { return p\Ctype::ctype_punct($input); }
105466 }
105467 if (!function_exists('ctype_space')) {
105468 function ctype_space($input) { return p\Ctype::ctype_space($input); }
105469 }
105470 if (!function_exists('ctype_upper')) {
105471 function ctype_upper($input) { return p\Ctype::ctype_upper($input); }
105472 }
105473 if (!function_exists('ctype_xdigit')) {
105474 function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); }
105475 }
105476 
105477 Copyright (c) 2015-2019 Fabien Potencier
105478 
105479 Permission is hereby granted, free of charge, to any person obtaining a copy
105480 of this software and associated documentation files (the "Software"), to deal
105481 in the Software without restriction, including without limitation the rights
105482 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
105483 copies of the Software, and to permit persons to whom the Software is furnished
105484 to do so, subject to the following conditions:
105485 
105486 The above copyright notice and this permission notice shall be included in all
105487 copies or substantial portions of the Software.
105488 
105489 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105490 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
105491 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
105492 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
105493 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
105494 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
105495 THE SOFTWARE.
105496 
105497 <?php
105498 
105499 
105500 
105501 
105502 
105503 
105504 
105505 
105506 
105507 
105508 namespace Symfony\Polyfill\Mbstring;
105509 
105510 
105511 
105512 
105513 
105514 
105515 
105516 
105517 
105518 
105519 
105520 
105521 
105522 
105523 
105524 
105525 
105526 
105527 
105528 
105529 
105530 
105531 
105532 
105533 
105534 
105535 
105536 
105537 
105538 
105539 
105540 
105541 
105542 
105543 
105544 
105545 
105546 
105547 
105548 
105549 
105550 
105551 
105552 
105553 
105554 
105555 
105556 
105557 
105558 
105559 
105560 
105561 
105562 
105563 
105564 final class Mbstring
105565 {
105566 const MB_CASE_FOLD = PHP_INT_MAX;
105567 
105568 private static $encodingList = array('ASCII', 'UTF-8');
105569 private static $language = 'neutral';
105570 private static $internalEncoding = 'UTF-8';
105571 private static $caseFold = array(
105572 array('µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"),
105573 array('μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'),
105574 );
105575 
105576 public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
105577 {
105578 if (\is_array($fromEncoding) || false !== strpos($fromEncoding, ',')) {
105579 $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
105580 } else {
105581 $fromEncoding = self::getEncoding($fromEncoding);
105582 }
105583 
105584 $toEncoding = self::getEncoding($toEncoding);
105585 
105586 if ('BASE64' === $fromEncoding) {
105587 $s = base64_decode($s);
105588 $fromEncoding = $toEncoding;
105589 }
105590 
105591 if ('BASE64' === $toEncoding) {
105592 return base64_encode($s);
105593 }
105594 
105595 if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
105596 if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
105597 $fromEncoding = 'Windows-1252';
105598 }
105599 if ('UTF-8' !== $fromEncoding) {
105600 $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s);
105601 }
105602 
105603 return preg_replace_callback('/[\x80-\xFF]+/', array(__CLASS__, 'html_encoding_callback'), $s);
105604 }
105605 
105606 if ('HTML-ENTITIES' === $fromEncoding) {
105607 $s = html_entity_decode($s, ENT_COMPAT, 'UTF-8');
105608 $fromEncoding = 'UTF-8';
105609 }
105610 
105611 return iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
105612 }
105613 
105614 public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null)
105615 {
105616 $vars = array(&$a, &$b, &$c, &$d, &$e, &$f);
105617 
105618 $ok = true;
105619 array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) {
105620 if (false === $v = Mbstring::mb_convert_encoding($v, $toEncoding, $fromEncoding)) {
105621 $ok = false;
105622 }
105623 });
105624 
105625 return $ok ? $fromEncoding : false;
105626 }
105627 
105628 public static function mb_decode_mimeheader($s)
105629 {
105630 return iconv_mime_decode($s, 2, self::$internalEncoding);
105631 }
105632 
105633 public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
105634 {
105635 trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
105636 }
105637 
105638 public static function mb_decode_numericentity($s, $convmap, $encoding = null)
105639 {
105640 if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
105641 trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
105642 
105643 return null;
105644 }
105645 
105646 if (!\is_array($convmap) || !$convmap) {
105647 return false;
105648 }
105649 
105650 if (null !== $encoding && !\is_scalar($encoding)) {
105651 trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
105652 
105653 return ''; 
105654 }
105655 
105656 $s = (string) $s;
105657 if ('' === $s) {
105658 return '';
105659 }
105660 
105661 $encoding = self::getEncoding($encoding);
105662 
105663 if ('UTF-8' === $encoding) {
105664 $encoding = null;
105665 if (!preg_match('//u', $s)) {
105666 $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
105667 }
105668 } else {
105669 $s = iconv($encoding, 'UTF-8//IGNORE', $s);
105670 }
105671 
105672 $cnt = floor(\count($convmap) / 4) * 4;
105673 
105674 for ($i = 0; $i < $cnt; $i += 4) {
105675 
105676 $convmap[$i] += $convmap[$i + 2];
105677 $convmap[$i + 1] += $convmap[$i + 2];
105678 }
105679 
105680 $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) {
105681 $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1];
105682 for ($i = 0; $i < $cnt; $i += 4) {
105683 if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
105684 return Mbstring::mb_chr($c - $convmap[$i + 2]);
105685 }
105686 }
105687 
105688 return $m[0];
105689 }, $s);
105690 
105691 if (null === $encoding) {
105692 return $s;
105693 }
105694 
105695 return iconv('UTF-8', $encoding.'//IGNORE', $s);
105696 }
105697 
105698 public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
105699 {
105700 if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
105701 trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', E_USER_WARNING);
105702 
105703 return null;
105704 }
105705 
105706 if (!\is_array($convmap) || !$convmap) {
105707 return false;
105708 }
105709 
105710 if (null !== $encoding && !\is_scalar($encoding)) {
105711 trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', E_USER_WARNING);
105712 
105713 return null; 
105714 }
105715 
105716 if (null !== $is_hex && !\is_scalar($is_hex)) {
105717 trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', E_USER_WARNING);
105718 
105719 return null;
105720 }
105721 
105722 $s = (string) $s;
105723 if ('' === $s) {
105724 return '';
105725 }
105726 
105727 $encoding = self::getEncoding($encoding);
105728 
105729 if ('UTF-8' === $encoding) {
105730 $encoding = null;
105731 if (!preg_match('//u', $s)) {
105732 $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
105733 }
105734 } else {
105735 $s = iconv($encoding, 'UTF-8//IGNORE', $s);
105736 }
105737 
105738 static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
105739 
105740 $cnt = floor(\count($convmap) / 4) * 4;
105741 $i = 0;
105742 $len = \strlen($s);
105743 $result = '';
105744 
105745 while ($i < $len) {
105746 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
105747 $uchr = substr($s, $i, $ulen);
105748 $i += $ulen;
105749 $c = self::mb_ord($uchr);
105750 
105751 for ($j = 0; $j < $cnt; $j += 4) {
105752 if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
105753 $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3];
105754 $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';';
105755 continue 2;
105756 }
105757 }
105758 $result .= $uchr;
105759 }
105760 
105761 if (null === $encoding) {
105762 return $result;
105763 }
105764 
105765 return iconv('UTF-8', $encoding.'//IGNORE', $result);
105766 }
105767 
105768 public static function mb_convert_case($s, $mode, $encoding = null)
105769 {
105770 $s = (string) $s;
105771 if ('' === $s) {
105772 return '';
105773 }
105774 
105775 $encoding = self::getEncoding($encoding);
105776 
105777 if ('UTF-8' === $encoding) {
105778 $encoding = null;
105779 if (!preg_match('//u', $s)) {
105780 $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s);
105781 }
105782 } else {
105783 $s = iconv($encoding, 'UTF-8//IGNORE', $s);
105784 }
105785 
105786 if (MB_CASE_TITLE == $mode) {
105787 static $titleRegexp = null;
105788 if (null === $titleRegexp) {
105789 $titleRegexp = self::getData('titleCaseRegexp');
105790 }
105791 $s = preg_replace_callback($titleRegexp, array(__CLASS__, 'title_case'), $s);
105792 } else {
105793 if (MB_CASE_UPPER == $mode) {
105794 static $upper = null;
105795 if (null === $upper) {
105796 $upper = self::getData('upperCase');
105797 }
105798 $map = $upper;
105799 } else {
105800 if (self::MB_CASE_FOLD === $mode) {
105801 $s = str_replace(self::$caseFold[0], self::$caseFold[1], $s);
105802 }
105803 
105804 static $lower = null;
105805 if (null === $lower) {
105806 $lower = self::getData('lowerCase');
105807 }
105808 $map = $lower;
105809 }
105810 
105811 static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
105812 
105813 $i = 0;
105814 $len = \strlen($s);
105815 
105816 while ($i < $len) {
105817 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"];
105818 $uchr = substr($s, $i, $ulen);
105819 $i += $ulen;
105820 
105821 if (isset($map[$uchr])) {
105822 $uchr = $map[$uchr];
105823 $nlen = \strlen($uchr);
105824 
105825 if ($nlen == $ulen) {
105826 $nlen = $i;
105827 do {
105828 $s[--$nlen] = $uchr[--$ulen];
105829 } while ($ulen);
105830 } else {
105831 $s = substr_replace($s, $uchr, $i - $ulen, $ulen);
105832 $len += $nlen - $ulen;
105833 $i += $nlen - $ulen;
105834 }
105835 }
105836 }
105837 }
105838 
105839 if (null === $encoding) {
105840 return $s;
105841 }
105842 
105843 return iconv('UTF-8', $encoding.'//IGNORE', $s);
105844 }
105845 
105846 public static function mb_internal_encoding($encoding = null)
105847 {
105848 if (null === $encoding) {
105849 return self::$internalEncoding;
105850 }
105851 
105852 $encoding = self::getEncoding($encoding);
105853 
105854 if ('UTF-8' === $encoding || false !== @iconv($encoding, $encoding, ' ')) {
105855 self::$internalEncoding = $encoding;
105856 
105857 return true;
105858 }
105859 
105860 return false;
105861 }
105862 
105863 public static function mb_language($lang = null)
105864 {
105865 if (null === $lang) {
105866 return self::$language;
105867 }
105868 
105869 switch ($lang = strtolower($lang)) {
105870 case 'uni':
105871 case 'neutral':
105872 self::$language = $lang;
105873 
105874 return true;
105875 }
105876 
105877 return false;
105878 }
105879 
105880 public static function mb_list_encodings()
105881 {
105882 return array('UTF-8');
105883 }
105884 
105885 public static function mb_encoding_aliases($encoding)
105886 {
105887 switch (strtoupper($encoding)) {
105888 case 'UTF8':
105889 case 'UTF-8':
105890 return array('utf8');
105891 }
105892 
105893 return false;
105894 }
105895 
105896 public static function mb_check_encoding($var = null, $encoding = null)
105897 {
105898 if (null === $encoding) {
105899 if (null === $var) {
105900 return false;
105901 }
105902 $encoding = self::$internalEncoding;
105903 }
105904 
105905 return self::mb_detect_encoding($var, array($encoding)) || false !== @iconv($encoding, $encoding, $var);
105906 }
105907 
105908 public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
105909 {
105910 if (null === $encodingList) {
105911 $encodingList = self::$encodingList;
105912 } else {
105913 if (!\is_array($encodingList)) {
105914 $encodingList = array_map('trim', explode(',', $encodingList));
105915 }
105916 $encodingList = array_map('strtoupper', $encodingList);
105917 }
105918 
105919 foreach ($encodingList as $enc) {
105920 switch ($enc) {
105921 case 'ASCII':
105922 if (!preg_match('/[\x80-\xFF]/', $str)) {
105923 return $enc;
105924 }
105925 break;
105926 
105927 case 'UTF8':
105928 case 'UTF-8':
105929 if (preg_match('//u', $str)) {
105930 return 'UTF-8';
105931 }
105932 break;
105933 
105934 default:
105935 if (0 === strncmp($enc, 'ISO-8859-', 9)) {
105936 return $enc;
105937 }
105938 }
105939 }
105940 
105941 return false;
105942 }
105943 
105944 public static function mb_detect_order($encodingList = null)
105945 {
105946 if (null === $encodingList) {
105947 return self::$encodingList;
105948 }
105949 
105950 if (!\is_array($encodingList)) {
105951 $encodingList = array_map('trim', explode(',', $encodingList));
105952 }
105953 $encodingList = array_map('strtoupper', $encodingList);
105954 
105955 foreach ($encodingList as $enc) {
105956 switch ($enc) {
105957 default:
105958 if (strncmp($enc, 'ISO-8859-', 9)) {
105959 return false;
105960 }
105961 
105962 case 'ASCII':
105963 case 'UTF8':
105964 case 'UTF-8':
105965 }
105966 }
105967 
105968 self::$encodingList = $encodingList;
105969 
105970 return true;
105971 }
105972 
105973 public static function mb_strlen($s, $encoding = null)
105974 {
105975 $encoding = self::getEncoding($encoding);
105976 if ('CP850' === $encoding || 'ASCII' === $encoding) {
105977 return \strlen($s);
105978 }
105979 
105980 return @iconv_strlen($s, $encoding);
105981 }
105982 
105983 public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
105984 {
105985 $encoding = self::getEncoding($encoding);
105986 if ('CP850' === $encoding || 'ASCII' === $encoding) {
105987 return strpos($haystack, $needle, $offset);
105988 }
105989 
105990 $needle = (string) $needle;
105991 if ('' === $needle) {
105992 trigger_error(__METHOD__.': Empty delimiter', E_USER_WARNING);
105993 
105994 return false;
105995 }
105996 
105997 return iconv_strpos($haystack, $needle, $offset, $encoding);
105998 }
105999 
106000 public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
106001 {
106002 $encoding = self::getEncoding($encoding);
106003 if ('CP850' === $encoding || 'ASCII' === $encoding) {
106004 return strrpos($haystack, $needle, $offset);
106005 }
106006 
106007 if ($offset != (int) $offset) {
106008 $offset = 0;
106009 } elseif ($offset = (int) $offset) {
106010 if ($offset < 0) {
106011 if (0 > $offset += self::mb_strlen($needle)) {
106012 $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
106013 }
106014 $offset = 0;
106015 } else {
106016 $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
106017 }
106018 }
106019 
106020 $pos = iconv_strrpos($haystack, $needle, $encoding);
106021 
106022 return false !== $pos ? $offset + $pos : false;
106023 }
106024 
106025 public static function mb_str_split($string, $split_length = 1, $encoding = null)
106026 {
106027 if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
106028 trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', E_USER_WARNING);
106029 
106030 return null;
106031 }
106032 
106033 if (1 > $split_length = (int) $split_length) {
106034 trigger_error('The length of each segment must be greater than zero', E_USER_WARNING);
106035 
106036 return false;
106037 }
106038 
106039 if (null === $encoding) {
106040 $encoding = mb_internal_encoding();
106041 }
106042 
106043 if ('UTF-8' === $encoding = self::getEncoding($encoding)) {
106044 $rx = '/(';
106045 while (65535 < $split_length) {
106046 $rx .= '.{65535}';
106047 $split_length -= 65535;
106048 }
106049 $rx .= '.{'.$split_length.'})/us';
106050 
106051 return preg_split($rx, $string, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
106052 }
106053 
106054 $result = array();
106055 $length = mb_strlen($string, $encoding);
106056 
106057 for ($i = 0; $i < $length; $i += $split_length) {
106058 $result[] = mb_substr($string, $i, $split_length, $encoding);
106059 }
106060 
106061 return $result;
106062 }
106063 
106064 public static function mb_strtolower($s, $encoding = null)
106065 {
106066 return self::mb_convert_case($s, MB_CASE_LOWER, $encoding);
106067 }
106068 
106069 public static function mb_strtoupper($s, $encoding = null)
106070 {
106071 return self::mb_convert_case($s, MB_CASE_UPPER, $encoding);
106072 }
106073 
106074 public static function mb_substitute_character($c = null)
106075 {
106076 if (0 === strcasecmp($c, 'none')) {
106077 return true;
106078 }
106079 
106080 return null !== $c ? false : 'none';
106081 }
106082 
106083 public static function mb_substr($s, $start, $length = null, $encoding = null)
106084 {
106085 $encoding = self::getEncoding($encoding);
106086 if ('CP850' === $encoding || 'ASCII' === $encoding) {
106087 return (string) substr($s, $start, null === $length ? 2147483647 : $length);
106088 }
106089 
106090 if ($start < 0) {
106091 $start = iconv_strlen($s, $encoding) + $start;
106092 if ($start < 0) {
106093 $start = 0;
106094 }
106095 }
106096 
106097 if (null === $length) {
106098 $length = 2147483647;
106099 } elseif ($length < 0) {
106100 $length = iconv_strlen($s, $encoding) + $length - $start;
106101 if ($length < 0) {
106102 return '';
106103 }
106104 }
106105 
106106 return (string) iconv_substr($s, $start, $length, $encoding);
106107 }
106108 
106109 public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
106110 {
106111 $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
106112 $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
106113 
106114 return self::mb_strpos($haystack, $needle, $offset, $encoding);
106115 }
106116 
106117 public static function mb_stristr($haystack, $needle, $part = false, $encoding = null)
106118 {
106119 $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
106120 
106121 return self::getSubpart($pos, $part, $haystack, $encoding);
106122 }
106123 
106124 public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null)
106125 {
106126 $encoding = self::getEncoding($encoding);
106127 if ('CP850' === $encoding || 'ASCII' === $encoding) {
106128 $pos = strrpos($haystack, $needle);
106129 } else {
106130 $needle = self::mb_substr($needle, 0, 1, $encoding);
106131 $pos = iconv_strrpos($haystack, $needle, $encoding);
106132 }
106133 
106134 return self::getSubpart($pos, $part, $haystack, $encoding);
106135 }
106136 
106137 public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null)
106138 {
106139 $needle = self::mb_substr($needle, 0, 1, $encoding);
106140 $pos = self::mb_strripos($haystack, $needle, $encoding);
106141 
106142 return self::getSubpart($pos, $part, $haystack, $encoding);
106143 }
106144 
106145 public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
106146 {
106147 $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
106148 $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
106149 
106150 return self::mb_strrpos($haystack, $needle, $offset, $encoding);
106151 }
106152 
106153 public static function mb_strstr($haystack, $needle, $part = false, $encoding = null)
106154 {
106155 $pos = strpos($haystack, $needle);
106156 if (false === $pos) {
106157 return false;
106158 }
106159 if ($part) {
106160 return substr($haystack, 0, $pos);
106161 }
106162 
106163 return substr($haystack, $pos);
106164 }
106165 
106166 public static function mb_get_info($type = 'all')
106167 {
106168 $info = array(
106169 'internal_encoding' => self::$internalEncoding,
106170 'http_output' => 'pass',
106171 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)',
106172 'func_overload' => 0,
106173 'func_overload_list' => 'no overload',
106174 'mail_charset' => 'UTF-8',
106175 'mail_header_encoding' => 'BASE64',
106176 'mail_body_encoding' => 'BASE64',
106177 'illegal_chars' => 0,
106178 'encoding_translation' => 'Off',
106179 'language' => self::$language,
106180 'detect_order' => self::$encodingList,
106181 'substitute_character' => 'none',
106182 'strict_detection' => 'Off',
106183 );
106184 
106185 if ('all' === $type) {
106186 return $info;
106187 }
106188 if (isset($info[$type])) {
106189 return $info[$type];
106190 }
106191 
106192 return false;
106193 }
106194 
106195 public static function mb_http_input($type = '')
106196 {
106197 return false;
106198 }
106199 
106200 public static function mb_http_output($encoding = null)
106201 {
106202 return null !== $encoding ? 'pass' === $encoding : 'pass';
106203 }
106204 
106205 public static function mb_strwidth($s, $encoding = null)
106206 {
106207 $encoding = self::getEncoding($encoding);
106208 
106209 if ('UTF-8' !== $encoding) {
106210 $s = iconv($encoding, 'UTF-8//IGNORE', $s);
106211 }
106212 
106213 $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
106214 
106215 return ($wide << 1) + iconv_strlen($s, 'UTF-8');
106216 }
106217 
106218 public static function mb_substr_count($haystack, $needle, $encoding = null)
106219 {
106220 return substr_count($haystack, $needle);
106221 }
106222 
106223 public static function mb_output_handler($contents, $status)
106224 {
106225 return $contents;
106226 }
106227 
106228 public static function mb_chr($code, $encoding = null)
106229 {
106230 if (0x80 > $code %= 0x200000) {
106231 $s = \chr($code);
106232 } elseif (0x800 > $code) {
106233 $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
106234 } elseif (0x10000 > $code) {
106235 $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
106236 } else {
106237 $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
106238 }
106239 
106240 if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
106241 $s = mb_convert_encoding($s, $encoding, 'UTF-8');
106242 }
106243 
106244 return $s;
106245 }
106246 
106247 public static function mb_ord($s, $encoding = null)
106248 {
106249 if ('UTF-8' !== $encoding = self::getEncoding($encoding)) {
106250 $s = mb_convert_encoding($s, 'UTF-8', $encoding);
106251 }
106252 
106253 if (1 === \strlen($s)) {
106254 return \ord($s);
106255 }
106256 
106257 $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
106258 if (0xF0 <= $code) {
106259 return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
106260 }
106261 if (0xE0 <= $code) {
106262 return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
106263 }
106264 if (0xC0 <= $code) {
106265 return (($code - 0xC0) << 6) + $s[2] - 0x80;
106266 }
106267 
106268 return $code;
106269 }
106270 
106271 private static function getSubpart($pos, $part, $haystack, $encoding)
106272 {
106273 if (false === $pos) {
106274 return false;
106275 }
106276 if ($part) {
106277 return self::mb_substr($haystack, 0, $pos, $encoding);
106278 }
106279 
106280 return self::mb_substr($haystack, $pos, null, $encoding);
106281 }
106282 
106283 private static function html_encoding_callback(array $m)
106284 {
106285 $i = 1;
106286 $entities = '';
106287 $m = unpack('C*', htmlentities($m[0], ENT_COMPAT, 'UTF-8'));
106288 
106289 while (isset($m[$i])) {
106290 if (0x80 > $m[$i]) {
106291 $entities .= \chr($m[$i++]);
106292 continue;
106293 }
106294 if (0xF0 <= $m[$i]) {
106295 $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
106296 } elseif (0xE0 <= $m[$i]) {
106297 $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80;
106298 } else {
106299 $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80;
106300 }
106301 
106302 $entities .= '&#'.$c.';';
106303 }
106304 
106305 return $entities;
106306 }
106307 
106308 private static function title_case(array $s)
106309 {
106310 return self::mb_convert_case($s[1], MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], MB_CASE_LOWER, 'UTF-8');
106311 }
106312 
106313 private static function getData($file)
106314 {
106315 if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
106316 return require $file;
106317 }
106318 
106319 return false;
106320 }
106321 
106322 private static function getEncoding($encoding)
106323 {
106324 if (null === $encoding) {
106325 return self::$internalEncoding;
106326 }
106327 
106328 if ('UTF-8' === $encoding) {
106329 return 'UTF-8';
106330 }
106331 
106332 $encoding = strtoupper($encoding);
106333 
106334 if ('8BIT' === $encoding || 'BINARY' === $encoding) {
106335 return 'CP850';
106336 }
106337 
106338 if ('UTF8' === $encoding) {
106339 return 'UTF-8';
106340 }
106341 
106342 return $encoding;
106343 }
106344 }
106345 <?php
106346 
106347 
106348 
106349 
106350 
106351 
106352 
106353 
106354 
106355 
106356 use Symfony\Polyfill\Mbstring as p;
106357 
106358 if (!function_exists('mb_convert_variables')) {
106359 
106360 
106361 
106362 function mb_convert_variables($to_encoding, $from_encoding, &$var, &...$vars)
106363 {
106364 $vars = [&$var, ...$vars];
106365 
106366 $ok = true;
106367 array_walk_recursive($vars, function (&$v) use (&$ok, $to_encoding, $from_encoding) {
106368 if (false === $v = p\Mbstring::mb_convert_encoding($v, $to_encoding, $from_encoding)) {
106369 $ok = false;
106370 }
106371 });
106372 
106373 return $ok ? $from_encoding : false;
106374 }
106375 }
106376 <?php
106377 
106378 return array (
106379 'A' => 'a',
106380 'B' => 'b',
106381 'C' => 'c',
106382 'D' => 'd',
106383 'E' => 'e',
106384 'F' => 'f',
106385 'G' => 'g',
106386 'H' => 'h',
106387 'I' => 'i',
106388 'J' => 'j',
106389 'K' => 'k',
106390 'L' => 'l',
106391 'M' => 'm',
106392 'N' => 'n',
106393 'O' => 'o',
106394 'P' => 'p',
106395 'Q' => 'q',
106396 'R' => 'r',
106397 'S' => 's',
106398 'T' => 't',
106399 'U' => 'u',
106400 'V' => 'v',
106401 'W' => 'w',
106402 'X' => 'x',
106403 'Y' => 'y',
106404 'Z' => 'z',
106405 'À' => 'à',
106406 'Á' => 'á',
106407 'Â' => 'â',
106408 'Ã' => 'ã',
106409 'Ä' => 'ä',
106410 'Å' => 'å',
106411 'Æ' => 'æ',
106412 'Ç' => 'ç',
106413 'È' => 'è',
106414 'É' => 'é',
106415 'Ê' => 'ê',
106416 'Ë' => 'ë',
106417 'Ì' => 'ì',
106418 'Í' => 'í',
106419 'Î' => 'î',
106420 'Ï' => 'ï',
106421 'Ð' => 'ð',
106422 'Ñ' => 'ñ',
106423 'Ò' => 'ò',
106424 'Ó' => 'ó',
106425 'Ô' => 'ô',
106426 'Õ' => 'õ',
106427 'Ö' => 'ö',
106428 'Ø' => 'ø',
106429 'Ù' => 'ù',
106430 'Ú' => 'ú',
106431 'Û' => 'û',
106432 'Ü' => 'ü',
106433 'Ý' => 'ý',
106434 'Þ' => 'þ',
106435 'Ā' => 'ā',
106436 'Ă' => 'ă',
106437 'Ą' => 'ą',
106438 'Ć' => 'ć',
106439 'Ĉ' => 'ĉ',
106440 'Ċ' => 'ċ',
106441 'Č' => 'č',
106442 'Ď' => 'ď',
106443 'Đ' => 'đ',
106444 'Ē' => 'ē',
106445 'Ĕ' => 'ĕ',
106446 'Ė' => 'ė',
106447 'Ę' => 'ę',
106448 'Ě' => 'ě',
106449 'Ĝ' => 'ĝ',
106450 'Ğ' => 'ğ',
106451 'Ġ' => 'ġ',
106452 'Ģ' => 'ģ',
106453 'Ĥ' => 'ĥ',
106454 'Ħ' => 'ħ',
106455 'Ĩ' => 'ĩ',
106456 'Ī' => 'ī',
106457 'Ĭ' => 'ĭ',
106458 'Į' => 'į',
106459 'İ' => 'i',
106460 'IJ' => 'ij',
106461 'Ĵ' => 'ĵ',
106462 'Ķ' => 'ķ',
106463 'Ĺ' => 'ĺ',
106464 'Ļ' => 'ļ',
106465 'Ľ' => 'ľ',
106466 'Ŀ' => 'ŀ',
106467 'Ł' => 'ł',
106468 'Ń' => 'ń',
106469 'Ņ' => 'ņ',
106470 'Ň' => 'ň',
106471 'Ŋ' => 'ŋ',
106472 'Ō' => 'ō',
106473 'Ŏ' => 'ŏ',
106474 'Ő' => 'ő',
106475 'Œ' => 'œ',
106476 'Ŕ' => 'ŕ',
106477 'Ŗ' => 'ŗ',
106478 'Ř' => 'ř',
106479 'Ś' => 'ś',
106480 'Ŝ' => 'ŝ',
106481 'Ş' => 'ş',
106482 'Š' => 'š',
106483 'Ţ' => 'ţ',
106484 'Ť' => 'ť',
106485 'Ŧ' => 'ŧ',
106486 'Ũ' => 'ũ',
106487 'Ū' => 'ū',
106488 'Ŭ' => 'ŭ',
106489 'Ů' => 'ů',
106490 'Ű' => 'ű',
106491 'Ų' => 'ų',
106492 'Ŵ' => 'ŵ',
106493 'Ŷ' => 'ŷ',
106494 'Ÿ' => 'ÿ',
106495 'Ź' => 'ź',
106496 'Ż' => 'ż',
106497 'Ž' => 'ž',
106498 'Ɓ' => 'ɓ',
106499 'Ƃ' => 'ƃ',
106500 'Ƅ' => 'ƅ',
106501 'Ɔ' => 'ɔ',
106502 'Ƈ' => 'ƈ',
106503 'Ɖ' => 'ɖ',
106504 'Ɗ' => 'ɗ',
106505 'Ƌ' => 'ƌ',
106506 'Ǝ' => 'ǝ',
106507 'Ə' => 'ə',
106508 'Ɛ' => 'ɛ',
106509 'Ƒ' => 'ƒ',
106510 'Ɠ' => 'ɠ',
106511 'Ɣ' => 'ɣ',
106512 'Ɩ' => 'ɩ',
106513 'Ɨ' => 'ɨ',
106514 'Ƙ' => 'ƙ',
106515 'Ɯ' => 'ɯ',
106516 'Ɲ' => 'ɲ',
106517 'Ɵ' => 'ɵ',
106518 'Ơ' => 'ơ',
106519 'Ƣ' => 'ƣ',
106520 'Ƥ' => 'ƥ',
106521 'Ʀ' => 'ʀ',
106522 'Ƨ' => 'ƨ',
106523 'Ʃ' => 'ʃ',
106524 'Ƭ' => 'ƭ',
106525 'Ʈ' => 'ʈ',
106526 'Ư' => 'ư',
106527 'Ʊ' => 'ʊ',
106528 'Ʋ' => 'ʋ',
106529 'Ƴ' => 'ƴ',
106530 'Ƶ' => 'ƶ',
106531 'Ʒ' => 'ʒ',
106532 'Ƹ' => 'ƹ',
106533 'Ƽ' => 'ƽ',
106534 'DŽ' => 'dž',
106535 'Dž' => 'dž',
106536 'LJ' => 'lj',
106537 'Lj' => 'lj',
106538 'NJ' => 'nj',
106539 'Nj' => 'nj',
106540 'Ǎ' => 'ǎ',
106541 'Ǐ' => 'ǐ',
106542 'Ǒ' => 'ǒ',
106543 'Ǔ' => 'ǔ',
106544 'Ǖ' => 'ǖ',
106545 'Ǘ' => 'ǘ',
106546 'Ǚ' => 'ǚ',
106547 'Ǜ' => 'ǜ',
106548 'Ǟ' => 'ǟ',
106549 'Ǡ' => 'ǡ',
106550 'Ǣ' => 'ǣ',
106551 'Ǥ' => 'ǥ',
106552 'Ǧ' => 'ǧ',
106553 'Ǩ' => 'ǩ',
106554 'Ǫ' => 'ǫ',
106555 'Ǭ' => 'ǭ',
106556 'Ǯ' => 'ǯ',
106557 'DZ' => 'dz',
106558 'Dz' => 'dz',
106559 'Ǵ' => 'ǵ',
106560 'Ƕ' => 'ƕ',
106561 'Ƿ' => 'ƿ',
106562 'Ǹ' => 'ǹ',
106563 'Ǻ' => 'ǻ',
106564 'Ǽ' => 'ǽ',
106565 'Ǿ' => 'ǿ',
106566 'Ȁ' => 'ȁ',
106567 'Ȃ' => 'ȃ',
106568 'Ȅ' => 'ȅ',
106569 'Ȇ' => 'ȇ',
106570 'Ȉ' => 'ȉ',
106571 'Ȋ' => 'ȋ',
106572 'Ȍ' => 'ȍ',
106573 'Ȏ' => 'ȏ',
106574 'Ȑ' => 'ȑ',
106575 'Ȓ' => 'ȓ',
106576 'Ȕ' => 'ȕ',
106577 'Ȗ' => 'ȗ',
106578 'Ș' => 'ș',
106579 'Ț' => 'ț',
106580 'Ȝ' => 'ȝ',
106581 'Ȟ' => 'ȟ',
106582 'Ƞ' => 'ƞ',
106583 'Ȣ' => 'ȣ',
106584 'Ȥ' => 'ȥ',
106585 'Ȧ' => 'ȧ',
106586 'Ȩ' => 'ȩ',
106587 'Ȫ' => 'ȫ',
106588 'Ȭ' => 'ȭ',
106589 'Ȯ' => 'ȯ',
106590 'Ȱ' => 'ȱ',
106591 'Ȳ' => 'ȳ',
106592 'Ⱥ' => 'ⱥ',
106593 'Ȼ' => 'ȼ',
106594 'Ƚ' => 'ƚ',
106595 'Ⱦ' => 'ⱦ',
106596 'Ɂ' => 'ɂ',
106597 'Ƀ' => 'ƀ',
106598 'Ʉ' => 'ʉ',
106599 'Ʌ' => 'ʌ',
106600 'Ɇ' => 'ɇ',
106601 'Ɉ' => 'ɉ',
106602 'Ɋ' => 'ɋ',
106603 'Ɍ' => 'ɍ',
106604 'Ɏ' => 'ɏ',
106605 'Ͱ' => 'ͱ',
106606 'Ͳ' => 'ͳ',
106607 'Ͷ' => 'ͷ',
106608 'Ϳ' => 'ϳ',
106609 'Ά' => 'ά',
106610 'Έ' => 'έ',
106611 'Ή' => 'ή',
106612 'Ί' => 'ί',
106613 'Ό' => 'ό',
106614 'Ύ' => 'ύ',
106615 'Ώ' => 'ώ',
106616 'Α' => 'α',
106617 'Β' => 'β',
106618 'Γ' => 'γ',
106619 'Δ' => 'δ',
106620 'Ε' => 'ε',
106621 'Ζ' => 'ζ',
106622 'Η' => 'η',
106623 'Θ' => 'θ',
106624 'Ι' => 'ι',
106625 'Κ' => 'κ',
106626 'Λ' => 'λ',
106627 'Μ' => 'μ',
106628 'Ν' => 'ν',
106629 'Ξ' => 'ξ',
106630 'Ο' => 'ο',
106631 'Π' => 'π',
106632 'Ρ' => 'ρ',
106633 'Σ' => 'σ',
106634 'Τ' => 'τ',
106635 'Υ' => 'υ',
106636 'Φ' => 'φ',
106637 'Χ' => 'χ',
106638 'Ψ' => 'ψ',
106639 'Ω' => 'ω',
106640 'Ϊ' => 'ϊ',
106641 'Ϋ' => 'ϋ',
106642 'Ϗ' => 'ϗ',
106643 'Ϙ' => 'ϙ',
106644 'Ϛ' => 'ϛ',
106645 'Ϝ' => 'ϝ',
106646 'Ϟ' => 'ϟ',
106647 'Ϡ' => 'ϡ',
106648 'Ϣ' => 'ϣ',
106649 'Ϥ' => 'ϥ',
106650 'Ϧ' => 'ϧ',
106651 'Ϩ' => 'ϩ',
106652 'Ϫ' => 'ϫ',
106653 'Ϭ' => 'ϭ',
106654 'Ϯ' => 'ϯ',
106655 'ϴ' => 'θ',
106656 'Ϸ' => 'ϸ',
106657 'Ϲ' => 'ϲ',
106658 'Ϻ' => 'ϻ',
106659 'Ͻ' => 'ͻ',
106660 'Ͼ' => 'ͼ',
106661 'Ͽ' => 'ͽ',
106662 'Ѐ' => 'ѐ',
106663 'Ё' => 'ё',
106664 'Ђ' => 'ђ',
106665 'Ѓ' => 'ѓ',
106666 'Є' => 'є',
106667 'Ѕ' => 'ѕ',
106668 'І' => 'і',
106669 'Ї' => 'ї',
106670 'Ј' => 'ј',
106671 'Љ' => 'љ',
106672 'Њ' => 'њ',
106673 'Ћ' => 'ћ',
106674 'Ќ' => 'ќ',
106675 'Ѝ' => 'ѝ',
106676 'Ў' => 'ў',
106677 'Џ' => 'џ',
106678 'А' => 'а',
106679 'Б' => 'б',
106680 'В' => 'в',
106681 'Г' => 'г',
106682 'Д' => 'д',
106683 'Е' => 'е',
106684 'Ж' => 'ж',
106685 'З' => 'з',
106686 'И' => 'и',
106687 'Й' => 'й',
106688 'К' => 'к',
106689 'Л' => 'л',
106690 'М' => 'м',
106691 'Н' => 'н',
106692 'О' => 'о',
106693 'П' => 'п',
106694 'Р' => 'р',
106695 'С' => 'с',
106696 'Т' => 'т',
106697 'У' => 'у',
106698 'Ф' => 'ф',
106699 'Х' => 'х',
106700 'Ц' => 'ц',
106701 'Ч' => 'ч',
106702 'Ш' => 'ш',
106703 'Щ' => 'щ',
106704 'Ъ' => 'ъ',
106705 'Ы' => 'ы',
106706 'Ь' => 'ь',
106707 'Э' => 'э',
106708 'Ю' => 'ю',
106709 'Я' => 'я',
106710 'Ѡ' => 'ѡ',
106711 'Ѣ' => 'ѣ',
106712 'Ѥ' => 'ѥ',
106713 'Ѧ' => 'ѧ',
106714 'Ѩ' => 'ѩ',
106715 'Ѫ' => 'ѫ',
106716 'Ѭ' => 'ѭ',
106717 'Ѯ' => 'ѯ',
106718 'Ѱ' => 'ѱ',
106719 'Ѳ' => 'ѳ',
106720 'Ѵ' => 'ѵ',
106721 'Ѷ' => 'ѷ',
106722 'Ѹ' => 'ѹ',
106723 'Ѻ' => 'ѻ',
106724 'Ѽ' => 'ѽ',
106725 'Ѿ' => 'ѿ',
106726 'Ҁ' => 'ҁ',
106727 'Ҋ' => 'ҋ',
106728 'Ҍ' => 'ҍ',
106729 'Ҏ' => 'ҏ',
106730 'Ґ' => 'ґ',
106731 'Ғ' => 'ғ',
106732 'Ҕ' => 'ҕ',
106733 'Җ' => 'җ',
106734 'Ҙ' => 'ҙ',
106735 'Қ' => 'қ',
106736 'Ҝ' => 'ҝ',
106737 'Ҟ' => 'ҟ',
106738 'Ҡ' => 'ҡ',
106739 'Ң' => 'ң',
106740 'Ҥ' => 'ҥ',
106741 'Ҧ' => 'ҧ',
106742 'Ҩ' => 'ҩ',
106743 'Ҫ' => 'ҫ',
106744 'Ҭ' => 'ҭ',
106745 'Ү' => 'ү',
106746 'Ұ' => 'ұ',
106747 'Ҳ' => 'ҳ',
106748 'Ҵ' => 'ҵ',
106749 'Ҷ' => 'ҷ',
106750 'Ҹ' => 'ҹ',
106751 'Һ' => 'һ',
106752 'Ҽ' => 'ҽ',
106753 'Ҿ' => 'ҿ',
106754 'Ӏ' => 'ӏ',
106755 'Ӂ' => 'ӂ',
106756 'Ӄ' => 'ӄ',
106757 'Ӆ' => 'ӆ',
106758 'Ӈ' => 'ӈ',
106759 'Ӊ' => 'ӊ',
106760 'Ӌ' => 'ӌ',
106761 'Ӎ' => 'ӎ',
106762 'Ӑ' => 'ӑ',
106763 'Ӓ' => 'ӓ',
106764 'Ӕ' => 'ӕ',
106765 'Ӗ' => 'ӗ',
106766 'Ә' => 'ә',
106767 'Ӛ' => 'ӛ',
106768 'Ӝ' => 'ӝ',
106769 'Ӟ' => 'ӟ',
106770 'Ӡ' => 'ӡ',
106771 'Ӣ' => 'ӣ',
106772 'Ӥ' => 'ӥ',
106773 'Ӧ' => 'ӧ',
106774 'Ө' => 'ө',
106775 'Ӫ' => 'ӫ',
106776 'Ӭ' => 'ӭ',
106777 'Ӯ' => 'ӯ',
106778 'Ӱ' => 'ӱ',
106779 'Ӳ' => 'ӳ',
106780 'Ӵ' => 'ӵ',
106781 'Ӷ' => 'ӷ',
106782 'Ӹ' => 'ӹ',
106783 'Ӻ' => 'ӻ',
106784 'Ӽ' => 'ӽ',
106785 'Ӿ' => 'ӿ',
106786 'Ԁ' => 'ԁ',
106787 'Ԃ' => 'ԃ',
106788 'Ԅ' => 'ԅ',
106789 'Ԇ' => 'ԇ',
106790 'Ԉ' => 'ԉ',
106791 'Ԋ' => 'ԋ',
106792 'Ԍ' => 'ԍ',
106793 'Ԏ' => 'ԏ',
106794 'Ԑ' => 'ԑ',
106795 'Ԓ' => 'ԓ',
106796 'Ԕ' => 'ԕ',
106797 'Ԗ' => 'ԗ',
106798 'Ԙ' => 'ԙ',
106799 'Ԛ' => 'ԛ',
106800 'Ԝ' => 'ԝ',
106801 'Ԟ' => 'ԟ',
106802 'Ԡ' => 'ԡ',
106803 'Ԣ' => 'ԣ',
106804 'Ԥ' => 'ԥ',
106805 'Ԧ' => 'ԧ',
106806 'Ԩ' => 'ԩ',
106807 'Ԫ' => 'ԫ',
106808 'Ԭ' => 'ԭ',
106809 'Ԯ' => 'ԯ',
106810 'Ա' => 'ա',
106811 'Բ' => 'բ',
106812 'Գ' => 'գ',
106813 'Դ' => 'դ',
106814 'Ե' => 'ե',
106815 'Զ' => 'զ',
106816 'Է' => 'է',
106817 'Ը' => 'ը',
106818 'Թ' => 'թ',
106819 'Ժ' => 'ժ',
106820 'Ի' => 'ի',
106821 'Լ' => 'լ',
106822 'Խ' => 'խ',
106823 'Ծ' => 'ծ',
106824 'Կ' => 'կ',
106825 'Հ' => 'հ',
106826 'Ձ' => 'ձ',
106827 'Ղ' => 'ղ',
106828 'Ճ' => 'ճ',
106829 'Մ' => 'մ',
106830 'Յ' => 'յ',
106831 'Ն' => 'ն',
106832 'Շ' => 'շ',
106833 'Ո' => 'ո',
106834 'Չ' => 'չ',
106835 'Պ' => 'պ',
106836 'Ջ' => 'ջ',
106837 'Ռ' => 'ռ',
106838 'Ս' => 'ս',
106839 'Վ' => 'վ',
106840 'Տ' => 'տ',
106841 'Ր' => 'ր',
106842 'Ց' => 'ց',
106843 'Ւ' => 'ւ',
106844 'Փ' => 'փ',
106845 'Ք' => 'ք',
106846 'Օ' => 'օ',
106847 'Ֆ' => 'ֆ',
106848 'Ⴀ' => 'ⴀ',
106849 'Ⴁ' => 'ⴁ',
106850 'Ⴂ' => 'ⴂ',
106851 'Ⴃ' => 'ⴃ',
106852 'Ⴄ' => 'ⴄ',
106853 'Ⴅ' => 'ⴅ',
106854 'Ⴆ' => 'ⴆ',
106855 'Ⴇ' => 'ⴇ',
106856 'Ⴈ' => 'ⴈ',
106857 'Ⴉ' => 'ⴉ',
106858 'Ⴊ' => 'ⴊ',
106859 'Ⴋ' => 'ⴋ',
106860 'Ⴌ' => 'ⴌ',
106861 'Ⴍ' => 'ⴍ',
106862 'Ⴎ' => 'ⴎ',
106863 'Ⴏ' => 'ⴏ',
106864 'Ⴐ' => 'ⴐ',
106865 'Ⴑ' => 'ⴑ',
106866 'Ⴒ' => 'ⴒ',
106867 'Ⴓ' => 'ⴓ',
106868 'Ⴔ' => 'ⴔ',
106869 'Ⴕ' => 'ⴕ',
106870 'Ⴖ' => 'ⴖ',
106871 'Ⴗ' => 'ⴗ',
106872 'Ⴘ' => 'ⴘ',
106873 'Ⴙ' => 'ⴙ',
106874 'Ⴚ' => 'ⴚ',
106875 'Ⴛ' => 'ⴛ',
106876 'Ⴜ' => 'ⴜ',
106877 'Ⴝ' => 'ⴝ',
106878 'Ⴞ' => 'ⴞ',
106879 'Ⴟ' => 'ⴟ',
106880 'Ⴠ' => 'ⴠ',
106881 'Ⴡ' => 'ⴡ',
106882 'Ⴢ' => 'ⴢ',
106883 'Ⴣ' => 'ⴣ',
106884 'Ⴤ' => 'ⴤ',
106885 'Ⴥ' => 'ⴥ',
106886 'Ⴧ' => 'ⴧ',
106887 'Ⴭ' => 'ⴭ',
106888 'Ꭰ' => 'ꭰ',
106889 'Ꭱ' => 'ꭱ',
106890 'Ꭲ' => 'ꭲ',
106891 'Ꭳ' => 'ꭳ',
106892 'Ꭴ' => 'ꭴ',
106893 'Ꭵ' => 'ꭵ',
106894 'Ꭶ' => 'ꭶ',
106895 'Ꭷ' => 'ꭷ',
106896 'Ꭸ' => 'ꭸ',
106897 'Ꭹ' => 'ꭹ',
106898 'Ꭺ' => 'ꭺ',
106899 'Ꭻ' => 'ꭻ',
106900 'Ꭼ' => 'ꭼ',
106901 'Ꭽ' => 'ꭽ',
106902 'Ꭾ' => 'ꭾ',
106903 'Ꭿ' => 'ꭿ',
106904 'Ꮀ' => 'ꮀ',
106905 'Ꮁ' => 'ꮁ',
106906 'Ꮂ' => 'ꮂ',
106907 'Ꮃ' => 'ꮃ',
106908 'Ꮄ' => 'ꮄ',
106909 'Ꮅ' => 'ꮅ',
106910 'Ꮆ' => 'ꮆ',
106911 'Ꮇ' => 'ꮇ',
106912 'Ꮈ' => 'ꮈ',
106913 'Ꮉ' => 'ꮉ',
106914 'Ꮊ' => 'ꮊ',
106915 'Ꮋ' => 'ꮋ',
106916 'Ꮌ' => 'ꮌ',
106917 'Ꮍ' => 'ꮍ',
106918 'Ꮎ' => 'ꮎ',
106919 'Ꮏ' => 'ꮏ',
106920 'Ꮐ' => 'ꮐ',
106921 'Ꮑ' => 'ꮑ',
106922 'Ꮒ' => 'ꮒ',
106923 'Ꮓ' => 'ꮓ',
106924 'Ꮔ' => 'ꮔ',
106925 'Ꮕ' => 'ꮕ',
106926 'Ꮖ' => 'ꮖ',
106927 'Ꮗ' => 'ꮗ',
106928 'Ꮘ' => 'ꮘ',
106929 'Ꮙ' => 'ꮙ',
106930 'Ꮚ' => 'ꮚ',
106931 'Ꮛ' => 'ꮛ',
106932 'Ꮜ' => 'ꮜ',
106933 'Ꮝ' => 'ꮝ',
106934 'Ꮞ' => 'ꮞ',
106935 'Ꮟ' => 'ꮟ',
106936 'Ꮠ' => 'ꮠ',
106937 'Ꮡ' => 'ꮡ',
106938 'Ꮢ' => 'ꮢ',
106939 'Ꮣ' => 'ꮣ',
106940 'Ꮤ' => 'ꮤ',
106941 'Ꮥ' => 'ꮥ',
106942 'Ꮦ' => 'ꮦ',
106943 'Ꮧ' => 'ꮧ',
106944 'Ꮨ' => 'ꮨ',
106945 'Ꮩ' => 'ꮩ',
106946 'Ꮪ' => 'ꮪ',
106947 'Ꮫ' => 'ꮫ',
106948 'Ꮬ' => 'ꮬ',
106949 'Ꮭ' => 'ꮭ',
106950 'Ꮮ' => 'ꮮ',
106951 'Ꮯ' => 'ꮯ',
106952 'Ꮰ' => 'ꮰ',
106953 'Ꮱ' => 'ꮱ',
106954 'Ꮲ' => 'ꮲ',
106955 'Ꮳ' => 'ꮳ',
106956 'Ꮴ' => 'ꮴ',
106957 'Ꮵ' => 'ꮵ',
106958 'Ꮶ' => 'ꮶ',
106959 'Ꮷ' => 'ꮷ',
106960 'Ꮸ' => 'ꮸ',
106961 'Ꮹ' => 'ꮹ',
106962 'Ꮺ' => 'ꮺ',
106963 'Ꮻ' => 'ꮻ',
106964 'Ꮼ' => 'ꮼ',
106965 'Ꮽ' => 'ꮽ',
106966 'Ꮾ' => 'ꮾ',
106967 'Ꮿ' => 'ꮿ',
106968 'Ᏸ' => 'ᏸ',
106969 'Ᏹ' => 'ᏹ',
106970 'Ᏺ' => 'ᏺ',
106971 'Ᏻ' => 'ᏻ',
106972 'Ᏼ' => 'ᏼ',
106973 'Ᏽ' => 'ᏽ',
106974 'Ა' => 'ა',
106975 'Ბ' => 'ბ',
106976 'Გ' => 'გ',
106977 'Დ' => 'დ',
106978 'Ე' => 'ე',
106979 'Ვ' => 'ვ',
106980 'Ზ' => 'ზ',
106981 'Თ' => 'თ',
106982 'Ი' => 'ი',
106983 'Კ' => 'კ',
106984 'Ლ' => 'ლ',
106985 'Მ' => 'მ',
106986 'Ნ' => 'ნ',
106987 'Ო' => 'ო',
106988 'Პ' => 'პ',
106989 'Ჟ' => 'ჟ',
106990 'Რ' => 'რ',
106991 'Ს' => 'ს',
106992 'Ტ' => 'ტ',
106993 'Უ' => 'უ',
106994 'Ფ' => 'ფ',
106995 'Ქ' => 'ქ',
106996 'Ღ' => 'ღ',
106997 'Ყ' => 'ყ',
106998 'Შ' => 'შ',
106999 'Ჩ' => 'ჩ',
107000 'Ც' => 'ც',
107001 'Ძ' => 'ძ',
107002 'Წ' => 'წ',
107003 'Ჭ' => 'ჭ',
107004 'Ხ' => 'ხ',
107005 'Ჯ' => 'ჯ',
107006 'Ჰ' => 'ჰ',
107007 'Ჱ' => 'ჱ',
107008 'Ჲ' => 'ჲ',
107009 'Ჳ' => 'ჳ',
107010 'Ჴ' => 'ჴ',
107011 'Ჵ' => 'ჵ',
107012 'Ჶ' => 'ჶ',
107013 'Ჷ' => 'ჷ',
107014 'Ჸ' => 'ჸ',
107015 'Ჹ' => 'ჹ',
107016 'Ჺ' => 'ჺ',
107017 'Ჽ' => 'ჽ',
107018 'Ჾ' => 'ჾ',
107019 'Ჿ' => 'ჿ',
107020 'Ḁ' => 'ḁ',
107021 'Ḃ' => 'ḃ',
107022 'Ḅ' => 'ḅ',
107023 'Ḇ' => 'ḇ',
107024 'Ḉ' => 'ḉ',
107025 'Ḋ' => 'ḋ',
107026 'Ḍ' => 'ḍ',
107027 'Ḏ' => 'ḏ',
107028 'Ḑ' => 'ḑ',
107029 'Ḓ' => 'ḓ',
107030 'Ḕ' => 'ḕ',
107031 'Ḗ' => 'ḗ',
107032 'Ḙ' => 'ḙ',
107033 'Ḛ' => 'ḛ',
107034 'Ḝ' => 'ḝ',
107035 'Ḟ' => 'ḟ',
107036 'Ḡ' => 'ḡ',
107037 'Ḣ' => 'ḣ',
107038 'Ḥ' => 'ḥ',
107039 'Ḧ' => 'ḧ',
107040 'Ḩ' => 'ḩ',
107041 'Ḫ' => 'ḫ',
107042 'Ḭ' => 'ḭ',
107043 'Ḯ' => 'ḯ',
107044 'Ḱ' => 'ḱ',
107045 'Ḳ' => 'ḳ',
107046 'Ḵ' => 'ḵ',
107047 'Ḷ' => 'ḷ',
107048 'Ḹ' => 'ḹ',
107049 'Ḻ' => 'ḻ',
107050 'Ḽ' => 'ḽ',
107051 'Ḿ' => 'ḿ',
107052 'Ṁ' => 'ṁ',
107053 'Ṃ' => 'ṃ',
107054 'Ṅ' => 'ṅ',
107055 'Ṇ' => 'ṇ',
107056 'Ṉ' => 'ṉ',
107057 'Ṋ' => 'ṋ',
107058 'Ṍ' => 'ṍ',
107059 'Ṏ' => 'ṏ',
107060 'Ṑ' => 'ṑ',
107061 'Ṓ' => 'ṓ',
107062 'Ṕ' => 'ṕ',
107063 'Ṗ' => 'ṗ',
107064 'Ṙ' => 'ṙ',
107065 'Ṛ' => 'ṛ',
107066 'Ṝ' => 'ṝ',
107067 'Ṟ' => 'ṟ',
107068 'Ṡ' => 'ṡ',
107069 'Ṣ' => 'ṣ',
107070 'Ṥ' => 'ṥ',
107071 'Ṧ' => 'ṧ',
107072 'Ṩ' => 'ṩ',
107073 'Ṫ' => 'ṫ',
107074 'Ṭ' => 'ṭ',
107075 'Ṯ' => 'ṯ',
107076 'Ṱ' => 'ṱ',
107077 'Ṳ' => 'ṳ',
107078 'Ṵ' => 'ṵ',
107079 'Ṷ' => 'ṷ',
107080 'Ṹ' => 'ṹ',
107081 'Ṻ' => 'ṻ',
107082 'Ṽ' => 'ṽ',
107083 'Ṿ' => 'ṿ',
107084 'Ẁ' => 'ẁ',
107085 'Ẃ' => 'ẃ',
107086 'Ẅ' => 'ẅ',
107087 'Ẇ' => 'ẇ',
107088 'Ẉ' => 'ẉ',
107089 'Ẋ' => 'ẋ',
107090 'Ẍ' => 'ẍ',
107091 'Ẏ' => 'ẏ',
107092 'Ẑ' => 'ẑ',
107093 'Ẓ' => 'ẓ',
107094 'Ẕ' => 'ẕ',
107095 'ẞ' => 'ß',
107096 'Ạ' => 'ạ',
107097 'Ả' => 'ả',
107098 'Ấ' => 'ấ',
107099 'Ầ' => 'ầ',
107100 'Ẩ' => 'ẩ',
107101 'Ẫ' => 'ẫ',
107102 'Ậ' => 'ậ',
107103 'Ắ' => 'ắ',
107104 'Ằ' => 'ằ',
107105 'Ẳ' => 'ẳ',
107106 'Ẵ' => 'ẵ',
107107 'Ặ' => 'ặ',
107108 'Ẹ' => 'ẹ',
107109 'Ẻ' => 'ẻ',
107110 'Ẽ' => 'ẽ',
107111 'Ế' => 'ế',
107112 'Ề' => 'ề',
107113 'Ể' => 'ể',
107114 'Ễ' => 'ễ',
107115 'Ệ' => 'ệ',
107116 'Ỉ' => 'ỉ',
107117 'Ị' => 'ị',
107118 'Ọ' => 'ọ',
107119 'Ỏ' => 'ỏ',
107120 'Ố' => 'ố',
107121 'Ồ' => 'ồ',
107122 'Ổ' => 'ổ',
107123 'Ỗ' => 'ỗ',
107124 'Ộ' => 'ộ',
107125 'Ớ' => 'ớ',
107126 'Ờ' => 'ờ',
107127 'Ở' => 'ở',
107128 'Ỡ' => 'ỡ',
107129 'Ợ' => 'ợ',
107130 'Ụ' => 'ụ',
107131 'Ủ' => 'ủ',
107132 'Ứ' => 'ứ',
107133 'Ừ' => 'ừ',
107134 'Ử' => 'ử',
107135 'Ữ' => 'ữ',
107136 'Ự' => 'ự',
107137 'Ỳ' => 'ỳ',
107138 'Ỵ' => 'ỵ',
107139 'Ỷ' => 'ỷ',
107140 'Ỹ' => 'ỹ',
107141 'Ỻ' => 'ỻ',
107142 'Ỽ' => 'ỽ',
107143 'Ỿ' => 'ỿ',
107144 'Ἀ' => 'ἀ',
107145 'Ἁ' => 'ἁ',
107146 'Ἂ' => 'ἂ',
107147 'Ἃ' => 'ἃ',
107148 'Ἄ' => 'ἄ',
107149 'Ἅ' => 'ἅ',
107150 'Ἆ' => 'ἆ',
107151 'Ἇ' => 'ἇ',
107152 'Ἐ' => 'ἐ',
107153 'Ἑ' => 'ἑ',
107154 'Ἒ' => 'ἒ',
107155 'Ἓ' => 'ἓ',
107156 'Ἔ' => 'ἔ',
107157 'Ἕ' => 'ἕ',
107158 'Ἠ' => 'ἠ',
107159 'Ἡ' => 'ἡ',
107160 'Ἢ' => 'ἢ',
107161 'Ἣ' => 'ἣ',
107162 'Ἤ' => 'ἤ',
107163 'Ἥ' => 'ἥ',
107164 'Ἦ' => 'ἦ',
107165 'Ἧ' => 'ἧ',
107166 'Ἰ' => 'ἰ',
107167 'Ἱ' => 'ἱ',
107168 'Ἲ' => 'ἲ',
107169 'Ἳ' => 'ἳ',
107170 'Ἴ' => 'ἴ',
107171 'Ἵ' => 'ἵ',
107172 'Ἶ' => 'ἶ',
107173 'Ἷ' => 'ἷ',
107174 'Ὀ' => 'ὀ',
107175 'Ὁ' => 'ὁ',
107176 'Ὂ' => 'ὂ',
107177 'Ὃ' => 'ὃ',
107178 'Ὄ' => 'ὄ',
107179 'Ὅ' => 'ὅ',
107180 'Ὑ' => 'ὑ',
107181 'Ὓ' => 'ὓ',
107182 'Ὕ' => 'ὕ',
107183 'Ὗ' => 'ὗ',
107184 'Ὠ' => 'ὠ',
107185 'Ὡ' => 'ὡ',
107186 'Ὢ' => 'ὢ',
107187 'Ὣ' => 'ὣ',
107188 'Ὤ' => 'ὤ',
107189 'Ὥ' => 'ὥ',
107190 'Ὦ' => 'ὦ',
107191 'Ὧ' => 'ὧ',
107192 'ᾈ' => 'ᾀ',
107193 'ᾉ' => 'ᾁ',
107194 'ᾊ' => 'ᾂ',
107195 'ᾋ' => 'ᾃ',
107196 'ᾌ' => 'ᾄ',
107197 'ᾍ' => 'ᾅ',
107198 'ᾎ' => 'ᾆ',
107199 'ᾏ' => 'ᾇ',
107200 'ᾘ' => 'ᾐ',
107201 'ᾙ' => 'ᾑ',
107202 'ᾚ' => 'ᾒ',
107203 'ᾛ' => 'ᾓ',
107204 'ᾜ' => 'ᾔ',
107205 'ᾝ' => 'ᾕ',
107206 'ᾞ' => 'ᾖ',
107207 'ᾟ' => 'ᾗ',
107208 'ᾨ' => 'ᾠ',
107209 'ᾩ' => 'ᾡ',
107210 'ᾪ' => 'ᾢ',
107211 'ᾫ' => 'ᾣ',
107212 'ᾬ' => 'ᾤ',
107213 'ᾭ' => 'ᾥ',
107214 'ᾮ' => 'ᾦ',
107215 'ᾯ' => 'ᾧ',
107216 'Ᾰ' => 'ᾰ',
107217 'Ᾱ' => 'ᾱ',
107218 'Ὰ' => 'ὰ',
107219 'Ά' => 'ά',
107220 'ᾼ' => 'ᾳ',
107221 'Ὲ' => 'ὲ',
107222 'Έ' => 'έ',
107223 'Ὴ' => 'ὴ',
107224 'Ή' => 'ή',
107225 'ῌ' => 'ῃ',
107226 'Ῐ' => 'ῐ',
107227 'Ῑ' => 'ῑ',
107228 'Ὶ' => 'ὶ',
107229 'Ί' => 'ί',
107230 'Ῠ' => 'ῠ',
107231 'Ῡ' => 'ῡ',
107232 'Ὺ' => 'ὺ',
107233 'Ύ' => 'ύ',
107234 'Ῥ' => 'ῥ',
107235 'Ὸ' => 'ὸ',
107236 'Ό' => 'ό',
107237 'Ὼ' => 'ὼ',
107238 'Ώ' => 'ώ',
107239 'ῼ' => 'ῳ',
107240 'Ω' => 'ω',
107241 'K' => 'k',
107242 'Å' => 'å',
107243 'Ⅎ' => 'ⅎ',
107244 'Ⅰ' => 'ⅰ',
107245 'Ⅱ' => 'ⅱ',
107246 'Ⅲ' => 'ⅲ',
107247 'Ⅳ' => 'ⅳ',
107248 'Ⅴ' => 'ⅴ',
107249 'Ⅵ' => 'ⅵ',
107250 'Ⅶ' => 'ⅶ',
107251 'Ⅷ' => 'ⅷ',
107252 'Ⅸ' => 'ⅸ',
107253 'Ⅹ' => 'ⅹ',
107254 'Ⅺ' => 'ⅺ',
107255 'Ⅻ' => 'ⅻ',
107256 'Ⅼ' => 'ⅼ',
107257 'Ⅽ' => 'ⅽ',
107258 'Ⅾ' => 'ⅾ',
107259 'Ⅿ' => 'ⅿ',
107260 'Ↄ' => 'ↄ',
107261 'Ⓐ' => 'ⓐ',
107262 'Ⓑ' => 'ⓑ',
107263 'Ⓒ' => 'ⓒ',
107264 'Ⓓ' => 'ⓓ',
107265 'Ⓔ' => 'ⓔ',
107266 'Ⓕ' => 'ⓕ',
107267 'Ⓖ' => 'ⓖ',
107268 'Ⓗ' => 'ⓗ',
107269 'Ⓘ' => 'ⓘ',
107270 'Ⓙ' => 'ⓙ',
107271 'Ⓚ' => 'ⓚ',
107272 'Ⓛ' => 'ⓛ',
107273 'Ⓜ' => 'ⓜ',
107274 'Ⓝ' => 'ⓝ',
107275 'Ⓞ' => 'ⓞ',
107276 'Ⓟ' => 'ⓟ',
107277 'Ⓠ' => 'ⓠ',
107278 'Ⓡ' => 'ⓡ',
107279 'Ⓢ' => 'ⓢ',
107280 'Ⓣ' => 'ⓣ',
107281 'Ⓤ' => 'ⓤ',
107282 'Ⓥ' => 'ⓥ',
107283 'Ⓦ' => 'ⓦ',
107284 'Ⓧ' => 'ⓧ',
107285 'Ⓨ' => 'ⓨ',
107286 'Ⓩ' => 'ⓩ',
107287 'Ⰰ' => 'ⰰ',
107288 'Ⰱ' => 'ⰱ',
107289 'Ⰲ' => 'ⰲ',
107290 'Ⰳ' => 'ⰳ',
107291 'Ⰴ' => 'ⰴ',
107292 'Ⰵ' => 'ⰵ',
107293 'Ⰶ' => 'ⰶ',
107294 'Ⰷ' => 'ⰷ',
107295 'Ⰸ' => 'ⰸ',
107296 'Ⰹ' => 'ⰹ',
107297 'Ⰺ' => 'ⰺ',
107298 'Ⰻ' => 'ⰻ',
107299 'Ⰼ' => 'ⰼ',
107300 'Ⰽ' => 'ⰽ',
107301 'Ⰾ' => 'ⰾ',
107302 'Ⰿ' => 'ⰿ',
107303 'Ⱀ' => 'ⱀ',
107304 'Ⱁ' => 'ⱁ',
107305 'Ⱂ' => 'ⱂ',
107306 'Ⱃ' => 'ⱃ',
107307 'Ⱄ' => 'ⱄ',
107308 'Ⱅ' => 'ⱅ',
107309 'Ⱆ' => 'ⱆ',
107310 'Ⱇ' => 'ⱇ',
107311 'Ⱈ' => 'ⱈ',
107312 'Ⱉ' => 'ⱉ',
107313 'Ⱊ' => 'ⱊ',
107314 'Ⱋ' => 'ⱋ',
107315 'Ⱌ' => 'ⱌ',
107316 'Ⱍ' => 'ⱍ',
107317 'Ⱎ' => 'ⱎ',
107318 'Ⱏ' => 'ⱏ',
107319 'Ⱐ' => 'ⱐ',
107320 'Ⱑ' => 'ⱑ',
107321 'Ⱒ' => 'ⱒ',
107322 'Ⱓ' => 'ⱓ',
107323 'Ⱔ' => 'ⱔ',
107324 'Ⱕ' => 'ⱕ',
107325 'Ⱖ' => 'ⱖ',
107326 'Ⱗ' => 'ⱗ',
107327 'Ⱘ' => 'ⱘ',
107328 'Ⱙ' => 'ⱙ',
107329 'Ⱚ' => 'ⱚ',
107330 'Ⱛ' => 'ⱛ',
107331 'Ⱜ' => 'ⱜ',
107332 'Ⱝ' => 'ⱝ',
107333 'Ⱞ' => 'ⱞ',
107334 'Ⱡ' => 'ⱡ',
107335 'Ɫ' => 'ɫ',
107336 'Ᵽ' => 'ᵽ',
107337 'Ɽ' => 'ɽ',
107338 'Ⱨ' => 'ⱨ',
107339 'Ⱪ' => 'ⱪ',
107340 'Ⱬ' => 'ⱬ',
107341 'Ɑ' => 'ɑ',
107342 'Ɱ' => 'ɱ',
107343 'Ɐ' => 'ɐ',
107344 'Ɒ' => 'ɒ',
107345 'Ⱳ' => 'ⱳ',
107346 'Ⱶ' => 'ⱶ',
107347 'Ȿ' => 'ȿ',
107348 'Ɀ' => 'ɀ',
107349 'Ⲁ' => 'ⲁ',
107350 'Ⲃ' => 'ⲃ',
107351 'Ⲅ' => 'ⲅ',
107352 'Ⲇ' => 'ⲇ',
107353 'Ⲉ' => 'ⲉ',
107354 'Ⲋ' => 'ⲋ',
107355 'Ⲍ' => 'ⲍ',
107356 'Ⲏ' => 'ⲏ',
107357 'Ⲑ' => 'ⲑ',
107358 'Ⲓ' => 'ⲓ',
107359 'Ⲕ' => 'ⲕ',
107360 'Ⲗ' => 'ⲗ',
107361 'Ⲙ' => 'ⲙ',
107362 'Ⲛ' => 'ⲛ',
107363 'Ⲝ' => 'ⲝ',
107364 'Ⲟ' => 'ⲟ',
107365 'Ⲡ' => 'ⲡ',
107366 'Ⲣ' => 'ⲣ',
107367 'Ⲥ' => 'ⲥ',
107368 'Ⲧ' => 'ⲧ',
107369 'Ⲩ' => 'ⲩ',
107370 'Ⲫ' => 'ⲫ',
107371 'Ⲭ' => 'ⲭ',
107372 'Ⲯ' => 'ⲯ',
107373 'Ⲱ' => 'ⲱ',
107374 'Ⲳ' => 'ⲳ',
107375 'Ⲵ' => 'ⲵ',
107376 'Ⲷ' => 'ⲷ',
107377 'Ⲹ' => 'ⲹ',
107378 'Ⲻ' => 'ⲻ',
107379 'Ⲽ' => 'ⲽ',
107380 'Ⲿ' => 'ⲿ',
107381 'Ⳁ' => 'ⳁ',
107382 'Ⳃ' => 'ⳃ',
107383 'Ⳅ' => 'ⳅ',
107384 'Ⳇ' => 'ⳇ',
107385 'Ⳉ' => 'ⳉ',
107386 'Ⳋ' => 'ⳋ',
107387 'Ⳍ' => 'ⳍ',
107388 'Ⳏ' => 'ⳏ',
107389 'Ⳑ' => 'ⳑ',
107390 'Ⳓ' => 'ⳓ',
107391 'Ⳕ' => 'ⳕ',
107392 'Ⳗ' => 'ⳗ',
107393 'Ⳙ' => 'ⳙ',
107394 'Ⳛ' => 'ⳛ',
107395 'Ⳝ' => 'ⳝ',
107396 'Ⳟ' => 'ⳟ',
107397 'Ⳡ' => 'ⳡ',
107398 'Ⳣ' => 'ⳣ',
107399 'Ⳬ' => 'ⳬ',
107400 'Ⳮ' => 'ⳮ',
107401 'Ⳳ' => 'ⳳ',
107402 'Ꙁ' => 'ꙁ',
107403 'Ꙃ' => 'ꙃ',
107404 'Ꙅ' => 'ꙅ',
107405 'Ꙇ' => 'ꙇ',
107406 'Ꙉ' => 'ꙉ',
107407 'Ꙋ' => 'ꙋ',
107408 'Ꙍ' => 'ꙍ',
107409 'Ꙏ' => 'ꙏ',
107410 'Ꙑ' => 'ꙑ',
107411 'Ꙓ' => 'ꙓ',
107412 'Ꙕ' => 'ꙕ',
107413 'Ꙗ' => 'ꙗ',
107414 'Ꙙ' => 'ꙙ',
107415 'Ꙛ' => 'ꙛ',
107416 'Ꙝ' => 'ꙝ',
107417 'Ꙟ' => 'ꙟ',
107418 'Ꙡ' => 'ꙡ',
107419 'Ꙣ' => 'ꙣ',
107420 'Ꙥ' => 'ꙥ',
107421 'Ꙧ' => 'ꙧ',
107422 'Ꙩ' => 'ꙩ',
107423 'Ꙫ' => 'ꙫ',
107424 'Ꙭ' => 'ꙭ',
107425 'Ꚁ' => 'ꚁ',
107426 'Ꚃ' => 'ꚃ',
107427 'Ꚅ' => 'ꚅ',
107428 'Ꚇ' => 'ꚇ',
107429 'Ꚉ' => 'ꚉ',
107430 'Ꚋ' => 'ꚋ',
107431 'Ꚍ' => 'ꚍ',
107432 'Ꚏ' => 'ꚏ',
107433 'Ꚑ' => 'ꚑ',
107434 'Ꚓ' => 'ꚓ',
107435 'Ꚕ' => 'ꚕ',
107436 'Ꚗ' => 'ꚗ',
107437 'Ꚙ' => 'ꚙ',
107438 'Ꚛ' => 'ꚛ',
107439 'Ꜣ' => 'ꜣ',
107440 'Ꜥ' => 'ꜥ',
107441 'Ꜧ' => 'ꜧ',
107442 'Ꜩ' => 'ꜩ',
107443 'Ꜫ' => 'ꜫ',
107444 'Ꜭ' => 'ꜭ',
107445 'Ꜯ' => 'ꜯ',
107446 'Ꜳ' => 'ꜳ',
107447 'Ꜵ' => 'ꜵ',
107448 'Ꜷ' => 'ꜷ',
107449 'Ꜹ' => 'ꜹ',
107450 'Ꜻ' => 'ꜻ',
107451 'Ꜽ' => 'ꜽ',
107452 'Ꜿ' => 'ꜿ',
107453 'Ꝁ' => 'ꝁ',
107454 'Ꝃ' => 'ꝃ',
107455 'Ꝅ' => 'ꝅ',
107456 'Ꝇ' => 'ꝇ',
107457 'Ꝉ' => 'ꝉ',
107458 'Ꝋ' => 'ꝋ',
107459 'Ꝍ' => 'ꝍ',
107460 'Ꝏ' => 'ꝏ',
107461 'Ꝑ' => 'ꝑ',
107462 'Ꝓ' => 'ꝓ',
107463 'Ꝕ' => 'ꝕ',
107464 'Ꝗ' => 'ꝗ',
107465 'Ꝙ' => 'ꝙ',
107466 'Ꝛ' => 'ꝛ',
107467 'Ꝝ' => 'ꝝ',
107468 'Ꝟ' => 'ꝟ',
107469 'Ꝡ' => 'ꝡ',
107470 'Ꝣ' => 'ꝣ',
107471 'Ꝥ' => 'ꝥ',
107472 'Ꝧ' => 'ꝧ',
107473 'Ꝩ' => 'ꝩ',
107474 'Ꝫ' => 'ꝫ',
107475 'Ꝭ' => 'ꝭ',
107476 'Ꝯ' => 'ꝯ',
107477 'Ꝺ' => 'ꝺ',
107478 'Ꝼ' => 'ꝼ',
107479 'Ᵹ' => 'ᵹ',
107480 'Ꝿ' => 'ꝿ',
107481 'Ꞁ' => 'ꞁ',
107482 'Ꞃ' => 'ꞃ',
107483 'Ꞅ' => 'ꞅ',
107484 'Ꞇ' => 'ꞇ',
107485 'Ꞌ' => 'ꞌ',
107486 'Ɥ' => 'ɥ',
107487 'Ꞑ' => 'ꞑ',
107488 'Ꞓ' => 'ꞓ',
107489 'Ꞗ' => 'ꞗ',
107490 'Ꞙ' => 'ꞙ',
107491 'Ꞛ' => 'ꞛ',
107492 'Ꞝ' => 'ꞝ',
107493 'Ꞟ' => 'ꞟ',
107494 'Ꞡ' => 'ꞡ',
107495 'Ꞣ' => 'ꞣ',
107496 'Ꞥ' => 'ꞥ',
107497 'Ꞧ' => 'ꞧ',
107498 'Ꞩ' => 'ꞩ',
107499 'Ɦ' => 'ɦ',
107500 'Ɜ' => 'ɜ',
107501 'Ɡ' => 'ɡ',
107502 'Ɬ' => 'ɬ',
107503 'Ɪ' => 'ɪ',
107504 'Ʞ' => 'ʞ',
107505 'Ʇ' => 'ʇ',
107506 'Ʝ' => 'ʝ',
107507 'Ꭓ' => 'ꭓ',
107508 'Ꞵ' => 'ꞵ',
107509 'Ꞷ' => 'ꞷ',
107510 'Ꞹ' => 'ꞹ',
107511 'Ꞻ' => 'ꞻ',
107512 'Ꞽ' => 'ꞽ',
107513 'Ꞿ' => 'ꞿ',
107514 'Ꟃ' => 'ꟃ',
107515 'Ꞔ' => 'ꞔ',
107516 'Ʂ' => 'ʂ',
107517 'Ᶎ' => 'ᶎ',
107518 'Ꟈ' => 'ꟈ',
107519 'Ꟊ' => 'ꟊ',
107520 'Ꟶ' => 'ꟶ',
107521 'A' => 'a',
107522 'B' => 'b',
107523 'C' => 'c',
107524 'D' => 'd',
107525 'E' => 'e',
107526 'F' => 'f',
107527 'G' => 'g',
107528 'H' => 'h',
107529 'I' => 'i',
107530 'J' => 'j',
107531 'K' => 'k',
107532 'L' => 'l',
107533 'M' => 'm',
107534 'N' => 'n',
107535 'O' => 'o',
107536 'P' => 'p',
107537 'Q' => 'q',
107538 'R' => 'r',
107539 'S' => 's',
107540 'T' => 't',
107541 'U' => 'u',
107542 'V' => 'v',
107543 'W' => 'w',
107544 'X' => 'x',
107545 'Y' => 'y',
107546 'Z' => 'z',
107547 '𐐀' => '𐐨',
107548 '𐐁' => '𐐩',
107549 '𐐂' => '𐐪',
107550 '𐐃' => '𐐫',
107551 '𐐄' => '𐐬',
107552 '𐐅' => '𐐭',
107553 '𐐆' => '𐐮',
107554 '𐐇' => '𐐯',
107555 '𐐈' => '𐐰',
107556 '𐐉' => '𐐱',
107557 '𐐊' => '𐐲',
107558 '𐐋' => '𐐳',
107559 '𐐌' => '𐐴',
107560 '𐐍' => '𐐵',
107561 '𐐎' => '𐐶',
107562 '𐐏' => '𐐷',
107563 '𐐐' => '𐐸',
107564 '𐐑' => '𐐹',
107565 '𐐒' => '𐐺',
107566 '𐐓' => '𐐻',
107567 '𐐔' => '𐐼',
107568 '𐐕' => '𐐽',
107569 '𐐖' => '𐐾',
107570 '𐐗' => '𐐿',
107571 '𐐘' => '𐑀',
107572 '𐐙' => '𐑁',
107573 '𐐚' => '𐑂',
107574 '𐐛' => '𐑃',
107575 '𐐜' => '𐑄',
107576 '𐐝' => '𐑅',
107577 '𐐞' => '𐑆',
107578 '𐐟' => '𐑇',
107579 '𐐠' => '𐑈',
107580 '𐐡' => '𐑉',
107581 '𐐢' => '𐑊',
107582 '𐐣' => '𐑋',
107583 '𐐤' => '𐑌',
107584 '𐐥' => '𐑍',
107585 '𐐦' => '𐑎',
107586 '𐐧' => '𐑏',
107587 '𐒰' => '𐓘',
107588 '𐒱' => '𐓙',
107589 '𐒲' => '𐓚',
107590 '𐒳' => '𐓛',
107591 '𐒴' => '𐓜',
107592 '𐒵' => '𐓝',
107593 '𐒶' => '𐓞',
107594 '𐒷' => '𐓟',
107595 '𐒸' => '𐓠',
107596 '𐒹' => '𐓡',
107597 '𐒺' => '𐓢',
107598 '𐒻' => '𐓣',
107599 '𐒼' => '𐓤',
107600 '𐒽' => '𐓥',
107601 '𐒾' => '𐓦',
107602 '𐒿' => '𐓧',
107603 '𐓀' => '𐓨',
107604 '𐓁' => '𐓩',
107605 '𐓂' => '𐓪',
107606 '𐓃' => '𐓫',
107607 '𐓄' => '𐓬',
107608 '𐓅' => '𐓭',
107609 '𐓆' => '𐓮',
107610 '𐓇' => '𐓯',
107611 '𐓈' => '𐓰',
107612 '𐓉' => '𐓱',
107613 '𐓊' => '𐓲',
107614 '𐓋' => '𐓳',
107615 '𐓌' => '𐓴',
107616 '𐓍' => '𐓵',
107617 '𐓎' => '𐓶',
107618 '𐓏' => '𐓷',
107619 '𐓐' => '𐓸',
107620 '𐓑' => '𐓹',
107621 '𐓒' => '𐓺',
107622 '𐓓' => '𐓻',
107623 '𐲀' => '𐳀',
107624 '𐲁' => '𐳁',
107625 '𐲂' => '𐳂',
107626 '𐲃' => '𐳃',
107627 '𐲄' => '𐳄',
107628 '𐲅' => '𐳅',
107629 '𐲆' => '𐳆',
107630 '𐲇' => '𐳇',
107631 '𐲈' => '𐳈',
107632 '𐲉' => '𐳉',
107633 '𐲊' => '𐳊',
107634 '𐲋' => '𐳋',
107635 '𐲌' => '𐳌',
107636 '𐲍' => '𐳍',
107637 '𐲎' => '𐳎',
107638 '𐲏' => '𐳏',
107639 '𐲐' => '𐳐',
107640 '𐲑' => '𐳑',
107641 '𐲒' => '𐳒',
107642 '𐲓' => '𐳓',
107643 '𐲔' => '𐳔',
107644 '𐲕' => '𐳕',
107645 '𐲖' => '𐳖',
107646 '𐲗' => '𐳗',
107647 '𐲘' => '𐳘',
107648 '𐲙' => '𐳙',
107649 '𐲚' => '𐳚',
107650 '𐲛' => '𐳛',
107651 '𐲜' => '𐳜',
107652 '𐲝' => '𐳝',
107653 '𐲞' => '𐳞',
107654 '𐲟' => '𐳟',
107655 '𐲠' => '𐳠',
107656 '𐲡' => '𐳡',
107657 '𐲢' => '𐳢',
107658 '𐲣' => '𐳣',
107659 '𐲤' => '𐳤',
107660 '𐲥' => '𐳥',
107661 '𐲦' => '𐳦',
107662 '𐲧' => '𐳧',
107663 '𐲨' => '𐳨',
107664 '𐲩' => '𐳩',
107665 '𐲪' => '𐳪',
107666 '𐲫' => '𐳫',
107667 '𐲬' => '𐳬',
107668 '𐲭' => '𐳭',
107669 '𐲮' => '𐳮',
107670 '𐲯' => '𐳯',
107671 '𐲰' => '𐳰',
107672 '𐲱' => '𐳱',
107673 '𐲲' => '𐳲',
107674 '𑢠' => '𑣀',
107675 '𑢡' => '𑣁',
107676 '𑢢' => '𑣂',
107677 '𑢣' => '𑣃',
107678 '𑢤' => '𑣄',
107679 '𑢥' => '𑣅',
107680 '𑢦' => '𑣆',
107681 '𑢧' => '𑣇',
107682 '𑢨' => '𑣈',
107683 '𑢩' => '𑣉',
107684 '𑢪' => '𑣊',
107685 '𑢫' => '𑣋',
107686 '𑢬' => '𑣌',
107687 '𑢭' => '𑣍',
107688 '𑢮' => '𑣎',
107689 '𑢯' => '𑣏',
107690 '𑢰' => '𑣐',
107691 '𑢱' => '𑣑',
107692 '𑢲' => '𑣒',
107693 '𑢳' => '𑣓',
107694 '𑢴' => '𑣔',
107695 '𑢵' => '𑣕',
107696 '𑢶' => '𑣖',
107697 '𑢷' => '𑣗',
107698 '𑢸' => '𑣘',
107699 '𑢹' => '𑣙',
107700 '𑢺' => '𑣚',
107701 '𑢻' => '𑣛',
107702 '𑢼' => '𑣜',
107703 '𑢽' => '𑣝',
107704 '𑢾' => '𑣞',
107705 '𑢿' => '𑣟',
107706 '𖹀' => '𖹠',
107707 '𖹁' => '𖹡',
107708 '𖹂' => '𖹢',
107709 '𖹃' => '𖹣',
107710 '𖹄' => '𖹤',
107711 '𖹅' => '𖹥',
107712 '𖹆' => '𖹦',
107713 '𖹇' => '𖹧',
107714 '𖹈' => '𖹨',
107715 '𖹉' => '𖹩',
107716 '𖹊' => '𖹪',
107717 '𖹋' => '𖹫',
107718 '𖹌' => '𖹬',
107719 '𖹍' => '𖹭',
107720 '𖹎' => '𖹮',
107721 '𖹏' => '𖹯',
107722 '𖹐' => '𖹰',
107723 '𖹑' => '𖹱',
107724 '𖹒' => '𖹲',
107725 '𖹓' => '𖹳',
107726 '𖹔' => '𖹴',
107727 '𖹕' => '𖹵',
107728 '𖹖' => '𖹶',
107729 '𖹗' => '𖹷',
107730 '𖹘' => '𖹸',
107731 '𖹙' => '𖹹',
107732 '𖹚' => '𖹺',
107733 '𖹛' => '𖹻',
107734 '𖹜' => '𖹼',
107735 '𖹝' => '𖹽',
107736 '𖹞' => '𖹾',
107737 '𖹟' => '𖹿',
107738 '𞤀' => '𞤢',
107739 '𞤁' => '𞤣',
107740 '𞤂' => '𞤤',
107741 '𞤃' => '𞤥',
107742 '𞤄' => '𞤦',
107743 '𞤅' => '𞤧',
107744 '𞤆' => '𞤨',
107745 '𞤇' => '𞤩',
107746 '𞤈' => '𞤪',
107747 '𞤉' => '𞤫',
107748 '𞤊' => '𞤬',
107749 '𞤋' => '𞤭',
107750 '𞤌' => '𞤮',
107751 '𞤍' => '𞤯',
107752 '𞤎' => '𞤰',
107753 '𞤏' => '𞤱',
107754 '𞤐' => '𞤲',
107755 '𞤑' => '𞤳',
107756 '𞤒' => '𞤴',
107757 '𞤓' => '𞤵',
107758 '𞤔' => '𞤶',
107759 '𞤕' => '𞤷',
107760 '𞤖' => '𞤸',
107761 '𞤗' => '𞤹',
107762 '𞤘' => '𞤺',
107763 '𞤙' => '𞤻',
107764 '𞤚' => '𞤼',
107765 '𞤛' => '𞤽',
107766 '𞤜' => '𞤾',
107767 '𞤝' => '𞤿',
107768 '𞤞' => '𞥀',
107769 '𞤟' => '𞥁',
107770 '𞤠' => '𞥂',
107771 '𞤡' => '𞥃',
107772 );
107773 <?php
107774 
107775 
107776 
107777 return '/(?<![\x{0027}\x{002E}\x{003A}\x{005E}\x{0060}\x{00A8}\x{00AD}\x{00AF}\x{00B4}\x{00B7}\x{00B8}\x{02B0}-\x{02C1}\x{02C2}-\x{02C5}\x{02C6}-\x{02D1}\x{02D2}-\x{02DF}\x{02E0}-\x{02E4}\x{02E5}-\x{02EB}\x{02EC}\x{02ED}\x{02EE}\x{02EF}-\x{02FF}\x{0300}-\x{036F}\x{0374}\x{0375}\x{037A}\x{0384}-\x{0385}\x{0387}\x{0483}-\x{0487}\x{0488}-\x{0489}\x{0559}\x{0591}-\x{05BD}\x{05BF}\x{05C1}-\x{05C2}\x{05C4}-\x{05C5}\x{05C7}\x{05F4}\x{0600}-\x{0605}\x{0610}-\x{061A}\x{061C}\x{0640}\x{064B}-\x{065F}\x{0670}\x{06D6}-\x{06DC}\x{06DD}\x{06DF}-\x{06E4}\x{06E5}-\x{06E6}\x{06E7}-\x{06E8}\x{06EA}-\x{06ED}\x{070F}\x{0711}\x{0730}-\x{074A}\x{07A6}-\x{07B0}\x{07EB}-\x{07F3}\x{07F4}-\x{07F5}\x{07FA}\x{07FD}\x{0816}-\x{0819}\x{081A}\x{081B}-\x{0823}\x{0824}\x{0825}-\x{0827}\x{0828}\x{0829}-\x{082D}\x{0859}-\x{085B}\x{08D3}-\x{08E1}\x{08E2}\x{08E3}-\x{0902}\x{093A}\x{093C}\x{0941}-\x{0948}\x{094D}\x{0951}-\x{0957}\x{0962}-\x{0963}\x{0971}\x{0981}\x{09BC}\x{09C1}-\x{09C4}\x{09CD}\x{09E2}-\x{09E3}\x{09FE}\x{0A01}-\x{0A02}\x{0A3C}\x{0A41}-\x{0A42}\x{0A47}-\x{0A48}\x{0A4B}-\x{0A4D}\x{0A51}\x{0A70}-\x{0A71}\x{0A75}\x{0A81}-\x{0A82}\x{0ABC}\x{0AC1}-\x{0AC5}\x{0AC7}-\x{0AC8}\x{0ACD}\x{0AE2}-\x{0AE3}\x{0AFA}-\x{0AFF}\x{0B01}\x{0B3C}\x{0B3F}\x{0B41}-\x{0B44}\x{0B4D}\x{0B56}\x{0B62}-\x{0B63}\x{0B82}\x{0BC0}\x{0BCD}\x{0C00}\x{0C04}\x{0C3E}-\x{0C40}\x{0C46}-\x{0C48}\x{0C4A}-\x{0C4D}\x{0C55}-\x{0C56}\x{0C62}-\x{0C63}\x{0C81}\x{0CBC}\x{0CBF}\x{0CC6}\x{0CCC}-\x{0CCD}\x{0CE2}-\x{0CE3}\x{0D00}-\x{0D01}\x{0D3B}-\x{0D3C}\x{0D41}-\x{0D44}\x{0D4D}\x{0D62}-\x{0D63}\x{0DCA}\x{0DD2}-\x{0DD4}\x{0DD6}\x{0E31}\x{0E34}-\x{0E3A}\x{0E46}\x{0E47}-\x{0E4E}\x{0EB1}\x{0EB4}-\x{0EB9}\x{0EBB}-\x{0EBC}\x{0EC6}\x{0EC8}-\x{0ECD}\x{0F18}-\x{0F19}\x{0F35}\x{0F37}\x{0F39}\x{0F71}-\x{0F7E}\x{0F80}-\x{0F84}\x{0F86}-\x{0F87}\x{0F8D}-\x{0F97}\x{0F99}-\x{0FBC}\x{0FC6}\x{102D}-\x{1030}\x{1032}-\x{1037}\x{1039}-\x{103A}\x{103D}-\x{103E}\x{1058}-\x{1059}\x{105E}-\x{1060}\x{1071}-\x{1074}\x{1082}\x{1085}-\x{1086}\x{108D}\x{109D}\x{10FC}\x{135D}-\x{135F}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}-\x{1753}\x{1772}-\x{1773}\x{17B4}-\x{17B5}\x{17B7}-\x{17BD}\x{17C6}\x{17C9}-\x{17D3}\x{17D7}\x{17DD}\x{180B}-\x{180D}\x{180E}\x{1843}\x{1885}-\x{1886}\x{18A9}\x{1920}-\x{1922}\x{1927}-\x{1928}\x{1932}\x{1939}-\x{193B}\x{1A17}-\x{1A18}\x{1A1B}\x{1A56}\x{1A58}-\x{1A5E}\x{1A60}\x{1A62}\x{1A65}-\x{1A6C}\x{1A73}-\x{1A7C}\x{1A7F}\x{1AA7}\x{1AB0}-\x{1ABD}\x{1ABE}\x{1B00}-\x{1B03}\x{1B34}\x{1B36}-\x{1B3A}\x{1B3C}\x{1B42}\x{1B6B}-\x{1B73}\x{1B80}-\x{1B81}\x{1BA2}-\x{1BA5}\x{1BA8}-\x{1BA9}\x{1BAB}-\x{1BAD}\x{1BE6}\x{1BE8}-\x{1BE9}\x{1BED}\x{1BEF}-\x{1BF1}\x{1C2C}-\x{1C33}\x{1C36}-\x{1C37}\x{1C78}-\x{1C7D}\x{1CD0}-\x{1CD2}\x{1CD4}-\x{1CE0}\x{1CE2}-\x{1CE8}\x{1CED}\x{1CF4}\x{1CF8}-\x{1CF9}\x{1D2C}-\x{1D6A}\x{1D78}\x{1D9B}-\x{1DBF}\x{1DC0}-\x{1DF9}\x{1DFB}-\x{1DFF}\x{1FBD}\x{1FBF}-\x{1FC1}\x{1FCD}-\x{1FCF}\x{1FDD}-\x{1FDF}\x{1FED}-\x{1FEF}\x{1FFD}-\x{1FFE}\x{200B}-\x{200F}\x{2018}\x{2019}\x{2024}\x{2027}\x{202A}-\x{202E}\x{2060}-\x{2064}\x{2066}-\x{206F}\x{2071}\x{207F}\x{2090}-\x{209C}\x{20D0}-\x{20DC}\x{20DD}-\x{20E0}\x{20E1}\x{20E2}-\x{20E4}\x{20E5}-\x{20F0}\x{2C7C}-\x{2C7D}\x{2CEF}-\x{2CF1}\x{2D6F}\x{2D7F}\x{2DE0}-\x{2DFF}\x{2E2F}\x{3005}\x{302A}-\x{302D}\x{3031}-\x{3035}\x{303B}\x{3099}-\x{309A}\x{309B}-\x{309C}\x{309D}-\x{309E}\x{30FC}-\x{30FE}\x{A015}\x{A4F8}-\x{A4FD}\x{A60C}\x{A66F}\x{A670}-\x{A672}\x{A674}-\x{A67D}\x{A67F}\x{A69C}-\x{A69D}\x{A69E}-\x{A69F}\x{A6F0}-\x{A6F1}\x{A700}-\x{A716}\x{A717}-\x{A71F}\x{A720}-\x{A721}\x{A770}\x{A788}\x{A789}-\x{A78A}\x{A7F8}-\x{A7F9}\x{A802}\x{A806}\x{A80B}\x{A825}-\x{A826}\x{A8C4}-\x{A8C5}\x{A8E0}-\x{A8F1}\x{A8FF}\x{A926}-\x{A92D}\x{A947}-\x{A951}\x{A980}-\x{A982}\x{A9B3}\x{A9B6}-\x{A9B9}\x{A9BC}\x{A9CF}\x{A9E5}\x{A9E6}\x{AA29}-\x{AA2E}\x{AA31}-\x{AA32}\x{AA35}-\x{AA36}\x{AA43}\x{AA4C}\x{AA70}\x{AA7C}\x{AAB0}\x{AAB2}-\x{AAB4}\x{AAB7}-\x{AAB8}\x{AABE}-\x{AABF}\x{AAC1}\x{AADD}\x{AAEC}-\x{AAED}\x{AAF3}-\x{AAF4}\x{AAF6}\x{AB5B}\x{AB5C}-\x{AB5F}\x{ABE5}\x{ABE8}\x{ABED}\x{FB1E}\x{FBB2}-\x{FBC1}\x{FE00}-\x{FE0F}\x{FE13}\x{FE20}-\x{FE2F}\x{FE52}\x{FE55}\x{FEFF}\x{FF07}\x{FF0E}\x{FF1A}\x{FF3E}\x{FF40}\x{FF70}\x{FF9E}-\x{FF9F}\x{FFE3}\x{FFF9}-\x{FFFB}\x{101FD}\x{102E0}\x{10376}-\x{1037A}\x{10A01}-\x{10A03}\x{10A05}-\x{10A06}\x{10A0C}-\x{10A0F}\x{10A38}-\x{10A3A}\x{10A3F}\x{10AE5}-\x{10AE6}\x{10D24}-\x{10D27}\x{10F46}-\x{10F50}\x{11001}\x{11038}-\x{11046}\x{1107F}-\x{11081}\x{110B3}-\x{110B6}\x{110B9}-\x{110BA}\x{110BD}\x{110CD}\x{11100}-\x{11102}\x{11127}-\x{1112B}\x{1112D}-\x{11134}\x{11173}\x{11180}-\x{11181}\x{111B6}-\x{111BE}\x{111C9}-\x{111CC}\x{1122F}-\x{11231}\x{11234}\x{11236}-\x{11237}\x{1123E}\x{112DF}\x{112E3}-\x{112EA}\x{11300}-\x{11301}\x{1133B}-\x{1133C}\x{11340}\x{11366}-\x{1136C}\x{11370}-\x{11374}\x{11438}-\x{1143F}\x{11442}-\x{11444}\x{11446}\x{1145E}\x{114B3}-\x{114B8}\x{114BA}\x{114BF}-\x{114C0}\x{114C2}-\x{114C3}\x{115B2}-\x{115B5}\x{115BC}-\x{115BD}\x{115BF}-\x{115C0}\x{115DC}-\x{115DD}\x{11633}-\x{1163A}\x{1163D}\x{1163F}-\x{11640}\x{116AB}\x{116AD}\x{116B0}-\x{116B5}\x{116B7}\x{1171D}-\x{1171F}\x{11722}-\x{11725}\x{11727}-\x{1172B}\x{1182F}-\x{11837}\x{11839}-\x{1183A}\x{11A01}-\x{11A0A}\x{11A33}-\x{11A38}\x{11A3B}-\x{11A3E}\x{11A47}\x{11A51}-\x{11A56}\x{11A59}-\x{11A5B}\x{11A8A}-\x{11A96}\x{11A98}-\x{11A99}\x{11C30}-\x{11C36}\x{11C38}-\x{11C3D}\x{11C3F}\x{11C92}-\x{11CA7}\x{11CAA}-\x{11CB0}\x{11CB2}-\x{11CB3}\x{11CB5}-\x{11CB6}\x{11D31}-\x{11D36}\x{11D3A}\x{11D3C}-\x{11D3D}\x{11D3F}-\x{11D45}\x{11D47}\x{11D90}-\x{11D91}\x{11D95}\x{11D97}\x{11EF3}-\x{11EF4}\x{16AF0}-\x{16AF4}\x{16B30}-\x{16B36}\x{16B40}-\x{16B43}\x{16F8F}-\x{16F92}\x{16F93}-\x{16F9F}\x{16FE0}-\x{16FE1}\x{1BC9D}-\x{1BC9E}\x{1BCA0}-\x{1BCA3}\x{1D167}-\x{1D169}\x{1D173}-\x{1D17A}\x{1D17B}-\x{1D182}\x{1D185}-\x{1D18B}\x{1D1AA}-\x{1D1AD}\x{1D242}-\x{1D244}\x{1DA00}-\x{1DA36}\x{1DA3B}-\x{1DA6C}\x{1DA75}\x{1DA84}\x{1DA9B}-\x{1DA9F}\x{1DAA1}-\x{1DAAF}\x{1E000}-\x{1E006}\x{1E008}-\x{1E018}\x{1E01B}-\x{1E021}\x{1E023}-\x{1E024}\x{1E026}-\x{1E02A}\x{1E8D0}-\x{1E8D6}\x{1E944}-\x{1E94A}\x{1F3FB}-\x{1F3FF}\x{E0001}\x{E0020}-\x{E007F}\x{E0100}-\x{E01EF}])(\pL)(\pL*+)/u';
107778 <?php
107779 
107780 return array (
107781 'a' => 'A',
107782 'b' => 'B',
107783 'c' => 'C',
107784 'd' => 'D',
107785 'e' => 'E',
107786 'f' => 'F',
107787 'g' => 'G',
107788 'h' => 'H',
107789 'i' => 'I',
107790 'j' => 'J',
107791 'k' => 'K',
107792 'l' => 'L',
107793 'm' => 'M',
107794 'n' => 'N',
107795 'o' => 'O',
107796 'p' => 'P',
107797 'q' => 'Q',
107798 'r' => 'R',
107799 's' => 'S',
107800 't' => 'T',
107801 'u' => 'U',
107802 'v' => 'V',
107803 'w' => 'W',
107804 'x' => 'X',
107805 'y' => 'Y',
107806 'z' => 'Z',
107807 'µ' => 'Μ',
107808 'à' => 'À',
107809 'á' => 'Á',
107810 'â' => 'Â',
107811 'ã' => 'Ã',
107812 'ä' => 'Ä',
107813 'å' => 'Å',
107814 'æ' => 'Æ',
107815 'ç' => 'Ç',
107816 'è' => 'È',
107817 'é' => 'É',
107818 'ê' => 'Ê',
107819 'ë' => 'Ë',
107820 'ì' => 'Ì',
107821 'í' => 'Í',
107822 'î' => 'Î',
107823 'ï' => 'Ï',
107824 'ð' => 'Ð',
107825 'ñ' => 'Ñ',
107826 'ò' => 'Ò',
107827 'ó' => 'Ó',
107828 'ô' => 'Ô',
107829 'õ' => 'Õ',
107830 'ö' => 'Ö',
107831 'ø' => 'Ø',
107832 'ù' => 'Ù',
107833 'ú' => 'Ú',
107834 'û' => 'Û',
107835 'ü' => 'Ü',
107836 'ý' => 'Ý',
107837 'þ' => 'Þ',
107838 'ÿ' => 'Ÿ',
107839 'ā' => 'Ā',
107840 'ă' => 'Ă',
107841 'ą' => 'Ą',
107842 'ć' => 'Ć',
107843 'ĉ' => 'Ĉ',
107844 'ċ' => 'Ċ',
107845 'č' => 'Č',
107846 'ď' => 'Ď',
107847 'đ' => 'Đ',
107848 'ē' => 'Ē',
107849 'ĕ' => 'Ĕ',
107850 'ė' => 'Ė',
107851 'ę' => 'Ę',
107852 'ě' => 'Ě',
107853 'ĝ' => 'Ĝ',
107854 'ğ' => 'Ğ',
107855 'ġ' => 'Ġ',
107856 'ģ' => 'Ģ',
107857 'ĥ' => 'Ĥ',
107858 'ħ' => 'Ħ',
107859 'ĩ' => 'Ĩ',
107860 'ī' => 'Ī',
107861 'ĭ' => 'Ĭ',
107862 'į' => 'Į',
107863 'ı' => 'I',
107864 'ij' => 'IJ',
107865 'ĵ' => 'Ĵ',
107866 'ķ' => 'Ķ',
107867 'ĺ' => 'Ĺ',
107868 'ļ' => 'Ļ',
107869 'ľ' => 'Ľ',
107870 'ŀ' => 'Ŀ',
107871 'ł' => 'Ł',
107872 'ń' => 'Ń',
107873 'ņ' => 'Ņ',
107874 'ň' => 'Ň',
107875 'ŋ' => 'Ŋ',
107876 'ō' => 'Ō',
107877 'ŏ' => 'Ŏ',
107878 'ő' => 'Ő',
107879 'œ' => 'Œ',
107880 'ŕ' => 'Ŕ',
107881 'ŗ' => 'Ŗ',
107882 'ř' => 'Ř',
107883 'ś' => 'Ś',
107884 'ŝ' => 'Ŝ',
107885 'ş' => 'Ş',
107886 'š' => 'Š',
107887 'ţ' => 'Ţ',
107888 'ť' => 'Ť',
107889 'ŧ' => 'Ŧ',
107890 'ũ' => 'Ũ',
107891 'ū' => 'Ū',
107892 'ŭ' => 'Ŭ',
107893 'ů' => 'Ů',
107894 'ű' => 'Ű',
107895 'ų' => 'Ų',
107896 'ŵ' => 'Ŵ',
107897 'ŷ' => 'Ŷ',
107898 'ź' => 'Ź',
107899 'ż' => 'Ż',
107900 'ž' => 'Ž',
107901 'ſ' => 'S',
107902 'ƀ' => 'Ƀ',
107903 'ƃ' => 'Ƃ',
107904 'ƅ' => 'Ƅ',
107905 'ƈ' => 'Ƈ',
107906 'ƌ' => 'Ƌ',
107907 'ƒ' => 'Ƒ',
107908 'ƕ' => 'Ƕ',
107909 'ƙ' => 'Ƙ',
107910 'ƚ' => 'Ƚ',
107911 'ƞ' => 'Ƞ',
107912 'ơ' => 'Ơ',
107913 'ƣ' => 'Ƣ',
107914 'ƥ' => 'Ƥ',
107915 'ƨ' => 'Ƨ',
107916 'ƭ' => 'Ƭ',
107917 'ư' => 'Ư',
107918 'ƴ' => 'Ƴ',
107919 'ƶ' => 'Ƶ',
107920 'ƹ' => 'Ƹ',
107921 'ƽ' => 'Ƽ',
107922 'ƿ' => 'Ƿ',
107923 'Dž' => 'DŽ',
107924 'dž' => 'DŽ',
107925 'Lj' => 'LJ',
107926 'lj' => 'LJ',
107927 'Nj' => 'NJ',
107928 'nj' => 'NJ',
107929 'ǎ' => 'Ǎ',
107930 'ǐ' => 'Ǐ',
107931 'ǒ' => 'Ǒ',
107932 'ǔ' => 'Ǔ',
107933 'ǖ' => 'Ǖ',
107934 'ǘ' => 'Ǘ',
107935 'ǚ' => 'Ǚ',
107936 'ǜ' => 'Ǜ',
107937 'ǝ' => 'Ǝ',
107938 'ǟ' => 'Ǟ',
107939 'ǡ' => 'Ǡ',
107940 'ǣ' => 'Ǣ',
107941 'ǥ' => 'Ǥ',
107942 'ǧ' => 'Ǧ',
107943 'ǩ' => 'Ǩ',
107944 'ǫ' => 'Ǫ',
107945 'ǭ' => 'Ǭ',
107946 'ǯ' => 'Ǯ',
107947 'Dz' => 'DZ',
107948 'dz' => 'DZ',
107949 'ǵ' => 'Ǵ',
107950 'ǹ' => 'Ǹ',
107951 'ǻ' => 'Ǻ',
107952 'ǽ' => 'Ǽ',
107953 'ǿ' => 'Ǿ',
107954 'ȁ' => 'Ȁ',
107955 'ȃ' => 'Ȃ',
107956 'ȅ' => 'Ȅ',
107957 'ȇ' => 'Ȇ',
107958 'ȉ' => 'Ȉ',
107959 'ȋ' => 'Ȋ',
107960 'ȍ' => 'Ȍ',
107961 'ȏ' => 'Ȏ',
107962 'ȑ' => 'Ȑ',
107963 'ȓ' => 'Ȓ',
107964 'ȕ' => 'Ȕ',
107965 'ȗ' => 'Ȗ',
107966 'ș' => 'Ș',
107967 'ț' => 'Ț',
107968 'ȝ' => 'Ȝ',
107969 'ȟ' => 'Ȟ',
107970 'ȣ' => 'Ȣ',
107971 'ȥ' => 'Ȥ',
107972 'ȧ' => 'Ȧ',
107973 'ȩ' => 'Ȩ',
107974 'ȫ' => 'Ȫ',
107975 'ȭ' => 'Ȭ',
107976 'ȯ' => 'Ȯ',
107977 'ȱ' => 'Ȱ',
107978 'ȳ' => 'Ȳ',
107979 'ȼ' => 'Ȼ',
107980 'ȿ' => 'Ȿ',
107981 'ɀ' => 'Ɀ',
107982 'ɂ' => 'Ɂ',
107983 'ɇ' => 'Ɇ',
107984 'ɉ' => 'Ɉ',
107985 'ɋ' => 'Ɋ',
107986 'ɍ' => 'Ɍ',
107987 'ɏ' => 'Ɏ',
107988 'ɐ' => 'Ɐ',
107989 'ɑ' => 'Ɑ',
107990 'ɒ' => 'Ɒ',
107991 'ɓ' => 'Ɓ',
107992 'ɔ' => 'Ɔ',
107993 'ɖ' => 'Ɖ',
107994 'ɗ' => 'Ɗ',
107995 'ə' => 'Ə',
107996 'ɛ' => 'Ɛ',
107997 'ɜ' => 'Ɜ',
107998 'ɠ' => 'Ɠ',
107999 'ɡ' => 'Ɡ',
108000 'ɣ' => 'Ɣ',
108001 'ɥ' => 'Ɥ',
108002 'ɦ' => 'Ɦ',
108003 'ɨ' => 'Ɨ',
108004 'ɩ' => 'Ɩ',
108005 'ɪ' => 'Ɪ',
108006 'ɫ' => 'Ɫ',
108007 'ɬ' => 'Ɬ',
108008 'ɯ' => 'Ɯ',
108009 'ɱ' => 'Ɱ',
108010 'ɲ' => 'Ɲ',
108011 'ɵ' => 'Ɵ',
108012 'ɽ' => 'Ɽ',
108013 'ʀ' => 'Ʀ',
108014 'ʂ' => 'Ʂ',
108015 'ʃ' => 'Ʃ',
108016 'ʇ' => 'Ʇ',
108017 'ʈ' => 'Ʈ',
108018 'ʉ' => 'Ʉ',
108019 'ʊ' => 'Ʊ',
108020 'ʋ' => 'Ʋ',
108021 'ʌ' => 'Ʌ',
108022 'ʒ' => 'Ʒ',
108023 'ʝ' => 'Ʝ',
108024 'ʞ' => 'Ʞ',
108025 'ͅ' => 'Ι',
108026 'ͱ' => 'Ͱ',
108027 'ͳ' => 'Ͳ',
108028 'ͷ' => 'Ͷ',
108029 'ͻ' => 'Ͻ',
108030 'ͼ' => 'Ͼ',
108031 'ͽ' => 'Ͽ',
108032 'ά' => 'Ά',
108033 'έ' => 'Έ',
108034 'ή' => 'Ή',
108035 'ί' => 'Ί',
108036 'α' => 'Α',
108037 'β' => 'Β',
108038 'γ' => 'Γ',
108039 'δ' => 'Δ',
108040 'ε' => 'Ε',
108041 'ζ' => 'Ζ',
108042 'η' => 'Η',
108043 'θ' => 'Θ',
108044 'ι' => 'Ι',
108045 'κ' => 'Κ',
108046 'λ' => 'Λ',
108047 'μ' => 'Μ',
108048 'ν' => 'Ν',
108049 'ξ' => 'Ξ',
108050 'ο' => 'Ο',
108051 'π' => 'Π',
108052 'ρ' => 'Ρ',
108053 'ς' => 'Σ',
108054 'σ' => 'Σ',
108055 'τ' => 'Τ',
108056 'υ' => 'Υ',
108057 'φ' => 'Φ',
108058 'χ' => 'Χ',
108059 'ψ' => 'Ψ',
108060 'ω' => 'Ω',
108061 'ϊ' => 'Ϊ',
108062 'ϋ' => 'Ϋ',
108063 'ό' => 'Ό',
108064 'ύ' => 'Ύ',
108065 'ώ' => 'Ώ',
108066 'ϐ' => 'Β',
108067 'ϑ' => 'Θ',
108068 'ϕ' => 'Φ',
108069 'ϖ' => 'Π',
108070 'ϗ' => 'Ϗ',
108071 'ϙ' => 'Ϙ',
108072 'ϛ' => 'Ϛ',
108073 'ϝ' => 'Ϝ',
108074 'ϟ' => 'Ϟ',
108075 'ϡ' => 'Ϡ',
108076 'ϣ' => 'Ϣ',
108077 'ϥ' => 'Ϥ',
108078 'ϧ' => 'Ϧ',
108079 'ϩ' => 'Ϩ',
108080 'ϫ' => 'Ϫ',
108081 'ϭ' => 'Ϭ',
108082 'ϯ' => 'Ϯ',
108083 'ϰ' => 'Κ',
108084 'ϱ' => 'Ρ',
108085 'ϲ' => 'Ϲ',
108086 'ϳ' => 'Ϳ',
108087 'ϵ' => 'Ε',
108088 'ϸ' => 'Ϸ',
108089 'ϻ' => 'Ϻ',
108090 'а' => 'А',
108091 'б' => 'Б',
108092 'в' => 'В',
108093 'г' => 'Г',
108094 'д' => 'Д',
108095 'е' => 'Е',
108096 'ж' => 'Ж',
108097 'з' => 'З',
108098 'и' => 'И',
108099 'й' => 'Й',
108100 'к' => 'К',
108101 'л' => 'Л',
108102 'м' => 'М',
108103 'н' => 'Н',
108104 'о' => 'О',
108105 'п' => 'П',
108106 'р' => 'Р',
108107 'с' => 'С',
108108 'т' => 'Т',
108109 'у' => 'У',
108110 'ф' => 'Ф',
108111 'х' => 'Х',
108112 'ц' => 'Ц',
108113 'ч' => 'Ч',
108114 'ш' => 'Ш',
108115 'щ' => 'Щ',
108116 'ъ' => 'Ъ',
108117 'ы' => 'Ы',
108118 'ь' => 'Ь',
108119 'э' => 'Э',
108120 'ю' => 'Ю',
108121 'я' => 'Я',
108122 'ѐ' => 'Ѐ',
108123 'ё' => 'Ё',
108124 'ђ' => 'Ђ',
108125 'ѓ' => 'Ѓ',
108126 'є' => 'Є',
108127 'ѕ' => 'Ѕ',
108128 'і' => 'І',
108129 'ї' => 'Ї',
108130 'ј' => 'Ј',
108131 'љ' => 'Љ',
108132 'њ' => 'Њ',
108133 'ћ' => 'Ћ',
108134 'ќ' => 'Ќ',
108135 'ѝ' => 'Ѝ',
108136 'ў' => 'Ў',
108137 'џ' => 'Џ',
108138 'ѡ' => 'Ѡ',
108139 'ѣ' => 'Ѣ',
108140 'ѥ' => 'Ѥ',
108141 'ѧ' => 'Ѧ',
108142 'ѩ' => 'Ѩ',
108143 'ѫ' => 'Ѫ',
108144 'ѭ' => 'Ѭ',
108145 'ѯ' => 'Ѯ',
108146 'ѱ' => 'Ѱ',
108147 'ѳ' => 'Ѳ',
108148 'ѵ' => 'Ѵ',
108149 'ѷ' => 'Ѷ',
108150 'ѹ' => 'Ѹ',
108151 'ѻ' => 'Ѻ',
108152 'ѽ' => 'Ѽ',
108153 'ѿ' => 'Ѿ',
108154 'ҁ' => 'Ҁ',
108155 'ҋ' => 'Ҋ',
108156 'ҍ' => 'Ҍ',
108157 'ҏ' => 'Ҏ',
108158 'ґ' => 'Ґ',
108159 'ғ' => 'Ғ',
108160 'ҕ' => 'Ҕ',
108161 'җ' => 'Җ',
108162 'ҙ' => 'Ҙ',
108163 'қ' => 'Қ',
108164 'ҝ' => 'Ҝ',
108165 'ҟ' => 'Ҟ',
108166 'ҡ' => 'Ҡ',
108167 'ң' => 'Ң',
108168 'ҥ' => 'Ҥ',
108169 'ҧ' => 'Ҧ',
108170 'ҩ' => 'Ҩ',
108171 'ҫ' => 'Ҫ',
108172 'ҭ' => 'Ҭ',
108173 'ү' => 'Ү',
108174 'ұ' => 'Ұ',
108175 'ҳ' => 'Ҳ',
108176 'ҵ' => 'Ҵ',
108177 'ҷ' => 'Ҷ',
108178 'ҹ' => 'Ҹ',
108179 'һ' => 'Һ',
108180 'ҽ' => 'Ҽ',
108181 'ҿ' => 'Ҿ',
108182 'ӂ' => 'Ӂ',
108183 'ӄ' => 'Ӄ',
108184 'ӆ' => 'Ӆ',
108185 'ӈ' => 'Ӈ',
108186 'ӊ' => 'Ӊ',
108187 'ӌ' => 'Ӌ',
108188 'ӎ' => 'Ӎ',
108189 'ӏ' => 'Ӏ',
108190 'ӑ' => 'Ӑ',
108191 'ӓ' => 'Ӓ',
108192 'ӕ' => 'Ӕ',
108193 'ӗ' => 'Ӗ',
108194 'ә' => 'Ә',
108195 'ӛ' => 'Ӛ',
108196 'ӝ' => 'Ӝ',
108197 'ӟ' => 'Ӟ',
108198 'ӡ' => 'Ӡ',
108199 'ӣ' => 'Ӣ',
108200 'ӥ' => 'Ӥ',
108201 'ӧ' => 'Ӧ',
108202 'ө' => 'Ө',
108203 'ӫ' => 'Ӫ',
108204 'ӭ' => 'Ӭ',
108205 'ӯ' => 'Ӯ',
108206 'ӱ' => 'Ӱ',
108207 'ӳ' => 'Ӳ',
108208 'ӵ' => 'Ӵ',
108209 'ӷ' => 'Ӷ',
108210 'ӹ' => 'Ӹ',
108211 'ӻ' => 'Ӻ',
108212 'ӽ' => 'Ӽ',
108213 'ӿ' => 'Ӿ',
108214 'ԁ' => 'Ԁ',
108215 'ԃ' => 'Ԃ',
108216 'ԅ' => 'Ԅ',
108217 'ԇ' => 'Ԇ',
108218 'ԉ' => 'Ԉ',
108219 'ԋ' => 'Ԋ',
108220 'ԍ' => 'Ԍ',
108221 'ԏ' => 'Ԏ',
108222 'ԑ' => 'Ԑ',
108223 'ԓ' => 'Ԓ',
108224 'ԕ' => 'Ԕ',
108225 'ԗ' => 'Ԗ',
108226 'ԙ' => 'Ԙ',
108227 'ԛ' => 'Ԛ',
108228 'ԝ' => 'Ԝ',
108229 'ԟ' => 'Ԟ',
108230 'ԡ' => 'Ԡ',
108231 'ԣ' => 'Ԣ',
108232 'ԥ' => 'Ԥ',
108233 'ԧ' => 'Ԧ',
108234 'ԩ' => 'Ԩ',
108235 'ԫ' => 'Ԫ',
108236 'ԭ' => 'Ԭ',
108237 'ԯ' => 'Ԯ',
108238 'ա' => 'Ա',
108239 'բ' => 'Բ',
108240 'գ' => 'Գ',
108241 'դ' => 'Դ',
108242 'ե' => 'Ե',
108243 'զ' => 'Զ',
108244 'է' => 'Է',
108245 'ը' => 'Ը',
108246 'թ' => 'Թ',
108247 'ժ' => 'Ժ',
108248 'ի' => 'Ի',
108249 'լ' => 'Լ',
108250 'խ' => 'Խ',
108251 'ծ' => 'Ծ',
108252 'կ' => 'Կ',
108253 'հ' => 'Հ',
108254 'ձ' => 'Ձ',
108255 'ղ' => 'Ղ',
108256 'ճ' => 'Ճ',
108257 'մ' => 'Մ',
108258 'յ' => 'Յ',
108259 'ն' => 'Ն',
108260 'շ' => 'Շ',
108261 'ո' => 'Ո',
108262 'չ' => 'Չ',
108263 'պ' => 'Պ',
108264 'ջ' => 'Ջ',
108265 'ռ' => 'Ռ',
108266 'ս' => 'Ս',
108267 'վ' => 'Վ',
108268 'տ' => 'Տ',
108269 'ր' => 'Ր',
108270 'ց' => 'Ց',
108271 'ւ' => 'Ւ',
108272 'փ' => 'Փ',
108273 'ք' => 'Ք',
108274 'օ' => 'Օ',
108275 'ֆ' => 'Ֆ',
108276 'ა' => 'Ა',
108277 'ბ' => 'Ბ',
108278 'გ' => 'Გ',
108279 'დ' => 'Დ',
108280 'ე' => 'Ე',
108281 'ვ' => 'Ვ',
108282 'ზ' => 'Ზ',
108283 'თ' => 'Თ',
108284 'ი' => 'Ი',
108285 'კ' => 'Კ',
108286 'ლ' => 'Ლ',
108287 'მ' => 'Მ',
108288 'ნ' => 'Ნ',
108289 'ო' => 'Ო',
108290 'პ' => 'Პ',
108291 'ჟ' => 'Ჟ',
108292 'რ' => 'Რ',
108293 'ს' => 'Ს',
108294 'ტ' => 'Ტ',
108295 'უ' => 'Უ',
108296 'ფ' => 'Ფ',
108297 'ქ' => 'Ქ',
108298 'ღ' => 'Ღ',
108299 'ყ' => 'Ყ',
108300 'შ' => 'Შ',
108301 'ჩ' => 'Ჩ',
108302 'ც' => 'Ც',
108303 'ძ' => 'Ძ',
108304 'წ' => 'Წ',
108305 'ჭ' => 'Ჭ',
108306 'ხ' => 'Ხ',
108307 'ჯ' => 'Ჯ',
108308 'ჰ' => 'Ჰ',
108309 'ჱ' => 'Ჱ',
108310 'ჲ' => 'Ჲ',
108311 'ჳ' => 'Ჳ',
108312 'ჴ' => 'Ჴ',
108313 'ჵ' => 'Ჵ',
108314 'ჶ' => 'Ჶ',
108315 'ჷ' => 'Ჷ',
108316 'ჸ' => 'Ჸ',
108317 'ჹ' => 'Ჹ',
108318 'ჺ' => 'Ჺ',
108319 'ჽ' => 'Ჽ',
108320 'ჾ' => 'Ჾ',
108321 'ჿ' => 'Ჿ',
108322 'ᏸ' => 'Ᏸ',
108323 'ᏹ' => 'Ᏹ',
108324 'ᏺ' => 'Ᏺ',
108325 'ᏻ' => 'Ᏻ',
108326 'ᏼ' => 'Ᏼ',
108327 'ᏽ' => 'Ᏽ',
108328 'ᲀ' => 'В',
108329 'ᲁ' => 'Д',
108330 'ᲂ' => 'О',
108331 'ᲃ' => 'С',
108332 'ᲄ' => 'Т',
108333 'ᲅ' => 'Т',
108334 'ᲆ' => 'Ъ',
108335 'ᲇ' => 'Ѣ',
108336 'ᲈ' => 'Ꙋ',
108337 'ᵹ' => 'Ᵹ',
108338 'ᵽ' => 'Ᵽ',
108339 'ᶎ' => 'Ᶎ',
108340 'ḁ' => 'Ḁ',
108341 'ḃ' => 'Ḃ',
108342 'ḅ' => 'Ḅ',
108343 'ḇ' => 'Ḇ',
108344 'ḉ' => 'Ḉ',
108345 'ḋ' => 'Ḋ',
108346 'ḍ' => 'Ḍ',
108347 'ḏ' => 'Ḏ',
108348 'ḑ' => 'Ḑ',
108349 'ḓ' => 'Ḓ',
108350 'ḕ' => 'Ḕ',
108351 'ḗ' => 'Ḗ',
108352 'ḙ' => 'Ḙ',
108353 'ḛ' => 'Ḛ',
108354 'ḝ' => 'Ḝ',
108355 'ḟ' => 'Ḟ',
108356 'ḡ' => 'Ḡ',
108357 'ḣ' => 'Ḣ',
108358 'ḥ' => 'Ḥ',
108359 'ḧ' => 'Ḧ',
108360 'ḩ' => 'Ḩ',
108361 'ḫ' => 'Ḫ',
108362 'ḭ' => 'Ḭ',
108363 'ḯ' => 'Ḯ',
108364 'ḱ' => 'Ḱ',
108365 'ḳ' => 'Ḳ',
108366 'ḵ' => 'Ḵ',
108367 'ḷ' => 'Ḷ',
108368 'ḹ' => 'Ḹ',
108369 'ḻ' => 'Ḻ',
108370 'ḽ' => 'Ḽ',
108371 'ḿ' => 'Ḿ',
108372 'ṁ' => 'Ṁ',
108373 'ṃ' => 'Ṃ',
108374 'ṅ' => 'Ṅ',
108375 'ṇ' => 'Ṇ',
108376 'ṉ' => 'Ṉ',
108377 'ṋ' => 'Ṋ',
108378 'ṍ' => 'Ṍ',
108379 'ṏ' => 'Ṏ',
108380 'ṑ' => 'Ṑ',
108381 'ṓ' => 'Ṓ',
108382 'ṕ' => 'Ṕ',
108383 'ṗ' => 'Ṗ',
108384 'ṙ' => 'Ṙ',
108385 'ṛ' => 'Ṛ',
108386 'ṝ' => 'Ṝ',
108387 'ṟ' => 'Ṟ',
108388 'ṡ' => 'Ṡ',
108389 'ṣ' => 'Ṣ',
108390 'ṥ' => 'Ṥ',
108391 'ṧ' => 'Ṧ',
108392 'ṩ' => 'Ṩ',
108393 'ṫ' => 'Ṫ',
108394 'ṭ' => 'Ṭ',
108395 'ṯ' => 'Ṯ',
108396 'ṱ' => 'Ṱ',
108397 'ṳ' => 'Ṳ',
108398 'ṵ' => 'Ṵ',
108399 'ṷ' => 'Ṷ',
108400 'ṹ' => 'Ṹ',
108401 'ṻ' => 'Ṻ',
108402 'ṽ' => 'Ṽ',
108403 'ṿ' => 'Ṿ',
108404 'ẁ' => 'Ẁ',
108405 'ẃ' => 'Ẃ',
108406 'ẅ' => 'Ẅ',
108407 'ẇ' => 'Ẇ',
108408 'ẉ' => 'Ẉ',
108409 'ẋ' => 'Ẋ',
108410 'ẍ' => 'Ẍ',
108411 'ẏ' => 'Ẏ',
108412 'ẑ' => 'Ẑ',
108413 'ẓ' => 'Ẓ',
108414 'ẕ' => 'Ẕ',
108415 'ẛ' => 'Ṡ',
108416 'ạ' => 'Ạ',
108417 'ả' => 'Ả',
108418 'ấ' => 'Ấ',
108419 'ầ' => 'Ầ',
108420 'ẩ' => 'Ẩ',
108421 'ẫ' => 'Ẫ',
108422 'ậ' => 'Ậ',
108423 'ắ' => 'Ắ',
108424 'ằ' => 'Ằ',
108425 'ẳ' => 'Ẳ',
108426 'ẵ' => 'Ẵ',
108427 'ặ' => 'Ặ',
108428 'ẹ' => 'Ẹ',
108429 'ẻ' => 'Ẻ',
108430 'ẽ' => 'Ẽ',
108431 'ế' => 'Ế',
108432 'ề' => 'Ề',
108433 'ể' => 'Ể',
108434 'ễ' => 'Ễ',
108435 'ệ' => 'Ệ',
108436 'ỉ' => 'Ỉ',
108437 'ị' => 'Ị',
108438 'ọ' => 'Ọ',
108439 'ỏ' => 'Ỏ',
108440 'ố' => 'Ố',
108441 'ồ' => 'Ồ',
108442 'ổ' => 'Ổ',
108443 'ỗ' => 'Ỗ',
108444 'ộ' => 'Ộ',
108445 'ớ' => 'Ớ',
108446 'ờ' => 'Ờ',
108447 'ở' => 'Ở',
108448 'ỡ' => 'Ỡ',
108449 'ợ' => 'Ợ',
108450 'ụ' => 'Ụ',
108451 'ủ' => 'Ủ',
108452 'ứ' => 'Ứ',
108453 'ừ' => 'Ừ',
108454 'ử' => 'Ử',
108455 'ữ' => 'Ữ',
108456 'ự' => 'Ự',
108457 'ỳ' => 'Ỳ',
108458 'ỵ' => 'Ỵ',
108459 'ỷ' => 'Ỷ',
108460 'ỹ' => 'Ỹ',
108461 'ỻ' => 'Ỻ',
108462 'ỽ' => 'Ỽ',
108463 'ỿ' => 'Ỿ',
108464 'ἀ' => 'Ἀ',
108465 'ἁ' => 'Ἁ',
108466 'ἂ' => 'Ἂ',
108467 'ἃ' => 'Ἃ',
108468 'ἄ' => 'Ἄ',
108469 'ἅ' => 'Ἅ',
108470 'ἆ' => 'Ἆ',
108471 'ἇ' => 'Ἇ',
108472 'ἐ' => 'Ἐ',
108473 'ἑ' => 'Ἑ',
108474 'ἒ' => 'Ἒ',
108475 'ἓ' => 'Ἓ',
108476 'ἔ' => 'Ἔ',
108477 'ἕ' => 'Ἕ',
108478 'ἠ' => 'Ἠ',
108479 'ἡ' => 'Ἡ',
108480 'ἢ' => 'Ἢ',
108481 'ἣ' => 'Ἣ',
108482 'ἤ' => 'Ἤ',
108483 'ἥ' => 'Ἥ',
108484 'ἦ' => 'Ἦ',
108485 'ἧ' => 'Ἧ',
108486 'ἰ' => 'Ἰ',
108487 'ἱ' => 'Ἱ',
108488 'ἲ' => 'Ἲ',
108489 'ἳ' => 'Ἳ',
108490 'ἴ' => 'Ἴ',
108491 'ἵ' => 'Ἵ',
108492 'ἶ' => 'Ἶ',
108493 'ἷ' => 'Ἷ',
108494 'ὀ' => 'Ὀ',
108495 'ὁ' => 'Ὁ',
108496 'ὂ' => 'Ὂ',
108497 'ὃ' => 'Ὃ',
108498 'ὄ' => 'Ὄ',
108499 'ὅ' => 'Ὅ',
108500 'ὑ' => 'Ὑ',
108501 'ὓ' => 'Ὓ',
108502 'ὕ' => 'Ὕ',
108503 'ὗ' => 'Ὗ',
108504 'ὠ' => 'Ὠ',
108505 'ὡ' => 'Ὡ',
108506 'ὢ' => 'Ὢ',
108507 'ὣ' => 'Ὣ',
108508 'ὤ' => 'Ὤ',
108509 'ὥ' => 'Ὥ',
108510 'ὦ' => 'Ὦ',
108511 'ὧ' => 'Ὧ',
108512 'ὰ' => 'Ὰ',
108513 'ά' => 'Ά',
108514 'ὲ' => 'Ὲ',
108515 'έ' => 'Έ',
108516 'ὴ' => 'Ὴ',
108517 'ή' => 'Ή',
108518 'ὶ' => 'Ὶ',
108519 'ί' => 'Ί',
108520 'ὸ' => 'Ὸ',
108521 'ό' => 'Ό',
108522 'ὺ' => 'Ὺ',
108523 'ύ' => 'Ύ',
108524 'ὼ' => 'Ὼ',
108525 'ώ' => 'Ώ',
108526 'ᾀ' => 'ᾈ',
108527 'ᾁ' => 'ᾉ',
108528 'ᾂ' => 'ᾊ',
108529 'ᾃ' => 'ᾋ',
108530 'ᾄ' => 'ᾌ',
108531 'ᾅ' => 'ᾍ',
108532 'ᾆ' => 'ᾎ',
108533 'ᾇ' => 'ᾏ',
108534 'ᾐ' => 'ᾘ',
108535 'ᾑ' => 'ᾙ',
108536 'ᾒ' => 'ᾚ',
108537 'ᾓ' => 'ᾛ',
108538 'ᾔ' => 'ᾜ',
108539 'ᾕ' => 'ᾝ',
108540 'ᾖ' => 'ᾞ',
108541 'ᾗ' => 'ᾟ',
108542 'ᾠ' => 'ᾨ',
108543 'ᾡ' => 'ᾩ',
108544 'ᾢ' => 'ᾪ',
108545 'ᾣ' => 'ᾫ',
108546 'ᾤ' => 'ᾬ',
108547 'ᾥ' => 'ᾭ',
108548 'ᾦ' => 'ᾮ',
108549 'ᾧ' => 'ᾯ',
108550 'ᾰ' => 'Ᾰ',
108551 'ᾱ' => 'Ᾱ',
108552 'ᾳ' => 'ᾼ',
108553 'ι' => 'Ι',
108554 'ῃ' => 'ῌ',
108555 'ῐ' => 'Ῐ',
108556 'ῑ' => 'Ῑ',
108557 'ῠ' => 'Ῠ',
108558 'ῡ' => 'Ῡ',
108559 'ῥ' => 'Ῥ',
108560 'ῳ' => 'ῼ',
108561 'ⅎ' => 'Ⅎ',
108562 'ⅰ' => 'Ⅰ',
108563 'ⅱ' => 'Ⅱ',
108564 'ⅲ' => 'Ⅲ',
108565 'ⅳ' => 'Ⅳ',
108566 'ⅴ' => 'Ⅴ',
108567 'ⅵ' => 'Ⅵ',
108568 'ⅶ' => 'Ⅶ',
108569 'ⅷ' => 'Ⅷ',
108570 'ⅸ' => 'Ⅸ',
108571 'ⅹ' => 'Ⅹ',
108572 'ⅺ' => 'Ⅺ',
108573 'ⅻ' => 'Ⅻ',
108574 'ⅼ' => 'Ⅼ',
108575 'ⅽ' => 'Ⅽ',
108576 'ⅾ' => 'Ⅾ',
108577 'ⅿ' => 'Ⅿ',
108578 'ↄ' => 'Ↄ',
108579 'ⓐ' => 'Ⓐ',
108580 'ⓑ' => 'Ⓑ',
108581 'ⓒ' => 'Ⓒ',
108582 'ⓓ' => 'Ⓓ',
108583 'ⓔ' => 'Ⓔ',
108584 'ⓕ' => 'Ⓕ',
108585 'ⓖ' => 'Ⓖ',
108586 'ⓗ' => 'Ⓗ',
108587 'ⓘ' => 'Ⓘ',
108588 'ⓙ' => 'Ⓙ',
108589 'ⓚ' => 'Ⓚ',
108590 'ⓛ' => 'Ⓛ',
108591 'ⓜ' => 'Ⓜ',
108592 'ⓝ' => 'Ⓝ',
108593 'ⓞ' => 'Ⓞ',
108594 'ⓟ' => 'Ⓟ',
108595 'ⓠ' => 'Ⓠ',
108596 'ⓡ' => 'Ⓡ',
108597 'ⓢ' => 'Ⓢ',
108598 'ⓣ' => 'Ⓣ',
108599 'ⓤ' => 'Ⓤ',
108600 'ⓥ' => 'Ⓥ',
108601 'ⓦ' => 'Ⓦ',
108602 'ⓧ' => 'Ⓧ',
108603 'ⓨ' => 'Ⓨ',
108604 'ⓩ' => 'Ⓩ',
108605 'ⰰ' => 'Ⰰ',
108606 'ⰱ' => 'Ⰱ',
108607 'ⰲ' => 'Ⰲ',
108608 'ⰳ' => 'Ⰳ',
108609 'ⰴ' => 'Ⰴ',
108610 'ⰵ' => 'Ⰵ',
108611 'ⰶ' => 'Ⰶ',
108612 'ⰷ' => 'Ⰷ',
108613 'ⰸ' => 'Ⰸ',
108614 'ⰹ' => 'Ⰹ',
108615 'ⰺ' => 'Ⰺ',
108616 'ⰻ' => 'Ⰻ',
108617 'ⰼ' => 'Ⰼ',
108618 'ⰽ' => 'Ⰽ',
108619 'ⰾ' => 'Ⰾ',
108620 'ⰿ' => 'Ⰿ',
108621 'ⱀ' => 'Ⱀ',
108622 'ⱁ' => 'Ⱁ',
108623 'ⱂ' => 'Ⱂ',
108624 'ⱃ' => 'Ⱃ',
108625 'ⱄ' => 'Ⱄ',
108626 'ⱅ' => 'Ⱅ',
108627 'ⱆ' => 'Ⱆ',
108628 'ⱇ' => 'Ⱇ',
108629 'ⱈ' => 'Ⱈ',
108630 'ⱉ' => 'Ⱉ',
108631 'ⱊ' => 'Ⱊ',
108632 'ⱋ' => 'Ⱋ',
108633 'ⱌ' => 'Ⱌ',
108634 'ⱍ' => 'Ⱍ',
108635 'ⱎ' => 'Ⱎ',
108636 'ⱏ' => 'Ⱏ',
108637 'ⱐ' => 'Ⱐ',
108638 'ⱑ' => 'Ⱑ',
108639 'ⱒ' => 'Ⱒ',
108640 'ⱓ' => 'Ⱓ',
108641 'ⱔ' => 'Ⱔ',
108642 'ⱕ' => 'Ⱕ',
108643 'ⱖ' => 'Ⱖ',
108644 'ⱗ' => 'Ⱗ',
108645 'ⱘ' => 'Ⱘ',
108646 'ⱙ' => 'Ⱙ',
108647 'ⱚ' => 'Ⱚ',
108648 'ⱛ' => 'Ⱛ',
108649 'ⱜ' => 'Ⱜ',
108650 'ⱝ' => 'Ⱝ',
108651 'ⱞ' => 'Ⱞ',
108652 'ⱡ' => 'Ⱡ',
108653 'ⱥ' => 'Ⱥ',
108654 'ⱦ' => 'Ⱦ',
108655 'ⱨ' => 'Ⱨ',
108656 'ⱪ' => 'Ⱪ',
108657 'ⱬ' => 'Ⱬ',
108658 'ⱳ' => 'Ⱳ',
108659 'ⱶ' => 'Ⱶ',
108660 'ⲁ' => 'Ⲁ',
108661 'ⲃ' => 'Ⲃ',
108662 'ⲅ' => 'Ⲅ',
108663 'ⲇ' => 'Ⲇ',
108664 'ⲉ' => 'Ⲉ',
108665 'ⲋ' => 'Ⲋ',
108666 'ⲍ' => 'Ⲍ',
108667 'ⲏ' => 'Ⲏ',
108668 'ⲑ' => 'Ⲑ',
108669 'ⲓ' => 'Ⲓ',
108670 'ⲕ' => 'Ⲕ',
108671 'ⲗ' => 'Ⲗ',
108672 'ⲙ' => 'Ⲙ',
108673 'ⲛ' => 'Ⲛ',
108674 'ⲝ' => 'Ⲝ',
108675 'ⲟ' => 'Ⲟ',
108676 'ⲡ' => 'Ⲡ',
108677 'ⲣ' => 'Ⲣ',
108678 'ⲥ' => 'Ⲥ',
108679 'ⲧ' => 'Ⲧ',
108680 'ⲩ' => 'Ⲩ',
108681 'ⲫ' => 'Ⲫ',
108682 'ⲭ' => 'Ⲭ',
108683 'ⲯ' => 'Ⲯ',
108684 'ⲱ' => 'Ⲱ',
108685 'ⲳ' => 'Ⲳ',
108686 'ⲵ' => 'Ⲵ',
108687 'ⲷ' => 'Ⲷ',
108688 'ⲹ' => 'Ⲹ',
108689 'ⲻ' => 'Ⲻ',
108690 'ⲽ' => 'Ⲽ',
108691 'ⲿ' => 'Ⲿ',
108692 'ⳁ' => 'Ⳁ',
108693 'ⳃ' => 'Ⳃ',
108694 'ⳅ' => 'Ⳅ',
108695 'ⳇ' => 'Ⳇ',
108696 'ⳉ' => 'Ⳉ',
108697 'ⳋ' => 'Ⳋ',
108698 'ⳍ' => 'Ⳍ',
108699 'ⳏ' => 'Ⳏ',
108700 'ⳑ' => 'Ⳑ',
108701 'ⳓ' => 'Ⳓ',
108702 'ⳕ' => 'Ⳕ',
108703 'ⳗ' => 'Ⳗ',
108704 'ⳙ' => 'Ⳙ',
108705 'ⳛ' => 'Ⳛ',
108706 'ⳝ' => 'Ⳝ',
108707 'ⳟ' => 'Ⳟ',
108708 'ⳡ' => 'Ⳡ',
108709 'ⳣ' => 'Ⳣ',
108710 'ⳬ' => 'Ⳬ',
108711 'ⳮ' => 'Ⳮ',
108712 'ⳳ' => 'Ⳳ',
108713 'ⴀ' => 'Ⴀ',
108714 'ⴁ' => 'Ⴁ',
108715 'ⴂ' => 'Ⴂ',
108716 'ⴃ' => 'Ⴃ',
108717 'ⴄ' => 'Ⴄ',
108718 'ⴅ' => 'Ⴅ',
108719 'ⴆ' => 'Ⴆ',
108720 'ⴇ' => 'Ⴇ',
108721 'ⴈ' => 'Ⴈ',
108722 'ⴉ' => 'Ⴉ',
108723 'ⴊ' => 'Ⴊ',
108724 'ⴋ' => 'Ⴋ',
108725 'ⴌ' => 'Ⴌ',
108726 'ⴍ' => 'Ⴍ',
108727 'ⴎ' => 'Ⴎ',
108728 'ⴏ' => 'Ⴏ',
108729 'ⴐ' => 'Ⴐ',
108730 'ⴑ' => 'Ⴑ',
108731 'ⴒ' => 'Ⴒ',
108732 'ⴓ' => 'Ⴓ',
108733 'ⴔ' => 'Ⴔ',
108734 'ⴕ' => 'Ⴕ',
108735 'ⴖ' => 'Ⴖ',
108736 'ⴗ' => 'Ⴗ',
108737 'ⴘ' => 'Ⴘ',
108738 'ⴙ' => 'Ⴙ',
108739 'ⴚ' => 'Ⴚ',
108740 'ⴛ' => 'Ⴛ',
108741 'ⴜ' => 'Ⴜ',
108742 'ⴝ' => 'Ⴝ',
108743 'ⴞ' => 'Ⴞ',
108744 'ⴟ' => 'Ⴟ',
108745 'ⴠ' => 'Ⴠ',
108746 'ⴡ' => 'Ⴡ',
108747 'ⴢ' => 'Ⴢ',
108748 'ⴣ' => 'Ⴣ',
108749 'ⴤ' => 'Ⴤ',
108750 'ⴥ' => 'Ⴥ',
108751 'ⴧ' => 'Ⴧ',
108752 'ⴭ' => 'Ⴭ',
108753 'ꙁ' => 'Ꙁ',
108754 'ꙃ' => 'Ꙃ',
108755 'ꙅ' => 'Ꙅ',
108756 'ꙇ' => 'Ꙇ',
108757 'ꙉ' => 'Ꙉ',
108758 'ꙋ' => 'Ꙋ',
108759 'ꙍ' => 'Ꙍ',
108760 'ꙏ' => 'Ꙏ',
108761 'ꙑ' => 'Ꙑ',
108762 'ꙓ' => 'Ꙓ',
108763 'ꙕ' => 'Ꙕ',
108764 'ꙗ' => 'Ꙗ',
108765 'ꙙ' => 'Ꙙ',
108766 'ꙛ' => 'Ꙛ',
108767 'ꙝ' => 'Ꙝ',
108768 'ꙟ' => 'Ꙟ',
108769 'ꙡ' => 'Ꙡ',
108770 'ꙣ' => 'Ꙣ',
108771 'ꙥ' => 'Ꙥ',
108772 'ꙧ' => 'Ꙧ',
108773 'ꙩ' => 'Ꙩ',
108774 'ꙫ' => 'Ꙫ',
108775 'ꙭ' => 'Ꙭ',
108776 'ꚁ' => 'Ꚁ',
108777 'ꚃ' => 'Ꚃ',
108778 'ꚅ' => 'Ꚅ',
108779 'ꚇ' => 'Ꚇ',
108780 'ꚉ' => 'Ꚉ',
108781 'ꚋ' => 'Ꚋ',
108782 'ꚍ' => 'Ꚍ',
108783 'ꚏ' => 'Ꚏ',
108784 'ꚑ' => 'Ꚑ',
108785 'ꚓ' => 'Ꚓ',
108786 'ꚕ' => 'Ꚕ',
108787 'ꚗ' => 'Ꚗ',
108788 'ꚙ' => 'Ꚙ',
108789 'ꚛ' => 'Ꚛ',
108790 'ꜣ' => 'Ꜣ',
108791 'ꜥ' => 'Ꜥ',
108792 'ꜧ' => 'Ꜧ',
108793 'ꜩ' => 'Ꜩ',
108794 'ꜫ' => 'Ꜫ',
108795 'ꜭ' => 'Ꜭ',
108796 'ꜯ' => 'Ꜯ',
108797 'ꜳ' => 'Ꜳ',
108798 'ꜵ' => 'Ꜵ',
108799 'ꜷ' => 'Ꜷ',
108800 'ꜹ' => 'Ꜹ',
108801 'ꜻ' => 'Ꜻ',
108802 'ꜽ' => 'Ꜽ',
108803 'ꜿ' => 'Ꜿ',
108804 'ꝁ' => 'Ꝁ',
108805 'ꝃ' => 'Ꝃ',
108806 'ꝅ' => 'Ꝅ',
108807 'ꝇ' => 'Ꝇ',
108808 'ꝉ' => 'Ꝉ',
108809 'ꝋ' => 'Ꝋ',
108810 'ꝍ' => 'Ꝍ',
108811 'ꝏ' => 'Ꝏ',
108812 'ꝑ' => 'Ꝑ',
108813 'ꝓ' => 'Ꝓ',
108814 'ꝕ' => 'Ꝕ',
108815 'ꝗ' => 'Ꝗ',
108816 'ꝙ' => 'Ꝙ',
108817 'ꝛ' => 'Ꝛ',
108818 'ꝝ' => 'Ꝝ',
108819 'ꝟ' => 'Ꝟ',
108820 'ꝡ' => 'Ꝡ',
108821 'ꝣ' => 'Ꝣ',
108822 'ꝥ' => 'Ꝥ',
108823 'ꝧ' => 'Ꝧ',
108824 'ꝩ' => 'Ꝩ',
108825 'ꝫ' => 'Ꝫ',
108826 'ꝭ' => 'Ꝭ',
108827 'ꝯ' => 'Ꝯ',
108828 'ꝺ' => 'Ꝺ',
108829 'ꝼ' => 'Ꝼ',
108830 'ꝿ' => 'Ꝿ',
108831 'ꞁ' => 'Ꞁ',
108832 'ꞃ' => 'Ꞃ',
108833 'ꞅ' => 'Ꞅ',
108834 'ꞇ' => 'Ꞇ',
108835 'ꞌ' => 'Ꞌ',
108836 'ꞑ' => 'Ꞑ',
108837 'ꞓ' => 'Ꞓ',
108838 'ꞔ' => 'Ꞔ',
108839 'ꞗ' => 'Ꞗ',
108840 'ꞙ' => 'Ꞙ',
108841 'ꞛ' => 'Ꞛ',
108842 'ꞝ' => 'Ꞝ',
108843 'ꞟ' => 'Ꞟ',
108844 'ꞡ' => 'Ꞡ',
108845 'ꞣ' => 'Ꞣ',
108846 'ꞥ' => 'Ꞥ',
108847 'ꞧ' => 'Ꞧ',
108848 'ꞩ' => 'Ꞩ',
108849 'ꞵ' => 'Ꞵ',
108850 'ꞷ' => 'Ꞷ',
108851 'ꞹ' => 'Ꞹ',
108852 'ꞻ' => 'Ꞻ',
108853 'ꞽ' => 'Ꞽ',
108854 'ꞿ' => 'Ꞿ',
108855 'ꟃ' => 'Ꟃ',
108856 'ꟈ' => 'Ꟈ',
108857 'ꟊ' => 'Ꟊ',
108858 'ꟶ' => 'Ꟶ',
108859 'ꭓ' => 'Ꭓ',
108860 'ꭰ' => 'Ꭰ',
108861 'ꭱ' => 'Ꭱ',
108862 'ꭲ' => 'Ꭲ',
108863 'ꭳ' => 'Ꭳ',
108864 'ꭴ' => 'Ꭴ',
108865 'ꭵ' => 'Ꭵ',
108866 'ꭶ' => 'Ꭶ',
108867 'ꭷ' => 'Ꭷ',
108868 'ꭸ' => 'Ꭸ',
108869 'ꭹ' => 'Ꭹ',
108870 'ꭺ' => 'Ꭺ',
108871 'ꭻ' => 'Ꭻ',
108872 'ꭼ' => 'Ꭼ',
108873 'ꭽ' => 'Ꭽ',
108874 'ꭾ' => 'Ꭾ',
108875 'ꭿ' => 'Ꭿ',
108876 'ꮀ' => 'Ꮀ',
108877 'ꮁ' => 'Ꮁ',
108878 'ꮂ' => 'Ꮂ',
108879 'ꮃ' => 'Ꮃ',
108880 'ꮄ' => 'Ꮄ',
108881 'ꮅ' => 'Ꮅ',
108882 'ꮆ' => 'Ꮆ',
108883 'ꮇ' => 'Ꮇ',
108884 'ꮈ' => 'Ꮈ',
108885 'ꮉ' => 'Ꮉ',
108886 'ꮊ' => 'Ꮊ',
108887 'ꮋ' => 'Ꮋ',
108888 'ꮌ' => 'Ꮌ',
108889 'ꮍ' => 'Ꮍ',
108890 'ꮎ' => 'Ꮎ',
108891 'ꮏ' => 'Ꮏ',
108892 'ꮐ' => 'Ꮐ',
108893 'ꮑ' => 'Ꮑ',
108894 'ꮒ' => 'Ꮒ',
108895 'ꮓ' => 'Ꮓ',
108896 'ꮔ' => 'Ꮔ',
108897 'ꮕ' => 'Ꮕ',
108898 'ꮖ' => 'Ꮖ',
108899 'ꮗ' => 'Ꮗ',
108900 'ꮘ' => 'Ꮘ',
108901 'ꮙ' => 'Ꮙ',
108902 'ꮚ' => 'Ꮚ',
108903 'ꮛ' => 'Ꮛ',
108904 'ꮜ' => 'Ꮜ',
108905 'ꮝ' => 'Ꮝ',
108906 'ꮞ' => 'Ꮞ',
108907 'ꮟ' => 'Ꮟ',
108908 'ꮠ' => 'Ꮠ',
108909 'ꮡ' => 'Ꮡ',
108910 'ꮢ' => 'Ꮢ',
108911 'ꮣ' => 'Ꮣ',
108912 'ꮤ' => 'Ꮤ',
108913 'ꮥ' => 'Ꮥ',
108914 'ꮦ' => 'Ꮦ',
108915 'ꮧ' => 'Ꮧ',
108916 'ꮨ' => 'Ꮨ',
108917 'ꮩ' => 'Ꮩ',
108918 'ꮪ' => 'Ꮪ',
108919 'ꮫ' => 'Ꮫ',
108920 'ꮬ' => 'Ꮬ',
108921 'ꮭ' => 'Ꮭ',
108922 'ꮮ' => 'Ꮮ',
108923 'ꮯ' => 'Ꮯ',
108924 'ꮰ' => 'Ꮰ',
108925 'ꮱ' => 'Ꮱ',
108926 'ꮲ' => 'Ꮲ',
108927 'ꮳ' => 'Ꮳ',
108928 'ꮴ' => 'Ꮴ',
108929 'ꮵ' => 'Ꮵ',
108930 'ꮶ' => 'Ꮶ',
108931 'ꮷ' => 'Ꮷ',
108932 'ꮸ' => 'Ꮸ',
108933 'ꮹ' => 'Ꮹ',
108934 'ꮺ' => 'Ꮺ',
108935 'ꮻ' => 'Ꮻ',
108936 'ꮼ' => 'Ꮼ',
108937 'ꮽ' => 'Ꮽ',
108938 'ꮾ' => 'Ꮾ',
108939 'ꮿ' => 'Ꮿ',
108940 'a' => 'A',
108941 'b' => 'B',
108942 'c' => 'C',
108943 'd' => 'D',
108944 'e' => 'E',
108945 'f' => 'F',
108946 'g' => 'G',
108947 'h' => 'H',
108948 'i' => 'I',
108949 'j' => 'J',
108950 'k' => 'K',
108951 'l' => 'L',
108952 'm' => 'M',
108953 'n' => 'N',
108954 'o' => 'O',
108955 'p' => 'P',
108956 'q' => 'Q',
108957 'r' => 'R',
108958 's' => 'S',
108959 't' => 'T',
108960 'u' => 'U',
108961 'v' => 'V',
108962 'w' => 'W',
108963 'x' => 'X',
108964 'y' => 'Y',
108965 'z' => 'Z',
108966 '𐐨' => '𐐀',
108967 '𐐩' => '𐐁',
108968 '𐐪' => '𐐂',
108969 '𐐫' => '𐐃',
108970 '𐐬' => '𐐄',
108971 '𐐭' => '𐐅',
108972 '𐐮' => '𐐆',
108973 '𐐯' => '𐐇',
108974 '𐐰' => '𐐈',
108975 '𐐱' => '𐐉',
108976 '𐐲' => '𐐊',
108977 '𐐳' => '𐐋',
108978 '𐐴' => '𐐌',
108979 '𐐵' => '𐐍',
108980 '𐐶' => '𐐎',
108981 '𐐷' => '𐐏',
108982 '𐐸' => '𐐐',
108983 '𐐹' => '𐐑',
108984 '𐐺' => '𐐒',
108985 '𐐻' => '𐐓',
108986 '𐐼' => '𐐔',
108987 '𐐽' => '𐐕',
108988 '𐐾' => '𐐖',
108989 '𐐿' => '𐐗',
108990 '𐑀' => '𐐘',
108991 '𐑁' => '𐐙',
108992 '𐑂' => '𐐚',
108993 '𐑃' => '𐐛',
108994 '𐑄' => '𐐜',
108995 '𐑅' => '𐐝',
108996 '𐑆' => '𐐞',
108997 '𐑇' => '𐐟',
108998 '𐑈' => '𐐠',
108999 '𐑉' => '𐐡',
109000 '𐑊' => '𐐢',
109001 '𐑋' => '𐐣',
109002 '𐑌' => '𐐤',
109003 '𐑍' => '𐐥',
109004 '𐑎' => '𐐦',
109005 '𐑏' => '𐐧',
109006 '𐓘' => '𐒰',
109007 '𐓙' => '𐒱',
109008 '𐓚' => '𐒲',
109009 '𐓛' => '𐒳',
109010 '𐓜' => '𐒴',
109011 '𐓝' => '𐒵',
109012 '𐓞' => '𐒶',
109013 '𐓟' => '𐒷',
109014 '𐓠' => '𐒸',
109015 '𐓡' => '𐒹',
109016 '𐓢' => '𐒺',
109017 '𐓣' => '𐒻',
109018 '𐓤' => '𐒼',
109019 '𐓥' => '𐒽',
109020 '𐓦' => '𐒾',
109021 '𐓧' => '𐒿',
109022 '𐓨' => '𐓀',
109023 '𐓩' => '𐓁',
109024 '𐓪' => '𐓂',
109025 '𐓫' => '𐓃',
109026 '𐓬' => '𐓄',
109027 '𐓭' => '𐓅',
109028 '𐓮' => '𐓆',
109029 '𐓯' => '𐓇',
109030 '𐓰' => '𐓈',
109031 '𐓱' => '𐓉',
109032 '𐓲' => '𐓊',
109033 '𐓳' => '𐓋',
109034 '𐓴' => '𐓌',
109035 '𐓵' => '𐓍',
109036 '𐓶' => '𐓎',
109037 '𐓷' => '𐓏',
109038 '𐓸' => '𐓐',
109039 '𐓹' => '𐓑',
109040 '𐓺' => '𐓒',
109041 '𐓻' => '𐓓',
109042 '𐳀' => '𐲀',
109043 '𐳁' => '𐲁',
109044 '𐳂' => '𐲂',
109045 '𐳃' => '𐲃',
109046 '𐳄' => '𐲄',
109047 '𐳅' => '𐲅',
109048 '𐳆' => '𐲆',
109049 '𐳇' => '𐲇',
109050 '𐳈' => '𐲈',
109051 '𐳉' => '𐲉',
109052 '𐳊' => '𐲊',
109053 '𐳋' => '𐲋',
109054 '𐳌' => '𐲌',
109055 '𐳍' => '𐲍',
109056 '𐳎' => '𐲎',
109057 '𐳏' => '𐲏',
109058 '𐳐' => '𐲐',
109059 '𐳑' => '𐲑',
109060 '𐳒' => '𐲒',
109061 '𐳓' => '𐲓',
109062 '𐳔' => '𐲔',
109063 '𐳕' => '𐲕',
109064 '𐳖' => '𐲖',
109065 '𐳗' => '𐲗',
109066 '𐳘' => '𐲘',
109067 '𐳙' => '𐲙',
109068 '𐳚' => '𐲚',
109069 '𐳛' => '𐲛',
109070 '𐳜' => '𐲜',
109071 '𐳝' => '𐲝',
109072 '𐳞' => '𐲞',
109073 '𐳟' => '𐲟',
109074 '𐳠' => '𐲠',
109075 '𐳡' => '𐲡',
109076 '𐳢' => '𐲢',
109077 '𐳣' => '𐲣',
109078 '𐳤' => '𐲤',
109079 '𐳥' => '𐲥',
109080 '𐳦' => '𐲦',
109081 '𐳧' => '𐲧',
109082 '𐳨' => '𐲨',
109083 '𐳩' => '𐲩',
109084 '𐳪' => '𐲪',
109085 '𐳫' => '𐲫',
109086 '𐳬' => '𐲬',
109087 '𐳭' => '𐲭',
109088 '𐳮' => '𐲮',
109089 '𐳯' => '𐲯',
109090 '𐳰' => '𐲰',
109091 '𐳱' => '𐲱',
109092 '𐳲' => '𐲲',
109093 '𑣀' => '𑢠',
109094 '𑣁' => '𑢡',
109095 '𑣂' => '𑢢',
109096 '𑣃' => '𑢣',
109097 '𑣄' => '𑢤',
109098 '𑣅' => '𑢥',
109099 '𑣆' => '𑢦',
109100 '𑣇' => '𑢧',
109101 '𑣈' => '𑢨',
109102 '𑣉' => '𑢩',
109103 '𑣊' => '𑢪',
109104 '𑣋' => '𑢫',
109105 '𑣌' => '𑢬',
109106 '𑣍' => '𑢭',
109107 '𑣎' => '𑢮',
109108 '𑣏' => '𑢯',
109109 '𑣐' => '𑢰',
109110 '𑣑' => '𑢱',
109111 '𑣒' => '𑢲',
109112 '𑣓' => '𑢳',
109113 '𑣔' => '𑢴',
109114 '𑣕' => '𑢵',
109115 '𑣖' => '𑢶',
109116 '𑣗' => '𑢷',
109117 '𑣘' => '𑢸',
109118 '𑣙' => '𑢹',
109119 '𑣚' => '𑢺',
109120 '𑣛' => '𑢻',
109121 '𑣜' => '𑢼',
109122 '𑣝' => '𑢽',
109123 '𑣞' => '𑢾',
109124 '𑣟' => '𑢿',
109125 '𖹠' => '𖹀',
109126 '𖹡' => '𖹁',
109127 '𖹢' => '𖹂',
109128 '𖹣' => '𖹃',
109129 '𖹤' => '𖹄',
109130 '𖹥' => '𖹅',
109131 '𖹦' => '𖹆',
109132 '𖹧' => '𖹇',
109133 '𖹨' => '𖹈',
109134 '𖹩' => '𖹉',
109135 '𖹪' => '𖹊',
109136 '𖹫' => '𖹋',
109137 '𖹬' => '𖹌',
109138 '𖹭' => '𖹍',
109139 '𖹮' => '𖹎',
109140 '𖹯' => '𖹏',
109141 '𖹰' => '𖹐',
109142 '𖹱' => '𖹑',
109143 '𖹲' => '𖹒',
109144 '𖹳' => '𖹓',
109145 '𖹴' => '𖹔',
109146 '𖹵' => '𖹕',
109147 '𖹶' => '𖹖',
109148 '𖹷' => '𖹗',
109149 '𖹸' => '𖹘',
109150 '𖹹' => '𖹙',
109151 '𖹺' => '𖹚',
109152 '𖹻' => '𖹛',
109153 '𖹼' => '𖹜',
109154 '𖹽' => '𖹝',
109155 '𖹾' => '𖹞',
109156 '𖹿' => '𖹟',
109157 '𞤢' => '𞤀',
109158 '𞤣' => '𞤁',
109159 '𞤤' => '𞤂',
109160 '𞤥' => '𞤃',
109161 '𞤦' => '𞤄',
109162 '𞤧' => '𞤅',
109163 '𞤨' => '𞤆',
109164 '𞤩' => '𞤇',
109165 '𞤪' => '𞤈',
109166 '𞤫' => '𞤉',
109167 '𞤬' => '𞤊',
109168 '𞤭' => '𞤋',
109169 '𞤮' => '𞤌',
109170 '𞤯' => '𞤍',
109171 '𞤰' => '𞤎',
109172 '𞤱' => '𞤏',
109173 '𞤲' => '𞤐',
109174 '𞤳' => '𞤑',
109175 '𞤴' => '𞤒',
109176 '𞤵' => '𞤓',
109177 '𞤶' => '𞤔',
109178 '𞤷' => '𞤕',
109179 '𞤸' => '𞤖',
109180 '𞤹' => '𞤗',
109181 '𞤺' => '𞤘',
109182 '𞤻' => '𞤙',
109183 '𞤼' => '𞤚',
109184 '𞤽' => '𞤛',
109185 '𞤾' => '𞤜',
109186 '𞤿' => '𞤝',
109187 '𞥀' => '𞤞',
109188 '𞥁' => '𞤟',
109189 '𞥂' => '𞤠',
109190 '𞥃' => '𞤡',
109191 );
109192 <?php
109193 
109194 
109195 
109196 
109197 
109198 
109199 
109200 
109201 
109202 
109203 use Symfony\Polyfill\Mbstring as p;
109204 
109205 if (!function_exists('mb_convert_encoding')) {
109206 function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); }
109207 }
109208 if (!function_exists('mb_decode_mimeheader')) {
109209 function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); }
109210 }
109211 if (!function_exists('mb_encode_mimeheader')) {
109212 function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = null, $indent = null) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); }
109213 }
109214 if (!function_exists('mb_decode_numericentity')) {
109215 function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); }
109216 }
109217 if (!function_exists('mb_encode_numericentity')) {
109218 function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); }
109219 }
109220 if (!function_exists('mb_convert_case')) {
109221 function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); }
109222 }
109223 if (!function_exists('mb_internal_encoding')) {
109224 function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); }
109225 }
109226 if (!function_exists('mb_language')) {
109227 function mb_language($language = null) { return p\Mbstring::mb_language($language); }
109228 }
109229 if (!function_exists('mb_list_encodings')) {
109230 function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); }
109231 }
109232 if (!function_exists('mb_encoding_aliases')) {
109233 function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); }
109234 }
109235 if (!function_exists('mb_check_encoding')) {
109236 function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); }
109237 }
109238 if (!function_exists('mb_detect_encoding')) {
109239 function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); }
109240 }
109241 if (!function_exists('mb_detect_order')) {
109242 function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); }
109243 }
109244 if (!function_exists('mb_parse_str')) {
109245 function mb_parse_str($string, &$result = array()) { parse_str($string, $result); }
109246 }
109247 if (!function_exists('mb_strlen')) {
109248 function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); }
109249 }
109250 if (!function_exists('mb_strpos')) {
109251 function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); }
109252 }
109253 if (!function_exists('mb_strtolower')) {
109254 function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); }
109255 }
109256 if (!function_exists('mb_strtoupper')) {
109257 function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); }
109258 }
109259 if (!function_exists('mb_substitute_character')) {
109260 function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); }
109261 }
109262 if (!function_exists('mb_substr')) {
109263 function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); }
109264 }
109265 if (!function_exists('mb_stripos')) {
109266 function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); }
109267 }
109268 if (!function_exists('mb_stristr')) {
109269 function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); }
109270 }
109271 if (!function_exists('mb_strrchr')) {
109272 function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); }
109273 }
109274 if (!function_exists('mb_strrichr')) {
109275 function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); }
109276 }
109277 if (!function_exists('mb_strripos')) {
109278 function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); }
109279 }
109280 if (!function_exists('mb_strrpos')) {
109281 function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); }
109282 }
109283 if (!function_exists('mb_strstr')) {
109284 function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); }
109285 }
109286 if (!function_exists('mb_get_info')) {
109287 function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); }
109288 }
109289 if (!function_exists('mb_http_output')) {
109290 function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); }
109291 }
109292 if (!function_exists('mb_strwidth')) {
109293 function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); }
109294 }
109295 if (!function_exists('mb_substr_count')) {
109296 function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); }
109297 }
109298 if (!function_exists('mb_output_handler')) {
109299 function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); }
109300 }
109301 if (!function_exists('mb_http_input')) {
109302 function mb_http_input($type = '') { return p\Mbstring::mb_http_input($type); }
109303 }
109304 
109305 if (PHP_VERSION_ID >= 80000) {
109306 require_once __DIR__.'/Resources/mb_convert_variables.php8';
109307 } elseif (!function_exists('mb_convert_variables')) {
109308 function mb_convert_variables($toEncoding, $fromEncoding, &$a = null, &$b = null, &$c = null, &$d = null, &$e = null, &$f = null) { return p\Mbstring::mb_convert_variables($toEncoding, $fromEncoding, $a, $b, $c, $d, $e, $f); }
109309 }
109310 
109311 if (!function_exists('mb_ord')) {
109312 function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); }
109313 }
109314 if (!function_exists('mb_chr')) {
109315 function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); }
109316 }
109317 if (!function_exists('mb_scrub')) {
109318 function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
109319 }
109320 if (!function_exists('mb_str_split')) {
109321 function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); }
109322 }
109323 
109324 if (extension_loaded('mbstring')) {
109325 return;
109326 }
109327 
109328 if (!defined('MB_CASE_UPPER')) {
109329 define('MB_CASE_UPPER', 0);
109330 }
109331 if (!defined('MB_CASE_LOWER')) {
109332 define('MB_CASE_LOWER', 1);
109333 }
109334 if (!defined('MB_CASE_TITLE')) {
109335 define('MB_CASE_TITLE', 2);
109336 }
109337 <?php
109338 
109339 
109340 
109341 
109342 
109343 
109344 
109345 
109346 
109347 
109348 namespace Symfony\Component\Process\Exception;
109349 
109350 
109351 
109352 
109353 
109354 
109355 interface ExceptionInterface
109356 {
109357 }
109358 <?php
109359 
109360 
109361 
109362 
109363 
109364 
109365 
109366 
109367 
109368 
109369 namespace Symfony\Component\Process\Exception;
109370 
109371 
109372 
109373 
109374 
109375 
109376 class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
109377 {
109378 }
109379 <?php
109380 
109381 
109382 
109383 
109384 
109385 
109386 
109387 
109388 
109389 
109390 namespace Symfony\Component\Process\Exception;
109391 
109392 
109393 
109394 
109395 
109396 
109397 class LogicException extends \LogicException implements ExceptionInterface
109398 {
109399 }
109400 <?php
109401 
109402 
109403 
109404 
109405 
109406 
109407 
109408 
109409 
109410 
109411 namespace Symfony\Component\Process\Exception;
109412 
109413 use Symfony\Component\Process\Process;
109414 
109415 
109416 
109417 
109418 
109419 
109420 class ProcessFailedException extends RuntimeException
109421 {
109422 private $process;
109423 
109424 public function __construct(Process $process)
109425 {
109426 if ($process->isSuccessful()) {
109427 throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
109428 }
109429 
109430 $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
109431 $process->getCommandLine(),
109432 $process->getExitCode(),
109433 $process->getExitCodeText(),
109434 $process->getWorkingDirectory()
109435 );
109436 
109437 if (!$process->isOutputDisabled()) {
109438 $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
109439 $process->getOutput(),
109440 $process->getErrorOutput()
109441 );
109442 }
109443 
109444 parent::__construct($error);
109445 
109446 $this->process = $process;
109447 }
109448 
109449 public function getProcess()
109450 {
109451 return $this->process;
109452 }
109453 }
109454 <?php
109455 
109456 
109457 
109458 
109459 
109460 
109461 
109462 
109463 
109464 
109465 namespace Symfony\Component\Process\Exception;
109466 
109467 use Symfony\Component\Process\Process;
109468 
109469 
109470 
109471 
109472 
109473 
109474 class ProcessTimedOutException extends RuntimeException
109475 {
109476 const TYPE_GENERAL = 1;
109477 const TYPE_IDLE = 2;
109478 
109479 private $process;
109480 private $timeoutType;
109481 
109482 public function __construct(Process $process, $timeoutType)
109483 {
109484 $this->process = $process;
109485 $this->timeoutType = $timeoutType;
109486 
109487 parent::__construct(sprintf(
109488 'The process "%s" exceeded the timeout of %s seconds.',
109489 $process->getCommandLine(),
109490 $this->getExceededTimeout()
109491 ));
109492 }
109493 
109494 public function getProcess()
109495 {
109496 return $this->process;
109497 }
109498 
109499 public function isGeneralTimeout()
109500 {
109501 return self::TYPE_GENERAL === $this->timeoutType;
109502 }
109503 
109504 public function isIdleTimeout()
109505 {
109506 return self::TYPE_IDLE === $this->timeoutType;
109507 }
109508 
109509 public function getExceededTimeout()
109510 {
109511 switch ($this->timeoutType) {
109512 case self::TYPE_GENERAL:
109513 return $this->process->getTimeout();
109514 
109515 case self::TYPE_IDLE:
109516 return $this->process->getIdleTimeout();
109517 
109518 default:
109519 throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
109520 }
109521 }
109522 }
109523 <?php
109524 
109525 
109526 
109527 
109528 
109529 
109530 
109531 
109532 
109533 
109534 namespace Symfony\Component\Process\Exception;
109535 
109536 
109537 
109538 
109539 
109540 
109541 class RuntimeException extends \RuntimeException implements ExceptionInterface
109542 {
109543 }
109544 <?php
109545 
109546 
109547 
109548 
109549 
109550 
109551 
109552 
109553 
109554 
109555 namespace Symfony\Component\Process;
109556 
109557 
109558 
109559 
109560 
109561 
109562 
109563 class ExecutableFinder
109564 {
109565 private $suffixes = array('.exe', '.bat', '.cmd', '.com');
109566 
109567 
109568 
109569 
109570 public function setSuffixes(array $suffixes)
109571 {
109572 $this->suffixes = $suffixes;
109573 }
109574 
109575 
109576 
109577 
109578 
109579 
109580 public function addSuffix($suffix)
109581 {
109582 $this->suffixes[] = $suffix;
109583 }
109584 
109585 
109586 
109587 
109588 
109589 
109590 
109591 
109592 
109593 
109594 public function find($name, $default = null, array $extraDirs = array())
109595 {
109596 if (ini_get('open_basedir')) {
109597 $searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
109598 $dirs = array();
109599 foreach ($searchPath as $path) {
109600 
109601 if (@is_dir($path)) {
109602 $dirs[] = $path;
109603 } else {
109604 if (basename($path) == $name && @is_executable($path)) {
109605 return $path;
109606 }
109607 }
109608 }
109609 } else {
109610 $dirs = array_merge(
109611 explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
109612 $extraDirs
109613 );
109614 }
109615 
109616 $suffixes = array('');
109617 if ('\\' === \DIRECTORY_SEPARATOR) {
109618 $pathExt = getenv('PATHEXT');
109619 $suffixes = array_merge($pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes);
109620 }
109621 foreach ($suffixes as $suffix) {
109622 foreach ($dirs as $dir) {
109623 if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) {
109624 return $file;
109625 }
109626 }
109627 }
109628 
109629 return $default;
109630 }
109631 }
109632 
109633 Copyright (c) 2004-2018 Fabien Potencier
109634 
109635 Permission is hereby granted, free of charge, to any person obtaining a copy
109636 of this software and associated documentation files (the "Software"), to deal
109637 in the Software without restriction, including without limitation the rights
109638 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
109639 copies of the Software, and to permit persons to whom the Software is furnished
109640 to do so, subject to the following conditions:
109641 
109642 The above copyright notice and this permission notice shall be included in all
109643 copies or substantial portions of the Software.
109644 
109645 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
109646 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
109647 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
109648 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
109649 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109650 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
109651 THE SOFTWARE.
109652 
109653 <?php
109654 
109655 
109656 
109657 
109658 
109659 
109660 
109661 
109662 
109663 
109664 namespace Symfony\Component\Process;
109665 
109666 
109667 
109668 
109669 
109670 
109671 
109672 class PhpExecutableFinder
109673 {
109674 private $executableFinder;
109675 
109676 public function __construct()
109677 {
109678 $this->executableFinder = new ExecutableFinder();
109679 }
109680 
109681 
109682 
109683 
109684 
109685 
109686 
109687 
109688 public function find($includeArgs = true)
109689 {
109690 $args = $this->findArguments();
109691 $args = $includeArgs && $args ? ' '.implode(' ', $args) : '';
109692 
109693 
109694 if (\defined('HHVM_VERSION')) {
109695 return (getenv('PHP_BINARY') ?: PHP_BINARY).$args;
109696 }
109697 
109698 
109699 if (\defined('PHP_BINARY') && PHP_BINARY && \in_array(\PHP_SAPI, array('cli', 'cli-server', 'phpdbg'), true)) {
109700 return PHP_BINARY.$args;
109701 }
109702 
109703 if ($php = getenv('PHP_PATH')) {
109704 if (!@is_executable($php)) {
109705 return false;
109706 }
109707 
109708 return $php;
109709 }
109710 
109711 if ($php = getenv('PHP_PEAR_PHP_BIN')) {
109712 if (@is_executable($php)) {
109713 return $php;
109714 }
109715 }
109716 
109717 if (@is_executable($php = PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) {
109718 return $php;
109719 }
109720 
109721 $dirs = array(PHP_BINDIR);
109722 if ('\\' === \DIRECTORY_SEPARATOR) {
109723 $dirs[] = 'C:\xampp\php\\';
109724 }
109725 
109726 return $this->executableFinder->find('php', false, $dirs);
109727 }
109728 
109729 
109730 
109731 
109732 
109733 
109734 public function findArguments()
109735 {
109736 $arguments = array();
109737 
109738 if (\defined('HHVM_VERSION')) {
109739 $arguments[] = '--php';
109740 } elseif ('phpdbg' === \PHP_SAPI) {
109741 $arguments[] = '-qrr';
109742 }
109743 
109744 return $arguments;
109745 }
109746 }
109747 <?php
109748 
109749 
109750 
109751 
109752 
109753 
109754 
109755 
109756 
109757 
109758 namespace Symfony\Component\Process;
109759 
109760 use Symfony\Component\Process\Exception\RuntimeException;
109761 
109762 
109763 
109764 
109765 
109766 
109767 
109768 
109769 
109770 
109771 class PhpProcess extends Process
109772 {
109773 
109774 
109775 
109776 
109777 
109778 
109779 
109780 public function __construct($script, $cwd = null, array $env = null, $timeout = 60, array $options = array())
109781 {
109782 $executableFinder = new PhpExecutableFinder();
109783 if (false === $php = $executableFinder->find()) {
109784 $php = null;
109785 }
109786 if ('phpdbg' === \PHP_SAPI) {
109787 $file = tempnam(sys_get_temp_dir(), 'dbg');
109788 file_put_contents($file, $script);
109789 register_shutdown_function('unlink', $file);
109790 $php .= ' '.ProcessUtils::escapeArgument($file);
109791 $script = null;
109792 }
109793 if ('\\' !== \DIRECTORY_SEPARATOR && null !== $php) {
109794 
109795 
109796 
109797 $php = 'exec '.$php;
109798 }
109799 
109800 parent::__construct($php, $cwd, $env, $script, $timeout, $options);
109801 }
109802 
109803 
109804 
109805 
109806 public function setPhpBinary($php)
109807 {
109808 $this->setCommandLine($php);
109809 }
109810 
109811 
109812 
109813 
109814 public function start($callback = null)
109815 {
109816 if (null === $this->getCommandLine()) {
109817 throw new RuntimeException('Unable to find the PHP executable.');
109818 }
109819 
109820 parent::start($callback);
109821 }
109822 }
109823 <?php
109824 
109825 
109826 
109827 
109828 
109829 
109830 
109831 
109832 
109833 
109834 namespace Symfony\Component\Process\Pipes;
109835 
109836 
109837 
109838 
109839 
109840 
109841 abstract class AbstractPipes implements PipesInterface
109842 {
109843 public $pipes = array();
109844 
109845 private $inputBuffer = '';
109846 private $input;
109847 private $blocked = true;
109848 private $lastError;
109849 
109850 
109851 
109852 
109853 public function __construct($input)
109854 {
109855 if (\is_resource($input)) {
109856 $this->input = $input;
109857 } elseif (\is_string($input)) {
109858 $this->inputBuffer = $input;
109859 } else {
109860 $this->inputBuffer = (string) $input;
109861 }
109862 }
109863 
109864 
109865 
109866 
109867 public function close()
109868 {
109869 foreach ($this->pipes as $pipe) {
109870 fclose($pipe);
109871 }
109872 $this->pipes = array();
109873 }
109874 
109875 
109876 
109877 
109878 
109879 
109880 protected function hasSystemCallBeenInterrupted()
109881 {
109882 $lastError = $this->lastError;
109883 $this->lastError = null;
109884 
109885 
109886 return null !== $lastError && false !== stripos($lastError, 'interrupted system call');
109887 }
109888 
109889 
109890 
109891 
109892 protected function unblock()
109893 {
109894 if (!$this->blocked) {
109895 return;
109896 }
109897 
109898 foreach ($this->pipes as $pipe) {
109899 stream_set_blocking($pipe, 0);
109900 }
109901 if (null !== $this->input) {
109902 stream_set_blocking($this->input, 0);
109903 }
109904 
109905 $this->blocked = false;
109906 }
109907 
109908 
109909 
109910 
109911 protected function write()
109912 {
109913 if (!isset($this->pipes[0])) {
109914 return;
109915 }
109916 $input = $this->input;
109917 $r = $e = array();
109918 $w = array($this->pipes[0]);
109919 
109920 
109921 if (false === @stream_select($r, $w, $e, 0, 0)) {
109922 return;
109923 }
109924 
109925 foreach ($w as $stdin) {
109926 if (isset($this->inputBuffer[0])) {
109927 $written = fwrite($stdin, $this->inputBuffer);
109928 $this->inputBuffer = substr($this->inputBuffer, $written);
109929 if (isset($this->inputBuffer[0])) {
109930 return array($this->pipes[0]);
109931 }
109932 }
109933 
109934 if ($input) {
109935 for (;;) {
109936 $data = fread($input, self::CHUNK_SIZE);
109937 if (!isset($data[0])) {
109938 break;
109939 }
109940 $written = fwrite($stdin, $data);
109941 $data = substr($data, $written);
109942 if (isset($data[0])) {
109943 $this->inputBuffer = $data;
109944 
109945 return array($this->pipes[0]);
109946 }
109947 }
109948 if (feof($input)) {
109949 
109950 
109951 $this->input = null;
109952 }
109953 }
109954 }
109955 
109956 
109957 if (null === $this->input && !isset($this->inputBuffer[0])) {
109958 fclose($this->pipes[0]);
109959 unset($this->pipes[0]);
109960 } elseif (!$w) {
109961 return array($this->pipes[0]);
109962 }
109963 }
109964 
109965 
109966 
109967 
109968 public function handleError($type, $msg)
109969 {
109970 $this->lastError = $msg;
109971 }
109972 }
109973 <?php
109974 
109975 
109976 
109977 
109978 
109979 
109980 
109981 
109982 
109983 
109984 namespace Symfony\Component\Process\Pipes;
109985 
109986 
109987 
109988 
109989 
109990 
109991 
109992 
109993 interface PipesInterface
109994 {
109995 const CHUNK_SIZE = 16384;
109996 
109997 
109998 
109999 
110000 
110001 
110002 public function getDescriptors();
110003 
110004 
110005 
110006 
110007 
110008 
110009 public function getFiles();
110010 
110011 
110012 
110013 
110014 
110015 
110016 
110017 
110018 
110019 public function readAndWrite($blocking, $close = false);
110020 
110021 
110022 
110023 
110024 
110025 
110026 public function areOpen();
110027 
110028 
110029 
110030 
110031 public function close();
110032 }
110033 <?php
110034 
110035 
110036 
110037 
110038 
110039 
110040 
110041 
110042 
110043 
110044 namespace Symfony\Component\Process\Pipes;
110045 
110046 use Symfony\Component\Process\Process;
110047 
110048 
110049 
110050 
110051 
110052 
110053 
110054 
110055 class UnixPipes extends AbstractPipes
110056 {
110057 private $ttyMode;
110058 private $ptyMode;
110059 private $disableOutput;
110060 
110061 public function __construct($ttyMode, $ptyMode, $input, $disableOutput)
110062 {
110063 $this->ttyMode = (bool) $ttyMode;
110064 $this->ptyMode = (bool) $ptyMode;
110065 $this->disableOutput = (bool) $disableOutput;
110066 
110067 parent::__construct($input);
110068 }
110069 
110070 public function __destruct()
110071 {
110072 $this->close();
110073 }
110074 
110075 
110076 
110077 
110078 public function getDescriptors()
110079 {
110080 if ($this->disableOutput) {
110081 $nullstream = fopen('/dev/null', 'c');
110082 
110083 return array(
110084 array('pipe', 'r'),
110085 $nullstream,
110086 $nullstream,
110087 );
110088 }
110089 
110090 if ($this->ttyMode) {
110091 return array(
110092 array('file', '/dev/tty', 'r'),
110093 array('file', '/dev/tty', 'w'),
110094 array('file', '/dev/tty', 'w'),
110095 );
110096 }
110097 
110098 if ($this->ptyMode && Process::isPtySupported()) {
110099 return array(
110100 array('pty'),
110101 array('pty'),
110102 array('pty'),
110103 );
110104 }
110105 
110106 return array(
110107 array('pipe', 'r'),
110108 array('pipe', 'w'), 
110109 array('pipe', 'w'), 
110110 );
110111 }
110112 
110113 
110114 
110115 
110116 public function getFiles()
110117 {
110118 return array();
110119 }
110120 
110121 
110122 
110123 
110124 public function readAndWrite($blocking, $close = false)
110125 {
110126 $this->unblock();
110127 $w = $this->write();
110128 
110129 $read = $e = array();
110130 $r = $this->pipes;
110131 unset($r[0]);
110132 
110133 
110134 set_error_handler(array($this, 'handleError'));
110135 if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
110136 restore_error_handler();
110137 
110138 
110139 if (!$this->hasSystemCallBeenInterrupted()) {
110140 $this->pipes = array();
110141 }
110142 
110143 return $read;
110144 }
110145 restore_error_handler();
110146 
110147 foreach ($r as $pipe) {
110148 
110149 
110150 $read[$type = array_search($pipe, $this->pipes, true)] = '';
110151 
110152 do {
110153 $data = fread($pipe, self::CHUNK_SIZE);
110154 $read[$type] .= $data;
110155 } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));
110156 
110157 if (!isset($read[$type][0])) {
110158 unset($read[$type]);
110159 }
110160 
110161 if ($close && feof($pipe)) {
110162 fclose($pipe);
110163 unset($this->pipes[$type]);
110164 }
110165 }
110166 
110167 return $read;
110168 }
110169 
110170 
110171 
110172 
110173 public function areOpen()
110174 {
110175 return (bool) $this->pipes;
110176 }
110177 
110178 
110179 
110180 
110181 
110182 
110183 
110184 
110185 
110186 public static function create(Process $process, $input)
110187 {
110188 return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled());
110189 }
110190 }
110191 <?php
110192 
110193 
110194 
110195 
110196 
110197 
110198 
110199 
110200 
110201 
110202 namespace Symfony\Component\Process\Pipes;
110203 
110204 use Symfony\Component\Process\Exception\RuntimeException;
110205 use Symfony\Component\Process\Process;
110206 
110207 
110208 
110209 
110210 
110211 
110212 
110213 
110214 
110215 
110216 
110217 class WindowsPipes extends AbstractPipes
110218 {
110219 private $files = array();
110220 private $fileHandles = array();
110221 private $lockHandles = array();
110222 private $readBytes = array(
110223 Process::STDOUT => 0,
110224 Process::STDERR => 0,
110225 );
110226 private $disableOutput;
110227 
110228 public function __construct($disableOutput, $input)
110229 {
110230 $this->disableOutput = (bool) $disableOutput;
110231 
110232 if (!$this->disableOutput) {
110233 
110234 
110235 
110236 
110237 $pipes = array(
110238 Process::STDOUT => Process::OUT,
110239 Process::STDERR => Process::ERR,
110240 );
110241 $tmpDir = sys_get_temp_dir();
110242 $lastError = 'unknown reason';
110243 set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
110244 for ($i = 0;; ++$i) {
110245 foreach ($pipes as $pipe => $name) {
110246 $file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
110247 
110248 if (!$h = fopen($file.'.lock', 'w')) {
110249 restore_error_handler();
110250 throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $lastError));
110251 }
110252 if (!flock($h, LOCK_EX | LOCK_NB)) {
110253 continue 2;
110254 }
110255 if (isset($this->lockHandles[$pipe])) {
110256 flock($this->lockHandles[$pipe], LOCK_UN);
110257 fclose($this->lockHandles[$pipe]);
110258 }
110259 $this->lockHandles[$pipe] = $h;
110260 
110261 if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) {
110262 flock($this->lockHandles[$pipe], LOCK_UN);
110263 fclose($this->lockHandles[$pipe]);
110264 unset($this->lockHandles[$pipe]);
110265 continue 2;
110266 }
110267 $this->fileHandles[$pipe] = $h;
110268 $this->files[$pipe] = $file;
110269 }
110270 break;
110271 }
110272 restore_error_handler();
110273 }
110274 
110275 parent::__construct($input);
110276 }
110277 
110278 public function __destruct()
110279 {
110280 $this->close();
110281 }
110282 
110283 
110284 
110285 
110286 public function getDescriptors()
110287 {
110288 if ($this->disableOutput) {
110289 $nullstream = fopen('NUL', 'c');
110290 
110291 return array(
110292 array('pipe', 'r'),
110293 $nullstream,
110294 $nullstream,
110295 );
110296 }
110297 
110298 
110299 
110300 
110301 return array(
110302 array('pipe', 'r'),
110303 array('file', 'NUL', 'w'),
110304 array('file', 'NUL', 'w'),
110305 );
110306 }
110307 
110308 
110309 
110310 
110311 public function getFiles()
110312 {
110313 return $this->files;
110314 }
110315 
110316 
110317 
110318 
110319 public function readAndWrite($blocking, $close = false)
110320 {
110321 $this->unblock();
110322 $w = $this->write();
110323 $read = $r = $e = array();
110324 
110325 if ($blocking) {
110326 if ($w) {
110327 @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
110328 } elseif ($this->fileHandles) {
110329 usleep(Process::TIMEOUT_PRECISION * 1E6);
110330 }
110331 }
110332 foreach ($this->fileHandles as $type => $fileHandle) {
110333 $data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]);
110334 
110335 if (isset($data[0])) {
110336 $this->readBytes[$type] += \strlen($data);
110337 $read[$type] = $data;
110338 }
110339 if ($close) {
110340 ftruncate($fileHandle, 0);
110341 fclose($fileHandle);
110342 flock($this->lockHandles[$type], LOCK_UN);
110343 fclose($this->lockHandles[$type]);
110344 unset($this->fileHandles[$type], $this->lockHandles[$type]);
110345 }
110346 }
110347 
110348 return $read;
110349 }
110350 
110351 
110352 
110353 
110354 public function areOpen()
110355 {
110356 return $this->pipes && $this->fileHandles;
110357 }
110358 
110359 
110360 
110361 
110362 public function close()
110363 {
110364 parent::close();
110365 foreach ($this->fileHandles as $type => $handle) {
110366 ftruncate($handle, 0);
110367 fclose($handle);
110368 flock($this->lockHandles[$type], LOCK_UN);
110369 fclose($this->lockHandles[$type]);
110370 }
110371 $this->fileHandles = $this->lockHandles = array();
110372 }
110373 
110374 
110375 
110376 
110377 
110378 
110379 
110380 
110381 
110382 public static function create(Process $process, $input)
110383 {
110384 return new static($process->isOutputDisabled(), $input);
110385 }
110386 }
110387 <?php
110388 
110389 
110390 
110391 
110392 
110393 
110394 
110395 
110396 
110397 
110398 namespace Symfony\Component\Process;
110399 
110400 use Symfony\Component\Process\Exception\InvalidArgumentException;
110401 use Symfony\Component\Process\Exception\LogicException;
110402 use Symfony\Component\Process\Exception\ProcessFailedException;
110403 use Symfony\Component\Process\Exception\ProcessTimedOutException;
110404 use Symfony\Component\Process\Exception\RuntimeException;
110405 use Symfony\Component\Process\Pipes\PipesInterface;
110406 use Symfony\Component\Process\Pipes\UnixPipes;
110407 use Symfony\Component\Process\Pipes\WindowsPipes;
110408 
110409 
110410 
110411 
110412 
110413 
110414 
110415 
110416 class Process
110417 {
110418 const ERR = 'err';
110419 const OUT = 'out';
110420 
110421 const STATUS_READY = 'ready';
110422 const STATUS_STARTED = 'started';
110423 const STATUS_TERMINATED = 'terminated';
110424 
110425 const STDIN = 0;
110426 const STDOUT = 1;
110427 const STDERR = 2;
110428 
110429 
110430 const TIMEOUT_PRECISION = 0.2;
110431 
110432 private $callback;
110433 private $commandline;
110434 private $cwd;
110435 private $env;
110436 private $input;
110437 private $starttime;
110438 private $lastOutputTime;
110439 private $timeout;
110440 private $idleTimeout;
110441 private $options;
110442 private $exitcode;
110443 private $fallbackStatus = array();
110444 private $processInformation;
110445 private $outputDisabled = false;
110446 private $stdout;
110447 private $stderr;
110448 private $enhanceWindowsCompatibility = true;
110449 private $enhanceSigchildCompatibility;
110450 private $process;
110451 private $status = self::STATUS_READY;
110452 private $incrementalOutputOffset = 0;
110453 private $incrementalErrorOutputOffset = 0;
110454 private $tty;
110455 private $pty;
110456 
110457 private $useFileHandles = false;
110458 
110459 private $processPipes;
110460 
110461 private $latestSignal;
110462 
110463 private static $sigchild;
110464 
110465 
110466 
110467 
110468 
110469 
110470 public static $exitCodes = array(
110471 0 => 'OK',
110472 1 => 'General error',
110473 2 => 'Misuse of shell builtins',
110474 
110475 126 => 'Invoked command cannot execute',
110476 127 => 'Command not found',
110477 128 => 'Invalid exit argument',
110478 
110479 
110480 129 => 'Hangup',
110481 130 => 'Interrupt',
110482 131 => 'Quit and dump core',
110483 132 => 'Illegal instruction',
110484 133 => 'Trace/breakpoint trap',
110485 134 => 'Process aborted',
110486 135 => 'Bus error: "access to undefined portion of memory object"',
110487 136 => 'Floating point exception: "erroneous arithmetic operation"',
110488 137 => 'Kill (terminate immediately)',
110489 138 => 'User-defined 1',
110490 139 => 'Segmentation violation',
110491 140 => 'User-defined 2',
110492 141 => 'Write to pipe with no one reading',
110493 142 => 'Signal raised by alarm',
110494 143 => 'Termination (request to terminate)',
110495 
110496 145 => 'Child process terminated, stopped (or continued*)',
110497 146 => 'Continue if stopped',
110498 147 => 'Stop executing temporarily',
110499 148 => 'Terminal stop signal',
110500 149 => 'Background process attempting to read from tty ("in")',
110501 150 => 'Background process attempting to write to tty ("out")',
110502 151 => 'Urgent data available on socket',
110503 152 => 'CPU time limit exceeded',
110504 153 => 'File size limit exceeded',
110505 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
110506 155 => 'Profiling timer expired',
110507 
110508 157 => 'Pollable event',
110509 
110510 159 => 'Bad syscall',
110511 );
110512 
110513 
110514 
110515 
110516 
110517 
110518 
110519 
110520 
110521 
110522 
110523 public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array())
110524 {
110525 if (!\function_exists('proc_open')) {
110526 throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
110527 }
110528 
110529 $this->commandline = $commandline;
110530 $this->cwd = $cwd;
110531 
110532 
110533 
110534 
110535 
110536 if (null === $this->cwd && (\defined('ZEND_THREAD_SAFE') || '\\' === \DIRECTORY_SEPARATOR)) {
110537 $this->cwd = getcwd();
110538 }
110539 if (null !== $env) {
110540 $this->setEnv($env);
110541 }
110542 
110543 $this->setInput($input);
110544 $this->setTimeout($timeout);
110545 $this->useFileHandles = '\\' === \DIRECTORY_SEPARATOR;
110546 $this->pty = false;
110547 $this->enhanceSigchildCompatibility = '\\' !== \DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
110548 $this->options = array_replace(array('suppress_errors' => true, 'binary_pipes' => true), $options);
110549 }
110550 
110551 public function __destruct()
110552 {
110553 $this->stop(0);
110554 }
110555 
110556 public function __clone()
110557 {
110558 $this->resetProcessData();
110559 }
110560 
110561 
110562 
110563 
110564 
110565 
110566 
110567 
110568 
110569 
110570 
110571 
110572 
110573 
110574 
110575 
110576 
110577 
110578 
110579 
110580 public function run($callback = null)
110581 {
110582 $this->start($callback);
110583 
110584 return $this->wait();
110585 }
110586 
110587 
110588 
110589 
110590 
110591 
110592 
110593 
110594 
110595 
110596 
110597 
110598 
110599 
110600 public function mustRun($callback = null)
110601 {
110602 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
110603 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
110604 }
110605 
110606 if (0 !== $this->run($callback)) {
110607 throw new ProcessFailedException($this);
110608 }
110609 
110610 return $this;
110611 }
110612 
110613 
110614 
110615 
110616 
110617 
110618 
110619 
110620 
110621 
110622 
110623 
110624 
110625 
110626 
110627 
110628 
110629 
110630 
110631 
110632 public function start($callback = null)
110633 {
110634 if ($this->isRunning()) {
110635 throw new RuntimeException('Process is already running');
110636 }
110637 if ($this->outputDisabled && null !== $callback) {
110638 throw new LogicException('Output has been disabled, enable it to allow the use of a callback.');
110639 }
110640 
110641 $this->resetProcessData();
110642 $this->starttime = $this->lastOutputTime = microtime(true);
110643 $this->callback = $this->buildCallback($callback);
110644 $descriptors = $this->getDescriptors();
110645 
110646 $commandline = $this->commandline;
110647 
110648 if ('\\' === \DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
110649 $commandline = 'cmd /V:ON /E:ON /D /C "('.$commandline.')';
110650 foreach ($this->processPipes->getFiles() as $offset => $filename) {
110651 $commandline .= ' '.$offset.'>'.ProcessUtils::escapeArgument($filename);
110652 }
110653 $commandline .= '"';
110654 
110655 if (!isset($this->options['bypass_shell'])) {
110656 $this->options['bypass_shell'] = true;
110657 }
110658 } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
110659 
110660 $descriptors[3] = array('pipe', 'w');
110661 
110662 
110663 $commandline = '{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
110664 $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
110665 
110666 
110667 
110668 $ptsWorkaround = fopen(__FILE__, 'r');
110669 }
110670 
110671 $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options);
110672 
110673 if (!\is_resource($this->process)) {
110674 throw new RuntimeException('Unable to launch a new process.');
110675 }
110676 $this->status = self::STATUS_STARTED;
110677 
110678 if (isset($descriptors[3])) {
110679 $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
110680 }
110681 
110682 if ($this->tty) {
110683 return;
110684 }
110685 
110686 $this->updateStatus(false);
110687 $this->checkTimeout();
110688 }
110689 
110690 
110691 
110692 
110693 
110694 
110695 
110696 
110697 
110698 
110699 
110700 
110701 
110702 
110703 
110704 
110705 public function restart($callback = null)
110706 {
110707 if ($this->isRunning()) {
110708 throw new RuntimeException('Process is already running');
110709 }
110710 
110711 $process = clone $this;
110712 $process->start($callback);
110713 
110714 return $process;
110715 }
110716 
110717 
110718 
110719 
110720 
110721 
110722 
110723 
110724 
110725 
110726 
110727 
110728 
110729 
110730 
110731 
110732 public function wait($callback = null)
110733 {
110734 $this->requireProcessIsStarted(__FUNCTION__);
110735 
110736 $this->updateStatus(false);
110737 if (null !== $callback) {
110738 $this->callback = $this->buildCallback($callback);
110739 }
110740 
110741 do {
110742 $this->checkTimeout();
110743 $running = '\\' === \DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
110744 $this->readPipes($running, '\\' !== \DIRECTORY_SEPARATOR || !$running);
110745 } while ($running);
110746 
110747 while ($this->isRunning()) {
110748 usleep(1000);
110749 }
110750 
110751 if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
110752 throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
110753 }
110754 
110755 return $this->exitcode;
110756 }
110757 
110758 
110759 
110760 
110761 
110762 
110763 public function getPid()
110764 {
110765 return $this->isRunning() ? $this->processInformation['pid'] : null;
110766 }
110767 
110768 
110769 
110770 
110771 
110772 
110773 
110774 
110775 
110776 
110777 
110778 
110779 public function signal($signal)
110780 {
110781 $this->doSignal($signal, true);
110782 
110783 return $this;
110784 }
110785 
110786 
110787 
110788 
110789 
110790 
110791 
110792 
110793 
110794 public function disableOutput()
110795 {
110796 if ($this->isRunning()) {
110797 throw new RuntimeException('Disabling output while the process is running is not possible.');
110798 }
110799 if (null !== $this->idleTimeout) {
110800 throw new LogicException('Output can not be disabled while an idle timeout is set.');
110801 }
110802 
110803 $this->outputDisabled = true;
110804 
110805 return $this;
110806 }
110807 
110808 
110809 
110810 
110811 
110812 
110813 
110814 
110815 public function enableOutput()
110816 {
110817 if ($this->isRunning()) {
110818 throw new RuntimeException('Enabling output while the process is running is not possible.');
110819 }
110820 
110821 $this->outputDisabled = false;
110822 
110823 return $this;
110824 }
110825 
110826 
110827 
110828 
110829 
110830 
110831 public function isOutputDisabled()
110832 {
110833 return $this->outputDisabled;
110834 }
110835 
110836 
110837 
110838 
110839 
110840 
110841 
110842 
110843 
110844 public function getOutput()
110845 {
110846 $this->readPipesForOutput(__FUNCTION__);
110847 
110848 if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
110849 return '';
110850 }
110851 
110852 return $ret;
110853 }
110854 
110855 
110856 
110857 
110858 
110859 
110860 
110861 
110862 
110863 
110864 
110865 
110866 public function getIncrementalOutput()
110867 {
110868 $this->readPipesForOutput(__FUNCTION__);
110869 
110870 $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
110871 $this->incrementalOutputOffset = ftell($this->stdout);
110872 
110873 if (false === $latest) {
110874 return '';
110875 }
110876 
110877 return $latest;
110878 }
110879 
110880 
110881 
110882 
110883 
110884 
110885 public function clearOutput()
110886 {
110887 ftruncate($this->stdout, 0);
110888 fseek($this->stdout, 0);
110889 $this->incrementalOutputOffset = 0;
110890 
110891 return $this;
110892 }
110893 
110894 
110895 
110896 
110897 
110898 
110899 
110900 
110901 
110902 public function getErrorOutput()
110903 {
110904 $this->readPipesForOutput(__FUNCTION__);
110905 
110906 if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
110907 return '';
110908 }
110909 
110910 return $ret;
110911 }
110912 
110913 
110914 
110915 
110916 
110917 
110918 
110919 
110920 
110921 
110922 
110923 
110924 
110925 public function getIncrementalErrorOutput()
110926 {
110927 $this->readPipesForOutput(__FUNCTION__);
110928 
110929 $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
110930 $this->incrementalErrorOutputOffset = ftell($this->stderr);
110931 
110932 if (false === $latest) {
110933 return '';
110934 }
110935 
110936 return $latest;
110937 }
110938 
110939 
110940 
110941 
110942 
110943 
110944 public function clearErrorOutput()
110945 {
110946 ftruncate($this->stderr, 0);
110947 fseek($this->stderr, 0);
110948 $this->incrementalErrorOutputOffset = 0;
110949 
110950 return $this;
110951 }
110952 
110953 
110954 
110955 
110956 
110957 
110958 
110959 
110960 public function getExitCode()
110961 {
110962 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
110963 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
110964 }
110965 
110966 $this->updateStatus(false);
110967 
110968 return $this->exitcode;
110969 }
110970 
110971 
110972 
110973 
110974 
110975 
110976 
110977 
110978 
110979 
110980 
110981 
110982 public function getExitCodeText()
110983 {
110984 if (null === $exitcode = $this->getExitCode()) {
110985 return;
110986 }
110987 
110988 return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
110989 }
110990 
110991 
110992 
110993 
110994 
110995 
110996 public function isSuccessful()
110997 {
110998 return 0 === $this->getExitCode();
110999 }
111000 
111001 
111002 
111003 
111004 
111005 
111006 
111007 
111008 
111009 
111010 
111011 public function hasBeenSignaled()
111012 {
111013 $this->requireProcessIsTerminated(__FUNCTION__);
111014 
111015 if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
111016 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
111017 }
111018 
111019 return $this->processInformation['signaled'];
111020 }
111021 
111022 
111023 
111024 
111025 
111026 
111027 
111028 
111029 
111030 
111031 
111032 public function getTermSignal()
111033 {
111034 $this->requireProcessIsTerminated(__FUNCTION__);
111035 
111036 if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) {
111037 throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
111038 }
111039 
111040 return $this->processInformation['termsig'];
111041 }
111042 
111043 
111044 
111045 
111046 
111047 
111048 
111049 
111050 
111051 
111052 public function hasBeenStopped()
111053 {
111054 $this->requireProcessIsTerminated(__FUNCTION__);
111055 
111056 return $this->processInformation['stopped'];
111057 }
111058 
111059 
111060 
111061 
111062 
111063 
111064 
111065 
111066 
111067 
111068 public function getStopSignal()
111069 {
111070 $this->requireProcessIsTerminated(__FUNCTION__);
111071 
111072 return $this->processInformation['stopsig'];
111073 }
111074 
111075 
111076 
111077 
111078 
111079 
111080 public function isRunning()
111081 {
111082 if (self::STATUS_STARTED !== $this->status) {
111083 return false;
111084 }
111085 
111086 $this->updateStatus(false);
111087 
111088 return $this->processInformation['running'];
111089 }
111090 
111091 
111092 
111093 
111094 
111095 
111096 public function isStarted()
111097 {
111098 return self::STATUS_READY != $this->status;
111099 }
111100 
111101 
111102 
111103 
111104 
111105 
111106 public function isTerminated()
111107 {
111108 $this->updateStatus(false);
111109 
111110 return self::STATUS_TERMINATED == $this->status;
111111 }
111112 
111113 
111114 
111115 
111116 
111117 
111118 
111119 
111120 public function getStatus()
111121 {
111122 $this->updateStatus(false);
111123 
111124 return $this->status;
111125 }
111126 
111127 
111128 
111129 
111130 
111131 
111132 
111133 
111134 
111135 public function stop($timeout = 10, $signal = null)
111136 {
111137 $timeoutMicro = microtime(true) + $timeout;
111138 if ($this->isRunning()) {
111139 
111140 $this->doSignal(15, false);
111141 do {
111142 usleep(1000);
111143 } while ($this->isRunning() && microtime(true) < $timeoutMicro);
111144 
111145 if ($this->isRunning()) {
111146 
111147 
111148 $this->doSignal($signal ?: 9, false);
111149 }
111150 }
111151 
111152 if ($this->isRunning()) {
111153 if (isset($this->fallbackStatus['pid'])) {
111154 unset($this->fallbackStatus['pid']);
111155 
111156 return $this->stop(0, $signal);
111157 }
111158 $this->close();
111159 }
111160 
111161 return $this->exitcode;
111162 }
111163 
111164 
111165 
111166 
111167 
111168 
111169 
111170 
111171 public function addOutput($line)
111172 {
111173 $this->lastOutputTime = microtime(true);
111174 
111175 fseek($this->stdout, 0, SEEK_END);
111176 fwrite($this->stdout, $line);
111177 fseek($this->stdout, $this->incrementalOutputOffset);
111178 }
111179 
111180 
111181 
111182 
111183 
111184 
111185 
111186 
111187 public function addErrorOutput($line)
111188 {
111189 $this->lastOutputTime = microtime(true);
111190 
111191 fseek($this->stderr, 0, SEEK_END);
111192 fwrite($this->stderr, $line);
111193 fseek($this->stderr, $this->incrementalErrorOutputOffset);
111194 }
111195 
111196 
111197 
111198 
111199 
111200 
111201 public function getCommandLine()
111202 {
111203 return $this->commandline;
111204 }
111205 
111206 
111207 
111208 
111209 
111210 
111211 
111212 
111213 public function setCommandLine($commandline)
111214 {
111215 $this->commandline = $commandline;
111216 
111217 return $this;
111218 }
111219 
111220 
111221 
111222 
111223 
111224 
111225 public function getTimeout()
111226 {
111227 return $this->timeout;
111228 }
111229 
111230 
111231 
111232 
111233 
111234 
111235 public function getIdleTimeout()
111236 {
111237 return $this->idleTimeout;
111238 }
111239 
111240 
111241 
111242 
111243 
111244 
111245 
111246 
111247 
111248 
111249 
111250 
111251 public function setTimeout($timeout)
111252 {
111253 $this->timeout = $this->validateTimeout($timeout);
111254 
111255 return $this;
111256 }
111257 
111258 
111259 
111260 
111261 
111262 
111263 
111264 
111265 
111266 
111267 
111268 
111269 
111270 public function setIdleTimeout($timeout)
111271 {
111272 if (null !== $timeout && $this->outputDisabled) {
111273 throw new LogicException('Idle timeout can not be set while the output is disabled.');
111274 }
111275 
111276 $this->idleTimeout = $this->validateTimeout($timeout);
111277 
111278 return $this;
111279 }
111280 
111281 
111282 
111283 
111284 
111285 
111286 
111287 
111288 
111289 
111290 public function setTty($tty)
111291 {
111292 if ('\\' === \DIRECTORY_SEPARATOR && $tty) {
111293 throw new RuntimeException('TTY mode is not supported on Windows platform.');
111294 }
111295 if ($tty) {
111296 static $isTtySupported;
111297 
111298 if (null === $isTtySupported) {
111299 $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
111300 }
111301 
111302 if (!$isTtySupported) {
111303 throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
111304 }
111305 }
111306 
111307 $this->tty = (bool) $tty;
111308 
111309 return $this;
111310 }
111311 
111312 
111313 
111314 
111315 
111316 
111317 public function isTty()
111318 {
111319 return $this->tty;
111320 }
111321 
111322 
111323 
111324 
111325 
111326 
111327 
111328 
111329 public function setPty($bool)
111330 {
111331 $this->pty = (bool) $bool;
111332 
111333 return $this;
111334 }
111335 
111336 
111337 
111338 
111339 
111340 
111341 public function isPty()
111342 {
111343 return $this->pty;
111344 }
111345 
111346 
111347 
111348 
111349 
111350 
111351 public function getWorkingDirectory()
111352 {
111353 if (null === $this->cwd) {
111354 
111355 
111356 return getcwd() ?: null;
111357 }
111358 
111359 return $this->cwd;
111360 }
111361 
111362 
111363 
111364 
111365 
111366 
111367 
111368 
111369 public function setWorkingDirectory($cwd)
111370 {
111371 $this->cwd = $cwd;
111372 
111373 return $this;
111374 }
111375 
111376 
111377 
111378 
111379 
111380 
111381 public function getEnv()
111382 {
111383 return $this->env;
111384 }
111385 
111386 
111387 
111388 
111389 
111390 
111391 
111392 
111393 
111394 
111395 
111396 
111397 
111398 
111399 public function setEnv(array $env)
111400 {
111401 
111402 $env = array_filter($env, function ($value) {
111403 return !\is_array($value);
111404 });
111405 
111406 $this->env = array();
111407 foreach ($env as $key => $value) {
111408 $this->env[$key] = (string) $value;
111409 }
111410 
111411 return $this;
111412 }
111413 
111414 
111415 
111416 
111417 
111418 
111419 
111420 
111421 
111422 
111423 public function getStdin()
111424 {
111425 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.5 and will be removed in 3.0. Use the getInput() method instead.', E_USER_DEPRECATED);
111426 
111427 return $this->getInput();
111428 }
111429 
111430 
111431 
111432 
111433 
111434 
111435 public function getInput()
111436 {
111437 return $this->input;
111438 }
111439 
111440 
111441 
111442 
111443 
111444 
111445 
111446 
111447 
111448 
111449 
111450 
111451 
111452 
111453 public function setStdin($stdin)
111454 {
111455 @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.5 and will be removed in 3.0. Use the setInput() method instead.', E_USER_DEPRECATED);
111456 
111457 return $this->setInput($stdin);
111458 }
111459 
111460 
111461 
111462 
111463 
111464 
111465 
111466 
111467 
111468 
111469 
111470 
111471 
111472 
111473 public function setInput($input)
111474 {
111475 if ($this->isRunning()) {
111476 throw new LogicException('Input can not be set while the process is running.');
111477 }
111478 
111479 $this->input = ProcessUtils::validateInput(__METHOD__, $input);
111480 
111481 return $this;
111482 }
111483 
111484 
111485 
111486 
111487 
111488 
111489 public function getOptions()
111490 {
111491 return $this->options;
111492 }
111493 
111494 
111495 
111496 
111497 
111498 
111499 
111500 
111501 public function setOptions(array $options)
111502 {
111503 $this->options = $options;
111504 
111505 return $this;
111506 }
111507 
111508 
111509 
111510 
111511 
111512 
111513 
111514 
111515 public function getEnhanceWindowsCompatibility()
111516 {
111517 return $this->enhanceWindowsCompatibility;
111518 }
111519 
111520 
111521 
111522 
111523 
111524 
111525 
111526 
111527 public function setEnhanceWindowsCompatibility($enhance)
111528 {
111529 $this->enhanceWindowsCompatibility = (bool) $enhance;
111530 
111531 return $this;
111532 }
111533 
111534 
111535 
111536 
111537 
111538 
111539 public function getEnhanceSigchildCompatibility()
111540 {
111541 return $this->enhanceSigchildCompatibility;
111542 }
111543 
111544 
111545 
111546 
111547 
111548 
111549 
111550 
111551 
111552 
111553 
111554 
111555 public function setEnhanceSigchildCompatibility($enhance)
111556 {
111557 $this->enhanceSigchildCompatibility = (bool) $enhance;
111558 
111559 return $this;
111560 }
111561 
111562 
111563 
111564 
111565 
111566 
111567 
111568 
111569 
111570 public function checkTimeout()
111571 {
111572 if (self::STATUS_STARTED !== $this->status) {
111573 return;
111574 }
111575 
111576 if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
111577 $this->stop(0);
111578 
111579 throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL);
111580 }
111581 
111582 if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
111583 $this->stop(0);
111584 
111585 throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE);
111586 }
111587 }
111588 
111589 
111590 
111591 
111592 
111593 
111594 public static function isPtySupported()
111595 {
111596 static $result;
111597 
111598 if (null !== $result) {
111599 return $result;
111600 }
111601 
111602 if ('\\' === \DIRECTORY_SEPARATOR) {
111603 return $result = false;
111604 }
111605 
111606 return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes);
111607 }
111608 
111609 
111610 
111611 
111612 
111613 
111614 private function getDescriptors()
111615 {
111616 if ('\\' === \DIRECTORY_SEPARATOR) {
111617 $this->processPipes = WindowsPipes::create($this, $this->input);
111618 } else {
111619 $this->processPipes = UnixPipes::create($this, $this->input);
111620 }
111621 
111622 return $this->processPipes->getDescriptors();
111623 }
111624 
111625 
111626 
111627 
111628 
111629 
111630 
111631 
111632 
111633 
111634 
111635 protected function buildCallback($callback)
111636 {
111637 $that = $this;
111638 $out = self::OUT;
111639 $callback = function ($type, $data) use ($that, $callback, $out) {
111640 if ($out == $type) {
111641 $that->addOutput($data);
111642 } else {
111643 $that->addErrorOutput($data);
111644 }
111645 
111646 if (null !== $callback) {
111647 \call_user_func($callback, $type, $data);
111648 }
111649 };
111650 
111651 return $callback;
111652 }
111653 
111654 
111655 
111656 
111657 
111658 
111659 protected function updateStatus($blocking)
111660 {
111661 if (self::STATUS_STARTED !== $this->status) {
111662 return;
111663 }
111664 
111665 $this->processInformation = proc_get_status($this->process);
111666 $running = $this->processInformation['running'];
111667 
111668 $this->readPipes($running && $blocking, '\\' !== \DIRECTORY_SEPARATOR || !$running);
111669 
111670 if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
111671 $this->processInformation = $this->fallbackStatus + $this->processInformation;
111672 }
111673 
111674 if (!$running) {
111675 $this->close();
111676 }
111677 }
111678 
111679 
111680 
111681 
111682 
111683 
111684 protected function isSigchildEnabled()
111685 {
111686 if (null !== self::$sigchild) {
111687 return self::$sigchild;
111688 }
111689 
111690 if (!\function_exists('phpinfo') || \defined('HHVM_VERSION')) {
111691 return self::$sigchild = false;
111692 }
111693 
111694 ob_start();
111695 phpinfo(INFO_GENERAL);
111696 
111697 return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
111698 }
111699 
111700 
111701 
111702 
111703 
111704 
111705 
111706 
111707 private function readPipesForOutput($caller)
111708 {
111709 if ($this->outputDisabled) {
111710 throw new LogicException('Output has been disabled.');
111711 }
111712 
111713 $this->requireProcessIsStarted($caller);
111714 
111715 $this->updateStatus(false);
111716 }
111717 
111718 
111719 
111720 
111721 
111722 
111723 
111724 
111725 
111726 
111727 private function validateTimeout($timeout)
111728 {
111729 $timeout = (float) $timeout;
111730 
111731 if (0.0 === $timeout) {
111732 $timeout = null;
111733 } elseif ($timeout < 0) {
111734 throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
111735 }
111736 
111737 return $timeout;
111738 }
111739 
111740 
111741 
111742 
111743 
111744 
111745 
111746 private function readPipes($blocking, $close)
111747 {
111748 $result = $this->processPipes->readAndWrite($blocking, $close);
111749 
111750 $callback = $this->callback;
111751 foreach ($result as $type => $data) {
111752 if (3 !== $type) {
111753 $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data);
111754 } elseif (!isset($this->fallbackStatus['signaled'])) {
111755 $this->fallbackStatus['exitcode'] = (int) $data;
111756 }
111757 }
111758 }
111759 
111760 
111761 
111762 
111763 
111764 
111765 private function close()
111766 {
111767 $this->processPipes->close();
111768 if (\is_resource($this->process)) {
111769 proc_close($this->process);
111770 }
111771 $this->exitcode = $this->processInformation['exitcode'];
111772 $this->status = self::STATUS_TERMINATED;
111773 
111774 if (-1 === $this->exitcode) {
111775 if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
111776 
111777 $this->exitcode = 128 + $this->processInformation['termsig'];
111778 } elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
111779 $this->processInformation['signaled'] = true;
111780 $this->processInformation['termsig'] = -1;
111781 }
111782 }
111783 
111784 
111785 
111786 
111787 $this->callback = null;
111788 
111789 return $this->exitcode;
111790 }
111791 
111792 
111793 
111794 
111795 private function resetProcessData()
111796 {
111797 $this->starttime = null;
111798 $this->callback = null;
111799 $this->exitcode = null;
111800 $this->fallbackStatus = array();
111801 $this->processInformation = null;
111802 $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+b');
111803 $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+b');
111804 $this->process = null;
111805 $this->latestSignal = null;
111806 $this->status = self::STATUS_READY;
111807 $this->incrementalOutputOffset = 0;
111808 $this->incrementalErrorOutputOffset = 0;
111809 }
111810 
111811 
111812 
111813 
111814 
111815 
111816 
111817 
111818 
111819 
111820 
111821 
111822 
111823 private function doSignal($signal, $throwException)
111824 {
111825 if (null === $pid = $this->getPid()) {
111826 if ($throwException) {
111827 throw new LogicException('Can not send signal on a non running process.');
111828 }
111829 
111830 return false;
111831 }
111832 
111833 if ('\\' === \DIRECTORY_SEPARATOR) {
111834 exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
111835 if ($exitCode && $this->isRunning()) {
111836 if ($throwException) {
111837 throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
111838 }
111839 
111840 return false;
111841 }
111842 } else {
111843 if (!$this->enhanceSigchildCompatibility || !$this->isSigchildEnabled()) {
111844 $ok = @proc_terminate($this->process, $signal);
111845 } elseif (\function_exists('posix_kill')) {
111846 $ok = @posix_kill($pid, $signal);
111847 } elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), array(2 => array('pipe', 'w')), $pipes)) {
111848 $ok = false === fgets($pipes[2]);
111849 }
111850 if (!$ok) {
111851 if ($throwException) {
111852 throw new RuntimeException(sprintf('Error while sending signal `%s`.', $signal));
111853 }
111854 
111855 return false;
111856 }
111857 }
111858 
111859 $this->latestSignal = (int) $signal;
111860 $this->fallbackStatus['signaled'] = true;
111861 $this->fallbackStatus['exitcode'] = -1;
111862 $this->fallbackStatus['termsig'] = $this->latestSignal;
111863 
111864 return true;
111865 }
111866 
111867 
111868 
111869 
111870 
111871 
111872 
111873 
111874 private function requireProcessIsStarted($functionName)
111875 {
111876 if (!$this->isStarted()) {
111877 throw new LogicException(sprintf('Process must be started before calling %s.', $functionName));
111878 }
111879 }
111880 
111881 
111882 
111883 
111884 
111885 
111886 
111887 
111888 private function requireProcessIsTerminated($functionName)
111889 {
111890 if (!$this->isTerminated()) {
111891 throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
111892 }
111893 }
111894 }
111895 <?php
111896 
111897 
111898 
111899 
111900 
111901 
111902 
111903 
111904 
111905 
111906 namespace Symfony\Component\Process;
111907 
111908 use Symfony\Component\Process\Exception\InvalidArgumentException;
111909 use Symfony\Component\Process\Exception\LogicException;
111910 
111911 
111912 
111913 
111914 class ProcessBuilder
111915 {
111916 private $arguments;
111917 private $cwd;
111918 private $env = array();
111919 private $input;
111920 private $timeout = 60;
111921 private $options = array();
111922 private $inheritEnv = true;
111923 private $prefix = array();
111924 private $outputDisabled = false;
111925 
111926 
111927 
111928 
111929 public function __construct(array $arguments = array())
111930 {
111931 $this->arguments = $arguments;
111932 }
111933 
111934 
111935 
111936 
111937 
111938 
111939 
111940 
111941 public static function create(array $arguments = array())
111942 {
111943 return new static($arguments);
111944 }
111945 
111946 
111947 
111948 
111949 
111950 
111951 
111952 
111953 public function add($argument)
111954 {
111955 $this->arguments[] = $argument;
111956 
111957 return $this;
111958 }
111959 
111960 
111961 
111962 
111963 
111964 
111965 
111966 
111967 
111968 
111969 public function setPrefix($prefix)
111970 {
111971 $this->prefix = \is_array($prefix) ? $prefix : array($prefix);
111972 
111973 return $this;
111974 }
111975 
111976 
111977 
111978 
111979 
111980 
111981 
111982 
111983 
111984 
111985 
111986 public function setArguments(array $arguments)
111987 {
111988 $this->arguments = $arguments;
111989 
111990 return $this;
111991 }
111992 
111993 
111994 
111995 
111996 
111997 
111998 
111999 
112000 public function setWorkingDirectory($cwd)
112001 {
112002 $this->cwd = $cwd;
112003 
112004 return $this;
112005 }
112006 
112007 
112008 
112009 
112010 
112011 
112012 
112013 
112014 public function inheritEnvironmentVariables($inheritEnv = true)
112015 {
112016 $this->inheritEnv = $inheritEnv;
112017 
112018 return $this;
112019 }
112020 
112021 
112022 
112023 
112024 
112025 
112026 
112027 
112028 
112029 
112030 
112031 
112032 public function setEnv($name, $value)
112033 {
112034 $this->env[$name] = $value;
112035 
112036 return $this;
112037 }
112038 
112039 
112040 
112041 
112042 
112043 
112044 
112045 
112046 
112047 
112048 
112049 
112050 public function addEnvironmentVariables(array $variables)
112051 {
112052 $this->env = array_replace($this->env, $variables);
112053 
112054 return $this;
112055 }
112056 
112057 
112058 
112059 
112060 
112061 
112062 
112063 
112064 
112065 
112066 
112067 
112068 public function setInput($input)
112069 {
112070 $this->input = ProcessUtils::validateInput(__METHOD__, $input);
112071 
112072 return $this;
112073 }
112074 
112075 
112076 
112077 
112078 
112079 
112080 
112081 
112082 
112083 
112084 
112085 
112086 public function setTimeout($timeout)
112087 {
112088 if (null === $timeout) {
112089 $this->timeout = null;
112090 
112091 return $this;
112092 }
112093 
112094 $timeout = (float) $timeout;
112095 
112096 if ($timeout < 0) {
112097 throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
112098 }
112099 
112100 $this->timeout = $timeout;
112101 
112102 return $this;
112103 }
112104 
112105 
112106 
112107 
112108 
112109 
112110 
112111 
112112 
112113 public function setOption($name, $value)
112114 {
112115 $this->options[$name] = $value;
112116 
112117 return $this;
112118 }
112119 
112120 
112121 
112122 
112123 
112124 
112125 public function disableOutput()
112126 {
112127 $this->outputDisabled = true;
112128 
112129 return $this;
112130 }
112131 
112132 
112133 
112134 
112135 
112136 
112137 public function enableOutput()
112138 {
112139 $this->outputDisabled = false;
112140 
112141 return $this;
112142 }
112143 
112144 
112145 
112146 
112147 
112148 
112149 
112150 
112151 public function getProcess()
112152 {
112153 if (0 === \count($this->prefix) && 0 === \count($this->arguments)) {
112154 throw new LogicException('You must add() command arguments before calling getProcess().');
112155 }
112156 
112157 $options = $this->options;
112158 
112159 $arguments = array_merge($this->prefix, $this->arguments);
112160 $script = implode(' ', array_map(array(__NAMESPACE__.'\\ProcessUtils', 'escapeArgument'), $arguments));
112161 
112162 if ($this->inheritEnv) {
112163 
112164 $env = array_replace($_ENV, $_SERVER, $this->env);
112165 } else {
112166 $env = $this->env;
112167 }
112168 
112169 $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options);
112170 
112171 if ($this->outputDisabled) {
112172 $process->disableOutput();
112173 }
112174 
112175 return $process;
112176 }
112177 }
112178 <?php
112179 
112180 
112181 
112182 
112183 
112184 
112185 
112186 
112187 
112188 
112189 namespace Symfony\Component\Process;
112190 
112191 use Symfony\Component\Process\Exception\InvalidArgumentException;
112192 
112193 
112194 
112195 
112196 
112197 
112198 
112199 
112200 class ProcessUtils
112201 {
112202 
112203 
112204 
112205 private function __construct()
112206 {
112207 }
112208 
112209 
112210 
112211 
112212 
112213 
112214 
112215 
112216 public static function escapeArgument($argument)
112217 {
112218 
112219 
112220 
112221 
112222 if ('\\' === \DIRECTORY_SEPARATOR) {
112223 if ('' === $argument) {
112224 return escapeshellarg($argument);
112225 }
112226 
112227 $escapedArgument = '';
112228 $quote = false;
112229 foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
112230 if ('"' === $part) {
112231 $escapedArgument .= '\\"';
112232 } elseif (self::isSurroundedBy($part, '%')) {
112233 
112234 $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
112235 } else {
112236 
112237 if ('\\' === substr($part, -1)) {
112238 $part .= '\\';
112239 }
112240 $quote = true;
112241 $escapedArgument .= $part;
112242 }
112243 }
112244 if ($quote) {
112245 $escapedArgument = '"'.$escapedArgument.'"';
112246 }
112247 
112248 return $escapedArgument;
112249 }
112250 
112251 return "'".str_replace("'", "'\\''", $argument)."'";
112252 }
112253 
112254 
112255 
112256 
112257 
112258 
112259 
112260 
112261 
112262 
112263 
112264 
112265 
112266 public static function validateInput($caller, $input)
112267 {
112268 if (null !== $input) {
112269 if (\is_resource($input)) {
112270 return $input;
112271 }
112272 if (\is_string($input)) {
112273 return $input;
112274 }
112275 if (is_scalar($input)) {
112276 return (string) $input;
112277 }
112278 
112279 if (\is_object($input) && method_exists($input, '__toString')) {
112280 @trigger_error('Passing an object as an input is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
112281 
112282 return (string) $input;
112283 }
112284 
112285 throw new InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller));
112286 }
112287 
112288 return $input;
112289 }
112290 
112291 private static function isSurroundedBy($arg, $char)
112292 {
112293 return 2 < \strlen($arg) && $char === $arg[0] && $char === $arg[\strlen($arg) - 1];
112294 }
112295 }
112296 <?php
112297 
112298 if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
112299     echo 'Warning: Composer should be invoked via the CLI version of PHP, not the '.PHP_SAPI.' SAPI'.PHP_EOL;
112300 }
112301 
112302 setlocale(LC_ALL, 'C');
112303 require __DIR__.'/../src/bootstrap.php';
112304 
112305 use Composer\Console\Application;
112306 use Composer\XdebugHandler\XdebugHandler;
112307 use Composer\Util\Platform;
112308 use Composer\Util\ErrorHandler;
112309 
112310 error_reporting(-1);
112311 
112312 // Restart without Xdebug
112313 $xdebug = new XdebugHandler('Composer');
112314 $xdebug->check();
112315 unset($xdebug);
112316 
112317 if (defined('HHVM_VERSION') && version_compare(HHVM_VERSION, '4.0', '>=')) {
112318     echo 'HHVM 4.0 has dropped support for Composer, please use PHP instead. Aborting.'.PHP_EOL;
112319     exit(1);
112320 }
112321 if (!extension_loaded('iconv') && !extension_loaded('mbstring')) {
112322     echo 'The iconv OR mbstring extension is required and both are missing.'
112323         .PHP_EOL.'Install either of them or recompile php without --disable-iconv.'
112324         .PHP_EOL.'Aborting.'.PHP_EOL;
112325     exit(1);
112326 }
112327 
112328 if (function_exists('ini_set')) {
112329     @ini_set('display_errors', '1');
112330 
112331     // Set user defined memory limit
112332     if ($memoryLimit = getenv('COMPOSER_MEMORY_LIMIT')) {
112333         @ini_set('memory_limit', $memoryLimit);
112334     } else {
112335         $memoryInBytes = function ($value) {
112336             $unit = strtolower(substr($value, -1, 1));
112337             $value = (int) $value;
112338             switch($unit) {
112339                 case 'g':
112340                     $value *= 1024;
112341                     // no break (cumulative multiplier)
112342                 case 'm':
112343                     $value *= 1024;
112344                     // no break (cumulative multiplier)
112345                 case 'k':
112346                     $value *= 1024;
112347             }
112348 
112349             return $value;
112350         };
112351 
112352         $memoryLimit = trim(ini_get('memory_limit'));
112353         // Increase memory_limit if it is lower than 1.5GB
112354         if ($memoryLimit != -1 && $memoryInBytes($memoryLimit) < 1024 * 1024 * 1536) {
112355             @ini_set('memory_limit', '1536M');
112356         }
112357         unset($memoryInBytes);
112358     }
112359     unset($memoryLimit);
112360 }
112361 
112362 // Workaround PHP bug on Windows where env vars containing Unicode chars are mangled in $_SERVER
112363 // see https://github.com/php/php-src/issues/7896
112364 if (PHP_VERSION_ID >= 70113 && (PHP_VERSION_ID < 80016 || (PHP_VERSION_ID >= 80100 && PHP_VERSION_ID < 80103)) && Platform::isWindows()) {
112365     foreach ($_SERVER as $serverVar => $serverVal) {
112366         if (($serverVal = getenv($serverVar)) !== false) {
112367             $_SERVER[$serverVar] = $serverVal;
112368         }
112369     }
112370 }
112371 
112372 Platform::putEnv('COMPOSER_BINARY', realpath($_SERVER['argv'][0]));
112373 
112374 ErrorHandler::register();
112375 
112376 // run the command application
112377 $application = new Application();
112378 $application->run();
112379 
112380 Copyright (c) Nils Adermann, Jordi Boggiano
112381 
112382 Permission is hereby granted, free of charge, to any person obtaining a copy
112383 of this software and associated documentation files (the "Software"), to deal
112384 in the Software without restriction, including without limitation the rights
112385 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112386 copies of the Software, and to permit persons to whom the Software is furnished
112387 to do so, subject to the following conditions:
112388 
112389 The above copyright notice and this permission notice shall be included in all
112390 copies or substantial portions of the Software.
112391 
112392 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
112393 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
112394 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
112395 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
112396 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
112397 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
112398 THE SOFTWARE.
112399 
112400 rΆ��I�vR�4J}��#�\;{�������T�v�T}+�;��<�8���Ҍ����Ÿ!2�GBMB