#!/usr/bin/env php
<?php

/*
 * Generated by Humbug Box 3.16.0@adb282a.
 *
 * @link https://github.com/humbug/box
 */

Phar::mapPhar('box-auto-generated-alias-d30d4e12fdbe.phar');

require 'phar://box-auto-generated-alias-d30d4e12fdbe.phar/.box/bin/check-requirements.php';

require 'phar://box-auto-generated-alias-d30d4e12fdbe.phar/bin/phpbrew';

__HALT_COMPILER(); ?>
`               /   vendor/symfony/class-loader/Psr4ClassLoader.phpB  38dB  ۪}I      #   vendor/symfony/class-loader/LICENSE)  38d)  NUN      1   vendor/symfony/class-loader/ClassMapGenerator.phpI  38dI  ,      9   vendor/symfony/class-loader/DebugUniversalClassLoader.php  38d  X%I      4   vendor/symfony/class-loader/UniversalClassLoader.php&  38d&  R      5   vendor/symfony/class-loader/ClassCollectionLoader.php  38d  H/]ִ      0   vendor/symfony/class-loader/DebugClassLoader.php  38d  px      3   vendor/symfony/class-loader/WinCacheClassLoader.php  38d  xA      7   vendor/symfony/class-loader/ApcUniversalClassLoader.php6  38d6  <?0      .   vendor/symfony/class-loader/MapClassLoader.php   38d   ]kV      +   vendor/symfony/class-loader/ClassLoader.php  38d  ?      1   vendor/symfony/class-loader/XcacheClassLoader.php  38d  zBq      .   vendor/symfony/class-loader/ApcClassLoader.php  38d  2      %   vendor/symfony/polyfill-ctype/LICENSE)  38d)  `e0      '   vendor/symfony/polyfill-ctype/Ctype.php
  38d
  ~d      -   vendor/symfony/polyfill-ctype/bootstrap80.phph  38dh  Ky      +   vendor/symfony/polyfill-ctype/bootstrap.php2  38d2  a8      $   vendor/symfony/polyfill-apcu/LICENSE)  38d)  \      %   vendor/symfony/polyfill-apcu/Apcu.php  38d  ~AA      ,   vendor/symfony/polyfill-apcu/bootstrap80.php	  38d	        *   vendor/symfony/polyfill-apcu/bootstrap.php	  38d	  JUݴ      ,   vendor/symfony/deprecation-contracts/LICENSE)  38d)  2      1   vendor/symfony/deprecation-contracts/function.php=  38d=           vendor/symfony/yaml/LICENSE)  38d)  ax      !   vendor/symfony/yaml/Unescaper.php  38d  .K         vendor/symfony/yaml/Escaper.php  38d  Gl         vendor/symfony/yaml/Parser.phpz  38dz  rp      '   vendor/symfony/yaml/Tag/TaggedValue.phpC  38dC  *ʴ         vendor/symfony/yaml/Yaml.phpG  38dG  Pn         vendor/symfony/yaml/Inline.phpP  38dP  4w      +   vendor/symfony/yaml/Command/LintCommand.phpp  38dp  s0      +   vendor/symfony/yaml/Resources/bin/yaml-lint  38d           vendor/symfony/yaml/Dumper.php  38d  X8      2   vendor/symfony/yaml/Exception/RuntimeException.php   38d   $      /   vendor/symfony/yaml/Exception/DumpException.phps   38ds   ƴ      4   vendor/symfony/yaml/Exception/ExceptionInterface.phpv   38dv   0ʴ      0   vendor/symfony/yaml/Exception/ParseException.phph  38dh  u      :   vendor/symfony/finder/Iterator/DateRangeFilterIterator.phpx  38dx  P      ;   vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php  38d  ͝q      =   vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php*  38d*        4   vendor/symfony/finder/Iterator/FilePathsIterator.php#  38d#  G?T      3   vendor/symfony/finder/Iterator/SortableIterator.php+  38d+         7   vendor/symfony/finder/Iterator/CustomFilterIterator.php]  38d]  oƴ      A   vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php  38d  nH      5   vendor/symfony/finder/Iterator/PathFilterIterator.php  38d  c      9   vendor/symfony/finder/Iterator/FilenameFilterIterator.phpr  38dr  tu      =   vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php	  38d	  O}C      :   vendor/symfony/finder/Iterator/SizeRangeFilterIterator.phpe  38de        1   vendor/symfony/finder/Iterator/FilterIterator.php  38d  㯴      <   vendor/symfony/finder/Iterator/FilecontentFilterIterator.php5  38d5        9   vendor/symfony/finder/Iterator/FileTypeFilterIterator.phpZ  38dZ  (&         vendor/symfony/finder/LICENSE)  38d)  NUN          vendor/symfony/finder/Finder.phpc.  38dc.  :5g      *   vendor/symfony/finder/Expression/Regex.php  38d  ;M)      /   vendor/symfony/finder/Expression/Expression.php  38d  i:Ŵ      3   vendor/symfony/finder/Expression/ValueInterface.php  38d  \p4      )   vendor/symfony/finder/Expression/Glob.phpf  38df  Dcj      '   vendor/symfony/finder/Shell/Command.php>  38d>  _~u      %   vendor/symfony/finder/Shell/Shell.phpq  38dq  ӊ0      5   vendor/symfony/finder/Comparator/NumberComparator.php{  38d{  Y      3   vendor/symfony/finder/Comparator/DateComparator.php#  38d#  δ      /   vendor/symfony/finder/Comparator/Comparator.php  38d        %   vendor/symfony/finder/SplFileInfo.php  38d         2   vendor/symfony/finder/Adapter/AdapterInterface.php  38d  M      1   vendor/symfony/finder/Adapter/AbstractAdapter.php\  38d\  hB      5   vendor/symfony/finder/Adapter/AbstractFindAdapter.php  38d  kM޴      ,   vendor/symfony/finder/Adapter/PhpAdapter.php  38d  d;      0   vendor/symfony/finder/Adapter/GnuFindAdapter.php  38d  O      0   vendor/symfony/finder/Adapter/BsdFindAdapter.php2  38d2  D)         vendor/symfony/finder/Glob.phpL  38dL  j9״      A   vendor/symfony/finder/Exception/OperationNotPermitedException.php)  38d)  xe      ;   vendor/symfony/finder/Exception/AdapterFailureException.php  38d  wR      6   vendor/symfony/finder/Exception/ExceptionInterface.php   38d   Gz-      @   vendor/symfony/finder/Exception/ShellCommandFailureException.php  38d        9   vendor/symfony/finder/Exception/AccessDeniedException.php   38d   s         vendor/twig/twig/LICENSE  38d  Qִ      *   vendor/twig/twig/lib/Twig/SimpleFilter.php~   38d~   Ȭ       ,   vendor/twig/twig/lib/Twig/CacheInterface.php   38d   kh)ٴ      2   vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php   38d   Ġ5      +   vendor/twig/twig/lib/Twig/NodeTraverser.php   38d   N      0   vendor/twig/twig/lib/Twig/ExtensionInterface.php   38d   ^      E   vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php   38d   cG]      4   vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php   38d   Vm      E   vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php   38d   Ayߴ      C   vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php   38d   t_C      @   vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php   38d         3   vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php   38d   yu      =   vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php   38d   j	X      C   vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php   38d   >      '   vendor/twig/twig/lib/Twig/Extension.php   38d   ,      $   vendor/twig/twig/lib/Twig/Parser.phpl   38dl   sմ      3   vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php   38d   `-Lx      (   vendor/twig/twig/lib/Twig/Node/Macro.php   38d   3      '   vendor/twig/twig/lib/Twig/Node/Text.php   38d   5s      '   vendor/twig/twig/lib/Twig/Node/Body.php   38d   񑬄      *   vendor/twig/twig/lib/Twig/Node/Sandbox.php   38d   I      1   vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php   38d   Vv      0   vendor/twig/twig/lib/Twig/Node/CheckSecurity.php   38d   Əд      @   vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php>  38d>  ko      3   vendor/twig/twig/lib/Twig/Node/Expression/Array.php   38d   U      7   vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php   38d   ţ      7   vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php   38d   b      7   vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php   38d   4B      9   vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php   38d   A      4   vendor/twig/twig/lib/Twig/Node/Expression/Binary.php   38d    E      8   vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php   38d   `ƴ      2   vendor/twig/twig/lib/Twig/Node/Expression/Name.php   38d   ô      <   vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php   38d   /      =   vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php   38d         >   vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php   38d   7J      8   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php   38d   gq      8   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php   38d   ܡr      8   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php   38d   y/a      8   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php   38d   烴      7   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php   38d   sWܴ      :   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php   38d         =   vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php   38d   pR      ;   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php   38d   Rz      ?   vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php   38d   	D      <   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php   38d   
xȴ      =   vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php   38d   OĴ      :   vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php   38d   +@      >   vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php   38d   ڋSL      <   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php   38d   D      :   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php   38d   x7G      9   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php   38d   _ƴ      8   vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php   38d   +      :   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php   38d   ;t      ?   vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php   38d   lNi      7   vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php   38d         ?   vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php   38d   N      A   vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php   38d   7      8   vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php   38d   My!      5   vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php   38d   #      8   vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php   38d   ?      4   vendor/twig/twig/lib/Twig/Node/Expression/Filter.php   38d   Vk      <   vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php   38d   c~      3   vendor/twig/twig/lib/Twig/Node/Expression/Unary.php   38d   풴      2   vendor/twig/twig/lib/Twig/Node/Expression/Call.php   38d   O      6   vendor/twig/twig/lib/Twig/Node/Expression/Constant.php   38d   *w@      6   vendor/twig/twig/lib/Twig/Node/Expression/Function.php   38d   5(Ӵ      4   vendor/twig/twig/lib/Twig/Node/Expression/Parent.php   38d         6   vendor/twig/twig/lib/Twig/Node/Expression/TempName.php   38d   ,      :   vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php   38d   [N~      *   vendor/twig/twig/lib/Twig/Node/ForLoop.php   38d   ]x      -   vendor/twig/twig/lib/Twig/Node/AutoEscape.php   38d         %   vendor/twig/twig/lib/Twig/Node/If.phpw   38dw   Z~      -   vendor/twig/twig/lib/Twig/Node/Expression.php   38d   fm      (   vendor/twig/twig/lib/Twig/Node/Embed.php   38d         %   vendor/twig/twig/lib/Twig/Node/Do.phpw   38dw         -   vendor/twig/twig/lib/Twig/Node/Deprecated.php   38d   \y.      (   vendor/twig/twig/lib/Twig/Node/Block.php   38d   8x@      1   vendor/twig/twig/lib/Twig/Node/BlockReference.php   38d         )   vendor/twig/twig/lib/Twig/Node/Module.php   38d   6Ҵ      '   vendor/twig/twig/lib/Twig/Node/With.php   38d   &O      &   vendor/twig/twig/lib/Twig/Node/For.php{   38d{         (   vendor/twig/twig/lib/Twig/Node/Flush.php   38d   (      )   vendor/twig/twig/lib/Twig/Node/Import.php   38d   t      (   vendor/twig/twig/lib/Twig/Node/Print.php   38d   z4a      *   vendor/twig/twig/lib/Twig/Node/Include.php   38d   ƴ      *   vendor/twig/twig/lib/Twig/Node/SetTemp.php   38d   ϴ      ,   vendor/twig/twig/lib/Twig/Node/Spaceless.php   38d   V䣴      &   vendor/twig/twig/lib/Twig/Node/Set.php{   38d{   15y      -   vendor/twig/twig/lib/Twig/LoaderInterface.php   38d   нʹ      *   vendor/twig/twig/lib/Twig/Loader/Array.php   38d   X      /   vendor/twig/twig/lib/Twig/Loader/Filesystem.php   38d   +!      *   vendor/twig/twig/lib/Twig/Loader/Chain.php   38d   Az      +   vendor/twig/twig/lib/Twig/Loader/String.php  38d  -ak      $   vendor/twig/twig/lib/Twig/Markup.phpl   38dl   S]      +   vendor/twig/twig/lib/Twig/NodeInterface.php   38d   M=      #   vendor/twig/twig/lib/Twig/Token.phph   38dh   Џ      &   vendor/twig/twig/lib/Twig/Compiler.phpt   38dt   sl      /   vendor/twig/twig/lib/Twig/FunctionInterface.php2  38d2  2״      4   vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php   38d   -e      2   vendor/twig/twig/lib/Twig/NodeVisitorInterface.php   38d   YO      )   vendor/twig/twig/lib/Twig/TokenStream.php   38d   a      /   vendor/twig/twig/lib/Twig/TemplateInterface.phpV  38dV  hX      (   vendor/twig/twig/lib/Twig/Autoloader.php  38d        #   vendor/twig/twig/lib/Twig/Lexer.phph   38dh         7   vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php   38d   h      6   vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php   38d   7?      )   vendor/twig/twig/lib/Twig/Filter/Node.php  38d  Դ      +   vendor/twig/twig/lib/Twig/Filter/Method.php  38d  F@      -   vendor/twig/twig/lib/Twig/Filter/Function.php  38d  p      -   vendor/twig/twig/lib/Twig/ParserInterface.php   38d   L~      8   vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php  38d  Bozδ      +   vendor/twig/twig/lib/Twig/TestInterface.phpX   38dX   Y      ,   vendor/twig/twig/lib/Twig/SimpleFunction.php   38d   68      3   vendor/twig/twig/lib/Twig/TestCallableInterface.php_   38d_   ]YL      "   vendor/twig/twig/lib/Twig/Node.phpn   38dn   DS      -   vendor/twig/twig/lib/Twig/TemplateWrapper.php   38d   2      $   vendor/twig/twig/lib/Twig/Source.phpl   38dl   u(      )   vendor/twig/twig/lib/Twig/TokenParser.php   38d   X      .   vendor/twig/twig/lib/Twig/Cache/Filesystem.php   38d         (   vendor/twig/twig/lib/Twig/Cache/Null.php   38d   &I      $   vendor/twig/twig/lib/Twig/Filter.php:  38d:  2dsC      4   vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php   38d   g.      -   vendor/twig/twig/lib/Twig/FilterInterface.phpw  38dw  v2      /   vendor/twig/twig/lib/Twig/TokenParser/Macro.php   38d   aŴ      1   vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php   38d   a;      4   vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php   38d    C      ,   vendor/twig/twig/lib/Twig/TokenParser/If.php   38d          /   vendor/twig/twig/lib/Twig/TokenParser/Embed.php   38d   1ҶҴ      ,   vendor/twig/twig/lib/Twig/TokenParser/Do.php   38d   XK      4   vendor/twig/twig/lib/Twig/TokenParser/Deprecated.php   38d   lV      /   vendor/twig/twig/lib/Twig/TokenParser/Block.php   38d         0   vendor/twig/twig/lib/Twig/TokenParser/Filter.php   38d   V ̓      .   vendor/twig/twig/lib/Twig/TokenParser/With.php   38d   T\      -   vendor/twig/twig/lib/Twig/TokenParser/For.php   38d   h<e      /   vendor/twig/twig/lib/Twig/TokenParser/Flush.php   38d   di      0   vendor/twig/twig/lib/Twig/TokenParser/Import.php   38d   
2      1   vendor/twig/twig/lib/Twig/TokenParser/Include.php   38d   TӴ      -   vendor/twig/twig/lib/Twig/TokenParser/Use.php   38d   (8|      .   vendor/twig/twig/lib/Twig/TokenParser/From.php   38d   mwF      3   vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php   38d   G      1   vendor/twig/twig/lib/Twig/TokenParser/Extends.php   38d   8'      -   vendor/twig/twig/lib/Twig/TokenParser/Set.php   38d   f      <   vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php   38d   m	      0   vendor/twig/twig/lib/Twig/Extension/Profiler.php   38d   ~      ,   vendor/twig/twig/lib/Twig/Extension/Core.php   38d   @|l      /   vendor/twig/twig/lib/Twig/Extension/Sandbox.php   38d   "      /   vendor/twig/twig/lib/Twig/Extension/Escaper.php   38d   !<      1   vendor/twig/twig/lib/Twig/Extension/Optimizer.php   38d   o      -   vendor/twig/twig/lib/Twig/Extension/Debug.php   38d   JB      /   vendor/twig/twig/lib/Twig/Extension/Staging.php   38d   3ʹ      8   vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php   38d   nx      4   vendor/twig/twig/lib/Twig/Extension/StringLoader.php   38d   .      &   vendor/twig/twig/lib/Twig/Function.php  38d  dT      /   vendor/twig/twig/lib/Twig/CompilerInterface.php   38d   Pۘ"      2   vendor/twig/twig/lib/Twig/TokenParserInterface.php   38d   @]      +   vendor/twig/twig/lib/Twig/Function/Node.php  38d  +ZO      -   vendor/twig/twig/lib/Twig/Function/Method.php  38d  1      /   vendor/twig/twig/lib/Twig/Function/Function.php  38d  致      -   vendor/twig/twig/lib/Twig/BaseNodeVisitor.php   38d   $޴      1   vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php   38d   ܨ      1   vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php   38d   X      3   vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php   38d   vK      6   vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php   38d   \k      ,   vendor/twig/twig/lib/Twig/LexerInterface.php   38d         :   vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php   38d   1      1   vendor/twig/twig/lib/Twig/NodeOutputInterface.php   38d   %5      /   vendor/twig/twig/lib/Twig/TokenParserBroker.php(  38d(  ^      *   vendor/twig/twig/lib/Twig/Error/Syntax.php   38d   s      *   vendor/twig/twig/lib/Twig/Error/Loader.php   38d         +   vendor/twig/twig/lib/Twig/Error/Runtime.php   38d   {      )   vendor/twig/twig/lib/Twig/Environment.php   38d   &      2   vendor/twig/twig/lib/Twig/NodeCaptureInterface.php   38d   %V      &   vendor/twig/twig/lib/Twig/Template.phpt   38dt   v      7   vendor/twig/twig/lib/Twig/FunctionCallableInterface.phpe   38de   4      ;   vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php   38d   5      5   vendor/twig/twig/lib/Twig/FilterCallableInterface.phpc   38dc   S      8   vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php   38d   b^      8   vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php   38d   .!      .   vendor/twig/twig/lib/Twig/Profiler/Profile.php   38d   
      ;   vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php   38d   ~|#      2   vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php   38d   !|      7   vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php   38d   !Ѵ      2   vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php   38d   pk{      2   vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php   38d   |Pô      #   vendor/twig/twig/lib/Twig/Error.phpt   38dt    ,ݴ      .   vendor/twig/twig/lib/Twig/ExpressionParser.php   38d   A"      ;   vendor/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php  38d  *      =   vendor/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php   38d   t[~      =   vendor/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php  38d  \̰      &   vendor/twig/twig/src/NodeTraverser.php  38d  VM-      @   vendor/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php  38d  ˅y      /   vendor/twig/twig/src/Sandbox/SecurityPolicy.php  38d  d      @   vendor/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php  38d  0      >   vendor/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php  38d  i}&      ;   vendor/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php  38d  ;      .   vendor/twig/twig/src/Sandbox/SecurityError.php   38d   t      8   vendor/twig/twig/src/Sandbox/SecurityPolicyInterface.phpX  38dX        >   vendor/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.phpz  38dz  Y-         vendor/twig/twig/src/Parser.phpI%  38dI%  tw>      ,   vendor/twig/twig/src/Node/DeprecatedNode.php  38d  no      )   vendor/twig/twig/src/Node/SandboxNode.php'  38d'  `]      )   vendor/twig/twig/src/Node/ForLoopNode.php  38d   ˩      /   vendor/twig/twig/src/Node/CheckToStringNode.php  38d  Dݧ      '   vendor/twig/twig/src/Node/FlushNode.php\  38d\  zo      0   vendor/twig/twig/src/Node/BlockReferenceNode.php  38d  ־      <   vendor/twig/twig/src/Node/Expression/Unary/AbstractUnary.phpO  38dO  g+      7   vendor/twig/twig/src/Node/Expression/Unary/PosUnary.php  38d  uE      7   vendor/twig/twig/src/Node/Expression/Unary/NegUnary.php  38d  q      7   vendor/twig/twig/src/Node/Expression/Unary/NotUnary.php  38d  +_      A   vendor/twig/twig/src/Node/Expression/BlockReferenceExpression.php  38d  sdw      @   vendor/twig/twig/src/Node/Expression/ArrowFunctionExpression.phpz  38dz        9   vendor/twig/twig/src/Node/Expression/ParentExpression.php  38d  Dh)Ҵ      ;   vendor/twig/twig/src/Node/Expression/AbstractExpression.php   38d   5      ;   vendor/twig/twig/src/Node/Expression/ConstantExpression.php  38d  ~      =   vendor/twig/twig/src/Node/Expression/MethodCallExpression.phpx  38dx  §      ;   vendor/twig/twig/src/Node/Expression/TempNameExpression.php  38d  [j      =   vendor/twig/twig/src/Node/Expression/AssignNameExpression.phpZ  38dZ  gn      =   vendor/twig/twig/src/Node/Expression/Filter/DefaultFilter.php  38d  Y      8   vendor/twig/twig/src/Node/Expression/Binary/OrBinary.php  38d  .NҴ      ;   vendor/twig/twig/src/Node/Expression/Binary/PowerBinary.php  38d  [8      ;   vendor/twig/twig/src/Node/Expression/Binary/NotInBinary.php  38d  Ӵ      9   vendor/twig/twig/src/Node/Expression/Binary/AndBinary.php   38d   !Ԇ      ?   vendor/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php1  38d1  f      :   vendor/twig/twig/src/Node/Expression/Binary/LessBinary.php!  38d!  +      9   vendor/twig/twig/src/Node/Expression/Binary/AddBinary.php  38d  Q=^      @   vendor/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php4  38d4  ~?|      =   vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php  38d  	      >   vendor/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php  38d  v<b      @   vendor/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php  38d  /Kh      >   vendor/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php.  38d.  A      >   vendor/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php  38d  Cb4      =   vendor/twig/twig/src/Node/Expression/Binary/GreaterBinary.php*  38d*  *5A      <   vendor/twig/twig/src/Node/Expression/Binary/ConcatBinary.php(  38d(  }      9   vendor/twig/twig/src/Node/Expression/Binary/ModBinary.php  38d  UFJ      ;   vendor/twig/twig/src/Node/Expression/Binary/EqualBinary.php%  38d%  vϴ      ?   vendor/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php1  38d1  p      9   vendor/twig/twig/src/Node/Expression/Binary/DivBinary.php  38d  nܴ      @   vendor/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php4  38d4  B}      B   vendor/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php:  38d:  g      9   vendor/twig/twig/src/Node/Expression/Binary/SubBinary.php  38d        9   vendor/twig/twig/src/Node/Expression/Binary/MulBinary.php  38d  *8      ;   vendor/twig/twig/src/Node/Expression/Binary/RangeBinary.php  38d  H      8   vendor/twig/twig/src/Node/Expression/Binary/InBinary.php  38d  0       >   vendor/twig/twig/src/Node/Expression/Binary/AbstractBinary.php  38d  5,      8   vendor/twig/twig/src/Node/Expression/ArrayExpression.php  38d  ?k      >   vendor/twig/twig/src/Node/Expression/ConditionalExpression.php  38d  1|      9   vendor/twig/twig/src/Node/Expression/FilterExpression.php  38d  fjv      7   vendor/twig/twig/src/Node/Expression/NameExpression.php  38d  ۈ      7   vendor/twig/twig/src/Node/Expression/CallExpression.php@"  38d@"  6d      4   vendor/twig/twig/src/Node/Expression/InlinePrint.php{  38d{  e      7   vendor/twig/twig/src/Node/Expression/TestExpression.php;  38d;  N      :   vendor/twig/twig/src/Node/Expression/GetAttrExpression.php  38d  ݃{i      ;   vendor/twig/twig/src/Node/Expression/FunctionExpression.php'  38d'  ״      ?   vendor/twig/twig/src/Node/Expression/NullCoalesceExpression.php  38d  PԴ      '   vendor/twig/twig/src/Node/PrintNode.php  38d  A      &   vendor/twig/twig/src/Node/BodyNode.php   38d   ' '      $   vendor/twig/twig/src/Node/DoNode.php  38d  F=      &   vendor/twig/twig/src/Node/TextNode.php  38d  Qɴ      $   vendor/twig/twig/src/Node/IfNode.php  38d  )B      ,   vendor/twig/twig/src/Node/AutoEscapeNode.php  38d  @Fʹ      &   vendor/twig/twig/src/Node/WithNode.php  38d  n      %   vendor/twig/twig/src/Node/SetNode.php  38d  P      "   vendor/twig/twig/src/Node/Node.php  38d  g?      (   vendor/twig/twig/src/Node/ModuleNode.php((  38d((  Yx      '   vendor/twig/twig/src/Node/EmbedNode.php  38d  `2      /   vendor/twig/twig/src/Node/CheckSecurityNode.php  38d        %   vendor/twig/twig/src/Node/ForNode.php  38d  Ȩ|ʴ      '   vendor/twig/twig/src/Node/BlockNode.php[  38d[  2޴      +   vendor/twig/twig/src/Node/SpacelessNode.php  38d  2K      0   vendor/twig/twig/src/Node/SandboxedPrintNode.php:  38d:        1   vendor/twig/twig/src/Node/NodeOutputInterface.php   38d   m      3   vendor/twig/twig/src/Node/CheckSecurityCallNode.php*  38d*        '   vendor/twig/twig/src/Node/MacroNode.php	  38d	  _~%      )   vendor/twig/twig/src/Node/IncludeNode.php  38d  umN      2   vendor/twig/twig/src/Node/NodeCaptureInterface.php   38d   x)      (   vendor/twig/twig/src/Node/ImportNode.php  38d  <5      )   vendor/twig/twig/src/Node/SetTempNode.php(  38d(        5   vendor/twig/twig/src/Loader/ExistsLoaderInterface.php   38d   \ok      /   vendor/twig/twig/src/Loader/LoaderInterface.php;  38d;  ?      0   vendor/twig/twig/src/Loader/FilesystemLoader.phpa  38da  I       +   vendor/twig/twig/src/Loader/ArrayLoader.php%  38d%  1      +   vendor/twig/twig/src/Loader/ChainLoader.phps  38ds  =      <   vendor/twig/twig/src/Loader/SourceContextLoaderInterface.php  38d  =         vendor/twig/twig/src/Markup.php  38d  iv         vendor/twig/twig/src/Token.php  38d  	sƴ      !   vendor/twig/twig/src/Compiler.phpP  38dP  iش      $   vendor/twig/twig/src/TokenStream.php  38d  ]b         vendor/twig/twig/src/Lexer.php7  38d7  񞚴      2   vendor/twig/twig/src/Util/DeprecationCollector.php~  38d~  cZ      1   vendor/twig/twig/src/Util/TemplateDirIterator.php6  38d6  [Xs      %   vendor/twig/twig/src/TwigFunction.php  38d  *t      (   vendor/twig/twig/src/TemplateWrapper.php\  38d\  y<8         vendor/twig/twig/src/Source.php  38d  v      -   vendor/twig/twig/src/Cache/CacheInterface.phpC  38dC  d      (   vendor/twig/twig/src/Cache/NullCache.phpP  38dP  e*      .   vendor/twig/twig/src/Cache/FilesystemCache.php  38d  hKӴ      4   vendor/twig/twig/src/TokenParser/FromTokenParser.phpH  38dH  4\:      :   vendor/twig/twig/src/TokenParser/AutoEscapeTokenParser.php}  38d}  Ƙ۴      2   vendor/twig/twig/src/TokenParser/IfTokenParser.phpQ  38dQ  	=e      6   vendor/twig/twig/src/TokenParser/FilterTokenParser.phpr  38dr   e      5   vendor/twig/twig/src/TokenParser/MacroTokenParser.php
  38d
  Շ*Ҵ      6   vendor/twig/twig/src/TokenParser/ImportTokenParser.php0  38d0  *      7   vendor/twig/twig/src/TokenParser/IncludeTokenParser.phpF  38dF        4   vendor/twig/twig/src/TokenParser/WithTokenParser.php]  38d]  +      9   vendor/twig/twig/src/TokenParser/SpacelessTokenParser.php  38d  SJ      3   vendor/twig/twig/src/TokenParser/ForTokenParser.phpB  38dB  }      7   vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php  38d  939      5   vendor/twig/twig/src/TokenParser/FlushTokenParser.php  38d  D      8   vendor/twig/twig/src/TokenParser/AbstractTokenParser.php3  38d3  	Y      9   vendor/twig/twig/src/TokenParser/TokenParserInterface.php  38d  \/      7   vendor/twig/twig/src/TokenParser/SandboxTokenParser.php:  38d:  E?ݴ      5   vendor/twig/twig/src/TokenParser/EmbedTokenParser.phpo  38do        5   vendor/twig/twig/src/TokenParser/ApplyTokenParser.php  38d  k1      2   vendor/twig/twig/src/TokenParser/DoTokenParser.php  38d  >      3   vendor/twig/twig/src/TokenParser/SetTokenParser.phpl  38dl  PP      3   vendor/twig/twig/src/TokenParser/UseTokenParser.php  38d  o      :   vendor/twig/twig/src/TokenParser/DeprecatedTokenParser.php  38d  Oߴ      5   vendor/twig/twig/src/TokenParser/BlockTokenParser.php  38d  9x      5   vendor/twig/twig/src/Extension/OptimizerExtension.php  38d  ~Du      <   vendor/twig/twig/src/Extension/RuntimeExtensionInterface.phpV   38dV   `>      7   vendor/twig/twig/src/Extension/InitRuntimeInterface.php   38d   o      3   vendor/twig/twig/src/Extension/StagingExtension.php  38d   zJ      5   vendor/twig/twig/src/Extension/ExtensionInterface.php  38d  񄅴      0   vendor/twig/twig/src/Extension/CoreExtension.phpT  38dT  E      1   vendor/twig/twig/src/Extension/DebugExtension.php  38d  d      8   vendor/twig/twig/src/Extension/StringLoaderExtension.phpw  38dw  ae      3   vendor/twig/twig/src/Extension/SandboxExtension.php  38d        3   vendor/twig/twig/src/Extension/GlobalsInterface.php   38d   -s      4   vendor/twig/twig/src/Extension/ProfilerExtension.php  38d         4   vendor/twig/twig/src/Extension/AbstractExtension.php  38d  ٴ      3   vendor/twig/twig/src/Extension/EscaperExtension.phpp  38dp        7   vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php'  38d'  k      9   vendor/twig/twig/src/NodeVisitor/NodeVisitorInterface.php  38d        7   vendor/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php  38d  /L      <   vendor/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php  38d  'ɴ      9   vendor/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php  38d        8   vendor/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php  38d  >Y      *   vendor/twig/twig/src/Error/LoaderError.php   38d   Qش      $   vendor/twig/twig/src/Error/Error.phpc  38dc        +   vendor/twig/twig/src/Error/RuntimeError.php   38d         *   vendor/twig/twig/src/Error/SyntaxError.php  38d  `      $   vendor/twig/twig/src/Environment.phps  38ds  )iN      !   vendor/twig/twig/src/Template.phpR6  38dR6  ge      6   vendor/twig/twig/src/FileExtensionEscapingStrategy.php  38d  o	81      7   vendor/twig/twig/src/Profiler/Node/EnterProfileNode.phpu  38du  ܏3Դ      7   vendor/twig/twig/src/Profiler/Node/LeaveProfileNode.php  38d        )   vendor/twig/twig/src/Profiler/Profile.php
  38d
  a      A   vendor/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php$  38d$  >j[      3   vendor/twig/twig/src/Profiler/Dumper/HtmlDumper.phpd  38dd  +VѴ      3   vendor/twig/twig/src/Profiler/Dumper/BaseDumper.php  38d  tݴ      3   vendor/twig/twig/src/Profiler/Dumper/TextDumper.php  38d  )"K      8   vendor/twig/twig/src/Profiler/Dumper/BlackfireDumper.php  38d  '      #   vendor/twig/twig/src/TwigFilter.phpo  38do  ?      )   vendor/twig/twig/src/ExpressionParser.php^  38d^  e       !   vendor/doctrine/inflector/LICENSE)  38d)  9޴      =   vendor/doctrine/inflector/lib/Doctrine/Inflector/Language.php_  38d_  o      E   vendor/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.phpb  38db  'ۣ      B   vendor/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php   38d         [   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/InflectorFactory.php  38d  G      P   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Rules.php  38d        V   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php  38d  $CS      V   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.php  38d  OT      J   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php  38d  Mɐ      G   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitution.phpM  38dM  rh      S   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/InflectorFactory.php  38d  6      H   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Rules.php  38d  z      N   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php  38d  p      N   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php  38d  H      R   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.php  38d  z[      G   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Rules.php  38d  A      M   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php  38d        M   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.phpK  38dK  Mp\      B   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Pattern.php`  38d`  áXY      C   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php5  38d5  nz8      ?   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Word.php   38d   N%      S   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.php  38d        H   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Rules.php  38d  =%      N   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php  38d  `|/      N   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php3  38d3  δ      V   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/InflectorFactory.php  38d  Q      K   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Rules.php  38d  9H      Q   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php   38d   bWf	      Q   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.phpU  38dU  rS      S   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.php  38d  =i      H   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Rules.php  38d  6*      N   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php  38d        N   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php'  38d'  I34      I   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php  38d  {!$      B   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Ruleset.phpC  38dC        H   vendor/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php6  38d6  )]      H   vendor/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php  38d  `Io.      M   vendor/doctrine/inflector/lib/Doctrine/Inflector/LanguageInflectorFactory.phpo  38do  M      >   vendor/doctrine/inflector/lib/Doctrine/Inflector/Inflector.php5  38d5  F      T   vendor/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php'  38d'        F   vendor/doctrine/inflector/lib/Doctrine/Inflector/NoopWordInflector.php   38d   _{      E   vendor/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php  38d  }=Ǵ         vendor/composer/LICENSE.  38d.         %   vendor/composer/InstalledVersions.php  38d  Pڴ      "   vendor/composer/autoload_files.php  38d  nY      !   vendor/composer/autoload_psr4.php=  38d=        #   vendor/composer/autoload_static.phpć 38dć F_5޴         vendor/composer/installed.php4  38d4  IW      '   vendor/composer/autoload_namespaces.php   38d   bb         vendor/composer/ClassLoader.php>  38d>  5Ky      %   vendor/composer/autoload_classmap.phpW 38dW       "   vendor/composer/platform_check.php  38d  UԴ      !   vendor/composer/autoload_real.php  38d  c         vendor/psr/container/LICENSEy  38dy  Op      /   vendor/psr/container/src/ContainerInterface.php   38d   [d      7   vendor/psr/container/src/NotFoundExceptionInterface.phpq   38dq   R      8   vendor/psr/container/src/ContainerExceptionInterface.phpN   38dN   L         vendor/pimple/pimple/LICENSE)  38d)  n%      8   vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php	  38d	        3   vendor/pimple/pimple/src/Pimple/Psr11/Container.php  38d  ~      <   vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php   38d   /}      -   vendor/pimple/pimple/src/Pimple/Container.php2  38d2  C      3   vendor/pimple/pimple/src/Pimple/ServiceIterator.php  38d  q      H   vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.phpL  38dL  /7      H   vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php   38d   2޴      O   vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.phpj  38dj  S      D   vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.phpG  38dG  #      %   vendor/corneltek/cliframework/LICENSE  38d  Y״      -   vendor/corneltek/cliframework/src/ArgInfo.php&  38d&  E      3   vendor/corneltek/cliframework/src/CommandLoader.php  38d  `z      -   vendor/corneltek/cliframework/src/Command.php  38d  @b      2   vendor/corneltek/cliframework/src/CommandGroup.php  38d  /z      1   vendor/corneltek/cliframework/src/Application.php%  38d%  a      5   vendor/corneltek/cliframework/src/ValueCollection.php,  38d,  {w4^      E   vendor/corneltek/cliframework/src/Component/Progress/ProgressStar.php  38d  &      I   vendor/corneltek/cliframework/src/Component/Progress/ProgressBarStyle.php/  38d/  jK̪      I   vendor/corneltek/cliframework/src/Component/Progress/ProgressReporter.php   38d   >M~      F   vendor/corneltek/cliframework/src/Component/Progress/ETACalculator.php  38d  YX      N   vendor/corneltek/cliframework/src/Component/Progress/SharpProgressBarStyle.phpM  38dM  E      D   vendor/corneltek/cliframework/src/Component/Progress/ProgressBar.php?  38d?  w(      ;   vendor/corneltek/cliframework/src/Component/Table/Table.php  38d  iX      C   vendor/corneltek/cliframework/src/Component/Table/CellAttribute.php	  38d	  /cA      H   vendor/corneltek/cliframework/src/Component/Table/CurrencyFormatCell.php  38d  δ      J   vendor/corneltek/cliframework/src/Component/Table/BorderlessTableStyle.php  38d  Є      @   vendor/corneltek/cliframework/src/Component/Table/TableStyle.php  38d  δ      H   vendor/corneltek/cliframework/src/Component/Table/MarkdownTableStyle.php  38d  \      N   vendor/corneltek/cliframework/src/Component/Table/SpellOutNumberFormatCell.php  38d  T>(ȴ      G   vendor/corneltek/cliframework/src/Component/Table/CompactTableStyle.php  38d   ޴      D   vendor/corneltek/cliframework/src/Component/Table/DateFormatCell.php  38d  .%K      G   vendor/corneltek/cliframework/src/Component/Table/PercentFormatCell.php:  38d:  ϟp      F   vendor/corneltek/cliframework/src/Component/Table/NumberFormatCell.php  38d  92      H   vendor/corneltek/cliframework/src/Component/Table/DurationFormatCell.php;  38d;  (ƴ      Q   vendor/corneltek/cliframework/src/ExceptionPrinter/ProductionExceptionPrinter.php6  38d6  gBy      R   vendor/corneltek/cliframework/src/ExceptionPrinter/DevelopmentExceptionPrinter.php  38d  -iѴ      ,   vendor/corneltek/cliframework/src/Logger.php:  38d:  c      4   vendor/corneltek/cliframework/src/ChainedCommand.php  38d        1   vendor/corneltek/cliframework/src/ArgInfoList.php  38d  {m      5   vendor/corneltek/cliframework/src/CompletionUtils.php	  38d	  =9Ŵ      =   vendor/corneltek/cliframework/src/Completion/ZshGenerator.php4  38d4  j|      >   vendor/corneltek/cliframework/src/Completion/BashGenerator.php;  38d;  yqkx      6   vendor/corneltek/cliframework/src/Completion/Utils.php  38d  9       :   vendor/corneltek/cliframework/src/LevenshteinCorrector.php  38d  >      0   vendor/corneltek/cliframework/src/ValueGroup.phpv  38dv  .       /   vendor/corneltek/cliframework/src/IO/Writer.php   38d   ։5      8   vendor/corneltek/cliframework/src/IO/ReadlineConsole.php  38d  Nr      3   vendor/corneltek/cliframework/src/IO/EchoWriter.php   38d   7      5   vendor/corneltek/cliframework/src/IO/StreamWriter.php  38d         1   vendor/corneltek/cliframework/src/IO/UnixStty.phpl  38dl  д      -   vendor/corneltek/cliframework/src/IO/Stty.php   38d   蚖      8   vendor/corneltek/cliframework/src/IO/StandardConsole.php  38d  Q@h      1   vendor/corneltek/cliframework/src/IO/NullStty.php   38d   '      0   vendor/corneltek/cliframework/src/IO/Console.php   38d   ɏ      9   vendor/corneltek/cliframework/src/Logger/ActionLogger.php5  38d5  S      3   vendor/corneltek/cliframework/src/Logger/Logger.php<   38d<   KaK      ;   vendor/corneltek/cliframework/src/PharKit/PharGenerator.php
  38d
  /G      5   vendor/corneltek/cliframework/src/PharKit/PharURI.php5  38d5  q(Ĵ      1   vendor/corneltek/cliframework/src/Ansi/Colors.phpZ  38dZ  
Ŵ      8   vendor/corneltek/cliframework/src/Ansi/CursorControl.php  38d  )w      /   vendor/corneltek/cliframework/src/Formatter.php
  38d
  ]Wa:      3   vendor/corneltek/cliframework/src/OptionPrinter.php  38d  N&      9   vendor/corneltek/cliframework/src/Config/GlobalConfig.php  38d  )      C   vendor/corneltek/cliframework/src/ArgumentEditor/ArgumentEditor.php!  38d!  fo      .   vendor/corneltek/cliframework/src/Prompter.php  38d  Zg      6   vendor/corneltek/cliframework/src/CommandInterface.php   38d   Q.      1   vendor/corneltek/cliframework/src/CommandBase.php0  38d0  )      9   vendor/corneltek/cliframework/src/Extension/Extension.php[   38d[   :X      @   vendor/corneltek/cliframework/src/Extension/CommandExtension.php  38d  B̴      =   vendor/corneltek/cliframework/src/Extension/ExtensionBase.php  38d  ɴ      ?   vendor/corneltek/cliframework/src/Extension/DaemonExtension.phpO  38dO  ?RF      D   vendor/corneltek/cliframework/src/Extension/ApplicationExtension.php   38d         H   vendor/corneltek/cliframework/src/Autoload/ComposerAutoloadGenerator.php  38d  ns      -   vendor/corneltek/cliframework/src/Chooser.php  38d  ZI      <   vendor/corneltek/cliframework/src/Command/ArchiveCommand.php  38d  Q      B   vendor/corneltek/cliframework/src/Command/ZshCompletionCommand.php  38d  7      9   vendor/corneltek/cliframework/src/Command/HelpCommand.php  38d  M	      J   vendor/corneltek/cliframework/src/Command/BuildGitHubWikiTopicsCommand.phpq  38dq  p      C   vendor/corneltek/cliframework/src/Command/BashCompletionCommand.php  38d  m2      <   vendor/corneltek/cliframework/src/Command/CompileCommand.phpj  38dj  a{      9   vendor/corneltek/cliframework/src/Command/MetaCommand.phpF  38dF  CB      9   vendor/corneltek/cliframework/src/Debug/LineIndicator.php  38d  p      8   vendor/corneltek/cliframework/src/Debug/ConsoleDebug.phpt  38dt  
3Ҵ      @   vendor/corneltek/cliframework/src/ConsoleInfo/EnvConsoleInfo.phpA  38dA  @^      D   vendor/corneltek/cliframework/src/ConsoleInfo/ConsoleInfoFactory.phpV  38dV        F   vendor/corneltek/cliframework/src/ConsoleInfo/ConsoleInfoInterface.php   38d   7m      A   vendor/corneltek/cliframework/src/ConsoleInfo/TputConsoleInfo.php  38d  \D      6   vendor/corneltek/cliframework/src/CommandException.php[   38d[   *)      ,   vendor/corneltek/cliframework/src/Buffer.php(
  38d(
  Av      7   vendor/corneltek/cliframework/src/CommandAutoloader.php,  38d,  (_ʴ      7   vendor/corneltek/cliframework/src/Topic/GitHubTopic.phpP   38dP         5   vendor/corneltek/cliframework/src/Topic/BaseTopic.php  38d  uf      4   vendor/corneltek/cliframework/src/Testing/Parser.phpw  38dw  cߴ      =   vendor/corneltek/cliframework/src/Testing/ConsoleTestCase.php\  38d\  :O      =   vendor/corneltek/cliframework/src/Testing/CommandTestCase.php  38d  K      /   vendor/corneltek/cliframework/src/Corrector.php  38d  2      6   vendor/corneltek/cliframework/src/ServiceContainer.php  38d  j      P   vendor/corneltek/cliframework/src/Exception/ExecuteMethodNotDefinedException.php   38d   55д      O   vendor/corneltek/cliframework/src/Exception/InvalidCommandArgumentException.php  38d  P      M   vendor/corneltek/cliframework/src/Exception/CommandClassNotFoundException.php  38d  ?BG~      D   vendor/corneltek/cliframework/src/Exception/CommandBaseException.php  38d  d       B   vendor/corneltek/cliframework/src/Exception/ExtensionException.phpp  38dp  hg      H   vendor/corneltek/cliframework/src/Exception/CommandNotFoundException.phpe  38de        Q   vendor/corneltek/cliframework/src/Exception/CommandArgumentNotEnoughException.php  38d  Xo      +   vendor/corneltek/cliframework/src/Utils.php5  38d5  t"      4   vendor/corneltek/cliframework/scripts/phar-debug.php(  38d(  |Ĵ      :   vendor/corneltek/cliframework/snippets/zsh/array_expansion   38d   >      8   vendor/corneltek/cliframework/snippets/zsh/_meta_command[  38d[  G˴      B   vendor/corneltek/cliframework/snippets/zsh/_describe_complex_array  38d  IDb      (   vendor/corneltek/cliframework/phpdox.xmlh  38dh  @      ,   vendor/corneltek/cliframework/phprelease.inil   38dl   #(      )   vendor/corneltek/cliframework/package.ini  38d        .   vendor/corneltek/cliframework/cliframework.ini4   38d4   m      >   vendor/corneltek/curlkit/src/CurlKit/Progress/ProgressStar.php6  38d6  9@      G   vendor/corneltek/curlkit/src/CurlKit/Progress/CurlProgressInterface.php   38d   HI      =   vendor/corneltek/curlkit/src/CurlKit/Progress/ProgressBar.php  38d  +      7   vendor/corneltek/curlkit/src/CurlKit/CurlDownloader.php  38d  
Z      5   vendor/corneltek/curlkit/src/CurlKit/CurlResponse.php6  38d6  Tr      4   vendor/corneltek/curlkit/src/CurlKit/CurlRequest.php  38d  2ҏ      6   vendor/corneltek/curlkit/src/CurlKit/CurlException.php   38d   Wg      2   vendor/corneltek/curlkit/src/CurlKit/CurlAgent.php  38d  >      '   vendor/corneltek/curlkit/phprelease.ini   38d   Cg;      "   vendor/corneltek/universal/LICENSE  38d  N      $   vendor/corneltek/universal/bin/phpbc*  38d*  5      @   vendor/corneltek/universal/src/Universal/Http/FilesParameter.php#  38d#        ;   vendor/corneltek/universal/src/Universal/Http/Parameter.php%  38d%  m      ;   vendor/corneltek/universal/src/Universal/Http/PutHandle.php  38d  aQ      >   vendor/corneltek/universal/src/Universal/Http/UploadedFile.php  38d        8   vendor/corneltek/universal/src/Universal/Http/Cookie.php  38d  ݴ      =   vendor/corneltek/universal/src/Universal/Http/HttpRequest.php   38d   D      >   vendor/corneltek/universal/src/Universal/Http/HttpResponse.php  38d  }      @   vendor/corneltek/universal/src/Universal/Http/StreamResponse.php  38d        A   vendor/corneltek/universal/src/Universal/FileSystem/PathUtils.php  38d  Y״      F   vendor/corneltek/universal/src/Universal/Container/ObjectContainer.phpA  38dA  (>d      H   vendor/corneltek/universal/src/Universal/ClassLoader/Psr4ClassLoader.php  38d  P      K   vendor/corneltek/universal/src/Universal/ClassLoader/ChainedClassLoader.php  38d  Q      L   vendor/corneltek/universal/src/Universal/ClassLoader/BytecodeClassLoader.phpo   38do   8      E   vendor/corneltek/universal/src/Universal/ClassLoader/PathIncluder.php/  38d/  ;$      G   vendor/corneltek/universal/src/Universal/ClassLoader/SplClassLoader.php  38d  )F.      G   vendor/corneltek/universal/src/Universal/ClassLoader/MapClassLoader.phpp  38dp  Ux      L   vendor/corneltek/universal/src/Universal/ClassLoader/BasePathClassLoader.php  38d  ޮf      D   vendor/corneltek/universal/src/Universal/ClassLoader/ClassLoader.php   38d    c      H   vendor/corneltek/universal/src/Universal/ClassLoader/Psr0ClassLoader.php  38d  ^E      G   vendor/corneltek/universal/src/Universal/ClassLoader/ApcClassLoader.php  38d  8ô      ;   vendor/corneltek/universal/src/Universal/Event/PhpEvent.php  38d  `      D   vendor/corneltek/universal/src/Universal/Requirement/Requirement.phpp  38dp  l      T   vendor/corneltek/universal/src/Universal/Exception/UploadedFileMoveFailException.php   38d   hӴ      Q   vendor/corneltek/universal/src/Universal/Exception/InvalidUploadFileException.php   38d   t      K   vendor/corneltek/universal/src/Universal/Exception/UploadErrorException.php   38d   *      F   vendor/corneltek/universal/src/Universal/Exception/UploadException.phpJ  38dJ  ʴ      %   vendor/corneltek/universal/phpdox.xmle  38de  6Uf      )   vendor/corneltek/universal/phprelease.iniF   38dF   |1      &   vendor/corneltek/universal/package.xml   38d   1y      &   vendor/corneltek/universal/package.ini   38d   !          vendor/corneltek/codegen/LICENSEJ  38dJ  	BМ      1   vendor/corneltek/codegen/src/CodeGen/Argument.php  38d  u      2   vendor/corneltek/codegen/src/CodeGen/ClassName.phpD  38dD  i{'      <   vendor/corneltek/codegen/src/CodeGen/ClassStaticVariable.php\  38d\  +[(      T   vendor/corneltek/codegen/src/CodeGen/Frameworks/PHPUnit/PHPUnitFrameworkTestCase.phpq  38dq  F8.      F   vendor/corneltek/codegen/src/CodeGen/Frameworks/PHPUnit/Assertions.php  38d  Zë      7   vendor/corneltek/codegen/src/CodeGen/BracketedBlock.php/  38d/  c      G   vendor/corneltek/codegen/src/CodeGen/Generator/ArrayAccessGenerator.php  38d  <&      D   vendor/corneltek/codegen/src/CodeGen/Generator/AppClassGenerator.php  38d  hf      2   vendor/corneltek/codegen/src/CodeGen/Annotator.php  38d        ,   vendor/corneltek/codegen/src/CodeGen/Raw.php   38d         3   vendor/corneltek/codegen/src/CodeGen/Renderable.phpd   38dd   9{       5   vendor/corneltek/codegen/src/CodeGen/LicenseBlock.php  38d  {C      2   vendor/corneltek/codegen/src/CodeGen/UserClass.php  38d  ^Jj      4   vendor/corneltek/codegen/src/CodeGen/ClassMethod.php  38d  	      .   vendor/corneltek/codegen/src/CodeGen/Block.phpk	  38dk	  Z;      1   vendor/corneltek/codegen/src/CodeGen/UseClass.php  38d  6+      5   vendor/corneltek/codegen/src/CodeGen/ArgumentList.php"  38d"  t       5   vendor/corneltek/codegen/src/CodeGen/CommentBlock.php  38d  O-״      3   vendor/corneltek/codegen/src/CodeGen/Exportable.phpV   38dV   Soݴ      1   vendor/corneltek/codegen/src/CodeGen/Variable.php  38d  g      1   vendor/corneltek/codegen/src/CodeGen/Constant.php  38d  X0      3   vendor/corneltek/codegen/src/CodeGen/ClassTrait.php;  38d;  W>      9   vendor/corneltek/codegen/src/CodeGen/VariableDeflator.php  38d  @      3   vendor/corneltek/codegen/src/CodeGen/ClassConst.php  38d  :$      ;   vendor/corneltek/codegen/src/CodeGen/Expr/NewObjectExpr.phpJ   38dJ    Ϲ      @   vendor/corneltek/codegen/src/CodeGen/Expr/SelfMethodCallExpr.phpW   38dW   b      <   vendor/corneltek/codegen/src/CodeGen/Expr/ObjectProperty.phpc  38dc  E;6      <   vendor/corneltek/codegen/src/CodeGen/Expr/SelfMethodCall.php   38d   O      8   vendor/corneltek/codegen/src/CodeGen/Expr/MethodCall.php  38d  WNP      8   vendor/corneltek/codegen/src/CodeGen/Expr/AssignExpr.php  38d  mK      6   vendor/corneltek/codegen/src/CodeGen/Expr/CallExpr.phpq  38dq  u[      >   vendor/corneltek/codegen/src/CodeGen/Expr/StaticMethodCall.phpP  38dP  ̓      <   vendor/corneltek/codegen/src/CodeGen/Expr/MethodCallExpr.phpQ   38dQ   g      :   vendor/corneltek/codegen/src/CodeGen/Expr/FunctionCall.php  38d  0      7   vendor/corneltek/codegen/src/CodeGen/Expr/NewObject.php  38d  b      1   vendor/corneltek/codegen/src/CodeGen/Indenter.php6  38d6  ¿"      6   vendor/corneltek/codegen/src/CodeGen/ClassProperty.phpW  38dW  9Ho-      -   vendor/corneltek/codegen/src/CodeGen/Line.php  38d  's;      5   vendor/corneltek/codegen/src/CodeGen/UserFunction.php  38d  W      D   vendor/corneltek/codegen/src/CodeGen/Statement/TryCatchStatement.phpg  38dg  Ww      B   vendor/corneltek/codegen/src/CodeGen/Statement/ElseIfStatement.phpX  38dX  Z      @   vendor/corneltek/codegen/src/CodeGen/Statement/ElseStatement.php  38d  5t      >   vendor/corneltek/codegen/src/CodeGen/Statement/IfStatement.php  38d         C   vendor/corneltek/codegen/src/CodeGen/Statement/IfIssetStatement.php  38d  l      B   vendor/corneltek/codegen/src/CodeGen/Statement/AssignStatement.php   38d   N\P      H   vendor/corneltek/codegen/src/CodeGen/Statement/RequireClassStatement.php   38d   N      H   vendor/corneltek/codegen/src/CodeGen/Statement/FunctionCallStatement.php*  38d*  D      F   vendor/corneltek/codegen/src/CodeGen/Statement/MethodCallStatement.phpG  38dG  9G      G   vendor/corneltek/codegen/src/CodeGen/Statement/RequireOnceStatement.phpf  38df  ot      <   vendor/corneltek/codegen/src/CodeGen/Statement/Statement.phpC  38dC  f      A   vendor/corneltek/codegen/src/CodeGen/Statement/ConstStatement.php  38d  ߡ$      C   vendor/corneltek/codegen/src/CodeGen/Statement/ForEachStatement.php9  38d9  ͭ      B   vendor/corneltek/codegen/src/CodeGen/Statement/IfElseStatement.php0  38d0  ]S      S   vendor/corneltek/codegen/src/CodeGen/Statement/RequireComposerAutoloadStatement.phpK  38dK  gΗ#      ?   vendor/corneltek/codegen/src/CodeGen/Statement/UseStatement.php  38d        B   vendor/corneltek/codegen/src/CodeGen/Statement/DefineStatement.phpn  38dn  Q      G   vendor/corneltek/codegen/src/CodeGen/Statement/ConditionalStatement.phpf  38df  5ô      C   vendor/corneltek/codegen/src/CodeGen/Statement/RequireStatement.php  38d  .x      @   vendor/corneltek/codegen/src/CodeGen/Testing/CodeGenTestCase.php  38d  &
      O   vendor/corneltek/codegen/src/CodeGen/Exception/InvalidArgumentTypeException.php  38d  V꛽      .   vendor/corneltek/codegen/src/CodeGen/Utils.php  38d  @      0   vendor/corneltek/codegen/src/CodeGen/Comment.phpo  38do  j      '   vendor/corneltek/codegen/phprelease.iniq   38dq   Jd      %   vendor/corneltek/getoptionkit/LICENSE2  38d2  ]&y      .   vendor/corneltek/getoptionkit/CONTRIBUTORS.txt  38d        .   vendor/corneltek/getoptionkit/src/Argument.php  38d  O5      2   vendor/corneltek/getoptionkit/src/OptionParser.php  38d        2   vendor/corneltek/getoptionkit/src/OptionResult.phpD	  38dD	  g4k      <   vendor/corneltek/getoptionkit/src/ContinuousOptionParser.phpe  38de  %      H   vendor/corneltek/getoptionkit/src/OptionPrinter/ConsoleOptionPrinter.php!  38d!  oukش      A   vendor/corneltek/getoptionkit/src/OptionPrinter/OptionPrinter.php   38d   SG      9   vendor/corneltek/getoptionkit/src/ValueType/RegexType.phpl  38dl  3%      8   vendor/corneltek/getoptionkit/src/ValueType/Ipv6Type.php   38d   dXд      7   vendor/corneltek/getoptionkit/src/ValueType/UrlType.php   38d   *ar      <   vendor/corneltek/getoptionkit/src/ValueType/DateTimeType.phpo  38do  DT      ;   vendor/corneltek/getoptionkit/src/ValueType/BooleanType.php  38d        8   vendor/corneltek/getoptionkit/src/ValueType/Ipv4Type.php   38d   n`      8   vendor/corneltek/getoptionkit/src/ValueType/DateType.php  38d  |ޟ      8   vendor/corneltek/getoptionkit/src/ValueType/PathType.php   38d   o`|      8   vendor/corneltek/getoptionkit/src/ValueType/BoolType.phpT   38dT   A<      7   vendor/corneltek/getoptionkit/src/ValueType/DirType.php   38d   İ-      8   vendor/corneltek/getoptionkit/src/ValueType/BaseType.php  38d  _Hc      9   vendor/corneltek/getoptionkit/src/ValueType/EmailType.php   38d   Jj      6   vendor/corneltek/getoptionkit/src/ValueType/IpType.php  38d  k      :   vendor/corneltek/getoptionkit/src/ValueType/NumberType.php   38d   r      8   vendor/corneltek/getoptionkit/src/ValueType/FileType.php   38d   >}      :   vendor/corneltek/getoptionkit/src/ValueType/StringType.php   38d   K{1;      ,   vendor/corneltek/getoptionkit/src/Option.phpm  38dm  k      6   vendor/corneltek/getoptionkit/src/OptionCollection.php  38d  q      E   vendor/corneltek/getoptionkit/src/Exception/RequireValueException.phpu   38du   iִ      K   vendor/corneltek/getoptionkit/src/Exception/InvalidOptionValueException.php{   38d{   ʹ      C   vendor/corneltek/getoptionkit/src/Exception/NonNumericException.phps   38ds         F   vendor/corneltek/getoptionkit/src/Exception/InvalidOptionException.phpv   38dv         G   vendor/corneltek/getoptionkit/src/Exception/OptionConflictException.phpw   38dw   
(G      (   vendor/corneltek/getoptionkit/phpdox.xmlh  38dh  w      ,   vendor/corneltek/getoptionkit/phprelease.inip   38dp   !      )   vendor/corneltek/getoptionkit/package.ini  38d   D      '   vendor/corneltek/class-template/LICENSEJ  38dJ  	BМ      G   vendor/corneltek/class-template/src/ClassTemplate/TemplateClassFile.phpy  38dy  *      B   vendor/corneltek/class-template/src/ClassTemplate/TemplateView.php  38d  9c      J   vendor/corneltek/class-template/src/ClassTemplate/Templates/Class.php.twigh  38dh  W      ?   vendor/corneltek/class-template/src/ClassTemplate/ClassFile.php2  38d2  ˹      D   vendor/corneltek/class-template/src/ClassTemplate/ClassInjection.php  38d  Mu      :   vendor/corneltek/class-template/src/ClassTemplate/File.phpX  38dX  o      .   vendor/corneltek/class-template/phprelease.iniq   38dq   Jd      .   vendor/corneltek/pearx/src/PEARX/Installer.php  38d  K      -   vendor/corneltek/pearx/src/PEARX/Category.php
  38d
  ˴      6   vendor/corneltek/pearx/src/PEARX/PackageCollection.phpO  38dO  S      )   vendor/corneltek/pearx/src/PEARX/Core.php  38d  4      ,   vendor/corneltek/pearx/src/PEARX/Channel.php  38d  YS      ,   vendor/corneltek/pearx/src/PEARX/Package.php  38d  (      2   vendor/corneltek/pearx/src/PEARX/ChannelParser.php  38d  1Wj      6   vendor/corneltek/pearx/src/PEARX/PackageXml/Parser.php  38d  +a      ;   vendor/corneltek/pearx/src/PEARX/PackageXml/ContentFile.php
  38d
  nh´      9   vendor/corneltek/pearx/src/PEARX/PackageXml/Generator.php  38d  KC      *   vendor/corneltek/pearx/src/PEARX/Utils.php  38d  O	*      !   vendor/corneltek/pearx/phpdox.xmla  38da  ~!      %   vendor/corneltek/pearx/phprelease.inip   38dp   !      "   vendor/corneltek/pearx/package.xml  38d        "   vendor/corneltek/pearx/package.ini.  38d.  4e         vendor/corneltek/pearx/Doxyfilea" 38da" xK=         vendor/autoload.php  38d  F0         shell/phpbrew.fish  38d  g9         shell/bashrcC  38dC  }'         .box/vendor/composer/LICENSE.  38d.         &   .box/vendor/composer/autoload_psr4.php6  38d6   0Ӵ      B   .box/vendor/composer/semver/src/Constraint/ConstraintInterface.php  38d  wQ      9   .box/vendor/composer/semver/src/Constraint/Constraint.php'&  38d'&  `      >   .box/vendor/composer/semver/src/Constraint/MultiConstraint.php~  38d~  5[e      *   .box/vendor/composer/semver/src/Semver.php  38d  ׯ      1   .box/vendor/composer/semver/src/VersionParser.php9  38d9  Wz      .   .box/vendor/composer/semver/src/Comparator.phpu  38du  	74      (   .box/vendor/composer/autoload_static.phpK  38dK  ?      ,   .box/vendor/composer/autoload_namespaces.php   38d   t!״      $   .box/vendor/composer/ClassLoader.php>  38d>  5Ky      *   .box/vendor/composer/autoload_classmap.php,
  38d,
  ӽǴ      &   .box/vendor/composer/autoload_real.php   38d   yi\         .box/vendor/autoload.php   38d   s         .box/bin/check-requirements.php  38d  ^ʨ         .box/src/Printer.php  38d  )8AV         .box/src/Terminal.php  38d  %V      !   .box/src/IsExtensionFulfilled.phpv  38dv  '0Ҵ         .box/src/IsFulfilled.phpv   38dv   %*H         .box/src/IO.php   38d   [l%      "   .box/src/IsPhpVersionFulfilled.php  38d  !83         .box/src/Checker.php  38d  )W>      "   .box/src/RequirementCollection.php  38d  Wb?         .box/src/Requirement.phpm  38dm  B         .box/.requirements.php&  38d&  ϣ,         bin/phpbrew  38d  ϴ         src/PhpBrew/PatchKit/Patch.php  38d  Q      "   src/PhpBrew/PatchKit/PatchRule.php   38d   %      &   src/PhpBrew/PatchKit/DiffPatchRule.php|  38d|  {.      (   src/PhpBrew/PatchKit/RegExpPatchRule.php	  38d	  &4-         src/PhpBrew/Build.php  38d  }۴      #   src/PhpBrew/ConfigureParameters.php  38d  [Eg         src/PhpBrew/CommandBuilder.phpU  38dU           src/PhpBrew/Buildable.php   38d   RL      +   src/PhpBrew/BuildSettings/BuildSettings.php  38d  f/         src/PhpBrew/PrefixFinder.php\   38d\   X         src/PhpBrew/Config.php)  38d)  !      2   src/PhpBrew/Distribution/DistributionUrlPolicy.php  38d           src/PhpBrew/ReleaseList.php  38d  L         src/PhpBrew/Tasks/TestTask.phpq  38dq   h      !   src/PhpBrew/Tasks/ExtractTask.php  38d  +v      "   src/PhpBrew/Tasks/DownloadTask.php  38d  w      (   src/PhpBrew/Tasks/AfterConfigureTask.php  38d  񟨴         src/PhpBrew/Tasks/BuildTask.phpp  38dp        *   src/PhpBrew/Tasks/PrepareDirectoryTask.php  38d  8h#         src/PhpBrew/Tasks/DSymTask.php  38d  F      *   src/PhpBrew/Tasks/FetchReleaseListTask.php:  38d:  I      )   src/PhpBrew/Tasks/BeforeConfigureTask.php  38d  '         src/PhpBrew/Tasks/MakeTask.phpl  38dl  ~      #   src/PhpBrew/Tasks/ConfigureTask.php  38d  4=´      !   src/PhpBrew/Tasks/InstallTask.php  38d  rG      #   src/PhpBrew/Tasks/BuildConfTask.phpX  38dX  7N      $   src/PhpBrew/Tasks/Apxs2CheckTask.php  38d           src/PhpBrew/Tasks/BaseTask.php  38d  ҫ      %   src/PhpBrew/Extension/M4Extension.phpM   38dM   }U<b      '   src/PhpBrew/Extension/PeclExtension.php  38d  㖂ȴ      #   src/PhpBrew/Extension/Extension.php  38d  L      4   src/PhpBrew/Extension/Provider/BitbucketProvider.php{
  38d{
        +   src/PhpBrew/Extension/Provider/Provider.php  38d  U      1   src/PhpBrew/Extension/Provider/GithubProvider.php
  38d
  &      /   src/PhpBrew/Extension/Provider/PeclProvider.php  38d        6   src/PhpBrew/Extension/Provider/RepositoryDslParser.php$  38d$  ]ì      *   src/PhpBrew/Extension/ExtensionManager.php  38d  i(      ,   src/PhpBrew/Extension/ExtensionInstaller.phpf  38df  52      -   src/PhpBrew/Extension/ExtensionDownloader.php	  38d	  R      )   src/PhpBrew/Extension/ConfigureOption.php  38d  y{      *   src/PhpBrew/Extension/ExtensionFactory.php]  38d]  	      3   src/PhpBrew/PrefixFinder/ExecutablePrefixFinder.phpo  38do  <mxƴ      0   src/PhpBrew/PrefixFinder/IncludePrefixFinder.php:  38d:  r      -   src/PhpBrew/PrefixFinder/BrewPrefixFinder.phpw  38dw        2   src/PhpBrew/PrefixFinder/PkgConfigPrefixFinder.phpL  38dL  p      ,   src/PhpBrew/PrefixFinder/LibPrefixFinder.php2  38d2  HŴ      /   src/PhpBrew/PrefixFinder/UserProvidedPrefix.php  38d  rCش         src/PhpBrew/VariantBuilder.phpR  38dR  D      -   src/PhpBrew/InvalidVariantSyntaxException.phpe   38de   h       $   src/PhpBrew/Command/CtagsCommand.php=  38d=  PƱ      "   src/PhpBrew/Command/OffCommand.php   38d   xI      $   src/PhpBrew/Command/KnownCommand.php  38d  O      &   src/PhpBrew/Command/VirtualCommand.phpV  38dV  e      5   src/PhpBrew/Command/ExtensionCommand/KnownCommand.php[  38d[  ERw      4   src/PhpBrew/Command/ExtensionCommand/ShowCommand.php	  38d	  QYj      6   src/PhpBrew/Command/ExtensionCommand/ConfigCommand.php7  38d7  
_      5   src/PhpBrew/Command/ExtensionCommand/CleanCommand.php  38d  Z      7   src/PhpBrew/Command/ExtensionCommand/InstallCommand.phpu  38du  <      7   src/PhpBrew/Command/ExtensionCommand/DisableCommand.phpk  38dk  ƅ      6   src/PhpBrew/Command/ExtensionCommand/EnableCommand.phpo  38do  &:      4   src/PhpBrew/Command/ExtensionCommand/BaseCommand.phpW  38dW  e:3{      &   src/PhpBrew/Command/ListIniCommand.php-  38d-        "   src/PhpBrew/Command/UseCommand.phpD  38dD  E}      %   src/PhpBrew/Command/ConfigCommand.phpp  38dp  S      $   src/PhpBrew/Command/PurgeCommand.php  38d  I>(	      '   src/PhpBrew/Command/MigratedCommand.phpb  38db  ð      %   src/PhpBrew/Command/UpdateCommand.php@  38d@  ES      (   src/PhpBrew/Command/SwitchOffCommand.php   38d   v(      #   src/PhpBrew/Command/InfoCommand.phpT  38dT  -      #   src/PhpBrew/Command/HelpCommand.php  38d  y      !   src/PhpBrew/Command/CdCommand.phpW  38dW        $   src/PhpBrew/Command/CleanCommand.php  38d  u      "   src/PhpBrew/Command/EnvCommand.php  38d  l      #   src/PhpBrew/Command/InitCommand.phpk  38dk  sh      1   src/PhpBrew/Command/FpmCommand/RestartCommand.php   38d   Ea      /   src/PhpBrew/Command/FpmCommand/SetupCommand.php'  38d'  ?      .   src/PhpBrew/Command/FpmCommand/StopCommand.php   38d   b      /   src/PhpBrew/Command/FpmCommand/StartCommand.php   38d   	RP      &   src/PhpBrew/Command/InstallCommand.phpuM  38duM  zL'Ѵ      (   src/PhpBrew/Command/ExtensionCommand.php  38d        #   src/PhpBrew/Command/PathCommand.php  38d  х      '   src/PhpBrew/Command/VariantsCommand.php%  38d%  rl6      '   src/PhpBrew/Command/DownloadCommand.phpw  38dw  Lh      %   src/PhpBrew/Command/SystemCommand.php  38d        (   src/PhpBrew/Command/SystemOffCommand.php   38d   퀴      #   src/PhpBrew/Command/EachCommand.php   38d         #   src/PhpBrew/Command/ListCommand.php  38d  p      )   src/PhpBrew/Command/SelfUpdateCommand.php  38d  :K      %   src/PhpBrew/Command/SwitchCommand.php?  38d?  =P      %   src/PhpBrew/Command/RemoveCommand.php  38d  Ӵ      "   src/PhpBrew/Command/FpmCommand.php  38d        .   src/PhpBrew/Downloader/PhpStreamDownloader.phpM  38dM  w      )   src/PhpBrew/Downloader/BaseDownloader.php  38d        *   src/PhpBrew/Downloader/DownloadFactory.phpo	  38do	  }.      0   src/PhpBrew/Downloader/CurlCommandDownloader.php  38d  =#      0   src/PhpBrew/Downloader/WgetCommandDownloader.php  38d  s&4      ,   src/PhpBrew/Downloader/PhpCurlDownloader.php  38d  q         src/PhpBrew/ExtensionList.php#  38d#  ׅ          src/PhpBrew/VersionDslParser.phpb  38db  Gb      *   src/PhpBrew/Patches/IntlWith64bitPatch.php  38d  =7      %   src/PhpBrew/Patches/FreeTypePatch.php  38d  Mɶ      '   src/PhpBrew/Patches/OpenSSLDSOPatch.php  38d  Pl      .   src/PhpBrew/Patches/Apache2ModuleNamePatch.php  38d  d       /   src/PhpBrew/Patches/PHP56WithOpenSSL11Patch.phpU  38dU  ?      %   src/PhpBrew/Patches/ReadlinePatch.php  38d  )"         src/PhpBrew/BuildFinder.php  38d  oW      '   src/PhpBrew/Testing/CommandTestCase.php  38d  Od      "   src/PhpBrew/Testing/VCRAdapter.php  38d        %   src/PhpBrew/Testing/PatchTestCase.php  38d  .      0   src/PhpBrew/Exception/SystemCommandException.php  38d   /      '   src/PhpBrew/Exception/OopsException.php   38d   dȴ         src/PhpBrew/VariantParser.php  38d  B         src/PhpBrew/Console.php[  38d[  x	         src/PhpBrew/Utils.php  38d  <:      <?php










namespace Symfony\Component\ClassLoader;








class Psr4ClassLoader
{
private $prefixes = array();





public function addPrefix($prefix, $baseDir)
{
$prefix = trim($prefix, '\\').'\\';
$baseDir = rtrim($baseDir, \DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR;
$this->prefixes[] = array($prefix, $baseDir);
}






public function findFile($class)
{
$class = ltrim($class, '\\');

foreach ($this->prefixes as $current) {
list($currentPrefix, $currentBaseDir) = $current;
if (0 === strpos($class, $currentPrefix)) {
$classWithoutPrefix = substr($class, \strlen($currentPrefix));
$file = $currentBaseDir.str_replace('\\', \DIRECTORY_SEPARATOR, $classWithoutPrefix).'.php';
if (file_exists($file)) {
return $file;
}
}
}
}






public function loadClass($class)
{
$file = $this->findFile($class);
if (null !== $file) {
require $file;

return true;
}

return false;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
}
Copyright (c) 2004-2018 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php










namespace Symfony\Component\ClassLoader;

if (!\defined('SYMFONY_TRAIT')) {
if (\PHP_VERSION_ID >= 50400) {
\define('SYMFONY_TRAIT', T_TRAIT);
} else {
\define('SYMFONY_TRAIT', 0);
}
}






class ClassMapGenerator
{






public static function dump($dirs, $file)
{
$dirs = (array) $dirs;
$maps = array();

foreach ($dirs as $dir) {
$maps = array_merge($maps, static::createMap($dir));
}

file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true)));
}








public static function createMap($dir)
{
if (\is_string($dir)) {
$dir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir));
}

$map = array();

foreach ($dir as $file) {
if (!$file->isFile()) {
continue;
}

$path = $file->getRealPath() ?: $file->getPathname();

if ('php' !== pathinfo($path, PATHINFO_EXTENSION)) {
continue;
}

$classes = self::findClasses($path);

if (\PHP_VERSION_ID >= 70000) {

gc_mem_caches();
}

foreach ($classes as $class) {
$map[$class] = $path;
}
}

return $map;
}








private static function findClasses($path)
{
$contents = file_get_contents($path);
$tokens = token_get_all($contents);

$classes = array();

$namespace = '';
for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];

if (!isset($token[1])) {
continue;
}

$class = '';

switch ($token[0]) {
case T_NAMESPACE:
$namespace = '';

while (isset($tokens[++$i][1])) {
if (\in_array($tokens[$i][0], array(T_STRING, T_NS_SEPARATOR))) {
$namespace .= $tokens[$i][1];
}
}
$namespace .= '\\';
break;
case T_CLASS:
case T_INTERFACE:
case SYMFONY_TRAIT:

$isClassConstant = false;
for ($j = $i - 1; $j > 0; --$j) {
if (!isset($tokens[$j][1])) {
break;
}

if (T_DOUBLE_COLON === $tokens[$j][0]) {
$isClassConstant = true;
break;
} elseif (!\in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
break;
}
}

if ($isClassConstant) {
break;
}


while (isset($tokens[++$i][1])) {
$t = $tokens[$i];
if (T_STRING === $t[0]) {
$class .= $t[1];
} elseif ('' !== $class && T_WHITESPACE === $t[0]) {
break;
}
}

$classes[] = ltrim($namespace.$class, '\\');
break;
default:
break;
}
}

return $classes;
}
}
<?php










namespace Symfony\Component\ClassLoader;

@trigger_error('The '.__NAMESPACE__.'\DebugUniversalClassLoader class is deprecated since Symfony 2.4 and will be removed in 3.0. Use the Symfony\Component\Debug\DebugClassLoader class instead.', E_USER_DEPRECATED);









class DebugUniversalClassLoader extends UniversalClassLoader
{



public static function enable()
{
if (!\is_array($functions = spl_autoload_functions())) {
return;
}

foreach ($functions as $function) {
spl_autoload_unregister($function);
}

foreach ($functions as $function) {
if (\is_array($function) && $function[0] instanceof UniversalClassLoader) {
$loader = new static();
$loader->registerNamespaceFallbacks($function[0]->getNamespaceFallbacks());
$loader->registerPrefixFallbacks($function[0]->getPrefixFallbacks());
$loader->registerNamespaces($function[0]->getNamespaces());
$loader->registerPrefixes($function[0]->getPrefixes());
$loader->useIncludePath($function[0]->getUseIncludePath());

$function[0] = $loader;
}

spl_autoload_register($function);
}
}




public function loadClass($class)
{
if ($file = $this->findFile($class)) {
require $file;

if (!class_exists($class, false) && !interface_exists($class, false) && (!\function_exists('trait_exists') || !trait_exists($class, false))) {
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));
}
}
}
}
<?php










namespace Symfony\Component\ClassLoader;

@trigger_error('The '.__NAMESPACE__.'\UniversalClassLoader class is deprecated since Symfony 2.7 and will be removed in 3.0. Use the Symfony\Component\ClassLoader\ClassLoader class instead.', E_USER_DEPRECATED);

















































class UniversalClassLoader
{
private $namespaces = array();
private $prefixes = array();
private $namespaceFallbacks = array();
private $prefixFallbacks = array();
private $useIncludePath = false;







public function useIncludePath($useIncludePath)
{
$this->useIncludePath = (bool) $useIncludePath;
}







public function getUseIncludePath()
{
return $this->useIncludePath;
}






public function getNamespaces()
{
return $this->namespaces;
}






public function getPrefixes()
{
return $this->prefixes;
}






public function getNamespaceFallbacks()
{
return $this->namespaceFallbacks;
}






public function getPrefixFallbacks()
{
return $this->prefixFallbacks;
}






public function registerNamespaceFallbacks(array $dirs)
{
$this->namespaceFallbacks = $dirs;
}






public function registerNamespaceFallback($dir)
{
$this->namespaceFallbacks[] = $dir;
}






public function registerPrefixFallbacks(array $dirs)
{
$this->prefixFallbacks = $dirs;
}






public function registerPrefixFallback($dir)
{
$this->prefixFallbacks[] = $dir;
}






public function registerNamespaces(array $namespaces)
{
foreach ($namespaces as $namespace => $locations) {
$this->namespaces[$namespace] = (array) $locations;
}
}







public function registerNamespace($namespace, $paths)
{
$this->namespaces[$namespace] = (array) $paths;
}






public function registerPrefixes(array $classes)
{
foreach ($classes as $prefix => $locations) {
$this->prefixes[$prefix] = (array) $locations;
}
}







public function registerPrefix($prefix, $paths)
{
$this->prefixes[$prefix] = (array) $paths;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}








public function loadClass($class)
{
if ($file = $this->findFile($class)) {
require $file;

return true;
}
}








public function findFile($class)
{
if (false !== $pos = strrpos($class, '\\')) {

$namespace = substr($class, 0, $pos);
$className = substr($class, $pos + 1);
$normalizedClass = str_replace('\\', \DIRECTORY_SEPARATOR, $namespace).\DIRECTORY_SEPARATOR.str_replace('_', \DIRECTORY_SEPARATOR, $className).'.php';
foreach ($this->namespaces as $ns => $dirs) {
if (0 !== strpos($namespace, $ns)) {
continue;
}

foreach ($dirs as $dir) {
$file = $dir.\DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) {
return $file;
}
}
}

foreach ($this->namespaceFallbacks as $dir) {
$file = $dir.\DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) {
return $file;
}
}
} else {

$normalizedClass = str_replace('_', \DIRECTORY_SEPARATOR, $class).'.php';
foreach ($this->prefixes as $prefix => $dirs) {
if (0 !== strpos($class, $prefix)) {
continue;
}

foreach ($dirs as $dir) {
$file = $dir.\DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) {
return $file;
}
}
}

foreach ($this->prefixFallbacks as $dir) {
$file = $dir.\DIRECTORY_SEPARATOR.$normalizedClass;
if (is_file($file)) {
return $file;
}
}
}

if ($this->useIncludePath && $file = stream_resolve_include_path($normalizedClass)) {
return $file;
}
}
}
<?php










namespace Symfony\Component\ClassLoader;






class ClassCollectionLoader
{
private static $loaded;
private static $seen;
private static $useTokenizer = true;













public static function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php')
{

if (isset(self::$loaded[$name])) {
return;
}

self::$loaded[$name] = true;

if ($adaptive) {
$declared = array_merge(get_declared_classes(), get_declared_interfaces());
if (\function_exists('get_declared_traits')) {
$declared = array_merge($declared, get_declared_traits());
}


$classes = array_diff($classes, $declared);


$name .= '-'.substr(hash('sha256', implode('|', $classes)), 0, 5);
}

$classes = array_unique($classes);


if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
throw new \RuntimeException(sprintf('Class Collection Loader was not able to create directory "%s"', $cacheDir));
}
$cacheDir = rtrim(realpath($cacheDir) ?: $cacheDir, '/'.\DIRECTORY_SEPARATOR);
$cache = $cacheDir.'/'.$name.$extension;


$reload = false;
if ($autoReload) {
$metadata = $cache.'.meta';
if (!is_file($metadata) || !is_file($cache)) {
$reload = true;
} else {
$time = filemtime($cache);
$meta = unserialize(file_get_contents($metadata));

sort($meta[1]);
sort($classes);

if ($meta[1] != $classes) {
$reload = true;
} else {
foreach ($meta[0] as $resource) {
if (!is_file($resource) || filemtime($resource) > $time) {
$reload = true;

break;
}
}
}
}
}

if (!$reload && file_exists($cache)) {
require_once $cache;

return;
}
if (!$adaptive) {
$declared = array_merge(get_declared_classes(), get_declared_interfaces());
if (\function_exists('get_declared_traits')) {
$declared = array_merge($declared, get_declared_traits());
}
}

$spacesRegex = '(?:\s*+(?:(?:\#|//)[^\n]*+\n|/\*(?:(?<!\*/).)++)?+)*+';
$dontInlineRegex = <<<REGEX
            '(?:
               ^<\?php\s.declare.\(.strict_types.=.1.\).;
               | \b__halt_compiler.\(.\)
               | \b__(?:DIR|FILE)__\b
            )'isx
REGEX;
$dontInlineRegex = str_replace('.', $spacesRegex, $dontInlineRegex);

$cacheDir = explode('/', str_replace(\DIRECTORY_SEPARATOR, '/', $cacheDir));
$files = array();
$content = '';
foreach (self::getOrderedClasses($classes) as $class) {
if (\in_array($class->getName(), $declared)) {
continue;
}

$files[] = $file = $class->getFileName();
$c = file_get_contents($file);

if (preg_match($dontInlineRegex, $c)) {
$file = explode('/', str_replace(\DIRECTORY_SEPARATOR, '/', $file));

for ($i = 0; isset($file[$i], $cacheDir[$i]); ++$i) {
if ($file[$i] !== $cacheDir[$i]) {
break;
}
}
if (1 >= $i) {
$file = var_export(implode('/', $file), true);
} else {
$file = \array_slice($file, $i);
$file = str_repeat('../', \count($cacheDir) - $i).implode('/', $file);
$file = '__DIR__.'.var_export('/'.$file, true);
}

$c = "\nnamespace {require $file;}";
} else {
$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', $c);


if (!$class->inNamespace()) {
$c = "\nnamespace\n{\n".$c."\n}\n";
}

$c = self::fixNamespaceDeclarations('<?php '.$c);
$c = preg_replace('/^\s*<\?php/', '', $c);
}

$content .= $c;
}
self::writeCacheFile($cache, '<?php '.$content);

if ($autoReload) {

self::writeCacheFile($metadata, serialize(array($files, $classes)));
}
}








public static function fixNamespaceDeclarations($source)
{
if (!\function_exists('token_get_all') || !self::$useTokenizer) {
if (preg_match('/(^|\s)namespace(.*?)\s*;/', $source)) {
$source = preg_replace('/(^|\s)namespace(.*?)\s*;/', "$1namespace$2\n{", $source)."}\n";
}

return $source;
}

$rawChunk = '';
$output = '';
$inNamespace = false;
$tokens = token_get_all($source);

for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];
if (!isset($token[1]) || 'b"' === $token) {
$rawChunk .= $token;
} elseif (\in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {

continue;
} elseif (T_NAMESPACE === $token[0]) {
if ($inNamespace) {
$rawChunk .= "}\n";
}
$rawChunk .= $token[1];


while (isset($tokens[++$i][1]) && \in_array($tokens[$i][0], array(T_WHITESPACE, T_NS_SEPARATOR, T_STRING))) {
$rawChunk .= $tokens[$i][1];
}
if ('{' === $tokens[$i]) {
$inNamespace = false;
--$i;
} else {
$rawChunk = rtrim($rawChunk)."\n{";
$inNamespace = true;
}
} elseif (T_START_HEREDOC === $token[0]) {
$output .= self::compressCode($rawChunk).$token[1];
do {
$token = $tokens[++$i];
$output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token;
} while (T_END_HEREDOC !== $token[0]);
$output .= "\n";
$rawChunk = '';
} elseif (T_CONSTANT_ENCAPSED_STRING === $token[0]) {
$output .= self::compressCode($rawChunk).$token[1];
$rawChunk = '';
} else {
$rawChunk .= $token[1];
}
}

if ($inNamespace) {
$rawChunk .= "}\n";
}

$output .= self::compressCode($rawChunk);

if (\PHP_VERSION_ID >= 70000) {

unset($tokens, $rawChunk);
gc_mem_caches();
}

return $output;
}




public static function enableTokenizer($bool)
{
self::$useTokenizer = (bool) $bool;
}








private static function compressCode($code)
{
return preg_replace(
array('/^\s+/m', '/\s+$/m', '/([\n\r]+ *[\n\r]+)+/', '/[ \t]+/'),
array('', '', "\n", ' '),
$code
);
}









private static function writeCacheFile($file, $content)
{
$dir = \dirname($file);
if (!is_writable($dir)) {
throw new \RuntimeException(sprintf('Cache directory "%s" is not writable.', $dir));
}

$tmpFile = tempnam($dir, basename($file));

if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
@chmod($file, 0666 & ~umask());

return;
}

throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
}








private static function getOrderedClasses(array $classes)
{
$map = array();
self::$seen = array();
foreach ($classes as $class) {
try {
$reflectionClass = new \ReflectionClass($class);
} catch (\ReflectionException $e) {
throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
}

$map = array_merge($map, self::getClassHierarchy($reflectionClass));
}

return $map;
}

private static function getClassHierarchy(\ReflectionClass $class)
{
if (isset(self::$seen[$class->getName()])) {
return array();
}

self::$seen[$class->getName()] = true;

$classes = array($class);
$parent = $class;
while (($parent = $parent->getParentClass()) && $parent->isUserDefined() && !isset(self::$seen[$parent->getName()])) {
self::$seen[$parent->getName()] = true;

array_unshift($classes, $parent);
}

$traits = array();

if (method_exists('ReflectionClass', 'getTraits')) {
foreach ($classes as $c) {
foreach (self::resolveDependencies(self::computeTraitDeps($c), $c) as $trait) {
if ($trait !== $c) {
$traits[] = $trait;
}
}
}
}

return array_merge(self::getInterfaces($class), $traits, $classes);
}

private static function getInterfaces(\ReflectionClass $class)
{
$classes = array();

foreach ($class->getInterfaces() as $interface) {
$classes = array_merge($classes, self::getInterfaces($interface));
}

if ($class->isUserDefined() && $class->isInterface() && !isset(self::$seen[$class->getName()])) {
self::$seen[$class->getName()] = true;

$classes[] = $class;
}

return $classes;
}

private static function computeTraitDeps(\ReflectionClass $class)
{
$traits = $class->getTraits();
$deps = array($class->getName() => $traits);
while ($trait = array_pop($traits)) {
if ($trait->isUserDefined() && !isset(self::$seen[$trait->getName()])) {
self::$seen[$trait->getName()] = true;
$traitDeps = $trait->getTraits();
$deps[$trait->getName()] = $traitDeps;
$traits = array_merge($traits, $traitDeps);
}
}

return $deps;
}
















private static function resolveDependencies(array $tree, $node, \ArrayObject $resolved = null, \ArrayObject $unresolved = null)
{
if (null === $resolved) {
$resolved = new \ArrayObject();
}
if (null === $unresolved) {
$unresolved = new \ArrayObject();
}
$nodeName = $node->getName();

if (isset($tree[$nodeName])) {
$unresolved[$nodeName] = $node;
foreach ($tree[$nodeName] as $dependency) {
if (!$resolved->offsetExists($dependency->getName())) {
self::resolveDependencies($tree, $dependency, $resolved, $unresolved);
}
}
$resolved[$nodeName] = $node;
unset($unresolved[$nodeName]);
}

return $resolved;
}
}
<?php










namespace Symfony\Component\ClassLoader;

@trigger_error('The '.__NAMESPACE__.'\DebugClassLoader class is deprecated since Symfony 2.4 and will be removed in 3.0. Use the Symfony\Component\Debug\DebugClassLoader class instead.', E_USER_DEPRECATED);














class DebugClassLoader
{
private $classFinder;




public function __construct($classFinder)
{
$this->classFinder = $classFinder;
}






public function getClassLoader()
{
return $this->classFinder;
}




public static function enable()
{
if (!\is_array($functions = spl_autoload_functions())) {
return;
}

foreach ($functions as $function) {
spl_autoload_unregister($function);
}

foreach ($functions as $function) {
if (\is_array($function) && !$function[0] instanceof self && method_exists($function[0], 'findFile')) {
$function = array(new static($function[0]), 'loadClass');
}

spl_autoload_register($function);
}
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}








public function findFile($class)
{
return $this->classFinder->findFile($class) ?: null;
}










public function loadClass($class)
{
if ($file = $this->classFinder->findFile($class)) {
require $file;

if (!class_exists($class, false) && !interface_exists($class, false) && (!\function_exists('trait_exists') || !trait_exists($class, false))) {
if (false !== strpos($class, '/')) {
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));
}

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));
}

return true;
}
}
}
<?php










namespace Symfony\Component\ClassLoader;




































class WinCacheClassLoader
{
private $prefix;






protected $decorated;








public function __construct($prefix, $decorated)
{
if (!\extension_loaded('wincache')) {
throw new \RuntimeException('Unable to use WinCacheClassLoader as WinCache is not enabled.');
}

if (!method_exists($decorated, 'findFile')) {
throw new \InvalidArgumentException('The class finder must implement a "findFile" method.');
}

$this->prefix = $prefix;
$this->decorated = $decorated;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}








public function loadClass($class)
{
if ($file = $this->findFile($class)) {
require $file;

return true;
}
}








public function findFile($class)
{
$file = wincache_ucache_get($this->prefix.$class, $success);

if (!$success) {
wincache_ucache_set($this->prefix.$class, $file = $this->decorated->findFile($class) ?: null, 0);
}

return $file;
}




public function __call($method, $args)
{
return \call_user_func_array(array($this->decorated, $method), $args);
}
}
<?php










namespace Symfony\Component\ClassLoader;

@trigger_error('The '.__NAMESPACE__.'\ApcUniversalClassLoader class is deprecated since Symfony 2.7 and will be removed in 3.0. Use the Symfony\Component\ClassLoader\ApcClassLoader class instead.', E_USER_DEPRECATED);



















































class ApcUniversalClassLoader extends UniversalClassLoader
{
private $prefix;






public function __construct($prefix)
{
if (!\function_exists('apcu_fetch')) {
throw new \RuntimeException('Unable to use ApcUniversalClassLoader as APC is not enabled.');
}

$this->prefix = $prefix;
}








public function findFile($class)
{
$file = apcu_fetch($this->prefix.$class, $success);

if (!$success) {
apcu_store($this->prefix.$class, $file = parent::findFile($class) ?: null);
}

return $file;
}
}
<?php










namespace Symfony\Component\ClassLoader;






class MapClassLoader
{
private $map = array();




public function __construct(array $map)
{
$this->map = $map;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}






public function loadClass($class)
{
if (isset($this->map[$class])) {
require $this->map[$class];
}
}








public function findFile($class)
{
if (isset($this->map[$class])) {
return $this->map[$class];
}
}
}
<?php










namespace Symfony\Component\ClassLoader;



























class ClassLoader
{
private $prefixes = array();
private $fallbackDirs = array();
private $useIncludePath = false;






public function getPrefixes()
{
return $this->prefixes;
}






public function getFallbackDirs()
{
return $this->fallbackDirs;
}






public function addPrefixes(array $prefixes)
{
foreach ($prefixes as $prefix => $path) {
$this->addPrefix($prefix, $path);
}
}







public function addPrefix($prefix, $paths)
{
if (!$prefix) {
foreach ((array) $paths as $path) {
$this->fallbackDirs[] = $path;
}

return;
}
if (isset($this->prefixes[$prefix])) {
if (\is_array($paths)) {
$this->prefixes[$prefix] = array_unique(array_merge(
$this->prefixes[$prefix],
$paths
));
} elseif (!\in_array($paths, $this->prefixes[$prefix])) {
$this->prefixes[$prefix][] = $paths;
}
} else {
$this->prefixes[$prefix] = array_unique((array) $paths);
}
}






public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = (bool) $useIncludePath;
}







public function getUseIncludePath()
{
return $this->useIncludePath;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}








public function loadClass($class)
{
if ($file = $this->findFile($class)) {
require $file;

return true;
}
}








public function findFile($class)
{
if (false !== $pos = strrpos($class, '\\')) {

$classPath = str_replace('\\', \DIRECTORY_SEPARATOR, substr($class, 0, $pos)).\DIRECTORY_SEPARATOR;
$className = substr($class, $pos + 1);
} else {

$classPath = null;
$className = $class;
}

$classPath .= str_replace('_', \DIRECTORY_SEPARATOR, $className).'.php';

foreach ($this->prefixes as $prefix => $dirs) {
if ($class === strstr($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($dir.\DIRECTORY_SEPARATOR.$classPath)) {
return $dir.\DIRECTORY_SEPARATOR.$classPath;
}
}
}
}

foreach ($this->fallbackDirs as $dir) {
if (file_exists($dir.\DIRECTORY_SEPARATOR.$classPath)) {
return $dir.\DIRECTORY_SEPARATOR.$classPath;
}
}

if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) {
return $file;
}
}
}
<?php










namespace Symfony\Component\ClassLoader;




































class XcacheClassLoader
{
private $prefix;
private $decorated;








public function __construct($prefix, $decorated)
{
if (!\extension_loaded('xcache')) {
throw new \RuntimeException('Unable to use XcacheClassLoader as XCache is not enabled.');
}

if (!method_exists($decorated, 'findFile')) {
throw new \InvalidArgumentException('The class finder must implement a "findFile" method.');
}

$this->prefix = $prefix;
$this->decorated = $decorated;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}








public function loadClass($class)
{
if ($file = $this->findFile($class)) {
require $file;

return true;
}
}








public function findFile($class)
{
if (xcache_isset($this->prefix.$class)) {
$file = xcache_get($this->prefix.$class);
} else {
$file = $this->decorated->findFile($class) ?: null;
xcache_set($this->prefix.$class, $file);
}

return $file;
}




public function __call($method, $args)
{
return \call_user_func_array(array($this->decorated, $method), $args);
}
}
<?php










namespace Symfony\Component\ClassLoader;



































class ApcClassLoader
{
private $prefix;






protected $decorated;








public function __construct($prefix, $decorated)
{
if (!\function_exists('apcu_fetch')) {
throw new \RuntimeException('Unable to use ApcClassLoader as APC is not installed.');
}

if (!method_exists($decorated, 'findFile')) {
throw new \InvalidArgumentException('The class finder must implement a "findFile" method.');
}

$this->prefix = $prefix;
$this->decorated = $decorated;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}








public function loadClass($class)
{
if ($file = $this->findFile($class)) {
require $file;

return true;
}
}








public function findFile($class)
{
$file = apcu_fetch($this->prefix.$class, $success);

if (!$success) {
apcu_store($this->prefix.$class, $file = $this->decorated->findFile($class) ?: null);
}

return $file;
}




public function __call($method, $args)
{
return \call_user_func_array(array($this->decorated, $method), $args);
}
}
Copyright (c) 2018-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php










namespace Symfony\Polyfill\Ctype;








final class Ctype
{









public static function ctype_alnum($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text);
}










public static function ctype_alpha($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text);
}










public static function ctype_cntrl($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text);
}










public static function ctype_digit($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text);
}










public static function ctype_graph($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text);
}










public static function ctype_lower($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text);
}










public static function ctype_print($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text);
}










public static function ctype_punct($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text);
}










public static function ctype_space($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text);
}










public static function ctype_upper($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text);
}










public static function ctype_xdigit($text)
{
$text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);

return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text);
}














private static function convert_int_to_char_for_ctype($int, $function)
{
if (!\is_int($int)) {
return $int;
}

if ($int < -128 || $int > 255) {
return (string) $int;
}

if (\PHP_VERSION_ID >= 80100) {
@trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED);
}

if ($int < 0) {
$int += 256;
}

return \chr($int);
}
}
<?php










use Symfony\Polyfill\Ctype as p;

if (!function_exists('ctype_alnum')) {
function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); }
}
if (!function_exists('ctype_alpha')) {
function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); }
}
if (!function_exists('ctype_cntrl')) {
function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); }
}
if (!function_exists('ctype_digit')) {
function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); }
}
if (!function_exists('ctype_graph')) {
function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); }
}
if (!function_exists('ctype_lower')) {
function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); }
}
if (!function_exists('ctype_print')) {
function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); }
}
if (!function_exists('ctype_punct')) {
function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); }
}
if (!function_exists('ctype_space')) {
function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); }
}
if (!function_exists('ctype_upper')) {
function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); }
}
if (!function_exists('ctype_xdigit')) {
function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); }
}
<?php










use Symfony\Polyfill\Ctype as p;

if (\PHP_VERSION_ID >= 80000) {
return require __DIR__.'/bootstrap80.php';
}

if (!function_exists('ctype_alnum')) {
function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); }
}
if (!function_exists('ctype_alpha')) {
function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); }
}
if (!function_exists('ctype_cntrl')) {
function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); }
}
if (!function_exists('ctype_digit')) {
function ctype_digit($text) { return p\Ctype::ctype_digit($text); }
}
if (!function_exists('ctype_graph')) {
function ctype_graph($text) { return p\Ctype::ctype_graph($text); }
}
if (!function_exists('ctype_lower')) {
function ctype_lower($text) { return p\Ctype::ctype_lower($text); }
}
if (!function_exists('ctype_print')) {
function ctype_print($text) { return p\Ctype::ctype_print($text); }
}
if (!function_exists('ctype_punct')) {
function ctype_punct($text) { return p\Ctype::ctype_punct($text); }
}
if (!function_exists('ctype_space')) {
function ctype_space($text) { return p\Ctype::ctype_space($text); }
}
if (!function_exists('ctype_upper')) {
function ctype_upper($text) { return p\Ctype::ctype_upper($text); }
}
if (!function_exists('ctype_xdigit')) {
function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); }
}
Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php










namespace Symfony\Polyfill\Apcu;









final class Apcu
{
public static function apcu_add($key, $var = null, $ttl = 0)
{
if (!\is_array($key)) {
return apc_add($key, $var, $ttl);
}

$errors = [];
foreach ($key as $k => $v) {
if (!apc_add($k, $v, $ttl)) {
$errors[$k] = -1;
}
}

return $errors;
}

public static function apcu_store($key, $var = null, $ttl = 0)
{
if (!\is_array($key)) {
return apc_store($key, $var, $ttl);
}

$errors = [];
foreach ($key as $k => $v) {
if (!apc_store($k, $v, $ttl)) {
$errors[$k] = -1;
}
}

return $errors;
}

public static function apcu_exists($keys)
{
if (!\is_array($keys)) {
return apc_exists($keys);
}

$existing = [];
foreach ($keys as $k) {
if (apc_exists($k)) {
$existing[$k] = true;
}
}

return $existing;
}

public static function apcu_fetch($key, &$success = null)
{
if (!\is_array($key)) {
return apc_fetch($key, $success);
}

$succeeded = true;
$values = [];
foreach ($key as $k) {
$v = apc_fetch($k, $success);
if ($success) {
$values[$k] = $v;
} else {
$succeeded = false;
}
}
$success = $succeeded;

return $values;
}

public static function apcu_delete($key)
{
if (!\is_array($key)) {
return apc_delete($key);
}

$success = true;
foreach ($key as $k) {
$success = apc_delete($k) && $success;
}

return $success;
}
}
<?php










use Symfony\Polyfill\Apcu as p;

if (extension_loaded('Zend Data Cache')) {
if (!function_exists('apcu_add')) {
function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_add($key, $value, (int) $ttl); }
}
if (!function_exists('apcu_delete')) {
function apcu_delete($key): array|bool { return p\Apcu::apcu_delete($key); }
}
if (!function_exists('apcu_exists')) {
function apcu_exists($key): array|bool { return p\Apcu::apcu_exists($key); }
}
if (!function_exists('apcu_fetch')) {
function apcu_fetch($key, &$success = null): mixed { return p\Apcu::apcu_fetch($key, $success); }
}
if (!function_exists('apcu_store')) {
function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_store($key, $value, (int) $ttl); }
}
} else {
if (!function_exists('apcu_add')) {
function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return apc_add($key, $value, (int) $ttl); }
}
if (!function_exists('apcu_delete')) {
function apcu_delete($key): array|bool { return apc_delete($key); }
}
if (!function_exists('apcu_exists')) {
function apcu_exists($key): array|bool { return apc_exists($key); }
}
if (!function_exists('apcu_fetch')) {
function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); }
}
if (!function_exists('apcu_store')) {
function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return apc_store($key, $value, (int) $ttl); }
}
}

if (!function_exists('apcu_cache_info')) {
function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); }
}
if (!function_exists('apcu_cas')) {
function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); }
}
if (!function_exists('apcu_clear_cache')) {
function apcu_clear_cache() { return apc_clear_cache('user'); }
}
if (!function_exists('apcu_dec')) {
function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); }
}
if (!function_exists('apcu_inc')) {
function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); }
}
if (!function_exists('apcu_sma_info')) {
function apcu_sma_info($limited = false) { return apc_sma_info($limited); }
}

if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) {
class APCuIterator extends APCIterator
{
public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE)
{
parent::__construct('user', $search, $format, $chunk_size, $list);
}
}
}
<?php










use Symfony\Polyfill\Apcu as p;

if (!extension_loaded('apc') && !extension_loaded('apcu')) {
return;
}

if (\PHP_VERSION_ID >= 80000) {
return require __DIR__.'/bootstrap80.php';
}

if (extension_loaded('Zend Data Cache')) {
if (!function_exists('apcu_add')) {
function apcu_add($key, $value = null, $ttl = 0) { return p\Apcu::apcu_add($key, $value, $ttl); }
}
if (!function_exists('apcu_delete')) {
function apcu_delete($key) { return p\Apcu::apcu_delete($key); }
}
if (!function_exists('apcu_exists')) {
function apcu_exists($key) { return p\Apcu::apcu_exists($key); }
}
if (!function_exists('apcu_fetch')) {
function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); }
}
if (!function_exists('apcu_store')) {
function apcu_store($key, $value = null, $ttl = 0) { return p\Apcu::apcu_store($key, $value, $ttl); }
}
} else {
if (!function_exists('apcu_add')) {
function apcu_add($key, $value = null, $ttl = 0) { return apc_add($key, $value, $ttl); }
}
if (!function_exists('apcu_delete')) {
function apcu_delete($key) { return apc_delete($key); }
}
if (!function_exists('apcu_exists')) {
function apcu_exists($key) { return apc_exists($key); }
}
if (!function_exists('apcu_fetch')) {
function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); }
}
if (!function_exists('apcu_store')) {
function apcu_store($key, $value = null, $ttl = 0) { return apc_store($key, $value, $ttl); }
}
}

if (!function_exists('apcu_cache_info')) {
function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); }
}
if (!function_exists('apcu_cas')) {
function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); }
}
if (!function_exists('apcu_clear_cache')) {
function apcu_clear_cache() { return apc_clear_cache('user'); }
}
if (!function_exists('apcu_dec')) {
function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); }
}
if (!function_exists('apcu_inc')) {
function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); }
}
if (!function_exists('apcu_sma_info')) {
function apcu_sma_info($limited = false) { return apc_sma_info($limited); }
}

if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) {
class APCuIterator extends APCIterator
{
public function __construct($search = null, $format = \APC_ITER_ALL, $chunk_size = 100, $list = \APC_LIST_ACTIVE)
{
parent::__construct('user', $search, $format, $chunk_size, $list);
}
}
}
Copyright (c) 2020-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php










if (!function_exists('trigger_deprecation')) {










function trigger_deprecation(string $package, string $version, string $message, ...$args): void
{
@trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
}
}
Copyright (c) 2004-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;









class Unescaper
{



public const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)';






public function unescapeSingleQuotedString(string $value): string
{
return str_replace('\'\'', '\'', $value);
}






public function unescapeDoubleQuotedString(string $value): string
{
$callback = function ($match) {
return $this->unescapeCharacter($match[0]);
};


return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
}






private function unescapeCharacter(string $value): string
{
switch ($value[1]) {
case '0':
return "\x0";
case 'a':
return "\x7";
case 'b':
return "\x8";
case 't':
return "\t";
case "\t":
return "\t";
case 'n':
return "\n";
case 'v':
return "\xB";
case 'f':
return "\xC";
case 'r':
return "\r";
case 'e':
return "\x1B";
case ' ':
return ' ';
case '"':
return '"';
case '/':
return '/';
case '\\':
return '\\';
case 'N':

return "\xC2\x85";
case '_':

return "\xC2\xA0";
case 'L':

return "\xE2\x80\xA8";
case 'P':

return "\xE2\x80\xA9";
case 'x':
return self::utf8chr(hexdec(substr($value, 2, 2)));
case 'u':
return self::utf8chr(hexdec(substr($value, 2, 4)));
case 'U':
return self::utf8chr(hexdec(substr($value, 2, 8)));
default:
throw new ParseException(sprintf('Found unknown escape character "%s".', $value));
}
}




private static function utf8chr(int $c): string
{
if (0x80 > $c %= 0x200000) {
return \chr($c);
}
if (0x800 > $c) {
return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F);
}
if (0x10000 > $c) {
return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F);
}

return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F);
}
}
<?php










namespace Symfony\Component\Yaml;









class Escaper
{

public const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\x7f|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";





private const ESCAPEES = ['\\', '\\\\', '\\"', '"',
"\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
"\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
"\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
"\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
"\x7f",
"\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9",
];
private const ESCAPED = ['\\\\', '\\"', '\\\\', '\\"',
'\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a',
'\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f',
'\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17',
'\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f',
'\\x7f',
'\\N', '\\_', '\\L', '\\P',
];






public static function requiresDoubleQuoting(string $value): bool
{
return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
}






public static function escapeWithDoubleQuotes(string $value): string
{
return sprintf('"%s"', str_replace(self::ESCAPEES, self::ESCAPED, $value));
}






public static function requiresSingleQuoting(string $value): bool
{


if (\in_array(strtolower($value), ['null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'])) {
return true;
}



return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` \p{Zs}]/xu', $value);
}






public static function escapeWithSingleQuotes(string $value): string
{
return sprintf("'%s'", str_replace('\'', '\'\'', $value));
}
}
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Tag\TaggedValue;








class Parser
{
public const TAG_PATTERN = '(?P<tag>![\w!.\/:-]+)';
public const BLOCK_SCALAR_HEADER_PATTERN = '(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?';
public const REFERENCE_PATTERN = '#^&(?P<ref>[^ ]++) *+(?P<value>.*)#u';

private $filename;
private $offset = 0;
private $numberOfParsedLines = 0;
private $totalNumberOfLines;
private $lines = [];
private $currentLineNb = -1;
private $currentLine = '';
private $refs = [];
private $skippedLineNumbers = [];
private $locallySkippedLineNumbers = [];
private $refsBeingParsed = [];











public function parseFile(string $filename, int $flags = 0)
{
if (!is_file($filename)) {
throw new ParseException(sprintf('File "%s" does not exist.', $filename));
}

if (!is_readable($filename)) {
throw new ParseException(sprintf('File "%s" cannot be read.', $filename));
}

$this->filename = $filename;

try {
return $this->parse(file_get_contents($filename), $flags);
} finally {
$this->filename = null;
}
}











public function parse(string $value, int $flags = 0)
{
if (false === preg_match('//u', $value)) {
throw new ParseException('The YAML value does not appear to be valid UTF-8.', -1, null, $this->filename);
}

$this->refs = [];

$mbEncoding = null;

if (2  & (int) \ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('UTF-8');
}

try {
$data = $this->doParse($value, $flags);
} finally {
if (null !== $mbEncoding) {
mb_internal_encoding($mbEncoding);
}
$this->refsBeingParsed = [];
$this->offset = 0;
$this->lines = [];
$this->currentLine = '';
$this->numberOfParsedLines = 0;
$this->refs = [];
$this->skippedLineNumbers = [];
$this->locallySkippedLineNumbers = [];
$this->totalNumberOfLines = null;
}

return $data;
}

private function doParse(string $value, int $flags)
{
$this->currentLineNb = -1;
$this->currentLine = '';
$value = $this->cleanup($value);
$this->lines = explode("\n", $value);
$this->numberOfParsedLines = \count($this->lines);
$this->locallySkippedLineNumbers = [];

if (null === $this->totalNumberOfLines) {
$this->totalNumberOfLines = $this->numberOfParsedLines;
}

if (!$this->moveToNextLine()) {
return null;
}

$data = [];
$context = null;
$allowOverwrite = false;

while ($this->isCurrentLineEmpty()) {
if (!$this->moveToNextLine()) {
return null;
}
}


if (null !== ($tag = $this->getLineTag($this->currentLine, $flags, false)) && !$this->moveToNextLine()) {
return new TaggedValue($tag, '');
}

do {
if ($this->isCurrentLineEmpty()) {
continue;
}


if ("\t" === $this->currentLine[0]) {
throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

Inline::initialize($flags, $this->getRealCurrentLineNb(), $this->filename);

$isRef = $mergeNode = false;
if ('-' === $this->currentLine[0] && self::preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+))?$#u', rtrim($this->currentLine), $values)) {
if ($context && 'mapping' == $context) {
throw new ParseException('You cannot define a sequence item when in a mapping.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}
$context = 'sequence';

if (isset($values['value']) && '&' === $values['value'][0] && self::preg_match(self::REFERENCE_PATTERN, $values['value'], $matches)) {
$isRef = $matches['ref'];
$this->refsBeingParsed[] = $isRef;
$values['value'] = $matches['value'];
}

if (isset($values['value'][1]) && '?' === $values['value'][0] && ' ' === $values['value'][1]) {
throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}


if (isset($values['value']) && 0 === strpos(ltrim($values['value'], ' '), '-')) {

$currentLineNumber = $this->getRealCurrentLineNb();

$sequenceIndentation = \strlen($values['leadspaces']) + 1;
$sequenceYaml = substr($this->currentLine, $sequenceIndentation);
$sequenceYaml .= "\n".$this->getNextEmbedBlock($sequenceIndentation, true);

$data[] = $this->parseBlock($currentLineNumber, rtrim($sequenceYaml), $flags);
} elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
$data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true) ?? '', $flags);
} elseif (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags)) {
$data[] = new TaggedValue(
$subTag,
$this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags)
);
} else {
if (
isset($values['leadspaces'])
&& (
'!' === $values['value'][0]
|| self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->trimTag($values['value']), $matches)
)
) {

$block = $values['value'];
if ($this->isNextLineIndented()) {
$block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1);
}

$data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags);
} else {
$data[] = $this->parseValue($values['value'], $flags, $context);
}
}
if ($isRef) {
$this->refs[$isRef] = end($data);
array_pop($this->refsBeingParsed);
}
} elseif (
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(( |\t)++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
&& (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"]))
) {
if ($context && 'sequence' == $context) {
throw new ParseException('You cannot define a mapping item when in a sequence.', $this->currentLineNb + 1, $this->currentLine, $this->filename);
}
$context = 'mapping';

try {
$key = Inline::parseScalar($values['key']);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}

if (!\is_string($key) && !\is_int($key)) {
throw new ParseException((is_numeric($key) ? 'Numeric' : 'Non-string').' keys are not supported. Quote your evaluable mapping keys instead.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}


if (\is_float($key)) {
$key = (string) $key;
}

if ('<<' === $key && (!isset($values['value']) || '&' !== $values['value'][0] || !self::preg_match('#^&(?P<ref>[^ ]+)#u', $values['value'], $refMatches))) {
$mergeNode = true;
$allowOverwrite = true;
if (isset($values['value'][0]) && '*' === $values['value'][0]) {
$refName = substr(rtrim($values['value']), 1);
if (!\array_key_exists($refName, $this->refs)) {
if (false !== $pos = array_search($refName, $this->refsBeingParsed, true)) {
throw new ParseException(sprintf('Circular reference [%s] detected for reference "%s".', implode(', ', array_merge(\array_slice($this->refsBeingParsed, $pos), [$refName])), $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

$refValue = $this->refs[$refName];

if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) {
$refValue = (array) $refValue;
}

if (!\is_array($refValue)) {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

$data += $refValue; 
} else {
if (isset($values['value']) && '' !== $values['value']) {
$value = $values['value'];
} else {
$value = $this->getNextEmbedBlock();
}
$parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags);

if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) {
$parsed = (array) $parsed;
}

if (!\is_array($parsed)) {
throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

if (isset($parsed[0])) {



foreach ($parsed as $parsedItem) {
if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) {
$parsedItem = (array) $parsedItem;
}

if (!\is_array($parsedItem)) {
throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem, $this->filename);
}

$data += $parsedItem; 
}
} else {


$data += $parsed; 
}
}
} elseif ('<<' !== $key && isset($values['value']) && '&' === $values['value'][0] && self::preg_match(self::REFERENCE_PATTERN, $values['value'], $matches)) {
$isRef = $matches['ref'];
$this->refsBeingParsed[] = $isRef;
$values['value'] = $matches['value'];
}

$subTag = null;
if ($mergeNode) {

} elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) {


if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) {


if ($allowOverwrite || !isset($data[$key])) {
if (null !== $subTag) {
$data[$key] = new TaggedValue($subTag, '');
} else {
$data[$key] = null;
}
} else {
throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
} else {

$realCurrentLineNbKey = $this->getRealCurrentLineNb();
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
if ('<<' === $key) {
$this->refs[$refMatches['ref']] = $value;

if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) {
$value = (array) $value;
}

$data += $value;
} elseif ($allowOverwrite || !isset($data[$key])) {


if (null !== $subTag) {
$data[$key] = new TaggedValue($subTag, $value);
} else {
$data[$key] = $value;
}
} else {
throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $realCurrentLineNbKey + 1, $this->currentLine);
}
}
} else {
$value = $this->parseValue(rtrim($values['value']), $flags, $context);


if ($allowOverwrite || !isset($data[$key])) {
$data[$key] = $value;
} else {
throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine);
}
}
if ($isRef) {
$this->refs[$isRef] = $data[$key];
array_pop($this->refsBeingParsed);
}
} elseif ('"' === $this->currentLine[0] || "'" === $this->currentLine[0]) {
if (null !== $context) {
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

try {
return Inline::parse($this->lexInlineQuotedString(), $flags, $this->refs);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}
} elseif ('{' === $this->currentLine[0]) {
if (null !== $context) {
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

try {
$parsedMapping = Inline::parse($this->lexInlineMapping(), $flags, $this->refs);

while ($this->moveToNextLine()) {
if (!$this->isCurrentLineEmpty()) {
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}
}

return $parsedMapping;
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}
} elseif ('[' === $this->currentLine[0]) {
if (null !== $context) {
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

try {
$parsedSequence = Inline::parse($this->lexInlineSequence(), $flags, $this->refs);

while ($this->moveToNextLine()) {
if (!$this->isCurrentLineEmpty()) {
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}
}

return $parsedSequence;
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}
} else {

if ('---' === $this->currentLine) {
throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) {
throw new ParseException('Complex mappings are not supported.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
}


if (\is_string($value) && $this->lines[0] === trim($value)) {
try {
$value = Inline::parse($this->lines[0], $flags, $this->refs);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}

return $value;
}


if (0 === $this->currentLineNb) {
$previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = false;
$value = '';

foreach ($this->lines as $line) {
$trimmedLine = trim($line);
if ('#' === ($trimmedLine[0] ?? '')) {
continue;
}

if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) {
throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

if (false !== strpos($line, ': ')) {
throw new ParseException('Mapping values are not allowed in multi-line blocks.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}

if ('' === $trimmedLine) {
$value .= "\n";
} elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
$value .= ' ';
}

if ('' !== $trimmedLine && '\\' === substr($line, -1)) {
$value .= ltrim(substr($line, 0, -1));
} elseif ('' !== $trimmedLine) {
$value .= $trimmedLine;
}

if ('' === $trimmedLine) {
$previousLineWasNewline = true;
$previousLineWasTerminatedWithBackslash = false;
} elseif ('\\' === substr($line, -1)) {
$previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = true;
} else {
$previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = false;
}
}

try {
return Inline::parse(trim($value));
} catch (ParseException $e) {

}
}

throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}
} while ($this->moveToNextLine());

if (null !== $tag) {
$data = new TaggedValue($tag, $data);
}

if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && 'mapping' === $context && !\is_object($data)) {
$object = new \stdClass();

foreach ($data as $key => $value) {
$object->$key = $value;
}

$data = $object;
}

return empty($data) ? null : $data;
}

private function parseBlock(int $offset, string $yaml, int $flags)
{
$skippedLineNumbers = $this->skippedLineNumbers;

foreach ($this->locallySkippedLineNumbers as $lineNumber) {
if ($lineNumber < $offset) {
continue;
}

$skippedLineNumbers[] = $lineNumber;
}

$parser = new self();
$parser->offset = $offset;
$parser->totalNumberOfLines = $this->totalNumberOfLines;
$parser->skippedLineNumbers = $skippedLineNumbers;
$parser->refs = &$this->refs;
$parser->refsBeingParsed = $this->refsBeingParsed;

return $parser->doParse($yaml, $flags);
}






public function getRealCurrentLineNb(): int
{
$realCurrentLineNumber = $this->currentLineNb + $this->offset;

foreach ($this->skippedLineNumbers as $skippedLineNumber) {
if ($skippedLineNumber > $realCurrentLineNumber) {
break;
}

++$realCurrentLineNumber;
}

return $realCurrentLineNumber;
}




private function getCurrentLineIndentation(): int
{
if (' ' !== ($this->currentLine[0] ?? '')) {
return 0;
}

return \strlen($this->currentLine) - \strlen(ltrim($this->currentLine, ' '));
}









private function getNextEmbedBlock(int $indentation = null, bool $inSequence = false): string
{
$oldLineIndentation = $this->getCurrentLineIndentation();

if (!$this->moveToNextLine()) {
return '';
}

if (null === $indentation) {
$newIndent = null;
$movements = 0;

do {
$EOF = false;


if ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
$EOF = !$this->moveToNextLine();

if (!$EOF) {
++$movements;
}
} else {
$newIndent = $this->getCurrentLineIndentation();
}
} while (!$EOF && null === $newIndent);

for ($i = 0; $i < $movements; ++$i) {
$this->moveToPreviousLine();
}

$unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem();

if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) {
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}
} else {
$newIndent = $indentation;
}

$data = [];

if ($this->getCurrentLineIndentation() >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent ?? 0);
} elseif ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) {
$data[] = $this->currentLine;
} else {
$this->moveToPreviousLine();

return '';
}

if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) {


$this->moveToPreviousLine();

return '';
}

$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
$isItComment = $this->isCurrentLineComment();

while ($this->moveToNextLine()) {
if ($isItComment && !$isItUnindentedCollection) {
$isItUnindentedCollection = $this->isStringUnIndentedCollectionItem();
$isItComment = $this->isCurrentLineComment();
}

$indent = $this->getCurrentLineIndentation();

if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) {
$this->moveToPreviousLine();
break;
}

if ($this->isCurrentLineBlank()) {
$data[] = substr($this->currentLine, $newIndent);
continue;
}

if ($indent >= $newIndent) {
$data[] = substr($this->currentLine, $newIndent);
} elseif ($this->isCurrentLineComment()) {
$data[] = $this->currentLine;
} elseif (0 == $indent) {
$this->moveToPreviousLine();

break;
} else {
throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename);
}
}

return implode("\n", $data);
}

private function hasMoreLines(): bool
{
return (\count($this->lines) - 1) > $this->currentLineNb;
}




private function moveToNextLine(): bool
{
if ($this->currentLineNb >= $this->numberOfParsedLines - 1) {
return false;
}

$this->currentLine = $this->lines[++$this->currentLineNb];

return true;
}




private function moveToPreviousLine(): bool
{
if ($this->currentLineNb < 1) {
return false;
}

$this->currentLine = $this->lines[--$this->currentLineNb];

return true;
}












private function parseValue(string $value, int $flags, string $context)
{
if (0 === strpos($value, '*')) {
if (false !== $pos = strpos($value, '#')) {
$value = substr($value, 1, $pos - 2);
} else {
$value = substr($value, 1);
}

if (!\array_key_exists($value, $this->refs)) {
if (false !== $pos = array_search($value, $this->refsBeingParsed, true)) {
throw new ParseException(sprintf('Circular reference [%s] detected for reference "%s".', implode(', ', array_merge(\array_slice($this->refsBeingParsed, $pos), [$value])), $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename);
}

return $this->refs[$value];
}

if (\in_array($value[0], ['!', '|', '>'], true) && self::preg_match('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) {
$modifiers = $matches['modifiers'] ?? '';

$data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), abs((int) $modifiers));

if ('' !== $matches['tag'] && '!' !== $matches['tag']) {
if ('!!binary' === $matches['tag']) {
return Inline::evaluateBinaryScalar($data);
}

return new TaggedValue(substr($matches['tag'], 1), $data);
}

return $data;
}

try {
if ('' !== $value && '{' === $value[0]) {
$cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value));

return Inline::parse($this->lexInlineMapping($cursor), $flags, $this->refs);
} elseif ('' !== $value && '[' === $value[0]) {
$cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value));

return Inline::parse($this->lexInlineSequence($cursor), $flags, $this->refs);
}

switch ($value[0] ?? '') {
case '"':
case "'":
$cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value));
$parsedValue = Inline::parse($this->lexInlineQuotedString($cursor), $flags, $this->refs);

if (isset($this->currentLine[$cursor]) && preg_replace('/\s*(#.*)?$/A', '', substr($this->currentLine, $cursor))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($this->currentLine, $cursor)));
}

return $parsedValue;
default:
$lines = [];

while ($this->moveToNextLine()) {

if (0 === $this->getCurrentLineIndentation()) {
$this->moveToPreviousLine();

break;
}

$lines[] = trim($this->currentLine);
}

for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) {
if ('' === $lines[$i]) {
$value .= "\n";
$previousLineBlank = true;
} elseif ($previousLineBlank) {
$value .= $lines[$i];
$previousLineBlank = false;
} else {
$value .= ' '.$lines[$i];
$previousLineBlank = false;
}
}

Inline::$parsedLineNumber = $this->getRealCurrentLineNb();

$parsedValue = Inline::parse($value, $flags, $this->refs);

if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) {
throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename);
}

return $parsedValue;
}
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

throw $e;
}
}








private function parseBlockScalar(string $style, string $chomping = '', int $indentation = 0): string
{
$notEOF = $this->moveToNextLine();
if (!$notEOF) {
return '';
}

$isCurrentLineBlank = $this->isCurrentLineBlank();
$blockLines = [];


while ($notEOF && $isCurrentLineBlank) {

if ($notEOF = $this->moveToNextLine()) {
$blockLines[] = '';
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}


if (0 === $indentation) {
$currentLineLength = \strlen($this->currentLine);

for ($i = 0; $i < $currentLineLength && ' ' === $this->currentLine[$i]; ++$i) {
++$indentation;
}
}

if ($indentation > 0) {
$pattern = sprintf('/^ {%d}(.*)$/', $indentation);

while (
$notEOF && (
$isCurrentLineBlank ||
self::preg_match($pattern, $this->currentLine, $matches)
)
) {
if ($isCurrentLineBlank && \strlen($this->currentLine) > $indentation) {
$blockLines[] = substr($this->currentLine, $indentation);
} elseif ($isCurrentLineBlank) {
$blockLines[] = '';
} else {
$blockLines[] = $matches[1];
}


if ($notEOF = $this->moveToNextLine()) {
$isCurrentLineBlank = $this->isCurrentLineBlank();
}
}
} elseif ($notEOF) {
$blockLines[] = '';
}

if ($notEOF) {
$blockLines[] = '';
$this->moveToPreviousLine();
} elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) {
$blockLines[] = '';
}


if ('>' === $style) {
$text = '';
$previousLineIndented = false;
$previousLineBlank = false;

for ($i = 0, $blockLinesCount = \count($blockLines); $i < $blockLinesCount; ++$i) {
if ('' === $blockLines[$i]) {
$text .= "\n";
$previousLineIndented = false;
$previousLineBlank = true;
} elseif (' ' === $blockLines[$i][0]) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = true;
$previousLineBlank = false;
} elseif ($previousLineIndented) {
$text .= "\n".$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} elseif ($previousLineBlank || 0 === $i) {
$text .= $blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
} else {
$text .= ' '.$blockLines[$i];
$previousLineIndented = false;
$previousLineBlank = false;
}
}
} else {
$text = implode("\n", $blockLines);
}


if ('' === $chomping) {
$text = preg_replace('/\n+$/', "\n", $text);
} elseif ('-' === $chomping) {
$text = preg_replace('/\n+$/', '', $text);
}

return $text;
}




private function isNextLineIndented(): bool
{
$currentIndentation = $this->getCurrentLineIndentation();
$movements = 0;

do {
$EOF = !$this->moveToNextLine();

if (!$EOF) {
++$movements;
}
} while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));

if ($EOF) {
return false;
}

$ret = $this->getCurrentLineIndentation() > $currentIndentation;

for ($i = 0; $i < $movements; ++$i) {
$this->moveToPreviousLine();
}

return $ret;
}




private function isCurrentLineEmpty(): bool
{
return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
}




private function isCurrentLineBlank(): bool
{
return '' === $this->currentLine || '' === trim($this->currentLine, ' ');
}




private function isCurrentLineComment(): bool
{

$ltrimmedLine = '' !== $this->currentLine && ' ' === $this->currentLine[0] ? ltrim($this->currentLine, ' ') : $this->currentLine;

return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0];
}

private function isCurrentLineLastLineInDocument(): bool
{
return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1);
}






private function cleanup(string $value): string
{
$value = str_replace(["\r\n", "\r"], "\n", $value);


$count = 0;
$value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count);
$this->offset += $count;


$trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
if (1 === $count) {

$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;
}


$trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
if (1 === $count) {

$this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
$value = $trimmedValue;


$value = preg_replace('#\.\.\.\s*$#', '', $value);
}

return $value;
}




private function isNextLineUnIndentedCollection(): bool
{
$currentIndentation = $this->getCurrentLineIndentation();
$movements = 0;

do {
$EOF = !$this->moveToNextLine();

if (!$EOF) {
++$movements;
}
} while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()));

if ($EOF) {
return false;
}

$ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem();

for ($i = 0; $i < $movements; ++$i) {
$this->moveToPreviousLine();
}

return $ret;
}




private function isStringUnIndentedCollectionItem(): bool
{
return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- ');
}














public static function preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int
{
if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) {
switch (preg_last_error()) {
case \PREG_INTERNAL_ERROR:
$error = 'Internal PCRE error.';
break;
case \PREG_BACKTRACK_LIMIT_ERROR:
$error = 'pcre.backtrack_limit reached.';
break;
case \PREG_RECURSION_LIMIT_ERROR:
$error = 'pcre.recursion_limit reached.';
break;
case \PREG_BAD_UTF8_ERROR:
$error = 'Malformed UTF-8 data.';
break;
case \PREG_BAD_UTF8_OFFSET_ERROR:
$error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
break;
default:
$error = 'Error.';
}

throw new ParseException($error);
}

return $ret;
}







private function trimTag(string $value): string
{
if ('!' === $value[0]) {
return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' ');
}

return $value;
}

private function getLineTag(string $value, int $flags, bool $nextLineCheck = true): ?string
{
if ('' === $value || '!' !== $value[0] || 1 !== self::preg_match('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) {
return null;
}

if ($nextLineCheck && !$this->isNextLineIndented()) {
return null;
}

$tag = substr($matches['tag'], 1);


if ($tag && '!' === $tag[0]) {
throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
}

if (Yaml::PARSE_CUSTOM_TAGS & $flags) {
return $tag;
}

throw new ParseException(sprintf('Tags support is not enabled. You must use the flag "Yaml::PARSE_CUSTOM_TAGS" to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename);
}

private function lexInlineQuotedString(int &$cursor = 0): string
{
$quotation = $this->currentLine[$cursor];
$value = $quotation;
++$cursor;

$previousLineWasNewline = true;
$previousLineWasTerminatedWithBackslash = false;
$lineNumber = 0;

do {
if (++$lineNumber > 1) {
$cursor += strspn($this->currentLine, ' ', $cursor);
}

if ($this->isCurrentLineBlank()) {
$value .= "\n";
} elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) {
$value .= ' ';
}

for (; \strlen($this->currentLine) > $cursor; ++$cursor) {
switch ($this->currentLine[$cursor]) {
case '\\':
if ("'" === $quotation) {
$value .= '\\';
} elseif (isset($this->currentLine[++$cursor])) {
$value .= '\\'.$this->currentLine[$cursor];
}

break;
case $quotation:
++$cursor;

if ("'" === $quotation && isset($this->currentLine[$cursor]) && "'" === $this->currentLine[$cursor]) {
$value .= "''";
break;
}

return $value.$quotation;
default:
$value .= $this->currentLine[$cursor];
}
}

if ($this->isCurrentLineBlank()) {
$previousLineWasNewline = true;
$previousLineWasTerminatedWithBackslash = false;
} elseif ('\\' === $this->currentLine[-1]) {
$previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = true;
} else {
$previousLineWasNewline = false;
$previousLineWasTerminatedWithBackslash = false;
}

if ($this->hasMoreLines()) {
$cursor = 0;
}
} while ($this->moveToNextLine());

throw new ParseException('Malformed inline YAML string.');
}

private function lexUnquotedString(int &$cursor): string
{
$offset = $cursor;
$cursor += strcspn($this->currentLine, '[]{},: ', $cursor);

if ($cursor === $offset) {
throw new ParseException('Malformed unquoted YAML string.');
}

return substr($this->currentLine, $offset, $cursor - $offset);
}

private function lexInlineMapping(int &$cursor = 0): string
{
return $this->lexInlineStructure($cursor, '}');
}

private function lexInlineSequence(int &$cursor = 0): string
{
return $this->lexInlineStructure($cursor, ']');
}

private function lexInlineStructure(int &$cursor, string $closingTag): string
{
$value = $this->currentLine[$cursor];
++$cursor;

do {
$this->consumeWhitespaces($cursor);

while (isset($this->currentLine[$cursor])) {
switch ($this->currentLine[$cursor]) {
case '"':
case "'":
$value .= $this->lexInlineQuotedString($cursor);
break;
case ':':
case ',':
$value .= $this->currentLine[$cursor];
++$cursor;
break;
case '{':
$value .= $this->lexInlineMapping($cursor);
break;
case '[':
$value .= $this->lexInlineSequence($cursor);
break;
case $closingTag:
$value .= $this->currentLine[$cursor];
++$cursor;

return $value;
case '#':
break 2;
default:
$value .= $this->lexUnquotedString($cursor);
}

if ($this->consumeWhitespaces($cursor)) {
$value .= ' ';
}
}

if ($this->hasMoreLines()) {
$cursor = 0;
}
} while ($this->moveToNextLine());

throw new ParseException('Malformed inline YAML string.');
}

private function consumeWhitespaces(int &$cursor): bool
{
$whitespacesConsumed = 0;

do {
$whitespaceOnlyTokenLength = strspn($this->currentLine, ' ', $cursor);
$whitespacesConsumed += $whitespaceOnlyTokenLength;
$cursor += $whitespaceOnlyTokenLength;

if (isset($this->currentLine[$cursor])) {
return 0 < $whitespacesConsumed;
}

if ($this->hasMoreLines()) {
$cursor = 0;
}
} while ($this->moveToNextLine());

return 0 < $whitespacesConsumed;
}
}
<?php










namespace Symfony\Component\Yaml\Tag;





final class TaggedValue
{
private $tag;
private $value;

public function __construct(string $tag, $value)
{
$this->tag = $tag;
$this->value = $value;
}

public function getTag(): string
{
return $this->tag;
}

public function getValue()
{
return $this->value;
}
}
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\ParseException;








class Yaml
{
public const DUMP_OBJECT = 1;
public const PARSE_EXCEPTION_ON_INVALID_TYPE = 2;
public const PARSE_OBJECT = 4;
public const PARSE_OBJECT_FOR_MAP = 8;
public const DUMP_EXCEPTION_ON_INVALID_TYPE = 16;
public const PARSE_DATETIME = 32;
public const DUMP_OBJECT_AS_MAP = 64;
public const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
public const PARSE_CONSTANT = 256;
public const PARSE_CUSTOM_TAGS = 512;
public const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
public const DUMP_NULL_AS_TILDE = 2048;
















public static function parseFile(string $filename, int $flags = 0)
{
$yaml = new Parser();

return $yaml->parseFile($filename, $flags);
}

















public static function parse(string $input, int $flags = 0)
{
$yaml = new Parser();

return $yaml->parse($input, $flags);
}












public static function dump($input, int $inline = 2, int $indent = 4, int $flags = 0): string
{
$yaml = new Dumper($indent);

return $yaml->dump($input, $inline, 0, $flags);
}
}
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Exception\DumpException;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Tag\TaggedValue;








class Inline
{
public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')';

public static $parsedLineNumber = -1;
public static $parsedFilename;

private static $exceptionOnInvalidType = false;
private static $objectSupport = false;
private static $objectForMap = false;
private static $constantSupport = false;

public static function initialize(int $flags, int $parsedLineNumber = null, string $parsedFilename = null)
{
self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags);
self::$parsedFilename = $parsedFilename;

if (null !== $parsedLineNumber) {
self::$parsedLineNumber = $parsedLineNumber;
}
}












public static function parse(string $value = null, int $flags = 0, array &$references = [])
{
self::initialize($flags);

$value = trim($value);

if ('' === $value) {
return '';
}

if (2  & (int) \ini_get('mbstring.func_overload')) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
}

try {
$i = 0;
$tag = self::parseTag($value, $i, $flags);
switch ($value[$i]) {
case '[':
$result = self::parseSequence($value, $flags, $i, $references);
++$i;
break;
case '{':
$result = self::parseMapping($value, $flags, $i, $references);
++$i;
break;
default:
$result = self::parseScalar($value, $flags, null, $i, true, $references);
}


if (preg_replace('/\s*#.*$/A', '', substr($value, $i))) {
throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

if (null !== $tag && '' !== $tag) {
return new TaggedValue($tag, $result);
}

return $result;
} finally {
if (isset($mbEncoding)) {
mb_internal_encoding($mbEncoding);
}
}
}









public static function dump($value, int $flags = 0): string
{
switch (true) {
case \is_resource($value):
if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
}

return self::dumpNull($flags);
case $value instanceof \DateTimeInterface:
return $value->format('c');
case $value instanceof \UnitEnum:
return sprintf('!php/const %s::%s', \get_class($value), $value->name);
case \is_object($value):
if ($value instanceof TaggedValue) {
return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags);
}

if (Yaml::DUMP_OBJECT & $flags) {
return '!php/object '.self::dump(serialize($value));
}

if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) {
$output = [];

foreach ($value as $key => $val) {
$output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
}

return sprintf('{ %s }', implode(', ', $output));
}

if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) {
throw new DumpException('Object support when dumping a YAML file has been disabled.');
}

return self::dumpNull($flags);
case \is_array($value):
return self::dumpArray($value, $flags);
case null === $value:
return self::dumpNull($flags);
case true === $value:
return 'true';
case false === $value:
return 'false';
case \is_int($value):
return $value;
case is_numeric($value) && false === strpbrk($value, "\f\n\r\t\v"):
$locale = setlocale(\LC_NUMERIC, 0);
if (false !== $locale) {
setlocale(\LC_NUMERIC, 'C');
}
if (\is_float($value)) {
$repr = (string) $value;
if (is_infinite($value)) {
$repr = str_ireplace('INF', '.Inf', $repr);
} elseif (floor($value) == $value && $repr == $value) {

if (false === strpos($repr, 'E')) {
$repr = $repr.'.0';
}
}
} else {
$repr = \is_string($value) ? "'$value'" : (string) $value;
}
if (false !== $locale) {
setlocale(\LC_NUMERIC, $locale);
}

return $repr;
case '' == $value:
return "''";
case self::isBinaryString($value):
return '!!binary '.base64_encode($value);
case Escaper::requiresDoubleQuoting($value):
return Escaper::escapeWithDoubleQuotes($value);
case Escaper::requiresSingleQuoting($value):
case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value):
case Parser::preg_match(self::getHexRegex(), $value):
case Parser::preg_match(self::getTimestampRegex(), $value):
return Escaper::escapeWithSingleQuotes($value);
default:
return $value;
}
}






public static function isHash($value): bool
{
if ($value instanceof \stdClass || $value instanceof \ArrayObject) {
return true;
}

$expectedKey = 0;

foreach ($value as $key => $val) {
if ($key !== $expectedKey++) {
return true;
}
}

return false;
}







private static function dumpArray(array $value, int $flags): string
{

if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) {
$output = [];
foreach ($value as $val) {
$output[] = self::dump($val, $flags);
}

return sprintf('[%s]', implode(', ', $output));
}


$output = [];
foreach ($value as $key => $val) {
$output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags));
}

return sprintf('{ %s }', implode(', ', $output));
}

private static function dumpNull(int $flags): string
{
if (Yaml::DUMP_NULL_AS_TILDE & $flags) {
return '~';
}

return 'null';
}








public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [], bool &$isQuoted = null)
{
if (\in_array($scalar[$i], ['"', "'"], true)) {

$isQuoted = true;
$output = self::parseQuotedScalar($scalar, $i);

if (null !== $delimiters) {
$tmp = ltrim(substr($scalar, $i), " \n");
if ('' === $tmp) {
throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode('', $delimiters)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}
if (!\in_array($tmp[0], $delimiters)) {
throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}
}
} else {

$isQuoted = false;

if (!$delimiters) {
$output = substr($scalar, $i);
$i += \strlen($output);


if (Parser::preg_match('/[ \t]+#/', $output, $match, \PREG_OFFSET_CAPTURE)) {
$output = substr($output, 0, $match[0][1]);
}
} elseif (Parser::preg_match('/^(.*?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
$output = $match[1];
$i += \strlen($output);
$output = trim($output);
} else {
throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename);
}


if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0] || '%' === $output[0])) {
throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename);
}

if ($evaluate) {
$output = self::evaluateScalar($output, $flags, $references, $isQuoted);
}
}

return $output;
}






private static function parseQuotedScalar(string $scalar, int &$i = 0): string
{
if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
throw new ParseException(sprintf('Malformed inline YAML string: "%s".', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}

$output = substr($match[0], 1, -1);

$unescaper = new Unescaper();
if ('"' == $scalar[$i]) {
$output = $unescaper->unescapeDoubleQuotedString($output);
} else {
$output = $unescaper->unescapeSingleQuotedString($output);
}

$i += \strlen($match[0]);

return $output;
}






private static function parseSequence(string $sequence, int $flags, int &$i = 0, array &$references = []): array
{
$output = [];
$len = \strlen($sequence);
++$i;


while ($i < $len) {
if (']' === $sequence[$i]) {
return $output;
}
if (',' === $sequence[$i] || ' ' === $sequence[$i]) {
++$i;

continue;
}

$tag = self::parseTag($sequence, $i, $flags);
switch ($sequence[$i]) {
case '[':

$value = self::parseSequence($sequence, $flags, $i, $references);
break;
case '{':

$value = self::parseMapping($sequence, $flags, $i, $references);
break;
default:
$value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references, $isQuoted);


if (\is_string($value) && !$isQuoted && false !== strpos($value, ': ')) {

try {
$pos = 0;
$value = self::parseMapping('{'.$value.'}', $flags, $pos, $references);
} catch (\InvalidArgumentException $e) {

}
}

if (!$isQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) {
$references[$matches['ref']] = $matches['value'];
$value = $matches['value'];
}

--$i;
}

if (null !== $tag && '' !== $tag) {
$value = new TaggedValue($tag, $value);
}

$output[] = $value;

++$i;
}

throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename);
}








private static function parseMapping(string $mapping, int $flags, int &$i = 0, array &$references = [])
{
$output = [];
$len = \strlen($mapping);
++$i;
$allowOverwrite = false;


while ($i < $len) {
switch ($mapping[$i]) {
case ' ':
case ',':
case "\n":
++$i;
continue 2;
case '}':
if (self::$objectForMap) {
return (object) $output;
}

return $output;
}


$offsetBeforeKeyParsing = $i;
$isKeyQuoted = \in_array($mapping[$i], ['"', "'"], true);
$key = self::parseScalar($mapping, $flags, [':', ' '], $i, false);

if ($offsetBeforeKeyParsing === $i) {
throw new ParseException('Missing mapping key.', self::$parsedLineNumber + 1, $mapping);
}

if ('!php/const' === $key) {
$key .= ' '.self::parseScalar($mapping, $flags, [':'], $i, false);
$key = self::evaluateScalar($key, $flags);
}

if (false === $i = strpos($mapping, ':', $i)) {
break;
}

if (!$isKeyQuoted) {
$evaluatedKey = self::evaluateScalar($key, $flags, $references);

if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) {
throw new ParseException('Implicit casting of incompatible mapping keys to strings is not supported. Quote your evaluable mapping keys instead.', self::$parsedLineNumber + 1, $mapping);
}
}

if (!$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], [' ', ',', '[', ']', '{', '}', "\n"], true))) {
throw new ParseException('Colons must be followed by a space or an indication character (i.e. " ", ",", "[", "]", "{", "}").', self::$parsedLineNumber + 1, $mapping);
}

if ('<<' === $key) {
$allowOverwrite = true;
}

while ($i < $len) {
if (':' === $mapping[$i] || ' ' === $mapping[$i] || "\n" === $mapping[$i]) {
++$i;

continue;
}

$tag = self::parseTag($mapping, $i, $flags);
switch ($mapping[$i]) {
case '[':

$value = self::parseSequence($mapping, $flags, $i, $references);




if ('<<' === $key) {
foreach ($value as $parsedValue) {
$output += $parsedValue;
}
} elseif ($allowOverwrite || !isset($output[$key])) {
if (null !== $tag) {
$output[$key] = new TaggedValue($tag, $value);
} else {
$output[$key] = $value;
}
} elseif (isset($output[$key])) {
throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
}
break;
case '{':

$value = self::parseMapping($mapping, $flags, $i, $references);




if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key])) {
if (null !== $tag) {
$output[$key] = new TaggedValue($tag, $value);
} else {
$output[$key] = $value;
}
} elseif (isset($output[$key])) {
throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
}
break;
default:
$value = self::parseScalar($mapping, $flags, [',', '}', "\n"], $i, null === $tag, $references, $isValueQuoted);




if ('<<' === $key) {
$output += $value;
} elseif ($allowOverwrite || !isset($output[$key])) {
if (!$isValueQuoted && \is_string($value) && '' !== $value && '&' === $value[0] && Parser::preg_match(Parser::REFERENCE_PATTERN, $value, $matches)) {
$references[$matches['ref']] = $matches['value'];
$value = $matches['value'];
}

if (null !== $tag) {
$output[$key] = new TaggedValue($tag, $value);
} else {
$output[$key] = $value;
}
} elseif (isset($output[$key])) {
throw new ParseException(sprintf('Duplicate key "%s" detected.', $key), self::$parsedLineNumber + 1, $mapping);
}
--$i;
}
++$i;

continue 2;
}
}

throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename);
}








private static function evaluateScalar(string $scalar, int $flags, array &$references = [], bool &$isQuotedString = null)
{
$isQuotedString = false;
$scalar = trim($scalar);

if (0 === strpos($scalar, '*')) {
if (false !== $pos = strpos($scalar, '#')) {
$value = substr($scalar, 1, $pos - 2);
} else {
$value = substr($scalar, 1);
}


if (false === $value || '' === $value) {
throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

if (!\array_key_exists($value, $references)) {
throw new ParseException(sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

return $references[$value];
}

$scalarLower = strtolower($scalar);

switch (true) {
case 'null' === $scalarLower:
case '' === $scalar:
case '~' === $scalar:
return null;
case 'true' === $scalarLower:
return true;
case 'false' === $scalarLower:
return false;
case '!' === $scalar[0]:
switch (true) {
case 0 === strpos($scalar, '!!str '):
$s = (string) substr($scalar, 6);

if (\in_array($s[0] ?? '', ['"', "'"], true)) {
$isQuotedString = true;
$s = self::parseQuotedScalar($s);
}

return $s;
case 0 === strpos($scalar, '! '):
return substr($scalar, 2);
case 0 === strpos($scalar, '!php/object'):
if (self::$objectSupport) {
if (!isset($scalar[12])) {
trigger_deprecation('symfony/yaml', '5.1', 'Using the !php/object tag without a value is deprecated.');

return false;
}

return unserialize(self::parseScalar(substr($scalar, 12)));
}

if (self::$exceptionOnInvalidType) {
throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}

return null;
case 0 === strpos($scalar, '!php/const'):
if (self::$constantSupport) {
if (!isset($scalar[11])) {
trigger_deprecation('symfony/yaml', '5.1', 'Using the !php/const tag without a value is deprecated.');

return '';
}

$i = 0;
if (\defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) {
return \constant($const);
}

throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}
if (self::$exceptionOnInvalidType) {
throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}

return null;
case 0 === strpos($scalar, '!!float '):
return (float) substr($scalar, 8);
case 0 === strpos($scalar, '!!binary '):
return self::evaluateBinaryScalar(substr($scalar, 9));
}

throw new ParseException(sprintf('The string "%s" could not be parsed as it uses an unsupported built-in tag.', $scalar), self::$parsedLineNumber, $scalar, self::$parsedFilename);
case preg_match('/^(?:\+|-)?0o(?P<value>[0-7_]++)$/', $scalar, $matches):
$value = str_replace('_', '', $matches['value']);

if ('-' === $scalar[0]) {
return -octdec($value);
}

return octdec($value);
case \in_array($scalar[0], ['+', '-', '.'], true) || is_numeric($scalar[0]):
if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) {
$scalar = str_replace('_', '', $scalar);
}

switch (true) {
case ctype_digit($scalar):
if (preg_match('/^0[0-7]+$/', $scalar)) {
trigger_deprecation('symfony/yaml', '5.1', 'Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0. Use "%s" to represent the octal number.', '0o'.substr($scalar, 1));

return octdec($scalar);
}

$cast = (int) $scalar;

return ($scalar === (string) $cast) ? $cast : $scalar;
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
if (preg_match('/^-0[0-7]+$/', $scalar)) {
trigger_deprecation('symfony/yaml', '5.1', 'Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0. Use "%s" to represent the octal number.', '-0o'.substr($scalar, 2));

return -octdec(substr($scalar, 1));
}

$cast = (int) $scalar;

return ($scalar === (string) $cast) ? $cast : $scalar;
case is_numeric($scalar):
case Parser::preg_match(self::getHexRegex(), $scalar):
$scalar = str_replace('_', '', $scalar);

return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar;
case '.inf' === $scalarLower:
case '.nan' === $scalarLower:
return -log(0);
case '-.inf' === $scalarLower:
return log(0);
case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar):
return (float) str_replace('_', '', $scalar);
case Parser::preg_match(self::getTimestampRegex(), $scalar):

$time = new \DateTime($scalar, new \DateTimeZone('UTC'));

if (Yaml::PARSE_DATETIME & $flags) {
return $time;
}

try {
if (false !== $scalar = $time->getTimestamp()) {
return $scalar;
}
} catch (\ValueError $e) {

}

return $time->format('U');
}
}

return (string) $scalar;
}

private static function parseTag(string $value, int &$i, int $flags): ?string
{
if ('!' !== $value[$i]) {
return null;
}

$tagLength = strcspn($value, " \t\n[]{},", $i + 1);
$tag = substr($value, $i + 1, $tagLength);

$nextOffset = $i + $tagLength + 1;
$nextOffset += strspn($value, ' ', $nextOffset);

if ('' === $tag && (!isset($value[$nextOffset]) || \in_array($value[$nextOffset], [']', '}', ','], true))) {
throw new ParseException('Using the unquoted scalar value "!" is not supported. You must quote it.', self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}


if ('' !== $tag && (!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && ('!' === $tag[0] || 'str' === $tag || 'php/const' === $tag || 'php/object' === $tag)) {

return null;
}

$i = $nextOffset;


if ('' !== $tag && '!' === $tag[0]) {
throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

if ('' !== $tag && !isset($value[$i])) {
throw new ParseException(sprintf('Missing value for tag "%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

if ('' === $tag || Yaml::PARSE_CUSTOM_TAGS & $flags) {
return $tag;
}

throw new ParseException(sprintf('Tags support is not enabled. Enable the "Yaml::PARSE_CUSTOM_TAGS" flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename);
}

public static function evaluateBinaryScalar(string $scalar): string
{
$parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar));

if (0 !== (\strlen($parsedBinaryData) % 4)) {
throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', \strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}

if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) {
throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename);
}

return base64_decode($parsedBinaryData, true);
}

private static function isBinaryString(string $value): bool
{
return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value);
}






private static function getTimestampRegex(): string
{
return <<<EOF
        ~^
        (?P<year>[0-9][0-9][0-9][0-9])
        -(?P<month>[0-9][0-9]?)
        -(?P<day>[0-9][0-9]?)
        (?:(?:[Tt]|[ \t]+)
        (?P<hour>[0-9][0-9]?)
        :(?P<minute>[0-9][0-9])
        :(?P<second>[0-9][0-9])
        (?:\.(?P<fraction>[0-9]*))?
        (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
        (?::(?P<tz_minute>[0-9][0-9]))?))?)?
        $~x
EOF;
}




private static function getHexRegex(): string
{
return '~^0x[0-9a-f_]++$~i';
}
}
<?php










namespace Symfony\Component\Yaml\Command;

use Symfony\Component\Console\CI\GithubActionReporter;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Yaml;







class LintCommand extends Command
{
protected static $defaultName = 'lint:yaml';
protected static $defaultDescription = 'Lint a YAML file and outputs encountered errors';

private $parser;
private $format;
private $displayCorrectFiles;
private $directoryIteratorProvider;
private $isReadableProvider;

public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null)
{
parent::__construct($name);

$this->directoryIteratorProvider = $directoryIteratorProvider;
$this->isReadableProvider = $isReadableProvider;
}




protected function configure()
{
$this
->setDescription(self::$defaultDescription)
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format')
->addOption('exclude', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Path(s) to exclude')
->addOption('parse-tags', null, InputOption::VALUE_NEGATABLE, 'Parse custom tags', null)
->setHelp(<<<EOF
The <info>%command.name%</info> command lints a YAML file and outputs to STDOUT
the first encountered syntax error.

You can validates YAML contents passed from STDIN:

  <info>cat filename | php %command.full_name% -</info>

You can also validate the syntax of a file:

  <info>php %command.full_name% filename</info>

Or of a whole directory:

  <info>php %command.full_name% dirname</info>
  <info>php %command.full_name% dirname --format=json</info>

You can also exclude one or more specific files:

  <info>php %command.full_name% dirname --exclude="dirname/foo.yaml" --exclude="dirname/bar.yaml"</info>

EOF
)
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$filenames = (array) $input->getArgument('filename');
$excludes = $input->getOption('exclude');
$this->format = $input->getOption('format');
$flags = $input->getOption('parse-tags');

if ('github' === $this->format && !class_exists(GithubActionReporter::class)) {
throw new \InvalidArgumentException('The "github" format is only available since "symfony/console" >= 5.3.');
}

if (null === $this->format) {

$this->format = class_exists(GithubActionReporter::class) && GithubActionReporter::isGithubActionEnvironment() ? 'github' : 'txt';
}

$flags = $flags ? Yaml::PARSE_CUSTOM_TAGS : 0;

$this->displayCorrectFiles = $output->isVerbose();

if (['-'] === $filenames) {
return $this->display($io, [$this->validate(file_get_contents('php://stdin'), $flags)]);
}

if (!$filenames) {
throw new RuntimeException('Please provide a filename or pipe file content to STDIN.');
}

$filesInfo = [];
foreach ($filenames as $filename) {
if (!$this->isReadable($filename)) {
throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename));
}

foreach ($this->getFiles($filename) as $file) {
if (!\in_array($file->getPathname(), $excludes, true)) {
$filesInfo[] = $this->validate(file_get_contents($file), $flags, $file);
}
}
}

return $this->display($io, $filesInfo);
}

private function validate(string $content, int $flags, string $file = null)
{
$prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) {
if (\E_USER_DEPRECATED === $level) {
throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1);
}

return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false;
});

try {
$this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags);
} catch (ParseException $e) {
return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => false, 'message' => $e->getMessage()];
} finally {
restore_error_handler();
}

return ['file' => $file, 'valid' => true];
}

private function display(SymfonyStyle $io, array $files): int
{
switch ($this->format) {
case 'txt':
return $this->displayTxt($io, $files);
case 'json':
return $this->displayJson($io, $files);
case 'github':
return $this->displayTxt($io, $files, true);
default:
throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format));
}
}

private function displayTxt(SymfonyStyle $io, array $filesInfo, bool $errorAsGithubAnnotations = false): int
{
$countFiles = \count($filesInfo);
$erroredFiles = 0;
$suggestTagOption = false;

if ($errorAsGithubAnnotations) {
$githubReporter = new GithubActionReporter($io);
}

foreach ($filesInfo as $info) {
if ($info['valid'] && $this->displayCorrectFiles) {
$io->comment('<info>OK</info>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
} elseif (!$info['valid']) {
++$erroredFiles;
$io->text('<error> ERROR </error>'.($info['file'] ? sprintf(' in %s', $info['file']) : ''));
$io->text(sprintf('<error> >> %s</error>', $info['message']));

if (false !== strpos($info['message'], 'PARSE_CUSTOM_TAGS')) {
$suggestTagOption = true;
}

if ($errorAsGithubAnnotations) {
$githubReporter->error($info['message'], $info['file'] ?? 'php://stdin', $info['line']);
}
}
}

if (0 === $erroredFiles) {
$io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles));
} else {
$io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.%s', $countFiles - $erroredFiles, $erroredFiles, $suggestTagOption ? ' Use the --parse-tags option if you want parse custom tags.' : ''));
}

return min($erroredFiles, 1);
}

private function displayJson(SymfonyStyle $io, array $filesInfo): int
{
$errors = 0;

array_walk($filesInfo, function (&$v) use (&$errors) {
$v['file'] = (string) $v['file'];
if (!$v['valid']) {
++$errors;
}

if (isset($v['message']) && false !== strpos($v['message'], 'PARSE_CUSTOM_TAGS')) {
$v['message'] .= ' Use the --parse-tags option if you want parse custom tags.';
}
});

$io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES));

return min($errors, 1);
}

private function getFiles(string $fileOrDirectory): iterable
{
if (is_file($fileOrDirectory)) {
yield new \SplFileInfo($fileOrDirectory);

return;
}

foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) {
if (!\in_array($file->getExtension(), ['yml', 'yaml'])) {
continue;
}

yield $file;
}
}

private function getParser(): Parser
{
if (!$this->parser) {
$this->parser = new Parser();
}

return $this->parser;
}

private function getDirectoryIterator(string $directory): iterable
{
$default = function ($directory) {
return new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS),
\RecursiveIteratorIterator::LEAVES_ONLY
);
};

if (null !== $this->directoryIteratorProvider) {
return ($this->directoryIteratorProvider)($directory, $default);
}

return $default($directory);
}

private function isReadable(string $fileOrDirectory): bool
{
$default = function ($fileOrDirectory) {
return is_readable($fileOrDirectory);
};

if (null !== $this->isReadableProvider) {
return ($this->isReadableProvider)($fileOrDirectory, $default);
}

return $default($fileOrDirectory);
}

public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
{
if ($input->mustSuggestOptionValuesFor('format')) {
$suggestions->suggestValues(['txt', 'json', 'github']);
}
}
}
#!/usr/bin/env php
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

if ('cli' !== \PHP_SAPI) {
    throw new Exception('This script must be run from the command line.');
}

/**
 * Runs the Yaml lint command.
 *
 * @author Jan Schädlich <jan.schaedlich@sensiolabs.de>
 */

use Symfony\Component\Console\Application;
use Symfony\Component\Yaml\Command\LintCommand;

function includeIfExists(string $file): bool
{
    return file_exists($file) && include $file;
}

if (
    !includeIfExists(__DIR__ . '/../../../../autoload.php') &&
    !includeIfExists(__DIR__ . '/../../vendor/autoload.php') &&
    !includeIfExists(__DIR__ . '/../../../../../../vendor/autoload.php')
) {
    fwrite(STDERR, 'Install dependencies using Composer.'.PHP_EOL);
    exit(1);
}

if (!class_exists(Application::class)) {
    fwrite(STDERR, 'You need the "symfony/console" component in order to run the Yaml linter.'.PHP_EOL);
    exit(1);
}

(new Application())->add($command = new LintCommand())
    ->getApplication()
    ->setDefaultCommand($command->getName(), true)
    ->run()
;
<?php










namespace Symfony\Component\Yaml;

use Symfony\Component\Yaml\Tag\TaggedValue;








class Dumper
{





protected $indentation;

public function __construct(int $indentation = 4)
{
if ($indentation < 1) {
throw new \InvalidArgumentException('The indentation must be greater than zero.');
}

$this->indentation = $indentation;
}









public function dump($input, int $inline = 0, int $indent = 0, int $flags = 0): string
{
$output = '';
$prefix = $indent ? str_repeat(' ', $indent) : '';
$dumpObjectAsInlineMap = true;

if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) {
$dumpObjectAsInlineMap = empty((array) $input);
}

if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) {
$output .= $prefix.Inline::dump($input, $flags);
} else {
$dumpAsMap = Inline::isHash($input);

foreach ($input as $key => $value) {
if ('' !== $output && "\n" !== $output[-1]) {
$output .= "\n";
}

if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) {


$blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : '';

if (isset($value[-2]) && "\n" === $value[-2] && "\n" === $value[-1]) {
$blockChompingIndicator = '+';
} elseif ("\n" === $value[-1]) {
$blockChompingIndicator = '';
} else {
$blockChompingIndicator = '-';
}

$output .= sprintf('%s%s%s |%s%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator, $blockChompingIndicator);

foreach (explode("\n", $value) as $row) {
if ('' === $row) {
$output .= "\n";
} else {
$output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row);
}
}

continue;
}

if ($value instanceof TaggedValue) {
$output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag());

if (Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) {


$blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : '';
$output .= sprintf(' |%s', $blockIndentationIndicator);

foreach (explode("\n", $value->getValue()) as $row) {
$output .= sprintf("\n%s%s%s", $prefix, str_repeat(' ', $this->indentation), $row);
}

continue;
}

if ($inline - 1 <= 0 || null === $value->getValue() || \is_scalar($value->getValue())) {
$output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n";
} else {
$output .= "\n";
$output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags);
}

continue;
}

$dumpObjectAsInlineMap = true;

if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) {
$dumpObjectAsInlineMap = empty((array) $value);
}

$willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value);

$output .= sprintf('%s%s%s%s',
$prefix,
$dumpAsMap ? Inline::dump($key, $flags).':' : '-',
$willBeInlined ? ' ' : "\n",
$this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags)
).($willBeInlined ? "\n" : '');
}
}

return $output;
}
}
<?php










namespace Symfony\Component\Yaml\Exception;






class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php










namespace Symfony\Component\Yaml\Exception;






class DumpException extends RuntimeException
{
}
<?php










namespace Symfony\Component\Yaml\Exception;






interface ExceptionInterface extends \Throwable
{
}
<?php










namespace Symfony\Component\Yaml\Exception;






class ParseException extends RuntimeException
{
private $parsedFile;
private $parsedLine;
private $snippet;
private $rawMessage;







public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Throwable $previous = null)
{
$this->parsedFile = $parsedFile;
$this->parsedLine = $parsedLine;
$this->snippet = $snippet;
$this->rawMessage = $message;

$this->updateRepr();

parent::__construct($this->message, 0, $previous);
}






public function getSnippet()
{
return $this->snippet;
}




public function setSnippet(string $snippet)
{
$this->snippet = $snippet;

$this->updateRepr();
}








public function getParsedFile()
{
return $this->parsedFile;
}




public function setParsedFile(string $parsedFile)
{
$this->parsedFile = $parsedFile;

$this->updateRepr();
}






public function getParsedLine()
{
return $this->parsedLine;
}




public function setParsedLine(int $parsedLine)
{
$this->parsedLine = $parsedLine;

$this->updateRepr();
}

private function updateRepr()
{
$this->message = $this->rawMessage;

$dot = false;
if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$dot = true;
}

if (null !== $this->parsedFile) {
$this->message .= sprintf(' in %s', json_encode($this->parsedFile, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE));
}

if ($this->parsedLine >= 0) {
$this->message .= sprintf(' at line %d', $this->parsedLine);
}

if ($this->snippet) {
$this->message .= sprintf(' (near "%s")', $this->snippet);
}

if ($dot) {
$this->message .= '.';
}
}
}
<?php










namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Comparator\DateComparator;






class DateRangeFilterIterator extends FilterIterator
{
private $comparators = array();





public function __construct(\Iterator $iterator, array $comparators)
{
$this->comparators = $comparators;

parent::__construct($iterator);
}






public function accept()
{
$fileinfo = $this->current();

if (!file_exists($fileinfo->getPathname())) {
return false;
}

$filedate = $fileinfo->getMTime();
foreach ($this->comparators as $compare) {
if (!$compare->test($filedate)) {
return false;
}
}

return true;
}
}
<?php










namespace Symfony\Component\Finder\Iterator;






class DepthRangeFilterIterator extends FilterIterator
{
private $minDepth = 0;






public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX)
{
$this->minDepth = $minDepth;
$iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);

parent::__construct($iterator);
}






public function accept()
{
return $this->getInnerIterator()->getDepth() >= $this->minDepth;
}
}
<?php










namespace Symfony\Component\Finder\Iterator;






abstract class MultiplePcreFilterIterator extends FilterIterator
{
protected $matchRegexps = array();
protected $noMatchRegexps = array();






public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
{
foreach ($matchPatterns as $pattern) {
$this->matchRegexps[] = $this->toRegex($pattern);
}

foreach ($noMatchPatterns as $pattern) {
$this->noMatchRegexps[] = $this->toRegex($pattern);
}

parent::__construct($iterator);
}












protected function isAccepted($string)
{

foreach ($this->noMatchRegexps as $regex) {
if (preg_match($regex, $string)) {
return false;
}
}


if ($this->matchRegexps) {
foreach ($this->matchRegexps as $regex) {
if (preg_match($regex, $string)) {
return true;
}
}

return false;
}


return true;
}








protected function isRegex($str)
{
if (preg_match('/^(.{3,}?)[imsxuADU]*$/', $str, $m)) {
$start = substr($m[1], 0, 1);
$end = substr($m[1], -1);

if ($start === $end) {
return !preg_match('/[*?[:alnum:] \\\\]/', $start);
}

foreach (array(array('{', '}'), array('(', ')'), array('[', ']'), array('<', '>')) as $delimiters) {
if ($start === $delimiters[0] && $end === $delimiters[1]) {
return true;
}
}
}

return false;
}








abstract protected function toRegex($str);
}
<?php










namespace Symfony\Component\Finder\Iterator;

@trigger_error('The '.__NAMESPACE__.'\FilePathsIterator class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\SplFileInfo;








class FilePathsIterator extends \ArrayIterator
{



private $baseDir;




private $baseDirLength;




private $subPath;




private $subPathname;




private $current;





public function __construct(array $paths, $baseDir)
{
$this->baseDir = $baseDir;
$this->baseDirLength = \strlen($baseDir);

parent::__construct($paths);
}







public function __call($name, array $arguments)
{
return \call_user_func_array(array($this->current(), $name), $arguments);
}






public function current()
{
return $this->current;
}




public function key()
{
return $this->current->getPathname();
}

public function next()
{
parent::next();
$this->buildProperties();
}

public function rewind()
{
parent::rewind();
$this->buildProperties();
}




public function getSubPath()
{
return $this->subPath;
}




public function getSubPathname()
{
return $this->subPathname;
}

private function buildProperties()
{
$absolutePath = parent::current();

if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
$this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
$dir = \dirname($this->subPathname);
$this->subPath = '.' === $dir ? '' : $dir;
} else {
$this->subPath = $this->subPathname = '';
}

$this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
}
}
<?php










namespace Symfony\Component\Finder\Iterator;






class SortableIterator implements \IteratorAggregate
{
const SORT_BY_NAME = 1;
const SORT_BY_TYPE = 2;
const SORT_BY_ACCESSED_TIME = 3;
const SORT_BY_CHANGED_TIME = 4;
const SORT_BY_MODIFIED_TIME = 5;

private $iterator;
private $sort;







public function __construct(\Traversable $iterator, $sort)
{
$this->iterator = $iterator;

if (self::SORT_BY_NAME === $sort) {
$this->sort = function ($a, $b) {
return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
};
} elseif (self::SORT_BY_TYPE === $sort) {
$this->sort = function ($a, $b) {
if ($a->isDir() && $b->isFile()) {
return -1;
} elseif ($a->isFile() && $b->isDir()) {
return 1;
}

return strcmp($a->getRealpath() ?: $a->getPathname(), $b->getRealpath() ?: $b->getPathname());
};
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
$this->sort = function ($a, $b) {
return $a->getATime() - $b->getATime();
};
} elseif (self::SORT_BY_CHANGED_TIME === $sort) {
$this->sort = function ($a, $b) {
return $a->getCTime() - $b->getCTime();
};
} elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
$this->sort = function ($a, $b) {
return $a->getMTime() - $b->getMTime();
};
} elseif (\is_callable($sort)) {
$this->sort = $sort;
} else {
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
}
}

public function getIterator()
{
$array = iterator_to_array($this->iterator, true);
uasort($array, $this->sort);

return new \ArrayIterator($array);
}
}
<?php










namespace Symfony\Component\Finder\Iterator;









class CustomFilterIterator extends FilterIterator
{
private $filters = array();







public function __construct(\Iterator $iterator, array $filters)
{
foreach ($filters as $filter) {
if (!\is_callable($filter)) {
throw new \InvalidArgumentException('Invalid PHP callback.');
}
}
$this->filters = $filters;

parent::__construct($iterator);
}






public function accept()
{
$fileinfo = $this->current();

foreach ($this->filters as $filter) {
if (false === \call_user_func($filter, $fileinfo)) {
return false;
}
}

return true;
}
}
<?php










namespace Symfony\Component\Finder\Iterator;






class ExcludeDirectoryFilterIterator extends FilterIterator implements \RecursiveIterator
{
private $iterator;
private $isRecursive;
private $excludedDirs = array();
private $excludedPattern;





public function __construct(\Iterator $iterator, array $directories)
{
$this->iterator = $iterator;
$this->isRecursive = $iterator instanceof \RecursiveIterator;
$patterns = array();
foreach ($directories as $directory) {
$directory = rtrim($directory, '/');
if (!$this->isRecursive || false !== strpos($directory, '/')) {
$patterns[] = preg_quote($directory, '#');
} else {
$this->excludedDirs[$directory] = true;
}
}
if ($patterns) {
$this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#';
}

parent::__construct($iterator);
}






public function accept()
{
if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) {
return false;
}

if ($this->excludedPattern) {
$path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
$path = str_replace('\\', '/', $path);

return !preg_match($this->excludedPattern, $path);
}

return true;
}

public function hasChildren()
{
return $this->isRecursive && $this->iterator->hasChildren();
}

public function getChildren()
{
$children = new self($this->iterator->getChildren(), array());
$children->excludedDirs = $this->excludedDirs;
$children->excludedPattern = $this->excludedPattern;

return $children;
}
}
<?php










namespace Symfony\Component\Finder\Iterator;







class PathFilterIterator extends MultiplePcreFilterIterator
{





public function accept()
{
$filename = $this->current()->getRelativePathname();

if ('\\' === \DIRECTORY_SEPARATOR) {
$filename = str_replace('\\', '/', $filename);
}

return $this->isAccepted($filename);
}















protected function toRegex($str)
{
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
}
}
<?php










namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Glob;






class FilenameFilterIterator extends MultiplePcreFilterIterator
{





public function accept()
{
return $this->isAccepted($this->current()->getFilename());
}











protected function toRegex($str)
{
return $this->isRegex($str) ? $str : Glob::toRegex($str);
}
}
<?php










namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Finder\SplFileInfo;






class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
{



private $ignoreUnreadableDirs;




private $rewindable;


private $rootPath;
private $subPath;
private $directorySeparator = '/';








public function __construct($path, $flags, $ignoreUnreadableDirs = false)
{
if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
throw new \RuntimeException('This iterator only support returning current as fileinfo.');
}

parent::__construct($path, $flags);
$this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
$this->rootPath = (string) $path;
if ('/' !== \DIRECTORY_SEPARATOR && !($flags & self::UNIX_PATHS)) {
$this->directorySeparator = \DIRECTORY_SEPARATOR;
}
}






public function current()
{


if (null === $subPathname = $this->subPath) {
$subPathname = $this->subPath = (string) $this->getSubPath();
}
if ('' !== $subPathname) {
$subPathname .= $this->directorySeparator;
}
$subPathname .= $this->getFilename();

return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
}






public function getChildren()
{
try {
$children = parent::getChildren();

if ($children instanceof self) {

$children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;


$children->rewindable = &$this->rewindable;
$children->rootPath = $this->rootPath;
}

return $children;
} catch (\UnexpectedValueException $e) {
if ($this->ignoreUnreadableDirs) {

return new \RecursiveArrayIterator(array());
} else {
throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
}
}
}




public function rewind()
{
if (false === $this->isRewindable()) {
return;
}


if (\PHP_VERSION_ID < 50523 || \PHP_VERSION_ID >= 50600 && \PHP_VERSION_ID < 50607) {
parent::next();
}

parent::rewind();
}






public function isRewindable()
{
if (null !== $this->rewindable) {
return $this->rewindable;
}


if ('' === $this->getPath()) {
return $this->rewindable = false;
}

if (false !== $stream = @opendir($this->getPath())) {
$infos = stream_get_meta_data($stream);
closedir($stream);

if ($infos['seekable']) {
return $this->rewindable = true;
}
}

return $this->rewindable = false;
}
}
<?php










namespace Symfony\Component\Finder\Iterator;

use Symfony\Component\Finder\Comparator\NumberComparator;






class SizeRangeFilterIterator extends FilterIterator
{
private $comparators = array();





public function __construct(\Iterator $iterator, array $comparators)
{
$this->comparators = $comparators;

parent::__construct($iterator);
}






public function accept()
{
$fileinfo = $this->current();
if (!$fileinfo->isFile()) {
return true;
}

$filesize = $fileinfo->getSize();
foreach ($this->comparators as $compare) {
if (!$compare->test($filesize)) {
return false;
}
}

return true;
}
}
<?php










namespace Symfony\Component\Finder\Iterator;









abstract class FilterIterator extends \FilterIterator
{






public function rewind()
{
if (\PHP_VERSION_ID > 50607 || (\PHP_VERSION_ID > 50523 && \PHP_VERSION_ID < 50600)) {
parent::rewind();

return;
}

$iterator = $this;
while ($iterator instanceof \OuterIterator) {
$innerIterator = $iterator->getInnerIterator();

if ($innerIterator instanceof RecursiveDirectoryIterator) {

if ($innerIterator->isRewindable()) {
$innerIterator->next();
$innerIterator->rewind();
}
} elseif ($innerIterator instanceof \FilesystemIterator) {
$innerIterator->next();
$innerIterator->rewind();
}

$iterator = $innerIterator;
}

parent::rewind();
}
}
<?php










namespace Symfony\Component\Finder\Iterator;







class FilecontentFilterIterator extends MultiplePcreFilterIterator
{





public function accept()
{
if (!$this->matchRegexps && !$this->noMatchRegexps) {
return true;
}

$fileinfo = $this->current();

if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
return false;
}

$content = $fileinfo->getContents();
if (!$content) {
return false;
}

return $this->isAccepted($content);
}








protected function toRegex($str)
{
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
}
}
<?php










namespace Symfony\Component\Finder\Iterator;






class FileTypeFilterIterator extends FilterIterator
{
const ONLY_FILES = 1;
const ONLY_DIRECTORIES = 2;

private $mode;





public function __construct(\Iterator $iterator, $mode)
{
$this->mode = $mode;

parent::__construct($iterator);
}






public function accept()
{
$fileinfo = $this->current();
if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
return false;
} elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
return false;
}

return true;
}
}
Copyright (c) 2004-2018 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php










namespace Symfony\Component\Finder;

use Symfony\Component\Finder\Adapter\AdapterInterface;
use Symfony\Component\Finder\Adapter\BsdFindAdapter;
use Symfony\Component\Finder\Adapter\GnuFindAdapter;
use Symfony\Component\Finder\Adapter\PhpAdapter;
use Symfony\Component\Finder\Comparator\DateComparator;
use Symfony\Component\Finder\Comparator\NumberComparator;
use Symfony\Component\Finder\Exception\ExceptionInterface;
use Symfony\Component\Finder\Iterator\CustomFilterIterator;
use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
use Symfony\Component\Finder\Iterator\SortableIterator;














class Finder implements \IteratorAggregate, \Countable
{
const IGNORE_VCS_FILES = 1;
const IGNORE_DOT_FILES = 2;

private $mode = 0;
private $names = array();
private $notNames = array();
private $exclude = array();
private $filters = array();
private $depths = array();
private $sizes = array();
private $followLinks = false;
private $sort = false;
private $ignore = 0;
private $dirs = array();
private $dates = array();
private $iterators = array();
private $contains = array();
private $notContains = array();
private $adapters = null;
private $paths = array();
private $notPaths = array();
private $ignoreUnreadableDirs = false;

private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');

public function __construct()
{
$this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
}






public static function create()
{
return new static();
}











public function addAdapter(AdapterInterface $adapter, $priority = 0)
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

$this->initDefaultAdapters();

$this->adapters[$adapter->getName()] = array(
'adapter' => $adapter,
'priority' => $priority,
'selected' => false,
);

return $this->sortAdapters();
}








public function useBestAdapter()
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

$this->initDefaultAdapters();

$this->resetAdapterSelection();

return $this->sortAdapters();
}












public function setAdapter($name)
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

$this->initDefaultAdapters();

if (!isset($this->adapters[$name])) {
throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
}

$this->resetAdapterSelection();
$this->adapters[$name]['selected'] = true;

return $this->sortAdapters();
}








public function removeAdapters()
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

$this->adapters = array();

return $this;
}








public function getAdapters()
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

$this->initDefaultAdapters();

return array_values(array_map(function (array $adapter) {
return $adapter['adapter'];
}, $this->adapters));
}






public function directories()
{
$this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;

return $this;
}






public function files()
{
$this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;

return $this;
}
















public function depth($level)
{
$this->depths[] = new Comparator\NumberComparator($level);

return $this;
}



















public function date($date)
{
$this->dates[] = new Comparator\DateComparator($date);

return $this;
}
















public function name($pattern)
{
$this->names[] = $pattern;

return $this;
}










public function notName($pattern)
{
$this->notNames[] = $pattern;

return $this;
}















public function contains($pattern)
{
$this->contains[] = $pattern;

return $this;
}















public function notContains($pattern)
{
$this->notContains[] = $pattern;

return $this;
}

















public function path($pattern)
{
$this->paths[] = $pattern;

return $this;
}

















public function notPath($pattern)
{
$this->notPaths[] = $pattern;

return $this;
}















public function size($size)
{
$this->sizes[] = new Comparator\NumberComparator($size);

return $this;
}














public function exclude($dirs)
{
$this->exclude = array_merge($this->exclude, (array) $dirs);

return $this;
}












public function ignoreDotFiles($ignoreDotFiles)
{
if ($ignoreDotFiles) {
$this->ignore |= static::IGNORE_DOT_FILES;
} else {
$this->ignore &= ~static::IGNORE_DOT_FILES;
}

return $this;
}












public function ignoreVCS($ignoreVCS)
{
if ($ignoreVCS) {
$this->ignore |= static::IGNORE_VCS_FILES;
} else {
$this->ignore &= ~static::IGNORE_VCS_FILES;
}

return $this;
}








public static function addVCSPattern($pattern)
{
foreach ((array) $pattern as $p) {
self::$vcsPatterns[] = $p;
}

self::$vcsPatterns = array_unique(self::$vcsPatterns);
}












public function sort(\Closure $closure)
{
$this->sort = $closure;

return $this;
}










public function sortByName()
{
$this->sort = Iterator\SortableIterator::SORT_BY_NAME;

return $this;
}










public function sortByType()
{
$this->sort = Iterator\SortableIterator::SORT_BY_TYPE;

return $this;
}












public function sortByAccessedTime()
{
$this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;

return $this;
}














public function sortByChangedTime()
{
$this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;

return $this;
}












public function sortByModifiedTime()
{
$this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;

return $this;
}











public function filter(\Closure $closure)
{
$this->filters[] = $closure;

return $this;
}






public function followLinks()
{
$this->followLinks = true;

return $this;
}










public function ignoreUnreadableDirs($ignore = true)
{
$this->ignoreUnreadableDirs = (bool) $ignore;

return $this;
}










public function in($dirs)
{
$resolvedDirs = array();

foreach ((array) $dirs as $dir) {
if (is_dir($dir)) {
$resolvedDirs[] = $this->normalizeDir($dir);
} elseif ($glob = glob($dir, (\defined('GLOB_BRACE') ? GLOB_BRACE : 0) | GLOB_ONLYDIR)) {
$resolvedDirs = array_merge($resolvedDirs, array_map(array($this, 'normalizeDir'), $glob));
} else {
throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
}
}

$this->dirs = array_merge($this->dirs, $resolvedDirs);

return $this;
}










public function getIterator()
{
if (0 === \count($this->dirs) && 0 === \count($this->iterators)) {
throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
}

if (1 === \count($this->dirs) && 0 === \count($this->iterators)) {
return $this->searchInDirectory($this->dirs[0]);
}

$iterator = new \AppendIterator();
foreach ($this->dirs as $dir) {
$iterator->append($this->searchInDirectory($dir));
}

foreach ($this->iterators as $it) {
$iterator->append($it);
}

return $iterator;
}












public function append($iterator)
{
if ($iterator instanceof \IteratorAggregate) {
$this->iterators[] = $iterator->getIterator();
} elseif ($iterator instanceof \Iterator) {
$this->iterators[] = $iterator;
} elseif ($iterator instanceof \Traversable || \is_array($iterator)) {
$it = new \ArrayIterator();
foreach ($iterator as $file) {
$it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
}
$this->iterators[] = $it;
} else {
throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
}

return $this;
}






public function count()
{
return iterator_count($this->getIterator());
}




private function sortAdapters()
{
uasort($this->adapters, function (array $a, array $b) {
if ($a['selected'] || $b['selected']) {
return $a['selected'] ? -1 : 1;
}

return $a['priority'] > $b['priority'] ? -1 : 1;
});

return $this;
}






private function searchInDirectory($dir)
{
if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
$this->exclude = array_merge($this->exclude, self::$vcsPatterns);
}

if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
$this->notPaths[] = '#(^|/)\..+(/|$)#';
}

if ($this->adapters) {
foreach ($this->adapters as $adapter) {
if ($adapter['adapter']->isSupported()) {
try {
return $this
->buildAdapter($adapter['adapter'])
->searchInDirectory($dir);
} catch (ExceptionInterface $e) {
}
}
}
}

$minDepth = 0;
$maxDepth = PHP_INT_MAX;

foreach ($this->depths as $comparator) {
switch ($comparator->getOperator()) {
case '>':
$minDepth = $comparator->getTarget() + 1;
break;
case '>=':
$minDepth = $comparator->getTarget();
break;
case '<':
$maxDepth = $comparator->getTarget() - 1;
break;
case '<=':
$maxDepth = $comparator->getTarget();
break;
default:
$minDepth = $maxDepth = $comparator->getTarget();
}
}

$flags = \RecursiveDirectoryIterator::SKIP_DOTS;

if ($this->followLinks) {
$flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
}

$iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);

if ($this->exclude) {
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
}

$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);

if ($minDepth > 0 || $maxDepth < PHP_INT_MAX) {
$iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth);
}

if ($this->mode) {
$iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
}

if ($this->names || $this->notNames) {
$iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
}

if ($this->contains || $this->notContains) {
$iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
}

if ($this->sizes) {
$iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
}

if ($this->dates) {
$iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
}

if ($this->filters) {
$iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
}

if ($this->paths || $this->notPaths) {
$iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
}

if ($this->sort) {
$iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
$iterator = $iteratorAggregate->getIterator();
}

return $iterator;
}




private function buildAdapter(AdapterInterface $adapter)
{
return $adapter
->setFollowLinks($this->followLinks)
->setDepths($this->depths)
->setMode($this->mode)
->setExclude($this->exclude)
->setNames($this->names)
->setNotNames($this->notNames)
->setContains($this->contains)
->setNotContains($this->notContains)
->setSizes($this->sizes)
->setDates($this->dates)
->setFilters($this->filters)
->setSort($this->sort)
->setPath($this->paths)
->setNotPath($this->notPaths)
->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
}




private function resetAdapterSelection()
{
$this->adapters = array_map(function (array $properties) {
$properties['selected'] = false;

return $properties;
}, $this->adapters);
}

private function initDefaultAdapters()
{
if (null === $this->adapters) {
$this->adapters = array();
$this
->addAdapter(new GnuFindAdapter())
->addAdapter(new BsdFindAdapter())
->addAdapter(new PhpAdapter(), -50)
->setAdapter('php')
;
}
}








private function normalizeDir($dir)
{
return rtrim($dir, '/'.\DIRECTORY_SEPARATOR);
}
}
<?php










namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\Regex class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);




class Regex implements ValueInterface
{
const START_FLAG = '^';
const END_FLAG = '$';
const BOUNDARY = '~';
const JOKER = '.*';
const ESCAPING = '\\';




private $pattern;




private $options;




private $startFlag;




private $endFlag;




private $startJoker;




private $endJoker;








public static function create($expr)
{
if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
$start = substr($m[1], 0, 1);
$end = substr($m[1], -1);

if (
($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
|| ('{' === $start && '}' === $end)
|| ('(' === $start && ')' === $end)
) {
return new self(substr($m[1], 1, -1), $m[2], $end);
}
}

throw new \InvalidArgumentException('Given expression is not a regex.');
}






public function __construct($pattern, $options = '', $delimiter = null)
{
if (null !== $delimiter) {

$pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
}

$this->parsePattern($pattern);
$this->options = $options;
}




public function __toString()
{
return $this->render();
}




public function render()
{
return self::BOUNDARY
.$this->renderPattern()
.self::BOUNDARY
.$this->options;
}




public function renderPattern()
{
return ($this->startFlag ? self::START_FLAG : '')
.($this->startJoker ? self::JOKER : '')
.str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
.($this->endJoker ? self::JOKER : '')
.($this->endFlag ? self::END_FLAG : '');
}




public function isCaseSensitive()
{
return !$this->hasOption('i');
}




public function getType()
{
return Expression::TYPE_REGEX;
}




public function prepend($expr)
{
$this->pattern = $expr.$this->pattern;

return $this;
}




public function append($expr)
{
$this->pattern .= $expr;

return $this;
}






public function hasOption($option)
{
return false !== strpos($this->options, $option);
}






public function addOption($option)
{
if (!$this->hasOption($option)) {
$this->options .= $option;
}

return $this;
}






public function removeOption($option)
{
$this->options = str_replace($option, '', $this->options);

return $this;
}






public function setStartFlag($startFlag)
{
$this->startFlag = $startFlag;

return $this;
}




public function hasStartFlag()
{
return $this->startFlag;
}






public function setEndFlag($endFlag)
{
$this->endFlag = (bool) $endFlag;

return $this;
}




public function hasEndFlag()
{
return $this->endFlag;
}






public function setStartJoker($startJoker)
{
$this->startJoker = $startJoker;

return $this;
}




public function hasStartJoker()
{
return $this->startJoker;
}






public function setEndJoker($endJoker)
{
$this->endJoker = (bool) $endJoker;

return $this;
}




public function hasEndJoker()
{
return $this->endJoker;
}




public function replaceJokers($replacement)
{
$replace = function ($subject) use ($replacement) {
$subject = $subject[0];
$replace = 0 === substr_count($subject, '\\') % 2;

return $replace ? str_replace('.', $replacement, $subject) : $subject;
};

$this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);

return $this;
}




private function parsePattern($pattern)
{
if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
$pattern = substr($pattern, 1);
}

if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
$pattern = substr($pattern, 2);
}

if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
$pattern = substr($pattern, 0, -1);
}

if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
$pattern = substr($pattern, 0, -2);
}

$this->pattern = $pattern;
}
}
<?php










namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\Expression class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);




class Expression implements ValueInterface
{
const TYPE_REGEX = 1;
const TYPE_GLOB = 2;




private $value;






public static function create($expr)
{
return new self($expr);
}




public function __construct($expr)
{
try {
$this->value = Regex::create($expr);
} catch (\InvalidArgumentException $e) {
$this->value = new Glob($expr);
}
}




public function __toString()
{
return $this->render();
}




public function render()
{
return $this->value->render();
}




public function renderPattern()
{
return $this->value->renderPattern();
}




public function isCaseSensitive()
{
return $this->value->isCaseSensitive();
}




public function getType()
{
return $this->value->getType();
}




public function prepend($expr)
{
$this->value->prepend($expr);

return $this;
}




public function append($expr)
{
$this->value->append($expr);

return $this;
}




public function isRegex()
{
return self::TYPE_REGEX === $this->value->getType();
}




public function isGlob()
{
return self::TYPE_GLOB === $this->value->getType();
}






public function getGlob()
{
if (self::TYPE_GLOB !== $this->value->getType()) {
throw new \LogicException('Regex can\'t be transformed to glob.');
}

return $this->value;
}




public function getRegex()
{
return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
}
}
<?php










namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\ValueInterface interface is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);




interface ValueInterface
{





public function render();






public function renderPattern();






public function isCaseSensitive();






public function getType();






public function prepend($expr);






public function append($expr);
}
<?php










namespace Symfony\Component\Finder\Expression;

@trigger_error('The '.__NAMESPACE__.'\Glob class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Glob as FinderGlob;




class Glob implements ValueInterface
{
private $pattern;




public function __construct($pattern)
{
$this->pattern = $pattern;
}




public function render()
{
return $this->pattern;
}




public function renderPattern()
{
return $this->pattern;
}




public function getType()
{
return Expression::TYPE_GLOB;
}




public function isCaseSensitive()
{
return true;
}




public function prepend($expr)
{
$this->pattern = $expr.$this->pattern;

return $this;
}




public function append($expr)
{
$this->pattern .= $expr;

return $this;
}






public function isExpandable()
{
return false !== strpos($this->pattern, '{')
&& false !== strpos($this->pattern, '}');
}







public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
{
$regex = FinderGlob::toRegex($this->pattern, $strictLeadingDot, $strictWildcardSlash, '');

return new Regex($regex);
}
}
<?php










namespace Symfony\Component\Finder\Shell;

@trigger_error('The '.__NAMESPACE__.'\Command class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);






class Command
{
private $parent;
private $bits = array();
private $labels = array();




private $errorHandler;

public function __construct(Command $parent = null)
{
$this->parent = $parent;
}






public function __toString()
{
return $this->join();
}






public static function create(Command $parent = null)
{
return new self($parent);
}








public static function escape($input)
{
return escapeshellcmd($input);
}








public static function quote($input)
{
return escapeshellarg($input);
}








public function add($bit)
{
$this->bits[] = $bit;

return $this;
}








public function top($bit)
{
array_unshift($this->bits, $bit);

foreach ($this->labels as $label => $index) {
++$this->labels[$label];
}

return $this;
}








public function arg($arg)
{
$this->bits[] = self::quote($arg);

return $this;
}








public function cmd($esc)
{
$this->bits[] = self::escape($esc);

return $this;
}










public function ins($label)
{
if (isset($this->labels[$label])) {
throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
}

$this->bits[] = self::create($this);
$this->labels[$label] = \count($this->bits) - 1;

return $this->bits[$this->labels[$label]];
}










public function get($label)
{
if (!isset($this->labels[$label])) {
throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
}

return $this->bits[$this->labels[$label]];
}








public function end()
{
if (null === $this->parent) {
throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
}

return $this->parent;
}






public function length()
{
return \count($this->bits);
}




public function setErrorHandler(\Closure $errorHandler)
{
$this->errorHandler = $errorHandler;

return $this;
}




public function getErrorHandler()
{
return $this->errorHandler;
}








public function execute()
{
if (null === $errorHandler = $this->errorHandler) {
exec($this->join(), $output);
} else {
$process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
$output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);

if ($error = stream_get_contents($pipes[2])) {
$errorHandler($error);
}

proc_close($process);
}

return $output ?: array();
}






public function join()
{
return implode(' ', array_filter(
array_map(function ($bit) {
return $bit instanceof Command ? $bit->join() : ($bit ?: null);
}, $this->bits),
function ($bit) { return null !== $bit; }
));
}









public function addAtIndex($bit, $index)
{
array_splice($this->bits, $index, 0, $bit instanceof self ? array($bit) : $bit);

return $this;
}
}
<?php










namespace Symfony\Component\Finder\Shell;

@trigger_error('The '.__NAMESPACE__.'\Shell class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);






class Shell
{
const TYPE_UNIX = 1;
const TYPE_DARWIN = 2;
const TYPE_CYGWIN = 3;
const TYPE_WINDOWS = 4;
const TYPE_BSD = 5;




private $type;






public function getType()
{
if (null === $this->type) {
$this->type = $this->guessType();
}

return $this->type;
}








public function testCommand($command)
{
if (!\function_exists('exec')) {
return false;
}


$testCommand = 'which ';
if (self::TYPE_WINDOWS === $this->type) {
$testCommand = 'where ';
}

$command = escapeshellcmd($command);

exec($testCommand.$command, $output, $code);

return 0 === $code && \count($output) > 0;
}






private function guessType()
{
$os = strtolower(PHP_OS);

if (false !== strpos($os, 'cygwin')) {
return self::TYPE_CYGWIN;
}

if (false !== strpos($os, 'darwin')) {
return self::TYPE_DARWIN;
}

if (false !== strpos($os, 'bsd')) {
return self::TYPE_BSD;
}

if (0 === strpos($os, 'win')) {
return self::TYPE_WINDOWS;
}

return self::TYPE_UNIX;
}
}
<?php










namespace Symfony\Component\Finder\Comparator;






















class NumberComparator extends Comparator
{





public function __construct($test)
{
if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test));
}

$target = $matches[2];
if (!is_numeric($target)) {
throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
}
if (isset($matches[3])) {

switch (strtolower($matches[3])) {
case 'k':
$target *= 1000;
break;
case 'ki':
$target *= 1024;
break;
case 'm':
$target *= 1000000;
break;
case 'mi':
$target *= 1024 * 1024;
break;
case 'g':
$target *= 1000000000;
break;
case 'gi':
$target *= 1024 * 1024 * 1024;
break;
}
}

$this->setTarget($target);
$this->setOperator(isset($matches[1]) ? $matches[1] : '==');
}
}
<?php










namespace Symfony\Component\Finder\Comparator;






class DateComparator extends Comparator
{





public function __construct($test)
{
if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
}

try {
$date = new \DateTime($matches[2]);
$target = $date->format('U');
} catch (\Exception $e) {
throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
}

$operator = isset($matches[1]) ? $matches[1] : '==';
if ('since' === $operator || 'after' === $operator) {
$operator = '>';
}

if ('until' === $operator || 'before' === $operator) {
$operator = '<';
}

$this->setOperator($operator);
$this->setTarget($target);
}
}
<?php










namespace Symfony\Component\Finder\Comparator;






class Comparator
{
private $target;
private $operator = '==';






public function getTarget()
{
return $this->target;
}






public function setTarget($target)
{
$this->target = $target;
}






public function getOperator()
{
return $this->operator;
}








public function setOperator($operator)
{
if (!$operator) {
$operator = '==';
}

if (!\in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) {
throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
}

$this->operator = $operator;
}








public function test($test)
{
switch ($this->operator) {
case '>':
return $test > $this->target;
case '>=':
return $test >= $this->target;
case '<':
return $test < $this->target;
case '<=':
return $test <= $this->target;
case '!=':
return $test != $this->target;
}

return $test == $this->target;
}
}
<?php










namespace Symfony\Component\Finder;






class SplFileInfo extends \SplFileInfo
{
private $relativePath;
private $relativePathname;






public function __construct($file, $relativePath, $relativePathname)
{
parent::__construct($file);
$this->relativePath = $relativePath;
$this->relativePathname = $relativePathname;
}








public function getRelativePath()
{
return $this->relativePath;
}








public function getRelativePathname()
{
return $this->relativePathname;
}








public function getContents()
{
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
$content = file_get_contents($this->getPathname());
restore_error_handler();
if (false === $content) {
throw new \RuntimeException($error);
}

return $content;
}
}
<?php










namespace Symfony\Component\Finder\Adapter;






interface AdapterInterface
{





public function setFollowLinks($followLinks);






public function setMode($mode);




public function setExclude(array $exclude);




public function setDepths(array $depths);




public function setNames(array $names);




public function setNotNames(array $notNames);




public function setContains(array $contains);




public function setNotContains(array $notContains);




public function setSizes(array $sizes);




public function setDates(array $dates);




public function setFilters(array $filters);






public function setSort($sort);




public function setPath(array $paths);




public function setNotPath(array $notPaths);






public function ignoreUnreadableDirs($ignore = true);






public function searchInDirectory($dir);






public function isSupported();






public function getName();
}
<?php










namespace Symfony\Component\Finder\Adapter;

@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);








abstract class AbstractAdapter implements AdapterInterface
{
protected $followLinks = false;
protected $mode = 0;
protected $minDepth = 0;
protected $maxDepth = PHP_INT_MAX;
protected $exclude = array();
protected $names = array();
protected $notNames = array();
protected $contains = array();
protected $notContains = array();
protected $sizes = array();
protected $dates = array();
protected $filters = array();
protected $sort = false;
protected $paths = array();
protected $notPaths = array();
protected $ignoreUnreadableDirs = false;

private static $areSupported = array();




public function isSupported()
{
$name = $this->getName();

if (!array_key_exists($name, self::$areSupported)) {
self::$areSupported[$name] = $this->canBeUsed();
}

return self::$areSupported[$name];
}




public function setFollowLinks($followLinks)
{
$this->followLinks = $followLinks;

return $this;
}




public function setMode($mode)
{
$this->mode = $mode;

return $this;
}




public function setDepths(array $depths)
{
$this->minDepth = 0;
$this->maxDepth = PHP_INT_MAX;

foreach ($depths as $comparator) {
switch ($comparator->getOperator()) {
case '>':
$this->minDepth = $comparator->getTarget() + 1;
break;
case '>=':
$this->minDepth = $comparator->getTarget();
break;
case '<':
$this->maxDepth = $comparator->getTarget() - 1;
break;
case '<=':
$this->maxDepth = $comparator->getTarget();
break;
default:
$this->minDepth = $this->maxDepth = $comparator->getTarget();
}
}

return $this;
}




public function setExclude(array $exclude)
{
$this->exclude = $exclude;

return $this;
}




public function setNames(array $names)
{
$this->names = $names;

return $this;
}




public function setNotNames(array $notNames)
{
$this->notNames = $notNames;

return $this;
}




public function setContains(array $contains)
{
$this->contains = $contains;

return $this;
}




public function setNotContains(array $notContains)
{
$this->notContains = $notContains;

return $this;
}




public function setSizes(array $sizes)
{
$this->sizes = $sizes;

return $this;
}




public function setDates(array $dates)
{
$this->dates = $dates;

return $this;
}




public function setFilters(array $filters)
{
$this->filters = $filters;

return $this;
}




public function setSort($sort)
{
$this->sort = $sort;

return $this;
}




public function setPath(array $paths)
{
$this->paths = $paths;

return $this;
}




public function setNotPath(array $notPaths)
{
$this->notPaths = $notPaths;

return $this;
}




public function ignoreUnreadableDirs($ignore = true)
{
$this->ignoreUnreadableDirs = (bool) $ignore;

return $this;
}












abstract protected function canBeUsed();
}
<?php










namespace Symfony\Component\Finder\Adapter;

@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);

use Symfony\Component\Finder\Comparator\DateComparator;
use Symfony\Component\Finder\Comparator\NumberComparator;
use Symfony\Component\Finder\Exception\AccessDeniedException;
use Symfony\Component\Finder\Expression\Expression;
use Symfony\Component\Finder\Iterator;
use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\Finder\Shell\Shell;








abstract class AbstractFindAdapter extends AbstractAdapter
{
protected $shell;

public function __construct()
{
$this->shell = new Shell();
}




public function searchInDirectory($dir)
{

$dir = realpath($dir);


if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
return new Iterator\FilePathsIterator(array(), $dir);
}

$command = Command::create();
$find = $this->buildFindCommand($command, $dir);

if ($this->followLinks) {
$find->add('-follow');
}

$find->add('-mindepth')->add($this->minDepth + 1);

if (PHP_INT_MAX !== $this->maxDepth) {
$find->add('-maxdepth')->add($this->maxDepth + 1);
}

if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
$find->add('-type d');
} elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
$find->add('-type f');
}

$this->buildNamesFiltering($find, $this->names);
$this->buildNamesFiltering($find, $this->notNames, true);
$this->buildPathsFiltering($find, $dir, $this->paths);
$this->buildPathsFiltering($find, $dir, $this->notPaths, true);
$this->buildSizesFiltering($find, $this->sizes);
$this->buildDatesFiltering($find, $this->dates);

$useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
$useSort = \is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');

if ($useGrep && ($this->contains || $this->notContains)) {
$grep = $command->ins('grep');
$this->buildContentFiltering($grep, $this->contains);
$this->buildContentFiltering($grep, $this->notContains, true);
}

if ($useSort) {
$this->buildSorting($command, $this->sort);
}

$command->setErrorHandler(
$this->ignoreUnreadableDirs

? function ($stderr) { }
: function ($stderr) { throw new AccessDeniedException($stderr); }
);

$paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
$iterator = new Iterator\FilePathsIterator($paths, $dir);

if ($this->exclude) {
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
}

if (!$useGrep && ($this->contains || $this->notContains)) {
$iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
}

if ($this->filters) {
$iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
}

if (!$useSort && $this->sort) {
$iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
$iterator = $iteratorAggregate->getIterator();
}

return $iterator;
}




protected function canBeUsed()
{
return $this->shell->testCommand('find');
}







protected function buildFindCommand(Command $command, $dir)
{
return $command
->ins('find')
->add('find ')
->arg($dir)
->add('-noleaf'); 
}






private function buildNamesFiltering(Command $command, array $names, $not = false)
{
if (0 === \count($names)) {
return;
}

$command->add($not ? '-not' : null)->cmd('(');

foreach ($names as $i => $name) {
$expr = Expression::create($name);


if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
$expr = Expression::create($expr->getGlob()->toRegex(false));
}




if ($expr->isRegex()) {
$regex = $expr->getRegex();
$regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
->setStartFlag(false)
->setStartJoker(true)
->replaceJokers('[^/]');
if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
$regex->setEndJoker(false)->append('[^/]*');
}
}

$command
->add($i > 0 ? '-or' : null)
->add($expr->isRegex()
? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
: ($expr->isCaseSensitive() ? '-name' : '-iname')
)
->arg($expr->renderPattern());
}

$command->cmd(')');
}







private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
{
if (0 === \count($paths)) {
return;
}

$command->add($not ? '-not' : null)->cmd('(');

foreach ($paths as $i => $path) {
$expr = Expression::create($path);


if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
$expr = Expression::create($expr->getGlob()->toRegex(false));
}


if ($expr->isRegex()) {
$regex = $expr->getRegex();
$regex->prepend($regex->hasStartFlag() ? preg_quote($dir).\DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
} else {
$expr->prepend('*')->append('*');
}

$command
->add($i > 0 ? '-or' : null)
->add($expr->isRegex()
? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
: ($expr->isCaseSensitive() ? '-path' : '-ipath')
)
->arg($expr->renderPattern());
}

$command->cmd(')');
}





private function buildSizesFiltering(Command $command, array $sizes)
{
foreach ($sizes as $i => $size) {
$command->add($i > 0 ? '-and' : null);

switch ($size->getOperator()) {
case '<=':
$command->add('-size -'.($size->getTarget() + 1).'c');
break;
case '>=':
$command->add('-size +'.($size->getTarget() - 1).'c');
break;
case '>':
$command->add('-size +'.$size->getTarget().'c');
break;
case '!=':
$command->add('-size -'.$size->getTarget().'c');
$command->add('-size +'.$size->getTarget().'c');
break;
case '<':
default:
$command->add('-size -'.$size->getTarget().'c');
}
}
}





private function buildDatesFiltering(Command $command, array $dates)
{
foreach ($dates as $i => $date) {
$command->add($i > 0 ? '-and' : null);

$mins = (int) round((time() - $date->getTarget()) / 60);

if (0 > $mins) {

$command->add(' -mmin -0');

return;
}

switch ($date->getOperator()) {
case '<=':
$command->add('-mmin +'.($mins - 1));
break;
case '>=':
$command->add('-mmin -'.($mins + 1));
break;
case '>':
$command->add('-mmin -'.$mins);
break;
case '!=':
$command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
break;
case '<':
default:
$command->add('-mmin +'.$mins);
}
}
}







private function buildSorting(Command $command, $sort)
{
$this->buildFormatSorting($command, $sort);
}





abstract protected function buildFormatSorting(Command $command, $sort);






abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
}
<?php










namespace Symfony\Component\Finder\Adapter;

@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);

use Symfony\Component\Finder\Iterator;








class PhpAdapter extends AbstractAdapter
{



public function searchInDirectory($dir)
{
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;

if ($this->followLinks) {
$flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
}

$iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs);

if ($this->exclude) {
$iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
}

$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);

if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
$iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
}

if ($this->mode) {
$iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
}

if ($this->names || $this->notNames) {
$iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
}

if ($this->contains || $this->notContains) {
$iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
}

if ($this->sizes) {
$iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
}

if ($this->dates) {
$iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
}

if ($this->filters) {
$iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
}

if ($this->paths || $this->notPaths) {
$iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
}

if ($this->sort) {
$iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
$iterator = $iteratorAggregate->getIterator();
}

return $iterator;
}




public function getName()
{
return 'php';
}




protected function canBeUsed()
{
return true;
}
}
<?php










namespace Symfony\Component\Finder\Adapter;

@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);

use Symfony\Component\Finder\Expression\Expression;
use Symfony\Component\Finder\Iterator\SortableIterator;
use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\Finder\Shell\Shell;








class GnuFindAdapter extends AbstractFindAdapter
{



public function getName()
{
return 'gnu_find';
}




protected function buildFormatSorting(Command $command, $sort)
{
switch ($sort) {
case SortableIterator::SORT_BY_NAME:
$command->ins('sort')->add('| sort');

return;
case SortableIterator::SORT_BY_TYPE:
$format = '%y';
break;
case SortableIterator::SORT_BY_ACCESSED_TIME:
$format = '%A@';
break;
case SortableIterator::SORT_BY_CHANGED_TIME:
$format = '%C@';
break;
case SortableIterator::SORT_BY_MODIFIED_TIME:
$format = '%T@';
break;
default:
throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
}

$command
->get('find')
->add('-printf')
->arg($format.' %h/%f\\n')
->add('| sort | cut')
->arg('-d ')
->arg('-f2-')
;
}




protected function canBeUsed()
{
return Shell::TYPE_UNIX === $this->shell->getType() && parent::canBeUsed();
}




protected function buildFindCommand(Command $command, $dir)
{
return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
}




protected function buildContentFiltering(Command $command, array $contains, $not = false)
{
foreach ($contains as $contain) {
$expr = Expression::create($contain);


$command
->add('| xargs -I{} -r grep -I')
->add($expr->isCaseSensitive() ? null : '-i')
->add($not ? '-L' : '-l')
->add('-Ee')->arg($expr->renderPattern())
->add('{}')
;
}
}
}
<?php










namespace Symfony\Component\Finder\Adapter;

@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);

use Symfony\Component\Finder\Expression\Expression;
use Symfony\Component\Finder\Iterator\SortableIterator;
use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\Finder\Shell\Shell;








class BsdFindAdapter extends AbstractFindAdapter
{



public function getName()
{
return 'bsd_find';
}




protected function canBeUsed()
{
return \in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
}




protected function buildFormatSorting(Command $command, $sort)
{
switch ($sort) {
case SortableIterator::SORT_BY_NAME:
$command->ins('sort')->add('| sort');

return;
case SortableIterator::SORT_BY_TYPE:
$format = '%HT';
break;
case SortableIterator::SORT_BY_ACCESSED_TIME:
$format = '%a';
break;
case SortableIterator::SORT_BY_CHANGED_TIME:
$format = '%c';
break;
case SortableIterator::SORT_BY_MODIFIED_TIME:
$format = '%m';
break;
default:
throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
}

$command
->add('-print0 | xargs -0 stat -f')
->arg($format.'%t%N')
->add('| sort | cut -f 2');
}




protected function buildFindCommand(Command $command, $dir)
{
parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);

return $command;
}




protected function buildContentFiltering(Command $command, array $contains, $not = false)
{
foreach ($contains as $contain) {
$expr = Expression::create($contain);


$command
->add('| grep -v \'^$\'')
->add('| xargs -I{} grep -I')
->add($expr->isCaseSensitive() ? null : '-i')
->add($not ? '-L' : '-l')
->add('-Ee')->arg($expr->renderPattern())
->add('{}')
;
}
}
}
<?php










namespace Symfony\Component\Finder;























class Glob
{










public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true, $delimiter = '#')
{
$firstByte = true;
$escaping = false;
$inCurlies = 0;
$regex = '';
$sizeGlob = \strlen($glob);
for ($i = 0; $i < $sizeGlob; ++$i) {
$car = $glob[$i];
if ($firstByte) {
if ($strictLeadingDot && '.' !== $car) {
$regex .= '(?=[^\.])';
}

$firstByte = false;
}

if ('/' === $car) {
$firstByte = true;
}

if ($delimiter === $car || '.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
$regex .= "\\$car";
} elseif ('*' === $car) {
$regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
} elseif ('?' === $car) {
$regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
} elseif ('{' === $car) {
$regex .= $escaping ? '\\{' : '(';
if (!$escaping) {
++$inCurlies;
}
} elseif ('}' === $car && $inCurlies) {
$regex .= $escaping ? '}' : ')';
if (!$escaping) {
--$inCurlies;
}
} elseif (',' === $car && $inCurlies) {
$regex .= $escaping ? ',' : '|';
} elseif ('\\' === $car) {
if ($escaping) {
$regex .= '\\\\';
$escaping = false;
} else {
$escaping = true;
}

continue;
} else {
$regex .= $car;
}
$escaping = false;
}

return $delimiter.'^'.$regex.'$'.$delimiter;
}
}
<?php










namespace Symfony\Component\Finder\Exception;

@trigger_error('The '.__NAMESPACE__.'\OperationNotPermitedException class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);






class OperationNotPermitedException extends AdapterFailureException
{
}
<?php










namespace Symfony\Component\Finder\Exception;

@trigger_error('The '.__NAMESPACE__.'\AdapterFailureException class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Adapter\AdapterInterface;








class AdapterFailureException extends \RuntimeException implements ExceptionInterface
{
private $adapter;






public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
{
$this->adapter = $adapter;
parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
}




public function getAdapter()
{
return $this->adapter;
}
}
<?php










namespace Symfony\Component\Finder\Exception;




interface ExceptionInterface
{



public function getAdapter();
}
<?php










namespace Symfony\Component\Finder\Exception;

@trigger_error('The '.__NAMESPACE__.'\ShellCommandFailureException class is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);

use Symfony\Component\Finder\Adapter\AdapterInterface;
use Symfony\Component\Finder\Shell\Command;






class ShellCommandFailureException extends AdapterFailureException
{
private $command;

public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
{
$this->command = $command;
parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
}




public function getCommand()
{
return $this->command;
}
}
<?php










namespace Symfony\Component\Finder\Exception;




class AccessDeniedException extends \UnexpectedValueException
{
}
Copyright (c) 2009-2021 by the Twig Team.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of Twig nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<?php

use Twig\TwigFilter;

class_exists('Twig\TwigFilter');

if (\false) {
class Twig_SimpleFilter extends TwigFilter
{
}
}
<?php

use Twig\Cache\CacheInterface;

class_exists('Twig\Cache\CacheInterface');

if (\false) {
class Twig_CacheInterface extends CacheInterface
{
}
}
<?php

use Twig\RuntimeLoader\FactoryRuntimeLoader;

class_exists('Twig\RuntimeLoader\FactoryRuntimeLoader');

if (\false) {
class Twig_FactoryRuntimeLoader extends FactoryRuntimeLoader
{
}
}
<?php

use Twig\NodeTraverser;

class_exists('Twig\NodeTraverser');

if (\false) {
class Twig_NodeTraverser extends NodeTraverser
{
}
}
<?php

use Twig\Extension\ExtensionInterface;

class_exists('Twig\Extension\ExtensionInterface');

if (\false) {
class Twig_ExtensionInterface extends ExtensionInterface
{
}
}
<?php

use Twig\Sandbox\SecurityNotAllowedPropertyError;

class_exists('Twig\Sandbox\SecurityNotAllowedPropertyError');

if (\false) {
class Twig_Sandbox_SecurityNotAllowedPropertyError extends SecurityNotAllowedPropertyError
{
}
}
<?php

use Twig\Sandbox\SecurityPolicy;

class_exists('Twig\Sandbox\SecurityPolicy');

if (\false) {
class Twig_Sandbox_SecurityPolicy extends SecurityPolicy
{
}
}
<?php

use Twig\Sandbox\SecurityNotAllowedFunctionError;

class_exists('Twig\Sandbox\SecurityNotAllowedFunctionError');

if (\false) {
class Twig_Sandbox_SecurityNotAllowedFunctionError extends SecurityNotAllowedFunctionError
{
}
}
<?php

use Twig\Sandbox\SecurityNotAllowedFilterError;

class_exists('Twig\Sandbox\SecurityNotAllowedFilterError');

if (\false) {
class Twig_Sandbox_SecurityNotAllowedFilterError extends SecurityNotAllowedFilterError
{
}
}
<?php

use Twig\Sandbox\SecurityNotAllowedTagError;

class_exists('Twig\Sandbox\SecurityNotAllowedTagError');

if (\false) {
class Twig_Sandbox_SecurityNotAllowedTagError extends SecurityNotAllowedTagError
{
}
}
<?php

use Twig\Sandbox\SecurityError;

class_exists('Twig\Sandbox\SecurityError');

if (\false) {
class Twig_Sandbox_SecurityError extends SecurityError
{
}
}
<?php

use Twig\Sandbox\SecurityPolicyInterface;

class_exists('Twig\Sandbox\SecurityPolicyInterface');

if (\false) {
class Twig_Sandbox_SecurityPolicyInterface extends SecurityPolicyInterface
{
}
}
<?php

use Twig\Sandbox\SecurityNotAllowedMethodError;

class_exists('Twig\Sandbox\SecurityNotAllowedMethodError');

if (\false) {
class Twig_Sandbox_SecurityNotAllowedMethodError extends SecurityNotAllowedMethodError
{
}
}
<?php

use Twig\Extension\AbstractExtension;

class_exists('Twig\Extension\AbstractExtension');

if (\false) {
class Twig_Extension extends AbstractExtension
{
}
}
<?php

use Twig\Parser;

class_exists('Twig\Parser');

if (\false) {
class Twig_Parser extends Parser
{
}
}
<?php

use Twig\Loader\ExistsLoaderInterface;

class_exists('Twig\Loader\ExistsLoaderInterface');

if (\false) {
class Twig_ExistsLoaderInterface extends ExistsLoaderInterface
{
}
}
<?php

use Twig\Node\MacroNode;

class_exists('Twig\Node\MacroNode');

if (\false) {
class Twig_Node_Macro extends MacroNode
{
}
}
<?php

use Twig\Node\TextNode;

class_exists('Twig\Node\TextNode');

if (\false) {
class Twig_Node_Text extends TextNode
{
}
}
<?php

use Twig\Node\BodyNode;

class_exists('Twig\Node\BodyNode');

if (\false) {
class Twig_Node_Body extends BodyNode
{
}
}
<?php

use Twig\Node\SandboxNode;

class_exists('Twig\Node\SandboxNode');

if (\false) {
class Twig_Node_Sandbox extends SandboxNode
{
}
}
<?php

use Twig\Node\SandboxedPrintNode;

class_exists('Twig\Node\SandboxedPrintNode');

if (\false) {
class Twig_Node_SandboxedPrint extends SandboxedPrintNode
{
}
}
<?php

use Twig\Node\CheckSecurityNode;

class_exists('Twig\Node\CheckSecurityNode');

if (\false) {
class Twig_Node_CheckSecurity extends CheckSecurityNode
{
}
}
<?php










use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;

@trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', \E_USER_DEPRECATED);








class Twig_Node_Expression_ExtensionReference extends AbstractExpression
{
public function __construct($name, $lineno, $tag = null)
{
parent::__construct([], ['name' => $name], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->raw(sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
}
}
<?php

use Twig\Node\Expression\ArrayExpression;

class_exists('Twig\Node\Expression\ArrayExpression');

if (\false) {
class Twig_Node_Expression_Array extends ArrayExpression
{
}
}
<?php

use Twig\Node\Expression\Unary\PosUnary;

class_exists('Twig\Node\Expression\Unary\PosUnary');

if (\false) {
class Twig_Node_Expression_Unary_Pos extends PosUnary
{
}
}
<?php

use Twig\Node\Expression\Unary\NotUnary;

class_exists('Twig\Node\Expression\Unary\NotUnary');

if (\false) {
class Twig_Node_Expression_Unary_Not extends NotUnary
{
}
}
<?php

use Twig\Node\Expression\Unary\NegUnary;

class_exists('Twig\Node\Expression\Unary\NegUnary');

if (\false) {
class Twig_Node_Expression_Unary_Neg extends NegUnary
{
}
}
<?php

use Twig\Node\Expression\ConditionalExpression;

class_exists('Twig\Node\Expression\ConditionalExpression');

if (\false) {
class Twig_Node_Expression_Conditional extends ConditionalExpression
{
}
}
<?php

use Twig\Node\Expression\Binary\AbstractBinary;

class_exists('Twig\Node\Expression\Binary\AbstractBinary');

if (\false) {
class Twig_Node_Expression_Binary extends AbstractBinary
{
}
}
<?php

use Twig\Node\Expression\AssignNameExpression;

class_exists('Twig\Node\Expression\AssignNameExpression');

if (\false) {
class Twig_Node_Expression_AssignName extends AssignNameExpression
{
}
}
<?php

use Twig\Node\Expression\NameExpression;

class_exists('Twig\Node\Expression\NameExpression');

if (\false) {
class Twig_Node_Expression_Name extends NameExpression
{
}
}
<?php

use Twig\Node\Expression\Filter\DefaultFilter;

class_exists('Twig\Node\Expression\Filter\DefaultFilter');

if (\false) {
class Twig_Node_Expression_Filter_Default extends DefaultFilter
{
}
}
<?php

use Twig\Node\Expression\Binary\NotEqualBinary;

class_exists('Twig\Node\Expression\Binary\NotEqualBinary');

if (\false) {
class Twig_Node_Expression_Binary_NotEqual extends NotEqualBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\BitwiseOrBinary;

class_exists('Twig\Node\Expression\Binary\BitwiseOrBinary');

if (\false) {
class Twig_Node_Expression_Binary_BitwiseOr extends BitwiseOrBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\DivBinary;

class_exists('Twig\Node\Expression\Binary\DivBinary');

if (\false) {
class Twig_Node_Expression_Binary_Div extends DivBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\SubBinary;

class_exists('Twig\Node\Expression\Binary\SubBinary');

if (\false) {
class Twig_Node_Expression_Binary_Sub extends SubBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\ModBinary;

class_exists('Twig\Node\Expression\Binary\ModBinary');

if (\false) {
class Twig_Node_Expression_Binary_Mod extends ModBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\MulBinary;

class_exists('Twig\Node\Expression\Binary\MulBinary');

if (\false) {
class Twig_Node_Expression_Binary_Mul extends MulBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\OrBinary;

class_exists('Twig\Node\Expression\Binary\OrBinary');

if (\false) {
class Twig_Node_Expression_Binary_Or extends OrBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\EqualBinary;

class_exists('Twig\Node\Expression\Binary\EqualBinary');

if (\false) {
class Twig_Node_Expression_Binary_Equal extends EqualBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\FloorDivBinary;

class_exists('Twig\Node\Expression\Binary\FloorDivBinary');

if (\false) {
class Twig_Node_Expression_Binary_FloorDiv extends FloorDivBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\ConcatBinary;

class_exists('Twig\Node\Expression\Binary\ConcatBinary');

if (\false) {
class Twig_Node_Expression_Binary_Concat extends ConcatBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\StartsWithBinary;

class_exists('Twig\Node\Expression\Binary\StartsWithBinary');

if (\false) {
class Twig_Node_Expression_Binary_StartsWith extends StartsWithBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\GreaterBinary;

class_exists('Twig\Node\Expression\Binary\GreaterBinary');

if (\false) {
class Twig_Node_Expression_Binary_Greater extends GreaterBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\EndsWithBinary;

class_exists('Twig\Node\Expression\Binary\EndsWithBinary');

if (\false) {
class Twig_Node_Expression_Binary_EndsWith extends EndsWithBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\NotInBinary;

class_exists('Twig\Node\Expression\Binary\NotInBinary');

if (\false) {
class Twig_Node_Expression_Binary_NotIn extends NotInBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\LessEqualBinary;

class_exists('Twig\Node\Expression\Binary\LessEqualBinary');

if (\false) {
class Twig_Node_Expression_Binary_LessEqual extends LessEqualBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\MatchesBinary;

class_exists('Twig\Node\Expression\Binary\MatchesBinary');

if (\false) {
class Twig_Node_Expression_Binary_Matches extends MatchesBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\PowerBinary;

class_exists('Twig\Node\Expression\Binary\PowerBinary');

if (\false) {
class Twig_Node_Expression_Binary_Power extends PowerBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\LessBinary;

class_exists('Twig\Node\Expression\Binary\LessBinary');

if (\false) {
class Twig_Node_Expression_Binary_Less extends LessBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\AndBinary;

class_exists('Twig\Node\Expression\Binary\AndBinary');

if (\false) {
class Twig_Node_Expression_Binary_And extends AndBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\RangeBinary;

class_exists('Twig\Node\Expression\Binary\RangeBinary');

if (\false) {
class Twig_Node_Expression_Binary_Range extends RangeBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\BitwiseXorBinary;

class_exists('Twig\Node\Expression\Binary\BitwiseXorBinary');

if (\false) {
class Twig_Node_Expression_Binary_BitwiseXor extends BitwiseXorBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\InBinary;

class_exists('Twig\Node\Expression\Binary\InBinary');

if (\false) {
class Twig_Node_Expression_Binary_In extends InBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\BitwiseAndBinary;

class_exists('Twig\Node\Expression\Binary\BitwiseAndBinary');

if (\false) {
class Twig_Node_Expression_Binary_BitwiseAnd extends BitwiseAndBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\GreaterEqualBinary;

class_exists('Twig\Node\Expression\Binary\GreaterEqualBinary');

if (\false) {
class Twig_Node_Expression_Binary_GreaterEqual extends GreaterEqualBinary
{
}
}
<?php

use Twig\Node\Expression\Binary\AddBinary;

class_exists('Twig\Node\Expression\Binary\AddBinary');

if (\false) {
class Twig_Node_Expression_Binary_Add extends AddBinary
{
}
}
<?php

use Twig\Node\Expression\GetAttrExpression;

class_exists('Twig\Node\Expression\GetAttrExpression');

if (\false) {
class Twig_Node_Expression_GetAttr extends GetAttrExpression
{
}
}
<?php

use Twig\Node\Expression\MethodCallExpression;

class_exists('Twig\Node\Expression\MethodCallExpression');

if (\false) {
class Twig_Node_Expression_MethodCall extends MethodCallExpression
{
}
}
<?php

use Twig\Node\Expression\FilterExpression;

class_exists('Twig\Node\Expression\FilterExpression');

if (\false) {
class Twig_Node_Expression_Filter extends FilterExpression
{
}
}
<?php

use Twig\Node\Expression\BlockReferenceExpression;

class_exists('Twig\Node\Expression\BlockReferenceExpression');

if (\false) {
class Twig_Node_Expression_BlockReference extends BlockReferenceExpression
{
}
}
<?php

use Twig\Node\Expression\Unary\AbstractUnary;

class_exists('Twig\Node\Expression\Unary\AbstractUnary');

if (\false) {
class Twig_Node_Expression_Unary extends AbstractUnary
{
}
}
<?php

use Twig\Node\Expression\CallExpression;

class_exists('Twig\Node\Expression\CallExpression');

if (\false) {
class Twig_Node_Expression_Call extends CallExpression
{
}
}
<?php

use Twig\Node\Expression\ConstantExpression;

class_exists('Twig\Node\Expression\ConstantExpression');

if (\false) {
class Twig_Node_Expression_Constant extends ConstantExpression
{
}
}
<?php

use Twig\Node\Expression\FunctionExpression;

class_exists('Twig\Node\Expression\FunctionExpression');

if (\false) {
class Twig_Node_Expression_Function extends FunctionExpression
{
}
}
<?php

use Twig\Node\Expression\ParentExpression;

class_exists('Twig\Node\Expression\ParentExpression');

if (\false) {
class Twig_Node_Expression_Parent extends ParentExpression
{
}
}
<?php

use Twig\Node\Expression\TempNameExpression;

class_exists('Twig\Node\Expression\TempNameExpression');

if (\false) {
class Twig_Node_Expression_TempName extends TempNameExpression
{
}
}
<?php

use Twig\Node\Expression\NullCoalesceExpression;

class_exists('Twig\Node\Expression\NullCoalesceExpression');

if (\false) {
class Twig_Node_Expression_NullCoalesce extends NullCoalesceExpression
{
}
}
<?php

use Twig\Node\ForLoopNode;

class_exists('Twig\Node\ForLoopNode');

if (\false) {
class Twig_Node_ForLoop extends ForLoopNode
{
}
}
<?php

use Twig\Node\AutoEscapeNode;

class_exists('Twig\Node\AutoEscapeNode');

if (\false) {
class Twig_Node_AutoEscape extends AutoEscapeNode
{
}
}
<?php

use Twig\Node\IfNode;

class_exists('Twig\Node\IfNode');

if (\false) {
class Twig_Node_If extends IfNode
{
}
}
<?php

use Twig\Node\Expression\AbstractExpression;

class_exists('Twig\Node\Expression\AbstractExpression');

if (\false) {
class Twig_Node_Expression extends AbstractExpression
{
}
}
<?php

use Twig\Node\EmbedNode;

class_exists('Twig\Node\EmbedNode');

if (\false) {
class Twig_Node_Embed extends EmbedNode
{
}
}
<?php

use Twig\Node\DoNode;

class_exists('Twig\Node\DoNode');

if (\false) {
class Twig_Node_Do extends DoNode
{
}
}
<?php

use Twig\Node\DeprecatedNode;

class_exists('Twig\Node\DeprecatedNode');

if (\false) {
class Twig_Node_Deprecated extends DeprecatedNode
{
}
}
<?php

use Twig\Node\BlockNode;

class_exists('Twig\Node\BlockNode');

if (\false) {
class Twig_Node_Block extends BlockNode
{
}
}
<?php

use Twig\Node\BlockReferenceNode;

class_exists('Twig\Node\BlockReferenceNode');

if (\false) {
class Twig_Node_BlockReference extends BlockReferenceNode
{
}
}
<?php

use Twig\Node\ModuleNode;

class_exists('Twig\Node\ModuleNode');

if (\false) {
class Twig_Node_Module extends ModuleNode
{
}
}
<?php

use Twig\Node\WithNode;

class_exists('Twig\Node\WithNode');

if (\false) {
class Twig_Node_With extends WithNode
{
}
}
<?php

use Twig\Node\ForNode;

class_exists('Twig\Node\ForNode');

if (\false) {
class Twig_Node_For extends ForNode
{
}
}
<?php

use Twig\Node\FlushNode;

class_exists('Twig\Node\FlushNode');

if (\false) {
class Twig_Node_Flush extends FlushNode
{
}
}
<?php

use Twig\Node\ImportNode;

class_exists('Twig\Node\ImportNode');

if (\false) {
class Twig_Node_Import extends ImportNode
{
}
}
<?php

use Twig\Node\PrintNode;

class_exists('Twig\Node\PrintNode');

if (\false) {
class Twig_Node_Print extends PrintNode
{
}
}
<?php

use Twig\Node\IncludeNode;

class_exists('Twig\Node\IncludeNode');

if (\false) {
class Twig_Node_Include extends IncludeNode
{
}
}
<?php

use Twig\Node\SetTempNode;

class_exists('Twig\Node\SetTempNode');

if (\false) {
class Twig_Node_SetTemp extends SetTempNode
{
}
}
<?php

use Twig\Node\SpacelessNode;

class_exists('Twig\Node\SpacelessNode');

if (\false) {
class Twig_Node_Spaceless extends SpacelessNode
{
}
}
<?php

use Twig\Node\SetNode;

class_exists('Twig\Node\SetNode');

if (\false) {
class Twig_Node_Set extends SetNode
{
}
}
<?php

use Twig\Loader\LoaderInterface;

class_exists('Twig\Loader\LoaderInterface');

if (\false) {
class Twig_LoaderInterface extends LoaderInterface
{
}
}
<?php

use Twig\Loader\ArrayLoader;

class_exists('Twig\Loader\ArrayLoader');

if (\false) {
class Twig_Loader_Array extends ArrayLoader
{
}
}
<?php

use Twig\Loader\FilesystemLoader;

class_exists('Twig\Loader\FilesystemLoader');

if (\false) {
class Twig_Loader_Filesystem extends FilesystemLoader
{
}
}
<?php

use Twig\Loader\ChainLoader;

class_exists('Twig\Loader\ChainLoader');

if (\false) {
class Twig_Loader_Chain extends ChainLoader
{
}
}
<?php










use Twig\Loader\ExistsLoaderInterface;
use Twig\Loader\LoaderInterface;
use Twig\Loader\SourceContextLoaderInterface;
use Twig\Source;

@trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use "Twig\Loader\ArrayLoader" instead or "Twig\Environment::createTemplate()".', \E_USER_DEPRECATED);

















class Twig_Loader_String implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
{
public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), \E_USER_DEPRECATED);

return $name;
}

public function getSourceContext($name)
{
return new Source($name, $name);
}

public function exists($name)
{
return true;
}

public function getCacheKey($name)
{
return $name;
}

public function isFresh($name, $time)
{
return true;
}
}
<?php

use Twig\Markup;

class_exists('Twig\Markup');

if (\false) {
class Twig_Markup extends Markup
{
}
}
<?php










use Twig\Compiler;








interface Twig_NodeInterface extends \Countable, \IteratorAggregate
{



public function compile(Compiler $compiler);




public function getLine();

public function getNodeTag();
}
<?php

use Twig\Token;

class_exists('Twig\Token');

if (\false) {
class Twig_Token extends Token
{
}
}
<?php

use Twig\Compiler;

class_exists('Twig\Compiler');

if (\false) {
class Twig_Compiler extends Compiler
{
}
}
<?php











use Twig\Node\Node;










interface Twig_FunctionInterface
{





public function compile();

public function needsEnvironment();

public function needsContext();

public function getSafe(Node $filterArgs);

public function setArguments($arguments);

public function getArguments();
}
<?php

use Twig\RuntimeLoader\RuntimeLoaderInterface;

class_exists('Twig\RuntimeLoader\RuntimeLoaderInterface');

if (\false) {
class Twig_RuntimeLoaderInterface extends RuntimeLoaderInterface
{
}
}
<?php

use Twig\NodeVisitor\NodeVisitorInterface;

class_exists('Twig\NodeVisitor\NodeVisitorInterface');

if (\false) {
class Twig_NodeVisitorInterface extends NodeVisitorInterface
{
}
}
<?php

use Twig\TokenStream;

class_exists('Twig\TokenStream');

if (\false) {
class Twig_TokenStream extends TokenStream
{
}
}
<?php










use Twig\Environment;








interface Twig_TemplateInterface
{
public const ANY_CALL = 'any';
public const ARRAY_CALL = 'array';
public const METHOD_CALL = 'method';








public function render(array $context);







public function display(array $context, array $blocks = []);






public function getEnvironment();
}
<?php










@trigger_error('The Twig_Autoloader class is deprecated since version 1.21 and will be removed in 2.0. Use Composer instead.', \E_USER_DEPRECATED);








class Twig_Autoloader
{





public static function register($prepend = false)
{
@trigger_error('Using Twig_Autoloader is deprecated since version 1.21. Use Composer instead.', \E_USER_DEPRECATED);

spl_autoload_register([__CLASS__, 'autoload'], true, $prepend);
}






public static function autoload($class)
{
if (0 !== strpos($class, 'Twig')) {
return;
}

if (is_file($file = __DIR__.'/../'.str_replace(['_', "\0"], ['/', ''], $class).'.php')) {
require $file;
} elseif (is_file($file = __DIR__.'/../../src/'.str_replace(['Twig\\', '\\', "\0"], ['', '/', ''], $class).'.php')) {
require $file;
}
}
}
<?php

use Twig\Lexer;

class_exists('Twig\Lexer');

if (\false) {
class Twig_Lexer extends Lexer
{
}
}
<?php

use Twig\Util\DeprecationCollector;

class_exists('Twig\Util\DeprecationCollector');

if (\false) {
class Twig_Util_DeprecationCollector extends DeprecationCollector
{
}
}
<?php

use Twig\Util\TemplateDirIterator;

class_exists('Twig\Util\TemplateDirIterator');

if (\false) {
class Twig_Util_TemplateDirIterator extends TemplateDirIterator
{
}
}
<?php










@trigger_error('The Twig_Filter_Node class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFilter instead.', \E_USER_DEPRECATED);










class Twig_Filter_Node extends Twig_Filter
{
protected $class;

public function __construct($class, array $options = [])
{
parent::__construct($options);

$this->class = $class;
}

public function getClass()
{
return $this->class;
}

public function compile()
{
}
}
<?php










use Twig\Extension\ExtensionInterface;

@trigger_error('The Twig_Filter_Method class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFilter instead.', \E_USER_DEPRECATED);










class Twig_Filter_Method extends Twig_Filter
{
protected $extension;
protected $method;

public function __construct(ExtensionInterface $extension, $method, array $options = [])
{
$options['callable'] = [$extension, $method];

parent::__construct($options);

$this->extension = $extension;
$this->method = $method;
}

public function compile()
{
return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
}
}
<?php










@trigger_error('The Twig_Filter_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFilter instead.', \E_USER_DEPRECATED);










class Twig_Filter_Function extends Twig_Filter
{
protected $function;

public function __construct($function, array $options = [])
{
$options['callable'] = $function;

parent::__construct($options);

$this->function = $function;
}

public function compile()
{
return $this->function;
}
}
<?php










use Twig\Error\SyntaxError;
use Twig\Node\ModuleNode;
use Twig\TokenStream;








interface Twig_ParserInterface
{







public function parse(TokenStream $stream);
}
<?php











use Twig\TokenParser\TokenParserInterface;










interface Twig_TokenParserBrokerInterface
{







public function getTokenParser($tag);




public function setParser(Twig_ParserInterface $parser);






public function getParser();
}
<?php

















interface Twig_TestInterface
{





public function compile();
}
<?php

use Twig\TwigFunction;

class_exists('Twig\TwigFunction');

if (\false) {
class Twig_SimpleFunction extends TwigFunction
{
}
}
<?php

















interface Twig_TestCallableInterface
{
public function getCallable();
}
<?php

use Twig\Node\Node;

class_exists('Twig\Node\Node');

if (\false) {
class Twig_Node extends Node
{
}
}
<?php

use Twig\TemplateWrapper;

class_exists('Twig\TemplateWrapper');

if (\false) {
class Twig_TemplateWrapper extends TemplateWrapper
{
}
}
<?php

use Twig\Source;

class_exists('Twig\Source');

if (\false) {
class Twig_Source extends Source
{
}
}
<?php

use Twig\TokenParser\AbstractTokenParser;

class_exists('Twig\TokenParser\AbstractTokenParser');

if (\false) {
class Twig_TokenParser extends AbstractTokenParser
{
}
}
<?php

use Twig\Cache\FilesystemCache;

class_exists('Twig\Cache\FilesystemCache');

if (\false) {
class Twig_Cache_Filesystem extends FilesystemCache
{
}
}
<?php

use Twig\Cache\NullCache;

class_exists('Twig\Cache\NullCache');

if (\false) {
class Twig_Cache_Null extends NullCache
{
}
}
<?php










use Twig\Node\Node;

@trigger_error('The Twig_Filter class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFilter instead.', \E_USER_DEPRECATED);










abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface
{
protected $options;
protected $arguments = [];

public function __construct(array $options = [])
{
$this->options = array_merge([
'needs_environment' => false,
'needs_context' => false,
'pre_escape' => null,
'preserves_safety' => null,
'callable' => null,
], $options);
}

public function setArguments($arguments)
{
$this->arguments = $arguments;
}

public function getArguments()
{
return $this->arguments;
}

public function needsEnvironment()
{
return $this->options['needs_environment'];
}

public function needsContext()
{
return $this->options['needs_context'];
}

public function getSafe(Node $filterArgs)
{
if (isset($this->options['is_safe'])) {
return $this->options['is_safe'];
}

if (isset($this->options['is_safe_callback'])) {
return \call_user_func($this->options['is_safe_callback'], $filterArgs);
}
}

public function getPreservesSafety()
{
return $this->options['preserves_safety'];
}

public function getPreEscape()
{
return $this->options['pre_escape'];
}

public function getCallable()
{
return $this->options['callable'];
}
}
<?php

use Twig\RuntimeLoader\ContainerRuntimeLoader;

class_exists('Twig\RuntimeLoader\ContainerRuntimeLoader');

if (\false) {
class Twig_ContainerRuntimeLoader extends ContainerRuntimeLoader
{
}
}
<?php










use Twig\Node\Node;










interface Twig_FilterInterface
{





public function compile();

public function needsEnvironment();

public function needsContext();

public function getSafe(Node $filterArgs);

public function getPreservesSafety();

public function getPreEscape();

public function setArguments($arguments);

public function getArguments();
}
<?php

use Twig\TokenParser\MacroTokenParser;

class_exists('Twig\TokenParser\MacroTokenParser');

if (\false) {
class Twig_TokenParser_Macro extends MacroTokenParser
{
}
}
<?php

use Twig\TokenParser\SandboxTokenParser;

class_exists('Twig\TokenParser\SandboxTokenParser');

if (\false) {
class Twig_TokenParser_Sandbox extends SandboxTokenParser
{
}
}
<?php

use Twig\TokenParser\AutoEscapeTokenParser;

class_exists('Twig\TokenParser\AutoEscapeTokenParser');

if (\false) {
class Twig_TokenParser_AutoEscape extends AutoEscapeTokenParser
{
}
}
<?php

use Twig\TokenParser\IfTokenParser;

class_exists('Twig\TokenParser\IfTokenParser');

if (\false) {
class Twig_TokenParser_If extends IfTokenParser
{
}
}
<?php

use Twig\TokenParser\EmbedTokenParser;

class_exists('Twig\TokenParser\EmbedTokenParser');

if (\false) {
class Twig_TokenParser_Embed extends EmbedTokenParser
{
}
}
<?php

use Twig\TokenParser\DoTokenParser;

class_exists('Twig\TokenParser\DoTokenParser');

if (\false) {
class Twig_TokenParser_Do extends DoTokenParser
{
}
}
<?php

use Twig\TokenParser\DeprecatedTokenParser;

class_exists('Twig\TokenParser\DeprecatedTokenParser');

if (\false) {
class Twig_TokenParser_Deprecated extends DeprecatedTokenParser
{
}
}
<?php

use Twig\TokenParser\BlockTokenParser;

class_exists('Twig\TokenParser\BlockTokenParser');

if (\false) {
class Twig_TokenParser_Block extends BlockTokenParser
{
}
}
<?php

use Twig\TokenParser\FilterTokenParser;

class_exists('Twig\TokenParser\FilterTokenParser');

if (\false) {
class Twig_TokenParser_Filter extends FilterTokenParser
{
}
}
<?php

use Twig\TokenParser\WithTokenParser;

class_exists('Twig\TokenParser\WithTokenParser');

if (\false) {
class Twig_TokenParser_With extends WithTokenParser
{
}
}
<?php

use Twig\TokenParser\ForTokenParser;

class_exists('Twig\TokenParser\ForTokenParser');

if (\false) {
class Twig_TokenParser_For extends ForTokenParser
{
}
}
<?php

use Twig\TokenParser\FlushTokenParser;

class_exists('Twig\TokenParser\FlushTokenParser');

if (\false) {
class Twig_TokenParser_Flush extends FlushTokenParser
{
}
}
<?php

use Twig\TokenParser\ImportTokenParser;

class_exists('Twig\TokenParser\ImportTokenParser');

if (\false) {
class Twig_TokenParser_Import extends ImportTokenParser
{
}
}
<?php

use Twig\TokenParser\IncludeTokenParser;

class_exists('Twig\TokenParser\IncludeTokenParser');

if (\false) {
class Twig_TokenParser_Include extends IncludeTokenParser
{
}
}
<?php

use Twig\TokenParser\UseTokenParser;

class_exists('Twig\TokenParser\UseTokenParser');

if (\false) {
class Twig_TokenParser_Use extends UseTokenParser
{
}
}
<?php

use Twig\TokenParser\FromTokenParser;

class_exists('Twig\TokenParser\FromTokenParser');

if (\false) {
class Twig_TokenParser_From extends FromTokenParser
{
}
}
<?php

use Twig\TokenParser\SpacelessTokenParser;

class_exists('Twig\TokenParser\SpacelessTokenParser');

if (\false) {
class Twig_TokenParser_Spaceless extends SpacelessTokenParser
{
}
}
<?php

use Twig\TokenParser\ExtendsTokenParser;

class_exists('Twig\TokenParser\ExtendsTokenParser');

if (\false) {
class Twig_TokenParser_Extends extends ExtendsTokenParser
{
}
}
<?php

use Twig\TokenParser\SetTokenParser;

class_exists('Twig\TokenParser\SetTokenParser');

if (\false) {
class Twig_TokenParser_Set extends SetTokenParser
{
}
}
<?php

use Twig\Extension\InitRuntimeInterface;

class_exists('Twig\Extension\InitRuntimeInterface');

if (\false) {
class Twig_Extension_InitRuntimeInterface extends InitRuntimeInterface
{
}
}
<?php

use Twig\Extension\ProfilerExtension;

class_exists('Twig\Extension\ProfilerExtension');

if (\false) {
class Twig_Extension_Profiler extends ProfilerExtension
{
}
}
<?php

use Twig\Extension\CoreExtension;

class_exists('Twig\Extension\CoreExtension');

if (\false) {
class Twig_Extension_Core extends CoreExtension
{
}
}
<?php

use Twig\Extension\SandboxExtension;

class_exists('Twig\Extension\SandboxExtension');

if (\false) {
class Twig_Extension_Sandbox extends SandboxExtension
{
}
}
<?php

use Twig\Extension\EscaperExtension;

class_exists('Twig\Extension\EscaperExtension');

if (\false) {
class Twig_Extension_Escaper extends EscaperExtension
{
}
}
<?php

use Twig\Extension\OptimizerExtension;

class_exists('Twig\Extension\OptimizerExtension');

if (\false) {
class Twig_Extension_Optimizer extends OptimizerExtension
{
}
}
<?php

use Twig\Extension\DebugExtension;

class_exists('Twig\Extension\DebugExtension');

if (\false) {
class Twig_Extension_Debug extends DebugExtension
{
}
}
<?php

use Twig\Extension\StagingExtension;

class_exists('Twig\Extension\StagingExtension');

if (\false) {
class Twig_Extension_Staging extends StagingExtension
{
}
}
<?php

use Twig\Extension\GlobalsInterface;

class_exists('Twig\Extension\GlobalsInterface');

if (\false) {
class Twig_Extension_GlobalsInterface extends GlobalsInterface
{
}
}
<?php

use Twig\Extension\StringLoaderExtension;

class_exists('Twig\Extension\StringLoaderExtension');

if (\false) {
class Twig_Extension_StringLoader extends StringLoaderExtension
{
}
}
<?php










use Twig\Node\Node;

@trigger_error('The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFunction instead.', \E_USER_DEPRECATED);










abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface
{
protected $options;
protected $arguments = [];

public function __construct(array $options = [])
{
$this->options = array_merge([
'needs_environment' => false,
'needs_context' => false,
'callable' => null,
], $options);
}

public function setArguments($arguments)
{
$this->arguments = $arguments;
}

public function getArguments()
{
return $this->arguments;
}

public function needsEnvironment()
{
return $this->options['needs_environment'];
}

public function needsContext()
{
return $this->options['needs_context'];
}

public function getSafe(Node $functionArgs)
{
if (isset($this->options['is_safe'])) {
return $this->options['is_safe'];
}

if (isset($this->options['is_safe_callback'])) {
return \call_user_func($this->options['is_safe_callback'], $functionArgs);
}

return [];
}

public function getCallable()
{
return $this->options['callable'];
}
}
<?php

















interface Twig_CompilerInterface
{





public function compile(Twig_NodeInterface $node);






public function getSource();
}
<?php

use Twig\TokenParser\TokenParserInterface;

class_exists('Twig\TokenParser\TokenParserInterface');

if (\false) {
class Twig_TokenParserInterface extends TokenParserInterface
{
}
}
<?php










@trigger_error('The Twig_Function_Node class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFunction instead.', \E_USER_DEPRECATED);










class Twig_Function_Node extends Twig_Function
{
protected $class;

public function __construct($class, array $options = [])
{
parent::__construct($options);

$this->class = $class;
}

public function getClass()
{
return $this->class;
}

public function compile()
{
}
}
<?php











use Twig\Extension\ExtensionInterface;

@trigger_error('The Twig_Function_Method class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFunction instead.', \E_USER_DEPRECATED);










class Twig_Function_Method extends Twig_Function
{
protected $extension;
protected $method;

public function __construct(ExtensionInterface $extension, $method, array $options = [])
{
$options['callable'] = [$extension, $method];

parent::__construct($options);

$this->extension = $extension;
$this->method = $method;
}

public function compile()
{
return sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
}
}
<?php











@trigger_error('The Twig_Function_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \Twig\TwigFunction instead.', \E_USER_DEPRECATED);










class Twig_Function_Function extends Twig_Function
{
protected $function;

public function __construct($function, array $options = [])
{
$options['callable'] = $function;

parent::__construct($options);

$this->function = $function;
}

public function compile()
{
return $this->function;
}
}
<?php

use Twig\NodeVisitor\AbstractNodeVisitor;

class_exists('Twig\NodeVisitor\AbstractNodeVisitor');

if (\false) {
class Twig_BaseNodeVisitor extends AbstractNodeVisitor
{
}
}
<?php

use Twig\NodeVisitor\SandboxNodeVisitor;

class_exists('Twig\NodeVisitor\SandboxNodeVisitor');

if (\false) {
class Twig_NodeVisitor_Sandbox extends SandboxNodeVisitor
{
}
}
<?php

use Twig\NodeVisitor\EscaperNodeVisitor;

class_exists('Twig\NodeVisitor\EscaperNodeVisitor');

if (\false) {
class Twig_NodeVisitor_Escaper extends EscaperNodeVisitor
{
}
}
<?php

use Twig\NodeVisitor\OptimizerNodeVisitor;

class_exists('Twig\NodeVisitor\OptimizerNodeVisitor');

if (\false) {
class Twig_NodeVisitor_Optimizer extends OptimizerNodeVisitor
{
}
}
<?php

use Twig\NodeVisitor\SafeAnalysisNodeVisitor;

class_exists('Twig\NodeVisitor\SafeAnalysisNodeVisitor');

if (\false) {
class Twig_NodeVisitor_SafeAnalysis extends SafeAnalysisNodeVisitor
{
}
}
<?php










use Twig\Error\SyntaxError;
use Twig\Source;
use Twig\TokenStream;








interface Twig_LexerInterface
{










public function tokenize($code, $name = null);
}
<?php

use Twig\Loader\SourceContextLoaderInterface;

class_exists('Twig\Loader\SourceContextLoaderInterface');

if (\false) {
class Twig_SourceContextLoaderInterface extends SourceContextLoaderInterface
{
}
}
<?php

use Twig\Node\NodeOutputInterface;

class_exists('Twig\Node\NodeOutputInterface');

if (\false) {
class Twig_NodeOutputInterface extends NodeOutputInterface
{
}
}
<?php











use Twig\TokenParser\TokenParserInterface;








class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
{
protected $parser;
protected $parsers = [];
protected $brokers = [];






public function __construct($parsers = [], $brokers = [], $triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
@trigger_error('The '.__CLASS__.' class is deprecated since version 1.12 and will be removed in 2.0.', \E_USER_DEPRECATED);
}

foreach ($parsers as $parser) {
if (!$parser instanceof TokenParserInterface) {
throw new \LogicException('$parsers must a an array of Twig_TokenParserInterface.');
}
$this->parsers[$parser->getTag()] = $parser;
}
foreach ($brokers as $broker) {
if (!$broker instanceof Twig_TokenParserBrokerInterface) {
throw new \LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface.');
}
$this->brokers[] = $broker;
}
}

public function addTokenParser(TokenParserInterface $parser)
{
$this->parsers[$parser->getTag()] = $parser;
}

public function removeTokenParser(TokenParserInterface $parser)
{
$name = $parser->getTag();
if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) {
unset($this->parsers[$name]);
}
}

public function addTokenParserBroker(self $broker)
{
$this->brokers[] = $broker;
}

public function removeTokenParserBroker(self $broker)
{
if (false !== $pos = array_search($broker, $this->brokers)) {
unset($this->brokers[$pos]);
}
}










public function getTokenParser($tag)
{
if (isset($this->parsers[$tag])) {
return $this->parsers[$tag];
}
$broker = end($this->brokers);
while (false !== $broker) {
$parser = $broker->getTokenParser($tag);
if (null !== $parser) {
return $parser;
}
$broker = prev($this->brokers);
}
}

public function getParsers()
{
return $this->parsers;
}

public function getParser()
{
return $this->parser;
}

public function setParser(Twig_ParserInterface $parser)
{
$this->parser = $parser;
foreach ($this->parsers as $tokenParser) {
$tokenParser->setParser($parser);
}
foreach ($this->brokers as $broker) {
$broker->setParser($parser);
}
}
}
<?php

use Twig\Error\SyntaxError;

class_exists('Twig\Error\SyntaxError');

if (\false) {
class Twig_Error_Syntax extends SyntaxError
{
}
}
<?php

use Twig\Error\LoaderError;

class_exists('Twig\Error\LoaderError');

if (\false) {
class Twig_Error_Loader extends LoaderError
{
}
}
<?php

use Twig\Error\RuntimeError;

class_exists('Twig\Error\RuntimeError');

if (\false) {
class Twig_Error_Runtime extends RuntimeError
{
}
}
<?php

use Twig\Environment;

class_exists('Twig\Environment');

if (\false) {
class Twig_Environment extends Environment
{
}
}
<?php

use Twig\Node\NodeCaptureInterface;

class_exists('Twig\Node\NodeCaptureInterface');

if (\false) {
class Twig_NodeCaptureInterface extends NodeCaptureInterface
{
}
}
<?php

use Twig\Template;

class_exists('Twig\Template');

if (\false) {
class Twig_Template extends Template
{
}
}
<?php



















interface Twig_FunctionCallableInterface
{
public function getCallable();
}
<?php

use Twig\FileExtensionEscapingStrategy;

class_exists('Twig\FileExtensionEscapingStrategy');

if (\false) {
class Twig_FileExtensionEscapingStrategy extends FileExtensionEscapingStrategy
{
}
}
<?php



















interface Twig_FilterCallableInterface
{
public function getCallable();
}
<?php

use Twig\Profiler\Node\EnterProfileNode;

class_exists('Twig\Profiler\Node\EnterProfileNode');

if (\false) {
class Twig_Profiler_Node_EnterProfile extends EnterProfileNode
{
}
}
<?php

use Twig\Profiler\Node\LeaveProfileNode;

class_exists('Twig\Profiler\Node\LeaveProfileNode');

if (\false) {
class Twig_Profiler_Node_LeaveProfile extends LeaveProfileNode
{
}
}
<?php

use Twig\Profiler\Profile;

class_exists('Twig\Profiler\Profile');

if (\false) {
class Twig_Profiler_Profile extends Profile
{
}
}
<?php

use Twig\Profiler\NodeVisitor\ProfilerNodeVisitor;

class_exists('Twig\Profiler\NodeVisitor\ProfilerNodeVisitor');

if (\false) {
class Twig_Profiler_NodeVisitor_Profiler extends ProfilerNodeVisitor
{
}
}
<?php

use Twig\Profiler\Dumper\TextDumper;

class_exists('Twig\Profiler\Dumper\TextDumper');

if (\false) {
class Twig_Profiler_Dumper_Text extends TextDumper
{
}
}
<?php

use Twig\Profiler\Dumper\BlackfireDumper;

class_exists('Twig\Profiler\Dumper\BlackfireDumper');

if (\false) {
class Twig_Profiler_Dumper_Blackfire extends BlackfireDumper
{
}
}
<?php

use Twig\Profiler\Dumper\HtmlDumper;

class_exists('Twig\Profiler\Dumper\HtmlDumper');

if (\false) {
class Twig_Profiler_Dumper_Html extends HtmlDumper
{
}
}
<?php

use Twig\Profiler\Dumper\BaseDumper;

class_exists('Twig\Profiler\Dumper\BaseDumper');

if (\false) {
class Twig_Profiler_Dumper_Base extends BaseDumper
{
}
}
<?php

use Twig\Error\Error;

class_exists('Twig\Error\Error');

if (\false) {
class Twig_Error extends Error
{
}
}
<?php

use Twig\ExpressionParser;

class_exists('Twig\ExpressionParser');

if (\false) {
class Twig_ExpressionParser extends ExpressionParser
{
}
}
<?php










namespace Twig\RuntimeLoader;






class FactoryRuntimeLoader implements RuntimeLoaderInterface
{
private $map;




public function __construct($map = [])
{
$this->map = $map;
}

public function load($class)
{
if (isset($this->map[$class])) {
$runtimeFactory = $this->map[$class];

return $runtimeFactory();
}
}
}

class_alias('Twig\RuntimeLoader\FactoryRuntimeLoader', 'Twig_FactoryRuntimeLoader');
<?php










namespace Twig\RuntimeLoader;






interface RuntimeLoaderInterface
{







public function load($class);
}

class_alias('Twig\RuntimeLoader\RuntimeLoaderInterface', 'Twig_RuntimeLoaderInterface');
<?php










namespace Twig\RuntimeLoader;

use Psr\Container\ContainerInterface;









class ContainerRuntimeLoader implements RuntimeLoaderInterface
{
private $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

public function load($class)
{
if ($this->container->has($class)) {
return $this->container->get($class);
}
}
}

class_alias('Twig\RuntimeLoader\ContainerRuntimeLoader', 'Twig_ContainerRuntimeLoader');
<?php










namespace Twig;

use Twig\NodeVisitor\NodeVisitorInterface;










class NodeTraverser
{
protected $env;
protected $visitors = [];




public function __construct(Environment $env, array $visitors = [])
{
$this->env = $env;
foreach ($visitors as $visitor) {
$this->addVisitor($visitor);
}
}

public function addVisitor(NodeVisitorInterface $visitor)
{
$this->visitors[$visitor->getPriority()][] = $visitor;
}






public function traverse(\Twig_NodeInterface $node)
{
ksort($this->visitors);
foreach ($this->visitors as $visitors) {
foreach ($visitors as $visitor) {
$node = $this->traverseForVisitor($visitor, $node);
}
}

return $node;
}

protected function traverseForVisitor(NodeVisitorInterface $visitor, \Twig_NodeInterface $node = null)
{
if (null === $node) {
return;
}

$node = $visitor->enterNode($node, $this->env);

foreach ($node as $k => $n) {
if (null === $n) {
continue;
}

if (false !== ($m = $this->traverseForVisitor($visitor, $n)) && null !== $m) {
if ($m !== $n) {
$node->setNode($k, $m);
}
} else {
$node->removeNode($k);
}
}

return $visitor->leaveNode($node, $this->env);
}
}

class_alias('Twig\NodeTraverser', 'Twig_NodeTraverser');
<?php










namespace Twig\Sandbox;






class SecurityNotAllowedPropertyError extends SecurityError
{
private $className;
private $propertyName;

public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, \Exception $previous = null)
{
parent::__construct($message, $lineno, $filename, $previous);
$this->className = $className;
$this->propertyName = $propertyName;
}

public function getClassName()
{
return $this->className;
}

public function getPropertyName()
{
return $this->propertyName;
}
}

class_alias('Twig\Sandbox\SecurityNotAllowedPropertyError', 'Twig_Sandbox_SecurityNotAllowedPropertyError');
<?php










namespace Twig\Sandbox;

use Twig\Markup;








class SecurityPolicy implements SecurityPolicyInterface
{
protected $allowedTags;
protected $allowedFilters;
protected $allowedMethods;
protected $allowedProperties;
protected $allowedFunctions;

public function __construct(array $allowedTags = [], array $allowedFilters = [], array $allowedMethods = [], array $allowedProperties = [], array $allowedFunctions = [])
{
$this->allowedTags = $allowedTags;
$this->allowedFilters = $allowedFilters;
$this->setAllowedMethods($allowedMethods);
$this->allowedProperties = $allowedProperties;
$this->allowedFunctions = $allowedFunctions;
}

public function setAllowedTags(array $tags)
{
$this->allowedTags = $tags;
}

public function setAllowedFilters(array $filters)
{
$this->allowedFilters = $filters;
}

public function setAllowedMethods(array $methods)
{
$this->allowedMethods = [];
foreach ($methods as $class => $m) {
$this->allowedMethods[$class] = array_map(function ($value) { return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); }, \is_array($m) ? $m : [$m]);
}
}

public function setAllowedProperties(array $properties)
{
$this->allowedProperties = $properties;
}

public function setAllowedFunctions(array $functions)
{
$this->allowedFunctions = $functions;
}

public function checkSecurity($tags, $filters, $functions)
{
foreach ($tags as $tag) {
if (!\in_array($tag, $this->allowedTags)) {
throw new SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
}
}

foreach ($filters as $filter) {
if (!\in_array($filter, $this->allowedFilters)) {
throw new SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
}
}

foreach ($functions as $function) {
if (!\in_array($function, $this->allowedFunctions)) {
throw new SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
}
}
}

public function checkMethodAllowed($obj, $method)
{
if ($obj instanceof \Twig_TemplateInterface || $obj instanceof Markup) {
return;
}

$allowed = false;
$method = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
foreach ($this->allowedMethods as $class => $methods) {
if ($obj instanceof $class) {
$allowed = \in_array($method, $methods);

break;
}
}

if (!$allowed) {
$class = \get_class($obj);
throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
}
}

public function checkPropertyAllowed($obj, $property)
{
$allowed = false;
foreach ($this->allowedProperties as $class => $properties) {
if ($obj instanceof $class) {
$allowed = \in_array($property, \is_array($properties) ? $properties : [$properties]);

break;
}
}

if (!$allowed) {
$class = \get_class($obj);
throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
}
}
}

class_alias('Twig\Sandbox\SecurityPolicy', 'Twig_Sandbox_SecurityPolicy');
<?php










namespace Twig\Sandbox;






class SecurityNotAllowedFunctionError extends SecurityError
{
private $functionName;

public function __construct($message, $functionName, $lineno = -1, $filename = null, \Exception $previous = null)
{
parent::__construct($message, $lineno, $filename, $previous);
$this->functionName = $functionName;
}

public function getFunctionName()
{
return $this->functionName;
}
}

class_alias('Twig\Sandbox\SecurityNotAllowedFunctionError', 'Twig_Sandbox_SecurityNotAllowedFunctionError');
<?php










namespace Twig\Sandbox;






class SecurityNotAllowedFilterError extends SecurityError
{
private $filterName;

public function __construct($message, $functionName, $lineno = -1, $filename = null, \Exception $previous = null)
{
parent::__construct($message, $lineno, $filename, $previous);
$this->filterName = $functionName;
}

public function getFilterName()
{
return $this->filterName;
}
}

class_alias('Twig\Sandbox\SecurityNotAllowedFilterError', 'Twig_Sandbox_SecurityNotAllowedFilterError');
<?php










namespace Twig\Sandbox;






class SecurityNotAllowedTagError extends SecurityError
{
private $tagName;

public function __construct($message, $tagName, $lineno = -1, $filename = null, \Exception $previous = null)
{
parent::__construct($message, $lineno, $filename, $previous);
$this->tagName = $tagName;
}

public function getTagName()
{
return $this->tagName;
}
}

class_alias('Twig\Sandbox\SecurityNotAllowedTagError', 'Twig_Sandbox_SecurityNotAllowedTagError');
<?php










namespace Twig\Sandbox;

use Twig\Error\Error;






class SecurityError extends Error
{
}

class_alias('Twig\Sandbox\SecurityError', 'Twig_Sandbox_SecurityError');
<?php










namespace Twig\Sandbox;






interface SecurityPolicyInterface
{
public function checkSecurity($tags, $filters, $functions);

public function checkMethodAllowed($obj, $method);

public function checkPropertyAllowed($obj, $method);
}

class_alias('Twig\Sandbox\SecurityPolicyInterface', 'Twig_Sandbox_SecurityPolicyInterface');
<?php










namespace Twig\Sandbox;






class SecurityNotAllowedMethodError extends SecurityError
{
private $className;
private $methodName;

public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, \Exception $previous = null)
{
parent::__construct($message, $lineno, $filename, $previous);
$this->className = $className;
$this->methodName = $methodName;
}

public function getClassName()
{
return $this->className;
}

public function getMethodName()
{
return $this->methodName;
}
}

class_alias('Twig\Sandbox\SecurityNotAllowedMethodError', 'Twig_Sandbox_SecurityNotAllowedMethodError');
<?php











namespace Twig;

use Twig\Error\SyntaxError;
use Twig\Node\BlockNode;
use Twig\Node\BlockReferenceNode;
use Twig\Node\BodyNode;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\MacroNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\NodeCaptureInterface;
use Twig\Node\NodeOutputInterface;
use Twig\Node\PrintNode;
use Twig\Node\TextNode;
use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\TokenParser\TokenParserInterface;






class Parser implements \Twig_ParserInterface
{
protected $stack = [];
protected $stream;
protected $parent;
protected $handlers;
protected $visitors;
protected $expressionParser;
protected $blocks;
protected $blockStack;
protected $macros;
protected $env;
protected $reservedMacroNames;
protected $importedSymbols;
protected $traits;
protected $embeddedTemplates = [];
private $varNameSalt = 0;

public function __construct(Environment $env)
{
$this->env = $env;
}




public function getEnvironment()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', \E_USER_DEPRECATED);

return $this->env;
}

public function getVarName()
{
return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->stream->getSourceContext()->getCode().$this->varNameSalt++));
}




public function getFilename()
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), \E_USER_DEPRECATED);

return $this->stream->getSourceContext()->getName();
}

public function parse(TokenStream $stream, $test = null, $dropNeedle = false)
{



$vars = [];
foreach ($this as $k => $v) {
$vars[$k] = $v;
}

unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']);
$this->stack[] = $vars;


if (null === $this->handlers) {
$this->handlers = $this->env->getTokenParsers();
$this->handlers->setParser($this);
}


if (null === $this->visitors) {
$this->visitors = $this->env->getNodeVisitors();
}

if (null === $this->expressionParser) {
$this->expressionParser = new ExpressionParser($this, $this->env);
}

$this->stream = $stream;
$this->parent = null;
$this->blocks = [];
$this->macros = [];
$this->traits = [];
$this->blockStack = [];
$this->importedSymbols = [[]];
$this->embeddedTemplates = [];
$this->varNameSalt = 0;

try {
$body = $this->subparse($test, $dropNeedle);

if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
$body = new Node();
}
} catch (SyntaxError $e) {
if (!$e->getSourceContext()) {
$e->setSourceContext($this->stream->getSourceContext());
}

if (!$e->getTemplateLine()) {
$e->setTemplateLine($this->stream->getCurrent()->getLine());
}

throw $e;
}

$node = new ModuleNode(new BodyNode([$body]), $this->parent, new Node($this->blocks), new Node($this->macros), new Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());

$traverser = new NodeTraverser($this->env, $this->visitors);

$node = $traverser->traverse($node);


foreach (array_pop($this->stack) as $key => $val) {
$this->$key = $val;
}

return $node;
}

public function subparse($test, $dropNeedle = false)
{
$lineno = $this->getCurrentToken()->getLine();
$rv = [];
while (!$this->stream->isEOF()) {
switch ($this->getCurrentToken()->getType()) {
case Token::TEXT_TYPE:
$token = $this->stream->next();
$rv[] = new TextNode($token->getValue(), $token->getLine());
break;

case Token::VAR_START_TYPE:
$token = $this->stream->next();
$expr = $this->expressionParser->parseExpression();
$this->stream->expect(Token::VAR_END_TYPE);
$rv[] = new PrintNode($expr, $token->getLine());
break;

case Token::BLOCK_START_TYPE:
$this->stream->next();
$token = $this->getCurrentToken();

if (Token::NAME_TYPE !== $token->getType()) {
throw new SyntaxError('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext());
}

if (null !== $test && \call_user_func($test, $token)) {
if ($dropNeedle) {
$this->stream->next();
}

if (1 === \count($rv)) {
return $rv[0];
}

return new Node($rv, [], $lineno);
}

$subparser = $this->handlers->getTokenParser($token->getValue());
if (null === $subparser) {
if (null !== $test) {
$e = new SyntaxError(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());

if (\is_array($test) && isset($test[0]) && $test[0] instanceof TokenParserInterface) {
$e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
}
} else {
$e = new SyntaxError(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
$e->addSuggestions($token->getValue(), array_keys($this->env->getTags()));
}

throw $e;
}

$this->stream->next();

$node = $subparser->parse($token);
if (null !== $node) {
$rv[] = $node;
}
break;

default:
throw new SyntaxError('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext());
}
}

if (1 === \count($rv)) {
return $rv[0];
}

return new Node($rv, [], $lineno);
}




public function addHandler($name, $class)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', \E_USER_DEPRECATED);

$this->handlers[$name] = $class;
}




public function addNodeVisitor(NodeVisitorInterface $visitor)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', \E_USER_DEPRECATED);

$this->visitors[] = $visitor;
}

public function getBlockStack()
{
return $this->blockStack;
}

public function peekBlockStack()
{
return isset($this->blockStack[\count($this->blockStack) - 1]) ? $this->blockStack[\count($this->blockStack) - 1] : null;
}

public function popBlockStack()
{
array_pop($this->blockStack);
}

public function pushBlockStack($name)
{
$this->blockStack[] = $name;
}

public function hasBlock($name)
{
return isset($this->blocks[$name]);
}

public function getBlock($name)
{
return $this->blocks[$name];
}

public function setBlock($name, BlockNode $value)
{
$this->blocks[$name] = new BodyNode([$value], [], $value->getTemplateLine());
}

public function hasMacro($name)
{
return isset($this->macros[$name]);
}

public function setMacro($name, MacroNode $node)
{
if ($this->isReservedMacroName($name)) {
throw new SyntaxError(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext());
}

$this->macros[$name] = $node;
}

public function isReservedMacroName($name)
{
if (null === $this->reservedMacroNames) {
$this->reservedMacroNames = [];
$r = new \ReflectionClass($this->env->getBaseTemplateClass());
foreach ($r->getMethods() as $method) {
$methodName = strtr($method->getName(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');

if ('get' === substr($methodName, 0, 3) && isset($methodName[3])) {
$this->reservedMacroNames[] = substr($methodName, 3);
}
}
}

return \in_array(strtr($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), $this->reservedMacroNames);
}

public function addTrait($trait)
{
$this->traits[] = $trait;
}

public function hasTraits()
{
return \count($this->traits) > 0;
}

public function embedTemplate(ModuleNode $template)
{
$template->setIndex(mt_rand());

$this->embeddedTemplates[] = $template;
}

public function addImportedSymbol($type, $alias, $name = null, AbstractExpression $node = null)
{
$this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $node];
}

public function getImportedSymbol($type, $alias)
{
if (null !== $this->peekBlockStack()) {
foreach ($this->importedSymbols as $functions) {
if (isset($functions[$type][$alias])) {
if (\count($this->blockStack) > 1) {
return null;
}

return $functions[$type][$alias];
}
}
} else {
return isset($this->importedSymbols[0][$type][$alias]) ? $this->importedSymbols[0][$type][$alias] : null;
}
}

public function isMainScope()
{
return 1 === \count($this->importedSymbols);
}

public function pushLocalScope()
{
array_unshift($this->importedSymbols, []);
}

public function popLocalScope()
{
array_shift($this->importedSymbols);
}




public function getExpressionParser()
{
return $this->expressionParser;
}

public function getParent()
{
return $this->parent;
}

public function setParent($parent)
{
$this->parent = $parent;
}




public function getStream()
{
return $this->stream;
}




public function getCurrentToken()
{
return $this->stream->getCurrent();
}

protected function filterBodyNodes(\Twig_NodeInterface $node)
{

if (
($node instanceof TextNode && !ctype_space($node->getAttribute('data')))
||
(!$node instanceof TextNode && !$node instanceof BlockReferenceNode && $node instanceof NodeOutputInterface)
) {
if (false !== strpos((string) $node, \chr(0xEF).\chr(0xBB).\chr(0xBF))) {
$t = substr($node->getAttribute('data'), 3);
if ('' === $t || ctype_space($t)) {

return;
}
}

throw new SyntaxError('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
}


if ($node instanceof NodeCaptureInterface) {
return $node;
}

if ($node instanceof NodeOutputInterface) {
return;
}

foreach ($node as $k => $n) {
if (null !== $n && null === $this->filterBodyNodes($n)) {
$node->removeNode($k);
}
}

return $node;
}
}

class_alias('Twig\Parser', 'Twig_Parser');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ConstantExpression;






class DeprecatedNode extends Node
{
public function __construct(AbstractExpression $expr, $lineno, $tag = null)
{
parent::__construct(['expr' => $expr], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->addDebugInfo($this);

$expr = $this->getNode('expr');

if ($expr instanceof ConstantExpression) {
$compiler->write('@trigger_error(')
->subcompile($expr);
} else {
$varName = $compiler->getVarName();
$compiler->write(sprintf('$%s = ', $varName))
->subcompile($expr)
->raw(";\n")
->write(sprintf('@trigger_error($%s', $varName));
}

$compiler
->raw('.')
->string(sprintf(' ("%s" at line %d).', $this->getTemplateName(), $this->getTemplateLine()))
->raw(", E_USER_DEPRECATED);\n")
;
}
}

class_alias('Twig\Node\DeprecatedNode', 'Twig_Node_Deprecated');
<?php










namespace Twig\Node;

use Twig\Compiler;






class SandboxNode extends Node
{
public function __construct(\Twig_NodeInterface $body, $lineno, $tag = null)
{
parent::__construct(['body' => $body], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write("if (!\$alreadySandboxed = \$this->sandbox->isSandboxed()) {\n")
->indent()
->write("\$this->sandbox->enableSandbox();\n")
->outdent()
->write("}\n")
->write("try {\n")
->indent()
->subcompile($this->getNode('body'))
->outdent()
->write("} finally {\n")
->indent()
->write("if (!\$alreadySandboxed) {\n")
->indent()
->write("\$this->sandbox->disableSandbox();\n")
->outdent()
->write("}\n")
->outdent()
->write("}\n")
;
}
}

class_alias('Twig\Node\SandboxNode', 'Twig_Node_Sandbox');
<?php










namespace Twig\Node;

use Twig\Compiler;






class ForLoopNode extends Node
{
public function __construct($lineno, $tag = null)
{
parent::__construct([], ['with_loop' => false, 'ifexpr' => false, 'else' => false], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
if ($this->getAttribute('else')) {
$compiler->write("\$context['_iterated'] = true;\n");
}

if ($this->getAttribute('with_loop')) {
$compiler
->write("++\$context['loop']['index0'];\n")
->write("++\$context['loop']['index'];\n")
->write("\$context['loop']['first'] = false;\n")
;

if (!$this->getAttribute('ifexpr')) {
$compiler
->write("if (isset(\$context['loop']['length'])) {\n")
->indent()
->write("--\$context['loop']['revindex0'];\n")
->write("--\$context['loop']['revindex'];\n")
->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
->outdent()
->write("}\n")
;
}
}
}
}

class_alias('Twig\Node\ForLoopNode', 'Twig_Node_ForLoop');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;











class CheckToStringNode extends AbstractExpression
{
public function __construct(AbstractExpression $expr)
{
parent::__construct(['expr' => $expr], [], $expr->getTemplateLine(), $expr->getNodeTag());
}

public function compile(Compiler $compiler)
{
$compiler
->raw('$this->sandbox->ensureToStringAllowed(')
->subcompile($this->getNode('expr'))
->raw(')')
;
}
}
<?php










namespace Twig\Node;

use Twig\Compiler;






class FlushNode extends Node
{
public function __construct($lineno, $tag)
{
parent::__construct([], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write("flush();\n")
;
}
}

class_alias('Twig\Node\FlushNode', 'Twig_Node_Flush');
<?php











namespace Twig\Node;

use Twig\Compiler;






class BlockReferenceNode extends Node implements NodeOutputInterface
{
public function __construct($name, $lineno, $tag = null)
{
parent::__construct([], ['name' => $name], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')))
;
}
}

class_alias('Twig\Node\BlockReferenceNode', 'Twig_Node_BlockReference');
<?php











namespace Twig\Node\Expression\Unary;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;

abstract class AbstractUnary extends AbstractExpression
{
public function __construct(\Twig_NodeInterface $node, $lineno)
{
parent::__construct(['node' => $node], [], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler->raw(' ');
$this->operator($compiler);
$compiler->subcompile($this->getNode('node'));
}

abstract public function operator(Compiler $compiler);
}

class_alias('Twig\Node\Expression\Unary\AbstractUnary', 'Twig_Node_Expression_Unary');
<?php











namespace Twig\Node\Expression\Unary;

use Twig\Compiler;

class PosUnary extends AbstractUnary
{
public function operator(Compiler $compiler)
{
$compiler->raw('+');
}
}

class_alias('Twig\Node\Expression\Unary\PosUnary', 'Twig_Node_Expression_Unary_Pos');
<?php











namespace Twig\Node\Expression\Unary;

use Twig\Compiler;

class NegUnary extends AbstractUnary
{
public function operator(Compiler $compiler)
{
$compiler->raw('-');
}
}

class_alias('Twig\Node\Expression\Unary\NegUnary', 'Twig_Node_Expression_Unary_Neg');
<?php











namespace Twig\Node\Expression\Unary;

use Twig\Compiler;

class NotUnary extends AbstractUnary
{
public function operator(Compiler $compiler)
{
$compiler->raw('!');
}
}

class_alias('Twig\Node\Expression\Unary\NotUnary', 'Twig_Node_Expression_Unary_Not');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\Node\Node;






class BlockReferenceExpression extends AbstractExpression
{



public function __construct(\Twig_NodeInterface $name, $template, $lineno, $tag = null)
{
if (\is_bool($template)) {
@trigger_error(sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), \E_USER_DEPRECATED);

$template = null;
}

$nodes = ['name' => $name];
if (null !== $template) {
$nodes['template'] = $template;
}

parent::__construct($nodes, ['is_defined_test' => false, 'output' => false], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
if ($this->getAttribute('is_defined_test')) {
$this->compileTemplateCall($compiler, 'hasBlock');
} else {
if ($this->getAttribute('output')) {
$compiler->addDebugInfo($this);

$this
->compileTemplateCall($compiler, 'displayBlock')
->raw(";\n");
} else {
$this->compileTemplateCall($compiler, 'renderBlock');
}
}
}

private function compileTemplateCall(Compiler $compiler, $method)
{
if (!$this->hasNode('template')) {
$compiler->write('$this');
} else {
$compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('template'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}

$compiler->raw(sprintf('->%s', $method));
$this->compileBlockArguments($compiler);

return $compiler;
}

private function compileBlockArguments(Compiler $compiler)
{
$compiler
->raw('(')
->subcompile($this->getNode('name'))
->raw(', $context');

if (!$this->hasNode('template')) {
$compiler->raw(', $blocks');
}

return $compiler->raw(')');
}
}

class_alias('Twig\Node\Expression\BlockReferenceExpression', 'Twig_Node_Expression_BlockReference');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\Node\Node;






class ArrowFunctionExpression extends AbstractExpression
{
public function __construct(AbstractExpression $expr, Node $names, $lineno, $tag = null)
{
parent::__construct(['expr' => $expr, 'names' => $names], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->raw('function (')
;
foreach ($this->getNode('names') as $i => $name) {
if ($i) {
$compiler->raw(', ');
}

$compiler
->raw('$__')
->raw($name->getAttribute('name'))
->raw('__')
;
}
$compiler
->raw(') use ($context) { ')
;
foreach ($this->getNode('names') as $name) {
$compiler
->raw('$context["')
->raw($name->getAttribute('name'))
->raw('"] = $__')
->raw($name->getAttribute('name'))
->raw('__; ')
;
}
$compiler
->raw('return ')
->subcompile($this->getNode('expr'))
->raw('; }')
;
}
}
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;






class ParentExpression extends AbstractExpression
{
public function __construct($name, $lineno, $tag = null)
{
parent::__construct([], ['output' => false, 'name' => $name], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
if ($this->getAttribute('output')) {
$compiler
->addDebugInfo($this)
->write('$this->displayParentBlock(')
->string($this->getAttribute('name'))
->raw(", \$context, \$blocks);\n")
;
} else {
$compiler
->raw('$this->renderParentBlock(')
->string($this->getAttribute('name'))
->raw(', $context, $blocks)')
;
}
}
}

class_alias('Twig\Node\Expression\ParentExpression', 'Twig_Node_Expression_Parent');
<?php











namespace Twig\Node\Expression;

use Twig\Node\Node;






abstract class AbstractExpression extends Node
{
}

class_alias('Twig\Node\Expression\AbstractExpression', 'Twig_Node_Expression');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;

class ConstantExpression extends AbstractExpression
{
public function __construct($value, $lineno)
{
parent::__construct([], ['value' => $value], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler->repr($this->getAttribute('value'));
}
}

class_alias('Twig\Node\Expression\ConstantExpression', 'Twig_Node_Expression_Constant');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;

class MethodCallExpression extends AbstractExpression
{
public function __construct(AbstractExpression $node, $method, ArrayExpression $arguments, $lineno)
{
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false], $lineno);

if ($node instanceof NameExpression) {
$node->setAttribute('always_defined', true);
}
}

public function compile(Compiler $compiler)
{
$compiler
->subcompile($this->getNode('node'))
->raw('->')
->raw($this->getAttribute('method'))
->raw('(')
;
$first = true;
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
if (!$first) {
$compiler->raw(', ');
}
$first = false;

$compiler->subcompile($pair['value']);
}
$compiler->raw(')');
}
}

class_alias('Twig\Node\Expression\MethodCallExpression', 'Twig_Node_Expression_MethodCall');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;

class TempNameExpression extends AbstractExpression
{
public function __construct($name, $lineno)
{
parent::__construct([], ['name' => $name], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler
->raw('$_')
->raw($this->getAttribute('name'))
->raw('_')
;
}
}

class_alias('Twig\Node\Expression\TempNameExpression', 'Twig_Node_Expression_TempName');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;

class AssignNameExpression extends NameExpression
{
public function compile(Compiler $compiler)
{
$compiler
->raw('$context[')
->string($this->getAttribute('name'))
->raw(']')
;
}
}

class_alias('Twig\Node\Expression\AssignNameExpression', 'Twig_Node_Expression_AssignName');
<?php










namespace Twig\Node\Expression\Filter;

use Twig\Compiler;
use Twig\Node\Expression\ConditionalExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Expression\Test\DefinedTest;
use Twig\Node\Node;








class DefaultFilter extends FilterExpression
{
public function __construct(\Twig_NodeInterface $node, ConstantExpression $filterName, \Twig_NodeInterface $arguments, $lineno, $tag = null)
{
$default = new FilterExpression($node, new ConstantExpression('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());

if ('default' === $filterName->getAttribute('value') && ($node instanceof NameExpression || $node instanceof GetAttrExpression)) {
$test = new DefinedTest(clone $node, 'defined', new Node(), $node->getTemplateLine());
$false = \count($arguments) ? $arguments->getNode(0) : new ConstantExpression('', $node->getTemplateLine());

$node = new ConditionalExpression($test, $default, $false, $node->getTemplateLine());
} else {
$node = $default;
}

parent::__construct($node, $filterName, $arguments, $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->subcompile($this->getNode('node'));
}
}

class_alias('Twig\Node\Expression\Filter\DefaultFilter', 'Twig_Node_Expression_Filter_Default');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class OrBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('||');
}
}

class_alias('Twig\Node\Expression\Binary\OrBinary', 'Twig_Node_Expression_Binary_Or');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class PowerBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
if (\PHP_VERSION_ID >= 50600) {
return parent::compile($compiler);
}

$compiler
->raw('pow(')
->subcompile($this->getNode('left'))
->raw(', ')
->subcompile($this->getNode('right'))
->raw(')')
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('**');
}
}

class_alias('Twig\Node\Expression\Binary\PowerBinary', 'Twig_Node_Expression_Binary_Power');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class NotInBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$compiler
->raw('!twig_in_filter(')
->subcompile($this->getNode('left'))
->raw(', ')
->subcompile($this->getNode('right'))
->raw(')')
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('not in');
}
}

class_alias('Twig\Node\Expression\Binary\NotInBinary', 'Twig_Node_Expression_Binary_NotIn');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class AndBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('&&');
}
}

class_alias('Twig\Node\Expression\Binary\AndBinary', 'Twig_Node_Expression_Binary_And');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class LessEqualBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('<=');
}
}

class_alias('Twig\Node\Expression\Binary\LessEqualBinary', 'Twig_Node_Expression_Binary_LessEqual');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class LessBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('<');
}
}

class_alias('Twig\Node\Expression\Binary\LessBinary', 'Twig_Node_Expression_Binary_Less');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class AddBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('+');
}
}

class_alias('Twig\Node\Expression\Binary\AddBinary', 'Twig_Node_Expression_Binary_Add');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class BitwiseAndBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('&');
}
}

class_alias('Twig\Node\Expression\Binary\BitwiseAndBinary', 'Twig_Node_Expression_Binary_BitwiseAnd');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class MatchesBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$compiler
->raw('preg_match(')
->subcompile($this->getNode('right'))
->raw(', ')
->subcompile($this->getNode('left'))
->raw(')')
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('');
}
}

class_alias('Twig\Node\Expression\Binary\MatchesBinary', 'Twig_Node_Expression_Binary_Matches');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class EndsWithBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$left = $compiler->getVarName();
$right = $compiler->getVarName();
$compiler
->raw(sprintf('(is_string($%s = ', $left))
->subcompile($this->getNode('left'))
->raw(sprintf(') && is_string($%s = ', $right))
->subcompile($this->getNode('right'))
->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right))
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('');
}
}

class_alias('Twig\Node\Expression\Binary\EndsWithBinary', 'Twig_Node_Expression_Binary_EndsWith');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class StartsWithBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$left = $compiler->getVarName();
$right = $compiler->getVarName();
$compiler
->raw(sprintf('(is_string($%s = ', $left))
->subcompile($this->getNode('left'))
->raw(sprintf(') && is_string($%s = ', $right))
->subcompile($this->getNode('right'))
->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right))
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('');
}
}

class_alias('Twig\Node\Expression\Binary\StartsWithBinary', 'Twig_Node_Expression_Binary_StartsWith');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class NotEqualBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('!=');
}
}

class_alias('Twig\Node\Expression\Binary\NotEqualBinary', 'Twig_Node_Expression_Binary_NotEqual');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class FloorDivBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$compiler->raw('(int) floor(');
parent::compile($compiler);
$compiler->raw(')');
}

public function operator(Compiler $compiler)
{
return $compiler->raw('/');
}
}

class_alias('Twig\Node\Expression\Binary\FloorDivBinary', 'Twig_Node_Expression_Binary_FloorDiv');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class GreaterBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('>');
}
}

class_alias('Twig\Node\Expression\Binary\GreaterBinary', 'Twig_Node_Expression_Binary_Greater');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class ConcatBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('.');
}
}

class_alias('Twig\Node\Expression\Binary\ConcatBinary', 'Twig_Node_Expression_Binary_Concat');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class ModBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('%');
}
}

class_alias('Twig\Node\Expression\Binary\ModBinary', 'Twig_Node_Expression_Binary_Mod');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class EqualBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('==');
}
}

class_alias('Twig\Node\Expression\Binary\EqualBinary', 'Twig_Node_Expression_Binary_Equal');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class BitwiseOrBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('|');
}
}

class_alias('Twig\Node\Expression\Binary\BitwiseOrBinary', 'Twig_Node_Expression_Binary_BitwiseOr');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class DivBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('/');
}
}

class_alias('Twig\Node\Expression\Binary\DivBinary', 'Twig_Node_Expression_Binary_Div');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class BitwiseXorBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('^');
}
}

class_alias('Twig\Node\Expression\Binary\BitwiseXorBinary', 'Twig_Node_Expression_Binary_BitwiseXor');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class GreaterEqualBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('>=');
}
}

class_alias('Twig\Node\Expression\Binary\GreaterEqualBinary', 'Twig_Node_Expression_Binary_GreaterEqual');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class SubBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('-');
}
}

class_alias('Twig\Node\Expression\Binary\SubBinary', 'Twig_Node_Expression_Binary_Sub');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class MulBinary extends AbstractBinary
{
public function operator(Compiler $compiler)
{
return $compiler->raw('*');
}
}

class_alias('Twig\Node\Expression\Binary\MulBinary', 'Twig_Node_Expression_Binary_Mul');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class RangeBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$compiler
->raw('range(')
->subcompile($this->getNode('left'))
->raw(', ')
->subcompile($this->getNode('right'))
->raw(')')
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('..');
}
}

class_alias('Twig\Node\Expression\Binary\RangeBinary', 'Twig_Node_Expression_Binary_Range');
<?php










namespace Twig\Node\Expression\Binary;

use Twig\Compiler;

class InBinary extends AbstractBinary
{
public function compile(Compiler $compiler)
{
$compiler
->raw('twig_in_filter(')
->subcompile($this->getNode('left'))
->raw(', ')
->subcompile($this->getNode('right'))
->raw(')')
;
}

public function operator(Compiler $compiler)
{
return $compiler->raw('in');
}
}

class_alias('Twig\Node\Expression\Binary\InBinary', 'Twig_Node_Expression_Binary_In');
<?php











namespace Twig\Node\Expression\Binary;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;

abstract class AbstractBinary extends AbstractExpression
{
public function __construct(\Twig_NodeInterface $left, \Twig_NodeInterface $right, $lineno)
{
parent::__construct(['left' => $left, 'right' => $right], [], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler
->raw('(')
->subcompile($this->getNode('left'))
->raw(' ')
;
$this->operator($compiler);
$compiler
->raw(' ')
->subcompile($this->getNode('right'))
->raw(')')
;
}

abstract public function operator(Compiler $compiler);
}

class_alias('Twig\Node\Expression\Binary\AbstractBinary', 'Twig_Node_Expression_Binary');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;

class ArrayExpression extends AbstractExpression
{
protected $index;

public function __construct(array $elements, $lineno)
{
parent::__construct($elements, [], $lineno);

$this->index = -1;
foreach ($this->getKeyValuePairs() as $pair) {
if ($pair['key'] instanceof ConstantExpression && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) {
$this->index = $pair['key']->getAttribute('value');
}
}
}

public function getKeyValuePairs()
{
$pairs = [];

foreach (array_chunk($this->nodes, 2) as $pair) {
$pairs[] = [
'key' => $pair[0],
'value' => $pair[1],
];
}

return $pairs;
}

public function hasElement(AbstractExpression $key)
{
foreach ($this->getKeyValuePairs() as $pair) {


if ((string) $key === (string) $pair['key']) {
return true;
}
}

return false;
}

public function addElement(AbstractExpression $value, AbstractExpression $key = null)
{
if (null === $key) {
$key = new ConstantExpression(++$this->index, $value->getTemplateLine());
}

array_push($this->nodes, $key, $value);
}

public function compile(Compiler $compiler)
{
$compiler->raw('[');
$first = true;
foreach ($this->getKeyValuePairs() as $pair) {
if (!$first) {
$compiler->raw(', ');
}
$first = false;

$compiler
->subcompile($pair['key'])
->raw(' => ')
->subcompile($pair['value'])
;
}
$compiler->raw(']');
}
}

class_alias('Twig\Node\Expression\ArrayExpression', 'Twig_Node_Expression_Array');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;

class ConditionalExpression extends AbstractExpression
{
public function __construct(AbstractExpression $expr1, AbstractExpression $expr2, AbstractExpression $expr3, $lineno)
{
parent::__construct(['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler
->raw('((')
->subcompile($this->getNode('expr1'))
->raw(') ? (')
->subcompile($this->getNode('expr2'))
->raw(') : (')
->subcompile($this->getNode('expr3'))
->raw('))')
;
}
}

class_alias('Twig\Node\Expression\ConditionalExpression', 'Twig_Node_Expression_Conditional');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\TwigFilter;

class FilterExpression extends CallExpression
{
public function __construct(\Twig_NodeInterface $node, ConstantExpression $filterName, \Twig_NodeInterface $arguments, $lineno, $tag = null)
{
parent::__construct(['node' => $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$name = $this->getNode('filter')->getAttribute('value');
$filter = $compiler->getEnvironment()->getFilter($name);

$this->setAttribute('name', $name);
$this->setAttribute('type', 'filter');
$this->setAttribute('thing', $filter);
$this->setAttribute('needs_environment', $filter->needsEnvironment());
$this->setAttribute('needs_context', $filter->needsContext());
$this->setAttribute('arguments', $filter->getArguments());
if ($filter instanceof \Twig_FilterCallableInterface || $filter instanceof TwigFilter) {
$this->setAttribute('callable', $filter->getCallable());
}
if ($filter instanceof TwigFilter) {
$this->setAttribute('is_variadic', $filter->isVariadic());
}

$this->compileCallable($compiler);
}
}

class_alias('Twig\Node\Expression\FilterExpression', 'Twig_Node_Expression_Filter');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;

class NameExpression extends AbstractExpression
{
protected $specialVars = [
'_self' => '$this',
'_context' => '$context',
'_charset' => '$this->env->getCharset()',
];

public function __construct($name, $lineno)
{
parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno);
}

public function compile(Compiler $compiler)
{
$name = $this->getAttribute('name');

$compiler->addDebugInfo($this);

if ($this->getAttribute('is_defined_test')) {
if ($this->isSpecial()) {
$compiler->repr(true);
} elseif (\PHP_VERSION_ID >= 70400) {
$compiler
->raw('array_key_exists(')
->string($name)
->raw(', $context)')
;
} else {
$compiler
->raw('(isset($context[')
->string($name)
->raw(']) || array_key_exists(')
->string($name)
->raw(', $context))')
;
}
} elseif ($this->isSpecial()) {
$compiler->raw($this->specialVars[$name]);
} elseif ($this->getAttribute('always_defined')) {
$compiler
->raw('$context[')
->string($name)
->raw(']')
;
} else {
if (\PHP_VERSION_ID >= 70000) {

$compiler
->raw('($context[')
->string($name)
->raw('] ?? ')
;

if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
$compiler->raw('null)');
} else {
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
}
} elseif (\PHP_VERSION_ID >= 50400) {

$compiler
->raw('(isset($context[')
->string($name)
->raw(']) ? $context[')
->string($name)
->raw('] : ')
;

if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
$compiler->raw('null)');
} else {
$compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
}
} else {
$compiler
->raw('$this->getContext($context, ')
->string($name)
;

if ($this->getAttribute('ignore_strict_check')) {
$compiler->raw(', true');
}

$compiler
->raw(')')
;
}
}
}

public function isSpecial()
{
return isset($this->specialVars[$this->getAttribute('name')]);
}

public function isSimple()
{
return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
}
}

class_alias('Twig\Node\Expression\NameExpression', 'Twig_Node_Expression_Name');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\Error\SyntaxError;
use Twig\Extension\ExtensionInterface;
use Twig\Node\Node;

abstract class CallExpression extends AbstractExpression
{
private $reflector;

protected function compileCallable(Compiler $compiler)
{
$closingParenthesis = false;
$isArray = false;
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
if (\is_string($callable) && false === strpos($callable, '::')) {
$compiler->raw($callable);
} else {
list($r, $callable) = $this->reflectCallable($callable);
if ($r instanceof \ReflectionMethod && \is_string($callable[0])) {
if ($r->isStatic()) {
$compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
} else {
$compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
}
} elseif ($r instanceof \ReflectionMethod && $callable[0] instanceof ExtensionInterface) {
$compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($callable[0]), $callable[1]));
} else {
$type = ucfirst($this->getAttribute('type'));
$compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', $type, $this->getAttribute('name')));
$closingParenthesis = true;
$isArray = true;
}
}
} else {
$compiler->raw($this->getAttribute('thing')->compile());
}

$this->compileArguments($compiler, $isArray);

if ($closingParenthesis) {
$compiler->raw(')');
}
}

protected function compileArguments(Compiler $compiler, $isArray = false)
{
$compiler->raw($isArray ? '[' : '(');

$first = true;

if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
$compiler->raw('$this->env');
$first = false;
}

if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
if (!$first) {
$compiler->raw(', ');
}
$compiler->raw('$context');
$first = false;
}

if ($this->hasAttribute('arguments')) {
foreach ($this->getAttribute('arguments') as $argument) {
if (!$first) {
$compiler->raw(', ');
}
$compiler->string($argument);
$first = false;
}
}

if ($this->hasNode('node')) {
if (!$first) {
$compiler->raw(', ');
}
$compiler->subcompile($this->getNode('node'));
$first = false;
}

if ($this->hasNode('arguments')) {
$callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;

$arguments = $this->getArguments($callable, $this->getNode('arguments'));

foreach ($arguments as $node) {
if (!$first) {
$compiler->raw(', ');
}
$compiler->subcompile($node);
$first = false;
}
}

$compiler->raw($isArray ? ']' : ')');
}

protected function getArguments($callable, $arguments)
{
$callType = $this->getAttribute('type');
$callName = $this->getAttribute('name');

$parameters = [];
$named = false;
foreach ($arguments as $name => $node) {
if (!\is_int($name)) {
$named = true;
$name = $this->normalizeName($name);
} elseif ($named) {
throw new SyntaxError(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
}

$parameters[$name] = $node;
}

$isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
if (!$named && !$isVariadic) {
return $parameters;
}

if (!$callable) {
if ($named) {
$message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
} else {
$message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
}

throw new \LogicException($message);
}

$callableParameters = $this->getCallableParameters($callable, $isVariadic);
$arguments = [];
$names = [];
$missingArguments = [];
$optionalArguments = [];
$pos = 0;
foreach ($callableParameters as $callableParameter) {
$name = $this->normalizeName($callableParameter->name);
if (\PHP_VERSION_ID >= 80000 && 'range' === $callable) {
if ('start' === $name) {
$name = 'low';
} elseif ('end' === $name) {
$name = 'high';
}
}

$names[] = $name;

if (\array_key_exists($name, $parameters)) {
if (\array_key_exists($pos, $parameters)) {
throw new SyntaxError(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
}

if (\count($missingArguments)) {
throw new SyntaxError(sprintf(
'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".',
$name, $callType, $callName, implode(', ', $names), \count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)
), $this->getTemplateLine(), $this->getSourceContext());
}

$arguments = array_merge($arguments, $optionalArguments);
$arguments[] = $parameters[$name];
unset($parameters[$name]);
$optionalArguments = [];
} elseif (\array_key_exists($pos, $parameters)) {
$arguments = array_merge($arguments, $optionalArguments);
$arguments[] = $parameters[$pos];
unset($parameters[$pos]);
$optionalArguments = [];
++$pos;
} elseif ($callableParameter->isDefaultValueAvailable()) {
$optionalArguments[] = new ConstantExpression($callableParameter->getDefaultValue(), -1);
} elseif ($callableParameter->isOptional()) {
if (empty($parameters)) {
break;
} else {
$missingArguments[] = $name;
}
} else {
throw new SyntaxError(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
}
}

if ($isVariadic) {
$arbitraryArguments = new ArrayExpression([], -1);
foreach ($parameters as $key => $value) {
if (\is_int($key)) {
$arbitraryArguments->addElement($value);
} else {
$arbitraryArguments->addElement($value, new ConstantExpression($key, -1));
}
unset($parameters[$key]);
}

if ($arbitraryArguments->count()) {
$arguments = array_merge($arguments, $optionalArguments);
$arguments[] = $arbitraryArguments;
}
}

if (!empty($parameters)) {
$unknownParameter = null;
foreach ($parameters as $parameter) {
if ($parameter instanceof Node) {
$unknownParameter = $parameter;
break;
}
}

throw new SyntaxError(
sprintf(
'Unknown argument%s "%s" for %s "%s(%s)".',
\count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
),
$unknownParameter ? $unknownParameter->getTemplateLine() : $this->getTemplateLine(),
$unknownParameter ? $unknownParameter->getSourceContext() : $this->getSourceContext()
);
}

return $arguments;
}

protected function normalizeName($name)
{
return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], $name));
}

private function getCallableParameters($callable, $isVariadic)
{
list($r) = $this->reflectCallable($callable);
if (null === $r) {
return [];
}

$parameters = $r->getParameters();
if ($this->hasNode('node')) {
array_shift($parameters);
}
if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
array_shift($parameters);
}
if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
array_shift($parameters);
}
if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
foreach ($this->getAttribute('arguments') as $argument) {
array_shift($parameters);
}
}
if ($isVariadic) {
$argument = end($parameters);
$isArray = $argument && $argument->hasType() && 'array' === $argument->getType()->getName();
if ($isArray && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {
array_pop($parameters);
} else {
$callableName = $r->name;
if ($r instanceof \ReflectionMethod) {
$callableName = $r->getDeclaringClass()->name.'::'.$callableName;
}

throw new \LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
}
}

return $parameters;
}

private function reflectCallable($callable)
{
if (null !== $this->reflector) {
return $this->reflector;
}

if (\is_array($callable)) {
if (!method_exists($callable[0], $callable[1])) {

return [null, []];
}
$r = new \ReflectionMethod($callable[0], $callable[1]);
} elseif (\is_object($callable) && !$callable instanceof \Closure) {
$r = new \ReflectionObject($callable);
$r = $r->getMethod('__invoke');
$callable = [$callable, '__invoke'];
} elseif (\is_string($callable) && false !== $pos = strpos($callable, '::')) {
$class = substr($callable, 0, $pos);
$method = substr($callable, $pos + 2);
if (!method_exists($class, $method)) {

return [null, []];
}
$r = new \ReflectionMethod($callable);
$callable = [$class, $method];
} else {
$r = new \ReflectionFunction($callable);
}

return $this->reflector = [$r, $callable];
}
}

class_alias('Twig\Node\Expression\CallExpression', 'Twig_Node_Expression_Call');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\Node\Node;




final class InlinePrint extends AbstractExpression
{
public function __construct(Node $node, $lineno)
{
parent::__construct(['node' => $node], [], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler
->raw('print (')
->subcompile($this->getNode('node'))
->raw(')')
;
}
}
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\TwigTest;

class TestExpression extends CallExpression
{
public function __construct(\Twig_NodeInterface $node, $name, ?\Twig_NodeInterface $arguments, $lineno)
{
$nodes = ['node' => $node];
if (null !== $arguments) {
$nodes['arguments'] = $arguments;
}

parent::__construct($nodes, ['name' => $name], $lineno);
}

public function compile(Compiler $compiler)
{
$name = $this->getAttribute('name');
$test = $compiler->getEnvironment()->getTest($name);

$this->setAttribute('name', $name);
$this->setAttribute('type', 'test');
$this->setAttribute('thing', $test);
if ($test instanceof TwigTest) {
$this->setAttribute('arguments', $test->getArguments());
}
if ($test instanceof \Twig_TestCallableInterface || $test instanceof TwigTest) {
$this->setAttribute('callable', $test->getCallable());
}
if ($test instanceof TwigTest) {
$this->setAttribute('is_variadic', $test->isVariadic());
}

$this->compileCallable($compiler);
}
}

class_alias('Twig\Node\Expression\TestExpression', 'Twig_Node_Expression_Test');
<?php











namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\Template;

class GetAttrExpression extends AbstractExpression
{
public function __construct(AbstractExpression $node, AbstractExpression $attribute, ?AbstractExpression $arguments, string $type, int $lineno)
{
$nodes = ['node' => $node, 'attribute' => $attribute];
if (null !== $arguments) {
$nodes['arguments'] = $arguments;
}

parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false], $lineno);
}

public function compile(Compiler $compiler)
{
if ($this->getAttribute('disable_c_ext')) {
@trigger_error(sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), \E_USER_DEPRECATED);
}

if (\function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
$compiler->raw('twig_template_get_attributes($this, ');
} else {
$compiler->raw('$this->getAttribute(');
}

if ($this->getAttribute('ignore_strict_check')) {
$this->getNode('node')->setAttribute('ignore_strict_check', true);
}

$compiler->subcompile($this->getNode('node'));

$compiler->raw(', ')->subcompile($this->getNode('attribute'));


$needFourth = $this->getAttribute('ignore_strict_check');
$needThird = $needFourth || $this->getAttribute('is_defined_test');
$needSecond = $needThird || Template::ANY_CALL !== $this->getAttribute('type');
$needFirst = $needSecond || $this->hasNode('arguments');

if ($needFirst) {
if ($this->hasNode('arguments')) {
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
} else {
$compiler->raw(', []');
}
}

if ($needSecond) {
$compiler->raw(', ')->repr($this->getAttribute('type'));
}

if ($needThird) {
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
}

if ($needFourth) {
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
}

$compiler->raw(')');
}
}

class_alias('Twig\Node\Expression\GetAttrExpression', 'Twig_Node_Expression_GetAttr');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\TwigFunction;

class FunctionExpression extends CallExpression
{
public function __construct($name, \Twig_NodeInterface $arguments, $lineno)
{
parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => false], $lineno);
}

public function compile(Compiler $compiler)
{
$name = $this->getAttribute('name');
$function = $compiler->getEnvironment()->getFunction($name);

$this->setAttribute('name', $name);
$this->setAttribute('type', 'function');
$this->setAttribute('thing', $function);
$this->setAttribute('needs_environment', $function->needsEnvironment());
$this->setAttribute('needs_context', $function->needsContext());
$this->setAttribute('arguments', $function->getArguments());
if ($function instanceof \Twig_FunctionCallableInterface || $function instanceof TwigFunction) {
$callable = $function->getCallable();
if ('constant' === $name && $this->getAttribute('is_defined_test')) {
$callable = 'twig_constant_is_defined';
}

$this->setAttribute('callable', $callable);
}
if ($function instanceof TwigFunction) {
$this->setAttribute('is_variadic', $function->isVariadic());
}

$this->compileCallable($compiler);
}
}

class_alias('Twig\Node\Expression\FunctionExpression', 'Twig_Node_Expression_Function');
<?php










namespace Twig\Node\Expression;

use Twig\Compiler;
use Twig\Node\Expression\Binary\AndBinary;
use Twig\Node\Expression\Test\DefinedTest;
use Twig\Node\Expression\Test\NullTest;
use Twig\Node\Expression\Unary\NotUnary;
use Twig\Node\Node;

class NullCoalesceExpression extends ConditionalExpression
{
public function __construct(\Twig_NodeInterface $left, \Twig_NodeInterface $right, $lineno)
{
$test = new DefinedTest(clone $left, 'defined', new Node(), $left->getTemplateLine());

if (!$left instanceof BlockReferenceExpression) {
$test = new AndBinary(
$test,
new NotUnary(new NullTest($left, 'null', new Node(), $left->getTemplateLine()), $left->getTemplateLine()),
$left->getTemplateLine()
);
}

parent::__construct($test, $left, $right, $lineno);
}

public function compile(Compiler $compiler)
{







if (\PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof NameExpression) {
$this->getNode('expr2')->setAttribute('always_defined', true);
$compiler
->raw('((')
->subcompile($this->getNode('expr2'))
->raw(') ?? (')
->subcompile($this->getNode('expr3'))
->raw('))')
;
} else {
parent::compile($compiler);
}
}
}

class_alias('Twig\Node\Expression\NullCoalesceExpression', 'Twig_Node_Expression_NullCoalesce');
<?php











namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;






class PrintNode extends Node implements NodeOutputInterface
{
public function __construct(AbstractExpression $expr, $lineno, $tag = null)
{
parent::__construct(['expr' => $expr], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('echo ')
->subcompile($this->getNode('expr'))
->raw(";\n")
;
}
}

class_alias('Twig\Node\PrintNode', 'Twig_Node_Print');
<?php










namespace Twig\Node;






class BodyNode extends Node
{
}

class_alias('Twig\Node\BodyNode', 'Twig_Node_Body');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;






class DoNode extends Node
{
public function __construct(AbstractExpression $expr, $lineno, $tag = null)
{
parent::__construct(['expr' => $expr], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('')
->subcompile($this->getNode('expr'))
->raw(";\n")
;
}
}

class_alias('Twig\Node\DoNode', 'Twig_Node_Do');
<?php











namespace Twig\Node;

use Twig\Compiler;






class TextNode extends Node implements NodeOutputInterface
{
public function __construct($data, $lineno)
{
parent::__construct([], ['data' => $data], $lineno);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('echo ')
->string($this->getAttribute('data'))
->raw(";\n")
;
}
}

class_alias('Twig\Node\TextNode', 'Twig_Node_Text');
<?php











namespace Twig\Node;

use Twig\Compiler;






class IfNode extends Node
{
public function __construct(\Twig_NodeInterface $tests, ?\Twig_NodeInterface $else, $lineno, $tag = null)
{
$nodes = ['tests' => $tests];
if (null !== $else) {
$nodes['else'] = $else;
}

parent::__construct($nodes, [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->addDebugInfo($this);
for ($i = 0, $count = \count($this->getNode('tests')); $i < $count; $i += 2) {
if ($i > 0) {
$compiler
->outdent()
->write('} elseif (')
;
} else {
$compiler
->write('if (')
;
}

$compiler
->subcompile($this->getNode('tests')->getNode($i))
->raw(") {\n")
->indent()
->subcompile($this->getNode('tests')->getNode($i + 1))
;
}

if ($this->hasNode('else')) {
$compiler
->outdent()
->write("} else {\n")
->indent()
->subcompile($this->getNode('else'))
;
}

$compiler
->outdent()
->write("}\n");
}
}

class_alias('Twig\Node\IfNode', 'Twig_Node_If');
<?php










namespace Twig\Node;

use Twig\Compiler;












class AutoEscapeNode extends Node
{
public function __construct($value, \Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
{
parent::__construct(['body' => $body], ['value' => $value], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->subcompile($this->getNode('body'));
}
}

class_alias('Twig\Node\AutoEscapeNode', 'Twig_Node_AutoEscape');
<?php










namespace Twig\Node;

use Twig\Compiler;






class WithNode extends Node
{
public function __construct(Node $body, ?Node $variables, $only, $lineno, $tag = null)
{
$nodes = ['body' => $body];
if (null !== $variables) {
$nodes['variables'] = $variables;
}

parent::__construct($nodes, ['only' => (bool) $only], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->addDebugInfo($this);

if ($this->hasNode('variables')) {
$node = $this->getNode('variables');
$varsName = $compiler->getVarName();
$compiler
->write(sprintf('$%s = ', $varsName))
->subcompile($node)
->raw(";\n")
->write(sprintf("if (!twig_test_iterable(\$%s)) {\n", $varsName))
->indent()
->write("throw new RuntimeError('Variables passed to the \"with\" tag must be a hash.', ")
->repr($node->getTemplateLine())
->raw(", \$this->getSourceContext());\n")
->outdent()
->write("}\n")
->write(sprintf("\$%s = twig_to_array(\$%s);\n", $varsName, $varsName))
;

if ($this->getAttribute('only')) {
$compiler->write("\$context = ['_parent' => \$context];\n");
} else {
$compiler->write("\$context['_parent'] = \$context;\n");
}

$compiler->write(sprintf("\$context = \$this->env->mergeGlobals(array_merge(\$context, \$%s));\n", $varsName));
} else {
$compiler->write("\$context['_parent'] = \$context;\n");
}

$compiler
->subcompile($this->getNode('body'))
->write("\$context = \$context['_parent'];\n")
;
}
}

class_alias('Twig\Node\WithNode', 'Twig_Node_With');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\ConstantExpression;






class SetNode extends Node implements NodeCaptureInterface
{
public function __construct($capture, \Twig_NodeInterface $names, \Twig_NodeInterface $values, $lineno, $tag = null)
{
parent::__construct(['names' => $names, 'values' => $values], ['capture' => $capture, 'safe' => false], $lineno, $tag);






if ($this->getAttribute('capture')) {
$this->setAttribute('safe', true);

$values = $this->getNode('values');
if ($values instanceof TextNode) {
$this->setNode('values', new ConstantExpression($values->getAttribute('data'), $values->getTemplateLine()));
$this->setAttribute('capture', false);
}
}
}

public function compile(Compiler $compiler)
{
$compiler->addDebugInfo($this);

if (\count($this->getNode('names')) > 1) {
$compiler->write('list(');
foreach ($this->getNode('names') as $idx => $node) {
if ($idx) {
$compiler->raw(', ');
}

$compiler->subcompile($node);
}
$compiler->raw(')');
} else {
if ($this->getAttribute('capture')) {
if ($compiler->getEnvironment()->isDebug()) {
$compiler->write("ob_start();\n");
} else {
$compiler->write("ob_start(function () { return ''; });\n");
}
$compiler
->subcompile($this->getNode('values'))
;
}

$compiler->subcompile($this->getNode('names'), false);

if ($this->getAttribute('capture')) {
$compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset())");
}
}

if (!$this->getAttribute('capture')) {
$compiler->raw(' = ');

if (\count($this->getNode('names')) > 1) {
$compiler->write('[');
foreach ($this->getNode('values') as $idx => $value) {
if ($idx) {
$compiler->raw(', ');
}

$compiler->subcompile($value);
}
$compiler->raw(']');
} else {
if ($this->getAttribute('safe')) {
$compiler
->raw("('' === \$tmp = ")
->subcompile($this->getNode('values'))
->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())")
;
} else {
$compiler->subcompile($this->getNode('values'));
}
}
}

$compiler->raw(";\n");
}
}

class_alias('Twig\Node\SetNode', 'Twig_Node_Set');
<?php











namespace Twig\Node;

use Twig\Compiler;
use Twig\Source;






class Node implements \Twig_NodeInterface
{
protected $nodes;
protected $attributes;
protected $lineno;
protected $tag;

private $name;
private $sourceContext;







public function __construct(array $nodes = [], array $attributes = [], $lineno = 0, $tag = null)
{
foreach ($nodes as $name => $node) {
if (!$node instanceof \Twig_NodeInterface) {
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, static::class), \E_USER_DEPRECATED);
}
}
$this->nodes = $nodes;
$this->attributes = $attributes;
$this->lineno = $lineno;
$this->tag = $tag;
}

public function __toString()
{
$attributes = [];
foreach ($this->attributes as $name => $value) {
$attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
}

$repr = [static::class.'('.implode(', ', $attributes)];

if (\count($this->nodes)) {
foreach ($this->nodes as $name => $node) {
$len = \strlen($name) + 4;
$noderepr = [];
foreach (explode("\n", (string) $node) as $line) {
$noderepr[] = str_repeat(' ', $len).$line;
}

$repr[] = sprintf('  %s: %s', $name, ltrim(implode("\n", $noderepr)));
}

$repr[] = ')';
} else {
$repr[0] .= ')';
}

return implode("\n", $repr);
}




public function toXml($asDom = false)
{
@trigger_error(sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), \E_USER_DEPRECATED);

$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
$dom->appendChild($xml = $dom->createElement('twig'));

$xml->appendChild($node = $dom->createElement('node'));
$node->setAttribute('class', static::class);

foreach ($this->attributes as $name => $value) {
$node->appendChild($attribute = $dom->createElement('attribute'));
$attribute->setAttribute('name', $name);
$attribute->appendChild($dom->createTextNode($value));
}

foreach ($this->nodes as $name => $n) {
if (null === $n) {
continue;
}

$child = $n->toXml(true)->getElementsByTagName('node')->item(0);
$child = $dom->importNode($child, true);
$child->setAttribute('name', $name);

$node->appendChild($child);
}

return $asDom ? $dom : $dom->saveXML();
}

public function compile(Compiler $compiler)
{
foreach ($this->nodes as $node) {
$node->compile($compiler);
}
}

public function getTemplateLine()
{
return $this->lineno;
}




public function getLine()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateLine() instead.', \E_USER_DEPRECATED);

return $this->lineno;
}

public function getNodeTag()
{
return $this->tag;
}




public function hasAttribute($name)
{
return \array_key_exists($name, $this->attributes);
}




public function getAttribute($name)
{
if (!\array_key_exists($name, $this->attributes)) {
throw new \LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, static::class));
}

return $this->attributes[$name];
}





public function setAttribute($name, $value)
{
$this->attributes[$name] = $value;
}

public function removeAttribute($name)
{
unset($this->attributes[$name]);
}




public function hasNode($name)
{
return \array_key_exists($name, $this->nodes);
}




public function getNode($name)
{
if (!\array_key_exists($name, $this->nodes)) {
throw new \LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, static::class));
}

return $this->nodes[$name];
}

public function setNode($name, $node = null)
{
if (!$node instanceof \Twig_NodeInterface) {
@trigger_error(sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, static::class), \E_USER_DEPRECATED);
}

$this->nodes[$name] = $node;
}

public function removeNode($name)
{
unset($this->nodes[$name]);
}




public function count()
{
return \count($this->nodes);
}




public function getIterator()
{
return new \ArrayIterator($this->nodes);
}

public function setTemplateName($name)
{
$this->name = $name;
foreach ($this->nodes as $node) {
if (null !== $node) {
$node->setTemplateName($name);
}
}
}

public function getTemplateName()
{
return $this->name;
}

public function setSourceContext(Source $source)
{
$this->sourceContext = $source;
foreach ($this->nodes as $node) {
if ($node instanceof self) {
$node->setSourceContext($source);
}
}
}

public function getSourceContext()
{
return $this->sourceContext;
}




public function setFilename($name)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', \E_USER_DEPRECATED);

$this->setTemplateName($name);
}




public function getFilename()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', \E_USER_DEPRECATED);

return $this->name;
}
}

class_alias('Twig\Node\Node', 'Twig_Node');


class_exists('Twig\Compiler');
<?php











namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Source;










class ModuleNode extends Node
{
public function __construct(\Twig_NodeInterface $body, ?AbstractExpression $parent, \Twig_NodeInterface $blocks, \Twig_NodeInterface $macros, \Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
{
if (!$name instanceof Source) {
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a \Twig\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
$source = new Source($source, $name);
} else {
$source = $name;
}

$nodes = [
'body' => $body,
'blocks' => $blocks,
'macros' => $macros,
'traits' => $traits,
'display_start' => new Node(),
'display_end' => new Node(),
'constructor_start' => new Node(),
'constructor_end' => new Node(),
'class_end' => new Node(),
];
if (null !== $parent) {
$nodes['parent'] = $parent;
}


parent::__construct($nodes, [

'source' => $source->getCode(),

'filename' => $source->getName(),
'index' => null,
'embedded_templates' => $embeddedTemplates,
], 1);


$this->setTemplateName($source->getName());
$this->setSourceContext($source);
}

public function setIndex($index)
{
$this->setAttribute('index', $index);
}

public function compile(Compiler $compiler)
{
$this->compileTemplate($compiler);

foreach ($this->getAttribute('embedded_templates') as $template) {
$compiler->subcompile($template);
}
}

protected function compileTemplate(Compiler $compiler)
{
if (!$this->getAttribute('index')) {
$compiler->write('<?php');
}

$this->compileClassHeader($compiler);

if (
\count($this->getNode('blocks'))
|| \count($this->getNode('traits'))
|| !$this->hasNode('parent')
|| $this->getNode('parent') instanceof ConstantExpression
|| \count($this->getNode('constructor_start'))
|| \count($this->getNode('constructor_end'))
) {
$this->compileConstructor($compiler);
}

$this->compileGetParent($compiler);

$this->compileDisplay($compiler);

$compiler->subcompile($this->getNode('blocks'));

$this->compileMacros($compiler);

$this->compileGetTemplateName($compiler);

$this->compileIsTraitable($compiler);

$this->compileDebugInfo($compiler);

$this->compileGetSource($compiler);

$this->compileGetSourceContext($compiler);

$this->compileClassFooter($compiler);
}

protected function compileGetParent(Compiler $compiler)
{
if (!$this->hasNode('parent')) {
return;
}
$parent = $this->getNode('parent');

$compiler
->write("protected function doGetParent(array \$context)\n", "{\n")
->indent()
->addDebugInfo($parent)
->write('return ')
;

if ($parent instanceof ConstantExpression) {
$compiler->subcompile($parent);
} else {
$compiler
->raw('$this->loadTemplate(')
->subcompile($parent)
->raw(', ')
->repr($this->getSourceContext()->getName())
->raw(', ')
->repr($parent->getTemplateLine())
->raw(')')
;
}

$compiler
->raw(";\n")
->outdent()
->write("}\n\n")
;
}

protected function compileClassHeader(Compiler $compiler)
{
$compiler
->write("\n\n")
;
if (!$this->getAttribute('index')) {
$compiler
->write("use Twig\Environment;\n")
->write("use Twig\Error\LoaderError;\n")
->write("use Twig\Error\RuntimeError;\n")
->write("use Twig\Markup;\n")
->write("use Twig\Sandbox\SecurityError;\n")
->write("use Twig\Sandbox\SecurityNotAllowedTagError;\n")
->write("use Twig\Sandbox\SecurityNotAllowedFilterError;\n")
->write("use Twig\Sandbox\SecurityNotAllowedFunctionError;\n")
->write("use Twig\Source;\n")
->write("use Twig\Template;\n\n")
;
}
$compiler

->write('/* '.str_replace('*/', '* /', $this->getSourceContext()->getName())." */\n")
->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getSourceContext()->getName(), $this->getAttribute('index')))
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
->write("{\n")
->indent()
;
}

protected function compileConstructor(Compiler $compiler)
{
$compiler
->write("public function __construct(Environment \$env)\n", "{\n")
->indent()
->subcompile($this->getNode('constructor_start'))
->write("parent::__construct(\$env);\n\n")
;


if (!$this->hasNode('parent')) {
$compiler->write("\$this->parent = false;\n\n");
}

$countTraits = \count($this->getNode('traits'));
if ($countTraits) {

foreach ($this->getNode('traits') as $i => $trait) {
$this->compileLoadTemplate($compiler, $trait->getNode('template'), sprintf('$_trait_%s', $i));

$node = $trait->getNode('template');
$compiler
->addDebugInfo($node)
->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))
->indent()
->write("throw new RuntimeError('Template \"'.")
->subcompile($trait->getNode('template'))
->raw(".'\" cannot be used as a trait.', ")
->repr($node->getTemplateLine())
->raw(", \$this->getSourceContext());\n")
->outdent()
->write("}\n")
->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i))
;

foreach ($trait->getNode('targets') as $key => $value) {
$compiler
->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
->string($key)
->raw("])) {\n")
->indent()
->write("throw new RuntimeError(sprintf('Block ")
->string($key)
->raw(' is not defined in trait ')
->subcompile($trait->getNode('template'))
->raw(".'), ")
->repr($node->getTemplateLine())
->raw(", \$this->getSourceContext());\n")
->outdent()
->write("}\n\n")

->write(sprintf('$_trait_%s_blocks[', $i))
->subcompile($value)
->raw(sprintf('] = $_trait_%s_blocks[', $i))
->string($key)
->raw(sprintf(']; unset($_trait_%s_blocks[', $i))
->string($key)
->raw("]);\n\n")
;
}
}

if ($countTraits > 1) {
$compiler
->write("\$this->traits = array_merge(\n")
->indent()
;

for ($i = 0; $i < $countTraits; ++$i) {
$compiler
->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
;
}

$compiler
->outdent()
->write(");\n\n")
;
} else {
$compiler
->write("\$this->traits = \$_trait_0_blocks;\n\n")
;
}

$compiler
->write("\$this->blocks = array_merge(\n")
->indent()
->write("\$this->traits,\n")
->write("[\n")
;
} else {
$compiler
->write("\$this->blocks = [\n")
;
}


$compiler
->indent()
;

foreach ($this->getNode('blocks') as $name => $node) {
$compiler
->write(sprintf("'%s' => [\$this, 'block_%s'],\n", $name, $name))
;
}

if ($countTraits) {
$compiler
->outdent()
->write("]\n")
->outdent()
->write(");\n")
;
} else {
$compiler
->outdent()
->write("];\n")
;
}

$compiler
->subcompile($this->getNode('constructor_end'))
->outdent()
->write("}\n\n")
;
}

protected function compileDisplay(Compiler $compiler)
{
$compiler
->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n")
->indent()
->subcompile($this->getNode('display_start'))
->subcompile($this->getNode('body'))
;

if ($this->hasNode('parent')) {
$parent = $this->getNode('parent');

$compiler->addDebugInfo($parent);
if ($parent instanceof ConstantExpression) {
$compiler
->write('$this->parent = $this->loadTemplate(')
->subcompile($parent)
->raw(', ')
->repr($this->getSourceContext()->getName())
->raw(', ')
->repr($parent->getTemplateLine())
->raw(");\n")
;
$compiler->write('$this->parent');
} else {
$compiler->write('$this->getParent($context)');
}
$compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
}

$compiler
->subcompile($this->getNode('display_end'))
->outdent()
->write("}\n\n")
;
}

protected function compileClassFooter(Compiler $compiler)
{
$compiler
->subcompile($this->getNode('class_end'))
->outdent()
->write("}\n")
;
}

protected function compileMacros(Compiler $compiler)
{
$compiler->subcompile($this->getNode('macros'));
}

protected function compileGetTemplateName(Compiler $compiler)
{
$compiler
->write("public function getTemplateName()\n", "{\n")
->indent()
->write('return ')
->repr($this->getSourceContext()->getName())
->raw(";\n")
->outdent()
->write("}\n\n")
;
}

protected function compileIsTraitable(Compiler $compiler)
{







$traitable = !$this->hasNode('parent') && 0 === \count($this->getNode('macros'));
if ($traitable) {
if ($this->getNode('body') instanceof BodyNode) {
$nodes = $this->getNode('body')->getNode(0);
} else {
$nodes = $this->getNode('body');
}

if (!\count($nodes)) {
$nodes = new Node([$nodes]);
}

foreach ($nodes as $node) {
if (!\count($node)) {
continue;
}

if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) {
continue;
}

if ($node instanceof BlockReferenceNode) {
continue;
}

$traitable = false;
break;
}
}

if ($traitable) {
return;
}

$compiler
->write("public function isTraitable()\n", "{\n")
->indent()
->write(sprintf("return %s;\n", $traitable ? 'true' : 'false'))
->outdent()
->write("}\n\n")
;
}

protected function compileDebugInfo(Compiler $compiler)
{
$compiler
->write("public function getDebugInfo()\n", "{\n")
->indent()
->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true))))
->outdent()
->write("}\n\n")
;
}

protected function compileGetSource(Compiler $compiler)
{
$compiler
->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")
->write("public function getSource()\n", "{\n")
->indent()
->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")
->write('return $this->getSourceContext()->getCode();')
->raw("\n")
->outdent()
->write("}\n\n")
;
}

protected function compileGetSourceContext(Compiler $compiler)
{
$compiler
->write("public function getSourceContext()\n", "{\n")
->indent()
->write('return new Source(')
->string($compiler->getEnvironment()->isDebug() ? $this->getSourceContext()->getCode() : '')
->raw(', ')
->string($this->getSourceContext()->getName())
->raw(', ')
->string($this->getSourceContext()->getPath())
->raw(");\n")
->outdent()
->write("}\n")
;
}

protected function compileLoadTemplate(Compiler $compiler, $node, $var)
{
if ($node instanceof ConstantExpression) {
$compiler
->write(sprintf('%s = $this->loadTemplate(', $var))
->subcompile($node)
->raw(', ')
->repr($node->getTemplateName())
->raw(', ')
->repr($node->getTemplateLine())
->raw(");\n")
;
} else {
throw new \LogicException('Trait templates can only be constant nodes.');
}
}
}

class_alias('Twig\Node\ModuleNode', 'Twig_Node_Module');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ConstantExpression;






class EmbedNode extends IncludeNode
{

public function __construct($name, $index, ?AbstractExpression $variables, $only, $ignoreMissing, $lineno, $tag = null)
{
parent::__construct(new ConstantExpression('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);

$this->setAttribute('name', $name);

$this->setAttribute('filename', $name);
$this->setAttribute('index', $index);
}

protected function addGetTemplate(Compiler $compiler)
{
$compiler
->write('$this->loadTemplate(')
->string($this->getAttribute('name'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(', ')
->string($this->getAttribute('index'))
->raw(')')
;
}
}

class_alias('Twig\Node\EmbedNode', 'Twig_Node_Embed');
<?php










namespace Twig\Node;

use Twig\Compiler;




class CheckSecurityNode extends Node
{
protected $usedFilters;
protected $usedTags;
protected $usedFunctions;

public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
{
$this->usedFilters = $usedFilters;
$this->usedTags = $usedTags;
$this->usedFunctions = $usedFunctions;

parent::__construct();
}

public function compile(Compiler $compiler)
{
$tags = $filters = $functions = [];
foreach (['tags', 'filters', 'functions'] as $type) {
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
if ($node instanceof Node) {
${$type}[$name] = $node->getTemplateLine();
} else {
${$type}[$node] = null;
}
}
}

$compiler
->write("\n")
->write("public function checkSecurity()\n")
->write("{\n")
->indent()
->write('static $tags = ')->repr(array_filter($tags))->raw(";\n")
->write('static $filters = ')->repr(array_filter($filters))->raw(";\n")
->write('static $functions = ')->repr(array_filter($functions))->raw(";\n\n")
->write("try {\n")
->indent()
->write("\$this->sandbox->checkSecurity(\n")
->indent()
->write(!$tags ? "[],\n" : "['".implode("', '", array_keys($tags))."'],\n")
->write(!$filters ? "[],\n" : "['".implode("', '", array_keys($filters))."'],\n")
->write(!$functions ? "[]\n" : "['".implode("', '", array_keys($functions))."']\n")
->outdent()
->write(");\n")
->outdent()
->write("} catch (SecurityError \$e) {\n")
->indent()
->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")
->write("if (\$e instanceof SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
->outdent()
->write("} elseif (\$e instanceof SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
->outdent()
->write("} elseif (\$e instanceof SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
->indent()
->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
->outdent()
->write("}\n\n")
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
->outdent()
->write("}\n")
;
}
}

class_alias('Twig\Node\CheckSecurityNode', 'Twig_Node_CheckSecurity');
<?php











namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\AssignNameExpression;






class ForNode extends Node
{
protected $loop;

public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, ?AbstractExpression $ifexpr, \Twig_NodeInterface $body, ?\Twig_NodeInterface $else, $lineno, $tag = null)
{
$body = new Node([$body, $this->loop = new ForLoopNode($lineno, $tag)]);

if (null !== $ifexpr) {
$body = new IfNode(new Node([$ifexpr, $body]), null, $lineno, $tag);
}

$nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body];
if (null !== $else) {
$nodes['else'] = $else;
}

parent::__construct($nodes, ['with_loop' => true, 'ifexpr' => null !== $ifexpr], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write("\$context['_parent'] = \$context;\n")
->write("\$context['_seq'] = twig_ensure_traversable(")
->subcompile($this->getNode('seq'))
->raw(");\n")
;

if ($this->hasNode('else')) {
$compiler->write("\$context['_iterated'] = false;\n");
}

if ($this->getAttribute('with_loop')) {
$compiler
->write("\$context['loop'] = [\n")
->write("  'parent' => \$context['_parent'],\n")
->write("  'index0' => 0,\n")
->write("  'index'  => 1,\n")
->write("  'first'  => true,\n")
->write("];\n")
;

if (!$this->getAttribute('ifexpr')) {
$compiler
->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \Countable)) {\n")
->indent()
->write("\$length = count(\$context['_seq']);\n")
->write("\$context['loop']['revindex0'] = \$length - 1;\n")
->write("\$context['loop']['revindex'] = \$length;\n")
->write("\$context['loop']['length'] = \$length;\n")
->write("\$context['loop']['last'] = 1 === \$length;\n")
->outdent()
->write("}\n")
;
}
}

$this->loop->setAttribute('else', $this->hasNode('else'));
$this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
$this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));

$compiler
->write("foreach (\$context['_seq'] as ")
->subcompile($this->getNode('key_target'))
->raw(' => ')
->subcompile($this->getNode('value_target'))
->raw(") {\n")
->indent()
->subcompile($this->getNode('body'))
->outdent()
->write("}\n")
;

if ($this->hasNode('else')) {
$compiler
->write("if (!\$context['_iterated']) {\n")
->indent()
->subcompile($this->getNode('else'))
->outdent()
->write("}\n")
;
}

$compiler->write("\$_parent = \$context['_parent'];\n");


$compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n");


$compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
}
}

class_alias('Twig\Node\ForNode', 'Twig_Node_For');
<?php











namespace Twig\Node;

use Twig\Compiler;






class BlockNode extends Node
{
public function __construct($name, \Twig_NodeInterface $body, $lineno, $tag = null)
{
parent::__construct(['body' => $body], ['name' => $name], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write(sprintf("public function block_%s(\$context, array \$blocks = [])\n", $this->getAttribute('name')), "{\n")
->indent()
;

$compiler
->subcompile($this->getNode('body'))
->outdent()
->write("}\n\n")
;
}
}

class_alias('Twig\Node\BlockNode', 'Twig_Node_Block');
<?php










namespace Twig\Node;

use Twig\Compiler;








class SpacelessNode extends Node
{
public function __construct(\Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
{
parent::__construct(['body' => $body], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
;
if ($compiler->getEnvironment()->isDebug()) {
$compiler->write("ob_start();\n");
} else {
$compiler->write("ob_start(function () { return ''; });\n");
}
$compiler
->subcompile($this->getNode('body'))
->write("echo trim(preg_replace('/>\s+</', '><', ob_get_clean()));\n")
;
}
}

class_alias('Twig\Node\SpacelessNode', 'Twig_Node_Spaceless');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;












class SandboxedPrintNode extends PrintNode
{
public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('echo ')
;
$expr = $this->getNode('expr');
if ($expr instanceof ConstantExpression) {
$compiler
->subcompile($expr)
->raw(";\n")
;
} else {
$compiler
->write('$this->env->getExtension(\'\Twig\Extension\SandboxExtension\')->ensureToStringAllowed(')
->subcompile($expr)
->raw(");\n")
;
}
}








protected function removeNodeFilter(Node $node)
{
if ($node instanceof FilterExpression) {
return $this->removeNodeFilter($node->getNode('node'));
}

return $node;
}
}

class_alias('Twig\Node\SandboxedPrintNode', 'Twig_Node_SandboxedPrint');
<?php










namespace Twig\Node;






interface NodeOutputInterface
{
}

class_alias('Twig\Node\NodeOutputInterface', 'Twig_NodeOutputInterface');
<?php










namespace Twig\Node;

use Twig\Compiler;




class CheckSecurityCallNode extends Node
{
public function compile(Compiler $compiler)
{
$compiler
->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n")
->write("\$this->checkSecurity();\n")
;
}
}
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Error\SyntaxError;






class MacroNode extends Node
{
public const VARARGS_NAME = 'varargs';

public function __construct($name, \Twig_NodeInterface $body, \Twig_NodeInterface $arguments, $lineno, $tag = null)
{
foreach ($arguments as $argumentName => $argument) {
if (self::VARARGS_NAME === $argumentName) {
throw new SyntaxError(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine(), $argument->getSourceContext());
}
}

parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write(sprintf('public function get%s(', $this->getAttribute('name')))
;

$count = \count($this->getNode('arguments'));
$pos = 0;
foreach ($this->getNode('arguments') as $name => $default) {
$compiler
->raw('$__'.$name.'__ = ')
->subcompile($default)
;

if (++$pos < $count) {
$compiler->raw(', ');
}
}

if (\PHP_VERSION_ID >= 50600) {
if ($count) {
$compiler->raw(', ');
}

$compiler->raw('...$__varargs__');
}

$compiler
->raw(")\n")
->write("{\n")
->indent()
;

$compiler
->write("\$context = \$this->env->mergeGlobals([\n")
->indent()
;

foreach ($this->getNode('arguments') as $name => $default) {
$compiler
->write('')
->string($name)
->raw(' => $__'.$name.'__')
->raw(",\n")
;
}

$compiler
->write('')
->string(self::VARARGS_NAME)
->raw(' => ')
;

if (\PHP_VERSION_ID >= 50600) {
$compiler->raw("\$__varargs__,\n");
} else {
$compiler
->raw('func_num_args() > ')
->repr($count)
->raw(' ? array_slice(func_get_args(), ')
->repr($count)
->raw(") : [],\n")
;
}

$compiler
->outdent()
->write("]);\n\n")
->write("\$blocks = [];\n\n")
;
if ($compiler->getEnvironment()->isDebug()) {
$compiler->write("ob_start();\n");
} else {
$compiler->write("ob_start(function () { return ''; });\n");
}
$compiler
->write("try {\n")
->indent()
->subcompile($this->getNode('body'))
->outdent()
->write("} catch (\Exception \$e) {\n")
->indent()
->write("ob_end_clean();\n\n")
->write("throw \$e;\n")
->outdent()
->write("} catch (\Throwable \$e) {\n")
->indent()
->write("ob_end_clean();\n\n")
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")
->outdent()
->write("}\n\n")
;
}
}

class_alias('Twig\Node\MacroNode', 'Twig_Node_Macro');
<?php











namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;






class IncludeNode extends Node implements NodeOutputInterface
{
public function __construct(AbstractExpression $expr, ?AbstractExpression $variables, $only, $ignoreMissing, $lineno, $tag = null)
{
$nodes = ['expr' => $expr];
if (null !== $variables) {
$nodes['variables'] = $variables;
}

parent::__construct($nodes, ['only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler->addDebugInfo($this);

if ($this->getAttribute('ignore_missing')) {
$template = $compiler->getVarName();

$compiler
->write(sprintf("$%s = null;\n", $template))
->write("try {\n")
->indent()
->write(sprintf('$%s = ', $template))
;

$this->addGetTemplate($compiler);

$compiler
->raw(";\n")
->outdent()
->write("} catch (LoaderError \$e) {\n")
->indent()
->write("// ignore missing template\n")
->outdent()
->write("}\n")
->write(sprintf("if ($%s) {\n", $template))
->indent()
->write(sprintf('$%s->display(', $template))
;
$this->addTemplateArguments($compiler);
$compiler
->raw(");\n")
->outdent()
->write("}\n")
;
} else {
$this->addGetTemplate($compiler);
$compiler->raw('->display(');
$this->addTemplateArguments($compiler);
$compiler->raw(");\n");
}
}

protected function addGetTemplate(Compiler $compiler)
{
$compiler
->write('$this->loadTemplate(')
->subcompile($this->getNode('expr'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')')
;
}

protected function addTemplateArguments(Compiler $compiler)
{
if (!$this->hasNode('variables')) {
$compiler->raw(false === $this->getAttribute('only') ? '$context' : '[]');
} elseif (false === $this->getAttribute('only')) {
$compiler
->raw('twig_array_merge($context, ')
->subcompile($this->getNode('variables'))
->raw(')')
;
} else {
$compiler->raw('twig_to_array(');
$compiler->subcompile($this->getNode('variables'));
$compiler->raw(')');
}
}
}

class_alias('Twig\Node\IncludeNode', 'Twig_Node_Include');
<?php










namespace Twig\Node;






interface NodeCaptureInterface
{
}

class_alias('Twig\Node\NodeCaptureInterface', 'Twig_NodeCaptureInterface');
<?php










namespace Twig\Node;

use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\NameExpression;






class ImportNode extends Node
{
public function __construct(AbstractExpression $expr, AbstractExpression $var, $lineno, $tag = null)
{
parent::__construct(['expr' => $expr, 'var' => $var], [], $lineno, $tag);
}

public function compile(Compiler $compiler)
{
$compiler
->addDebugInfo($this)
->write('')
->subcompile($this->getNode('var'))
->raw(' = ')
;

if ($this->getNode('expr') instanceof NameExpression && '_self' === $this->getNode('expr')->getAttribute('name')) {
$compiler->raw('$this');
} else {
$compiler
->raw('$this->loadTemplate(')
->subcompile($this->getNode('expr'))
->raw(', ')
->repr($this->getTemplateName())
->raw(', ')
->repr($this->getTemplateLine())
->raw(')->unwrap()')
;
}

$compiler->raw(";\n");
}
}

class_alias('Twig\Node\ImportNode', 'Twig_Node_Import');
<?php










namespace Twig\Node;

use Twig\Compiler;




class SetTempNode extends Node
{
public function __construct($name, $lineno)
{
parent::__construct([], ['name' => $name], $lineno);
}

public function compile(Compiler $compiler)
{
$name = $this->getAttribute('name');
$compiler
->addDebugInfo($this)
->write('if (isset($context[')
->string($name)
->raw('])) { $_')
->raw($name)
->raw('_ = $context[')
->repr($name)
->raw(']; } else { $_')
->raw($name)
->raw("_ = null; }\n")
;
}
}

class_alias('Twig\Node\SetTempNode', 'Twig_Node_SetTemp');
<?php










namespace Twig\Loader;








interface ExistsLoaderInterface
{







public function exists($name);
}

class_alias('Twig\Loader\ExistsLoaderInterface', 'Twig_ExistsLoaderInterface');
<?php










namespace Twig\Loader;

use Twig\Error\LoaderError;






interface LoaderInterface
{











public function getSource($name);










public function getCacheKey($name);












public function isFresh($name, $time);
}

class_alias('Twig\Loader\LoaderInterface', 'Twig_LoaderInterface');
<?php










namespace Twig\Loader;

use Twig\Error\LoaderError;
use Twig\Source;






class FilesystemLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
{

public const MAIN_NAMESPACE = '__main__';

protected $paths = [];
protected $cache = [];
protected $errorCache = [];

private $rootPath;





public function __construct($paths = [], $rootPath = null)
{
$this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR;
if (null !== $rootPath && false !== ($realPath = realpath($rootPath))) {
$this->rootPath = $realPath.\DIRECTORY_SEPARATOR;
}

if ($paths) {
$this->setPaths($paths);
}
}








public function getPaths($namespace = self::MAIN_NAMESPACE)
{
return isset($this->paths[$namespace]) ? $this->paths[$namespace] : [];
}








public function getNamespaces()
{
return array_keys($this->paths);
}







public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
{
if (!\is_array($paths)) {
$paths = [$paths];
}

$this->paths[$namespace] = [];
foreach ($paths as $path) {
$this->addPath($path, $namespace);
}
}









public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{

$this->cache = $this->errorCache = [];

$checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
if (!is_dir($checkPath)) {
throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
}

$this->paths[$namespace][] = rtrim($path, '/\\');
}









public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
{

$this->cache = $this->errorCache = [];

$checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path;
if (!is_dir($checkPath)) {
throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
}

$path = rtrim($path, '/\\');

if (!isset($this->paths[$namespace])) {
$this->paths[$namespace][] = $path;
} else {
array_unshift($this->paths[$namespace], $path);
}
}

public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), \E_USER_DEPRECATED);

if (null === ($path = $this->findTemplate($name)) || false === $path) {
return '';
}

return file_get_contents($path);
}

public function getSourceContext($name)
{
if (null === ($path = $this->findTemplate($name)) || false === $path) {
return new Source('', $name, '');
}

return new Source(file_get_contents($path), $name, $path);
}

public function getCacheKey($name)
{
if (null === ($path = $this->findTemplate($name)) || false === $path) {
return '';
}
$len = \strlen($this->rootPath);
if (0 === strncmp($this->rootPath, $path, $len)) {
return substr($path, $len);
}

return $path;
}

public function exists($name)
{
$name = $this->normalizeName($name);

if (isset($this->cache[$name])) {
return true;
}

try {
return null !== ($path = $this->findTemplate($name, false)) && false !== $path;
} catch (LoaderError $e) {
@trigger_error(sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', static::class), \E_USER_DEPRECATED);

return false;
}
}

public function isFresh($name, $time)
{

if (null === ($path = $this->findTemplate($name)) || false === $path) {
return false;
}

return filemtime($path) < $time;
}








protected function findTemplate($name)
{
$throw = \func_num_args() > 1 ? func_get_arg(1) : true;
$name = $this->normalizeName($name);

if (isset($this->cache[$name])) {
return $this->cache[$name];
}

if (isset($this->errorCache[$name])) {
if (!$throw) {
return false;
}

throw new LoaderError($this->errorCache[$name]);
}

try {
list($namespace, $shortname) = $this->parseName($name);

$this->validateName($shortname);
} catch (LoaderError $e) {
if (!$throw) {
return false;
}

throw $e;
}

if (!isset($this->paths[$namespace])) {
$this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);

if (!$throw) {
return false;
}

throw new LoaderError($this->errorCache[$name]);
}

foreach ($this->paths[$namespace] as $path) {
if (!$this->isAbsolutePath($path)) {
$path = $this->rootPath.$path;
}

if (is_file($path.'/'.$shortname)) {
if (false !== $realpath = realpath($path.'/'.$shortname)) {
return $this->cache[$name] = $realpath;
}

return $this->cache[$name] = $path.'/'.$shortname;
}
}

$this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));

if (!$throw) {
return false;
}

throw new LoaderError($this->errorCache[$name]);
}

protected function parseName($name, $default = self::MAIN_NAMESPACE)
{
if (isset($name[0]) && '@' == $name[0]) {
if (false === $pos = strpos($name, '/')) {
throw new LoaderError(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
}

$namespace = substr($name, 1, $pos - 1);
$shortname = substr($name, $pos + 1);

return [$namespace, $shortname];
}

return [$default, $name];
}

protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}

protected function validateName($name)
{
if (false !== strpos($name, "\0")) {
throw new LoaderError('A template name cannot contain NUL bytes.');
}

$name = ltrim($name, '/');
$parts = explode('/', $name);
$level = 0;
foreach ($parts as $part) {
if ('..' === $part) {
--$level;
} elseif ('.' !== $part) {
++$level;
}

if ($level < 0) {
throw new LoaderError(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
}
}
}

private function isAbsolutePath($file)
{
return strspn($file, '/\\', 0, 1)
|| (\strlen($file) > 3 && ctype_alpha($file[0])
&& ':' === substr($file, 1, 1)
&& strspn($file, '/\\', 2, 1)
)
|| null !== parse_url($file, \PHP_URL_SCHEME)
;
}
}

class_alias('Twig\Loader\FilesystemLoader', 'Twig_Loader_Filesystem');
<?php










namespace Twig\Loader;

use Twig\Error\LoaderError;
use Twig\Source;















class ArrayLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
{
protected $templates = [];




public function __construct(array $templates = [])
{
$this->templates = $templates;
}







public function setTemplate($name, $template)
{
$this->templates[(string) $name] = $template;
}

public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), \E_USER_DEPRECATED);

$name = (string) $name;
if (!isset($this->templates[$name])) {
throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
}

return $this->templates[$name];
}

public function getSourceContext($name)
{
$name = (string) $name;
if (!isset($this->templates[$name])) {
throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
}

return new Source($this->templates[$name], $name);
}

public function exists($name)
{
return isset($this->templates[(string) $name]);
}

public function getCacheKey($name)
{
$name = (string) $name;
if (!isset($this->templates[$name])) {
throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
}

return $name.':'.$this->templates[$name];
}

public function isFresh($name, $time)
{
$name = (string) $name;
if (!isset($this->templates[$name])) {
throw new LoaderError(sprintf('Template "%s" is not defined.', $name));
}

return true;
}
}

class_alias('Twig\Loader\ArrayLoader', 'Twig_Loader_Array');
<?php










namespace Twig\Loader;

use Twig\Error\LoaderError;
use Twig\Source;








class ChainLoader implements LoaderInterface, ExistsLoaderInterface, SourceContextLoaderInterface
{
private $hasSourceCache = [];
protected $loaders = [];




public function __construct(array $loaders = [])
{
foreach ($loaders as $loader) {
$this->addLoader($loader);
}
}

public function addLoader(LoaderInterface $loader)
{
$this->loaders[] = $loader;
$this->hasSourceCache = [];
}




public function getLoaders()
{
return $this->loaders;
}

public function getSource($name)
{
@trigger_error(sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', static::class), \E_USER_DEPRECATED);

$exceptions = [];
foreach ($this->loaders as $loader) {
if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
continue;
}

try {
return $loader->getSource($name);
} catch (LoaderError $e) {
$exceptions[] = $e->getMessage();
}
}

throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}

public function getSourceContext($name)
{
$exceptions = [];
foreach ($this->loaders as $loader) {
if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
continue;
}

try {
if ($loader instanceof SourceContextLoaderInterface) {
return $loader->getSourceContext($name);
}

return new Source($loader->getSource($name), $name);
} catch (LoaderError $e) {
$exceptions[] = $e->getMessage();
}
}

throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}

public function exists($name)
{
$name = (string) $name;

if (isset($this->hasSourceCache[$name])) {
return $this->hasSourceCache[$name];
}

foreach ($this->loaders as $loader) {
if ($loader instanceof ExistsLoaderInterface) {
if ($loader->exists($name)) {
return $this->hasSourceCache[$name] = true;
}

continue;
}

try {
if ($loader instanceof SourceContextLoaderInterface) {
$loader->getSourceContext($name);
} else {
$loader->getSource($name);
}

return $this->hasSourceCache[$name] = true;
} catch (LoaderError $e) {
}
}

return $this->hasSourceCache[$name] = false;
}

public function getCacheKey($name)
{
$exceptions = [];
foreach ($this->loaders as $loader) {
if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
continue;
}

try {
return $loader->getCacheKey($name);
} catch (LoaderError $e) {
$exceptions[] = \get_class($loader).': '.$e->getMessage();
}
}

throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}

public function isFresh($name, $time)
{
$exceptions = [];
foreach ($this->loaders as $loader) {
if ($loader instanceof ExistsLoaderInterface && !$loader->exists($name)) {
continue;
}

try {
return $loader->isFresh($name, $time);
} catch (LoaderError $e) {
$exceptions[] = \get_class($loader).': '.$e->getMessage();
}
}

throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
}
}

class_alias('Twig\Loader\ChainLoader', 'Twig_Loader_Chain');
<?php










namespace Twig\Loader;

use Twig\Error\LoaderError;
use Twig\Source;








interface SourceContextLoaderInterface
{









public function getSourceContext($name);
}

class_alias('Twig\Loader\SourceContextLoaderInterface', 'Twig_SourceContextLoaderInterface');
<?php










namespace Twig;






class Markup implements \Countable
{
protected $content;
protected $charset;

public function __construct($content, $charset)
{
$this->content = (string) $content;
$this->charset = $charset;
}

public function __toString()
{
return $this->content;
}




public function count()
{
return \function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : \strlen($this->content);
}
}

class_alias('Twig\Markup', 'Twig_Markup');
<?php











namespace Twig;








class Token
{
protected $value;
protected $type;
protected $lineno;

public const EOF_TYPE = -1;
public const TEXT_TYPE = 0;
public const BLOCK_START_TYPE = 1;
public const VAR_START_TYPE = 2;
public const BLOCK_END_TYPE = 3;
public const VAR_END_TYPE = 4;
public const NAME_TYPE = 5;
public const NUMBER_TYPE = 6;
public const STRING_TYPE = 7;
public const OPERATOR_TYPE = 8;
public const PUNCTUATION_TYPE = 9;
public const INTERPOLATION_START_TYPE = 10;
public const INTERPOLATION_END_TYPE = 11;
public const ARROW_TYPE = 12;






public function __construct($type, $value, $lineno)
{
$this->type = $type;
$this->value = $value;
$this->lineno = $lineno;
}

public function __toString()
{
return sprintf('%s(%s)', self::typeToString($this->type, true), $this->value);
}














public function test($type, $values = null)
{
if (null === $values && !\is_int($type)) {
$values = $type;
$type = self::NAME_TYPE;
}

return ($this->type === $type) && (
null === $values ||
(\is_array($values) && \in_array($this->value, $values)) ||
$this->value == $values
);
}




public function getLine()
{
return $this->lineno;
}




public function getType()
{
return $this->type;
}




public function getValue()
{
return $this->value;
}









public static function typeToString($type, $short = false)
{
switch ($type) {
case self::EOF_TYPE:
$name = 'EOF_TYPE';
break;
case self::TEXT_TYPE:
$name = 'TEXT_TYPE';
break;
case self::BLOCK_START_TYPE:
$name = 'BLOCK_START_TYPE';
break;
case self::VAR_START_TYPE:
$name = 'VAR_START_TYPE';
break;
case self::BLOCK_END_TYPE:
$name = 'BLOCK_END_TYPE';
break;
case self::VAR_END_TYPE:
$name = 'VAR_END_TYPE';
break;
case self::NAME_TYPE:
$name = 'NAME_TYPE';
break;
case self::NUMBER_TYPE:
$name = 'NUMBER_TYPE';
break;
case self::STRING_TYPE:
$name = 'STRING_TYPE';
break;
case self::OPERATOR_TYPE:
$name = 'OPERATOR_TYPE';
break;
case self::PUNCTUATION_TYPE:
$name = 'PUNCTUATION_TYPE';
break;
case self::INTERPOLATION_START_TYPE:
$name = 'INTERPOLATION_START_TYPE';
break;
case self::INTERPOLATION_END_TYPE:
$name = 'INTERPOLATION_END_TYPE';
break;
case self::ARROW_TYPE:
$name = 'ARROW_TYPE';
break;
default:
throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type));
}

return $short ? $name : 'Twig\Token::'.$name;
}








public static function typeToEnglish($type)
{
switch ($type) {
case self::EOF_TYPE:
return 'end of template';
case self::TEXT_TYPE:
return 'text';
case self::BLOCK_START_TYPE:
return 'begin of statement block';
case self::VAR_START_TYPE:
return 'begin of print statement';
case self::BLOCK_END_TYPE:
return 'end of statement block';
case self::VAR_END_TYPE:
return 'end of print statement';
case self::NAME_TYPE:
return 'name';
case self::NUMBER_TYPE:
return 'number';
case self::STRING_TYPE:
return 'string';
case self::OPERATOR_TYPE:
return 'operator';
case self::PUNCTUATION_TYPE:
return 'punctuation';
case self::INTERPOLATION_START_TYPE:
return 'begin of string interpolation';
case self::INTERPOLATION_END_TYPE:
return 'end of string interpolation';
case self::ARROW_TYPE:
return 'arrow function';
default:
throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type));
}
}
}

class_alias('Twig\Token', 'Twig_Token');
<?php











namespace Twig;

use Twig\Node\ModuleNode;






class Compiler implements \Twig_CompilerInterface
{
protected $lastLine;
protected $source;
protected $indentation;
protected $env;
protected $debugInfo = [];
protected $sourceOffset;
protected $sourceLine;
protected $filename;
private $varNameSalt = 0;

public function __construct(Environment $env)
{
$this->env = $env;
}




public function getFilename()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);

return $this->filename;
}






public function getEnvironment()
{
return $this->env;
}






public function getSource()
{
return $this->source;
}








public function compile(\Twig_NodeInterface $node, $indentation = 0)
{
$this->lastLine = null;
$this->source = '';
$this->debugInfo = [];
$this->sourceOffset = 0;

$this->sourceLine = 1;
$this->indentation = $indentation;
$this->varNameSalt = 0;

if ($node instanceof ModuleNode) {

$this->filename = $node->getTemplateName();
}

$node->compile($this);

return $this;
}

public function subcompile(\Twig_NodeInterface $node, $raw = true)
{
if (false === $raw) {
$this->source .= str_repeat(' ', $this->indentation * 4);
}

$node->compile($this);

return $this;
}








public function raw($string)
{
$this->source .= $string;

return $this;
}






public function write()
{
$strings = \func_get_args();
foreach ($strings as $string) {
$this->source .= str_repeat(' ', $this->indentation * 4).$string;
}

return $this;
}








public function addIndentation()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', \E_USER_DEPRECATED);

$this->source .= str_repeat(' ', $this->indentation * 4);

return $this;
}








public function string($value)
{
$this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));

return $this;
}








public function repr($value)
{
if (\is_int($value) || \is_float($value)) {
if (false !== $locale = setlocale(\LC_NUMERIC, '0')) {
setlocale(\LC_NUMERIC, 'C');
}

$this->raw(var_export($value, true));

if (false !== $locale) {
setlocale(\LC_NUMERIC, $locale);
}
} elseif (null === $value) {
$this->raw('null');
} elseif (\is_bool($value)) {
$this->raw($value ? 'true' : 'false');
} elseif (\is_array($value)) {
$this->raw('[');
$first = true;
foreach ($value as $key => $v) {
if (!$first) {
$this->raw(', ');
}
$first = false;
$this->repr($key);
$this->raw(' => ');
$this->repr($v);
}
$this->raw(']');
} else {
$this->string($value);
}

return $this;
}






public function addDebugInfo(\Twig_NodeInterface $node)
{
if ($node->getTemplateLine() != $this->lastLine) {
$this->write(sprintf("// line %d\n", $node->getTemplateLine()));




if (((int) ini_get('mbstring.func_overload')) & 2) {
@trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', \E_USER_DEPRECATED);


$this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n");
} else {
$this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
}
$this->sourceOffset = \strlen($this->source);
$this->debugInfo[$this->sourceLine] = $node->getTemplateLine();

$this->lastLine = $node->getTemplateLine();
}

return $this;
}

public function getDebugInfo()
{
ksort($this->debugInfo);

return $this->debugInfo;
}








public function indent($step = 1)
{
$this->indentation += $step;

return $this;
}










public function outdent($step = 1)
{

if ($this->indentation < $step) {
throw new \LogicException('Unable to call outdent() as the indentation would become negative.');
}

$this->indentation -= $step;

return $this;
}

public function getVarName()
{
return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->varNameSalt++));
}
}

class_alias('Twig\Compiler', 'Twig_Compiler');
<?php











namespace Twig;

use Twig\Error\SyntaxError;








class TokenStream
{
protected $tokens;
protected $current = 0;
protected $filename;

private $source;






public function __construct(array $tokens, $name = null, $source = null)
{
if (!$name instanceof Source) {
if (null !== $name || null !== $source) {
@trigger_error(sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a \Twig\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
}
$this->source = new Source($source, $name);
} else {
$this->source = $name;
}

$this->tokens = $tokens;


$this->filename = $this->source->getName();
}

public function __toString()
{
return implode("\n", $this->tokens);
}

public function injectTokens(array $tokens)
{
$this->tokens = array_merge(\array_slice($this->tokens, 0, $this->current), $tokens, \array_slice($this->tokens, $this->current));
}






public function next()
{
if (!isset($this->tokens[++$this->current])) {
throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source);
}

return $this->tokens[$this->current - 1];
}






public function nextIf($primary, $secondary = null)
{
if ($this->tokens[$this->current]->test($primary, $secondary)) {
return $this->next();
}
}






public function expect($type, $value = null, $message = null)
{
$token = $this->tokens[$this->current];
if (!$token->test($type, $value)) {
$line = $token->getLine();
throw new SyntaxError(sprintf('%sUnexpected token "%s"%s ("%s" expected%s).',
$message ? $message.'. ' : '',
Token::typeToEnglish($token->getType()),
$token->getValue() ? sprintf(' of value "%s"', $token->getValue()) : '',
Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
$line,
$this->source
);
}
$this->next();

return $token;
}








public function look($number = 1)
{
if (!isset($this->tokens[$this->current + $number])) {
throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source);
}

return $this->tokens[$this->current + $number];
}






public function test($primary, $secondary = null)
{
return $this->tokens[$this->current]->test($primary, $secondary);
}






public function isEOF()
{
return Token::EOF_TYPE === $this->tokens[$this->current]->getType();
}




public function getCurrent()
{
return $this->tokens[$this->current];
}








public function getFilename()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);

return $this->source->getName();
}










public function getSource()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);

return $this->source->getCode();
}








public function getSourceContext()
{
return $this->source;
}
}

class_alias('Twig\TokenStream', 'Twig_TokenStream');
<?php











namespace Twig;

use Twig\Error\SyntaxError;






class Lexer implements \Twig_LexerInterface
{
protected $tokens;
protected $code;
protected $cursor;
protected $lineno;
protected $end;
protected $state;
protected $states;
protected $brackets;
protected $env;

protected $filename;
protected $options;
protected $regexes;
protected $position;
protected $positions;
protected $currentVarBlockLine;

private $source;

public const STATE_DATA = 0;
public const STATE_BLOCK = 1;
public const STATE_VAR = 2;
public const STATE_STRING = 3;
public const STATE_INTERPOLATION = 4;

public const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
public const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?([Ee][\+\-][0-9]+)?/A';
public const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
public const REGEX_DQ_STRING_DELIM = '/"/A';
public const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
public const PUNCTUATION = '()[]{}?:.,|';

public function __construct(Environment $env, array $options = [])
{
$this->env = $env;

$this->options = array_merge([
'tag_comment' => ['{#', '#}'],
'tag_block' => ['{%', '%}'],
'tag_variable' => ['{{', '}}'],
'whitespace_trim' => '-',
'whitespace_line_trim' => '~',
'whitespace_line_chars' => ' \t\0\x0B',
'interpolation' => ['#{', '}'],
], $options);


$this->regexes = [

'lex_var' => '{
                \s*
                (?:'.
preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '#').'\s*'. 
'|'.
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_variable'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. 
'|'.
preg_quote($this->options['tag_variable'][1], '#'). 
')
            }Ax',


'lex_block' => '{
                \s*
                (?:'.
preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*\n?'. 
'|'.
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. 
'|'.
preg_quote($this->options['tag_block'][1], '#').'\n?'. 
')
            }Ax',


'lex_raw_data' => '{'.
preg_quote($this->options['tag_block'][0], '#'). 
'('.
$this->options['whitespace_trim']. 
'|'.
$this->options['whitespace_line_trim']. 
')?\s*'.
'(?:end%s)'. 
'\s*'.
'(?:'.
preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. 
'|'.
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. 
'|'.
preg_quote($this->options['tag_block'][1], '#'). 
')
            }sx',

'operator' => $this->getOperatorRegex(),


'lex_comment' => '{
                (?:'.
preg_quote($this->options['whitespace_trim'].$this->options['tag_comment'][1], '#').'\s*\n?'. 
'|'.
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_comment'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. 
'|'.
preg_quote($this->options['tag_comment'][1], '#').'\n?'. 
')
            }sx',


'lex_block_raw' => '{
                \s*
                (raw|verbatim)
                \s*
                (?:'.
preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. 
'|'.
preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. 
'|'.
preg_quote($this->options['tag_block'][1], '#'). 
')
            }Asx',

'lex_block_line' => '{\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '#').'}As',


'lex_tokens_start' => '{
                ('.
preg_quote($this->options['tag_variable'][0], '#'). 
'|'.
preg_quote($this->options['tag_block'][0], '#'). 
'|'.
preg_quote($this->options['tag_comment'][0], '#'). 
')('.
preg_quote($this->options['whitespace_trim'], '#'). 
'|'.
preg_quote($this->options['whitespace_line_trim'], '#'). 
')?
            }sx',
'interpolation_start' => '{'.preg_quote($this->options['interpolation'][0], '#').'\s*}A',
'interpolation_end' => '{\s*'.preg_quote($this->options['interpolation'][1], '#').'}A',
];
}

public function tokenize($code, $name = null)
{
if (!$code instanceof Source) {
@trigger_error(sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a \Twig\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
$this->source = new Source($code, $name);
} else {
$this->source = $code;
}

if (((int) ini_get('mbstring.func_overload')) & 2) {
@trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', \E_USER_DEPRECATED);
}

if (\function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
$mbEncoding = mb_internal_encoding();
mb_internal_encoding('ASCII');
} else {
$mbEncoding = null;
}

$this->code = str_replace(["\r\n", "\r"], "\n", $this->source->getCode());
$this->filename = $this->source->getName();
$this->cursor = 0;
$this->lineno = 1;
$this->end = \strlen($this->code);
$this->tokens = [];
$this->state = self::STATE_DATA;
$this->states = [];
$this->brackets = [];
$this->position = -1;


preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, \PREG_OFFSET_CAPTURE);
$this->positions = $matches;

while ($this->cursor < $this->end) {


switch ($this->state) {
case self::STATE_DATA:
$this->lexData();
break;

case self::STATE_BLOCK:
$this->lexBlock();
break;

case self::STATE_VAR:
$this->lexVar();
break;

case self::STATE_STRING:
$this->lexString();
break;

case self::STATE_INTERPOLATION:
$this->lexInterpolation();
break;
}
}

$this->pushToken(Token::EOF_TYPE);

if (!empty($this->brackets)) {
list($expect, $lineno) = array_pop($this->brackets);
throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
}

if ($mbEncoding) {
mb_internal_encoding($mbEncoding);
}

return new TokenStream($this->tokens, $this->source);
}

protected function lexData()
{

if ($this->position == \count($this->positions[0]) - 1) {
$this->pushToken(Token::TEXT_TYPE, substr($this->code, $this->cursor));
$this->cursor = $this->end;

return;
}


$position = $this->positions[0][++$this->position];
while ($position[1] < $this->cursor) {
if ($this->position == \count($this->positions[0]) - 1) {
return;
}
$position = $this->positions[0][++$this->position];
}


$text = $textContent = substr($this->code, $this->cursor, $position[1] - $this->cursor);


if (isset($this->positions[2][$this->position][0])) {
if ($this->options['whitespace_trim'] === $this->positions[2][$this->position][0]) {

$text = rtrim($text);
} elseif ($this->options['whitespace_line_trim'] === $this->positions[2][$this->position][0]) {


$text = rtrim($text, " \t\0\x0B");
}
}
$this->pushToken(Token::TEXT_TYPE, $text);
$this->moveCursor($textContent.$position[0]);

switch ($this->positions[1][$this->position][0]) {
case $this->options['tag_comment'][0]:
$this->lexComment();
break;

case $this->options['tag_block'][0]:

if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, 0, $this->cursor)) {
$this->moveCursor($match[0]);
$this->lexRawData($match[1]);

} elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, 0, $this->cursor)) {
$this->moveCursor($match[0]);
$this->lineno = (int) $match[1];
} else {
$this->pushToken(Token::BLOCK_START_TYPE);
$this->pushState(self::STATE_BLOCK);
$this->currentVarBlockLine = $this->lineno;
}
break;

case $this->options['tag_variable'][0]:
$this->pushToken(Token::VAR_START_TYPE);
$this->pushState(self::STATE_VAR);
$this->currentVarBlockLine = $this->lineno;
break;
}
}

protected function lexBlock()
{
if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, 0, $this->cursor)) {
$this->pushToken(Token::BLOCK_END_TYPE);
$this->moveCursor($match[0]);
$this->popState();
} else {
$this->lexExpression();
}
}

protected function lexVar()
{
if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, 0, $this->cursor)) {
$this->pushToken(Token::VAR_END_TYPE);
$this->moveCursor($match[0]);
$this->popState();
} else {
$this->lexExpression();
}
}

protected function lexExpression()
{

if (preg_match('/\s+/A', $this->code, $match, 0, $this->cursor)) {
$this->moveCursor($match[0]);

if ($this->cursor >= $this->end) {
throw new SyntaxError(sprintf('Unclosed "%s".', self::STATE_BLOCK === $this->state ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source);
}
}


if ('=' === $this->code[$this->cursor] && '>' === $this->code[$this->cursor + 1]) {
$this->pushToken(Token::ARROW_TYPE, '=>');
$this->moveCursor('=>');
}

elseif (preg_match($this->regexes['operator'], $this->code, $match, 0, $this->cursor)) {
$this->pushToken(Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
$this->moveCursor($match[0]);
}

elseif (preg_match(self::REGEX_NAME, $this->code, $match, 0, $this->cursor)) {
$this->pushToken(Token::NAME_TYPE, $match[0]);
$this->moveCursor($match[0]);
}

elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, 0, $this->cursor)) {
$number = (float) $match[0]; 
if (ctype_digit($match[0]) && $number <= \PHP_INT_MAX) {
$number = (int) $match[0]; 
}
$this->pushToken(Token::NUMBER_TYPE, $number);
$this->moveCursor($match[0]);
}

elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) {

if (false !== strpos('([{', $this->code[$this->cursor])) {
$this->brackets[] = [$this->code[$this->cursor], $this->lineno];
}

elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
if (empty($this->brackets)) {
throw new SyntaxError(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
}

list($expect, $lineno) = array_pop($this->brackets);
if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
}
}

$this->pushToken(Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
++$this->cursor;
}

elseif (preg_match(self::REGEX_STRING, $this->code, $match, 0, $this->cursor)) {
$this->pushToken(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)));
$this->moveCursor($match[0]);
}

elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
$this->brackets[] = ['"', $this->lineno];
$this->pushState(self::STATE_STRING);
$this->moveCursor($match[0]);
}

else {
throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
}
}

protected function lexRawData($tag)
{
if ('raw' === $tag) {
@trigger_error(sprintf('Twig Tag "raw" is deprecated since version 1.21. Use "verbatim" instead in %s at line %d.', $this->filename, $this->lineno), \E_USER_DEPRECATED);
}

if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, \PREG_OFFSET_CAPTURE, $this->cursor)) {
throw new SyntaxError(sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source);
}

$text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
$this->moveCursor($text.$match[0][0]);


if (isset($match[1][0])) {
if ($this->options['whitespace_trim'] === $match[1][0]) {

$text = rtrim($text);
} else {


$text = rtrim($text, " \t\0\x0B");
}
}

$this->pushToken(Token::TEXT_TYPE, $text);
}

protected function lexComment()
{
if (!preg_match($this->regexes['lex_comment'], $this->code, $match, \PREG_OFFSET_CAPTURE, $this->cursor)) {
throw new SyntaxError('Unclosed comment.', $this->lineno, $this->source);
}

$this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
}

protected function lexString()
{
if (preg_match($this->regexes['interpolation_start'], $this->code, $match, 0, $this->cursor)) {
$this->brackets[] = [$this->options['interpolation'][0], $this->lineno];
$this->pushToken(Token::INTERPOLATION_START_TYPE);
$this->moveCursor($match[0]);
$this->pushState(self::STATE_INTERPOLATION);
} elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, 0, $this->cursor) && \strlen($match[0]) > 0) {
$this->pushToken(Token::STRING_TYPE, stripcslashes($match[0]));
$this->moveCursor($match[0]);
} elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
list($expect, $lineno) = array_pop($this->brackets);
if ('"' != $this->code[$this->cursor]) {
throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
}

$this->popState();
++$this->cursor;
} else {

throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
}
}

protected function lexInterpolation()
{
$bracket = end($this->brackets);
if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, 0, $this->cursor)) {
array_pop($this->brackets);
$this->pushToken(Token::INTERPOLATION_END_TYPE);
$this->moveCursor($match[0]);
$this->popState();
} else {
$this->lexExpression();
}
}

protected function pushToken($type, $value = '')
{

if (Token::TEXT_TYPE === $type && '' === $value) {
return;
}

$this->tokens[] = new Token($type, $value, $this->lineno);
}

protected function moveCursor($text)
{
$this->cursor += \strlen($text);
$this->lineno += substr_count($text, "\n");
}

protected function getOperatorRegex()
{
$operators = array_merge(
['='],
array_keys($this->env->getUnaryOperators()),
array_keys($this->env->getBinaryOperators())
);

$operators = array_combine($operators, array_map('strlen', $operators));
arsort($operators);

$regex = [];
foreach ($operators as $operator => $length) {


$r = preg_quote($operator, '/');
if (ctype_alpha($operator[$length - 1])) {
$r .= '(?=[\s()\[{])';
}


if (ctype_alpha($operator[0])) {
$r = '(?<![\.\|])'.$r;
}


$r = preg_replace('/\s+/', '\s+', $r);

$regex[] = $r;
}

return '/'.implode('|', $regex).'/A';
}

protected function pushState($state)
{
$this->states[] = $this->state;
$this->state = $state;
}

protected function popState()
{
if (0 === \count($this->states)) {
throw new \LogicException('Cannot pop state without a previous state.');
}

$this->state = array_pop($this->states);
}
}

class_alias('Twig\Lexer', 'Twig_Lexer');
<?php










namespace Twig\Util;

use Twig\Environment;
use Twig\Error\SyntaxError;
use Twig\Source;






class DeprecationCollector
{
private $twig;
private $deprecations;

public function __construct(Environment $twig)
{
$this->twig = $twig;
}









public function collectDir($dir, $ext = '.twig')
{
$iterator = new \RegexIterator(
new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY
), '{'.preg_quote($ext).'$}'
);

return $this->collect(new TemplateDirIterator($iterator));
}








public function collect(\Traversable $iterator)
{
$this->deprecations = [];

set_error_handler([$this, 'errorHandler']);

foreach ($iterator as $name => $contents) {
try {
$this->twig->parse($this->twig->tokenize(new Source($contents, $name)));
} catch (SyntaxError $e) {

}
}

restore_error_handler();

$deprecations = $this->deprecations;
$this->deprecations = [];

return $deprecations;
}




public function errorHandler($type, $msg)
{
if (\E_USER_DEPRECATED === $type) {
$this->deprecations[] = $msg;
}
}
}

class_alias('Twig\Util\DeprecationCollector', 'Twig_Util_DeprecationCollector');
<?php










namespace Twig\Util;




class TemplateDirIterator extends \IteratorIterator
{
public function current()
{
return file_get_contents(parent::current());
}

public function key()
{
return (string) parent::key();
}
}

class_alias('Twig\Util\TemplateDirIterator', 'Twig_Util_TemplateDirIterator');
<?php










namespace Twig;

use Twig\Node\Node;








class TwigFunction
{
protected $name;
protected $callable;
protected $options;
protected $arguments = [];

public function __construct($name, $callable, array $options = [])
{
$this->name = $name;
$this->callable = $callable;
$this->options = array_merge([
'needs_environment' => false,
'needs_context' => false,
'is_variadic' => false,
'is_safe' => null,
'is_safe_callback' => null,
'node_class' => '\Twig\Node\Expression\FunctionExpression',
'deprecated' => false,
'alternative' => null,
], $options);
}

public function getName()
{
return $this->name;
}

public function getCallable()
{
return $this->callable;
}

public function getNodeClass()
{
return $this->options['node_class'];
}

public function setArguments($arguments)
{
$this->arguments = $arguments;
}

public function getArguments()
{
return $this->arguments;
}

public function needsEnvironment()
{
return $this->options['needs_environment'];
}

public function needsContext()
{
return $this->options['needs_context'];
}

public function getSafe(Node $functionArgs)
{
if (null !== $this->options['is_safe']) {
return $this->options['is_safe'];
}

if (null !== $this->options['is_safe_callback']) {
return \call_user_func($this->options['is_safe_callback'], $functionArgs);
}

return [];
}

public function isVariadic()
{
return $this->options['is_variadic'];
}

public function isDeprecated()
{
return (bool) $this->options['deprecated'];
}

public function getDeprecatedVersion()
{
return $this->options['deprecated'];
}

public function getAlternative()
{
return $this->options['alternative'];
}
}

class_alias('Twig\TwigFunction', 'Twig_SimpleFunction');


class_exists('Twig\Node\Node');
<?php










namespace Twig;






final class TemplateWrapper
{
private $env;
private $template;







public function __construct(Environment $env, Template $template)
{
$this->env = $env;
$this->template = $template;
}








public function render($context = [])
{


return $this->template->render($context, \func_num_args() > 1 ? func_get_arg(1) : []);
}






public function display($context = [])
{


$this->template->display($context, \func_num_args() > 1 ? func_get_arg(1) : []);
}









public function hasBlock($name, $context = [])
{
return $this->template->hasBlock($name, $context);
}








public function getBlockNames($context = [])
{
return $this->template->getBlockNames($context);
}









public function renderBlock($name, $context = [])
{
$context = $this->env->mergeGlobals($context);
$level = ob_get_level();
if ($this->env->isDebug()) {
ob_start();
} else {
ob_start(function () { return ''; });
}
try {
$this->template->displayBlock($name, $context);
} catch (\Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}

throw $e;
} catch (\Throwable $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}

throw $e;
}

return ob_get_clean();
}







public function displayBlock($name, $context = [])
{
$this->template->displayBlock($name, $this->env->mergeGlobals($context));
}




public function getSourceContext()
{
return $this->template->getSourceContext();
}




public function getTemplateName()
{
return $this->template->getTemplateName();
}






public function unwrap()
{
return $this->template;
}
}

class_alias('Twig\TemplateWrapper', 'Twig_TemplateWrapper');
<?php










namespace Twig;








class Source
{
private $code;
private $name;
private $path;






public function __construct($code, $name, $path = '')
{
$this->code = $code;
$this->name = $name;
$this->path = $path;
}

public function getCode()
{
return $this->code;
}

public function getName()
{
return $this->name;
}

public function getPath()
{
return $this->path;
}
}

class_alias('Twig\Source', 'Twig_Source');
<?php










namespace Twig\Cache;










interface CacheInterface
{








public function generateKey($name, $className);







public function write($key, $content);






public function load($key);








public function getTimestamp($key);
}

class_alias('Twig\Cache\CacheInterface', 'Twig_CacheInterface');
<?php










namespace Twig\Cache;








class NullCache implements CacheInterface
{
public function generateKey($name, $className)
{
return '';
}

public function write($key, $content)
{
}

public function load($key)
{
}

public function getTimestamp($key)
{
return 0;
}
}

class_alias('Twig\Cache\NullCache', 'Twig_Cache_Null');
<?php










namespace Twig\Cache;






class FilesystemCache implements CacheInterface
{
public const FORCE_BYTECODE_INVALIDATION = 1;

private $directory;
private $options;





public function __construct($directory, $options = 0)
{
$this->directory = rtrim($directory, '\/').'/';
$this->options = $options;
}

public function generateKey($name, $className)
{
$hash = hash('sha256', $className);

return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
}

public function load($key)
{
if (file_exists($key)) {
@include_once $key;
}
}

public function write($key, $content)
{
$dir = \dirname($key);
if (!is_dir($dir)) {
if (false === @mkdir($dir, 0777, true)) {
clearstatcache(true, $dir);
if (!is_dir($dir)) {
throw new \RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
}
}
} elseif (!is_writable($dir)) {
throw new \RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
}

$tmpFile = tempnam($dir, basename($key));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) {
@chmod($key, 0666 & ~umask());

if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {

if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
@opcache_invalidate($key, true);
} elseif (\function_exists('apc_compile_file')) {
apc_compile_file($key);
}
}

return;
}

throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $key));
}

public function getTimestamp($key)
{
if (!file_exists($key)) {
return 0;
}

return (int) @filemtime($key);
}
}

class_alias('Twig\Cache\FilesystemCache', 'Twig_Cache_Filesystem');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\ImportNode;
use Twig\Token;








class FromTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$macro = $this->parser->getExpressionParser()->parseExpression();
$stream = $this->parser->getStream();
$stream->expect(Token::NAME_TYPE, 'import');

$targets = [];
do {
$name = $stream->expect(Token::NAME_TYPE)->getValue();

$alias = $name;
if ($stream->nextIf('as')) {
$alias = $stream->expect(Token::NAME_TYPE)->getValue();
}

$targets[$name] = $alias;

if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
break;
}
} while (true);

$stream->expect(Token::BLOCK_END_TYPE);

$var = new AssignNameExpression($this->parser->getVarName(), $token->getLine());
$node = new ImportNode($macro, $var, $token->getLine(), $this->getTag());

foreach ($targets as $name => $alias) {
if ($this->parser->isReservedMacroName($name)) {
throw new SyntaxError(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
}

$this->parser->addImportedSymbol('function', $alias, 'get'.$name, $var);
}

return $node;
}

public function getTag()
{
return 'from';
}
}

class_alias('Twig\TokenParser\FromTokenParser', 'Twig_TokenParser_From');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\AutoEscapeNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Token;



















class AutoEscapeTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();

if ($stream->test(Token::BLOCK_END_TYPE)) {
$value = 'html';
} else {
$expr = $this->parser->getExpressionParser()->parseExpression();
if (!$expr instanceof ConstantExpression) {
throw new SyntaxError('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
$value = $expr->getAttribute('value');

$compat = true === $value || false === $value;

if (true === $value) {
$value = 'html';
}

if ($compat && $stream->test(Token::NAME_TYPE)) {
@trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', \E_USER_DEPRECATED);

if (false === $value) {
throw new SyntaxError('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}

$value = $stream->next()->getValue();
}
}

$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);

return new AutoEscapeNode($value, $body, $lineno, $this->getTag());
}

public function decideBlockEnd(Token $token)
{
return $token->test('endautoescape');
}

public function getTag()
{
return 'autoescape';
}
}

class_alias('Twig\TokenParser\AutoEscapeTokenParser', 'Twig_TokenParser_AutoEscape');
<?php











namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\IfNode;
use Twig\Node\Node;
use Twig\Token;














class IfTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$expr = $this->parser->getExpressionParser()->parseExpression();
$stream = $this->parser->getStream();
$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideIfFork']);
$tests = [$expr, $body];
$else = null;

$end = false;
while (!$end) {
switch ($stream->next()->getValue()) {
case 'else':
$stream->expect(Token::BLOCK_END_TYPE);
$else = $this->parser->subparse([$this, 'decideIfEnd']);
break;

case 'elseif':
$expr = $this->parser->getExpressionParser()->parseExpression();
$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideIfFork']);
$tests[] = $expr;
$tests[] = $body;
break;

case 'endif':
$end = true;
break;

default:
throw new SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
}

$stream->expect(Token::BLOCK_END_TYPE);

return new IfNode(new Node($tests), $else, $lineno, $this->getTag());
}

public function decideIfFork(Token $token)
{
return $token->test(['elseif', 'else', 'endif']);
}

public function decideIfEnd(Token $token)
{
return $token->test(['endif']);
}

public function getTag()
{
return 'if';
}
}

class_alias('Twig\TokenParser\IfTokenParser', 'Twig_TokenParser_If');
<?php










namespace Twig\TokenParser;

use Twig\Node\BlockNode;
use Twig\Node\Expression\BlockReferenceExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\PrintNode;
use Twig\Token;










class FilterTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$name = $this->parser->getVarName();
$ref = new BlockReferenceExpression(new ConstantExpression($name, $token->getLine()), null, $token->getLine(), $this->getTag());

$filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

$block = new BlockNode($name, $body, $token->getLine());
$this->parser->setBlock($name, $block);

return new PrintNode($filter, $token->getLine(), $this->getTag());
}

public function decideBlockEnd(Token $token)
{
return $token->test('endfilter');
}

public function getTag()
{
return 'filter';
}
}

class_alias('Twig\TokenParser\FilterTokenParser', 'Twig_TokenParser_Filter');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\BodyNode;
use Twig\Node\MacroNode;
use Twig\Node\Node;
use Twig\Token;










class MacroTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();

$arguments = $this->parser->getExpressionParser()->parseArguments(true, true);

$stream->expect(Token::BLOCK_END_TYPE);
$this->parser->pushLocalScope();
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
if ($token = $stream->nextIf(Token::NAME_TYPE)) {
$value = $token->getValue();

if ($value != $name) {
throw new SyntaxError(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
}
$this->parser->popLocalScope();
$stream->expect(Token::BLOCK_END_TYPE);

$this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno, $this->getTag()));

return new Node();
}

public function decideBlockEnd(Token $token)
{
return $token->test('endmacro');
}

public function getTag()
{
return 'macro';
}
}

class_alias('Twig\TokenParser\MacroTokenParser', 'Twig_TokenParser_Macro');
<?php










namespace Twig\TokenParser;

use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\ImportNode;
use Twig\Token;








class ImportTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$macro = $this->parser->getExpressionParser()->parseExpression();
$this->parser->getStream()->expect(Token::NAME_TYPE, 'as');
$var = new AssignNameExpression($this->parser->getStream()->expect(Token::NAME_TYPE)->getValue(), $token->getLine());
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

$this->parser->addImportedSymbol('template', $var->getAttribute('name'));

return new ImportNode($macro, $var, $token->getLine(), $this->getTag());
}

public function getTag()
{
return 'import';
}
}

class_alias('Twig\TokenParser\ImportTokenParser', 'Twig_TokenParser_Import');
<?php











namespace Twig\TokenParser;

use Twig\Node\IncludeNode;
use Twig\Token;








class IncludeTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();

list($variables, $only, $ignoreMissing) = $this->parseArguments();

return new IncludeNode($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
}

protected function parseArguments()
{
$stream = $this->parser->getStream();

$ignoreMissing = false;
if ($stream->nextIf(Token::NAME_TYPE, 'ignore')) {
$stream->expect(Token::NAME_TYPE, 'missing');

$ignoreMissing = true;
}

$variables = null;
if ($stream->nextIf(Token::NAME_TYPE, 'with')) {
$variables = $this->parser->getExpressionParser()->parseExpression();
}

$only = false;
if ($stream->nextIf(Token::NAME_TYPE, 'only')) {
$only = true;
}

$stream->expect(Token::BLOCK_END_TYPE);

return [$variables, $only, $ignoreMissing];
}

public function getTag()
{
return 'include';
}
}

class_alias('Twig\TokenParser\IncludeTokenParser', 'Twig_TokenParser_Include');
<?php










namespace Twig\TokenParser;

use Twig\Node\WithNode;
use Twig\Token;








class WithTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();

$variables = null;
$only = false;
if (!$stream->test(Token::BLOCK_END_TYPE)) {
$variables = $this->parser->getExpressionParser()->parseExpression();
$only = $stream->nextIf(Token::NAME_TYPE, 'only');
}

$stream->expect(Token::BLOCK_END_TYPE);

$body = $this->parser->subparse([$this, 'decideWithEnd'], true);

$stream->expect(Token::BLOCK_END_TYPE);

return new WithNode($body, $variables, $only, $token->getLine(), $this->getTag());
}

public function decideWithEnd(Token $token)
{
return $token->test('endwith');
}

public function getTag()
{
return 'with';
}
}

class_alias('Twig\TokenParser\WithTokenParser', 'Twig_TokenParser_With');
<?php










namespace Twig\TokenParser;

use Twig\Node\SpacelessNode;
use Twig\Token;













class SpacelessTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();

$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideSpacelessEnd'], true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

return new SpacelessNode($body, $lineno, $this->getTag());
}

public function decideSpacelessEnd(Token $token)
{
return $token->test('endspaceless');
}

public function getTag()
{
return 'spaceless';
}
}

class_alias('Twig\TokenParser\SpacelessTokenParser', 'Twig_TokenParser_Spaceless');
<?php











namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\ForNode;
use Twig\Token;
use Twig\TokenStream;












class ForTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
$stream->expect(Token::OPERATOR_TYPE, 'in');
$seq = $this->parser->getExpressionParser()->parseExpression();

$ifexpr = null;
if ($stream->nextIf(Token::NAME_TYPE, 'if')) {
$ifexpr = $this->parser->getExpressionParser()->parseExpression();
}

$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideForFork']);
if ('else' == $stream->next()->getValue()) {
$stream->expect(Token::BLOCK_END_TYPE);
$else = $this->parser->subparse([$this, 'decideForEnd'], true);
} else {
$else = null;
}
$stream->expect(Token::BLOCK_END_TYPE);

if (\count($targets) > 1) {
$keyTarget = $targets->getNode(0);
$keyTarget = new AssignNameExpression($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
$valueTarget = $targets->getNode(1);
$valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
} else {
$keyTarget = new AssignNameExpression('_key', $lineno);
$valueTarget = $targets->getNode(0);
$valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
}

if ($ifexpr) {
$this->checkLoopUsageCondition($stream, $ifexpr);
$this->checkLoopUsageBody($stream, $body);
}

return new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
}

public function decideForFork(Token $token)
{
return $token->test(['else', 'endfor']);
}

public function decideForEnd(Token $token)
{
return $token->test('endfor');
}


protected function checkLoopUsageCondition(TokenStream $stream, \Twig_NodeInterface $node)
{
if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
throw new SyntaxError('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext());
}

foreach ($node as $n) {
if (!$n) {
continue;
}

$this->checkLoopUsageCondition($stream, $n);
}
}



protected function checkLoopUsageBody(TokenStream $stream, \Twig_NodeInterface $node)
{
if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
$attribute = $node->getNode('attribute');
if ($attribute instanceof ConstantExpression && \in_array($attribute->getAttribute('value'), ['length', 'revindex0', 'revindex', 'last'])) {
throw new SyntaxError(sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext());
}
}


if ($node instanceof ForNode) {
return;
}

foreach ($node as $n) {
if (!$n) {
continue;
}

$this->checkLoopUsageBody($stream, $n);
}
}

public function getTag()
{
return 'for';
}
}

class_alias('Twig\TokenParser\ForTokenParser', 'Twig_TokenParser_For');
<?php











namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\Node;
use Twig\Token;








class ExtendsTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();

if ($this->parser->peekBlockStack()) {
throw new SyntaxError('Cannot use "extend" in a block.', $token->getLine(), $stream->getSourceContext());
} elseif (!$this->parser->isMainScope()) {
throw new SyntaxError('Cannot use "extend" in a macro.', $token->getLine(), $stream->getSourceContext());
}

if (null !== $this->parser->getParent()) {
throw new SyntaxError('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext());
}
$this->parser->setParent($this->parser->getExpressionParser()->parseExpression());

$stream->expect(Token::BLOCK_END_TYPE);

return new Node();
}

public function getTag()
{
return 'extends';
}
}

class_alias('Twig\TokenParser\ExtendsTokenParser', 'Twig_TokenParser_Extends');
<?php










namespace Twig\TokenParser;

use Twig\Node\FlushNode;
use Twig\Token;








class FlushTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

return new FlushNode($token->getLine(), $this->getTag());
}

public function getTag()
{
return 'flush';
}
}

class_alias('Twig\TokenParser\FlushTokenParser', 'Twig_TokenParser_Flush');
<?php










namespace Twig\TokenParser;

use Twig\Parser;






abstract class AbstractTokenParser implements TokenParserInterface
{



protected $parser;

public function setParser(Parser $parser)
{
$this->parser = $parser;
}
}

class_alias('Twig\TokenParser\AbstractTokenParser', 'Twig_TokenParser');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Parser;
use Twig\Token;






interface TokenParserInterface
{



public function setParser(Parser $parser);








public function parse(Token $token);






public function getTag();
}

class_alias('Twig\TokenParser\TokenParserInterface', 'Twig_TokenParserInterface');


class_exists('Twig\Token');
class_exists('Twig\Parser');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\IncludeNode;
use Twig\Node\SandboxNode;
use Twig\Node\TextNode;
use Twig\Token;












class SandboxTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();
$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);


if (!$body instanceof IncludeNode) {
foreach ($body as $node) {
if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) {
continue;
}

if (!$node instanceof IncludeNode) {
throw new SyntaxError('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext());
}
}
}

return new SandboxNode($body, $token->getLine(), $this->getTag());
}

public function decideBlockEnd(Token $token)
{
return $token->test('endsandbox');
}

public function getTag()
{
return 'sandbox';
}
}

class_alias('Twig\TokenParser\SandboxTokenParser', 'Twig_TokenParser_Sandbox');
<?php










namespace Twig\TokenParser;

use Twig\Node\EmbedNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Token;






class EmbedTokenParser extends IncludeTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();

$parent = $this->parser->getExpressionParser()->parseExpression();

list($variables, $only, $ignoreMissing) = $this->parseArguments();

$parentToken = $fakeParentToken = new Token(Token::STRING_TYPE, '__parent__', $token->getLine());
if ($parent instanceof ConstantExpression) {
$parentToken = new Token(Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
} elseif ($parent instanceof NameExpression) {
$parentToken = new Token(Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
}


$stream->injectTokens([
new Token(Token::BLOCK_START_TYPE, '', $token->getLine()),
new Token(Token::NAME_TYPE, 'extends', $token->getLine()),
$parentToken,
new Token(Token::BLOCK_END_TYPE, '', $token->getLine()),
]);

$module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);


if ($fakeParentToken === $parentToken) {
$module->setNode('parent', $parent);
}

$this->parser->embedTemplate($module);

$stream->expect(Token::BLOCK_END_TYPE);

return new EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
}

public function decideBlockEnd(Token $token)
{
return $token->test('endembed');
}

public function getTag()
{
return 'embed';
}
}

class_alias('Twig\TokenParser\EmbedTokenParser', 'Twig_TokenParser_Embed');
<?php










namespace Twig\TokenParser;

use Twig\Node\Expression\TempNameExpression;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\Node\SetNode;
use Twig\Token;








final class ApplyTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$name = $this->parser->getVarName();

$ref = new TempNameExpression($name, $lineno);
$ref->setAttribute('always_defined', true);

$filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());

$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideApplyEnd'], true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

return new Node([
new SetNode(true, $ref, $body, $lineno, $this->getTag()),
new PrintNode($filter, $lineno, $this->getTag()),
]);
}

public function decideApplyEnd(Token $token)
{
return $token->test('endapply');
}

public function getTag()
{
return 'apply';
}
}
<?php










namespace Twig\TokenParser;

use Twig\Node\DoNode;
use Twig\Token;






class DoTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();

$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

return new DoNode($expr, $token->getLine(), $this->getTag());
}

public function getTag()
{
return 'do';
}
}

class_alias('Twig\TokenParser\DoTokenParser', 'Twig_TokenParser_Do');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\SetNode;
use Twig\Token;













class SetTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$names = $this->parser->getExpressionParser()->parseAssignmentExpression();

$capture = false;
if ($stream->nextIf(Token::OPERATOR_TYPE, '=')) {
$values = $this->parser->getExpressionParser()->parseMultitargetExpression();

$stream->expect(Token::BLOCK_END_TYPE);

if (\count($names) !== \count($values)) {
throw new SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
} else {
$capture = true;

if (\count($names) > 1) {
throw new SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}

$stream->expect(Token::BLOCK_END_TYPE);

$values = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);
}

return new SetNode($capture, $names, $values, $lineno, $this->getTag());
}

public function decideBlockEnd(Token $token)
{
return $token->test('endset');
}

public function getTag()
{
return 'set';
}
}

class_alias('Twig\TokenParser\SetTokenParser', 'Twig_TokenParser_Set');
<?php










namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Node;
use Twig\Token;















class UseTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$template = $this->parser->getExpressionParser()->parseExpression();
$stream = $this->parser->getStream();

if (!$template instanceof ConstantExpression) {
throw new SyntaxError('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}

$targets = [];
if ($stream->nextIf('with')) {
do {
$name = $stream->expect(Token::NAME_TYPE)->getValue();

$alias = $name;
if ($stream->nextIf('as')) {
$alias = $stream->expect(Token::NAME_TYPE)->getValue();
}

$targets[$name] = new ConstantExpression($alias, -1);

if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
break;
}
} while (true);
}

$stream->expect(Token::BLOCK_END_TYPE);

$this->parser->addTrait(new Node(['template' => $template, 'targets' => new Node($targets)]));

return new Node();
}

public function getTag()
{
return 'use';
}
}

class_alias('Twig\TokenParser\UseTokenParser', 'Twig_TokenParser_Use');
<?php










namespace Twig\TokenParser;

use Twig\Node\DeprecatedNode;
use Twig\Token;











class DeprecatedTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();

$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);

return new DeprecatedNode($expr, $token->getLine(), $this->getTag());
}

public function getTag()
{
return 'deprecated';
}
}

class_alias('Twig\TokenParser\DeprecatedTokenParser', 'Twig_TokenParser_Deprecated');
<?php











namespace Twig\TokenParser;

use Twig\Error\SyntaxError;
use Twig\Node\BlockNode;
use Twig\Node\BlockReferenceNode;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\Token;











class BlockTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
if ($this->parser->hasBlock($name)) {
throw new SyntaxError(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
$this->parser->setBlock($name, $block = new BlockNode($name, new Node([]), $lineno));
$this->parser->pushLocalScope();
$this->parser->pushBlockStack($name);

if ($stream->nextIf(Token::BLOCK_END_TYPE)) {
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
if ($token = $stream->nextIf(Token::NAME_TYPE)) {
$value = $token->getValue();

if ($value != $name) {
throw new SyntaxError(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
}
} else {
$body = new Node([
new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno),
]);
}
$stream->expect(Token::BLOCK_END_TYPE);

$block->setNode('body', $body);
$this->parser->popBlockStack();
$this->parser->popLocalScope();

return new BlockReferenceNode($name, $lineno, $this->getTag());
}

public function decideBlockEnd(Token $token)
{
return $token->test('endblock');
}

public function getTag()
{
return 'block';
}
}

class_alias('Twig\TokenParser\BlockTokenParser', 'Twig_TokenParser_Block');
<?php










namespace Twig\Extension;

use Twig\NodeVisitor\OptimizerNodeVisitor;




class OptimizerExtension extends AbstractExtension
{
protected $optimizers;

public function __construct($optimizers = -1)
{
$this->optimizers = $optimizers;
}

public function getNodeVisitors()
{
return [new OptimizerNodeVisitor($this->optimizers)];
}

public function getName()
{
return 'optimizer';
}
}

class_alias('Twig\Extension\OptimizerExtension', 'Twig_Extension_Optimizer');
<?php










namespace Twig\Extension;




interface RuntimeExtensionInterface
{
}
<?php










namespace Twig\Extension;









interface InitRuntimeInterface
{
}

class_alias('Twig\Extension\InitRuntimeInterface', 'Twig_Extension_InitRuntimeInterface');
<?php










namespace Twig\Extension;

use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\TokenParser\TokenParserInterface;










class StagingExtension extends AbstractExtension
{
protected $functions = [];
protected $filters = [];
protected $visitors = [];
protected $tokenParsers = [];
protected $globals = [];
protected $tests = [];

public function addFunction($name, $function)
{
if (isset($this->functions[$name])) {
@trigger_error(sprintf('Overriding function "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), \E_USER_DEPRECATED);
}

$this->functions[$name] = $function;
}

public function getFunctions()
{
return $this->functions;
}

public function addFilter($name, $filter)
{
if (isset($this->filters[$name])) {
@trigger_error(sprintf('Overriding filter "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), \E_USER_DEPRECATED);
}

$this->filters[$name] = $filter;
}

public function getFilters()
{
return $this->filters;
}

public function addNodeVisitor(NodeVisitorInterface $visitor)
{
$this->visitors[] = $visitor;
}

public function getNodeVisitors()
{
return $this->visitors;
}

public function addTokenParser(TokenParserInterface $parser)
{
if (isset($this->tokenParsers[$parser->getTag()])) {
@trigger_error(sprintf('Overriding tag "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $parser->getTag()), \E_USER_DEPRECATED);
}

$this->tokenParsers[$parser->getTag()] = $parser;
}

public function getTokenParsers()
{
return $this->tokenParsers;
}

public function addGlobal($name, $value)
{
$this->globals[$name] = $value;
}

public function getGlobals()
{
return $this->globals;
}

public function addTest($name, $test)
{
if (isset($this->tests[$name])) {
@trigger_error(sprintf('Overriding test "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), \E_USER_DEPRECATED);
}

$this->tests[$name] = $test;
}

public function getTests()
{
return $this->tests;
}

public function getName()
{
return 'staging';
}
}

class_alias('Twig\Extension\StagingExtension', 'Twig_Extension_Staging');
<?php










namespace Twig\Extension;

use Twig\Environment;
use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\TokenParser\TokenParserInterface;
use Twig\TwigFilter;
use Twig\TwigFunction;
use Twig\TwigTest;






interface ExtensionInterface
{







public function initRuntime(Environment $environment);






public function getTokenParsers();






public function getNodeVisitors();






public function getFilters();






public function getTests();






public function getFunctions();






public function getOperators();








public function getGlobals();








public function getName();
}

class_alias('Twig\Extension\ExtensionInterface', 'Twig_ExtensionInterface');


class_exists('Twig\Environment');
<?php










namespace Twig\Extension {
use Twig\ExpressionParser;
use Twig\TokenParser\ApplyTokenParser;
use Twig\TokenParser\BlockTokenParser;
use Twig\TokenParser\DeprecatedTokenParser;
use Twig\TokenParser\DoTokenParser;
use Twig\TokenParser\EmbedTokenParser;
use Twig\TokenParser\ExtendsTokenParser;
use Twig\TokenParser\FilterTokenParser;
use Twig\TokenParser\FlushTokenParser;
use Twig\TokenParser\ForTokenParser;
use Twig\TokenParser\FromTokenParser;
use Twig\TokenParser\IfTokenParser;
use Twig\TokenParser\ImportTokenParser;
use Twig\TokenParser\IncludeTokenParser;
use Twig\TokenParser\MacroTokenParser;
use Twig\TokenParser\SetTokenParser;
use Twig\TokenParser\SpacelessTokenParser;
use Twig\TokenParser\UseTokenParser;
use Twig\TokenParser\WithTokenParser;
use Twig\TwigFilter;
use Twig\TwigFunction;
use Twig\TwigTest;




class CoreExtension extends AbstractExtension
{
protected $dateFormats = ['F j, Y H:i', '%d days'];
protected $numberFormat = [0, '.', ','];
protected $timezone = null;
protected $escapers = [];







public function setEscaper($strategy, $callable)
{
$this->escapers[$strategy] = $callable;
}






public function getEscapers()
{
return $this->escapers;
}







public function setDateFormat($format = null, $dateIntervalFormat = null)
{
if (null !== $format) {
$this->dateFormats[0] = $format;
}

if (null !== $dateIntervalFormat) {
$this->dateFormats[1] = $dateIntervalFormat;
}
}






public function getDateFormat()
{
return $this->dateFormats;
}






public function setTimezone($timezone)
{
$this->timezone = $timezone instanceof \DateTimeZone ? $timezone : new \DateTimeZone($timezone);
}






public function getTimezone()
{
if (null === $this->timezone) {
$this->timezone = new \DateTimeZone(date_default_timezone_get());
}

return $this->timezone;
}








public function setNumberFormat($decimal, $decimalPoint, $thousandSep)
{
$this->numberFormat = [$decimal, $decimalPoint, $thousandSep];
}






public function getNumberFormat()
{
return $this->numberFormat;
}

public function getTokenParsers()
{
return [
new ApplyTokenParser(),
new ForTokenParser(),
new IfTokenParser(),
new ExtendsTokenParser(),
new IncludeTokenParser(),
new BlockTokenParser(),
new UseTokenParser(),
new FilterTokenParser(),
new MacroTokenParser(),
new ImportTokenParser(),
new FromTokenParser(),
new SetTokenParser(),
new SpacelessTokenParser(),
new FlushTokenParser(),
new DoTokenParser(),
new EmbedTokenParser(),
new WithTokenParser(),
new DeprecatedTokenParser(),
];
}

public function getFilters()
{
$filters = [

new TwigFilter('date', 'twig_date_format_filter', ['needs_environment' => true]),
new TwigFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]),
new TwigFilter('format', 'sprintf'),
new TwigFilter('replace', 'twig_replace_filter'),
new TwigFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]),
new TwigFilter('abs', 'abs'),
new TwigFilter('round', 'twig_round'),


new TwigFilter('url_encode', 'twig_urlencode_filter'),
new TwigFilter('json_encode', 'twig_jsonencode_filter'),
new TwigFilter('convert_encoding', 'twig_convert_encoding'),


new TwigFilter('title', 'twig_title_string_filter', ['needs_environment' => true]),
new TwigFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]),
new TwigFilter('upper', 'strtoupper'),
new TwigFilter('lower', 'strtolower'),
new TwigFilter('striptags', 'strip_tags'),
new TwigFilter('trim', 'twig_trim_filter'),
new TwigFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
new TwigFilter('spaceless', 'twig_spaceless', ['is_safe' => ['html']]),


new TwigFilter('join', 'twig_join_filter'),
new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]),
new TwigFilter('sort', 'twig_sort_filter'),
new TwigFilter('merge', 'twig_array_merge'),
new TwigFilter('batch', 'twig_array_batch'),
new TwigFilter('filter', 'twig_array_filter', ['needs_environment' => true]),
new TwigFilter('map', 'twig_array_map', ['needs_environment' => true]),
new TwigFilter('reduce', 'twig_array_reduce', ['needs_environment' => true]),


new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]),
new TwigFilter('length', 'twig_length_filter', ['needs_environment' => true]),
new TwigFilter('slice', 'twig_slice', ['needs_environment' => true]),
new TwigFilter('first', 'twig_first', ['needs_environment' => true]),
new TwigFilter('last', 'twig_last', ['needs_environment' => true]),


new TwigFilter('default', '_twig_default_filter', ['node_class' => '\Twig\Node\Expression\Filter\DefaultFilter']),
new TwigFilter('keys', 'twig_get_array_keys_filter'),


new TwigFilter('escape', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
new TwigFilter('e', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']),
];

if (\function_exists('mb_get_info')) {
$filters[] = new TwigFilter('upper', 'twig_upper_filter', ['needs_environment' => true]);
$filters[] = new TwigFilter('lower', 'twig_lower_filter', ['needs_environment' => true]);
}

return $filters;
}

public function getFunctions()
{
return [
new TwigFunction('max', 'max'),
new TwigFunction('min', 'min'),
new TwigFunction('range', 'range'),
new TwigFunction('constant', 'twig_constant'),
new TwigFunction('cycle', 'twig_cycle'),
new TwigFunction('random', 'twig_random', ['needs_environment' => true]),
new TwigFunction('date', 'twig_date_converter', ['needs_environment' => true]),
new TwigFunction('include', 'twig_include', ['needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all']]),
new TwigFunction('source', 'twig_source', ['needs_environment' => true, 'is_safe' => ['all']]),
];
}

public function getTests()
{
return [
new TwigTest('even', null, ['node_class' => '\Twig\Node\Expression\Test\EvenTest']),
new TwigTest('odd', null, ['node_class' => '\Twig\Node\Expression\Test\OddTest']),
new TwigTest('defined', null, ['node_class' => '\Twig\Node\Expression\Test\DefinedTest']),
new TwigTest('sameas', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']),
new TwigTest('same as', null, ['node_class' => '\Twig\Node\Expression\Test\SameasTest', 'one_mandatory_argument' => true]),
new TwigTest('none', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
new TwigTest('null', null, ['node_class' => '\Twig\Node\Expression\Test\NullTest']),
new TwigTest('divisibleby', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']),
new TwigTest('divisible by', null, ['node_class' => '\Twig\Node\Expression\Test\DivisiblebyTest', 'one_mandatory_argument' => true]),
new TwigTest('constant', null, ['node_class' => '\Twig\Node\Expression\Test\ConstantTest']),
new TwigTest('empty', 'twig_test_empty'),
new TwigTest('iterable', 'twig_test_iterable'),
];
}

public function getOperators()
{
return [
[
'not' => ['precedence' => 50, 'class' => '\Twig\Node\Expression\Unary\NotUnary'],
'-' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\NegUnary'],
'+' => ['precedence' => 500, 'class' => '\Twig\Node\Expression\Unary\PosUnary'],
],
[
'or' => ['precedence' => 10, 'class' => '\Twig\Node\Expression\Binary\OrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'and' => ['precedence' => 15, 'class' => '\Twig\Node\Expression\Binary\AndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'b-or' => ['precedence' => 16, 'class' => '\Twig\Node\Expression\Binary\BitwiseOrBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'b-xor' => ['precedence' => 17, 'class' => '\Twig\Node\Expression\Binary\BitwiseXorBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'b-and' => ['precedence' => 18, 'class' => '\Twig\Node\Expression\Binary\BitwiseAndBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'==' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'!=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'<' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'>' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'>=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\GreaterEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'<=' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\LessEqualBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'not in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\NotInBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'in' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\InBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'matches' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\MatchesBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'starts with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\StartsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'ends with' => ['precedence' => 20, 'class' => '\Twig\Node\Expression\Binary\EndsWithBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'..' => ['precedence' => 25, 'class' => '\Twig\Node\Expression\Binary\RangeBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'+' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\AddBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'-' => ['precedence' => 30, 'class' => '\Twig\Node\Expression\Binary\SubBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'~' => ['precedence' => 40, 'class' => '\Twig\Node\Expression\Binary\ConcatBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'*' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\MulBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'/' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\DivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'//' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\FloorDivBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'%' => ['precedence' => 60, 'class' => '\Twig\Node\Expression\Binary\ModBinary', 'associativity' => ExpressionParser::OPERATOR_LEFT],
'is' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
'is not' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT],
'**' => ['precedence' => 200, 'class' => '\Twig\Node\Expression\Binary\PowerBinary', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
'??' => ['precedence' => 300, 'class' => '\Twig\Node\Expression\NullCoalesceExpression', 'associativity' => ExpressionParser::OPERATOR_RIGHT],
],
];
}

public function getName()
{
return 'core';
}
}

class_alias('Twig\Extension\CoreExtension', 'Twig_Extension_Core');
}

namespace {
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Loader\SourceContextLoaderInterface;
use Twig\Markup;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Node;
use Twig\Template;
use Twig\TemplateWrapper;









function twig_cycle($values, $position)
{
if (!\is_array($values) && !$values instanceof \ArrayAccess) {
return $values;
}

return $values[$position % \count($values)];
}














function twig_random(Environment $env, $values = null, $max = null)
{
if (null === $values) {
return null === $max ? mt_rand() : mt_rand(0, (int) $max);
}

if (\is_int($values) || \is_float($values)) {
if (null === $max) {
if ($values < 0) {
$max = 0;
$min = $values;
} else {
$max = $values;
$min = 0;
}
} else {
$min = $values;
$max = $max;
}

return mt_rand((int) $min, (int) $max);
}

if (\is_string($values)) {
if ('' === $values) {
return '';
}
if (null !== $charset = $env->getCharset()) {
if ('UTF-8' !== $charset) {
$values = twig_convert_encoding($values, 'UTF-8', $charset);
}



$values = preg_split('/(?<!^)(?!$)/u', $values);

if ('UTF-8' !== $charset) {
foreach ($values as $i => $value) {
$values[$i] = twig_convert_encoding($value, $charset, 'UTF-8');
}
}
} else {
return $values[mt_rand(0, \strlen($values) - 1)];
}
}

if (!twig_test_iterable($values)) {
return $values;
}

$values = twig_to_array($values);

if (0 === \count($values)) {
throw new RuntimeError('The random function cannot pick from an empty array.');
}

return $values[array_rand($values, 1)];
}












function twig_date_format_filter(Environment $env, $date, $format = null, $timezone = null)
{
if (null === $format) {
$formats = $env->getExtension('\Twig\Extension\CoreExtension')->getDateFormat();
$format = $date instanceof \DateInterval ? $formats[1] : $formats[0];
}

if ($date instanceof \DateInterval) {
return $date->format($format);
}

return twig_date_converter($env, $date, $timezone)->format($format);
}











function twig_date_modify_filter(Environment $env, $date, $modifier)
{
$date = twig_date_converter($env, $date, false);
$resultDate = $date->modify($modifier);




return null === $resultDate ? $date : $resultDate;
}













function twig_date_converter(Environment $env, $date = null, $timezone = null)
{

if (false !== $timezone) {
if (null === $timezone) {
$timezone = $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone();
} elseif (!$timezone instanceof \DateTimeZone) {
$timezone = new \DateTimeZone($timezone);
}
}


if ($date instanceof \DateTimeImmutable) {
return false !== $timezone ? $date->setTimezone($timezone) : $date;
}

if ($date instanceof \DateTime || $date instanceof \DateTimeInterface) {
$date = clone $date;
if (false !== $timezone) {
$date->setTimezone($timezone);
}

return $date;
}

if (null === $date || 'now' === $date) {
if (null === $date) {
$date = 'now';
}

return new \DateTime($date, false !== $timezone ? $timezone : $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
}

$asString = (string) $date;
if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) {
$date = new \DateTime('@'.$date);
} else {
$date = new \DateTime($date, $env->getExtension('\Twig\Extension\CoreExtension')->getTimezone());
}

if (false !== $timezone) {
$date->setTimezone($timezone);
}

return $date;
}










function twig_replace_filter($str, $from, $to = null)
{
if (\is_string($from) && \is_string($to)) {
@trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', \E_USER_DEPRECATED);

return strtr($str, $from, $to);
}

if (!twig_test_iterable($from)) {
throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
}

return strtr($str, twig_to_array($from));
}










function twig_round($value, $precision = 0, $method = 'common')
{
if ('common' === $method) {
return round($value, $precision);
}

if ('ceil' !== $method && 'floor' !== $method) {
throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
}

return $method($value * 10 ** $precision) / 10 ** $precision;
}















function twig_number_format_filter(Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
{
$defaults = $env->getExtension('\Twig\Extension\CoreExtension')->getNumberFormat();
if (null === $decimal) {
$decimal = $defaults[0];
}

if (null === $decimalPoint) {
$decimalPoint = $defaults[1];
}

if (null === $thousandSep) {
$thousandSep = $defaults[2];
}

return number_format((float) $number, $decimal, $decimalPoint, $thousandSep);
}








function twig_urlencode_filter($url)
{
if (\is_array($url)) {
if (\defined('PHP_QUERY_RFC3986')) {
return http_build_query($url, '', '&', \PHP_QUERY_RFC3986);
}

return http_build_query($url, '', '&');
}

return rawurlencode($url);
}









function twig_jsonencode_filter($value, $options = 0)
{
if ($value instanceof Markup) {
$value = (string) $value;
} elseif (\is_array($value)) {
array_walk_recursive($value, '_twig_markup2string');
}

return json_encode($value, $options);
}

function _twig_markup2string(&$value)
{
if ($value instanceof Markup) {
$value = (string) $value;
}
}















function twig_array_merge($arr1, $arr2)
{
if (!twig_test_iterable($arr1)) {
throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($arr1)));
}

if (!twig_test_iterable($arr2)) {
throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', \gettype($arr2)));
}

return array_merge(twig_to_array($arr1), twig_to_array($arr2));
}











function twig_slice(Environment $env, $item, $start, $length = null, $preserveKeys = false)
{
if ($item instanceof \Traversable) {
while ($item instanceof \IteratorAggregate) {
$item = $item->getIterator();
}

if ($start >= 0 && $length >= 0 && $item instanceof \Iterator) {
try {
return iterator_to_array(new \LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys);
} catch (\OutOfBoundsException $e) {
return [];
}
}

$item = iterator_to_array($item, $preserveKeys);
}

if (\is_array($item)) {
return \array_slice($item, $start, $length, $preserveKeys);
}

$item = (string) $item;

if (\function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
}

return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length));
}








function twig_first(Environment $env, $item)
{
$elements = twig_slice($env, $item, 0, 1, false);

return \is_string($elements) ? $elements : current($elements);
}








function twig_last(Environment $env, $item)
{
$elements = twig_slice($env, $item, -1, 1, false);

return \is_string($elements) ? $elements : current($elements);
}





















function twig_join_filter($value, $glue = '', $and = null)
{
if (!twig_test_iterable($value)) {
$value = (array) $value;
}

$value = twig_to_array($value, false);

if (0 === \count($value)) {
return '';
}

if (null === $and || $and === $glue) {
return implode($glue, $value);
}

if (1 === \count($value)) {
return $value[0];
}

return implode($glue, \array_slice($value, 0, -1)).$and.$value[\count($value) - 1];
}






















function twig_split_filter(Environment $env, $value, $delimiter, $limit = null)
{
if (\strlen($delimiter) > 0) {
return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
}

if (!\function_exists('mb_get_info') || null === $charset = $env->getCharset()) {
return str_split($value, null === $limit ? 1 : $limit);
}

if ($limit <= 1) {
return preg_split('/(?<!^)(?!$)/u', $value);
}

$length = mb_strlen($value, $charset);
if ($length < $limit) {
return [$value];
}

$r = [];
for ($i = 0; $i < $length; $i += $limit) {
$r[] = mb_substr($value, $i, $limit, $charset);
}

return $r;
}







function _twig_default_filter($value, $default = '')
{
if (twig_test_empty($value)) {
return $default;
}

return $value;
}














function twig_get_array_keys_filter($array)
{
if ($array instanceof \Traversable) {
while ($array instanceof \IteratorAggregate) {
$array = $array->getIterator();
}

if ($array instanceof \Iterator) {
$keys = [];
$array->rewind();
while ($array->valid()) {
$keys[] = $array->key();
$array->next();
}

return $keys;
}

$keys = [];
foreach ($array as $key => $item) {
$keys[] = $key;
}

return $keys;
}

if (!\is_array($array)) {
return [];
}

return array_keys($array);
}









function twig_reverse_filter(Environment $env, $item, $preserveKeys = false)
{
if ($item instanceof \Traversable) {
return array_reverse(iterator_to_array($item), $preserveKeys);
}

if (\is_array($item)) {
return array_reverse($item, $preserveKeys);
}

if (null !== $charset = $env->getCharset()) {
$string = (string) $item;

if ('UTF-8' !== $charset) {
$item = twig_convert_encoding($string, 'UTF-8', $charset);
}

preg_match_all('/./us', $item, $matches);

$string = implode('', array_reverse($matches[0]));

if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}

return $string;
}

return strrev((string) $item);
}








function twig_sort_filter($array)
{
if ($array instanceof \Traversable) {
$array = iterator_to_array($array);
} elseif (!\is_array($array)) {
throw new RuntimeError(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array)));
}

asort($array);

return $array;
}




function twig_in_filter($value, $compare)
{
if ($value instanceof Markup) {
$value = (string) $value;
}
if ($compare instanceof Markup) {
$compare = (string) $compare;
}

if (\is_array($compare)) {
return \in_array($value, $compare, \is_object($value) || \is_resource($value));
} elseif (\is_string($compare) && (\is_string($value) || \is_int($value) || \is_float($value))) {
return '' === $value || false !== strpos($compare, (string) $value);
} elseif ($compare instanceof \Traversable) {
if (\is_object($value) || \is_resource($value)) {
foreach ($compare as $item) {
if ($item === $value) {
return true;
}
}
} else {
foreach ($compare as $item) {
if ($item == $value) {
return true;
}
}
}

return false;
}

return false;
}








function twig_trim_filter($string, $characterMask = null, $side = 'both')
{
if (null === $characterMask) {
$characterMask = " \t\n\r\0\x0B";
}

switch ($side) {
case 'both':
return trim($string, $characterMask);
case 'left':
return ltrim($string, $characterMask);
case 'right':
return rtrim($string, $characterMask);
default:
throw new RuntimeError('Trimming side must be "left", "right" or "both".');
}
}






function twig_spaceless($content)
{
return trim(preg_replace('/>\s+</', '><', $content));
}











function twig_escape_filter(Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
{
if ($autoescape && $string instanceof Markup) {
return $string;
}

if (!\is_string($string)) {
if (\is_object($string) && method_exists($string, '__toString')) {
$string = (string) $string;
} elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) {
return $string;
}
}

if ('' === $string) {
return '';
}

if (null === $charset) {
$charset = $env->getCharset();
}

switch ($strategy) {
case 'html':





static $htmlspecialcharsCharsets = [
'ISO-8859-1' => true, 'ISO8859-1' => true,
'ISO-8859-15' => true, 'ISO8859-15' => true,
'utf-8' => true, 'UTF-8' => true,
'CP866' => true, 'IBM866' => true, '866' => true,
'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
'1251' => true,
'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
'BIG5' => true, '950' => true,
'GB2312' => true, '936' => true,
'BIG5-HKSCS' => true,
'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
'EUC-JP' => true, 'EUCJP' => true,
'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
];

if (isset($htmlspecialcharsCharsets[$charset])) {
return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);
}

if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) {

$htmlspecialcharsCharsets[$charset] = true;

return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);
}

$string = twig_convert_encoding($string, 'UTF-8', $charset);
$string = htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8');

return twig_convert_encoding($string, $charset, 'UTF-8');

case 'js':


if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}

if (!preg_match('//u', $string)) {
throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
}

$string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);

if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}

return $string;

case 'css':
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}

if (!preg_match('//u', $string)) {
throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
}

$string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);

if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}

return $string;

case 'html_attr':
if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}

if (!preg_match('//u', $string)) {
throw new RuntimeError('The string to escape is not a valid UTF-8 string.');
}

$string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);

if ('UTF-8' !== $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}

return $string;

case 'url':
return rawurlencode($string);

default:
static $escapers;

if (null === $escapers) {
$escapers = $env->getExtension('\Twig\Extension\CoreExtension')->getEscapers();
}

if (isset($escapers[$strategy])) {
return \call_user_func($escapers[$strategy], $env, $string, $charset);
}

$validStrategies = implode(', ', array_merge(['html', 'js', 'url', 'css', 'html_attr'], array_keys($escapers)));

throw new RuntimeError(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
}
}




function twig_escape_filter_is_safe(Node $filterArgs)
{
foreach ($filterArgs as $arg) {
if ($arg instanceof ConstantExpression) {
return [$arg->getAttribute('value')];
}

return [];
}

return ['html'];
}

if (\function_exists('mb_convert_encoding')) {
function twig_convert_encoding($string, $to, $from)
{
return mb_convert_encoding($string, $to, $from);
}
} elseif (\function_exists('iconv')) {
function twig_convert_encoding($string, $to, $from)
{
return iconv($from, $to, $string);
}
} else {
function twig_convert_encoding($string, $to, $from)
{
throw new RuntimeError('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
}
}

if (\function_exists('mb_ord')) {
function twig_ord($string)
{
return mb_ord($string, 'UTF-8');
}
} else {
function twig_ord($string)
{
$code = ($string = unpack('C*', substr($string, 0, 4))) ? $string[1] : 0;
if (0xF0 <= $code) {
return (($code - 0xF0) << 18) + (($string[2] - 0x80) << 12) + (($string[3] - 0x80) << 6) + $string[4] - 0x80;
}
if (0xE0 <= $code) {
return (($code - 0xE0) << 12) + (($string[2] - 0x80) << 6) + $string[3] - 0x80;
}
if (0xC0 <= $code) {
return (($code - 0xC0) << 6) + $string[2] - 0x80;
}

return $code;
}
}

function _twig_escape_js_callback($matches)
{
$char = $matches[0];






static $shortMap = [
'\\' => '\\\\',
'/' => '\\/',
"\x08" => '\b',
"\x0C" => '\f',
"\x0A" => '\n',
"\x0D" => '\r',
"\x09" => '\t',
];

if (isset($shortMap[$char])) {
return $shortMap[$char];
}

$codepoint = mb_ord($char, 'UTF-8');
if (0x10000 > $codepoint) {
return sprintf('\u%04X', $codepoint);
}



$u = $codepoint - 0x10000;
$high = 0xD800 | ($u >> 10);
$low = 0xDC00 | ($u & 0x3FF);

return sprintf('\u%04X\u%04X', $high, $low);
}

function _twig_escape_css_callback($matches)
{
$char = $matches[0];

return sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : twig_ord($char));
}







function _twig_escape_html_attr_callback($matches)
{
$chr = $matches[0];
$ord = \ord($chr);





if (($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr) || ($ord >= 0x7f && $ord <= 0x9f)) {
return '&#xFFFD;';
}





if (1 == \strlen($chr)) {






static $entityMap = [
34 => '&quot;', 
38 => '&amp;', 
60 => '&lt;', 
62 => '&gt;', 
];

if (isset($entityMap[$ord])) {
return $entityMap[$ord];
}

return sprintf('&#x%02X;', $ord);
}





return sprintf('&#x%04X;', twig_ord($chr));
}


if (\function_exists('mb_get_info')) {







function twig_length_filter(Environment $env, $thing)
{
if (null === $thing) {
return 0;
}

if (is_scalar($thing)) {
return mb_strlen($thing, $env->getCharset());
}

if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) {
return \count($thing);
}

if ($thing instanceof \Traversable) {
return iterator_count($thing);
}

if (\is_object($thing) && method_exists($thing, '__toString')) {
return mb_strlen((string) $thing, $env->getCharset());
}

return 1;
}








function twig_upper_filter(Environment $env, $string)
{
if (null !== $charset = $env->getCharset()) {
return mb_strtoupper($string, $charset);
}

return strtoupper($string);
}








function twig_lower_filter(Environment $env, $string)
{
if (null !== $charset = $env->getCharset()) {
return mb_strtolower($string, $charset);
}

return strtolower($string);
}








function twig_title_string_filter(Environment $env, $string)
{
if (null !== $charset = $env->getCharset()) {
return mb_convert_case($string, \MB_CASE_TITLE, $charset);
}

return ucwords(strtolower($string));
}








function twig_capitalize_string_filter(Environment $env, $string)
{
if (null !== $charset = $env->getCharset()) {
return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, mb_strlen($string, $charset), $charset), $charset);
}

return ucfirst(strtolower($string));
}
}

else {







function twig_length_filter(Environment $env, $thing)
{
if (null === $thing) {
return 0;
}

if (is_scalar($thing)) {
return \strlen($thing);
}

if ($thing instanceof \SimpleXMLElement) {
return \count($thing);
}

if (\is_object($thing) && method_exists($thing, '__toString') && !$thing instanceof \Countable) {
return \strlen((string) $thing);
}

if ($thing instanceof \Countable || \is_array($thing)) {
return \count($thing);
}

if ($thing instanceof \IteratorAggregate) {
return iterator_count($thing);
}

return 1;
}








function twig_title_string_filter(Environment $env, $string)
{
return ucwords(strtolower($string));
}








function twig_capitalize_string_filter(Environment $env, $string)
{
return ucfirst(strtolower($string));
}
}




function twig_ensure_traversable($seq)
{
if ($seq instanceof \Traversable || \is_array($seq)) {
return $seq;
}

return [];
}




function twig_to_array($seq, $preserveKeys = true)
{
if ($seq instanceof \Traversable) {
return iterator_to_array($seq, $preserveKeys);
}

if (!\is_array($seq)) {
return $seq;
}

return $preserveKeys ? $seq : array_values($seq);
}













function twig_test_empty($value)
{
if ($value instanceof \Countable) {
return 0 === \count($value);
}

if ($value instanceof \Traversable) {
return !iterator_count($value);
}

if (\is_object($value) && method_exists($value, '__toString')) {
return '' === (string) $value;
}

return '' === $value || false === $value || null === $value || [] === $value;
}













function twig_test_iterable($value)
{
return $value instanceof \Traversable || \is_array($value);
}













function twig_include(Environment $env, $context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false)
{
$alreadySandboxed = false;
$sandbox = null;
if ($withContext) {
$variables = array_merge($context, $variables);
}

if ($isSandboxed = $sandboxed && $env->hasExtension('\Twig\Extension\SandboxExtension')) {
$sandbox = $env->getExtension('\Twig\Extension\SandboxExtension');
if (!$alreadySandboxed = $sandbox->isSandboxed()) {
$sandbox->enableSandbox();
}

foreach ((\is_array($template) ? $template : [$template]) as $name) {

if ($name instanceof TemplateWrapper || $name instanceof Template) {
$name->unwrap()->checkSecurity();
}
}
}

$loaded = null;
try {
$loaded = $env->resolveTemplate($template);
} catch (LoaderError $e) {
if (!$ignoreMissing) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}

throw $e;
}
} catch (\Throwable $e) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}

throw $e;
} catch (\Exception $e) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}

throw $e;
}

try {
$ret = $loaded ? $loaded->render($variables) : '';
} catch (\Exception $e) {
if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}

throw $e;
}

if ($isSandboxed && !$alreadySandboxed) {
$sandbox->disableSandbox();
}

return $ret;
}









function twig_source(Environment $env, $name, $ignoreMissing = false)
{
$loader = $env->getLoader();
try {
if (!$loader instanceof SourceContextLoaderInterface) {
return $loader->getSource($name);
} else {
return $loader->getSourceContext($name)->getCode();
}
} catch (LoaderError $e) {
if (!$ignoreMissing) {
throw $e;
}
}
}









function twig_constant($constant, $object = null)
{
if (null !== $object) {
$constant = \get_class($object).'::'.$constant;
}

return \constant($constant);
}









function twig_constant_is_defined($constant, $object = null)
{
if (null !== $object) {
$constant = \get_class($object).'::'.$constant;
}

return \defined($constant);
}










function twig_array_batch($items, $size, $fill = null, $preserveKeys = true)
{
if (!twig_test_iterable($items)) {
throw new RuntimeError(sprintf('The "batch" filter expects an array or "Traversable", got "%s".', \is_object($items) ? \get_class($items) : \gettype($items)));
}

$size = ceil($size);

$result = array_chunk(twig_to_array($items, $preserveKeys), $size, $preserveKeys);

if (null !== $fill && $result) {
$last = \count($result) - 1;
if ($fillCount = $size - \count($result[$last])) {
for ($i = 0; $i < $fillCount; ++$i) {
$result[$last][] = $fill;
}
}
}

return $result;
}

function twig_array_filter(Environment $env, $array, $arrow)
{
if (!twig_test_iterable($array)) {
throw new RuntimeError(sprintf('The "filter" filter expects an array or "Traversable", got "%s".', \is_object($array) ? \get_class($array) : \gettype($array)));
}

if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
throw new RuntimeError('The callable passed to "filter" filter must be a Closure in sandbox mode.');
}

if (\is_array($array)) {
if (\PHP_VERSION_ID >= 50600) {
return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH);
}

return array_filter($array, $arrow);
}


return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow);
}

function twig_array_map(Environment $env, $array, $arrow)
{
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
throw new RuntimeError('The callable passed to the "map" filter must be a Closure in sandbox mode.');
}

$r = [];
foreach ($array as $k => $v) {
$r[$k] = $arrow($v, $k);
}

return $r;
}

function twig_array_reduce(Environment $env, $array, $arrow, $initial = null)
{
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
throw new RuntimeError('The callable passed to the "reduce" filter must be a Closure in sandbox mode.');
}

if (!\is_array($array)) {
if (!$array instanceof \Traversable) {
throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array)));
}

$array = iterator_to_array($array);
}

return array_reduce($array, $arrow, $initial);
}
}
<?php










namespace Twig\Extension {
use Twig\TwigFunction;




class DebugExtension extends AbstractExtension
{
public function getFunctions()
{

$isDumpOutputHtmlSafe = \extension_loaded('xdebug')

&& (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump'))


&& (false === ini_get('html_errors') || ini_get('html_errors'))
|| 'cli' === \PHP_SAPI
;

return [
new TwigFunction('dump', 'twig_var_dump', ['is_safe' => $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true, 'is_variadic' => true]),
];
}

public function getName()
{
return 'debug';
}
}

class_alias('Twig\Extension\DebugExtension', 'Twig_Extension_Debug');
}

namespace {
use Twig\Environment;
use Twig\Template;
use Twig\TemplateWrapper;

function twig_var_dump(Environment $env, $context, array $vars = [])
{
if (!$env->isDebug()) {
return;
}

ob_start();

if (!$vars) {
$vars = [];
foreach ($context as $key => $value) {
if (!$value instanceof Template && !$value instanceof TemplateWrapper) {
$vars[$key] = $value;
}
}

var_dump($vars);
} else {
foreach ($vars as $var) {
var_dump($var);
}
}

return ob_get_clean();
}
}
<?php










namespace Twig\Extension {
use Twig\TwigFunction;




class StringLoaderExtension extends AbstractExtension
{
public function getFunctions()
{
return [
new TwigFunction('template_from_string', 'twig_template_from_string', ['needs_environment' => true]),
];
}

public function getName()
{
return 'string_loader';
}
}

class_alias('Twig\Extension\StringLoaderExtension', 'Twig_Extension_StringLoader');
}

namespace {
use Twig\Environment;
use Twig\TemplateWrapper;











function twig_template_from_string(Environment $env, $template, $name = null)
{
return $env->createTemplate((string) $template, $name);
}
}
<?php










namespace Twig\Extension;

use Twig\NodeVisitor\SandboxNodeVisitor;
use Twig\Sandbox\SecurityPolicyInterface;
use Twig\TokenParser\SandboxTokenParser;




class SandboxExtension extends AbstractExtension
{
protected $sandboxedGlobally;
protected $sandboxed;
protected $policy;

public function __construct(SecurityPolicyInterface $policy, $sandboxed = false)
{
$this->policy = $policy;
$this->sandboxedGlobally = $sandboxed;
}

public function getTokenParsers()
{
return [new SandboxTokenParser()];
}

public function getNodeVisitors()
{
return [new SandboxNodeVisitor()];
}

public function enableSandbox()
{
$this->sandboxed = true;
}

public function disableSandbox()
{
$this->sandboxed = false;
}

public function isSandboxed()
{
return $this->sandboxedGlobally || $this->sandboxed;
}

public function isSandboxedGlobally()
{
return $this->sandboxedGlobally;
}

public function setSecurityPolicy(SecurityPolicyInterface $policy)
{
$this->policy = $policy;
}

public function getSecurityPolicy()
{
return $this->policy;
}

public function checkSecurity($tags, $filters, $functions)
{
if ($this->isSandboxed()) {
$this->policy->checkSecurity($tags, $filters, $functions);
}
}

public function checkMethodAllowed($obj, $method)
{
if ($this->isSandboxed()) {
$this->policy->checkMethodAllowed($obj, $method);
}
}

public function checkPropertyAllowed($obj, $method)
{
if ($this->isSandboxed()) {
$this->policy->checkPropertyAllowed($obj, $method);
}
}

public function ensureToStringAllowed($obj)
{
if ($this->isSandboxed() && \is_object($obj) && method_exists($obj, '__toString')) {
$this->policy->checkMethodAllowed($obj, '__toString');
}

return $obj;
}

public function getName()
{
return 'sandbox';
}
}

class_alias('Twig\Extension\SandboxExtension', 'Twig_Extension_Sandbox');
<?php










namespace Twig\Extension;









interface GlobalsInterface
{
}

class_alias('Twig\Extension\GlobalsInterface', 'Twig_Extension_GlobalsInterface');
<?php










namespace Twig\Extension;

use Twig\Profiler\NodeVisitor\ProfilerNodeVisitor;
use Twig\Profiler\Profile;

class ProfilerExtension extends AbstractExtension
{
private $actives = [];

public function __construct(Profile $profile)
{
$this->actives[] = $profile;
}

public function enter(Profile $profile)
{
$this->actives[0]->addProfile($profile);
array_unshift($this->actives, $profile);
}

public function leave(Profile $profile)
{
$profile->leave();
array_shift($this->actives);

if (1 === \count($this->actives)) {
$this->actives[0]->leave();
}
}

public function getNodeVisitors()
{
return [new ProfilerNodeVisitor(static::class)];
}

public function getName()
{
return 'profiler';
}
}

class_alias('Twig\Extension\ProfilerExtension', 'Twig_Extension_Profiler');
<?php










namespace Twig\Extension;

use Twig\Environment;

abstract class AbstractExtension implements ExtensionInterface
{



public function initRuntime(Environment $environment)
{
}

public function getTokenParsers()
{
return [];
}

public function getNodeVisitors()
{
return [];
}

public function getFilters()
{
return [];
}

public function getTests()
{
return [];
}

public function getFunctions()
{
return [];
}

public function getOperators()
{
return [];
}




public function getGlobals()
{
return [];
}




public function getName()
{
return static::class;
}
}

class_alias('Twig\Extension\AbstractExtension', 'Twig_Extension');
<?php










namespace Twig\Extension {
use Twig\NodeVisitor\EscaperNodeVisitor;
use Twig\TokenParser\AutoEscapeTokenParser;
use Twig\TwigFilter;




class EscaperExtension extends AbstractExtension
{
protected $defaultStrategy;






public function __construct($defaultStrategy = 'html')
{
$this->setDefaultStrategy($defaultStrategy);
}

public function getTokenParsers()
{
return [new AutoEscapeTokenParser()];
}

public function getNodeVisitors()
{
return [new EscaperNodeVisitor()];
}

public function getFilters()
{
return [
new TwigFilter('raw', 'twig_raw_filter', ['is_safe' => ['all']]),
];
}









public function setDefaultStrategy($defaultStrategy)
{

if (true === $defaultStrategy) {
@trigger_error('Using "true" as the default strategy is deprecated since version 1.21. Use "html" instead.', \E_USER_DEPRECATED);

$defaultStrategy = 'html';
}

if ('filename' === $defaultStrategy) {
@trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', \E_USER_DEPRECATED);

$defaultStrategy = 'name';
}

if ('name' === $defaultStrategy) {
$defaultStrategy = ['\Twig\FileExtensionEscapingStrategy', 'guess'];
}

$this->defaultStrategy = $defaultStrategy;
}








public function getDefaultStrategy($name)
{


if (!\is_string($this->defaultStrategy) && false !== $this->defaultStrategy) {
return \call_user_func($this->defaultStrategy, $name);
}

return $this->defaultStrategy;
}

public function getName()
{
return 'escaper';
}
}

class_alias('Twig\Extension\EscaperExtension', 'Twig_Extension_Escaper');
}

namespace {







function twig_raw_filter($string)
{
return $string;
}
}
<?php










namespace Twig\NodeVisitor;

use Twig\Environment;
use Twig\Node\CheckSecurityCallNode;
use Twig\Node\CheckSecurityNode;
use Twig\Node\CheckToStringNode;
use Twig\Node\Expression\Binary\ConcatBinary;
use Twig\Node\Expression\Binary\RangeBinary;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\Node\SetNode;






class SandboxNodeVisitor extends AbstractNodeVisitor
{
protected $inAModule = false;
protected $tags;
protected $filters;
protected $functions;

private $needsToStringWrap = false;

protected function doEnterNode(Node $node, Environment $env)
{
if ($node instanceof ModuleNode) {
$this->inAModule = true;
$this->tags = [];
$this->filters = [];
$this->functions = [];

return $node;
} elseif ($this->inAModule) {

if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) {
$this->tags[$node->getNodeTag()] = $node;
}


if ($node instanceof FilterExpression && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
$this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
}


if ($node instanceof FunctionExpression && !isset($this->functions[$node->getAttribute('name')])) {
$this->functions[$node->getAttribute('name')] = $node;
}


if ($node instanceof RangeBinary && !isset($this->functions['range'])) {
$this->functions['range'] = $node;
}

if ($node instanceof PrintNode) {
$this->needsToStringWrap = true;
$this->wrapNode($node, 'expr');
}

if ($node instanceof SetNode && !$node->getAttribute('capture')) {
$this->needsToStringWrap = true;
}


if ($this->needsToStringWrap) {
if ($node instanceof ConcatBinary) {
$this->wrapNode($node, 'left');
$this->wrapNode($node, 'right');
}
if ($node instanceof FilterExpression) {
$this->wrapNode($node, 'node');
$this->wrapArrayNode($node, 'arguments');
}
if ($node instanceof FunctionExpression) {
$this->wrapArrayNode($node, 'arguments');
}
}
}

return $node;
}

protected function doLeaveNode(Node $node, Environment $env)
{
if ($node instanceof ModuleNode) {
$this->inAModule = false;

$node->setNode('constructor_end', new Node([new CheckSecurityCallNode(), $node->getNode('constructor_end')]));
$node->setNode('class_end', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('class_end')]));
} elseif ($this->inAModule) {
if ($node instanceof PrintNode || $node instanceof SetNode) {
$this->needsToStringWrap = false;
}
}

return $node;
}

private function wrapNode(Node $node, $name)
{
$expr = $node->getNode($name);
if ($expr instanceof NameExpression || $expr instanceof GetAttrExpression) {
$node->setNode($name, new CheckToStringNode($expr));
}
}

private function wrapArrayNode(Node $node, $name)
{
$args = $node->getNode($name);
foreach ($args as $name => $_) {
$this->wrapNode($args, $name);
}
}

public function getPriority()
{
return 0;
}
}

class_alias('Twig\NodeVisitor\SandboxNodeVisitor', 'Twig_NodeVisitor_Sandbox');
<?php










namespace Twig\NodeVisitor;

use Twig\Environment;






interface NodeVisitorInterface
{





public function enterNode(\Twig_NodeInterface $node, Environment $env);






public function leaveNode(\Twig_NodeInterface $node, Environment $env);








public function getPriority();
}

class_alias('Twig\NodeVisitor\NodeVisitorInterface', 'Twig_NodeVisitorInterface');


class_exists('Twig\Environment');
<?php










namespace Twig\NodeVisitor;

use Twig\Environment;
use Twig\Node\AutoEscapeNode;
use Twig\Node\BlockNode;
use Twig\Node\BlockReferenceNode;
use Twig\Node\DoNode;
use Twig\Node\Expression\ConditionalExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Expression\InlinePrint;
use Twig\Node\ImportNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\NodeTraverser;






class EscaperNodeVisitor extends AbstractNodeVisitor
{
protected $statusStack = [];
protected $blocks = [];
protected $safeAnalysis;
protected $traverser;
protected $defaultStrategy = false;
protected $safeVars = [];

public function __construct()
{
$this->safeAnalysis = new SafeAnalysisNodeVisitor();
}

protected function doEnterNode(Node $node, Environment $env)
{
if ($node instanceof ModuleNode) {
if ($env->hasExtension('\Twig\Extension\EscaperExtension') && $defaultStrategy = $env->getExtension('\Twig\Extension\EscaperExtension')->getDefaultStrategy($node->getTemplateName())) {
$this->defaultStrategy = $defaultStrategy;
}
$this->safeVars = [];
$this->blocks = [];
} elseif ($node instanceof AutoEscapeNode) {
$this->statusStack[] = $node->getAttribute('value');
} elseif ($node instanceof BlockNode) {
$this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
} elseif ($node instanceof ImportNode) {
$this->safeVars[] = $node->getNode('var')->getAttribute('name');
}

return $node;
}

protected function doLeaveNode(Node $node, Environment $env)
{
if ($node instanceof ModuleNode) {
$this->defaultStrategy = false;
$this->safeVars = [];
$this->blocks = [];
} elseif ($node instanceof FilterExpression) {
return $this->preEscapeFilterNode($node, $env);
} elseif ($node instanceof PrintNode && false !== $type = $this->needEscaping($env)) {
$expression = $node->getNode('expr');
if ($expression instanceof ConditionalExpression && $this->shouldUnwrapConditional($expression, $env, $type)) {
return new DoNode($this->unwrapConditional($expression, $env, $type), $expression->getTemplateLine());
}

return $this->escapePrintNode($node, $env, $type);
}

if ($node instanceof AutoEscapeNode || $node instanceof BlockNode) {
array_pop($this->statusStack);
} elseif ($node instanceof BlockReferenceNode) {
$this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
}

return $node;
}

private function shouldUnwrapConditional(ConditionalExpression $expression, Environment $env, $type)
{
$expr2Safe = $this->isSafeFor($type, $expression->getNode('expr2'), $env);
$expr3Safe = $this->isSafeFor($type, $expression->getNode('expr3'), $env);

return $expr2Safe !== $expr3Safe;
}

private function unwrapConditional(ConditionalExpression $expression, Environment $env, $type)
{

$expr2 = $expression->getNode('expr2');
if ($expr2 instanceof ConditionalExpression && $this->shouldUnwrapConditional($expr2, $env, $type)) {
$expr2 = $this->unwrapConditional($expr2, $env, $type);
} else {
$expr2 = $this->escapeInlinePrintNode(new InlinePrint($expr2, $expr2->getTemplateLine()), $env, $type);
}
$expr3 = $expression->getNode('expr3');
if ($expr3 instanceof ConditionalExpression && $this->shouldUnwrapConditional($expr3, $env, $type)) {
$expr3 = $this->unwrapConditional($expr3, $env, $type);
} else {
$expr3 = $this->escapeInlinePrintNode(new InlinePrint($expr3, $expr3->getTemplateLine()), $env, $type);
}

return new ConditionalExpression($expression->getNode('expr1'), $expr2, $expr3, $expression->getTemplateLine());
}

private function escapeInlinePrintNode(InlinePrint $node, Environment $env, $type)
{
$expression = $node->getNode('node');

if ($this->isSafeFor($type, $expression, $env)) {
return $node;
}

return new InlinePrint($this->getEscaperFilter($type, $expression), $node->getTemplateLine());
}

protected function escapePrintNode(PrintNode $node, Environment $env, $type)
{
if (false === $type) {
return $node;
}

$expression = $node->getNode('expr');

if ($this->isSafeFor($type, $expression, $env)) {
return $node;
}

$class = \get_class($node);

return new $class($this->getEscaperFilter($type, $expression), $node->getTemplateLine());
}

protected function preEscapeFilterNode(FilterExpression $filter, Environment $env)
{
$name = $filter->getNode('filter')->getAttribute('value');

$type = $env->getFilter($name)->getPreEscape();
if (null === $type) {
return $filter;
}

$node = $filter->getNode('node');
if ($this->isSafeFor($type, $node, $env)) {
return $filter;
}

$filter->setNode('node', $this->getEscaperFilter($type, $node));

return $filter;
}

protected function isSafeFor($type, \Twig_NodeInterface $expression, $env)
{
$safe = $this->safeAnalysis->getSafe($expression);

if (null === $safe) {
if (null === $this->traverser) {
$this->traverser = new NodeTraverser($env, [$this->safeAnalysis]);
}

$this->safeAnalysis->setSafeVars($this->safeVars);

$this->traverser->traverse($expression);
$safe = $this->safeAnalysis->getSafe($expression);
}

return \in_array($type, $safe) || \in_array('all', $safe);
}

protected function needEscaping(Environment $env)
{
if (\count($this->statusStack)) {
return $this->statusStack[\count($this->statusStack) - 1];
}

return $this->defaultStrategy ? $this->defaultStrategy : false;
}

protected function getEscaperFilter($type, \Twig_NodeInterface $node)
{
$line = $node->getTemplateLine();
$name = new ConstantExpression('escape', $line);
$args = new Node([new ConstantExpression((string) $type, $line), new ConstantExpression(null, $line), new ConstantExpression(true, $line)]);

return new FilterExpression($node, $name, $args, $line);
}

public function getPriority()
{
return 0;
}
}

class_alias('Twig\NodeVisitor\EscaperNodeVisitor', 'Twig_NodeVisitor_Escaper');
<?php










namespace Twig\NodeVisitor;

use Twig\Environment;
use Twig\Node\Expression\BlockReferenceExpression;
use Twig\Node\Expression\ConditionalExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\MethodCallExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Expression\ParentExpression;
use Twig\Node\Node;




class SafeAnalysisNodeVisitor extends AbstractNodeVisitor
{
protected $data = [];
protected $safeVars = [];

public function setSafeVars($safeVars)
{
$this->safeVars = $safeVars;
}

public function getSafe(\Twig_NodeInterface $node)
{
$hash = spl_object_hash($node);
if (!isset($this->data[$hash])) {
return;
}

foreach ($this->data[$hash] as $bucket) {
if ($bucket['key'] !== $node) {
continue;
}

if (\in_array('html_attr', $bucket['value'])) {
$bucket['value'][] = 'html';
}

return $bucket['value'];
}
}

protected function setSafe(\Twig_NodeInterface $node, array $safe)
{
$hash = spl_object_hash($node);
if (isset($this->data[$hash])) {
foreach ($this->data[$hash] as &$bucket) {
if ($bucket['key'] === $node) {
$bucket['value'] = $safe;

return;
}
}
}
$this->data[$hash][] = [
'key' => $node,
'value' => $safe,
];
}

protected function doEnterNode(Node $node, Environment $env)
{
return $node;
}

protected function doLeaveNode(Node $node, Environment $env)
{
if ($node instanceof ConstantExpression) {

$this->setSafe($node, ['all']);
} elseif ($node instanceof BlockReferenceExpression) {

$this->setSafe($node, ['all']);
} elseif ($node instanceof ParentExpression) {

$this->setSafe($node, ['all']);
} elseif ($node instanceof ConditionalExpression) {

$safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
$this->setSafe($node, $safe);
} elseif ($node instanceof FilterExpression) {

$name = $node->getNode('filter')->getAttribute('value');
$args = $node->getNode('arguments');
if (false !== $filter = $env->getFilter($name)) {
$safe = $filter->getSafe($args);
if (null === $safe) {
$safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety());
}
$this->setSafe($node, $safe);
} else {
$this->setSafe($node, []);
}
} elseif ($node instanceof FunctionExpression) {

$name = $node->getAttribute('name');
$args = $node->getNode('arguments');
$function = $env->getFunction($name);
if (false !== $function) {
$this->setSafe($node, $function->getSafe($args));
} else {
$this->setSafe($node, []);
}
} elseif ($node instanceof MethodCallExpression) {
if ($node->getAttribute('safe')) {
$this->setSafe($node, ['all']);
} else {
$this->setSafe($node, []);
}
} elseif ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression) {
$name = $node->getNode('node')->getAttribute('name');

if ('_self' == $name || \in_array($name, $this->safeVars)) {
$this->setSafe($node, ['all']);
} else {
$this->setSafe($node, []);
}
} else {
$this->setSafe($node, []);
}

return $node;
}

protected function intersectSafe(array $a = null, array $b = null)
{
if (null === $a || null === $b) {
return [];
}

if (\in_array('all', $a)) {
return $b;
}

if (\in_array('all', $b)) {
return $a;
}

return array_intersect($a, $b);
}

public function getPriority()
{
return 0;
}
}

class_alias('Twig\NodeVisitor\SafeAnalysisNodeVisitor', 'Twig_NodeVisitor_SafeAnalysis');
<?php










namespace Twig\NodeVisitor;

use Twig\Environment;
use Twig\Node\BlockReferenceNode;
use Twig\Node\BodyNode;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\BlockReferenceExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Expression\ParentExpression;
use Twig\Node\Expression\TempNameExpression;
use Twig\Node\ForNode;
use Twig\Node\IncludeNode;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\Node\SetTempNode;













class OptimizerNodeVisitor extends AbstractNodeVisitor
{
public const OPTIMIZE_ALL = -1;
public const OPTIMIZE_NONE = 0;
public const OPTIMIZE_FOR = 2;
public const OPTIMIZE_RAW_FILTER = 4;
public const OPTIMIZE_VAR_ACCESS = 8;

protected $loops = [];
protected $loopsTargets = [];
protected $optimizers;
protected $prependedNodes = [];
protected $inABody = false;




public function __construct($optimizers = -1)
{
if (!\is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) {
throw new \InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers));
}

$this->optimizers = $optimizers;
}

protected function doEnterNode(Node $node, Environment $env)
{
if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
$this->enterOptimizeFor($node, $env);
}

if (\PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('\Twig\Extension\SandboxExtension')) {
if ($this->inABody) {
if (!$node instanceof AbstractExpression) {
if ('Twig_Node' !== \get_class($node)) {
array_unshift($this->prependedNodes, []);
}
} else {
$node = $this->optimizeVariables($node, $env);
}
} elseif ($node instanceof BodyNode) {
$this->inABody = true;
}
}

return $node;
}

protected function doLeaveNode(Node $node, Environment $env)
{
$expression = $node instanceof AbstractExpression;

if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
$this->leaveOptimizeFor($node, $env);
}

if (self::OPTIMIZE_RAW_FILTER === (self::OPTIMIZE_RAW_FILTER & $this->optimizers)) {
$node = $this->optimizeRawFilter($node, $env);
}

$node = $this->optimizePrintNode($node, $env);

if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('\Twig\Extension\SandboxExtension')) {
if ($node instanceof BodyNode) {
$this->inABody = false;
} elseif ($this->inABody) {
if (!$expression && 'Twig_Node' !== \get_class($node) && $prependedNodes = array_shift($this->prependedNodes)) {
$nodes = [];
foreach (array_unique($prependedNodes) as $name) {
$nodes[] = new SetTempNode($name, $node->getTemplateLine());
}

$nodes[] = $node;
$node = new Node($nodes);
}
}
}

return $node;
}

protected function optimizeVariables(\Twig_NodeInterface $node, Environment $env)
{
if ('Twig_Node_Expression_Name' === \get_class($node) && $node->isSimple()) {
$this->prependedNodes[0][] = $node->getAttribute('name');

return new TempNameExpression($node->getAttribute('name'), $node->getTemplateLine());
}

return $node;
}










protected function optimizePrintNode(\Twig_NodeInterface $node, Environment $env)
{
if (!$node instanceof PrintNode) {
return $node;
}

$exprNode = $node->getNode('expr');
if (
$exprNode instanceof BlockReferenceExpression ||
$exprNode instanceof ParentExpression
) {
$exprNode->setAttribute('output', true);

return $exprNode;
}

return $node;
}






protected function optimizeRawFilter(\Twig_NodeInterface $node, Environment $env)
{
if ($node instanceof FilterExpression && 'raw' == $node->getNode('filter')->getAttribute('value')) {
return $node->getNode('node');
}

return $node;
}




protected function enterOptimizeFor(\Twig_NodeInterface $node, Environment $env)
{
if ($node instanceof ForNode) {

$node->setAttribute('with_loop', false);
array_unshift($this->loops, $node);
array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name'));
array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name'));
} elseif (!$this->loops) {

return;
}




elseif ($node instanceof NameExpression && 'loop' === $node->getAttribute('name')) {
$node->setAttribute('always_defined', true);
$this->addLoopToCurrent();
}


elseif ($node instanceof NameExpression && \in_array($node->getAttribute('name'), $this->loopsTargets)) {
$node->setAttribute('always_defined', true);
}


elseif ($node instanceof BlockReferenceNode || $node instanceof BlockReferenceExpression) {
$this->addLoopToCurrent();
}


elseif ($node instanceof IncludeNode && !$node->getAttribute('only')) {
$this->addLoopToAll();
}


elseif ($node instanceof FunctionExpression
&& 'include' === $node->getAttribute('name')
&& (!$node->getNode('arguments')->hasNode('with_context')
|| false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value')
)
) {
$this->addLoopToAll();
}


elseif ($node instanceof GetAttrExpression
&& (!$node->getNode('attribute') instanceof ConstantExpression
|| 'parent' === $node->getNode('attribute')->getAttribute('value')
)
&& (true === $this->loops[0]->getAttribute('with_loop')
|| ($node->getNode('node') instanceof NameExpression
&& 'loop' === $node->getNode('node')->getAttribute('name')
)
)
) {
$this->addLoopToAll();
}
}




protected function leaveOptimizeFor(\Twig_NodeInterface $node, Environment $env)
{
if ($node instanceof ForNode) {
array_shift($this->loops);
array_shift($this->loopsTargets);
array_shift($this->loopsTargets);
}
}

protected function addLoopToCurrent()
{
$this->loops[0]->setAttribute('with_loop', true);
}

protected function addLoopToAll()
{
foreach ($this->loops as $loop) {
$loop->setAttribute('with_loop', true);
}
}

public function getPriority()
{
return 255;
}
}

class_alias('Twig\NodeVisitor\OptimizerNodeVisitor', 'Twig_NodeVisitor_Optimizer');
<?php










namespace Twig\NodeVisitor;

use Twig\Environment;
use Twig\Node\Node;








abstract class AbstractNodeVisitor implements NodeVisitorInterface
{
final public function enterNode(\Twig_NodeInterface $node, Environment $env)
{
if (!$node instanceof Node) {
throw new \LogicException(sprintf('%s only supports \Twig\Node\Node instances.', __CLASS__));
}

return $this->doEnterNode($node, $env);
}

final public function leaveNode(\Twig_NodeInterface $node, Environment $env)
{
if (!$node instanceof Node) {
throw new \LogicException(sprintf('%s only supports \Twig\Node\Node instances.', __CLASS__));
}

return $this->doLeaveNode($node, $env);
}






abstract protected function doEnterNode(Node $node, Environment $env);






abstract protected function doLeaveNode(Node $node, Environment $env);
}

class_alias('Twig\NodeVisitor\AbstractNodeVisitor', 'Twig_BaseNodeVisitor');
<?php










namespace Twig\Error;






class LoaderError extends Error
{
}

class_alias('Twig\Error\LoaderError', 'Twig_Error_Loader');
<?php










namespace Twig\Error;

use Twig\Source;
use Twig\Template;























class Error extends \Exception
{
protected $lineno;

protected $filename;
protected $rawMessage;

private $sourcePath;
private $sourceCode;












public function __construct($message, $lineno = -1, $source = null, \Exception $previous = null)
{
if (null === $source) {
$name = null;
} elseif (!$source instanceof Source) {

$name = $source;
} else {
$name = $source->getName();
$this->sourceCode = $source->getCode();
$this->sourcePath = $source->getPath();
}
parent::__construct('', 0, $previous);

$this->lineno = $lineno;
$this->filename = $name;
$this->rawMessage = $message;
$this->updateRepr();
}






public function getRawMessage()
{
return $this->rawMessage;
}








public function getTemplateFile()
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);

return $this->filename;
}








public function setTemplateFile($name)
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);

$this->filename = $name;

$this->updateRepr();
}








public function getTemplateName()
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);

return $this->filename;
}








public function setTemplateName($name)
{
@trigger_error(sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);

$this->filename = $name;
$this->sourceCode = $this->sourcePath = null;

$this->updateRepr();
}






public function getTemplateLine()
{
return $this->lineno;
}






public function setTemplateLine($lineno)
{
$this->lineno = $lineno;

$this->updateRepr();
}






public function getSourceContext()
{
return $this->filename ? new Source($this->sourceCode, $this->filename, $this->sourcePath) : null;
}




public function setSourceContext(Source $source = null)
{
if (null === $source) {
$this->sourceCode = $this->filename = $this->sourcePath = null;
} else {
$this->sourceCode = $source->getCode();
$this->filename = $source->getName();
$this->sourcePath = $source->getPath();
}

$this->updateRepr();
}

public function guess()
{
$this->guessTemplateInfo();
$this->updateRepr();
}

public function appendMessage($rawMessage)
{
$this->rawMessage .= $rawMessage;
$this->updateRepr();
}




protected function updateRepr()
{
$this->message = $this->rawMessage;

if ($this->sourcePath && $this->lineno > 0) {
$this->file = $this->sourcePath;
$this->line = $this->lineno;

return;
}

$dot = false;
if ('.' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$dot = true;
}

$questionMark = false;
if ('?' === substr($this->message, -1)) {
$this->message = substr($this->message, 0, -1);
$questionMark = true;
}

if ($this->filename) {
if (\is_string($this->filename) || (\is_object($this->filename) && method_exists($this->filename, '__toString'))) {
$name = sprintf('"%s"', $this->filename);
} else {
$name = json_encode($this->filename);
}
$this->message .= sprintf(' in %s', $name);
}

if ($this->lineno && $this->lineno >= 0) {
$this->message .= sprintf(' at line %d', $this->lineno);
}

if ($dot) {
$this->message .= '.';
}

if ($questionMark) {
$this->message .= '?';
}
}




protected function guessTemplateInfo()
{
$template = null;
$templateClass = null;

$backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT);
foreach ($backtrace as $trace) {
if (isset($trace['object']) && $trace['object'] instanceof Template && 'Twig_Template' !== \get_class($trace['object'])) {
$currentClass = \get_class($trace['object']);
$isEmbedContainer = null === $templateClass ? false : 0 === strpos($templateClass, $currentClass);
if (null === $this->filename || ($this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer)) {
$template = $trace['object'];
$templateClass = \get_class($trace['object']);
}
}
}


if (null !== $template && null === $this->filename) {
$this->filename = $template->getTemplateName();
}


if (null !== $template && null === $this->sourcePath) {
$src = $template->getSourceContext();
$this->sourceCode = $src->getCode();
$this->sourcePath = $src->getPath();
}

if (null === $template || $this->lineno > -1) {
return;
}

$r = new \ReflectionObject($template);
$file = $r->getFileName();

$exceptions = [$e = $this];
while ($e instanceof self && $e = $e->getPrevious()) {
$exceptions[] = $e;
}

while ($e = array_pop($exceptions)) {
$traces = $e->getTrace();
array_unshift($traces, ['file' => $e->getFile(), 'line' => $e->getLine()]);

while ($trace = array_shift($traces)) {
if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
continue;
}

foreach ($template->getDebugInfo() as $codeLine => $templateLine) {
if ($codeLine <= $trace['line']) {

$this->lineno = $templateLine;

return;
}
}
}
}
}
}

class_alias('Twig\Error\Error', 'Twig_Error');
<?php











namespace Twig\Error;






class RuntimeError extends Error
{
}

class_alias('Twig\Error\RuntimeError', 'Twig_Error_Runtime');
<?php











namespace Twig\Error;






class SyntaxError extends Error
{






public function addSuggestions($name, array $items)
{
if (!$alternatives = self::computeAlternatives($name, $items)) {
return;
}

$this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', $alternatives)));
}






public static function computeAlternatives($name, $items)
{
$alternatives = [];
foreach ($items as $item) {
$lev = levenshtein($name, $item);
if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) {
$alternatives[$item] = $lev;
}
}
asort($alternatives);

return array_keys($alternatives);
}
}

class_alias('Twig\Error\SyntaxError', 'Twig_Error_Syntax');
<?php










namespace Twig;

use Twig\Cache\CacheInterface;
use Twig\Cache\FilesystemCache;
use Twig\Cache\NullCache;
use Twig\Error\Error;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
use Twig\Extension\CoreExtension;
use Twig\Extension\EscaperExtension;
use Twig\Extension\ExtensionInterface;
use Twig\Extension\GlobalsInterface;
use Twig\Extension\InitRuntimeInterface;
use Twig\Extension\OptimizerExtension;
use Twig\Extension\StagingExtension;
use Twig\Loader\ArrayLoader;
use Twig\Loader\ChainLoader;
use Twig\Loader\LoaderInterface;
use Twig\Loader\SourceContextLoaderInterface;
use Twig\Node\ModuleNode;
use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\RuntimeLoader\RuntimeLoaderInterface;
use Twig\TokenParser\TokenParserInterface;






class Environment
{
public const VERSION = '1.44.7';
public const VERSION_ID = 14407;
public const MAJOR_VERSION = 1;
public const MINOR_VERSION = 44;
public const RELEASE_VERSION = 7;
public const EXTRA_VERSION = '';

protected $charset;
protected $loader;
protected $debug;
protected $autoReload;
protected $cache;
protected $lexer;
protected $parser;
protected $compiler;
protected $baseTemplateClass;
protected $extensions;
protected $parsers;
protected $visitors;
protected $filters;
protected $tests;
protected $functions;
protected $globals;
protected $runtimeInitialized = false;
protected $extensionInitialized = false;
protected $loadedTemplates;
protected $strictVariables;
protected $unaryOperators;
protected $binaryOperators;
protected $templateClassPrefix = '__TwigTemplate_';
protected $functionCallbacks = [];
protected $filterCallbacks = [];
protected $staging;

private $originalCache;
private $bcWriteCacheFile = false;
private $bcGetCacheFilename = false;
private $lastModifiedExtension = 0;
private $extensionsByClass = [];
private $runtimeLoaders = [];
private $runtimes = [];
private $optionsHash;




































public function __construct(LoaderInterface $loader = null, $options = [])
{
if (null !== $loader) {
$this->setLoader($loader);
} else {
@trigger_error('Not passing a "Twig\Lodaer\LoaderInterface" as the first constructor argument of "Twig\Environment" is deprecated since version 1.21.', \E_USER_DEPRECATED);
}

$options = array_merge([
'debug' => false,
'charset' => 'UTF-8',
'base_template_class' => '\Twig\Template',
'strict_variables' => false,
'autoescape' => 'html',
'cache' => false,
'auto_reload' => null,
'optimizations' => -1,
], $options);

$this->debug = (bool) $options['debug'];
$this->charset = null === $options['charset'] ? null : strtoupper($options['charset']);
$this->baseTemplateClass = $options['base_template_class'];
$this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
$this->strictVariables = (bool) $options['strict_variables'];
$this->setCache($options['cache']);

$this->addExtension(new CoreExtension());
$this->addExtension(new EscaperExtension($options['autoescape']));
$this->addExtension(new OptimizerExtension($options['optimizations']));
$this->staging = new StagingExtension();


if (\is_string($this->originalCache)) {
$r = new \ReflectionMethod($this, 'writeCacheFile');
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
@trigger_error('The Twig\Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', \E_USER_DEPRECATED);

$this->bcWriteCacheFile = true;
}

$r = new \ReflectionMethod($this, 'getCacheFilename');
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
@trigger_error('The Twig\Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', \E_USER_DEPRECATED);

$this->bcGetCacheFilename = true;
}
}
}






public function getBaseTemplateClass()
{
return $this->baseTemplateClass;
}






public function setBaseTemplateClass($class)
{
$this->baseTemplateClass = $class;
$this->updateOptionsHash();
}




public function enableDebug()
{
$this->debug = true;
$this->updateOptionsHash();
}




public function disableDebug()
{
$this->debug = false;
$this->updateOptionsHash();
}






public function isDebug()
{
return $this->debug;
}




public function enableAutoReload()
{
$this->autoReload = true;
}




public function disableAutoReload()
{
$this->autoReload = false;
}






public function isAutoReload()
{
return $this->autoReload;
}




public function enableStrictVariables()
{
$this->strictVariables = true;
$this->updateOptionsHash();
}




public function disableStrictVariables()
{
$this->strictVariables = false;
$this->updateOptionsHash();
}






public function isStrictVariables()
{
return $this->strictVariables;
}










public function getCache($original = true)
{
return $original ? $this->originalCache : $this->cache;
}








public function setCache($cache)
{
if (\is_string($cache)) {
$this->originalCache = $cache;
$this->cache = new FilesystemCache($cache);
} elseif (false === $cache) {
$this->originalCache = $cache;
$this->cache = new NullCache();
} elseif (null === $cache) {
@trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', \E_USER_DEPRECATED);
$this->originalCache = false;
$this->cache = new NullCache();
} elseif ($cache instanceof CacheInterface) {
$this->originalCache = $this->cache = $cache;
} else {
throw new \LogicException('Cache can only be a string, false, or a \Twig\Cache\CacheInterface implementation.');
}
}










public function getCacheFilename($name)
{
@trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);

$key = $this->cache->generateKey($name, $this->getTemplateClass($name));

return !$key ? false : $key;
}


















public function getTemplateClass($name, $index = null)
{
$key = $this->getLoader()->getCacheKey($name).$this->optionsHash;

return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '___'.$index);
}








public function getTemplateClassPrefix()
{
@trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);

return $this->templateClassPrefix;
}













public function render($name, array $context = [])
{
return $this->load($name)->render($context);
}











public function display($name, array $context = [])
{
$this->load($name)->display($context);
}












public function load($name)
{
if ($name instanceof TemplateWrapper) {
return $name;
}

if ($name instanceof Template) {
return new TemplateWrapper($this, $name);
}

return new TemplateWrapper($this, $this->loadTemplate($name));
}


















public function loadTemplate($name, $index = null)
{
return $this->loadClass($this->getTemplateClass($name), $name, $index);
}




public function loadClass($cls, $name, $index = null)
{
$mainCls = $cls;
if (null !== $index) {
$cls .= '___'.$index;
}

if (isset($this->loadedTemplates[$cls])) {
return $this->loadedTemplates[$cls];
}

if (!class_exists($cls, false)) {
if ($this->bcGetCacheFilename) {
$key = $this->getCacheFilename($name);
} else {
$key = $this->cache->generateKey($name, $mainCls);
}

if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
$this->cache->load($key);
}

$source = null;
if (!class_exists($cls, false)) {
$loader = $this->getLoader();
if (!$loader instanceof SourceContextLoaderInterface) {
$source = new Source($loader->getSource($name), $name);
} else {
$source = $loader->getSourceContext($name);
}

$content = $this->compileSource($source);

if ($this->bcWriteCacheFile) {
$this->writeCacheFile($key, $content);
} else {
$this->cache->write($key, $content);
$this->cache->load($key);
}

if (!class_exists($mainCls, false)) {





eval('?>'.$content);
}
}

if (!class_exists($cls, false)) {
throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source);
}
}

if (!$this->runtimeInitialized) {
$this->initRuntime();
}

return $this->loadedTemplates[$cls] = new $cls($this);
}














public function createTemplate($template, $name = null)
{
$hash = hash('sha256', $template, false);
if (null !== $name) {
$name = sprintf('%s (string template %s)', $name, $hash);
} else {
$name = sprintf('__string_template__%s', $hash);
}

$loader = new ChainLoader([
new ArrayLoader([$name => $template]),
$current = $this->getLoader(),
]);

$this->setLoader($loader);
try {
$template = new TemplateWrapper($this, $this->loadTemplate($name));
} catch (\Exception $e) {
$this->setLoader($current);

throw $e;
} catch (\Throwable $e) {
$this->setLoader($current);

throw $e;
}
$this->setLoader($current);

return $template;
}













public function isTemplateFresh($name, $time)
{
if (0 === $this->lastModifiedExtension) {
foreach ($this->extensions as $extension) {
$r = new \ReflectionObject($extension);
if (file_exists($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModifiedExtension) {
$this->lastModifiedExtension = $extensionTime;
}
}
}

return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
}














public function resolveTemplate($names)
{
if (!\is_array($names)) {
$names = [$names];
}

foreach ($names as $name) {
if ($name instanceof Template) {
return $name;
}
if ($name instanceof TemplateWrapper) {
return $name;
}

try {
return $this->loadTemplate($name);
} catch (LoaderError $e) {
if (1 === \count($names)) {
throw $e;
}
}
}

throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names)));
}






public function clearTemplateCache()
{
@trigger_error(sprintf('The %s method is deprecated since version 1.18.3 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);

$this->loadedTemplates = [];
}






public function clearCacheFiles()
{
@trigger_error(sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);

if (\is_string($this->originalCache)) {
foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->originalCache), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
if ($file->isFile()) {
@unlink($file->getPathname());
}
}
}
}








public function getLexer()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);

if (null === $this->lexer) {
$this->lexer = new Lexer($this);
}

return $this->lexer;
}

public function setLexer(\Twig_LexerInterface $lexer)
{
$this->lexer = $lexer;
}











public function tokenize($source, $name = null)
{
if (!$source instanceof Source) {
@trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
$source = new Source($source, $name);
}

if (null === $this->lexer) {
$this->lexer = new Lexer($this);
}

return $this->lexer->tokenize($source);
}








public function getParser()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);

if (null === $this->parser) {
$this->parser = new Parser($this);
}

return $this->parser;
}

public function setParser(\Twig_ParserInterface $parser)
{
$this->parser = $parser;
}








public function parse(TokenStream $stream)
{
if (null === $this->parser) {
$this->parser = new Parser($this);
}

return $this->parser->parse($stream);
}








public function getCompiler()
{
@trigger_error(sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);

if (null === $this->compiler) {
$this->compiler = new Compiler($this);
}

return $this->compiler;
}

public function setCompiler(\Twig_CompilerInterface $compiler)
{
$this->compiler = $compiler;
}






public function compile(\Twig_NodeInterface $node)
{
if (null === $this->compiler) {
$this->compiler = new Compiler($this);
}

return $this->compiler->compile($node)->getSource();
}











public function compileSource($source, $name = null)
{
if (!$source instanceof Source) {
@trigger_error(sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
$source = new Source($source, $name);
}

try {
return $this->compile($this->parse($this->tokenize($source)));
} catch (Error $e) {
$e->setSourceContext($source);
throw $e;
} catch (\Exception $e) {
throw new SyntaxError(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
}
}

public function setLoader(LoaderInterface $loader)
{
if (!$loader instanceof SourceContextLoaderInterface && 0 !== strpos(\get_class($loader), 'Mock_')) {
@trigger_error(sprintf('Twig loader "%s" should implement Twig\Loader\SourceContextLoaderInterface since version 1.27.', \get_class($loader)), \E_USER_DEPRECATED);
}

$this->loader = $loader;
}






public function getLoader()
{
if (null === $this->loader) {
throw new \LogicException('You must set a loader first.');
}

return $this->loader;
}






public function setCharset($charset)
{
$this->charset = strtoupper($charset);
}






public function getCharset()
{
return $this->charset;
}






public function initRuntime()
{
$this->runtimeInitialized = true;

foreach ($this->getExtensions() as $name => $extension) {
if (!$extension instanceof InitRuntimeInterface) {
$m = new \ReflectionMethod($extension, 'initRuntime');

$parentClass = $m->getDeclaringClass()->getName();
if ('Twig_Extension' !== $parentClass && 'Twig\Extension\AbstractExtension' !== $parentClass) {
@trigger_error(sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the \Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig\Extension\InitRuntimeInterface if needed (not recommended).', $name), \E_USER_DEPRECATED);
}
}

$extension->initRuntime($this);
}
}








public function hasExtension($class)
{
$class = ltrim($class, '\\');
if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {

$class = new \ReflectionClass($class);
$class = $class->name;
}

if (isset($this->extensions[$class])) {
if ($class !== \get_class($this->extensions[$class])) {
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), \E_USER_DEPRECATED);
}

return true;
}

return isset($this->extensionsByClass[$class]);
}




public function addRuntimeLoader(RuntimeLoaderInterface $loader)
{
$this->runtimeLoaders[] = $loader;
}








public function getExtension($class)
{
$class = ltrim($class, '\\');
if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {

$class = new \ReflectionClass($class);
$class = $class->name;
}

if (isset($this->extensions[$class])) {
if ($class !== \get_class($this->extensions[$class])) {
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), \E_USER_DEPRECATED);
}

return $this->extensions[$class];
}

if (!isset($this->extensionsByClass[$class])) {
throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class));
}

return $this->extensionsByClass[$class];
}










public function getRuntime($class)
{
if (isset($this->runtimes[$class])) {
return $this->runtimes[$class];
}

foreach ($this->runtimeLoaders as $loader) {
if (null !== $runtime = $loader->load($class)) {
return $this->runtimes[$class] = $runtime;
}
}

throw new RuntimeError(sprintf('Unable to load the "%s" runtime.', $class));
}

public function addExtension(ExtensionInterface $extension)
{
if ($this->extensionInitialized) {
throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
}

$class = \get_class($extension);
if ($class !== $extension->getName()) {
if (isset($this->extensions[$extension->getName()])) {
unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
@trigger_error(sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), \E_USER_DEPRECATED);
}
}

$this->lastModifiedExtension = 0;
$this->extensionsByClass[$class] = $extension;
$this->extensions[$extension->getName()] = $extension;
$this->updateOptionsHash();
}










public function removeExtension($name)
{
@trigger_error(sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);

if ($this->extensionInitialized) {
throw new \LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
}

$class = ltrim($name, '\\');
if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {

$class = new \ReflectionClass($class);
$class = $class->name;
}

if (isset($this->extensions[$class])) {
if ($class !== \get_class($this->extensions[$class])) {
@trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), \E_USER_DEPRECATED);
}

unset($this->extensions[$class]);
}

unset($this->extensions[$class]);
$this->updateOptionsHash();
}






public function setExtensions(array $extensions)
{
foreach ($extensions as $extension) {
$this->addExtension($extension);
}
}






public function getExtensions()
{
return $this->extensions;
}

public function addTokenParser(TokenParserInterface $parser)
{
if ($this->extensionInitialized) {
throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
}

$this->staging->addTokenParser($parser);
}








public function getTokenParsers()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->parsers;
}










public function getTags()
{
$tags = [];
foreach ($this->getTokenParsers()->getParsers() as $parser) {
if ($parser instanceof TokenParserInterface) {
$tags[$parser->getTag()] = $parser;
}
}

return $tags;
}

public function addNodeVisitor(NodeVisitorInterface $visitor)
{
if ($this->extensionInitialized) {
throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
}

$this->staging->addNodeVisitor($visitor);
}








public function getNodeVisitors()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->visitors;
}







public function addFilter($name, $filter = null)
{
if (!$name instanceof TwigFilter && !($filter instanceof TwigFilter || $filter instanceof \Twig_FilterInterface)) {
throw new \LogicException('A filter must be an instance of \Twig_FilterInterface or \Twig_SimpleFilter.');
}

if ($name instanceof TwigFilter) {
$filter = $name;
$name = $filter->getName();
} else {
@trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
}

if ($this->extensionInitialized) {
throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
}

$this->staging->addFilter($name, $filter);
}













public function getFilter($name)
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

if (isset($this->filters[$name])) {
return $this->filters[$name];
}

foreach ($this->filters as $pattern => $filter) {
$pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);

if ($count) {
if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
array_shift($matches);
$filter->setArguments($matches);

return $filter;
}
}
}

foreach ($this->filterCallbacks as $callback) {
if (false !== $filter = \call_user_func($callback, $name)) {
return $filter;
}
}

return false;
}

public function registerUndefinedFilterCallback($callable)
{
$this->filterCallbacks[] = $callable;
}












public function getFilters()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->filters;
}







public function addTest($name, $test = null)
{
if (!$name instanceof TwigTest && !($test instanceof TwigTest || $test instanceof \Twig_TestInterface)) {
throw new \LogicException('A test must be an instance of \Twig_TestInterface or \Twig_SimpleTest.');
}

if ($name instanceof TwigTest) {
$test = $name;
$name = $test->getName();
} else {
@trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
}

if ($this->extensionInitialized) {
throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
}

$this->staging->addTest($name, $test);
}








public function getTests()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->tests;
}










public function getTest($name)
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

if (isset($this->tests[$name])) {
return $this->tests[$name];
}

foreach ($this->tests as $pattern => $test) {
$pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);

if ($count) {
if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
array_shift($matches);
$test->setArguments($matches);

return $test;
}
}
}

return false;
}







public function addFunction($name, $function = null)
{
if (!$name instanceof TwigFunction && !($function instanceof TwigFunction || $function instanceof \Twig_FunctionInterface)) {
throw new \LogicException('A function must be an instance of \Twig_FunctionInterface or \Twig_SimpleFunction.');
}

if ($name instanceof TwigFunction) {
$function = $name;
$name = $function->getName();
} else {
@trigger_error(sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
}

if ($this->extensionInitialized) {
throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
}

$this->staging->addFunction($name, $function);
}













public function getFunction($name)
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

if (isset($this->functions[$name])) {
return $this->functions[$name];
}

foreach ($this->functions as $pattern => $function) {
$pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count);

if ($count) {
if (preg_match('#^'.$pattern.'$#', $name, $matches)) {
array_shift($matches);
$function->setArguments($matches);

return $function;
}
}
}

foreach ($this->functionCallbacks as $callback) {
if (false !== $function = \call_user_func($callback, $name)) {
return $function;
}
}

return false;
}

public function registerUndefinedFunctionCallback($callable)
{
$this->functionCallbacks[] = $callable;
}












public function getFunctions()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->functions;
}










public function addGlobal($name, $value)
{
if ($this->extensionInitialized || $this->runtimeInitialized) {
if (null === $this->globals) {
$this->globals = $this->initGlobals();
}

if (!\array_key_exists($name, $this->globals)) {

@trigger_error(sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), \E_USER_DEPRECATED);

}
}

if ($this->extensionInitialized || $this->runtimeInitialized) {

$this->globals[$name] = $value;
} else {
$this->staging->addGlobal($name, $value);
}
}








public function getGlobals()
{
if (!$this->runtimeInitialized && !$this->extensionInitialized) {
return $this->initGlobals();
}

if (null === $this->globals) {
$this->globals = $this->initGlobals();
}

return $this->globals;
}








public function mergeGlobals(array $context)
{


foreach ($this->getGlobals() as $key => $value) {
if (!\array_key_exists($key, $context)) {
$context[$key] = $value;
}
}

return $context;
}








public function getUnaryOperators()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->unaryOperators;
}








public function getBinaryOperators()
{
if (!$this->extensionInitialized) {
$this->initExtensions();
}

return $this->binaryOperators;
}




public function computeAlternatives($name, $items)
{
@trigger_error(sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);

return SyntaxError::computeAlternatives($name, $items);
}




protected function initGlobals()
{
$globals = [];
foreach ($this->extensions as $name => $extension) {
if (!$extension instanceof GlobalsInterface) {
$m = new \ReflectionMethod($extension, 'getGlobals');

$parentClass = $m->getDeclaringClass()->getName();
if ('Twig_Extension' !== $parentClass && 'Twig\Extension\AbstractExtension' !== $parentClass) {
@trigger_error(sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig\Extension\GlobalsInterface is deprecated since version 1.23.', $name), \E_USER_DEPRECATED);
}
}

$extGlob = $extension->getGlobals();
if (!\is_array($extGlob)) {
throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
}

$globals[] = $extGlob;
}

$globals[] = $this->staging->getGlobals();

return \call_user_func_array('array_merge', $globals);
}




protected function initExtensions()
{
if ($this->extensionInitialized) {
return;
}

$this->parsers = new \Twig_TokenParserBroker([], [], false);
$this->filters = [];
$this->functions = [];
$this->tests = [];
$this->visitors = [];
$this->unaryOperators = [];
$this->binaryOperators = [];

foreach ($this->extensions as $extension) {
$this->initExtension($extension);
}
$this->initExtension($this->staging);

$this->extensionInitialized = true;
}




protected function initExtension(ExtensionInterface $extension)
{

foreach ($extension->getFilters() as $name => $filter) {
if ($filter instanceof TwigFilter) {
$name = $filter->getName();
} else {
@trigger_error(sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use \Twig_SimpleFilter instead.', \get_class($filter), $name), \E_USER_DEPRECATED);
}

$this->filters[$name] = $filter;
}


foreach ($extension->getFunctions() as $name => $function) {
if ($function instanceof TwigFunction) {
$name = $function->getName();
} else {
@trigger_error(sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use \Twig_SimpleFunction instead.', \get_class($function), $name), \E_USER_DEPRECATED);
}

$this->functions[$name] = $function;
}


foreach ($extension->getTests() as $name => $test) {
if ($test instanceof TwigTest) {
$name = $test->getName();
} else {
@trigger_error(sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use \Twig_SimpleTest instead.', \get_class($test), $name), \E_USER_DEPRECATED);
}

$this->tests[$name] = $test;
}


foreach ($extension->getTokenParsers() as $parser) {
if ($parser instanceof TokenParserInterface) {
$this->parsers->addTokenParser($parser);
} elseif ($parser instanceof \Twig_TokenParserBrokerInterface) {
@trigger_error('Registering a \Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', \E_USER_DEPRECATED);

$this->parsers->addTokenParserBroker($parser);
} else {
throw new \LogicException('getTokenParsers() must return an array of \Twig_TokenParserInterface or \Twig_TokenParserBrokerInterface instances.');
}
}


foreach ($extension->getNodeVisitors() as $visitor) {
$this->visitors[] = $visitor;
}


if ($operators = $extension->getOperators()) {
if (!\is_array($operators)) {
throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators).(\is_resource($operators) ? '' : '#'.$operators)));
}

if (2 !== \count($operators)) {
throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
}

$this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
$this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
}
}




protected function writeCacheFile($file, $content)
{
$this->cache->write($file, $content);
}

private function updateOptionsHash()
{
$hashParts = array_merge(
array_keys($this->extensions),
[
(int) \function_exists('twig_template_get_attributes'),
\PHP_MAJOR_VERSION,
\PHP_MINOR_VERSION,
self::VERSION,
(int) $this->debug,
$this->baseTemplateClass,
(int) $this->strictVariables,
]
);
$this->optionsHash = implode(':', $hashParts);
}
}

class_alias('Twig\Environment', 'Twig_Environment');
<?php











namespace Twig;

use Twig\Error\Error;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;












abstract class Template implements \Twig_TemplateInterface
{



protected static $cache = [];

protected $parent;
protected $parents = [];
protected $env;
protected $blocks = [];
protected $traits = [];
protected $sandbox;

public function __construct(Environment $env)
{
$this->env = $env;
}




public function __toString()
{
return $this->getTemplateName();
}






abstract public function getTemplateName();






public function getDebugInfo()
{
return [];
}








public function getSource()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', \E_USER_DEPRECATED);

return '';
}






public function getSourceContext()
{
return new Source('', $this->getTemplateName());
}




public function getEnvironment()
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 1.20 and will be removed in 2.0.', \E_USER_DEPRECATED);

return $this->env;
}











public function getParent(array $context)
{
if (null !== $this->parent) {
return $this->parent;
}

try {
$parent = $this->doGetParent($context);

if (false === $parent) {
return false;
}

if ($parent instanceof self || $parent instanceof TemplateWrapper) {
return $this->parents[$parent->getSourceContext()->getName()] = $parent;
}

if (!isset($this->parents[$parent])) {
$this->parents[$parent] = $this->loadTemplate($parent);
}
} catch (LoaderError $e) {
$e->setSourceContext(null);
$e->guess();

throw $e;
}

return $this->parents[$parent];
}

protected function doGetParent(array $context)
{
return false;
}

public function isTraitable()
{
return true;
}











public function displayParentBlock($name, array $context, array $blocks = [])
{
$name = (string) $name;

if (isset($this->traits[$name])) {
$this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
} elseif (false !== $parent = $this->getParent($context)) {
$parent->displayBlock($name, $context, $blocks, false);
} else {
throw new RuntimeError(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
}
}












public function displayBlock($name, array $context, array $blocks = [], $useBlocks = true)
{
$name = (string) $name;

if ($useBlocks && isset($blocks[$name])) {
$template = $blocks[$name][0];
$block = $blocks[$name][1];
} elseif (isset($this->blocks[$name])) {
$template = $this->blocks[$name][0];
$block = $this->blocks[$name][1];
} else {
$template = null;
$block = null;
}


if (null !== $template && !$template instanceof self) {
throw new \LogicException('A block must be a method on a \Twig\Template instance.');
}

if (null !== $template) {
try {
$template->$block($context, $blocks);
} catch (Error $e) {
if (!$e->getSourceContext()) {
$e->setSourceContext($template->getSourceContext());
}



if (-1 === $e->getTemplateLine()) {
$e->guess();
}

throw $e;
} catch (\Exception $e) {
$e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
$e->guess();

throw $e;
}
} elseif (false !== $parent = $this->getParent($context)) {
$parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
} else {
@trigger_error(sprintf('Silent display of undefined block "%s" in template "%s" is deprecated since version 1.29 and will throw an exception in 2.0. Use the "block(\'%s\') is defined" expression to test for block existence.', $name, $this->getTemplateName(), $name), \E_USER_DEPRECATED);
}
}













public function renderParentBlock($name, array $context, array $blocks = [])
{
if ($this->env->isDebug()) {
ob_start();
} else {
ob_start(function () { return ''; });
}
$this->displayParentBlock($name, $context, $blocks);

return ob_get_clean();
}














public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true)
{
if ($this->env->isDebug()) {
ob_start();
} else {
ob_start(function () { return ''; });
}
$this->displayBlock($name, $context, $blocks, $useBlocks);

return ob_get_clean();
}













public function hasBlock($name, array $context = null, array $blocks = [])
{
if (null === $context) {
@trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', \E_USER_DEPRECATED);

return isset($this->blocks[(string) $name]);
}

if (isset($blocks[$name])) {
return $blocks[$name][0] instanceof self;
}

if (isset($this->blocks[$name])) {
return true;
}

if (false !== $parent = $this->getParent($context)) {
return $parent->hasBlock($name, $context);
}

return false;
}












public function getBlockNames(array $context = null, array $blocks = [])
{
if (null === $context) {
@trigger_error('The '.__METHOD__.' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', \E_USER_DEPRECATED);

return array_keys($this->blocks);
}

$names = array_merge(array_keys($blocks), array_keys($this->blocks));

if (false !== $parent = $this->getParent($context)) {
$names = array_merge($names, $parent->getBlockNames($context));
}

return array_unique($names);
}




protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
{
try {
if (\is_array($template)) {
return $this->env->resolveTemplate($template);
}

if ($template instanceof self || $template instanceof TemplateWrapper) {
return $template;
}

if ($template === $this->getTemplateName()) {
$class = static::class;
if (false !== $pos = strrpos($class, '___', -1)) {
$class = substr($class, 0, $pos);
}

return $this->env->loadClass($class, $template, $index);
}

return $this->env->loadTemplate($template, $index);
} catch (Error $e) {
if (!$e->getSourceContext()) {
$e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext());
}

if ($e->getTemplateLine() > 0) {
throw $e;
}

if (!$line) {
$e->guess();
} else {
$e->setTemplateLine($line);
}

throw $e;
}
}






public function unwrap()
{
return $this;
}









public function getBlocks()
{
return $this->blocks;
}

public function display(array $context, array $blocks = [])
{
$this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
}

public function render(array $context)
{
$level = ob_get_level();
if ($this->env->isDebug()) {
ob_start();
} else {
ob_start(function () { return ''; });
}
try {
$this->display($context);
} catch (\Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}

throw $e;
} catch (\Throwable $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}

throw $e;
}

return ob_get_clean();
}

protected function displayWithErrorHandling(array $context, array $blocks = [])
{
try {
$this->doDisplay($context, $blocks);
} catch (Error $e) {
if (!$e->getSourceContext()) {
$e->setSourceContext($this->getSourceContext());
}



if (-1 === $e->getTemplateLine()) {
$e->guess();
}

throw $e;
} catch (\Exception $e) {
$e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
$e->guess();

throw $e;
}
}







abstract protected function doDisplay(array $context, array $blocks = []);






















final protected function getContext($context, $item, $ignoreStrictCheck = false)
{
if (!\array_key_exists($item, $context)) {
if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
return;
}

throw new RuntimeError(sprintf('Variable "%s" does not exist.', $item), -1, $this->getSourceContext());
}

return $context[$item];
}

















protected function getAttribute($object, $item, array $arguments = [], $type = self::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
{

if (self::METHOD_CALL !== $type) {
$arrayItem = \is_bool($item) || \is_float($item) ? (int) $item : $item;

if (((\is_array($object) || $object instanceof \ArrayObject) && (isset($object[$arrayItem]) || \array_key_exists($arrayItem, (array) $object)))
|| ($object instanceof \ArrayAccess && isset($object[$arrayItem]))
) {
if ($isDefinedTest) {
return true;
}

return $object[$arrayItem];
}

if (self::ARRAY_CALL === $type || !\is_object($object)) {
if ($isDefinedTest) {
return false;
}

if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
return;
}

if ($object instanceof \ArrayAccess) {
$message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, \get_class($object));
} elseif (\is_object($object)) {
$message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, \get_class($object));
} elseif (\is_array($object)) {
if (empty($object)) {
$message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem);
} else {
$message = sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object)));
}
} elseif (self::ARRAY_CALL === $type) {
if (null === $object) {
$message = sprintf('Impossible to access a key ("%s") on a null variable.', $item);
} else {
$message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
}
} elseif (null === $object) {
$message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
} else {
$message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
}

throw new RuntimeError($message, -1, $this->getSourceContext());
}
}

if (!\is_object($object)) {
if ($isDefinedTest) {
return false;
}

if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
return;
}

if (null === $object) {
$message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
} elseif (\is_array($object)) {
$message = sprintf('Impossible to invoke a method ("%s") on an array.', $item);
} else {
$message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
}

throw new RuntimeError($message, -1, $this->getSourceContext());
}


if (self::METHOD_CALL !== $type && !$object instanceof self) { 
if (isset($object->$item) || \array_key_exists((string) $item, (array) $object)) {
if ($isDefinedTest) {
return true;
}

if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
$this->env->getExtension('\Twig\Extension\SandboxExtension')->checkPropertyAllowed($object, $item);
}

return $object->$item;
}
}

$class = \get_class($object);


if (!isset(self::$cache[$class])) {

if ($object instanceof self) {
$ref = new \ReflectionClass($class);
$methods = [];

foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $refMethod) {

if ('getenvironment' !== strtr($refMethod->name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')) {
$methods[] = $refMethod->name;
}
}
} else {
$methods = get_class_methods($object);
}

sort($methods);

$cache = [];

foreach ($methods as $method) {
$cache[$method] = $method;
$cache[$lcName = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')] = $method;

if ('g' === $lcName[0] && 0 === strpos($lcName, 'get')) {
$name = substr($method, 3);
$lcName = substr($lcName, 3);
} elseif ('i' === $lcName[0] && 0 === strpos($lcName, 'is')) {
$name = substr($method, 2);
$lcName = substr($lcName, 2);
} else {
continue;
}


if ($name) {
if (!isset($cache[$name])) {
$cache[$name] = $method;
}
if (!isset($cache[$lcName])) {
$cache[$lcName] = $method;
}
}
}
self::$cache[$class] = $cache;
}

$call = false;
if (isset(self::$cache[$class][$item])) {
$method = self::$cache[$class][$item];
} elseif (isset(self::$cache[$class][$lcItem = strtr($item, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')])) {
$method = self::$cache[$class][$lcItem];
} elseif (isset(self::$cache[$class]['__call'])) {
$method = $item;
$call = true;
} else {
if ($isDefinedTest) {
return false;
}

if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
return;
}

throw new RuntimeError(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getSourceContext());
}

if ($isDefinedTest) {
return true;
}

if ($this->env->hasExtension('\Twig\Extension\SandboxExtension')) {
$this->env->getExtension('\Twig\Extension\SandboxExtension')->checkMethodAllowed($object, $method);
}



try {
if (!$arguments) {
$ret = $object->$method();
} else {
$ret = \call_user_func_array([$object, $method], $arguments);
}
} catch (\BadMethodCallException $e) {
if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
return;
}
throw $e;
}


if ($object instanceof \Twig_TemplateInterface) {
$self = $object->getTemplateName() === $this->getTemplateName();
$message = sprintf('Calling "%s" on template "%s" from template "%s" is deprecated since version 1.28 and won\'t be supported anymore in 2.0.', $item, $object->getTemplateName(), $this->getTemplateName());
if ('renderBlock' === $method || 'displayBlock' === $method) {
$message .= sprintf(' Use block("%s"%s) instead).', $arguments[0], $self ? '' : ', template');
} elseif ('hasBlock' === $method) {
$message .= sprintf(' Use "block("%s"%s) is defined" instead).', $arguments[0], $self ? '' : ', template');
} elseif ('render' === $method || 'display' === $method) {
$message .= sprintf(' Use include("%s") instead).', $object->getTemplateName());
}
@trigger_error($message, \E_USER_DEPRECATED);

return '' === $ret ? '' : new Markup($ret, $this->env->getCharset());
}

return $ret;
}
}

class_alias('Twig\Template', 'Twig_Template');
<?php










namespace Twig;












class FileExtensionEscapingStrategy
{







public static function guess($name)
{
if (\in_array(substr($name, -1), ['/', '\\'])) {
return 'html'; 
}

if ('.twig' === substr($name, -5)) {
$name = substr($name, 0, -5);
}

$extension = pathinfo($name, \PATHINFO_EXTENSION);

switch ($extension) {
case 'js':
return 'js';

case 'css':
return 'css';

case 'txt':
return false;

default:
return 'html';
}
}
}

class_alias('Twig\FileExtensionEscapingStrategy', 'Twig_FileExtensionEscapingStrategy');
<?php










namespace Twig\Profiler\Node;

use Twig\Compiler;
use Twig\Node\Node;






class EnterProfileNode extends Node
{
public function __construct($extensionName, $type, $name, $varName)
{
parent::__construct([], ['extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName]);
}

public function compile(Compiler $compiler)
{
$compiler
->write(sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name')))
->repr($this->getAttribute('extension_name'))
->raw(");\n")
->write(sprintf('$%s->enter($%s = new \Twig\Profiler\Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof'))
->repr($this->getAttribute('type'))
->raw(', ')
->repr($this->getAttribute('name'))
->raw("));\n\n")
;
}
}

class_alias('Twig\Profiler\Node\EnterProfileNode', 'Twig_Profiler_Node_EnterProfile');
<?php










namespace Twig\Profiler\Node;

use Twig\Compiler;
use Twig\Node\Node;






class LeaveProfileNode extends Node
{
public function __construct($varName)
{
parent::__construct([], ['var_name' => $varName]);
}

public function compile(Compiler $compiler)
{
$compiler
->write("\n")
->write(sprintf("\$%s->leave(\$%s);\n\n", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof'))
;
}
}

class_alias('Twig\Profiler\Node\LeaveProfileNode', 'Twig_Profiler_Node_LeaveProfile');
<?php










namespace Twig\Profiler;






class Profile implements \IteratorAggregate, \Serializable
{
public const ROOT = 'ROOT';
public const BLOCK = 'block';
public const TEMPLATE = 'template';
public const MACRO = 'macro';

private $template;
private $name;
private $type;
private $starts = [];
private $ends = [];
private $profiles = [];

public function __construct($template = 'main', $type = self::ROOT, $name = 'main')
{
$this->template = $template;
$this->type = $type;
$this->name = 0 === strpos($name, '__internal_') ? 'INTERNAL' : $name;
$this->enter();
}

public function getTemplate()
{
return $this->template;
}

public function getType()
{
return $this->type;
}

public function getName()
{
return $this->name;
}

public function isRoot()
{
return self::ROOT === $this->type;
}

public function isTemplate()
{
return self::TEMPLATE === $this->type;
}

public function isBlock()
{
return self::BLOCK === $this->type;
}

public function isMacro()
{
return self::MACRO === $this->type;
}

public function getProfiles()
{
return $this->profiles;
}

public function addProfile(self $profile)
{
$this->profiles[] = $profile;
}






public function getDuration()
{
if ($this->isRoot() && $this->profiles) {

$duration = 0;
foreach ($this->profiles as $profile) {
$duration += $profile->getDuration();
}

return $duration;
}

return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0;
}






public function getMemoryUsage()
{
return isset($this->ends['mu']) && isset($this->starts['mu']) ? $this->ends['mu'] - $this->starts['mu'] : 0;
}






public function getPeakMemoryUsage()
{
return isset($this->ends['pmu']) && isset($this->starts['pmu']) ? $this->ends['pmu'] - $this->starts['pmu'] : 0;
}




public function enter()
{
$this->starts = [
'wt' => microtime(true),
'mu' => memory_get_usage(),
'pmu' => memory_get_peak_usage(),
];
}




public function leave()
{
$this->ends = [
'wt' => microtime(true),
'mu' => memory_get_usage(),
'pmu' => memory_get_peak_usage(),
];
}

public function reset()
{
$this->starts = $this->ends = $this->profiles = [];
$this->enter();
}

public function getIterator(): \Traversable
{
return new \ArrayIterator($this->profiles);
}

public function serialize(): string
{
return serialize($this->__serialize());
}

public function unserialize($data): void
{
$this->__unserialize(unserialize($data));
}




public function __serialize(): array
{
return [$this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles];
}




public function __unserialize(array $data): void
{
list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = $data;
}
}

class_alias('Twig\Profiler\Profile', 'Twig_Profiler_Profile');
<?php










namespace Twig\Profiler\NodeVisitor;

use Twig\Environment;
use Twig\Node\BlockNode;
use Twig\Node\BodyNode;
use Twig\Node\MacroNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\NodeVisitor\AbstractNodeVisitor;
use Twig\Profiler\Node\EnterProfileNode;
use Twig\Profiler\Node\LeaveProfileNode;
use Twig\Profiler\Profile;






class ProfilerNodeVisitor extends AbstractNodeVisitor
{
private $extensionName;

public function __construct($extensionName)
{
$this->extensionName = $extensionName;
}

protected function doEnterNode(Node $node, Environment $env)
{
return $node;
}

protected function doLeaveNode(Node $node, Environment $env)
{
if ($node instanceof ModuleNode) {
$varName = $this->getVarName();
$node->setNode('display_start', new Node([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')]));
$node->setNode('display_end', new Node([new LeaveProfileNode($varName), $node->getNode('display_end')]));
} elseif ($node instanceof BlockNode) {
$varName = $this->getVarName();
$node->setNode('body', new BodyNode([
new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $varName),
$node->getNode('body'),
new LeaveProfileNode($varName),
]));
} elseif ($node instanceof MacroNode) {
$varName = $this->getVarName();
$node->setNode('body', new BodyNode([
new EnterProfileNode($this->extensionName, Profile::MACRO, $node->getAttribute('name'), $varName),
$node->getNode('body'),
new LeaveProfileNode($varName),
]));
}

return $node;
}

private function getVarName()
{
return sprintf('__internal_%s', hash('sha256', $this->extensionName));
}

public function getPriority()
{
return 0;
}
}

class_alias('Twig\Profiler\NodeVisitor\ProfilerNodeVisitor', 'Twig_Profiler_NodeVisitor_Profiler');
<?php










namespace Twig\Profiler\Dumper;

use Twig\Profiler\Profile;






class HtmlDumper extends BaseDumper
{
private static $colors = [
'block' => '#dfd',
'macro' => '#ddf',
'template' => '#ffd',
'big' => '#d44',
];

public function dump(Profile $profile)
{
return '<pre>'.parent::dump($profile).'</pre>';
}

protected function formatTemplate(Profile $profile, $prefix)
{
return sprintf('%s└ <span style="background-color: %s">%s</span>', $prefix, self::$colors['template'], $profile->getTemplate());
}

protected function formatNonTemplate(Profile $profile, $prefix)
{
return sprintf('%s└ %s::%s(<span style="background-color: %s">%s</span>)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName());
}

protected function formatTime(Profile $profile, $percent)
{
return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
}
}

class_alias('Twig\Profiler\Dumper\HtmlDumper', 'Twig_Profiler_Dumper_Html');
<?php










namespace Twig\Profiler\Dumper;

use Twig\Profiler\Profile;




abstract class BaseDumper
{
private $root;

public function dump(Profile $profile)
{
return $this->dumpProfile($profile);
}

abstract protected function formatTemplate(Profile $profile, $prefix);

abstract protected function formatNonTemplate(Profile $profile, $prefix);

abstract protected function formatTime(Profile $profile, $percent);

private function dumpProfile(Profile $profile, $prefix = '', $sibling = false)
{
if ($profile->isRoot()) {
$this->root = $profile->getDuration();
$start = $profile->getName();
} else {
if ($profile->isTemplate()) {
$start = $this->formatTemplate($profile, $prefix);
} else {
$start = $this->formatNonTemplate($profile, $prefix);
}
$prefix .= $sibling ? '│ ' : '  ';
}

$percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;

if ($profile->getDuration() * 1000 < 1) {
$str = $start."\n";
} else {
$str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
}

$nCount = \count($profile->getProfiles());
foreach ($profile as $i => $p) {
$str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
}

return $str;
}
}

class_alias('Twig\Profiler\Dumper\BaseDumper', 'Twig_Profiler_Dumper_Base');
<?php










namespace Twig\Profiler\Dumper;

use Twig\Profiler\Profile;






class TextDumper extends BaseDumper
{
protected function formatTemplate(Profile $profile, $prefix)
{
return sprintf('%s└ %s', $prefix, $profile->getTemplate());
}

protected function formatNonTemplate(Profile $profile, $prefix)
{
return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName());
}

protected function formatTime(Profile $profile, $percent)
{
return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
}
}

class_alias('Twig\Profiler\Dumper\TextDumper', 'Twig_Profiler_Dumper_Text');
<?php










namespace Twig\Profiler\Dumper;

use Twig\Profiler\Profile;






class BlackfireDumper
{
public function dump(Profile $profile)
{
$data = [];
$this->dumpProfile('main()', $profile, $data);
$this->dumpChildren('main()', $profile, $data);

$start = sprintf('%f', microtime(true));
$str = <<<EOF
file-format: BlackfireProbe
cost-dimensions: wt mu pmu
request-start: {$start}


EOF;

foreach ($data as $name => $values) {
$str .= "{$name}//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n";
}

return $str;
}

private function dumpChildren($parent, Profile $profile, &$data)
{
foreach ($profile as $p) {
if ($p->isTemplate()) {
$name = $p->getTemplate();
} else {
$name = sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName());
}
$this->dumpProfile(sprintf('%s==>%s', $parent, $name), $p, $data);
$this->dumpChildren($name, $p, $data);
}
}

private function dumpProfile($edge, Profile $profile, &$data)
{
if (isset($data[$edge])) {
++$data[$edge]['ct'];
$data[$edge]['wt'] += floor($profile->getDuration() * 1000000);
$data[$edge]['mu'] += $profile->getMemoryUsage();
$data[$edge]['pmu'] += $profile->getPeakMemoryUsage();
} else {
$data[$edge] = [
'ct' => 1,
'wt' => floor($profile->getDuration() * 1000000),
'mu' => $profile->getMemoryUsage(),
'pmu' => $profile->getPeakMemoryUsage(),
];
}
}
}

class_alias('Twig\Profiler\Dumper\BlackfireDumper', 'Twig_Profiler_Dumper_Blackfire');
<?php










namespace Twig;

use Twig\Node\Node;








class TwigFilter
{
protected $name;
protected $callable;
protected $options;
protected $arguments = [];

public function __construct($name, $callable, array $options = [])
{
$this->name = $name;
$this->callable = $callable;
$this->options = array_merge([
'needs_environment' => false,
'needs_context' => false,
'is_variadic' => false,
'is_safe' => null,
'is_safe_callback' => null,
'pre_escape' => null,
'preserves_safety' => null,
'node_class' => '\Twig\Node\Expression\FilterExpression',
'deprecated' => false,
'alternative' => null,
], $options);
}

public function getName()
{
return $this->name;
}

public function getCallable()
{
return $this->callable;
}

public function getNodeClass()
{
return $this->options['node_class'];
}

public function setArguments($arguments)
{
$this->arguments = $arguments;
}

public function getArguments()
{
return $this->arguments;
}

public function needsEnvironment()
{
return $this->options['needs_environment'];
}

public function needsContext()
{
return $this->options['needs_context'];
}

public function getSafe(Node $filterArgs)
{
if (null !== $this->options['is_safe']) {
return $this->options['is_safe'];
}

if (null !== $this->options['is_safe_callback']) {
return \call_user_func($this->options['is_safe_callback'], $filterArgs);
}
}

public function getPreservesSafety()
{
return $this->options['preserves_safety'];
}

public function getPreEscape()
{
return $this->options['pre_escape'];
}

public function isVariadic()
{
return $this->options['is_variadic'];
}

public function isDeprecated()
{
return (bool) $this->options['deprecated'];
}

public function getDeprecatedVersion()
{
return $this->options['deprecated'];
}

public function getAlternative()
{
return $this->options['alternative'];
}
}

class_alias('Twig\TwigFilter', 'Twig_SimpleFilter');


class_exists('Twig\Node\Node');
<?php











namespace Twig;

use Twig\Error\SyntaxError;
use Twig\Node\Expression\ArrayExpression;
use Twig\Node\Expression\ArrowFunctionExpression;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\Expression\Binary\ConcatBinary;
use Twig\Node\Expression\BlockReferenceExpression;
use Twig\Node\Expression\ConditionalExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\MethodCallExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Expression\ParentExpression;
use Twig\Node\Expression\Unary\NegUnary;
use Twig\Node\Expression\Unary\NotUnary;
use Twig\Node\Expression\Unary\PosUnary;
use Twig\Node\Node;













class ExpressionParser
{
public const OPERATOR_LEFT = 1;
public const OPERATOR_RIGHT = 2;

protected $parser;
protected $unaryOperators;
protected $binaryOperators;

private $env;

public function __construct(Parser $parser, $env = null)
{
$this->parser = $parser;

if ($env instanceof Environment) {
$this->env = $env;
$this->unaryOperators = $env->getUnaryOperators();
$this->binaryOperators = $env->getBinaryOperators();
} else {
@trigger_error('Passing the operators as constructor arguments to '.__METHOD__.' is deprecated since version 1.27. Pass the environment instead.', \E_USER_DEPRECATED);

$this->env = $parser->getEnvironment();
$this->unaryOperators = func_get_arg(1);
$this->binaryOperators = func_get_arg(2);
}
}

public function parseExpression($precedence = 0, $allowArrow = false)
{
if ($allowArrow && $arrow = $this->parseArrow()) {
return $arrow;
}

$expr = $this->getPrimary();
$token = $this->parser->getCurrentToken();
while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
$op = $this->binaryOperators[$token->getValue()];
$this->parser->getStream()->next();

if ('is not' === $token->getValue()) {
$expr = $this->parseNotTestExpression($expr);
} elseif ('is' === $token->getValue()) {
$expr = $this->parseTestExpression($expr);
} elseif (isset($op['callable'])) {
$expr = \call_user_func($op['callable'], $this->parser, $expr);
} else {
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
$class = $op['class'];
$expr = new $class($expr, $expr1, $token->getLine());
}

$token = $this->parser->getCurrentToken();
}

if (0 === $precedence) {
return $this->parseConditionalExpression($expr);
}

return $expr;
}




private function parseArrow()
{
$stream = $this->parser->getStream();


if ($stream->look(1)->test(Token::ARROW_TYPE)) {
$line = $stream->getCurrent()->getLine();
$token = $stream->expect(Token::NAME_TYPE);
$names = [new AssignNameExpression($token->getValue(), $token->getLine())];
$stream->expect(Token::ARROW_TYPE);

return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
}


$i = 0;
if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, '(')) {
return null;
}
++$i;
while (true) {

++$i;
if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, ',')) {
break;
}
++$i;
}
if (!$stream->look($i)->test(Token::PUNCTUATION_TYPE, ')')) {
return null;
}
++$i;
if (!$stream->look($i)->test(Token::ARROW_TYPE)) {
return null;
}


$token = $stream->expect(Token::PUNCTUATION_TYPE, '(');
$line = $token->getLine();

$names = [];
while (true) {
$token = $stream->expect(Token::NAME_TYPE);
$names[] = new AssignNameExpression($token->getValue(), $token->getLine());

if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
break;
}
}
$stream->expect(Token::PUNCTUATION_TYPE, ')');
$stream->expect(Token::ARROW_TYPE);

return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
}

protected function getPrimary()
{
$token = $this->parser->getCurrentToken();

if ($this->isUnary($token)) {
$operator = $this->unaryOperators[$token->getValue()];
$this->parser->getStream()->next();
$expr = $this->parseExpression($operator['precedence']);
$class = $operator['class'];

return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
} elseif ($token->test(Token::PUNCTUATION_TYPE, '(')) {
$this->parser->getStream()->next();
$expr = $this->parseExpression();
$this->parser->getStream()->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');

return $this->parsePostfixExpression($expr);
}

return $this->parsePrimaryExpression();
}

protected function parseConditionalExpression($expr)
{
while ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, '?')) {
if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
$expr2 = $this->parseExpression();
if ($this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ':')) {
$expr3 = $this->parseExpression();
} else {
$expr3 = new ConstantExpression('', $this->parser->getCurrentToken()->getLine());
}
} else {
$expr2 = $expr;
$expr3 = $this->parseExpression();
}

$expr = new ConditionalExpression($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
}

return $expr;
}

protected function isUnary(Token $token)
{
return $token->test(Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
}

protected function isBinary(Token $token)
{
return $token->test(Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
}

public function parsePrimaryExpression()
{
$token = $this->parser->getCurrentToken();
switch ($token->getType()) {
case Token::NAME_TYPE:
$this->parser->getStream()->next();
switch ($token->getValue()) {
case 'true':
case 'TRUE':
$node = new ConstantExpression(true, $token->getLine());
break;

case 'false':
case 'FALSE':
$node = new ConstantExpression(false, $token->getLine());
break;

case 'none':
case 'NONE':
case 'null':
case 'NULL':
$node = new ConstantExpression(null, $token->getLine());
break;

default:
if ('(' === $this->parser->getCurrentToken()->getValue()) {
$node = $this->getFunctionNode($token->getValue(), $token->getLine());
} else {
$node = new NameExpression($token->getValue(), $token->getLine());
}
}
break;

case Token::NUMBER_TYPE:
$this->parser->getStream()->next();
$node = new ConstantExpression($token->getValue(), $token->getLine());
break;

case Token::STRING_TYPE:
case Token::INTERPOLATION_START_TYPE:
$node = $this->parseStringExpression();
break;

case Token::OPERATOR_TYPE:
if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {

$this->parser->getStream()->next();
$node = new NameExpression($token->getValue(), $token->getLine());
break;
} elseif (isset($this->unaryOperators[$token->getValue()])) {
$class = $this->unaryOperators[$token->getValue()]['class'];

$ref = new \ReflectionClass($class);
$negClass = 'Twig\Node\Expression\Unary\NegUnary';
$posClass = 'Twig\Node\Expression\Unary\PosUnary';
if (!(\in_array($ref->getName(), [$negClass, $posClass, 'Twig_Node_Expression_Unary_Neg', 'Twig_Node_Expression_Unary_Pos'])
|| $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass)
|| $ref->isSubclassOf('Twig_Node_Expression_Unary_Neg') || $ref->isSubclassOf('Twig_Node_Expression_Unary_Pos'))
) {
throw new SyntaxError(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
}

$this->parser->getStream()->next();
$expr = $this->parsePrimaryExpression();

$node = new $class($expr, $token->getLine());
break;
}


default:
if ($token->test(Token::PUNCTUATION_TYPE, '[')) {
$node = $this->parseArrayExpression();
} elseif ($token->test(Token::PUNCTUATION_TYPE, '{')) {
$node = $this->parseHashExpression();
} elseif ($token->test(Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
throw new SyntaxError(sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
} else {
throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
}
}

return $this->parsePostfixExpression($node);
}

public function parseStringExpression()
{
$stream = $this->parser->getStream();

$nodes = [];

$nextCanBeString = true;
while (true) {
if ($nextCanBeString && $token = $stream->nextIf(Token::STRING_TYPE)) {
$nodes[] = new ConstantExpression($token->getValue(), $token->getLine());
$nextCanBeString = false;
} elseif ($stream->nextIf(Token::INTERPOLATION_START_TYPE)) {
$nodes[] = $this->parseExpression();
$stream->expect(Token::INTERPOLATION_END_TYPE);
$nextCanBeString = true;
} else {
break;
}
}

$expr = array_shift($nodes);
foreach ($nodes as $node) {
$expr = new ConcatBinary($expr, $node, $node->getTemplateLine());
}

return $expr;
}

public function parseArrayExpression()
{
$stream = $this->parser->getStream();
$stream->expect(Token::PUNCTUATION_TYPE, '[', 'An array element was expected');

$node = new ArrayExpression([], $stream->getCurrent()->getLine());
$first = true;
while (!$stream->test(Token::PUNCTUATION_TYPE, ']')) {
if (!$first) {
$stream->expect(Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');


if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
break;
}
}
$first = false;

$node->addElement($this->parseExpression());
}
$stream->expect(Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');

return $node;
}

public function parseHashExpression()
{
$stream = $this->parser->getStream();
$stream->expect(Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');

$node = new ArrayExpression([], $stream->getCurrent()->getLine());
$first = true;
while (!$stream->test(Token::PUNCTUATION_TYPE, '}')) {
if (!$first) {
$stream->expect(Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');


if ($stream->test(Token::PUNCTUATION_TYPE, '}')) {
break;
}
}
$first = false;







if ($token = $stream->nextIf(Token::NAME_TYPE)) {
$key = new ConstantExpression($token->getValue(), $token->getLine());


if ($stream->test(Token::PUNCTUATION_TYPE, [',', '}'])) {
$value = new NameExpression($key->getAttribute('value'), $key->getTemplateLine());
$node->addElement($value, $key);
continue;
}
} elseif (($token = $stream->nextIf(Token::STRING_TYPE)) || $token = $stream->nextIf(Token::NUMBER_TYPE)) {
$key = new ConstantExpression($token->getValue(), $token->getLine());
} elseif ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
$key = $this->parseExpression();
} else {
$current = $stream->getCurrent();

throw new SyntaxError(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
}

$stream->expect(Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
$value = $this->parseExpression();

$node->addElement($value, $key);
}
$stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');

return $node;
}

public function parsePostfixExpression($node)
{
while (true) {
$token = $this->parser->getCurrentToken();
if (Token::PUNCTUATION_TYPE == $token->getType()) {
if ('.' == $token->getValue() || '[' == $token->getValue()) {
$node = $this->parseSubscriptExpression($node);
} elseif ('|' == $token->getValue()) {
$node = $this->parseFilterExpression($node);
} else {
break;
}
} else {
break;
}
}

return $node;
}

public function getFunctionNode($name, $line)
{
switch ($name) {
case 'parent':
$this->parseArguments();
if (!\count($this->parser->getBlockStack())) {
throw new SyntaxError('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
}

if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
throw new SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
}

return new ParentExpression($this->parser->peekBlockStack(), $line);
case 'block':
$args = $this->parseArguments();
if (\count($args) < 1) {
throw new SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
}

return new BlockReferenceExpression($args->getNode(0), \count($args) > 1 ? $args->getNode(1) : null, $line);
case 'attribute':
$args = $this->parseArguments();
if (\count($args) < 2) {
throw new SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
}

return new GetAttrExpression($args->getNode(0), $args->getNode(1), \count($args) > 2 ? $args->getNode(2) : null, Template::ANY_CALL, $line);
default:
if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
$arguments = new ArrayExpression([], $line);
foreach ($this->parseArguments() as $n) {
$arguments->addElement($n);
}

$node = new MethodCallExpression($alias['node'], $alias['name'], $arguments, $line);
$node->setAttribute('safe', true);

return $node;
}

$args = $this->parseArguments(true);
$class = $this->getFunctionNodeClass($name, $line);

return new $class($name, $args, $line);
}
}

public function parseSubscriptExpression($node)
{
$stream = $this->parser->getStream();
$token = $stream->next();
$lineno = $token->getLine();
$arguments = new ArrayExpression([], $lineno);
$type = Template::ANY_CALL;
if ('.' == $token->getValue()) {
$token = $stream->next();
if (
Token::NAME_TYPE == $token->getType()
||
Token::NUMBER_TYPE == $token->getType()
||
(Token::OPERATOR_TYPE == $token->getType() && preg_match(Lexer::REGEX_NAME, $token->getValue()))
) {
$arg = new ConstantExpression($token->getValue(), $lineno);

if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
$type = Template::METHOD_CALL;
foreach ($this->parseArguments() as $n) {
$arguments->addElement($n);
}
}
} else {
throw new SyntaxError('Expected name or number.', $lineno, $stream->getSourceContext());
}

if ($node instanceof NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
if (!$arg instanceof ConstantExpression) {
throw new SyntaxError(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
}

$name = $arg->getAttribute('value');

if ($this->parser->isReservedMacroName($name)) {
throw new SyntaxError(sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
}

$node = new MethodCallExpression($node, 'get'.$name, $arguments, $lineno);
$node->setAttribute('safe', true);

return $node;
}
} else {
$type = Template::ARRAY_CALL;


$slice = false;
if ($stream->test(Token::PUNCTUATION_TYPE, ':')) {
$slice = true;
$arg = new ConstantExpression(0, $token->getLine());
} else {
$arg = $this->parseExpression();
}

if ($stream->nextIf(Token::PUNCTUATION_TYPE, ':')) {
$slice = true;
}

if ($slice) {
if ($stream->test(Token::PUNCTUATION_TYPE, ']')) {
$length = new ConstantExpression(null, $token->getLine());
} else {
$length = $this->parseExpression();
}

$class = $this->getFilterNodeClass('slice', $token->getLine());
$arguments = new Node([$arg, $length]);
$filter = new $class($node, new ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine());

$stream->expect(Token::PUNCTUATION_TYPE, ']');

return $filter;
}

$stream->expect(Token::PUNCTUATION_TYPE, ']');
}

return new GetAttrExpression($node, $arg, $arguments, $type, $lineno);
}

public function parseFilterExpression($node)
{
$this->parser->getStream()->next();

return $this->parseFilterExpressionRaw($node);
}

public function parseFilterExpressionRaw($node, $tag = null)
{
while (true) {
$token = $this->parser->getStream()->expect(Token::NAME_TYPE);

$name = new ConstantExpression($token->getValue(), $token->getLine());
if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '(')) {
$arguments = new Node();
} else {
$arguments = $this->parseArguments(true, false, true);
}

$class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());

$node = new $class($node, $name, $arguments, $token->getLine(), $tag);

if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '|')) {
break;
}

$this->parser->getStream()->next();
}

return $node;
}











public function parseArguments($namedArguments = false, $definition = false, $allowArrow = false)
{
$args = [];
$stream = $this->parser->getStream();

$stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
if (!empty($args)) {
$stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');


if ($stream->test(Token::PUNCTUATION_TYPE, ')')) {
break;
}
}

if ($definition) {
$token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name');
$value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
} else {
$value = $this->parseExpression(0, $allowArrow);
}

$name = null;
if ($namedArguments && $token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) {
if (!$value instanceof NameExpression) {
throw new SyntaxError(sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
}
$name = $value->getAttribute('name');

if ($definition) {
$value = $this->parsePrimaryExpression();

if (!$this->checkConstantExpression($value)) {
throw new SyntaxError('A default value for an argument must be a constant (a boolean, a string, a number, or an array).', $token->getLine(), $stream->getSourceContext());
}
} else {
$value = $this->parseExpression(0, $allowArrow);
}
}

if ($definition) {
if (null === $name) {
$name = $value->getAttribute('name');
$value = new ConstantExpression(null, $this->parser->getCurrentToken()->getLine());
}
$args[$name] = $value;
} else {
if (null === $name) {
$args[] = $value;
} else {
$args[$name] = $value;
}
}
}
$stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');

return new Node($args);
}

public function parseAssignmentExpression()
{
$stream = $this->parser->getStream();
$targets = [];
while (true) {
$token = $this->parser->getCurrentToken();
if ($stream->test(Token::OPERATOR_TYPE) && preg_match(Lexer::REGEX_NAME, $token->getValue())) {

$this->parser->getStream()->next();
} else {
$stream->expect(Token::NAME_TYPE, null, 'Only variables can be assigned to');
}
$value = $token->getValue();
if (\in_array(strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ['true', 'false', 'none', 'null'])) {
throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
}
$targets[] = new AssignNameExpression($value, $token->getLine());

if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
break;
}
}

return new Node($targets);
}

public function parseMultitargetExpression()
{
$targets = [];
while (true) {
$targets[] = $this->parseExpression();
if (!$this->parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, ',')) {
break;
}
}

return new Node($targets);
}

private function parseNotTestExpression(\Twig_NodeInterface $node)
{
return new NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
}

private function parseTestExpression(\Twig_NodeInterface $node)
{
$stream = $this->parser->getStream();
list($name, $test) = $this->getTest($node->getTemplateLine());

$class = $this->getTestNodeClass($test);
$arguments = null;
if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
$arguments = $this->parseArguments(true);
} elseif ($test->hasOneMandatoryArgument()) {
$arguments = new Node([0 => $this->parsePrimaryExpression()]);
}

return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
}

private function getTest($line)
{
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();

if ($test = $this->env->getTest($name)) {
return [$name, $test];
}

if ($stream->test(Token::NAME_TYPE)) {

$name = $name.' '.$this->parser->getCurrentToken()->getValue();

if ($test = $this->env->getTest($name)) {
$stream->next();

return [$name, $test];
}
}

$e = new SyntaxError(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
$e->addSuggestions($name, array_keys($this->env->getTests()));

throw $e;
}

private function getTestNodeClass($test)
{
if ($test instanceof TwigTest && $test->isDeprecated()) {
$stream = $this->parser->getStream();
$message = sprintf('Twig Test "%s" is deprecated', $test->getName());
if (!\is_bool($test->getDeprecatedVersion())) {
$message .= sprintf(' since version %s', $test->getDeprecatedVersion());
}
if ($test->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $test->getAlternative());
}
$src = $stream->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $stream->getCurrent()->getLine());

@trigger_error($message, \E_USER_DEPRECATED);
}

if ($test instanceof TwigTest) {
return $test->getNodeClass();
}

return $test instanceof \Twig_Test_Node ? $test->getClass() : 'Twig\Node\Expression\TestExpression';
}

protected function getFunctionNodeClass($name, $line)
{
if (false === $function = $this->env->getFunction($name)) {
$e = new SyntaxError(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
$e->addSuggestions($name, array_keys($this->env->getFunctions()));

throw $e;
}

if ($function instanceof TwigFunction && $function->isDeprecated()) {
$message = sprintf('Twig Function "%s" is deprecated', $function->getName());
if (!\is_bool($function->getDeprecatedVersion())) {
$message .= sprintf(' since version %s', $function->getDeprecatedVersion());
}
if ($function->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $function->getAlternative());
}
$src = $this->parser->getStream()->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line);

@trigger_error($message, \E_USER_DEPRECATED);
}

if ($function instanceof TwigFunction) {
return $function->getNodeClass();
}

return $function instanceof \Twig_Function_Node ? $function->getClass() : 'Twig\Node\Expression\FunctionExpression';
}

protected function getFilterNodeClass($name, $line)
{
if (false === $filter = $this->env->getFilter($name)) {
$e = new SyntaxError(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
$e->addSuggestions($name, array_keys($this->env->getFilters()));

throw $e;
}

if ($filter instanceof TwigFilter && $filter->isDeprecated()) {
$message = sprintf('Twig Filter "%s" is deprecated', $filter->getName());
if (!\is_bool($filter->getDeprecatedVersion())) {
$message .= sprintf(' since version %s', $filter->getDeprecatedVersion());
}
if ($filter->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $filter->getAlternative());
}
$src = $this->parser->getStream()->getSourceContext();
$message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line);

@trigger_error($message, \E_USER_DEPRECATED);
}

if ($filter instanceof TwigFilter) {
return $filter->getNodeClass();
}

return $filter instanceof \Twig_Filter_Node ? $filter->getClass() : 'Twig\Node\Expression\FilterExpression';
}


protected function checkConstantExpression(\Twig_NodeInterface $node)
{
if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression
|| $node instanceof NegUnary || $node instanceof PosUnary
)) {
return false;
}

foreach ($node as $n) {
if (!$this->checkConstantExpression($n)) {
return false;
}
}

return true;
}
}

class_alias('Twig\ExpressionParser', 'Twig_ExpressionParser');
Copyright (c) 2006-2015 Doctrine Project

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

final class Language
{
public const ENGLISH = 'english';
public const FRENCH = 'french';
public const NORWEGIAN_BOKMAL = 'norwegian-bokmal';
public const PORTUGUESE = 'portuguese';
public const SPANISH = 'spanish';
public const TURKISH = 'turkish';

private function __construct()
{
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

use Doctrine\Inflector\Rules\English;
use Doctrine\Inflector\Rules\French;
use Doctrine\Inflector\Rules\NorwegianBokmal;
use Doctrine\Inflector\Rules\Portuguese;
use Doctrine\Inflector\Rules\Spanish;
use Doctrine\Inflector\Rules\Turkish;
use InvalidArgumentException;

use function sprintf;

final class InflectorFactory
{
public static function create(): LanguageInflectorFactory
{
return self::createForLanguage(Language::ENGLISH);
}

public static function createForLanguage(string $language): LanguageInflectorFactory
{
switch ($language) {
case Language::ENGLISH:
return new English\InflectorFactory();

case Language::FRENCH:
return new French\InflectorFactory();

case Language::NORWEGIAN_BOKMAL:
return new NorwegianBokmal\InflectorFactory();

case Language::PORTUGUESE:
return new Portuguese\InflectorFactory();

case Language::SPANISH:
return new Spanish\InflectorFactory();

case Language::TURKISH:
return new Turkish\InflectorFactory();

default:
throw new InvalidArgumentException(sprintf(
'Language "%s" is not supported.',
$language
));
}
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

interface WordInflector
{
public function inflect(string $word): string;
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\NorwegianBokmal;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\NorwegianBokmal;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\NorwegianBokmal;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{

public static function getSingular(): iterable
{
yield from self::getDefault();
}


public static function getPlural(): iterable
{
yield from self::getDefault();
}


private static function getDefault(): iterable
{
yield new Pattern('barn');
yield new Pattern('fjell');
yield new Pattern('hus');
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\NorwegianBokmal;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

class Inflectible
{

public static function getSingular(): iterable
{
yield new Transformation(new Pattern('/re$/i'), 'r');
yield new Transformation(new Pattern('/er$/i'), '');
}


public static function getPlural(): iterable
{
yield new Transformation(new Pattern('/e$/i'), 'er');
yield new Transformation(new Pattern('/r$/i'), 're');
yield new Transformation(new Pattern('/$/'), 'er');
}


public static function getIrregular(): iterable
{
yield new Substitution(new Word('konto'), new Word('konti'));
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

use Doctrine\Inflector\WordInflector;

class Transformations implements WordInflector
{

private $transformations;

public function __construct(Transformation ...$transformations)
{
$this->transformations = $transformations;
}

public function inflect(string $word): string
{
foreach ($this->transformations as $transformation) {
if ($transformation->getPattern()->matches($word)) {
return $transformation->inflect($word);
}
}

return $word;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

final class Substitution
{

private $from;


private $to;

public function __construct(Word $from, Word $to)
{
$this->from = $from;
$this->to = $to;
}

public function getFrom(): Word
{
return $this->from;
}

public function getTo(): Word
{
return $this->to;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Spanish;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Spanish;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Spanish;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{

public static function getSingular(): iterable
{
yield from self::getDefault();
}


public static function getPlural(): iterable
{
yield from self::getDefault();
}


private static function getDefault(): iterable
{
yield new Pattern('lunes');
yield new Pattern('rompecabezas');
yield new Pattern('crisis');
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Spanish;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

class Inflectible
{

public static function getSingular(): iterable
{
yield new Transformation(new Pattern('/ereses$/'), 'erés');
yield new Transformation(new Pattern('/iones$/'), 'ión');
yield new Transformation(new Pattern('/ces$/'), 'z');
yield new Transformation(new Pattern('/es$/'), '');
yield new Transformation(new Pattern('/s$/'), '');
}


public static function getPlural(): iterable
{
yield new Transformation(new Pattern('/ú([sn])$/i'), 'u\1es');
yield new Transformation(new Pattern('/ó([sn])$/i'), 'o\1es');
yield new Transformation(new Pattern('/í([sn])$/i'), 'i\1es');
yield new Transformation(new Pattern('/é([sn])$/i'), 'e\1es');
yield new Transformation(new Pattern('/á([sn])$/i'), 'a\1es');
yield new Transformation(new Pattern('/z$/i'), 'ces');
yield new Transformation(new Pattern('/([aeiou]s)$/i'), '\1');
yield new Transformation(new Pattern('/([^aeéiou])$/i'), '\1es');
yield new Transformation(new Pattern('/$/'), 's');
}


public static function getIrregular(): iterable
{
yield new Substitution(new Word('el'), new Word('los'));
yield new Substitution(new Word('papá'), new Word('papás'));
yield new Substitution(new Word('mamá'), new Word('mamás'));
yield new Substitution(new Word('sofá'), new Word('sofás'));
yield new Substitution(new Word('mes'), new Word('meses'));
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\French;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\French;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\French;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{

public static function getSingular(): iterable
{
yield from self::getDefault();
}


public static function getPlural(): iterable
{
yield from self::getDefault();
}


private static function getDefault(): iterable
{
yield new Pattern('');
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\French;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

class Inflectible
{

public static function getSingular(): iterable
{
yield new Transformation(new Pattern('/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/'), '\1ail');
yield new Transformation(new Pattern('/ails$/'), 'ail');
yield new Transformation(new Pattern('/(journ|chev)aux$/'), '\1al');
yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/'), '\1');
yield new Transformation(new Pattern('/s$/'), '');
}


public static function getPlural(): iterable
{
yield new Transformation(new Pattern('/(s|x|z)$/'), '\1');
yield new Transformation(new Pattern('/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/'), '\1aux');
yield new Transformation(new Pattern('/ail$/'), 'ails');
yield new Transformation(new Pattern('/(chacal|carnaval|festival|récital)$/'), '\1s');
yield new Transformation(new Pattern('/al$/'), 'aux');
yield new Transformation(new Pattern('/(bleu|émeu|landau|pneu|sarrau)$/'), '\1s');
yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|lieu|pou|au|eu|eau)$/'), '\1x');
yield new Transformation(new Pattern('/$/'), 's');
}


public static function getIrregular(): iterable
{
yield new Substitution(new Word('monsieur'), new Word('messieurs'));
yield new Substitution(new Word('madame'), new Word('mesdames'));
yield new Substitution(new Word('mademoiselle'), new Word('mesdemoiselles'));
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

use function preg_match;

final class Pattern
{

private $pattern;


private $regex;

public function __construct(string $pattern)
{
$this->pattern = $pattern;

if (isset($this->pattern[0]) && $this->pattern[0] === '/') {
$this->regex = $this->pattern;
} else {
$this->regex = '/' . $this->pattern . '/i';
}
}

public function getPattern(): string
{
return $this->pattern;
}

public function getRegex(): string
{
return $this->regex;
}

public function matches(string $word): bool
{
return preg_match($this->getRegex(), $word) === 1;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

use function array_map;
use function implode;
use function preg_match;

class Patterns
{

private $patterns;


private $regex;

public function __construct(Pattern ...$patterns)
{
$this->patterns = $patterns;

$patterns = array_map(static function (Pattern $pattern): string {
return $pattern->getPattern();
}, $this->patterns);

$this->regex = '/^(?:' . implode('|', $patterns) . ')$/i';
}

public function matches(string $word): bool
{
return preg_match($this->regex, $word, $regs) === 1;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

class Word
{

private $word;

public function __construct(string $word)
{
$this->word = $word;
}

public function getWord(): string
{
return $this->word;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Turkish;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Turkish;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Turkish;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{

public static function getSingular(): iterable
{
yield from self::getDefault();
}


public static function getPlural(): iterable
{
yield from self::getDefault();
}


private static function getDefault(): iterable
{
yield new Pattern('lunes');
yield new Pattern('rompecabezas');
yield new Pattern('crisis');
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Turkish;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

class Inflectible
{

public static function getSingular(): iterable
{
yield new Transformation(new Pattern('/l[ae]r$/i'), '');
}


public static function getPlural(): iterable
{
yield new Transformation(new Pattern('/([eöiü][^aoıueöiü]{0,6})$/u'), '\1ler');
yield new Transformation(new Pattern('/([aoıu][^aoıueöiü]{0,6})$/u'), '\1lar');
}


public static function getIrregular(): iterable
{
yield new Substitution(new Word('ben'), new Word('biz'));
yield new Substitution(new Word('sen'), new Word('siz'));
yield new Substitution(new Word('o'), new Word('onlar'));
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Portuguese;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Portuguese;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Portuguese;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{

public static function getSingular(): iterable
{
yield from self::getDefault();
}


public static function getPlural(): iterable
{
yield from self::getDefault();
}


private static function getDefault(): iterable
{
yield new Pattern('tórax');
yield new Pattern('tênis');
yield new Pattern('ônibus');
yield new Pattern('lápis');
yield new Pattern('fênix');
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\Portuguese;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

class Inflectible
{

public static function getSingular(): iterable
{
yield new Transformation(new Pattern('/^(g|)ases$/i'), '\1ás');
yield new Transformation(new Pattern('/(japon|escoc|ingl|dinamarqu|fregu|portugu)eses$/i'), '\1ês');
yield new Transformation(new Pattern('/(ae|ao|oe)s$/'), 'ao');
yield new Transformation(new Pattern('/(ãe|ão|õe)s$/'), 'ão');
yield new Transformation(new Pattern('/^(.*[^s]s)es$/i'), '\1');
yield new Transformation(new Pattern('/sses$/i'), 'sse');
yield new Transformation(new Pattern('/ns$/i'), 'm');
yield new Transformation(new Pattern('/(r|t|f|v)is$/i'), '\1il');
yield new Transformation(new Pattern('/uis$/i'), 'ul');
yield new Transformation(new Pattern('/ois$/i'), 'ol');
yield new Transformation(new Pattern('/eis$/i'), 'ei');
yield new Transformation(new Pattern('/éis$/i'), 'el');
yield new Transformation(new Pattern('/([^p])ais$/i'), '\1al');
yield new Transformation(new Pattern('/(r|z)es$/i'), '\1');
yield new Transformation(new Pattern('/^(á|gá)s$/i'), '\1s');
yield new Transformation(new Pattern('/([^ê])s$/i'), '\1');
}


public static function getPlural(): iterable
{
yield new Transformation(new Pattern('/^(alem|c|p)ao$/i'), '\1aes');
yield new Transformation(new Pattern('/^(irm|m)ao$/i'), '\1aos');
yield new Transformation(new Pattern('/ao$/i'), 'oes');
yield new Transformation(new Pattern('/^(alem|c|p)ão$/i'), '\1ães');
yield new Transformation(new Pattern('/^(irm|m)ão$/i'), '\1ãos');
yield new Transformation(new Pattern('/ão$/i'), 'ões');
yield new Transformation(new Pattern('/^(|g)ás$/i'), '\1ases');
yield new Transformation(new Pattern('/^(japon|escoc|ingl|dinamarqu|fregu|portugu)ês$/i'), '\1eses');
yield new Transformation(new Pattern('/m$/i'), 'ns');
yield new Transformation(new Pattern('/([^aeou])il$/i'), '\1is');
yield new Transformation(new Pattern('/ul$/i'), 'uis');
yield new Transformation(new Pattern('/ol$/i'), 'ois');
yield new Transformation(new Pattern('/el$/i'), 'eis');
yield new Transformation(new Pattern('/al$/i'), 'ais');
yield new Transformation(new Pattern('/(z|r)$/i'), '\1es');
yield new Transformation(new Pattern('/(s)$/i'), '\1');
yield new Transformation(new Pattern('/$/'), 's');
}


public static function getIrregular(): iterable
{
yield new Substitution(new Word('abdomen'), new Word('abdomens'));
yield new Substitution(new Word('alemão'), new Word('alemães'));
yield new Substitution(new Word('artesã'), new Word('artesãos'));
yield new Substitution(new Word('álcool'), new Word('álcoois'));
yield new Substitution(new Word('árvore'), new Word('árvores'));
yield new Substitution(new Word('bencão'), new Word('bencãos'));
yield new Substitution(new Word('cão'), new Word('cães'));
yield new Substitution(new Word('campus'), new Word('campi'));
yield new Substitution(new Word('cadáver'), new Word('cadáveres'));
yield new Substitution(new Word('capelão'), new Word('capelães'));
yield new Substitution(new Word('capitão'), new Word('capitães'));
yield new Substitution(new Word('chão'), new Word('chãos'));
yield new Substitution(new Word('charlatão'), new Word('charlatães'));
yield new Substitution(new Word('cidadão'), new Word('cidadãos'));
yield new Substitution(new Word('consul'), new Word('consules'));
yield new Substitution(new Word('cristão'), new Word('cristãos'));
yield new Substitution(new Word('difícil'), new Word('difíceis'));
yield new Substitution(new Word('email'), new Word('emails'));
yield new Substitution(new Word('escrivão'), new Word('escrivães'));
yield new Substitution(new Word('fóssil'), new Word('fósseis'));
yield new Substitution(new Word('gás'), new Word('gases'));
yield new Substitution(new Word('germens'), new Word('germen'));
yield new Substitution(new Word('grão'), new Word('grãos'));
yield new Substitution(new Word('hífen'), new Word('hífens'));
yield new Substitution(new Word('irmão'), new Word('irmãos'));
yield new Substitution(new Word('liquens'), new Word('liquen'));
yield new Substitution(new Word('mal'), new Word('males'));
yield new Substitution(new Word('mão'), new Word('mãos'));
yield new Substitution(new Word('orfão'), new Word('orfãos'));
yield new Substitution(new Word('país'), new Word('países'));
yield new Substitution(new Word('pai'), new Word('pais'));
yield new Substitution(new Word('pão'), new Word('pães'));
yield new Substitution(new Word('projétil'), new Word('projéteis'));
yield new Substitution(new Word('réptil'), new Word('répteis'));
yield new Substitution(new Word('sacristão'), new Word('sacristães'));
yield new Substitution(new Word('sotão'), new Word('sotãos'));
yield new Substitution(new Word('tabelião'), new Word('tabeliães'));
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\English;

use Doctrine\Inflector\GenericLanguageInflectorFactory;
use Doctrine\Inflector\Rules\Ruleset;

final class InflectorFactory extends GenericLanguageInflectorFactory
{
protected function getSingularRuleset(): Ruleset
{
return Rules::getSingularRuleset();
}

protected function getPluralRuleset(): Ruleset
{
return Rules::getPluralRuleset();
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\English;

use Doctrine\Inflector\Rules\Patterns;
use Doctrine\Inflector\Rules\Ruleset;
use Doctrine\Inflector\Rules\Substitutions;
use Doctrine\Inflector\Rules\Transformations;

final class Rules
{
public static function getSingularRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getSingular()),
new Patterns(...Uninflected::getSingular()),
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
);
}

public static function getPluralRuleset(): Ruleset
{
return new Ruleset(
new Transformations(...Inflectible::getPlural()),
new Patterns(...Uninflected::getPlural()),
new Substitutions(...Inflectible::getIrregular())
);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\English;

use Doctrine\Inflector\Rules\Pattern;

final class Uninflected
{

public static function getSingular(): iterable
{
yield from self::getDefault();

yield new Pattern('.*ss');
yield new Pattern('clothes');
yield new Pattern('data');
yield new Pattern('fascia');
yield new Pattern('fuchsia');
yield new Pattern('galleria');
yield new Pattern('mafia');
yield new Pattern('militia');
yield new Pattern('pants');
yield new Pattern('petunia');
yield new Pattern('sepia');
yield new Pattern('trivia');
yield new Pattern('utopia');
}


public static function getPlural(): iterable
{
yield from self::getDefault();

yield new Pattern('people');
yield new Pattern('trivia');
yield new Pattern('\w+ware$');
yield new Pattern('media');
}


private static function getDefault(): iterable
{
yield new Pattern('\w+media');
yield new Pattern('advice');
yield new Pattern('aircraft');
yield new Pattern('amoyese');
yield new Pattern('art');
yield new Pattern('audio');
yield new Pattern('baggage');
yield new Pattern('bison');
yield new Pattern('borghese');
yield new Pattern('bream');
yield new Pattern('breeches');
yield new Pattern('britches');
yield new Pattern('buffalo');
yield new Pattern('butter');
yield new Pattern('cantus');
yield new Pattern('carp');
yield new Pattern('cattle');
yield new Pattern('chassis');
yield new Pattern('clippers');
yield new Pattern('clothing');
yield new Pattern('coal');
yield new Pattern('cod');
yield new Pattern('coitus');
yield new Pattern('compensation');
yield new Pattern('congoese');
yield new Pattern('contretemps');
yield new Pattern('coreopsis');
yield new Pattern('corps');
yield new Pattern('cotton');
yield new Pattern('data');
yield new Pattern('debris');
yield new Pattern('deer');
yield new Pattern('diabetes');
yield new Pattern('djinn');
yield new Pattern('education');
yield new Pattern('eland');
yield new Pattern('elk');
yield new Pattern('emoji');
yield new Pattern('equipment');
yield new Pattern('evidence');
yield new Pattern('faroese');
yield new Pattern('feedback');
yield new Pattern('fish');
yield new Pattern('flounder');
yield new Pattern('flour');
yield new Pattern('foochowese');
yield new Pattern('food');
yield new Pattern('furniture');
yield new Pattern('gallows');
yield new Pattern('genevese');
yield new Pattern('genoese');
yield new Pattern('gilbertese');
yield new Pattern('gold');
yield new Pattern('headquarters');
yield new Pattern('herpes');
yield new Pattern('hijinks');
yield new Pattern('homework');
yield new Pattern('hottentotese');
yield new Pattern('impatience');
yield new Pattern('information');
yield new Pattern('innings');
yield new Pattern('jackanapes');
yield new Pattern('jeans');
yield new Pattern('jedi');
yield new Pattern('kin');
yield new Pattern('kiplingese');
yield new Pattern('knowledge');
yield new Pattern('kongoese');
yield new Pattern('leather');
yield new Pattern('love');
yield new Pattern('lucchese');
yield new Pattern('luggage');
yield new Pattern('mackerel');
yield new Pattern('Maltese');
yield new Pattern('management');
yield new Pattern('metadata');
yield new Pattern('mews');
yield new Pattern('money');
yield new Pattern('moose');
yield new Pattern('mumps');
yield new Pattern('music');
yield new Pattern('nankingese');
yield new Pattern('news');
yield new Pattern('nexus');
yield new Pattern('niasese');
yield new Pattern('nutrition');
yield new Pattern('offspring');
yield new Pattern('oil');
yield new Pattern('patience');
yield new Pattern('pekingese');
yield new Pattern('piedmontese');
yield new Pattern('pincers');
yield new Pattern('pistoiese');
yield new Pattern('plankton');
yield new Pattern('pliers');
yield new Pattern('pokemon');
yield new Pattern('police');
yield new Pattern('polish');
yield new Pattern('portuguese');
yield new Pattern('proceedings');
yield new Pattern('progress');
yield new Pattern('rabies');
yield new Pattern('rain');
yield new Pattern('research');
yield new Pattern('rhinoceros');
yield new Pattern('rice');
yield new Pattern('salmon');
yield new Pattern('sand');
yield new Pattern('sarawakese');
yield new Pattern('scissors');
yield new Pattern('sea[- ]bass');
yield new Pattern('series');
yield new Pattern('shavese');
yield new Pattern('shears');
yield new Pattern('sheep');
yield new Pattern('siemens');
yield new Pattern('silk');
yield new Pattern('sms');
yield new Pattern('soap');
yield new Pattern('social media');
yield new Pattern('spam');
yield new Pattern('species');
yield new Pattern('staff');
yield new Pattern('sugar');
yield new Pattern('swine');
yield new Pattern('talent');
yield new Pattern('toothpaste');
yield new Pattern('traffic');
yield new Pattern('travel');
yield new Pattern('trousers');
yield new Pattern('trout');
yield new Pattern('tuna');
yield new Pattern('us');
yield new Pattern('vermontese');
yield new Pattern('vinegar');
yield new Pattern('weather');
yield new Pattern('wenchowese');
yield new Pattern('wheat');
yield new Pattern('whiting');
yield new Pattern('wildebeest');
yield new Pattern('wood');
yield new Pattern('wool');
yield new Pattern('yengeese');
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules\English;

use Doctrine\Inflector\Rules\Pattern;
use Doctrine\Inflector\Rules\Substitution;
use Doctrine\Inflector\Rules\Transformation;
use Doctrine\Inflector\Rules\Word;

class Inflectible
{

public static function getSingular(): iterable
{
yield new Transformation(new Pattern('(s)tatuses$'), '\1\2tatus');
yield new Transformation(new Pattern('(s)tatus$'), '\1\2tatus');
yield new Transformation(new Pattern('(c)ampus$'), '\1\2ampus');
yield new Transformation(new Pattern('^(.*)(menu)s$'), '\1\2');
yield new Transformation(new Pattern('(quiz)zes$'), '\\1');
yield new Transformation(new Pattern('(matr)ices$'), '\1ix');
yield new Transformation(new Pattern('(vert|ind)ices$'), '\1ex');
yield new Transformation(new Pattern('^(ox)en'), '\1');
yield new Transformation(new Pattern('(alias)(es)*$'), '\1');
yield new Transformation(new Pattern('(buffal|her|potat|tomat|volcan)oes$'), '\1o');
yield new Transformation(new Pattern('(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$'), '\1us');
yield new Transformation(new Pattern('([ftw]ax)es'), '\1');
yield new Transformation(new Pattern('(analys|ax|cris|test|thes)es$'), '\1is');
yield new Transformation(new Pattern('(shoe|slave)s$'), '\1');
yield new Transformation(new Pattern('(o)es$'), '\1');
yield new Transformation(new Pattern('ouses$'), 'ouse');
yield new Transformation(new Pattern('([^a])uses$'), '\1us');
yield new Transformation(new Pattern('([m|l])ice$'), '\1ouse');
yield new Transformation(new Pattern('(x|ch|ss|sh)es$'), '\1');
yield new Transformation(new Pattern('(m)ovies$'), '\1\2ovie');
yield new Transformation(new Pattern('(s)eries$'), '\1\2eries');
yield new Transformation(new Pattern('([^aeiouy]|qu)ies$'), '\1y');
yield new Transformation(new Pattern('([lr])ves$'), '\1f');
yield new Transformation(new Pattern('(tive)s$'), '\1');
yield new Transformation(new Pattern('(hive)s$'), '\1');
yield new Transformation(new Pattern('(drive)s$'), '\1');
yield new Transformation(new Pattern('(dive)s$'), '\1');
yield new Transformation(new Pattern('(olive)s$'), '\1');
yield new Transformation(new Pattern('([^fo])ves$'), '\1fe');
yield new Transformation(new Pattern('(^analy)ses$'), '\1sis');
yield new Transformation(new Pattern('(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$'), '\1\2sis');
yield new Transformation(new Pattern('(tax)a$'), '\1on');
yield new Transformation(new Pattern('(c)riteria$'), '\1riterion');
yield new Transformation(new Pattern('([ti])a$'), '\1um');
yield new Transformation(new Pattern('(p)eople$'), '\1\2erson');
yield new Transformation(new Pattern('(m)en$'), '\1an');
yield new Transformation(new Pattern('(c)hildren$'), '\1\2hild');
yield new Transformation(new Pattern('(f)eet$'), '\1oot');
yield new Transformation(new Pattern('(n)ews$'), '\1\2ews');
yield new Transformation(new Pattern('eaus$'), 'eau');
yield new Transformation(new Pattern('^tights$'), 'tights');
yield new Transformation(new Pattern('^shorts$'), 'shorts');
yield new Transformation(new Pattern('s$'), '');
}


public static function getPlural(): iterable
{
yield new Transformation(new Pattern('(s)tatus$'), '\1\2tatuses');
yield new Transformation(new Pattern('(quiz)$'), '\1zes');
yield new Transformation(new Pattern('^(ox)$'), '\1\2en');
yield new Transformation(new Pattern('([m|l])ouse$'), '\1ice');
yield new Transformation(new Pattern('(matr|vert|ind)(ix|ex)$'), '\1ices');
yield new Transformation(new Pattern('(x|ch|ss|sh)$'), '\1es');
yield new Transformation(new Pattern('([^aeiouy]|qu)y$'), '\1ies');
yield new Transformation(new Pattern('(hive|gulf)$'), '\1s');
yield new Transformation(new Pattern('(?:([^f])fe|([lr])f)$'), '\1\2ves');
yield new Transformation(new Pattern('sis$'), 'ses');
yield new Transformation(new Pattern('([ti])um$'), '\1a');
yield new Transformation(new Pattern('(tax)on$'), '\1a');
yield new Transformation(new Pattern('(c)riterion$'), '\1riteria');
yield new Transformation(new Pattern('(p)erson$'), '\1eople');
yield new Transformation(new Pattern('(m)an$'), '\1en');
yield new Transformation(new Pattern('(c)hild$'), '\1hildren');
yield new Transformation(new Pattern('(f)oot$'), '\1eet');
yield new Transformation(new Pattern('(buffal|her|potat|tomat|volcan)o$'), '\1\2oes');
yield new Transformation(new Pattern('(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$'), '\1i');
yield new Transformation(new Pattern('us$'), 'uses');
yield new Transformation(new Pattern('(alias)$'), '\1es');
yield new Transformation(new Pattern('(analys|ax|cris|test|thes)is$'), '\1es');
yield new Transformation(new Pattern('s$'), 's');
yield new Transformation(new Pattern('^$'), '');
yield new Transformation(new Pattern('$'), 's');
}


public static function getIrregular(): iterable
{
yield new Substitution(new Word('atlas'), new Word('atlases'));
yield new Substitution(new Word('axe'), new Word('axes'));
yield new Substitution(new Word('beef'), new Word('beefs'));
yield new Substitution(new Word('blouse'), new Word('blouses'));
yield new Substitution(new Word('brother'), new Word('brothers'));
yield new Substitution(new Word('cafe'), new Word('cafes'));
yield new Substitution(new Word('chateau'), new Word('chateaux'));
yield new Substitution(new Word('niveau'), new Word('niveaux'));
yield new Substitution(new Word('child'), new Word('children'));
yield new Substitution(new Word('canvas'), new Word('canvases'));
yield new Substitution(new Word('cookie'), new Word('cookies'));
yield new Substitution(new Word('corpus'), new Word('corpuses'));
yield new Substitution(new Word('cow'), new Word('cows'));
yield new Substitution(new Word('criterion'), new Word('criteria'));
yield new Substitution(new Word('curriculum'), new Word('curricula'));
yield new Substitution(new Word('demo'), new Word('demos'));
yield new Substitution(new Word('domino'), new Word('dominoes'));
yield new Substitution(new Word('echo'), new Word('echoes'));
yield new Substitution(new Word('foot'), new Word('feet'));
yield new Substitution(new Word('fungus'), new Word('fungi'));
yield new Substitution(new Word('ganglion'), new Word('ganglions'));
yield new Substitution(new Word('gas'), new Word('gases'));
yield new Substitution(new Word('genie'), new Word('genies'));
yield new Substitution(new Word('genus'), new Word('genera'));
yield new Substitution(new Word('goose'), new Word('geese'));
yield new Substitution(new Word('graffito'), new Word('graffiti'));
yield new Substitution(new Word('hippopotamus'), new Word('hippopotami'));
yield new Substitution(new Word('hoof'), new Word('hoofs'));
yield new Substitution(new Word('human'), new Word('humans'));
yield new Substitution(new Word('iris'), new Word('irises'));
yield new Substitution(new Word('larva'), new Word('larvae'));
yield new Substitution(new Word('leaf'), new Word('leaves'));
yield new Substitution(new Word('lens'), new Word('lenses'));
yield new Substitution(new Word('loaf'), new Word('loaves'));
yield new Substitution(new Word('man'), new Word('men'));
yield new Substitution(new Word('medium'), new Word('media'));
yield new Substitution(new Word('memorandum'), new Word('memoranda'));
yield new Substitution(new Word('money'), new Word('monies'));
yield new Substitution(new Word('mongoose'), new Word('mongooses'));
yield new Substitution(new Word('motto'), new Word('mottoes'));
yield new Substitution(new Word('move'), new Word('moves'));
yield new Substitution(new Word('mythos'), new Word('mythoi'));
yield new Substitution(new Word('niche'), new Word('niches'));
yield new Substitution(new Word('nucleus'), new Word('nuclei'));
yield new Substitution(new Word('numen'), new Word('numina'));
yield new Substitution(new Word('occiput'), new Word('occiputs'));
yield new Substitution(new Word('octopus'), new Word('octopuses'));
yield new Substitution(new Word('opus'), new Word('opuses'));
yield new Substitution(new Word('ox'), new Word('oxen'));
yield new Substitution(new Word('passerby'), new Word('passersby'));
yield new Substitution(new Word('penis'), new Word('penises'));
yield new Substitution(new Word('person'), new Word('people'));
yield new Substitution(new Word('plateau'), new Word('plateaux'));
yield new Substitution(new Word('runner-up'), new Word('runners-up'));
yield new Substitution(new Word('safe'), new Word('safes'));
yield new Substitution(new Word('sex'), new Word('sexes'));
yield new Substitution(new Word('sieve'), new Word('sieves'));
yield new Substitution(new Word('soliloquy'), new Word('soliloquies'));
yield new Substitution(new Word('son-in-law'), new Word('sons-in-law'));
yield new Substitution(new Word('syllabus'), new Word('syllabi'));
yield new Substitution(new Word('testis'), new Word('testes'));
yield new Substitution(new Word('thief'), new Word('thieves'));
yield new Substitution(new Word('tooth'), new Word('teeth'));
yield new Substitution(new Word('tornado'), new Word('tornadoes'));
yield new Substitution(new Word('trilby'), new Word('trilbys'));
yield new Substitution(new Word('turf'), new Word('turfs'));
yield new Substitution(new Word('valve'), new Word('valves'));
yield new Substitution(new Word('volcano'), new Word('volcanoes'));
yield new Substitution(new Word('abuse'), new Word('abuses'));
yield new Substitution(new Word('avalanche'), new Word('avalanches'));
yield new Substitution(new Word('cache'), new Word('caches'));
yield new Substitution(new Word('criterion'), new Word('criteria'));
yield new Substitution(new Word('curve'), new Word('curves'));
yield new Substitution(new Word('emphasis'), new Word('emphases'));
yield new Substitution(new Word('foe'), new Word('foes'));
yield new Substitution(new Word('grave'), new Word('graves'));
yield new Substitution(new Word('hoax'), new Word('hoaxes'));
yield new Substitution(new Word('medium'), new Word('media'));
yield new Substitution(new Word('neurosis'), new Word('neuroses'));
yield new Substitution(new Word('save'), new Word('saves'));
yield new Substitution(new Word('wave'), new Word('waves'));
yield new Substitution(new Word('oasis'), new Word('oases'));
yield new Substitution(new Word('valve'), new Word('valves'));
yield new Substitution(new Word('zombie'), new Word('zombies'));
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

use Doctrine\Inflector\WordInflector;

use function preg_replace;

final class Transformation implements WordInflector
{

private $pattern;


private $replacement;

public function __construct(Pattern $pattern, string $replacement)
{
$this->pattern = $pattern;
$this->replacement = $replacement;
}

public function getPattern(): Pattern
{
return $this->pattern;
}

public function getReplacement(): string
{
return $this->replacement;
}

public function inflect(string $word): string
{
return (string) preg_replace($this->pattern->getRegex(), $this->replacement, $word);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

class Ruleset
{

private $regular;


private $uninflected;


private $irregular;

public function __construct(Transformations $regular, Patterns $uninflected, Substitutions $irregular)
{
$this->regular = $regular;
$this->uninflected = $uninflected;
$this->irregular = $irregular;
}

public function getRegular(): Transformations
{
return $this->regular;
}

public function getUninflected(): Patterns
{
return $this->uninflected;
}

public function getIrregular(): Substitutions
{
return $this->irregular;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector\Rules;

use Doctrine\Inflector\WordInflector;

use function strtolower;
use function strtoupper;
use function substr;

class Substitutions implements WordInflector
{

private $substitutions;

public function __construct(Substitution ...$substitutions)
{
foreach ($substitutions as $substitution) {
$this->substitutions[$substitution->getFrom()->getWord()] = $substitution;
}
}

public function getFlippedSubstitutions(): Substitutions
{
$substitutions = [];

foreach ($this->substitutions as $substitution) {
$substitutions[] = new Substitution(
$substitution->getTo(),
$substitution->getFrom()
);
}

return new Substitutions(...$substitutions);
}

public function inflect(string $word): string
{
$lowerWord = strtolower($word);

if (isset($this->substitutions[$lowerWord])) {
$firstLetterUppercase = $lowerWord[0] !== $word[0];

$toWord = $this->substitutions[$lowerWord]->getTo()->getWord();

if ($firstLetterUppercase) {
return strtoupper($toWord[0]) . substr($toWord, 1);
}

return $toWord;
}

return $word;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

class CachedWordInflector implements WordInflector
{

private $wordInflector;


private $cache = [];

public function __construct(WordInflector $wordInflector)
{
$this->wordInflector = $wordInflector;
}

public function inflect(string $word): string
{
return $this->cache[$word] ?? $this->cache[$word] = $this->wordInflector->inflect($word);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

use Doctrine\Inflector\Rules\Ruleset;

interface LanguageInflectorFactory
{







public function withSingularRules(?Ruleset $singularRules, bool $reset = false): self;








public function withPluralRules(?Ruleset $pluralRules, bool $reset = false): self;




public function build(): Inflector;
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

use RuntimeException;

use function chr;
use function function_exists;
use function lcfirst;
use function mb_strtolower;
use function ord;
use function preg_match;
use function preg_replace;
use function sprintf;
use function str_replace;
use function strlen;
use function strtolower;
use function strtr;
use function trim;
use function ucwords;

class Inflector
{
private const ACCENTED_CHARACTERS = [
'À' => 'A',
'Á' => 'A',
'Â' => 'A',
'Ã' => 'A',
'Ä' => 'Ae',
'Æ' => 'Ae',
'Å' => 'Aa',
'æ' => 'a',
'Ç' => 'C',
'È' => 'E',
'É' => 'E',
'Ê' => 'E',
'Ë' => 'E',
'Ì' => 'I',
'Í' => 'I',
'Î' => 'I',
'Ï' => 'I',
'Ñ' => 'N',
'Ò' => 'O',
'Ó' => 'O',
'Ô' => 'O',
'Õ' => 'O',
'Ö' => 'Oe',
'Ù' => 'U',
'Ú' => 'U',
'Û' => 'U',
'Ü' => 'Ue',
'Ý' => 'Y',
'ß' => 'ss',
'à' => 'a',
'á' => 'a',
'â' => 'a',
'ã' => 'a',
'ä' => 'ae',
'å' => 'aa',
'ç' => 'c',
'è' => 'e',
'é' => 'e',
'ê' => 'e',
'ë' => 'e',
'ì' => 'i',
'í' => 'i',
'î' => 'i',
'ï' => 'i',
'ñ' => 'n',
'ò' => 'o',
'ó' => 'o',
'ô' => 'o',
'õ' => 'o',
'ö' => 'oe',
'ù' => 'u',
'ú' => 'u',
'û' => 'u',
'ü' => 'ue',
'ý' => 'y',
'ÿ' => 'y',
'Ā' => 'A',
'ā' => 'a',
'Ă' => 'A',
'ă' => 'a',
'Ą' => 'A',
'ą' => 'a',
'Ć' => 'C',
'ć' => 'c',
'Ĉ' => 'C',
'ĉ' => 'c',
'Ċ' => 'C',
'ċ' => 'c',
'Č' => 'C',
'č' => 'c',
'Ď' => 'D',
'ď' => 'd',
'Đ' => 'D',
'đ' => 'd',
'Ē' => 'E',
'ē' => 'e',
'Ĕ' => 'E',
'ĕ' => 'e',
'Ė' => 'E',
'ė' => 'e',
'Ę' => 'E',
'ę' => 'e',
'Ě' => 'E',
'ě' => 'e',
'Ĝ' => 'G',
'ĝ' => 'g',
'Ğ' => 'G',
'ğ' => 'g',
'Ġ' => 'G',
'ġ' => 'g',
'Ģ' => 'G',
'ģ' => 'g',
'Ĥ' => 'H',
'ĥ' => 'h',
'Ħ' => 'H',
'ħ' => 'h',
'Ĩ' => 'I',
'ĩ' => 'i',
'Ī' => 'I',
'ī' => 'i',
'Ĭ' => 'I',
'ĭ' => 'i',
'Į' => 'I',
'į' => 'i',
'İ' => 'I',
'ı' => 'i',
'Ĳ' => 'IJ',
'ĳ' => 'ij',
'Ĵ' => 'J',
'ĵ' => 'j',
'Ķ' => 'K',
'ķ' => 'k',
'ĸ' => 'k',
'Ĺ' => 'L',
'ĺ' => 'l',
'Ļ' => 'L',
'ļ' => 'l',
'Ľ' => 'L',
'ľ' => 'l',
'Ŀ' => 'L',
'ŀ' => 'l',
'Ł' => 'L',
'ł' => 'l',
'Ń' => 'N',
'ń' => 'n',
'Ņ' => 'N',
'ņ' => 'n',
'Ň' => 'N',
'ň' => 'n',
'ŉ' => 'N',
'Ŋ' => 'n',
'ŋ' => 'N',
'Ō' => 'O',
'ō' => 'o',
'Ŏ' => 'O',
'ŏ' => 'o',
'Ő' => 'O',
'ő' => 'o',
'Œ' => 'OE',
'œ' => 'oe',
'Ø' => 'O',
'ø' => 'o',
'Ŕ' => 'R',
'ŕ' => 'r',
'Ŗ' => 'R',
'ŗ' => 'r',
'Ř' => 'R',
'ř' => 'r',
'Ś' => 'S',
'ś' => 's',
'Ŝ' => 'S',
'ŝ' => 's',
'Ş' => 'S',
'ş' => 's',
'Š' => 'S',
'š' => 's',
'Ţ' => 'T',
'ţ' => 't',
'Ť' => 'T',
'ť' => 't',
'Ŧ' => 'T',
'ŧ' => 't',
'Ũ' => 'U',
'ũ' => 'u',
'Ū' => 'U',
'ū' => 'u',
'Ŭ' => 'U',
'ŭ' => 'u',
'Ů' => 'U',
'ů' => 'u',
'Ű' => 'U',
'ű' => 'u',
'Ų' => 'U',
'ų' => 'u',
'Ŵ' => 'W',
'ŵ' => 'w',
'Ŷ' => 'Y',
'ŷ' => 'y',
'Ÿ' => 'Y',
'Ź' => 'Z',
'ź' => 'z',
'Ż' => 'Z',
'ż' => 'z',
'Ž' => 'Z',
'ž' => 'z',
'ſ' => 's',
'€' => 'E',
'£' => '',
];


private $singularizer;


private $pluralizer;

public function __construct(WordInflector $singularizer, WordInflector $pluralizer)
{
$this->singularizer = $singularizer;
$this->pluralizer = $pluralizer;
}




public function tableize(string $word): string
{
$tableized = preg_replace('~(?<=\\w)([A-Z])~u', '_$1', $word);

if ($tableized === null) {
throw new RuntimeException(sprintf(
'preg_replace returned null for value "%s"',
$word
));
}

return mb_strtolower($tableized);
}




public function classify(string $word): string
{
return str_replace([' ', '_', '-'], '', ucwords($word, ' _-'));
}




public function camelize(string $word): string
{
return lcfirst($this->classify($word));
}


























public function capitalize(string $string, string $delimiters = " \n\t\r\0\x0B-"): string
{
return ucwords($string, $delimiters);
}






public function seemsUtf8(string $string): bool
{
for ($i = 0; $i < strlen($string); $i++) {
if (ord($string[$i]) < 0x80) {
continue; 
}

if ((ord($string[$i]) & 0xE0) === 0xC0) {
$n = 1; 
} elseif ((ord($string[$i]) & 0xF0) === 0xE0) {
$n = 2; 
} elseif ((ord($string[$i]) & 0xF8) === 0xF0) {
$n = 3; 
} elseif ((ord($string[$i]) & 0xFC) === 0xF8) {
$n = 4; 
} elseif ((ord($string[$i]) & 0xFE) === 0xFC) {
$n = 5; 
} else {
return false; 
}

for ($j = 0; $j < $n; $j++) { 
if (++$i === strlen($string) || ((ord($string[$i]) & 0xC0) !== 0x80)) {
return false;
}
}
}

return true;
}








public function unaccent(string $string): string
{
if (preg_match('/[\x80-\xff]/', $string) === false) {
return $string;
}

if ($this->seemsUtf8($string)) {
$string = strtr($string, self::ACCENTED_CHARACTERS);
} else {
$characters = [];


$characters['in'] =
chr(128)
. chr(131)
. chr(138)
. chr(142)
. chr(154)
. chr(158)
. chr(159)
. chr(162)
. chr(165)
. chr(181)
. chr(192)
. chr(193)
. chr(194)
. chr(195)
. chr(196)
. chr(197)
. chr(199)
. chr(200)
. chr(201)
. chr(202)
. chr(203)
. chr(204)
. chr(205)
. chr(206)
. chr(207)
. chr(209)
. chr(210)
. chr(211)
. chr(212)
. chr(213)
. chr(214)
. chr(216)
. chr(217)
. chr(218)
. chr(219)
. chr(220)
. chr(221)
. chr(224)
. chr(225)
. chr(226)
. chr(227)
. chr(228)
. chr(229)
. chr(231)
. chr(232)
. chr(233)
. chr(234)
. chr(235)
. chr(236)
. chr(237)
. chr(238)
. chr(239)
. chr(241)
. chr(242)
. chr(243)
. chr(244)
. chr(245)
. chr(246)
. chr(248)
. chr(249)
. chr(250)
. chr(251)
. chr(252)
. chr(253)
. chr(255);

$characters['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';

$string = strtr($string, $characters['in'], $characters['out']);

$doubleChars = [];

$doubleChars['in'] = [
chr(140),
chr(156),
chr(198),
chr(208),
chr(222),
chr(223),
chr(230),
chr(240),
chr(254),
];

$doubleChars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];

$string = str_replace($doubleChars['in'], $doubleChars['out'], $string);
}

return $string;
}









public function urlize(string $string): string
{

$unaccented = $this->unaccent($string);

if (function_exists('mb_strtolower')) {
$lowered = mb_strtolower($unaccented);
} else {
$lowered = strtolower($unaccented);
}

$replacements = [
'/\W/' => ' ',
'/([A-Z]+)([A-Z][a-z])/' => '\1_\2',
'/([a-z\d])([A-Z])/' => '\1_\2',
'/[^A-Z^a-z^0-9^\/]+/' => '-',
];

$urlized = $lowered;

foreach ($replacements as $pattern => $replacement) {
$replaced = preg_replace($pattern, $replacement, $urlized);

if ($replaced === null) {
throw new RuntimeException(sprintf(
'preg_replace returned null for value "%s"',
$urlized
));
}

$urlized = $replaced;
}

return trim($urlized, '-');
}








public function singularize(string $word): string
{
return $this->singularizer->inflect($word);
}








public function pluralize(string $word): string
{
return $this->pluralizer->inflect($word);
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

use Doctrine\Inflector\Rules\Ruleset;

use function array_unshift;

abstract class GenericLanguageInflectorFactory implements LanguageInflectorFactory
{

private $singularRulesets = [];


private $pluralRulesets = [];

final public function __construct()
{
$this->singularRulesets[] = $this->getSingularRuleset();
$this->pluralRulesets[] = $this->getPluralRuleset();
}

final public function build(): Inflector
{
return new Inflector(
new CachedWordInflector(new RulesetInflector(
...$this->singularRulesets
)),
new CachedWordInflector(new RulesetInflector(
...$this->pluralRulesets
))
);
}

final public function withSingularRules(?Ruleset $singularRules, bool $reset = false): LanguageInflectorFactory
{
if ($reset) {
$this->singularRulesets = [];
}

if ($singularRules instanceof Ruleset) {
array_unshift($this->singularRulesets, $singularRules);
}

return $this;
}

final public function withPluralRules(?Ruleset $pluralRules, bool $reset = false): LanguageInflectorFactory
{
if ($reset) {
$this->pluralRulesets = [];
}

if ($pluralRules instanceof Ruleset) {
array_unshift($this->pluralRulesets, $pluralRules);
}

return $this;
}

abstract protected function getSingularRuleset(): Ruleset;

abstract protected function getPluralRuleset(): Ruleset;
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

class NoopWordInflector implements WordInflector
{
public function inflect(string $word): string
{
return $word;
}
}
<?php

declare(strict_types=1);

namespace Doctrine\Inflector;

use Doctrine\Inflector\Rules\Ruleset;

use function array_merge;










class RulesetInflector implements WordInflector
{

private $rulesets;

public function __construct(Ruleset $ruleset, Ruleset ...$rulesets)
{
$this->rulesets = array_merge([$ruleset], $rulesets);
}

public function inflect(string $word): string
{
if ($word === '') {
return '';
}

foreach ($this->rulesets as $ruleset) {
if ($ruleset->getUninflected()->matches($word)) {
return $word;
}

$inflected = $ruleset->getIrregular()->inflect($word);

if ($inflected !== $word) {
return $inflected;
}

$inflected = $ruleset->getRegular()->inflect($word);

if ($inflected !== $word) {
return $inflected;
}
}

return $word;
}
}

Copyright (c) Nils Adermann, Jordi Boggiano

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

<?php











namespace Composer;

use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;










class InstalledVersions
{
/**
@psalm-var

*/
private static $installed;




private static $canGetVendors;

/**
@psalm-var

*/
private static $installedByVendor = array();

/**
@psalm-return



*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}

if (1 === \count($packages)) {
return $packages[0];
}

return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}

/**
@psalm-return




*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();

foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}

return $packagesByType;
}










public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}

return false;
}













public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));

return $provided->matches($constraint);
}










public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}

$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}

return implode(' || ', $ranges);
}

throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}





public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}

if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}

return $installed['versions'][$packageName]['version'];
}

throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}





public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}

if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}

return $installed['versions'][$packageName]['pretty_version'];
}

throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}





public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}

if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}

return $installed['versions'][$packageName]['reference'];
}

throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}





public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}

return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}

throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}

/**
@psalm-return

*/
public static function getRootPackage()
{
$installed = self::getInstalled();

return $installed[0]['root'];
}

/**
@psalm-return




*/
public static function getRawData()
{
@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);

if (null === self::$installed) {


if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}

return self::$installed;
}

/**
@psalm-return



*/
public static function getAllRawData()
{
return self::getInstalled();
}

/**
@psalm-param















*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
}

/**
@psalm-return

*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}

$installed = array();

if (self::$canGetVendors) {
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {

$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
}
}
}

if (null === self::$installed) {


if (substr(__DIR__, -8, 1) !== 'C') {

$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}

if (self::$installed !== array()) {
$installed[] = self::$installed;
}

return $installed;
}
}
<?php

// autoload_files.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
    '32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
    '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
);
<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'Universal\\' => array($vendorDir . '/corneltek/universal/src/Universal'),
    'Twig\\' => array($vendorDir . '/twig/twig/src'),
    'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
    'Symfony\\Polyfill\\Apcu\\' => array($vendorDir . '/symfony/polyfill-apcu'),
    'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
    'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
    'Symfony\\Component\\ClassLoader\\' => array($vendorDir . '/symfony/class-loader'),
    'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
    'PhpBrew\\' => array($baseDir . '/src/PhpBrew'),
    'PEARX\\' => array($vendorDir . '/corneltek/pearx/src/PEARX'),
    'GetOptionKit\\' => array($vendorDir . '/corneltek/getoptionkit/src'),
    'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
    'CurlKit\\' => array($vendorDir . '/corneltek/curlkit/src/CurlKit'),
    'CodeGen\\' => array($vendorDir . '/corneltek/codegen/src/CodeGen'),
    'ClassTemplate\\' => array($vendorDir . '/corneltek/class-template/src/ClassTemplate'),
    'CLIFramework\\' => array($vendorDir . '/corneltek/cliframework/src'),
);
<?php

// autoload_static.php @generated by Composer

namespace Composer\Autoload;

class ComposerStaticInit365e25e34522fee120bee0a71e662cb3
{
    public static $files = array (
        '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
        '32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
        '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
    );

    public static $prefixLengthsPsr4 = array (
        'U' => 
        array (
            'Universal\\' => 10,
        ),
        'T' => 
        array (
            'Twig\\' => 5,
        ),
        'S' => 
        array (
            'Symfony\\Polyfill\\Ctype\\' => 23,
            'Symfony\\Polyfill\\Apcu\\' => 22,
            'Symfony\\Component\\Yaml\\' => 23,
            'Symfony\\Component\\Finder\\' => 25,
            'Symfony\\Component\\ClassLoader\\' => 30,
        ),
        'P' => 
        array (
            'Psr\\Container\\' => 14,
            'PhpBrew\\' => 8,
            'PEARX\\' => 6,
        ),
        'G' => 
        array (
            'GetOptionKit\\' => 13,
        ),
        'D' => 
        array (
            'Doctrine\\Inflector\\' => 19,
        ),
        'C' => 
        array (
            'CurlKit\\' => 8,
            'CodeGen\\' => 8,
            'ClassTemplate\\' => 14,
            'CLIFramework\\' => 13,
        ),
    );

    public static $prefixDirsPsr4 = array (
        'Universal\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/universal/src/Universal',
        ),
        'Twig\\' => 
        array (
            0 => __DIR__ . '/..' . '/twig/twig/src',
        ),
        'Symfony\\Polyfill\\Ctype\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
        ),
        'Symfony\\Polyfill\\Apcu\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-apcu',
        ),
        'Symfony\\Component\\Yaml\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/yaml',
        ),
        'Symfony\\Component\\Finder\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/finder',
        ),
        'Symfony\\Component\\ClassLoader\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/class-loader',
        ),
        'Psr\\Container\\' => 
        array (
            0 => __DIR__ . '/..' . '/psr/container/src',
        ),
        'PhpBrew\\' => 
        array (
            0 => __DIR__ . '/../..' . '/src/PhpBrew',
        ),
        'PEARX\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX',
        ),
        'GetOptionKit\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/getoptionkit/src',
        ),
        'Doctrine\\Inflector\\' => 
        array (
            0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector',
        ),
        'CurlKit\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit',
        ),
        'CodeGen\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen',
        ),
        'ClassTemplate\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/class-template/src/ClassTemplate',
        ),
        'CLIFramework\\' => 
        array (
            0 => __DIR__ . '/..' . '/corneltek/cliframework/src',
        ),
    );

    public static $prefixesPsr0 = array (
        'T' => 
        array (
            'Twig_' => 
            array (
                0 => __DIR__ . '/..' . '/twig/twig/lib',
            ),
        ),
        'P' => 
        array (
            'Pimple' => 
            array (
                0 => __DIR__ . '/..' . '/pimple/pimple/src',
            ),
        ),
    );

    public static $classMap = array (
        'CLIFramework\\Ansi\\Colors' => __DIR__ . '/..' . '/corneltek/cliframework/src/Ansi/Colors.php',
        'CLIFramework\\Ansi\\CursorControl' => __DIR__ . '/..' . '/corneltek/cliframework/src/Ansi/CursorControl.php',
        'CLIFramework\\Application' => __DIR__ . '/..' . '/corneltek/cliframework/src/Application.php',
        'CLIFramework\\ArgInfo' => __DIR__ . '/..' . '/corneltek/cliframework/src/ArgInfo.php',
        'CLIFramework\\ArgInfoList' => __DIR__ . '/..' . '/corneltek/cliframework/src/ArgInfoList.php',
        'CLIFramework\\ArgumentEditor\\ArgumentEditor' => __DIR__ . '/..' . '/corneltek/cliframework/src/ArgumentEditor/ArgumentEditor.php',
        'CLIFramework\\Autoload\\ComposerAutoloadGenerator' => __DIR__ . '/..' . '/corneltek/cliframework/src/Autoload/ComposerAutoloadGenerator.php',
        'CLIFramework\\Buffer' => __DIR__ . '/..' . '/corneltek/cliframework/src/Buffer.php',
        'CLIFramework\\ChainedCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/ChainedCommand.php',
        'CLIFramework\\Chooser' => __DIR__ . '/..' . '/corneltek/cliframework/src/Chooser.php',
        'CLIFramework\\Command' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command.php',
        'CLIFramework\\CommandAutoloader' => __DIR__ . '/..' . '/corneltek/cliframework/src/CommandAutoloader.php',
        'CLIFramework\\CommandBase' => __DIR__ . '/..' . '/corneltek/cliframework/src/CommandBase.php',
        'CLIFramework\\CommandException' => __DIR__ . '/..' . '/corneltek/cliframework/src/CommandException.php',
        'CLIFramework\\CommandGroup' => __DIR__ . '/..' . '/corneltek/cliframework/src/CommandGroup.php',
        'CLIFramework\\CommandInterface' => __DIR__ . '/..' . '/corneltek/cliframework/src/CommandInterface.php',
        'CLIFramework\\CommandLoader' => __DIR__ . '/..' . '/corneltek/cliframework/src/CommandLoader.php',
        'CLIFramework\\Command\\ArchiveCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/ArchiveCommand.php',
        'CLIFramework\\Command\\BashCompletionCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/BashCompletionCommand.php',
        'CLIFramework\\Command\\BuildGitHubWikiTopicsCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/BuildGitHubWikiTopicsCommand.php',
        'CLIFramework\\Command\\CompileCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/CompileCommand.php',
        'CLIFramework\\Command\\HelpCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/HelpCommand.php',
        'CLIFramework\\Command\\MetaCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/MetaCommand.php',
        'CLIFramework\\Command\\ZshCompletionCommand' => __DIR__ . '/..' . '/corneltek/cliframework/src/Command/ZshCompletionCommand.php',
        'CLIFramework\\CompletionUtils' => __DIR__ . '/..' . '/corneltek/cliframework/src/CompletionUtils.php',
        'CLIFramework\\Completion\\BashGenerator' => __DIR__ . '/..' . '/corneltek/cliframework/src/Completion/BashGenerator.php',
        'CLIFramework\\Completion\\Utils' => __DIR__ . '/..' . '/corneltek/cliframework/src/Completion/Utils.php',
        'CLIFramework\\Completion\\ZshGenerator' => __DIR__ . '/..' . '/corneltek/cliframework/src/Completion/ZshGenerator.php',
        'CLIFramework\\Component\\Progress\\ETACalculator' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Progress/ETACalculator.php',
        'CLIFramework\\Component\\Progress\\ProgressBar' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Progress/ProgressBar.php',
        'CLIFramework\\Component\\Progress\\ProgressBarStyle' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Progress/ProgressBarStyle.php',
        'CLIFramework\\Component\\Progress\\ProgressReporter' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Progress/ProgressReporter.php',
        'CLIFramework\\Component\\Progress\\ProgressStar' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Progress/ProgressStar.php',
        'CLIFramework\\Component\\Progress\\SharpProgressBarStyle' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Progress/SharpProgressBarStyle.php',
        'CLIFramework\\Component\\Table\\BorderlessTableStyle' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/BorderlessTableStyle.php',
        'CLIFramework\\Component\\Table\\CellAttribute' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/CellAttribute.php',
        'CLIFramework\\Component\\Table\\CompactTableStyle' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/CompactTableStyle.php',
        'CLIFramework\\Component\\Table\\CurrencyFormatCell' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/CurrencyFormatCell.php',
        'CLIFramework\\Component\\Table\\DateFormatCell' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/DateFormatCell.php',
        'CLIFramework\\Component\\Table\\DurationFormatCell' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/DurationFormatCell.php',
        'CLIFramework\\Component\\Table\\MarkdownTableStyle' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/MarkdownTableStyle.php',
        'CLIFramework\\Component\\Table\\NumberFormatCell' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/NumberFormatCell.php',
        'CLIFramework\\Component\\Table\\SpellOutNumberFormatCell' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/SpellOutNumberFormatCell.php',
        'CLIFramework\\Component\\Table\\Table' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/Table.php',
        'CLIFramework\\Component\\Table\\TableStyle' => __DIR__ . '/..' . '/corneltek/cliframework/src/Component/Table/TableStyle.php',
        'CLIFramework\\Config\\GlobalConfig' => __DIR__ . '/..' . '/corneltek/cliframework/src/Config/GlobalConfig.php',
        'CLIFramework\\ConsoleInfo\\ConsoleInfoFactory' => __DIR__ . '/..' . '/corneltek/cliframework/src/ConsoleInfo/ConsoleInfoFactory.php',
        'CLIFramework\\ConsoleInfo\\ConsoleInfoInterface' => __DIR__ . '/..' . '/corneltek/cliframework/src/ConsoleInfo/ConsoleInfoInterface.php',
        'CLIFramework\\ConsoleInfo\\EnvConsoleInfo' => __DIR__ . '/..' . '/corneltek/cliframework/src/ConsoleInfo/EnvConsoleInfo.php',
        'CLIFramework\\ConsoleInfo\\TputConsoleInfo' => __DIR__ . '/..' . '/corneltek/cliframework/src/ConsoleInfo/TputConsoleInfo.php',
        'CLIFramework\\Corrector' => __DIR__ . '/..' . '/corneltek/cliframework/src/Corrector.php',
        'CLIFramework\\Debug\\ConsoleDebug' => __DIR__ . '/..' . '/corneltek/cliframework/src/Debug/ConsoleDebug.php',
        'CLIFramework\\Debug\\LineIndicator' => __DIR__ . '/..' . '/corneltek/cliframework/src/Debug/LineIndicator.php',
        'CLIFramework\\ExceptionPrinter\\DevelopmentExceptionPrinter' => __DIR__ . '/..' . '/corneltek/cliframework/src/ExceptionPrinter/DevelopmentExceptionPrinter.php',
        'CLIFramework\\ExceptionPrinter\\ProductionExceptionPrinter' => __DIR__ . '/..' . '/corneltek/cliframework/src/ExceptionPrinter/ProductionExceptionPrinter.php',
        'CLIFramework\\Exception\\CommandArgumentNotEnoughException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/CommandArgumentNotEnoughException.php',
        'CLIFramework\\Exception\\CommandBaseException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/CommandBaseException.php',
        'CLIFramework\\Exception\\CommandClassNotFoundException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/CommandClassNotFoundException.php',
        'CLIFramework\\Exception\\CommandNotFoundException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/CommandNotFoundException.php',
        'CLIFramework\\Exception\\ExecuteMethodNotDefinedException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/ExecuteMethodNotDefinedException.php',
        'CLIFramework\\Exception\\ExtensionException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/ExtensionException.php',
        'CLIFramework\\Exception\\InvalidCommandArgumentException' => __DIR__ . '/..' . '/corneltek/cliframework/src/Exception/InvalidCommandArgumentException.php',
        'CLIFramework\\Extension\\ApplicationExtension' => __DIR__ . '/..' . '/corneltek/cliframework/src/Extension/ApplicationExtension.php',
        'CLIFramework\\Extension\\CommandExtension' => __DIR__ . '/..' . '/corneltek/cliframework/src/Extension/CommandExtension.php',
        'CLIFramework\\Extension\\DaemonExtension' => __DIR__ . '/..' . '/corneltek/cliframework/src/Extension/DaemonExtension.php',
        'CLIFramework\\Extension\\Extension' => __DIR__ . '/..' . '/corneltek/cliframework/src/Extension/Extension.php',
        'CLIFramework\\Extension\\ExtensionBase' => __DIR__ . '/..' . '/corneltek/cliframework/src/Extension/ExtensionBase.php',
        'CLIFramework\\Formatter' => __DIR__ . '/..' . '/corneltek/cliframework/src/Formatter.php',
        'CLIFramework\\IO\\Console' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/Console.php',
        'CLIFramework\\IO\\EchoWriter' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/EchoWriter.php',
        'CLIFramework\\IO\\NullStty' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/NullStty.php',
        'CLIFramework\\IO\\ReadlineConsole' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/ReadlineConsole.php',
        'CLIFramework\\IO\\StandardConsole' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/StandardConsole.php',
        'CLIFramework\\IO\\StreamWriter' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/StreamWriter.php',
        'CLIFramework\\IO\\Stty' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/Stty.php',
        'CLIFramework\\IO\\UnixStty' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/UnixStty.php',
        'CLIFramework\\IO\\Writer' => __DIR__ . '/..' . '/corneltek/cliframework/src/IO/Writer.php',
        'CLIFramework\\LevenshteinCorrector' => __DIR__ . '/..' . '/corneltek/cliframework/src/LevenshteinCorrector.php',
        'CLIFramework\\Logger' => __DIR__ . '/..' . '/corneltek/cliframework/src/Logger.php',
        'CLIFramework\\Logger\\ActionLogger' => __DIR__ . '/..' . '/corneltek/cliframework/src/Logger/ActionLogger.php',
        'CLIFramework\\Logger\\Logger' => __DIR__ . '/..' . '/corneltek/cliframework/src/Logger/Logger.php',
        'CLIFramework\\OptionPrinter' => __DIR__ . '/..' . '/corneltek/cliframework/src/OptionPrinter.php',
        'CLIFramework\\PharKit\\PharGenerator' => __DIR__ . '/..' . '/corneltek/cliframework/src/PharKit/PharGenerator.php',
        'CLIFramework\\PharKit\\PharURI' => __DIR__ . '/..' . '/corneltek/cliframework/src/PharKit/PharURI.php',
        'CLIFramework\\Prompter' => __DIR__ . '/..' . '/corneltek/cliframework/src/Prompter.php',
        'CLIFramework\\ServiceContainer' => __DIR__ . '/..' . '/corneltek/cliframework/src/ServiceContainer.php',
        'CLIFramework\\Testing\\CommandTestCase' => __DIR__ . '/..' . '/corneltek/cliframework/src/Testing/CommandTestCase.php',
        'CLIFramework\\Testing\\ConsoleTestCase' => __DIR__ . '/..' . '/corneltek/cliframework/src/Testing/ConsoleTestCase.php',
        'CLIFramework\\Testing\\Parser' => __DIR__ . '/..' . '/corneltek/cliframework/src/Testing/Parser.php',
        'CLIFramework\\Topic\\BaseTopic' => __DIR__ . '/..' . '/corneltek/cliframework/src/Topic/BaseTopic.php',
        'CLIFramework\\Topic\\GitHubTopic' => __DIR__ . '/..' . '/corneltek/cliframework/src/Topic/GitHubTopic.php',
        'CLIFramework\\Utils' => __DIR__ . '/..' . '/corneltek/cliframework/src/Utils.php',
        'CLIFramework\\ValueCollection' => __DIR__ . '/..' . '/corneltek/cliframework/src/ValueCollection.php',
        'CLIFramework\\ValueGroup' => __DIR__ . '/..' . '/corneltek/cliframework/src/ValueGroup.php',
        'ClassTemplate\\ClassFile' => __DIR__ . '/..' . '/corneltek/class-template/src/ClassTemplate/ClassFile.php',
        'ClassTemplate\\ClassInjection' => __DIR__ . '/..' . '/corneltek/class-template/src/ClassTemplate/ClassInjection.php',
        'ClassTemplate\\File' => __DIR__ . '/..' . '/corneltek/class-template/src/ClassTemplate/File.php',
        'ClassTemplate\\TemplateClassFile' => __DIR__ . '/..' . '/corneltek/class-template/src/ClassTemplate/TemplateClassFile.php',
        'ClassTemplate\\TemplateView' => __DIR__ . '/..' . '/corneltek/class-template/src/ClassTemplate/TemplateView.php',
        'CodeGen\\Annotator' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Annotator.php',
        'CodeGen\\Argument' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Argument.php',
        'CodeGen\\ArgumentList' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ArgumentList.php',
        'CodeGen\\Block' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Block.php',
        'CodeGen\\BracketedBlock' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/BracketedBlock.php',
        'CodeGen\\ClassConst' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ClassConst.php',
        'CodeGen\\ClassMethod' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ClassMethod.php',
        'CodeGen\\ClassName' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ClassName.php',
        'CodeGen\\ClassProperty' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ClassProperty.php',
        'CodeGen\\ClassStaticVariable' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ClassStaticVariable.php',
        'CodeGen\\ClassTrait' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/ClassTrait.php',
        'CodeGen\\Comment' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Comment.php',
        'CodeGen\\CommentBlock' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/CommentBlock.php',
        'CodeGen\\Constant' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Constant.php',
        'CodeGen\\Exception\\InvalidArgumentTypeException' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Exception/InvalidArgumentTypeException.php',
        'CodeGen\\Exportable' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Exportable.php',
        'CodeGen\\Expr\\AssignExpr' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/AssignExpr.php',
        'CodeGen\\Expr\\CallExpr' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/CallExpr.php',
        'CodeGen\\Expr\\FunctionCall' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/FunctionCall.php',
        'CodeGen\\Expr\\MethodCall' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/MethodCall.php',
        'CodeGen\\Expr\\MethodCallExpr' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/MethodCallExpr.php',
        'CodeGen\\Expr\\NewObject' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/NewObject.php',
        'CodeGen\\Expr\\NewObjectExpr' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/NewObjectExpr.php',
        'CodeGen\\Expr\\ObjectProperty' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/ObjectProperty.php',
        'CodeGen\\Expr\\SelfMethodCall' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/SelfMethodCall.php',
        'CodeGen\\Expr\\SelfMethodCallExpr' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/SelfMethodCallExpr.php',
        'CodeGen\\Expr\\StaticMethodCall' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Expr/StaticMethodCall.php',
        'CodeGen\\Frameworks\\PHPUnit\\Assertions' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Frameworks/PHPUnit/Assertions.php',
        'CodeGen\\Frameworks\\PHPUnit\\PHPUnitFrameworkTestCase' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Frameworks/PHPUnit/PHPUnitFrameworkTestCase.php',
        'CodeGen\\Generator\\AppClassGenerator' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Generator/AppClassGenerator.php',
        'CodeGen\\Generator\\ArrayAccessGenerator' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Generator/ArrayAccessGenerator.php',
        'CodeGen\\Indenter' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Indenter.php',
        'CodeGen\\LicenseBlock' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/LicenseBlock.php',
        'CodeGen\\Line' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Line.php',
        'CodeGen\\Raw' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Raw.php',
        'CodeGen\\Renderable' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Renderable.php',
        'CodeGen\\Statement\\AssignStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/AssignStatement.php',
        'CodeGen\\Statement\\ConditionalStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/ConditionalStatement.php',
        'CodeGen\\Statement\\ConstStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/ConstStatement.php',
        'CodeGen\\Statement\\DefineStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/DefineStatement.php',
        'CodeGen\\Statement\\ElseIfStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/ElseIfStatement.php',
        'CodeGen\\Statement\\ElseStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/ElseStatement.php',
        'CodeGen\\Statement\\ForEachStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/ForEachStatement.php',
        'CodeGen\\Statement\\FunctionCallStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/FunctionCallStatement.php',
        'CodeGen\\Statement\\IfElseStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/IfElseStatement.php',
        'CodeGen\\Statement\\IfIssetStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/IfIssetStatement.php',
        'CodeGen\\Statement\\IfStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/IfStatement.php',
        'CodeGen\\Statement\\MethodCallStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/MethodCallStatement.php',
        'CodeGen\\Statement\\RequireClassStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/RequireClassStatement.php',
        'CodeGen\\Statement\\RequireComposerAutoloadStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/RequireComposerAutoloadStatement.php',
        'CodeGen\\Statement\\RequireOnceStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/RequireOnceStatement.php',
        'CodeGen\\Statement\\RequireStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/RequireStatement.php',
        'CodeGen\\Statement\\Statement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/Statement.php',
        'CodeGen\\Statement\\TryCatchStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/TryCatchStatement.php',
        'CodeGen\\Statement\\UseStatement' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Statement/UseStatement.php',
        'CodeGen\\Testing\\CodeGenTestCase' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Testing/CodeGenTestCase.php',
        'CodeGen\\UseClass' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/UseClass.php',
        'CodeGen\\UserClass' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/UserClass.php',
        'CodeGen\\UserFunction' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/UserFunction.php',
        'CodeGen\\Utils' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Utils.php',
        'CodeGen\\Variable' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/Variable.php',
        'CodeGen\\VariableDeflator' => __DIR__ . '/..' . '/corneltek/codegen/src/CodeGen/VariableDeflator.php',
        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
        'CurlKit\\CurlAgent' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/CurlAgent.php',
        'CurlKit\\CurlDownloader' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/CurlDownloader.php',
        'CurlKit\\CurlException' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/CurlException.php',
        'CurlKit\\CurlRequest' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/CurlRequest.php',
        'CurlKit\\CurlResponse' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/CurlResponse.php',
        'CurlKit\\Progress\\CurlProgressInterface' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/Progress/CurlProgressInterface.php',
        'CurlKit\\Progress\\ProgressBar' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/Progress/ProgressBar.php',
        'CurlKit\\Progress\\ProgressStar' => __DIR__ . '/..' . '/corneltek/curlkit/src/CurlKit/Progress/ProgressStar.php',
        'Doctrine\\Inflector\\CachedWordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php',
        'Doctrine\\Inflector\\GenericLanguageInflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php',
        'Doctrine\\Inflector\\Inflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Inflector.php',
        'Doctrine\\Inflector\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php',
        'Doctrine\\Inflector\\Language' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Language.php',
        'Doctrine\\Inflector\\LanguageInflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/LanguageInflectorFactory.php',
        'Doctrine\\Inflector\\NoopWordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/NoopWordInflector.php',
        'Doctrine\\Inflector\\Rules\\English\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php',
        'Doctrine\\Inflector\\Rules\\English\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.php',
        'Doctrine\\Inflector\\Rules\\English\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Rules.php',
        'Doctrine\\Inflector\\Rules\\English\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php',
        'Doctrine\\Inflector\\Rules\\French\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.php',
        'Doctrine\\Inflector\\Rules\\French\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.php',
        'Doctrine\\Inflector\\Rules\\French\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Rules.php',
        'Doctrine\\Inflector\\Rules\\French\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php',
        'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.php',
        'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/InflectorFactory.php',
        'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Rules.php',
        'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php',
        'Doctrine\\Inflector\\Rules\\Pattern' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Pattern.php',
        'Doctrine\\Inflector\\Rules\\Patterns' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php',
        'Doctrine\\Inflector\\Rules\\Portuguese\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php',
        'Doctrine\\Inflector\\Rules\\Portuguese\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/InflectorFactory.php',
        'Doctrine\\Inflector\\Rules\\Portuguese\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Rules.php',
        'Doctrine\\Inflector\\Rules\\Portuguese\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php',
        'Doctrine\\Inflector\\Rules\\Ruleset' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Ruleset.php',
        'Doctrine\\Inflector\\Rules\\Spanish\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php',
        'Doctrine\\Inflector\\Rules\\Spanish\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/InflectorFactory.php',
        'Doctrine\\Inflector\\Rules\\Spanish\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Rules.php',
        'Doctrine\\Inflector\\Rules\\Spanish\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php',
        'Doctrine\\Inflector\\Rules\\Substitution' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitution.php',
        'Doctrine\\Inflector\\Rules\\Substitutions' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php',
        'Doctrine\\Inflector\\Rules\\Transformation' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php',
        'Doctrine\\Inflector\\Rules\\Transformations' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php',
        'Doctrine\\Inflector\\Rules\\Turkish\\Inflectible' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php',
        'Doctrine\\Inflector\\Rules\\Turkish\\InflectorFactory' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.php',
        'Doctrine\\Inflector\\Rules\\Turkish\\Rules' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Rules.php',
        'Doctrine\\Inflector\\Rules\\Turkish\\Uninflected' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php',
        'Doctrine\\Inflector\\Rules\\Word' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Word.php',
        'Doctrine\\Inflector\\RulesetInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php',
        'Doctrine\\Inflector\\WordInflector' => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php',
        'GetOptionKit\\Argument' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Argument.php',
        'GetOptionKit\\ContinuousOptionParser' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ContinuousOptionParser.php',
        'GetOptionKit\\Exception\\InvalidOptionException' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Exception/InvalidOptionException.php',
        'GetOptionKit\\Exception\\InvalidOptionValueException' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Exception/InvalidOptionValueException.php',
        'GetOptionKit\\Exception\\NonNumericException' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Exception/NonNumericException.php',
        'GetOptionKit\\Exception\\OptionConflictException' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Exception/OptionConflictException.php',
        'GetOptionKit\\Exception\\RequireValueException' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Exception/RequireValueException.php',
        'GetOptionKit\\Option' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/Option.php',
        'GetOptionKit\\OptionCollection' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/OptionCollection.php',
        'GetOptionKit\\OptionParser' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/OptionParser.php',
        'GetOptionKit\\OptionPrinter\\ConsoleOptionPrinter' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/OptionPrinter/ConsoleOptionPrinter.php',
        'GetOptionKit\\OptionPrinter\\OptionPrinter' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/OptionPrinter/OptionPrinter.php',
        'GetOptionKit\\OptionResult' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/OptionResult.php',
        'GetOptionKit\\ValueType\\BaseType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/BaseType.php',
        'GetOptionKit\\ValueType\\BoolType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/BoolType.php',
        'GetOptionKit\\ValueType\\BooleanType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/BooleanType.php',
        'GetOptionKit\\ValueType\\DateTimeType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/DateTimeType.php',
        'GetOptionKit\\ValueType\\DateType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/DateType.php',
        'GetOptionKit\\ValueType\\DirType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/DirType.php',
        'GetOptionKit\\ValueType\\EmailType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/EmailType.php',
        'GetOptionKit\\ValueType\\FileType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/FileType.php',
        'GetOptionKit\\ValueType\\IpType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/IpType.php',
        'GetOptionKit\\ValueType\\Ipv4Type' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/Ipv4Type.php',
        'GetOptionKit\\ValueType\\Ipv6Type' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/Ipv6Type.php',
        'GetOptionKit\\ValueType\\NumberType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/NumberType.php',
        'GetOptionKit\\ValueType\\PathType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/PathType.php',
        'GetOptionKit\\ValueType\\RegexType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/RegexType.php',
        'GetOptionKit\\ValueType\\StringType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/StringType.php',
        'GetOptionKit\\ValueType\\UrlType' => __DIR__ . '/..' . '/corneltek/getoptionkit/src/ValueType/UrlType.php',
        'PEARX\\Category' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/Category.php',
        'PEARX\\Channel' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/Channel.php',
        'PEARX\\ChannelParser' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/ChannelParser.php',
        'PEARX\\Core' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/Core.php',
        'PEARX\\Installer' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/Installer.php',
        'PEARX\\Package' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/Package.php',
        'PEARX\\PackageCollection' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/PackageCollection.php',
        'PEARX\\PackageXml\\ContentFile' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/PackageXml/ContentFile.php',
        'PEARX\\PackageXml\\Parser' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/PackageXml/Parser.php',
        'PEARX\\Utils' => __DIR__ . '/..' . '/corneltek/pearx/src/PEARX/Utils.php',
        'PhpBrew\\Build' => __DIR__ . '/../..' . '/src/PhpBrew/Build.php',
        'PhpBrew\\BuildFinder' => __DIR__ . '/../..' . '/src/PhpBrew/BuildFinder.php',
        'PhpBrew\\BuildSettings\\BuildSettings' => __DIR__ . '/../..' . '/src/PhpBrew/BuildSettings/BuildSettings.php',
        'PhpBrew\\Buildable' => __DIR__ . '/../..' . '/src/PhpBrew/Buildable.php',
        'PhpBrew\\CommandBuilder' => __DIR__ . '/../..' . '/src/PhpBrew/CommandBuilder.php',
        'PhpBrew\\Command\\CdCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/CdCommand.php',
        'PhpBrew\\Command\\CleanCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/CleanCommand.php',
        'PhpBrew\\Command\\ConfigCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ConfigCommand.php',
        'PhpBrew\\Command\\CtagsCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/CtagsCommand.php',
        'PhpBrew\\Command\\DownloadCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/DownloadCommand.php',
        'PhpBrew\\Command\\EachCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/EachCommand.php',
        'PhpBrew\\Command\\EnvCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/EnvCommand.php',
        'PhpBrew\\Command\\ExtensionCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\BaseCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/BaseCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\CleanCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/CleanCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\ConfigCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/ConfigCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\DisableCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/DisableCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\EnableCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/EnableCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\InstallCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/InstallCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\KnownCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/KnownCommand.php',
        'PhpBrew\\Command\\ExtensionCommand\\ShowCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ExtensionCommand/ShowCommand.php',
        'PhpBrew\\Command\\FpmCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/FpmCommand.php',
        'PhpBrew\\Command\\FpmCommand\\RestartCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/FpmCommand/RestartCommand.php',
        'PhpBrew\\Command\\FpmCommand\\SetupCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/FpmCommand/SetupCommand.php',
        'PhpBrew\\Command\\FpmCommand\\StartCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/FpmCommand/StartCommand.php',
        'PhpBrew\\Command\\FpmCommand\\StopCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/FpmCommand/StopCommand.php',
        'PhpBrew\\Command\\HelpCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/HelpCommand.php',
        'PhpBrew\\Command\\InfoCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/InfoCommand.php',
        'PhpBrew\\Command\\InitCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/InitCommand.php',
        'PhpBrew\\Command\\InstallCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/InstallCommand.php',
        'PhpBrew\\Command\\KnownCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/KnownCommand.php',
        'PhpBrew\\Command\\ListCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ListCommand.php',
        'PhpBrew\\Command\\ListIniCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/ListIniCommand.php',
        'PhpBrew\\Command\\MigratedCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/MigratedCommand.php',
        'PhpBrew\\Command\\OffCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/OffCommand.php',
        'PhpBrew\\Command\\PathCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/PathCommand.php',
        'PhpBrew\\Command\\PurgeCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/PurgeCommand.php',
        'PhpBrew\\Command\\RemoveCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/RemoveCommand.php',
        'PhpBrew\\Command\\SelfUpdateCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/SelfUpdateCommand.php',
        'PhpBrew\\Command\\SwitchCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/SwitchCommand.php',
        'PhpBrew\\Command\\SwitchOffCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/SwitchOffCommand.php',
        'PhpBrew\\Command\\SystemCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/SystemCommand.php',
        'PhpBrew\\Command\\SystemOffCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/SystemOffCommand.php',
        'PhpBrew\\Command\\UpdateCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/UpdateCommand.php',
        'PhpBrew\\Command\\UseCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/UseCommand.php',
        'PhpBrew\\Command\\VariantsCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/VariantsCommand.php',
        'PhpBrew\\Command\\VirtualCommand' => __DIR__ . '/../..' . '/src/PhpBrew/Command/VirtualCommand.php',
        'PhpBrew\\Config' => __DIR__ . '/../..' . '/src/PhpBrew/Config.php',
        'PhpBrew\\ConfigureParameters' => __DIR__ . '/../..' . '/src/PhpBrew/ConfigureParameters.php',
        'PhpBrew\\Console' => __DIR__ . '/../..' . '/src/PhpBrew/Console.php',
        'PhpBrew\\Distribution\\DistributionUrlPolicy' => __DIR__ . '/../..' . '/src/PhpBrew/Distribution/DistributionUrlPolicy.php',
        'PhpBrew\\Downloader\\BaseDownloader' => __DIR__ . '/../..' . '/src/PhpBrew/Downloader/BaseDownloader.php',
        'PhpBrew\\Downloader\\CurlCommandDownloader' => __DIR__ . '/../..' . '/src/PhpBrew/Downloader/CurlCommandDownloader.php',
        'PhpBrew\\Downloader\\DownloadFactory' => __DIR__ . '/../..' . '/src/PhpBrew/Downloader/DownloadFactory.php',
        'PhpBrew\\Downloader\\PhpCurlDownloader' => __DIR__ . '/../..' . '/src/PhpBrew/Downloader/PhpCurlDownloader.php',
        'PhpBrew\\Downloader\\PhpStreamDownloader' => __DIR__ . '/../..' . '/src/PhpBrew/Downloader/PhpStreamDownloader.php',
        'PhpBrew\\Downloader\\WgetCommandDownloader' => __DIR__ . '/../..' . '/src/PhpBrew/Downloader/WgetCommandDownloader.php',
        'PhpBrew\\Exception\\OopsException' => __DIR__ . '/../..' . '/src/PhpBrew/Exception/OopsException.php',
        'PhpBrew\\Exception\\SystemCommandException' => __DIR__ . '/../..' . '/src/PhpBrew/Exception/SystemCommandException.php',
        'PhpBrew\\ExtensionList' => __DIR__ . '/../..' . '/src/PhpBrew/ExtensionList.php',
        'PhpBrew\\Extension\\ConfigureOption' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/ConfigureOption.php',
        'PhpBrew\\Extension\\Extension' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/Extension.php',
        'PhpBrew\\Extension\\ExtensionDownloader' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/ExtensionDownloader.php',
        'PhpBrew\\Extension\\ExtensionFactory' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/ExtensionFactory.php',
        'PhpBrew\\Extension\\ExtensionInstaller' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/ExtensionInstaller.php',
        'PhpBrew\\Extension\\ExtensionManager' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/ExtensionManager.php',
        'PhpBrew\\Extension\\M4Extension' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/M4Extension.php',
        'PhpBrew\\Extension\\PeclExtension' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/PeclExtension.php',
        'PhpBrew\\Extension\\Provider\\BitbucketProvider' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/Provider/BitbucketProvider.php',
        'PhpBrew\\Extension\\Provider\\GithubProvider' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/Provider/GithubProvider.php',
        'PhpBrew\\Extension\\Provider\\PeclProvider' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/Provider/PeclProvider.php',
        'PhpBrew\\Extension\\Provider\\Provider' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/Provider/Provider.php',
        'PhpBrew\\Extension\\Provider\\RepositoryDslParser' => __DIR__ . '/../..' . '/src/PhpBrew/Extension/Provider/RepositoryDslParser.php',
        'PhpBrew\\InvalidVariantSyntaxException' => __DIR__ . '/../..' . '/src/PhpBrew/InvalidVariantSyntaxException.php',
        'PhpBrew\\PatchKit\\DiffPatchRule' => __DIR__ . '/../..' . '/src/PhpBrew/PatchKit/DiffPatchRule.php',
        'PhpBrew\\PatchKit\\Patch' => __DIR__ . '/../..' . '/src/PhpBrew/PatchKit/Patch.php',
        'PhpBrew\\PatchKit\\PatchRule' => __DIR__ . '/../..' . '/src/PhpBrew/PatchKit/PatchRule.php',
        'PhpBrew\\PatchKit\\RegExpPatchRule' => __DIR__ . '/../..' . '/src/PhpBrew/PatchKit/RegExpPatchRule.php',
        'PhpBrew\\Patches\\Apache2ModuleNamePatch' => __DIR__ . '/../..' . '/src/PhpBrew/Patches/Apache2ModuleNamePatch.php',
        'PhpBrew\\Patches\\FreeTypePatch' => __DIR__ . '/../..' . '/src/PhpBrew/Patches/FreeTypePatch.php',
        'PhpBrew\\Patches\\IntlWith64bitPatch' => __DIR__ . '/../..' . '/src/PhpBrew/Patches/IntlWith64bitPatch.php',
        'PhpBrew\\Patches\\OpenSSLDSOPatch' => __DIR__ . '/../..' . '/src/PhpBrew/Patches/OpenSSLDSOPatch.php',
        'PhpBrew\\Patches\\PHP56WithOpenSSL11Patch' => __DIR__ . '/../..' . '/src/PhpBrew/Patches/PHP56WithOpenSSL11Patch.php',
        'PhpBrew\\Patches\\ReadlinePatch' => __DIR__ . '/../..' . '/src/PhpBrew/Patches/ReadlinePatch.php',
        'PhpBrew\\PrefixFinder' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder.php',
        'PhpBrew\\PrefixFinder\\BrewPrefixFinder' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder/BrewPrefixFinder.php',
        'PhpBrew\\PrefixFinder\\ExecutablePrefixFinder' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder/ExecutablePrefixFinder.php',
        'PhpBrew\\PrefixFinder\\IncludePrefixFinder' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder/IncludePrefixFinder.php',
        'PhpBrew\\PrefixFinder\\LibPrefixFinder' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder/LibPrefixFinder.php',
        'PhpBrew\\PrefixFinder\\PkgConfigPrefixFinder' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder/PkgConfigPrefixFinder.php',
        'PhpBrew\\PrefixFinder\\UserProvidedPrefix' => __DIR__ . '/../..' . '/src/PhpBrew/PrefixFinder/UserProvidedPrefix.php',
        'PhpBrew\\ReleaseList' => __DIR__ . '/../..' . '/src/PhpBrew/ReleaseList.php',
        'PhpBrew\\Tasks\\AfterConfigureTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/AfterConfigureTask.php',
        'PhpBrew\\Tasks\\Apxs2CheckTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/Apxs2CheckTask.php',
        'PhpBrew\\Tasks\\BaseTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/BaseTask.php',
        'PhpBrew\\Tasks\\BeforeConfigureTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/BeforeConfigureTask.php',
        'PhpBrew\\Tasks\\BuildConfTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/BuildConfTask.php',
        'PhpBrew\\Tasks\\BuildTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/BuildTask.php',
        'PhpBrew\\Tasks\\ConfigureTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/ConfigureTask.php',
        'PhpBrew\\Tasks\\DSymTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/DSymTask.php',
        'PhpBrew\\Tasks\\DownloadTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/DownloadTask.php',
        'PhpBrew\\Tasks\\ExtractTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/ExtractTask.php',
        'PhpBrew\\Tasks\\FetchReleaseListTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/FetchReleaseListTask.php',
        'PhpBrew\\Tasks\\InstallTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/InstallTask.php',
        'PhpBrew\\Tasks\\MakeTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/MakeTask.php',
        'PhpBrew\\Tasks\\PrepareDirectoryTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/PrepareDirectoryTask.php',
        'PhpBrew\\Tasks\\TestTask' => __DIR__ . '/../..' . '/src/PhpBrew/Tasks/TestTask.php',
        'PhpBrew\\Testing\\CommandTestCase' => __DIR__ . '/../..' . '/src/PhpBrew/Testing/CommandTestCase.php',
        'PhpBrew\\Testing\\PatchTestCase' => __DIR__ . '/../..' . '/src/PhpBrew/Testing/PatchTestCase.php',
        'PhpBrew\\Testing\\VCRAdapter' => __DIR__ . '/../..' . '/src/PhpBrew/Testing/VCRAdapter.php',
        'PhpBrew\\Utils' => __DIR__ . '/../..' . '/src/PhpBrew/Utils.php',
        'PhpBrew\\VariantBuilder' => __DIR__ . '/../..' . '/src/PhpBrew/VariantBuilder.php',
        'PhpBrew\\VariantParser' => __DIR__ . '/../..' . '/src/PhpBrew/VariantParser.php',
        'PhpBrew\\VersionDslParser' => __DIR__ . '/../..' . '/src/PhpBrew/VersionDslParser.php',
        'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
        'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
        'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
        'Pimple\\Exception\\InvalidServiceIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php',
        'Pimple\\Exception\\UnknownIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php',
        'Pimple\\Psr11\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/Container.php',
        'Pimple\\Psr11\\ServiceLocator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
        'Pimple\\ServiceIterator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceIterator.php',
        'Pimple\\ServiceProviderInterface' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
        'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
        'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
        'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
        'Symfony\\Component\\ClassLoader\\ApcClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/ApcClassLoader.php',
        'Symfony\\Component\\ClassLoader\\ApcUniversalClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/ApcUniversalClassLoader.php',
        'Symfony\\Component\\ClassLoader\\ClassCollectionLoader' => __DIR__ . '/..' . '/symfony/class-loader/ClassCollectionLoader.php',
        'Symfony\\Component\\ClassLoader\\ClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/ClassLoader.php',
        'Symfony\\Component\\ClassLoader\\ClassMapGenerator' => __DIR__ . '/..' . '/symfony/class-loader/ClassMapGenerator.php',
        'Symfony\\Component\\ClassLoader\\DebugClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/DebugClassLoader.php',
        'Symfony\\Component\\ClassLoader\\DebugUniversalClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/DebugUniversalClassLoader.php',
        'Symfony\\Component\\ClassLoader\\MapClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/MapClassLoader.php',
        'Symfony\\Component\\ClassLoader\\Psr4ClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/Psr4ClassLoader.php',
        'Symfony\\Component\\ClassLoader\\UniversalClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/UniversalClassLoader.php',
        'Symfony\\Component\\ClassLoader\\WinCacheClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/WinCacheClassLoader.php',
        'Symfony\\Component\\ClassLoader\\XcacheClassLoader' => __DIR__ . '/..' . '/symfony/class-loader/XcacheClassLoader.php',
        'Symfony\\Component\\Finder\\Adapter\\AbstractAdapter' => __DIR__ . '/..' . '/symfony/finder/Adapter/AbstractAdapter.php',
        'Symfony\\Component\\Finder\\Adapter\\AbstractFindAdapter' => __DIR__ . '/..' . '/symfony/finder/Adapter/AbstractFindAdapter.php',
        'Symfony\\Component\\Finder\\Adapter\\AdapterInterface' => __DIR__ . '/..' . '/symfony/finder/Adapter/AdapterInterface.php',
        'Symfony\\Component\\Finder\\Adapter\\BsdFindAdapter' => __DIR__ . '/..' . '/symfony/finder/Adapter/BsdFindAdapter.php',
        'Symfony\\Component\\Finder\\Adapter\\GnuFindAdapter' => __DIR__ . '/..' . '/symfony/finder/Adapter/GnuFindAdapter.php',
        'Symfony\\Component\\Finder\\Adapter\\PhpAdapter' => __DIR__ . '/..' . '/symfony/finder/Adapter/PhpAdapter.php',
        'Symfony\\Component\\Finder\\Comparator\\Comparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/Comparator.php',
        'Symfony\\Component\\Finder\\Comparator\\DateComparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/DateComparator.php',
        'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => __DIR__ . '/..' . '/symfony/finder/Comparator/NumberComparator.php',
        'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => __DIR__ . '/..' . '/symfony/finder/Exception/AccessDeniedException.php',
        'Symfony\\Component\\Finder\\Exception\\AdapterFailureException' => __DIR__ . '/..' . '/symfony/finder/Exception/AdapterFailureException.php',
        'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/finder/Exception/ExceptionInterface.php',
        'Symfony\\Component\\Finder\\Exception\\OperationNotPermitedException' => __DIR__ . '/..' . '/symfony/finder/Exception/OperationNotPermitedException.php',
        'Symfony\\Component\\Finder\\Exception\\ShellCommandFailureException' => __DIR__ . '/..' . '/symfony/finder/Exception/ShellCommandFailureException.php',
        'Symfony\\Component\\Finder\\Expression\\Expression' => __DIR__ . '/..' . '/symfony/finder/Expression/Expression.php',
        'Symfony\\Component\\Finder\\Expression\\Glob' => __DIR__ . '/..' . '/symfony/finder/Expression/Glob.php',
        'Symfony\\Component\\Finder\\Expression\\Regex' => __DIR__ . '/..' . '/symfony/finder/Expression/Regex.php',
        'Symfony\\Component\\Finder\\Expression\\ValueInterface' => __DIR__ . '/..' . '/symfony/finder/Expression/ValueInterface.php',
        'Symfony\\Component\\Finder\\Finder' => __DIR__ . '/..' . '/symfony/finder/Finder.php',
        'Symfony\\Component\\Finder\\Glob' => __DIR__ . '/..' . '/symfony/finder/Glob.php',
        'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/CustomFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/DateRangeFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/DepthRangeFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\FilePathsIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilePathsIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FileTypeFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilecontentFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilenameFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/FilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/PathFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SizeRangeFilterIterator.php',
        'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => __DIR__ . '/..' . '/symfony/finder/Iterator/SortableIterator.php',
        'Symfony\\Component\\Finder\\Shell\\Command' => __DIR__ . '/..' . '/symfony/finder/Shell/Command.php',
        'Symfony\\Component\\Finder\\Shell\\Shell' => __DIR__ . '/..' . '/symfony/finder/Shell/Shell.php',
        'Symfony\\Component\\Finder\\SplFileInfo' => __DIR__ . '/..' . '/symfony/finder/SplFileInfo.php',
        'Symfony\\Component\\Yaml\\Command\\LintCommand' => __DIR__ . '/..' . '/symfony/yaml/Command/LintCommand.php',
        'Symfony\\Component\\Yaml\\Dumper' => __DIR__ . '/..' . '/symfony/yaml/Dumper.php',
        'Symfony\\Component\\Yaml\\Escaper' => __DIR__ . '/..' . '/symfony/yaml/Escaper.php',
        'Symfony\\Component\\Yaml\\Exception\\DumpException' => __DIR__ . '/..' . '/symfony/yaml/Exception/DumpException.php',
        'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/yaml/Exception/ExceptionInterface.php',
        'Symfony\\Component\\Yaml\\Exception\\ParseException' => __DIR__ . '/..' . '/symfony/yaml/Exception/ParseException.php',
        'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/yaml/Exception/RuntimeException.php',
        'Symfony\\Component\\Yaml\\Inline' => __DIR__ . '/..' . '/symfony/yaml/Inline.php',
        'Symfony\\Component\\Yaml\\Parser' => __DIR__ . '/..' . '/symfony/yaml/Parser.php',
        'Symfony\\Component\\Yaml\\Tag\\TaggedValue' => __DIR__ . '/..' . '/symfony/yaml/Tag/TaggedValue.php',
        'Symfony\\Component\\Yaml\\Unescaper' => __DIR__ . '/..' . '/symfony/yaml/Unescaper.php',
        'Symfony\\Component\\Yaml\\Yaml' => __DIR__ . '/..' . '/symfony/yaml/Yaml.php',
        'Symfony\\Polyfill\\Apcu\\Apcu' => __DIR__ . '/..' . '/symfony/polyfill-apcu/Apcu.php',
        'Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php',
        'Twig\\Cache\\CacheInterface' => __DIR__ . '/..' . '/twig/twig/src/Cache/CacheInterface.php',
        'Twig\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/FilesystemCache.php',
        'Twig\\Cache\\NullCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/NullCache.php',
        'Twig\\Compiler' => __DIR__ . '/..' . '/twig/twig/src/Compiler.php',
        'Twig\\Environment' => __DIR__ . '/..' . '/twig/twig/src/Environment.php',
        'Twig\\Error\\Error' => __DIR__ . '/..' . '/twig/twig/src/Error/Error.php',
        'Twig\\Error\\LoaderError' => __DIR__ . '/..' . '/twig/twig/src/Error/LoaderError.php',
        'Twig\\Error\\RuntimeError' => __DIR__ . '/..' . '/twig/twig/src/Error/RuntimeError.php',
        'Twig\\Error\\SyntaxError' => __DIR__ . '/..' . '/twig/twig/src/Error/SyntaxError.php',
        'Twig\\ExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser.php',
        'Twig\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/AbstractExtension.php',
        'Twig\\Extension\\CoreExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/CoreExtension.php',
        'Twig\\Extension\\DebugExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/DebugExtension.php',
        'Twig\\Extension\\EscaperExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/EscaperExtension.php',
        'Twig\\Extension\\ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/ExtensionInterface.php',
        'Twig\\Extension\\GlobalsInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/GlobalsInterface.php',
        'Twig\\Extension\\InitRuntimeInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/InitRuntimeInterface.php',
        'Twig\\Extension\\OptimizerExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/OptimizerExtension.php',
        'Twig\\Extension\\ProfilerExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/ProfilerExtension.php',
        'Twig\\Extension\\RuntimeExtensionInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/RuntimeExtensionInterface.php',
        'Twig\\Extension\\SandboxExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/SandboxExtension.php',
        'Twig\\Extension\\StagingExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/StagingExtension.php',
        'Twig\\Extension\\StringLoaderExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/StringLoaderExtension.php',
        'Twig\\FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/src/FileExtensionEscapingStrategy.php',
        'Twig\\Lexer' => __DIR__ . '/..' . '/twig/twig/src/Lexer.php',
        'Twig\\Loader\\ArrayLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/ArrayLoader.php',
        'Twig\\Loader\\ChainLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/ChainLoader.php',
        'Twig\\Loader\\ExistsLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/ExistsLoaderInterface.php',
        'Twig\\Loader\\FilesystemLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/FilesystemLoader.php',
        'Twig\\Loader\\LoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/LoaderInterface.php',
        'Twig\\Loader\\SourceContextLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/SourceContextLoaderInterface.php',
        'Twig\\Markup' => __DIR__ . '/..' . '/twig/twig/src/Markup.php',
        'Twig\\NodeTraverser' => __DIR__ . '/..' . '/twig/twig/src/NodeTraverser.php',
        'Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
        'Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
        'Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
        'Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
        'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
        'Twig\\NodeVisitor\\SandboxNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php',
        'Twig\\Node\\AutoEscapeNode' => __DIR__ . '/..' . '/twig/twig/src/Node/AutoEscapeNode.php',
        'Twig\\Node\\BlockNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockNode.php',
        'Twig\\Node\\BlockReferenceNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockReferenceNode.php',
        'Twig\\Node\\BodyNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BodyNode.php',
        'Twig\\Node\\CheckSecurityCallNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityCallNode.php',
        'Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityNode.php',
        'Twig\\Node\\CheckToStringNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckToStringNode.php',
        'Twig\\Node\\DeprecatedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DeprecatedNode.php',
        'Twig\\Node\\DoNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DoNode.php',
        'Twig\\Node\\EmbedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/EmbedNode.php',
        'Twig\\Node\\Expression\\AbstractExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/AbstractExpression.php',
        'Twig\\Node\\Expression\\ArrayExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ArrayExpression.php',
        'Twig\\Node\\Expression\\ArrowFunctionExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ArrowFunctionExpression.php',
        'Twig\\Node\\Expression\\AssignNameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/AssignNameExpression.php',
        'Twig\\Node\\Expression\\Binary\\AbstractBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AbstractBinary.php',
        'Twig\\Node\\Expression\\Binary\\AddBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AddBinary.php',
        'Twig\\Node\\Expression\\Binary\\AndBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AndBinary.php',
        'Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
        'Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
        'Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
        'Twig\\Node\\Expression\\Binary\\ConcatBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ConcatBinary.php',
        'Twig\\Node\\Expression\\Binary\\DivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/DivBinary.php',
        'Twig\\Node\\Expression\\Binary\\EndsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php',
        'Twig\\Node\\Expression\\Binary\\EqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/EqualBinary.php',
        'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
        'Twig\\Node\\Expression\\Binary\\GreaterBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
        'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
        'Twig\\Node\\Expression\\Binary\\InBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
        'Twig\\Node\\Expression\\Binary\\LessBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
        'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
        'Twig\\Node\\Expression\\Binary\\MatchesBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MatchesBinary.php',
        'Twig\\Node\\Expression\\Binary\\ModBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ModBinary.php',
        'Twig\\Node\\Expression\\Binary\\MulBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MulBinary.php',
        'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php',
        'Twig\\Node\\Expression\\Binary\\NotInBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php',
        'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
        'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
        'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
        'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
        'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
        'Twig\\Node\\Expression\\BlockReferenceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
        'Twig\\Node\\Expression\\CallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/CallExpression.php',
        'Twig\\Node\\Expression\\ConditionalExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConditionalExpression.php',
        'Twig\\Node\\Expression\\ConstantExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConstantExpression.php',
        'Twig\\Node\\Expression\\FilterExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FilterExpression.php',
        'Twig\\Node\\Expression\\Filter\\DefaultFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php',
        'Twig\\Node\\Expression\\FunctionExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FunctionExpression.php',
        'Twig\\Node\\Expression\\GetAttrExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/GetAttrExpression.php',
        'Twig\\Node\\Expression\\InlinePrint' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/InlinePrint.php',
        'Twig\\Node\\Expression\\MethodCallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/MethodCallExpression.php',
        'Twig\\Node\\Expression\\NameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/NameExpression.php',
        'Twig\\Node\\Expression\\NullCoalesceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/NullCoalesceExpression.php',
        'Twig\\Node\\Expression\\ParentExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ParentExpression.php',
        'Twig\\Node\\Expression\\TempNameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/TempNameExpression.php',
        'Twig\\Node\\Expression\\TestExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/TestExpression.php',
        'Twig\\Node\\Expression\\Unary\\AbstractUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/AbstractUnary.php',
        'Twig\\Node\\Expression\\Unary\\NegUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
        'Twig\\Node\\Expression\\Unary\\NotUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
        'Twig\\Node\\Expression\\Unary\\PosUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
        'Twig\\Node\\FlushNode' => __DIR__ . '/..' . '/twig/twig/src/Node/FlushNode.php',
        'Twig\\Node\\ForLoopNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForLoopNode.php',
        'Twig\\Node\\ForNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForNode.php',
        'Twig\\Node\\IfNode' => __DIR__ . '/..' . '/twig/twig/src/Node/IfNode.php',
        'Twig\\Node\\ImportNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ImportNode.php',
        'Twig\\Node\\IncludeNode' => __DIR__ . '/..' . '/twig/twig/src/Node/IncludeNode.php',
        'Twig\\Node\\MacroNode' => __DIR__ . '/..' . '/twig/twig/src/Node/MacroNode.php',
        'Twig\\Node\\ModuleNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ModuleNode.php',
        'Twig\\Node\\Node' => __DIR__ . '/..' . '/twig/twig/src/Node/Node.php',
        'Twig\\Node\\NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/NodeCaptureInterface.php',
        'Twig\\Node\\NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/NodeOutputInterface.php',
        'Twig\\Node\\PrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/PrintNode.php',
        'Twig\\Node\\SandboxNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxNode.php',
        'Twig\\Node\\SandboxedPrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxedPrintNode.php',
        'Twig\\Node\\SetNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetNode.php',
        'Twig\\Node\\SetTempNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetTempNode.php',
        'Twig\\Node\\SpacelessNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SpacelessNode.php',
        'Twig\\Node\\TextNode' => __DIR__ . '/..' . '/twig/twig/src/Node/TextNode.php',
        'Twig\\Node\\WithNode' => __DIR__ . '/..' . '/twig/twig/src/Node/WithNode.php',
        'Twig\\Parser' => __DIR__ . '/..' . '/twig/twig/src/Parser.php',
        'Twig\\Profiler\\Dumper\\BaseDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/BaseDumper.php',
        'Twig\\Profiler\\Dumper\\BlackfireDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/BlackfireDumper.php',
        'Twig\\Profiler\\Dumper\\HtmlDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/HtmlDumper.php',
        'Twig\\Profiler\\Dumper\\TextDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/TextDumper.php',
        'Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
        'Twig\\Profiler\\Node\\EnterProfileNode' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Node/EnterProfileNode.php',
        'Twig\\Profiler\\Node\\LeaveProfileNode' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Node/LeaveProfileNode.php',
        'Twig\\Profiler\\Profile' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Profile.php',
        'Twig\\RuntimeLoader\\ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
        'Twig\\RuntimeLoader\\FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
        'Twig\\RuntimeLoader\\RuntimeLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
        'Twig\\Sandbox\\SecurityError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityError.php',
        'Twig\\Sandbox\\SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
        'Twig\\Sandbox\\SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
        'Twig\\Sandbox\\SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
        'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
        'Twig\\Sandbox\\SecurityNotAllowedTagError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php',
        'Twig\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicy.php',
        'Twig\\Sandbox\\SecurityPolicyInterface' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php',
        'Twig\\Source' => __DIR__ . '/..' . '/twig/twig/src/Source.php',
        'Twig\\Template' => __DIR__ . '/..' . '/twig/twig/src/Template.php',
        'Twig\\TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/src/TemplateWrapper.php',
        'Twig\\Token' => __DIR__ . '/..' . '/twig/twig/src/Token.php',
        'Twig\\TokenParser\\AbstractTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
        'Twig\\TokenParser\\ApplyTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ApplyTokenParser.php',
        'Twig\\TokenParser\\AutoEscapeTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AutoEscapeTokenParser.php',
        'Twig\\TokenParser\\BlockTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/BlockTokenParser.php',
        'Twig\\TokenParser\\DeprecatedTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/DeprecatedTokenParser.php',
        'Twig\\TokenParser\\DoTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/DoTokenParser.php',
        'Twig\\TokenParser\\EmbedTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/EmbedTokenParser.php',
        'Twig\\TokenParser\\ExtendsTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ExtendsTokenParser.php',
        'Twig\\TokenParser\\FilterTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FilterTokenParser.php',
        'Twig\\TokenParser\\FlushTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FlushTokenParser.php',
        'Twig\\TokenParser\\ForTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ForTokenParser.php',
        'Twig\\TokenParser\\FromTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FromTokenParser.php',
        'Twig\\TokenParser\\IfTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/IfTokenParser.php',
        'Twig\\TokenParser\\ImportTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ImportTokenParser.php',
        'Twig\\TokenParser\\IncludeTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/IncludeTokenParser.php',
        'Twig\\TokenParser\\MacroTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/MacroTokenParser.php',
        'Twig\\TokenParser\\SandboxTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SandboxTokenParser.php',
        'Twig\\TokenParser\\SetTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SetTokenParser.php',
        'Twig\\TokenParser\\SpacelessTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SpacelessTokenParser.php',
        'Twig\\TokenParser\\TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/TokenParserInterface.php',
        'Twig\\TokenParser\\UseTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/UseTokenParser.php',
        'Twig\\TokenParser\\WithTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/WithTokenParser.php',
        'Twig\\TokenStream' => __DIR__ . '/..' . '/twig/twig/src/TokenStream.php',
        'Twig\\TwigFilter' => __DIR__ . '/..' . '/twig/twig/src/TwigFilter.php',
        'Twig\\TwigFunction' => __DIR__ . '/..' . '/twig/twig/src/TwigFunction.php',
        'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php',
        'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php',
        'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
        'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
        'Twig_CacheInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CacheInterface.php',
        'Twig_Cache_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Filesystem.php',
        'Twig_Cache_Null' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Null.php',
        'Twig_Compiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Compiler.php',
        'Twig_CompilerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CompilerInterface.php',
        'Twig_ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
        'Twig_Environment' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Environment.php',
        'Twig_Error' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error.php',
        'Twig_Error_Loader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error/Loader.php',
        'Twig_Error_Runtime' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error/Runtime.php',
        'Twig_Error_Syntax' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error/Syntax.php',
        'Twig_ExistsLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExistsLoaderInterface.php',
        'Twig_ExpressionParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExpressionParser.php',
        'Twig_Extension' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension.php',
        'Twig_ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExtensionInterface.php',
        'Twig_Extension_Core' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Core.php',
        'Twig_Extension_Debug' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Debug.php',
        'Twig_Extension_Escaper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Escaper.php',
        'Twig_Extension_GlobalsInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/GlobalsInterface.php',
        'Twig_Extension_InitRuntimeInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php',
        'Twig_Extension_Optimizer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Optimizer.php',
        'Twig_Extension_Profiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Profiler.php',
        'Twig_Extension_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Sandbox.php',
        'Twig_Extension_Staging' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Staging.php',
        'Twig_Extension_StringLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/StringLoader.php',
        'Twig_FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
        'Twig_FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
        'Twig_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter.php',
        'Twig_FilterCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FilterCallableInterface.php',
        'Twig_FilterInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FilterInterface.php',
        'Twig_Filter_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Function.php',
        'Twig_Filter_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Method.php',
        'Twig_Filter_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Node.php',
        'Twig_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function.php',
        'Twig_FunctionCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
        'Twig_FunctionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FunctionInterface.php',
        'Twig_Function_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Function.php',
        'Twig_Function_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Method.php',
        'Twig_Function_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Node.php',
        'Twig_Lexer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Lexer.php',
        'Twig_LexerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LexerInterface.php',
        'Twig_LoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LoaderInterface.php',
        'Twig_Loader_Array' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Array.php',
        'Twig_Loader_Chain' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Chain.php',
        'Twig_Loader_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Filesystem.php',
        'Twig_Loader_String' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/String.php',
        'Twig_Markup' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Markup.php',
        'Twig_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node.php',
        'Twig_NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
        'Twig_NodeInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeInterface.php',
        'Twig_NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeOutputInterface.php',
        'Twig_NodeTraverser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeTraverser.php',
        'Twig_NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
        'Twig_NodeVisitor_Escaper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/Escaper.php',
        'Twig_NodeVisitor_Optimizer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/Optimizer.php',
        'Twig_NodeVisitor_SafeAnalysis' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
        'Twig_NodeVisitor_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/Sandbox.php',
        'Twig_Node_AutoEscape' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/AutoEscape.php',
        'Twig_Node_Block' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Block.php',
        'Twig_Node_BlockReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/BlockReference.php',
        'Twig_Node_Body' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Body.php',
        'Twig_Node_CheckSecurity' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/CheckSecurity.php',
        'Twig_Node_Deprecated' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Deprecated.php',
        'Twig_Node_Do' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Do.php',
        'Twig_Node_Embed' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Embed.php',
        'Twig_Node_Expression' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression.php',
        'Twig_Node_Expression_Array' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Array.php',
        'Twig_Node_Expression_AssignName' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/AssignName.php',
        'Twig_Node_Expression_Binary' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary.php',
        'Twig_Node_Expression_Binary_Add' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Add.php',
        'Twig_Node_Expression_Binary_And' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/And.php',
        'Twig_Node_Expression_Binary_BitwiseAnd' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
        'Twig_Node_Expression_Binary_BitwiseOr' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
        'Twig_Node_Expression_Binary_BitwiseXor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
        'Twig_Node_Expression_Binary_Concat' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php',
        'Twig_Node_Expression_Binary_Div' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Div.php',
        'Twig_Node_Expression_Binary_EndsWith' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
        'Twig_Node_Expression_Binary_Equal' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php',
        'Twig_Node_Expression_Binary_FloorDiv' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
        'Twig_Node_Expression_Binary_Greater' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php',
        'Twig_Node_Expression_Binary_GreaterEqual' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
        'Twig_Node_Expression_Binary_In' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/In.php',
        'Twig_Node_Expression_Binary_Less' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Less.php',
        'Twig_Node_Expression_Binary_LessEqual' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
        'Twig_Node_Expression_Binary_Matches' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php',
        'Twig_Node_Expression_Binary_Mod' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php',
        'Twig_Node_Expression_Binary_Mul' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php',
        'Twig_Node_Expression_Binary_NotEqual' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
        'Twig_Node_Expression_Binary_NotIn' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
        'Twig_Node_Expression_Binary_Or' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Or.php',
        'Twig_Node_Expression_Binary_Power' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Power.php',
        'Twig_Node_Expression_Binary_Range' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Range.php',
        'Twig_Node_Expression_Binary_StartsWith' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
        'Twig_Node_Expression_Binary_Sub' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php',
        'Twig_Node_Expression_BlockReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/BlockReference.php',
        'Twig_Node_Expression_Call' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Call.php',
        'Twig_Node_Expression_Conditional' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
        'Twig_Node_Expression_Constant' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
        'Twig_Node_Expression_ExtensionReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
        'Twig_Node_Expression_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
        'Twig_Node_Expression_Filter_Default' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
        'Twig_Node_Expression_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Function.php',
        'Twig_Node_Expression_GetAttr' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/GetAttr.php',
        'Twig_Node_Expression_MethodCall' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/MethodCall.php',
        'Twig_Node_Expression_Name' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Name.php',
        'Twig_Node_Expression_NullCoalesce' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php',
        'Twig_Node_Expression_Parent' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Parent.php',
        'Twig_Node_Expression_TempName' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/TempName.php',
        'Twig_Node_Expression_Unary' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary.php',
        'Twig_Node_Expression_Unary_Neg' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php',
        'Twig_Node_Expression_Unary_Not' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary/Not.php',
        'Twig_Node_Expression_Unary_Pos' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php',
        'Twig_Node_Flush' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Flush.php',
        'Twig_Node_For' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/For.php',
        'Twig_Node_ForLoop' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/ForLoop.php',
        'Twig_Node_If' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/If.php',
        'Twig_Node_Import' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Import.php',
        'Twig_Node_Include' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Include.php',
        'Twig_Node_Macro' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Macro.php',
        'Twig_Node_Module' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Module.php',
        'Twig_Node_Print' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Print.php',
        'Twig_Node_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Sandbox.php',
        'Twig_Node_SandboxedPrint' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
        'Twig_Node_Set' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Set.php',
        'Twig_Node_SetTemp' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SetTemp.php',
        'Twig_Node_Spaceless' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Spaceless.php',
        'Twig_Node_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Text.php',
        'Twig_Node_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/With.php',
        'Twig_Parser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Parser.php',
        'Twig_ParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ParserInterface.php',
        'Twig_Profiler_Dumper_Base' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
        'Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
        'Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
        'Twig_Profiler_Dumper_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
        'Twig_Profiler_NodeVisitor_Profiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
        'Twig_Profiler_Node_EnterProfile' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php',
        'Twig_Profiler_Node_LeaveProfile' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
        'Twig_Profiler_Profile' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Profile.php',
        'Twig_RuntimeLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/RuntimeLoaderInterface.php',
        'Twig_Sandbox_SecurityError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityError.php',
        'Twig_Sandbox_SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
        'Twig_Sandbox_SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
        'Twig_Sandbox_SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
        'Twig_Sandbox_SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
        'Twig_Sandbox_SecurityNotAllowedTagError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
        'Twig_Sandbox_SecurityPolicy' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php',
        'Twig_Sandbox_SecurityPolicyInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
        'Twig_SimpleFilter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SimpleFilter.php',
        'Twig_SimpleFunction' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SimpleFunction.php',
        'Twig_Source' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Source.php',
        'Twig_SourceContextLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
        'Twig_Template' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Template.php',
        'Twig_TemplateInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateInterface.php',
        'Twig_TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateWrapper.php',
        'Twig_TestCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestCallableInterface.php',
        'Twig_TestInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestInterface.php',
        'Twig_Token' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Token.php',
        'Twig_TokenParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser.php',
        'Twig_TokenParserBroker' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBroker.php',
        'Twig_TokenParserBrokerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
        'Twig_TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserInterface.php',
        'Twig_TokenParser_AutoEscape' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
        'Twig_TokenParser_Block' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Block.php',
        'Twig_TokenParser_Deprecated' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Deprecated.php',
        'Twig_TokenParser_Do' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Do.php',
        'Twig_TokenParser_Embed' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Embed.php',
        'Twig_TokenParser_Extends' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Extends.php',
        'Twig_TokenParser_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Filter.php',
        'Twig_TokenParser_Flush' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Flush.php',
        'Twig_TokenParser_For' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/For.php',
        'Twig_TokenParser_From' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/From.php',
        'Twig_TokenParser_If' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/If.php',
        'Twig_TokenParser_Import' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Import.php',
        'Twig_TokenParser_Include' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Include.php',
        'Twig_TokenParser_Macro' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Macro.php',
        'Twig_TokenParser_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Sandbox.php',
        'Twig_TokenParser_Set' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Set.php',
        'Twig_TokenParser_Spaceless' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Spaceless.php',
        'Twig_TokenParser_Use' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Use.php',
        'Twig_TokenParser_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/With.php',
        'Twig_TokenStream' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenStream.php',
        'Twig_Util_DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Util/DeprecationCollector.php',
        'Twig_Util_TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Util/TemplateDirIterator.php',
        'Universal\\ClassLoader\\ApcClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/ApcClassLoader.php',
        'Universal\\ClassLoader\\BasePathClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/BasePathClassLoader.php',
        'Universal\\ClassLoader\\BytecodeClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/BytecodeClassLoader.php',
        'Universal\\ClassLoader\\ChainedClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/ChainedClassLoader.php',
        'Universal\\ClassLoader\\ClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/ClassLoader.php',
        'Universal\\ClassLoader\\MapClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/MapClassLoader.php',
        'Universal\\ClassLoader\\PathIncluder' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/PathIncluder.php',
        'Universal\\ClassLoader\\Psr0ClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/Psr0ClassLoader.php',
        'Universal\\ClassLoader\\Psr4ClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/Psr4ClassLoader.php',
        'Universal\\ClassLoader\\SplClassLoader' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/ClassLoader/SplClassLoader.php',
        'Universal\\Container\\ObjectContainer' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Container/ObjectContainer.php',
        'Universal\\Event\\PhpEvent' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Event/PhpEvent.php',
        'Universal\\Exception\\InvalidUploadFileException' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Exception/InvalidUploadFileException.php',
        'Universal\\Exception\\UploadErrorException' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Exception/UploadErrorException.php',
        'Universal\\Exception\\UploadException' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Exception/UploadException.php',
        'Universal\\Exception\\UploadedFileMoveFailException' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Exception/UploadedFileMoveFailException.php',
        'Universal\\FileSystem\\PathUtils' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/FileSystem/PathUtils.php',
        'Universal\\Http\\Cookie' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/Cookie.php',
        'Universal\\Http\\FilesParameter' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/FilesParameter.php',
        'Universal\\Http\\HttpRequest' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/HttpRequest.php',
        'Universal\\Http\\HttpResponse' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/HttpResponse.php',
        'Universal\\Http\\Parameter' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/Parameter.php',
        'Universal\\Http\\PutHandle' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/PutHandle.php',
        'Universal\\Http\\StreamResponse' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/StreamResponse.php',
        'Universal\\Http\\UploadedFile' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Http/UploadedFile.php',
        'Universal\\Requirement\\Requirement' => __DIR__ . '/..' . '/corneltek/universal/src/Universal/Requirement/Requirement.php',
    );

    public static function getInitializer(ClassLoader $loader)
    {
        return \Closure::bind(function () use ($loader) {
            $loader->prefixLengthsPsr4 = ComposerStaticInit365e25e34522fee120bee0a71e662cb3::$prefixLengthsPsr4;
            $loader->prefixDirsPsr4 = ComposerStaticInit365e25e34522fee120bee0a71e662cb3::$prefixDirsPsr4;
            $loader->prefixesPsr0 = ComposerStaticInit365e25e34522fee120bee0a71e662cb3::$prefixesPsr0;
            $loader->classMap = ComposerStaticInit365e25e34522fee120bee0a71e662cb3::$classMap;

        }, null, ClassLoader::class);
    }
}
<?php return array(
'root' => array(
'name' => 'phpbrew/phpbrew',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '8f386dc86865f9060feb550a5d93c3791c841f81',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(
0 => '2.0.x-dev',
),
'dev' => true,
),
'versions' => array(
'beberlei/assert' => array(
'pretty_version' => 'v3.3.2',
'version' => '3.3.2.0',
'reference' => 'cb70015c04be1baee6f5f5c953703347c0ac1655',
'type' => 'library',
'install_path' => __DIR__ . '/../beberlei/assert',
'aliases' => array(),
'dev_requirement' => true,
),
'corneltek/class-template' => array(
'pretty_version' => '2.1.2',
'version' => '2.1.2.0',
'reference' => '4bdb46a6b1a5245118e7bf08b4cdacdfdaadb77b',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/class-template',
'aliases' => array(),
'dev_requirement' => false,
),
'corneltek/cliframework' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => '01cee2d491085cfae63c677611b5e4604624771e',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/cliframework',
'aliases' => array(),
'dev_requirement' => false,
),
'corneltek/codegen' => array(
'pretty_version' => '2.7.1',
'version' => '2.7.1.0',
'reference' => '265b089d07e73ebd1a4057a1e760ae519969e245',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/codegen',
'aliases' => array(),
'dev_requirement' => false,
),
'corneltek/curlkit' => array(
'pretty_version' => '1.0.11',
'version' => '1.0.11.0',
'reference' => '5f0765bd6e81d66ec6f71d24c6312a1509e65c5f',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/curlkit',
'aliases' => array(),
'dev_requirement' => false,
),
'corneltek/getoptionkit' => array(
'pretty_version' => '2.7.2',
'version' => '2.7.2.0',
'reference' => 'aab2728de80175217cab0d7a4d078c3eb907e2c0',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/getoptionkit',
'aliases' => array(),
'dev_requirement' => false,
),
'corneltek/pearx' => array(
'pretty_version' => '1.3.5',
'version' => '1.3.5.0',
'reference' => '2c5b5da4abd46bae9585f0f4ceeeaad2651e5cf6',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/pearx',
'aliases' => array(),
'dev_requirement' => false,
),
'corneltek/universal' => array(
'pretty_version' => '1.8.0',
'version' => '1.8.0.0',
'reference' => '7b69d656be18d6b1d01a5a672141c80b43b5c2f3',
'type' => 'library',
'install_path' => __DIR__ . '/../corneltek/universal',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/inflector' => array(
'pretty_version' => '2.0.6',
'version' => '2.0.6.0',
'reference' => 'd9d313a36c872fd6ee06d9a6cbcf713eaa40f024',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/inflector',
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/instantiator' => array(
'pretty_version' => '1.4.1',
'version' => '1.4.1.0',
'reference' => '10dcfce151b967d20fde1b34ae6640712c3891bc',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/instantiator',
'aliases' => array(),
'dev_requirement' => true,
),
'myclabs/deep-copy' => array(
'pretty_version' => '1.11.0',
'version' => '1.11.0.0',
'reference' => '14daed4296fae74d9e3201d2c4925d1acb7aa614',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/deep-copy',
'aliases' => array(),
'dev_requirement' => true,
),
'phar-io/manifest' => array(
'pretty_version' => '2.0.3',
'version' => '2.0.3.0',
'reference' => '97803eca37d319dfa7826cc2437fc020857acb53',
'type' => 'library',
'install_path' => __DIR__ . '/../phar-io/manifest',
'aliases' => array(),
'dev_requirement' => true,
),
'phar-io/version' => array(
'pretty_version' => '3.2.1',
'version' => '3.2.1.0',
'reference' => '4f7fd7836c6f332bb2933569e566a0d6c4cbed74',
'type' => 'library',
'install_path' => __DIR__ . '/../phar-io/version',
'aliases' => array(),
'dev_requirement' => true,
),
'php-vcr/php-vcr' => array(
'pretty_version' => '1.5.4',
'version' => '1.5.4.0',
'reference' => '042549510784889e75ca8803d87dcf6b8c6c4681',
'type' => 'library',
'install_path' => __DIR__ . '/../php-vcr/php-vcr',
'aliases' => array(),
'dev_requirement' => true,
),
'phpbrew/phpbrew' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '8f386dc86865f9060feb550a5d93c3791c841f81',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(
0 => '2.0.x-dev',
),
'dev_requirement' => false,
),
'phpunit/php-code-coverage' => array(
'pretty_version' => '7.0.15',
'version' => '7.0.15.0',
'reference' => '819f92bba8b001d4363065928088de22f25a3a48',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-code-coverage',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-file-iterator' => array(
'pretty_version' => '2.0.5',
'version' => '2.0.5.0',
'reference' => '42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-file-iterator',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-text-template' => array(
'pretty_version' => '1.2.1',
'version' => '1.2.1.0',
'reference' => '31f8b717e51d9a2afca6c9f046f5d69fc27c8686',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-text-template',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-timer' => array(
'pretty_version' => '2.1.3',
'version' => '2.1.3.0',
'reference' => '2454ae1765516d20c4ffe103d85a58a9a3bd5662',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-timer',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/php-token-stream' => array(
'pretty_version' => '3.1.3',
'version' => '3.1.3.0',
'reference' => '9c1da83261628cb24b6a6df371b6e312b3954768',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-token-stream',
'aliases' => array(),
'dev_requirement' => true,
),
'phpunit/phpunit' => array(
'pretty_version' => '8.5.31',
'version' => '8.5.31.0',
'reference' => '33c126b09a42de5c99e5e8032b54e8221264a74e',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/phpunit',
'aliases' => array(),
'dev_requirement' => true,
),
'pimple/pimple' => array(
'pretty_version' => 'v3.5.0',
'version' => '3.5.0.0',
'reference' => 'a94b3a4db7fb774b3d78dad2315ddc07629e1bed',
'type' => 'library',
'install_path' => __DIR__ . '/../pimple/pimple',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/container' => array(
'pretty_version' => '2.0.1',
'version' => '2.0.1.0',
'reference' => '2ae37329ee82f91efadc282cc2d527fd6065a5ef',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/container',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/event-dispatcher' => array(
'pretty_version' => '1.0.0',
'version' => '1.0.0.0',
'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/event-dispatcher',
'aliases' => array(),
'dev_requirement' => true,
),
'psr/event-dispatcher-implementation' => array(
'dev_requirement' => true,
'provided' => array(
0 => '1.0',
),
),
'sebastian/code-unit-reverse-lookup' => array(
'pretty_version' => '1.0.2',
'version' => '1.0.2.0',
'reference' => '1de8cd5c010cb153fcd68b8d0f64606f523f7619',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/code-unit-reverse-lookup',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/comparator' => array(
'pretty_version' => '3.0.5',
'version' => '3.0.5.0',
'reference' => '1dc7ceb4a24aede938c7af2a9ed1de09609ca770',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/comparator',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/diff' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
'reference' => '14f72dd46eaf2f2293cbe79c93cc0bc43161a211',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/diff',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/environment' => array(
'pretty_version' => '4.2.4',
'version' => '4.2.4.0',
'reference' => 'd47bbbad83711771f167c72d4e3f25f7fcc1f8b0',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/environment',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/exporter' => array(
'pretty_version' => '3.1.5',
'version' => '3.1.5.0',
'reference' => '73a9676f2833b9a7c36968f9d882589cd75511e6',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/exporter',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/global-state' => array(
'pretty_version' => '3.0.2',
'version' => '3.0.2.0',
'reference' => 'de036ec91d55d2a9e0db2ba975b512cdb1c23921',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/global-state',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/object-enumerator' => array(
'pretty_version' => '3.0.4',
'version' => '3.0.4.0',
'reference' => 'e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/object-enumerator',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/object-reflector' => array(
'pretty_version' => '1.1.2',
'version' => '1.1.2.0',
'reference' => '9b8772b9cbd456ab45d4a598d2dd1a1bced6363d',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/object-reflector',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/recursion-context' => array(
'pretty_version' => '3.0.1',
'version' => '3.0.1.0',
'reference' => '367dcba38d6e1977be014dc4b22f47a484dac7fb',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/recursion-context',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/resource-operations' => array(
'pretty_version' => '2.0.2',
'version' => '2.0.2.0',
'reference' => '31d35ca87926450c44eae7e2611d45a7a65ea8b3',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/resource-operations',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/type' => array(
'pretty_version' => '1.1.4',
'version' => '1.1.4.0',
'reference' => '0150cfbc4495ed2df3872fb31b26781e4e077eb4',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/type',
'aliases' => array(),
'dev_requirement' => true,
),
'sebastian/version' => array(
'pretty_version' => '2.0.1',
'version' => '2.0.1.0',
'reference' => '99732be0ddb3361e16ad77b68ba41efc8e979019',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/version',
'aliases' => array(),
'dev_requirement' => true,
),
'symfony/class-loader' => array(
'pretty_version' => 'v2.8.52',
'version' => '2.8.52.0',
'reference' => '8194721a1e2768cfb95079581889c41eec7a5959',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/class-loader',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/deprecation-contracts' => array(
'pretty_version' => 'v2.5.2',
'version' => '2.5.2.0',
'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/event-dispatcher' => array(
'pretty_version' => 'v5.4.9',
'version' => '5.4.9.0',
'reference' => '8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(),
'dev_requirement' => true,
),
'symfony/event-dispatcher-contracts' => array(
'pretty_version' => 'v2.5.2',
'version' => '2.5.2.0',
'reference' => 'f98b54df6ad059855739db6fcbc2d36995283fe1',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
'aliases' => array(),
'dev_requirement' => true,
),
'symfony/event-dispatcher-implementation' => array(
'dev_requirement' => true,
'provided' => array(
0 => '2.0',
),
),
'symfony/finder' => array(
'pretty_version' => 'v2.8.52',
'version' => '2.8.52.0',
'reference' => '1444eac52273e345d9b95129bf914639305a9ba4',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/finder',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-apcu' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '6e7f6ed2168779a2b3927e606a9768860a8bdfa0',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-apcu',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.27.0',
'version' => '1.27.0.0',
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'dev_requirement' => true,
),
'symfony/yaml' => array(
'pretty_version' => 'v5.4.16',
'version' => '5.4.16.0',
'reference' => 'ebd37c71f62d5ec5f6e27de3e06fee492d4c6298',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/yaml',
'aliases' => array(),
'dev_requirement' => false,
),
'theseer/tokenizer' => array(
'pretty_version' => '1.2.1',
'version' => '1.2.1.0',
'reference' => '34a41e998c2183e22995f158c581e7b5e755ab9e',
'type' => 'library',
'install_path' => __DIR__ . '/../theseer/tokenizer',
'aliases' => array(),
'dev_requirement' => true,
),
'twig/twig' => array(
'pretty_version' => 'v1.44.7',
'version' => '1.44.7.0',
'reference' => '0887422319889e442458e48e2f3d9add1a172ad5',
'type' => 'library',
'install_path' => __DIR__ . '/../twig/twig',
'aliases' => array(),
'dev_requirement' => false,
),
),
);
<?php

// autoload_namespaces.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'Twig_' => array($vendorDir . '/twig/twig/lib'),
    'Pimple' => array($vendorDir . '/pimple/pimple/src'),
);
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Autoload;

/**
 * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 *
 *     $loader = new \Composer\Autoload\ClassLoader();
 *
 *     // register classes with namespaces
 *     $loader->add('Symfony\Component', __DIR__.'/component');
 *     $loader->add('Symfony',           __DIR__.'/framework');
 *
 *     // activate the autoloader
 *     $loader->register();
 *
 *     // to enable searching the include path (eg. for PEAR packages)
 *     $loader->setUseIncludePath(true);
 *
 * In this example, if you try to use a class in the Symfony\Component
 * namespace or one of its children (Symfony\Component\Console for instance),
 * the autoloader will first look for the class under the component/
 * directory, and it will then fallback to the framework/ directory if not
 * found before giving up.
 *
 * This class is loosely based on the Symfony UniversalClassLoader.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @see    https://www.php-fig.org/psr/psr-0/
 * @see    https://www.php-fig.org/psr/psr-4/
 */
class ClassLoader
{
    /** @var ?string */
    private $vendorDir;

    // PSR-4
    /**
     * @var array[]
     * @psalm-var array<string, array<string, int>>
     */
    private $prefixLengthsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, array<int, string>>
     */
    private $prefixDirsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr4 = array();

    // PSR-0
    /**
     * @var array[]
     * @psalm-var array<string, array<string, string[]>>
     */
    private $prefixesPsr0 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr0 = array();

    /** @var bool */
    private $useIncludePath = false;

    /**
     * @var string[]
     * @psalm-var array<string, string>
     */
    private $classMap = array();

    /** @var bool */
    private $classMapAuthoritative = false;

    /**
     * @var bool[]
     * @psalm-var array<string, bool>
     */
    private $missingClasses = array();

    /** @var ?string */
    private $apcuPrefix;

    /**
     * @var self[]
     */
    private static $registeredLoaders = array();

    /**
     * @param ?string $vendorDir
     */
    public function __construct($vendorDir = null)
    {
        $this->vendorDir = $vendorDir;
    }

    /**
     * @return string[]
     */
    public function getPrefixes()
    {
        if (!empty($this->prefixesPsr0)) {
            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
        }

        return array();
    }

    /**
     * @return array[]
     * @psalm-return array<string, array<int, string>>
     */
    public function getPrefixesPsr4()
    {
        return $this->prefixDirsPsr4;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirs()
    {
        return $this->fallbackDirsPsr0;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirsPsr4()
    {
        return $this->fallbackDirsPsr4;
    }

    /**
     * @return string[] Array of classname => path
     * @psalm-return array<string, string>
     */
    public function getClassMap()
    {
        return $this->classMap;
    }

    /**
     * @param string[] $classMap Class to filename map
     * @psalm-param array<string, string> $classMap
     *
     * @return void
     */
    public function addClassMap(array $classMap)
    {
        if ($this->classMap) {
            $this->classMap = array_merge($this->classMap, $classMap);
        } else {
            $this->classMap = $classMap;
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix, either
     * appending or prepending to the ones previously set for this prefix.
     *
     * @param string          $prefix  The prefix
     * @param string[]|string $paths   The PSR-0 root directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @return void
     */
    public function add($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            if ($prepend) {
                $this->fallbackDirsPsr0 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr0
                );
            } else {
                $this->fallbackDirsPsr0 = array_merge(
                    $this->fallbackDirsPsr0,
                    (array) $paths
                );
            }

            return;
        }

        $first = $prefix[0];
        if (!isset($this->prefixesPsr0[$first][$prefix])) {
            $this->prefixesPsr0[$first][$prefix] = (array) $paths;

            return;
        }
        if ($prepend) {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                (array) $paths,
                $this->prefixesPsr0[$first][$prefix]
            );
        } else {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                $this->prefixesPsr0[$first][$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace, either
     * appending or prepending to the ones previously set for this namespace.
     *
     * @param string          $prefix  The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths   The PSR-4 base directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function addPsr4($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            // Register directories for the root namespace.
            if ($prepend) {
                $this->fallbackDirsPsr4 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr4
                );
            } else {
                $this->fallbackDirsPsr4 = array_merge(
                    $this->fallbackDirsPsr4,
                    (array) $paths
                );
            }
        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
            // Register directories for a new namespace.
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        } elseif ($prepend) {
            // Prepend directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                (array) $paths,
                $this->prefixDirsPsr4[$prefix]
            );
        } else {
            // Append directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                $this->prefixDirsPsr4[$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix,
     * replacing any others previously set for this prefix.
     *
     * @param string          $prefix The prefix
     * @param string[]|string $paths  The PSR-0 base directories
     *
     * @return void
     */
    public function set($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr0 = (array) $paths;
        } else {
            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace,
     * replacing any others previously set for this namespace.
     *
     * @param string          $prefix The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths  The PSR-4 base directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function setPsr4($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr4 = (array) $paths;
        } else {
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        }
    }

    /**
     * Turns on searching the include path for class files.
     *
     * @param bool $useIncludePath
     *
     * @return void
     */
    public function setUseIncludePath($useIncludePath)
    {
        $this->useIncludePath = $useIncludePath;
    }

    /**
     * Can be used to check if the autoloader uses the include path to check
     * for classes.
     *
     * @return bool
     */
    public function getUseIncludePath()
    {
        return $this->useIncludePath;
    }

    /**
     * Turns off searching the prefix and fallback directories for classes
     * that have not been registered with the class map.
     *
     * @param bool $classMapAuthoritative
     *
     * @return void
     */
    public function setClassMapAuthoritative($classMapAuthoritative)
    {
        $this->classMapAuthoritative = $classMapAuthoritative;
    }

    /**
     * Should class lookup fail if not found in the current class map?
     *
     * @return bool
     */
    public function isClassMapAuthoritative()
    {
        return $this->classMapAuthoritative;
    }

    /**
     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
     *
     * @param string|null $apcuPrefix
     *
     * @return void
     */
    public function setApcuPrefix($apcuPrefix)
    {
        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
    }

    /**
     * The APCu prefix in use, or null if APCu caching is not enabled.
     *
     * @return string|null
     */
    public function getApcuPrefix()
    {
        return $this->apcuPrefix;
    }

    /**
     * Registers this instance as an autoloader.
     *
     * @param bool $prepend Whether to prepend the autoloader or not
     *
     * @return void
     */
    public function register($prepend = false)
    {
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);

        if (null === $this->vendorDir) {
            return;
        }

        if ($prepend) {
            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
        } else {
            unset(self::$registeredLoaders[$this->vendorDir]);
            self::$registeredLoaders[$this->vendorDir] = $this;
        }
    }

    /**
     * Unregisters this instance as an autoloader.
     *
     * @return void
     */
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));

        if (null !== $this->vendorDir) {
            unset(self::$registeredLoaders[$this->vendorDir]);
        }
    }

    /**
     * Loads the given class or interface.
     *
     * @param  string    $class The name of the class
     * @return true|null True if loaded, null otherwise
     */
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            includeFile($file);

            return true;
        }

        return null;
    }

    /**
     * Finds the path to the file where the class is defined.
     *
     * @param string $class The name of the class
     *
     * @return string|false The path if found, false otherwise
     */
    public function findFile($class)
    {
        // class map lookup
        if (isset($this->classMap[$class])) {
            return $this->classMap[$class];
        }
        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
            return false;
        }
        if (null !== $this->apcuPrefix) {
            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
            if ($hit) {
                return $file;
            }
        }

        $file = $this->findFileWithExtension($class, '.php');

        // Search for Hack files if we are running on HHVM
        if (false === $file && defined('HHVM_VERSION')) {
            $file = $this->findFileWithExtension($class, '.hh');
        }

        if (null !== $this->apcuPrefix) {
            apcu_add($this->apcuPrefix.$class, $file);
        }

        if (false === $file) {
            // Remember that this class does not exist.
            $this->missingClasses[$class] = true;
        }

        return $file;
    }

    /**
     * Returns the currently registered loaders indexed by their corresponding vendor directories.
     *
     * @return self[]
     */
    public static function getRegisteredLoaders()
    {
        return self::$registeredLoaders;
    }

    /**
     * @param  string       $class
     * @param  string       $ext
     * @return string|false
     */
    private function findFileWithExtension($class, $ext)
    {
        // PSR-4 lookup
        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

        $first = $class[0];
        if (isset($this->prefixLengthsPsr4[$first])) {
            $subPath = $class;
            while (false !== $lastPos = strrpos($subPath, '\\')) {
                $subPath = substr($subPath, 0, $lastPos);
                $search = $subPath . '\\';
                if (isset($this->prefixDirsPsr4[$search])) {
                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
                        if (file_exists($file = $dir . $pathEnd)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-4 fallback dirs
        foreach ($this->fallbackDirsPsr4 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
                return $file;
            }
        }

        // PSR-0 lookup
        if (false !== $pos = strrpos($class, '\\')) {
            // namespaced class name
            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
        } else {
            // PEAR-like class name
            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
        }

        if (isset($this->prefixesPsr0[$first])) {
            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                if (0 === strpos($class, $prefix)) {
                    foreach ($dirs as $dir) {
                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-0 fallback dirs
        foreach ($this->fallbackDirsPsr0 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                return $file;
            }
        }

        // PSR-0 include paths.
        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
            return $file;
        }

        return false;
    }
}

/**
 * Scope isolated include.
 *
 * Prevents access to $this/self from included files.
 *
 * @param  string $file
 * @return void
 * @private
 */
function includeFile($file)
{
    include $file;
}
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'CLIFramework\\Ansi\\Colors' => $vendorDir . '/corneltek/cliframework/src/Ansi/Colors.php',
    'CLIFramework\\Ansi\\CursorControl' => $vendorDir . '/corneltek/cliframework/src/Ansi/CursorControl.php',
    'CLIFramework\\Application' => $vendorDir . '/corneltek/cliframework/src/Application.php',
    'CLIFramework\\ArgInfo' => $vendorDir . '/corneltek/cliframework/src/ArgInfo.php',
    'CLIFramework\\ArgInfoList' => $vendorDir . '/corneltek/cliframework/src/ArgInfoList.php',
    'CLIFramework\\ArgumentEditor\\ArgumentEditor' => $vendorDir . '/corneltek/cliframework/src/ArgumentEditor/ArgumentEditor.php',
    'CLIFramework\\Autoload\\ComposerAutoloadGenerator' => $vendorDir . '/corneltek/cliframework/src/Autoload/ComposerAutoloadGenerator.php',
    'CLIFramework\\Buffer' => $vendorDir . '/corneltek/cliframework/src/Buffer.php',
    'CLIFramework\\ChainedCommand' => $vendorDir . '/corneltek/cliframework/src/ChainedCommand.php',
    'CLIFramework\\Chooser' => $vendorDir . '/corneltek/cliframework/src/Chooser.php',
    'CLIFramework\\Command' => $vendorDir . '/corneltek/cliframework/src/Command.php',
    'CLIFramework\\CommandAutoloader' => $vendorDir . '/corneltek/cliframework/src/CommandAutoloader.php',
    'CLIFramework\\CommandBase' => $vendorDir . '/corneltek/cliframework/src/CommandBase.php',
    'CLIFramework\\CommandException' => $vendorDir . '/corneltek/cliframework/src/CommandException.php',
    'CLIFramework\\CommandGroup' => $vendorDir . '/corneltek/cliframework/src/CommandGroup.php',
    'CLIFramework\\CommandInterface' => $vendorDir . '/corneltek/cliframework/src/CommandInterface.php',
    'CLIFramework\\CommandLoader' => $vendorDir . '/corneltek/cliframework/src/CommandLoader.php',
    'CLIFramework\\Command\\ArchiveCommand' => $vendorDir . '/corneltek/cliframework/src/Command/ArchiveCommand.php',
    'CLIFramework\\Command\\BashCompletionCommand' => $vendorDir . '/corneltek/cliframework/src/Command/BashCompletionCommand.php',
    'CLIFramework\\Command\\BuildGitHubWikiTopicsCommand' => $vendorDir . '/corneltek/cliframework/src/Command/BuildGitHubWikiTopicsCommand.php',
    'CLIFramework\\Command\\CompileCommand' => $vendorDir . '/corneltek/cliframework/src/Command/CompileCommand.php',
    'CLIFramework\\Command\\HelpCommand' => $vendorDir . '/corneltek/cliframework/src/Command/HelpCommand.php',
    'CLIFramework\\Command\\MetaCommand' => $vendorDir . '/corneltek/cliframework/src/Command/MetaCommand.php',
    'CLIFramework\\Command\\ZshCompletionCommand' => $vendorDir . '/corneltek/cliframework/src/Command/ZshCompletionCommand.php',
    'CLIFramework\\CompletionUtils' => $vendorDir . '/corneltek/cliframework/src/CompletionUtils.php',
    'CLIFramework\\Completion\\BashGenerator' => $vendorDir . '/corneltek/cliframework/src/Completion/BashGenerator.php',
    'CLIFramework\\Completion\\Utils' => $vendorDir . '/corneltek/cliframework/src/Completion/Utils.php',
    'CLIFramework\\Completion\\ZshGenerator' => $vendorDir . '/corneltek/cliframework/src/Completion/ZshGenerator.php',
    'CLIFramework\\Component\\Progress\\ETACalculator' => $vendorDir . '/corneltek/cliframework/src/Component/Progress/ETACalculator.php',
    'CLIFramework\\Component\\Progress\\ProgressBar' => $vendorDir . '/corneltek/cliframework/src/Component/Progress/ProgressBar.php',
    'CLIFramework\\Component\\Progress\\ProgressBarStyle' => $vendorDir . '/corneltek/cliframework/src/Component/Progress/ProgressBarStyle.php',
    'CLIFramework\\Component\\Progress\\ProgressReporter' => $vendorDir . '/corneltek/cliframework/src/Component/Progress/ProgressReporter.php',
    'CLIFramework\\Component\\Progress\\ProgressStar' => $vendorDir . '/corneltek/cliframework/src/Component/Progress/ProgressStar.php',
    'CLIFramework\\Component\\Progress\\SharpProgressBarStyle' => $vendorDir . '/corneltek/cliframework/src/Component/Progress/SharpProgressBarStyle.php',
    'CLIFramework\\Component\\Table\\BorderlessTableStyle' => $vendorDir . '/corneltek/cliframework/src/Component/Table/BorderlessTableStyle.php',
    'CLIFramework\\Component\\Table\\CellAttribute' => $vendorDir . '/corneltek/cliframework/src/Component/Table/CellAttribute.php',
    'CLIFramework\\Component\\Table\\CompactTableStyle' => $vendorDir . '/corneltek/cliframework/src/Component/Table/CompactTableStyle.php',
    'CLIFramework\\Component\\Table\\CurrencyFormatCell' => $vendorDir . '/corneltek/cliframework/src/Component/Table/CurrencyFormatCell.php',
    'CLIFramework\\Component\\Table\\DateFormatCell' => $vendorDir . '/corneltek/cliframework/src/Component/Table/DateFormatCell.php',
    'CLIFramework\\Component\\Table\\DurationFormatCell' => $vendorDir . '/corneltek/cliframework/src/Component/Table/DurationFormatCell.php',
    'CLIFramework\\Component\\Table\\MarkdownTableStyle' => $vendorDir . '/corneltek/cliframework/src/Component/Table/MarkdownTableStyle.php',
    'CLIFramework\\Component\\Table\\NumberFormatCell' => $vendorDir . '/corneltek/cliframework/src/Component/Table/NumberFormatCell.php',
    'CLIFramework\\Component\\Table\\SpellOutNumberFormatCell' => $vendorDir . '/corneltek/cliframework/src/Component/Table/SpellOutNumberFormatCell.php',
    'CLIFramework\\Component\\Table\\Table' => $vendorDir . '/corneltek/cliframework/src/Component/Table/Table.php',
    'CLIFramework\\Component\\Table\\TableStyle' => $vendorDir . '/corneltek/cliframework/src/Component/Table/TableStyle.php',
    'CLIFramework\\Config\\GlobalConfig' => $vendorDir . '/corneltek/cliframework/src/Config/GlobalConfig.php',
    'CLIFramework\\ConsoleInfo\\ConsoleInfoFactory' => $vendorDir . '/corneltek/cliframework/src/ConsoleInfo/ConsoleInfoFactory.php',
    'CLIFramework\\ConsoleInfo\\ConsoleInfoInterface' => $vendorDir . '/corneltek/cliframework/src/ConsoleInfo/ConsoleInfoInterface.php',
    'CLIFramework\\ConsoleInfo\\EnvConsoleInfo' => $vendorDir . '/corneltek/cliframework/src/ConsoleInfo/EnvConsoleInfo.php',
    'CLIFramework\\ConsoleInfo\\TputConsoleInfo' => $vendorDir . '/corneltek/cliframework/src/ConsoleInfo/TputConsoleInfo.php',
    'CLIFramework\\Corrector' => $vendorDir . '/corneltek/cliframework/src/Corrector.php',
    'CLIFramework\\Debug\\ConsoleDebug' => $vendorDir . '/corneltek/cliframework/src/Debug/ConsoleDebug.php',
    'CLIFramework\\Debug\\LineIndicator' => $vendorDir . '/corneltek/cliframework/src/Debug/LineIndicator.php',
    'CLIFramework\\ExceptionPrinter\\DevelopmentExceptionPrinter' => $vendorDir . '/corneltek/cliframework/src/ExceptionPrinter/DevelopmentExceptionPrinter.php',
    'CLIFramework\\ExceptionPrinter\\ProductionExceptionPrinter' => $vendorDir . '/corneltek/cliframework/src/ExceptionPrinter/ProductionExceptionPrinter.php',
    'CLIFramework\\Exception\\CommandArgumentNotEnoughException' => $vendorDir . '/corneltek/cliframework/src/Exception/CommandArgumentNotEnoughException.php',
    'CLIFramework\\Exception\\CommandBaseException' => $vendorDir . '/corneltek/cliframework/src/Exception/CommandBaseException.php',
    'CLIFramework\\Exception\\CommandClassNotFoundException' => $vendorDir . '/corneltek/cliframework/src/Exception/CommandClassNotFoundException.php',
    'CLIFramework\\Exception\\CommandNotFoundException' => $vendorDir . '/corneltek/cliframework/src/Exception/CommandNotFoundException.php',
    'CLIFramework\\Exception\\ExecuteMethodNotDefinedException' => $vendorDir . '/corneltek/cliframework/src/Exception/ExecuteMethodNotDefinedException.php',
    'CLIFramework\\Exception\\ExtensionException' => $vendorDir . '/corneltek/cliframework/src/Exception/ExtensionException.php',
    'CLIFramework\\Exception\\InvalidCommandArgumentException' => $vendorDir . '/corneltek/cliframework/src/Exception/InvalidCommandArgumentException.php',
    'CLIFramework\\Extension\\ApplicationExtension' => $vendorDir . '/corneltek/cliframework/src/Extension/ApplicationExtension.php',
    'CLIFramework\\Extension\\CommandExtension' => $vendorDir . '/corneltek/cliframework/src/Extension/CommandExtension.php',
    'CLIFramework\\Extension\\DaemonExtension' => $vendorDir . '/corneltek/cliframework/src/Extension/DaemonExtension.php',
    'CLIFramework\\Extension\\Extension' => $vendorDir . '/corneltek/cliframework/src/Extension/Extension.php',
    'CLIFramework\\Extension\\ExtensionBase' => $vendorDir . '/corneltek/cliframework/src/Extension/ExtensionBase.php',
    'CLIFramework\\Formatter' => $vendorDir . '/corneltek/cliframework/src/Formatter.php',
    'CLIFramework\\IO\\Console' => $vendorDir . '/corneltek/cliframework/src/IO/Console.php',
    'CLIFramework\\IO\\EchoWriter' => $vendorDir . '/corneltek/cliframework/src/IO/EchoWriter.php',
    'CLIFramework\\IO\\NullStty' => $vendorDir . '/corneltek/cliframework/src/IO/NullStty.php',
    'CLIFramework\\IO\\ReadlineConsole' => $vendorDir . '/corneltek/cliframework/src/IO/ReadlineConsole.php',
    'CLIFramework\\IO\\StandardConsole' => $vendorDir . '/corneltek/cliframework/src/IO/StandardConsole.php',
    'CLIFramework\\IO\\StreamWriter' => $vendorDir . '/corneltek/cliframework/src/IO/StreamWriter.php',
    'CLIFramework\\IO\\Stty' => $vendorDir . '/corneltek/cliframework/src/IO/Stty.php',
    'CLIFramework\\IO\\UnixStty' => $vendorDir . '/corneltek/cliframework/src/IO/UnixStty.php',
    'CLIFramework\\IO\\Writer' => $vendorDir . '/corneltek/cliframework/src/IO/Writer.php',
    'CLIFramework\\LevenshteinCorrector' => $vendorDir . '/corneltek/cliframework/src/LevenshteinCorrector.php',
    'CLIFramework\\Logger' => $vendorDir . '/corneltek/cliframework/src/Logger.php',
    'CLIFramework\\Logger\\ActionLogger' => $vendorDir . '/corneltek/cliframework/src/Logger/ActionLogger.php',
    'CLIFramework\\Logger\\Logger' => $vendorDir . '/corneltek/cliframework/src/Logger/Logger.php',
    'CLIFramework\\OptionPrinter' => $vendorDir . '/corneltek/cliframework/src/OptionPrinter.php',
    'CLIFramework\\PharKit\\PharGenerator' => $vendorDir . '/corneltek/cliframework/src/PharKit/PharGenerator.php',
    'CLIFramework\\PharKit\\PharURI' => $vendorDir . '/corneltek/cliframework/src/PharKit/PharURI.php',
    'CLIFramework\\Prompter' => $vendorDir . '/corneltek/cliframework/src/Prompter.php',
    'CLIFramework\\ServiceContainer' => $vendorDir . '/corneltek/cliframework/src/ServiceContainer.php',
    'CLIFramework\\Testing\\CommandTestCase' => $vendorDir . '/corneltek/cliframework/src/Testing/CommandTestCase.php',
    'CLIFramework\\Testing\\ConsoleTestCase' => $vendorDir . '/corneltek/cliframework/src/Testing/ConsoleTestCase.php',
    'CLIFramework\\Testing\\Parser' => $vendorDir . '/corneltek/cliframework/src/Testing/Parser.php',
    'CLIFramework\\Topic\\BaseTopic' => $vendorDir . '/corneltek/cliframework/src/Topic/BaseTopic.php',
    'CLIFramework\\Topic\\GitHubTopic' => $vendorDir . '/corneltek/cliframework/src/Topic/GitHubTopic.php',
    'CLIFramework\\Utils' => $vendorDir . '/corneltek/cliframework/src/Utils.php',
    'CLIFramework\\ValueCollection' => $vendorDir . '/corneltek/cliframework/src/ValueCollection.php',
    'CLIFramework\\ValueGroup' => $vendorDir . '/corneltek/cliframework/src/ValueGroup.php',
    'ClassTemplate\\ClassFile' => $vendorDir . '/corneltek/class-template/src/ClassTemplate/ClassFile.php',
    'ClassTemplate\\ClassInjection' => $vendorDir . '/corneltek/class-template/src/ClassTemplate/ClassInjection.php',
    'ClassTemplate\\File' => $vendorDir . '/corneltek/class-template/src/ClassTemplate/File.php',
    'ClassTemplate\\TemplateClassFile' => $vendorDir . '/corneltek/class-template/src/ClassTemplate/TemplateClassFile.php',
    'ClassTemplate\\TemplateView' => $vendorDir . '/corneltek/class-template/src/ClassTemplate/TemplateView.php',
    'CodeGen\\Annotator' => $vendorDir . '/corneltek/codegen/src/CodeGen/Annotator.php',
    'CodeGen\\Argument' => $vendorDir . '/corneltek/codegen/src/CodeGen/Argument.php',
    'CodeGen\\ArgumentList' => $vendorDir . '/corneltek/codegen/src/CodeGen/ArgumentList.php',
    'CodeGen\\Block' => $vendorDir . '/corneltek/codegen/src/CodeGen/Block.php',
    'CodeGen\\BracketedBlock' => $vendorDir . '/corneltek/codegen/src/CodeGen/BracketedBlock.php',
    'CodeGen\\ClassConst' => $vendorDir . '/corneltek/codegen/src/CodeGen/ClassConst.php',
    'CodeGen\\ClassMethod' => $vendorDir . '/corneltek/codegen/src/CodeGen/ClassMethod.php',
    'CodeGen\\ClassName' => $vendorDir . '/corneltek/codegen/src/CodeGen/ClassName.php',
    'CodeGen\\ClassProperty' => $vendorDir . '/corneltek/codegen/src/CodeGen/ClassProperty.php',
    'CodeGen\\ClassStaticVariable' => $vendorDir . '/corneltek/codegen/src/CodeGen/ClassStaticVariable.php',
    'CodeGen\\ClassTrait' => $vendorDir . '/corneltek/codegen/src/CodeGen/ClassTrait.php',
    'CodeGen\\Comment' => $vendorDir . '/corneltek/codegen/src/CodeGen/Comment.php',
    'CodeGen\\CommentBlock' => $vendorDir . '/corneltek/codegen/src/CodeGen/CommentBlock.php',
    'CodeGen\\Constant' => $vendorDir . '/corneltek/codegen/src/CodeGen/Constant.php',
    'CodeGen\\Exception\\InvalidArgumentTypeException' => $vendorDir . '/corneltek/codegen/src/CodeGen/Exception/InvalidArgumentTypeException.php',
    'CodeGen\\Exportable' => $vendorDir . '/corneltek/codegen/src/CodeGen/Exportable.php',
    'CodeGen\\Expr\\AssignExpr' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/AssignExpr.php',
    'CodeGen\\Expr\\CallExpr' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/CallExpr.php',
    'CodeGen\\Expr\\FunctionCall' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/FunctionCall.php',
    'CodeGen\\Expr\\MethodCall' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/MethodCall.php',
    'CodeGen\\Expr\\MethodCallExpr' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/MethodCallExpr.php',
    'CodeGen\\Expr\\NewObject' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/NewObject.php',
    'CodeGen\\Expr\\NewObjectExpr' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/NewObjectExpr.php',
    'CodeGen\\Expr\\ObjectProperty' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/ObjectProperty.php',
    'CodeGen\\Expr\\SelfMethodCall' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/SelfMethodCall.php',
    'CodeGen\\Expr\\SelfMethodCallExpr' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/SelfMethodCallExpr.php',
    'CodeGen\\Expr\\StaticMethodCall' => $vendorDir . '/corneltek/codegen/src/CodeGen/Expr/StaticMethodCall.php',
    'CodeGen\\Frameworks\\PHPUnit\\Assertions' => $vendorDir . '/corneltek/codegen/src/CodeGen/Frameworks/PHPUnit/Assertions.php',
    'CodeGen\\Frameworks\\PHPUnit\\PHPUnitFrameworkTestCase' => $vendorDir . '/corneltek/codegen/src/CodeGen/Frameworks/PHPUnit/PHPUnitFrameworkTestCase.php',
    'CodeGen\\Generator\\AppClassGenerator' => $vendorDir . '/corneltek/codegen/src/CodeGen/Generator/AppClassGenerator.php',
    'CodeGen\\Generator\\ArrayAccessGenerator' => $vendorDir . '/corneltek/codegen/src/CodeGen/Generator/ArrayAccessGenerator.php',
    'CodeGen\\Indenter' => $vendorDir . '/corneltek/codegen/src/CodeGen/Indenter.php',
    'CodeGen\\LicenseBlock' => $vendorDir . '/corneltek/codegen/src/CodeGen/LicenseBlock.php',
    'CodeGen\\Line' => $vendorDir . '/corneltek/codegen/src/CodeGen/Line.php',
    'CodeGen\\Raw' => $vendorDir . '/corneltek/codegen/src/CodeGen/Raw.php',
    'CodeGen\\Renderable' => $vendorDir . '/corneltek/codegen/src/CodeGen/Renderable.php',
    'CodeGen\\Statement\\AssignStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/AssignStatement.php',
    'CodeGen\\Statement\\ConditionalStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/ConditionalStatement.php',
    'CodeGen\\Statement\\ConstStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/ConstStatement.php',
    'CodeGen\\Statement\\DefineStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/DefineStatement.php',
    'CodeGen\\Statement\\ElseIfStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/ElseIfStatement.php',
    'CodeGen\\Statement\\ElseStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/ElseStatement.php',
    'CodeGen\\Statement\\ForEachStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/ForEachStatement.php',
    'CodeGen\\Statement\\FunctionCallStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/FunctionCallStatement.php',
    'CodeGen\\Statement\\IfElseStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/IfElseStatement.php',
    'CodeGen\\Statement\\IfIssetStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/IfIssetStatement.php',
    'CodeGen\\Statement\\IfStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/IfStatement.php',
    'CodeGen\\Statement\\MethodCallStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/MethodCallStatement.php',
    'CodeGen\\Statement\\RequireClassStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/RequireClassStatement.php',
    'CodeGen\\Statement\\RequireComposerAutoloadStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/RequireComposerAutoloadStatement.php',
    'CodeGen\\Statement\\RequireOnceStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/RequireOnceStatement.php',
    'CodeGen\\Statement\\RequireStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/RequireStatement.php',
    'CodeGen\\Statement\\Statement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/Statement.php',
    'CodeGen\\Statement\\TryCatchStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/TryCatchStatement.php',
    'CodeGen\\Statement\\UseStatement' => $vendorDir . '/corneltek/codegen/src/CodeGen/Statement/UseStatement.php',
    'CodeGen\\Testing\\CodeGenTestCase' => $vendorDir . '/corneltek/codegen/src/CodeGen/Testing/CodeGenTestCase.php',
    'CodeGen\\UseClass' => $vendorDir . '/corneltek/codegen/src/CodeGen/UseClass.php',
    'CodeGen\\UserClass' => $vendorDir . '/corneltek/codegen/src/CodeGen/UserClass.php',
    'CodeGen\\UserFunction' => $vendorDir . '/corneltek/codegen/src/CodeGen/UserFunction.php',
    'CodeGen\\Utils' => $vendorDir . '/corneltek/codegen/src/CodeGen/Utils.php',
    'CodeGen\\Variable' => $vendorDir . '/corneltek/codegen/src/CodeGen/Variable.php',
    'CodeGen\\VariableDeflator' => $vendorDir . '/corneltek/codegen/src/CodeGen/VariableDeflator.php',
    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    'CurlKit\\CurlAgent' => $vendorDir . '/corneltek/curlkit/src/CurlKit/CurlAgent.php',
    'CurlKit\\CurlDownloader' => $vendorDir . '/corneltek/curlkit/src/CurlKit/CurlDownloader.php',
    'CurlKit\\CurlException' => $vendorDir . '/corneltek/curlkit/src/CurlKit/CurlException.php',
    'CurlKit\\CurlRequest' => $vendorDir . '/corneltek/curlkit/src/CurlKit/CurlRequest.php',
    'CurlKit\\CurlResponse' => $vendorDir . '/corneltek/curlkit/src/CurlKit/CurlResponse.php',
    'CurlKit\\Progress\\CurlProgressInterface' => $vendorDir . '/corneltek/curlkit/src/CurlKit/Progress/CurlProgressInterface.php',
    'CurlKit\\Progress\\ProgressBar' => $vendorDir . '/corneltek/curlkit/src/CurlKit/Progress/ProgressBar.php',
    'CurlKit\\Progress\\ProgressStar' => $vendorDir . '/corneltek/curlkit/src/CurlKit/Progress/ProgressStar.php',
    'Doctrine\\Inflector\\CachedWordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/CachedWordInflector.php',
    'Doctrine\\Inflector\\GenericLanguageInflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/GenericLanguageInflectorFactory.php',
    'Doctrine\\Inflector\\Inflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Inflector.php',
    'Doctrine\\Inflector\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/InflectorFactory.php',
    'Doctrine\\Inflector\\Language' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Language.php',
    'Doctrine\\Inflector\\LanguageInflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/LanguageInflectorFactory.php',
    'Doctrine\\Inflector\\NoopWordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/NoopWordInflector.php',
    'Doctrine\\Inflector\\Rules\\English\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Inflectible.php',
    'Doctrine\\Inflector\\Rules\\English\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/InflectorFactory.php',
    'Doctrine\\Inflector\\Rules\\English\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Rules.php',
    'Doctrine\\Inflector\\Rules\\English\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/English/Uninflected.php',
    'Doctrine\\Inflector\\Rules\\French\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Inflectible.php',
    'Doctrine\\Inflector\\Rules\\French\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/InflectorFactory.php',
    'Doctrine\\Inflector\\Rules\\French\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Rules.php',
    'Doctrine\\Inflector\\Rules\\French\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/French/Uninflected.php',
    'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Inflectible.php',
    'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/InflectorFactory.php',
    'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Rules.php',
    'Doctrine\\Inflector\\Rules\\NorwegianBokmal\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/NorwegianBokmal/Uninflected.php',
    'Doctrine\\Inflector\\Rules\\Pattern' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Pattern.php',
    'Doctrine\\Inflector\\Rules\\Patterns' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Patterns.php',
    'Doctrine\\Inflector\\Rules\\Portuguese\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Inflectible.php',
    'Doctrine\\Inflector\\Rules\\Portuguese\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/InflectorFactory.php',
    'Doctrine\\Inflector\\Rules\\Portuguese\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Rules.php',
    'Doctrine\\Inflector\\Rules\\Portuguese\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Portuguese/Uninflected.php',
    'Doctrine\\Inflector\\Rules\\Ruleset' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Ruleset.php',
    'Doctrine\\Inflector\\Rules\\Spanish\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Inflectible.php',
    'Doctrine\\Inflector\\Rules\\Spanish\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/InflectorFactory.php',
    'Doctrine\\Inflector\\Rules\\Spanish\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Rules.php',
    'Doctrine\\Inflector\\Rules\\Spanish\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Spanish/Uninflected.php',
    'Doctrine\\Inflector\\Rules\\Substitution' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitution.php',
    'Doctrine\\Inflector\\Rules\\Substitutions' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Substitutions.php',
    'Doctrine\\Inflector\\Rules\\Transformation' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformation.php',
    'Doctrine\\Inflector\\Rules\\Transformations' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Transformations.php',
    'Doctrine\\Inflector\\Rules\\Turkish\\Inflectible' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Inflectible.php',
    'Doctrine\\Inflector\\Rules\\Turkish\\InflectorFactory' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/InflectorFactory.php',
    'Doctrine\\Inflector\\Rules\\Turkish\\Rules' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Rules.php',
    'Doctrine\\Inflector\\Rules\\Turkish\\Uninflected' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Turkish/Uninflected.php',
    'Doctrine\\Inflector\\Rules\\Word' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/Rules/Word.php',
    'Doctrine\\Inflector\\RulesetInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/RulesetInflector.php',
    'Doctrine\\Inflector\\WordInflector' => $vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector/WordInflector.php',
    'GetOptionKit\\Argument' => $vendorDir . '/corneltek/getoptionkit/src/Argument.php',
    'GetOptionKit\\ContinuousOptionParser' => $vendorDir . '/corneltek/getoptionkit/src/ContinuousOptionParser.php',
    'GetOptionKit\\Exception\\InvalidOptionException' => $vendorDir . '/corneltek/getoptionkit/src/Exception/InvalidOptionException.php',
    'GetOptionKit\\Exception\\InvalidOptionValueException' => $vendorDir . '/corneltek/getoptionkit/src/Exception/InvalidOptionValueException.php',
    'GetOptionKit\\Exception\\NonNumericException' => $vendorDir . '/corneltek/getoptionkit/src/Exception/NonNumericException.php',
    'GetOptionKit\\Exception\\OptionConflictException' => $vendorDir . '/corneltek/getoptionkit/src/Exception/OptionConflictException.php',
    'GetOptionKit\\Exception\\RequireValueException' => $vendorDir . '/corneltek/getoptionkit/src/Exception/RequireValueException.php',
    'GetOptionKit\\Option' => $vendorDir . '/corneltek/getoptionkit/src/Option.php',
    'GetOptionKit\\OptionCollection' => $vendorDir . '/corneltek/getoptionkit/src/OptionCollection.php',
    'GetOptionKit\\OptionParser' => $vendorDir . '/corneltek/getoptionkit/src/OptionParser.php',
    'GetOptionKit\\OptionPrinter\\ConsoleOptionPrinter' => $vendorDir . '/corneltek/getoptionkit/src/OptionPrinter/ConsoleOptionPrinter.php',
    'GetOptionKit\\OptionPrinter\\OptionPrinter' => $vendorDir . '/corneltek/getoptionkit/src/OptionPrinter/OptionPrinter.php',
    'GetOptionKit\\OptionResult' => $vendorDir . '/corneltek/getoptionkit/src/OptionResult.php',
    'GetOptionKit\\ValueType\\BaseType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/BaseType.php',
    'GetOptionKit\\ValueType\\BoolType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/BoolType.php',
    'GetOptionKit\\ValueType\\BooleanType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/BooleanType.php',
    'GetOptionKit\\ValueType\\DateTimeType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/DateTimeType.php',
    'GetOptionKit\\ValueType\\DateType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/DateType.php',
    'GetOptionKit\\ValueType\\DirType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/DirType.php',
    'GetOptionKit\\ValueType\\EmailType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/EmailType.php',
    'GetOptionKit\\ValueType\\FileType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/FileType.php',
    'GetOptionKit\\ValueType\\IpType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/IpType.php',
    'GetOptionKit\\ValueType\\Ipv4Type' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/Ipv4Type.php',
    'GetOptionKit\\ValueType\\Ipv6Type' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/Ipv6Type.php',
    'GetOptionKit\\ValueType\\NumberType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/NumberType.php',
    'GetOptionKit\\ValueType\\PathType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/PathType.php',
    'GetOptionKit\\ValueType\\RegexType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/RegexType.php',
    'GetOptionKit\\ValueType\\StringType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/StringType.php',
    'GetOptionKit\\ValueType\\UrlType' => $vendorDir . '/corneltek/getoptionkit/src/ValueType/UrlType.php',
    'PEARX\\Category' => $vendorDir . '/corneltek/pearx/src/PEARX/Category.php',
    'PEARX\\Channel' => $vendorDir . '/corneltek/pearx/src/PEARX/Channel.php',
    'PEARX\\ChannelParser' => $vendorDir . '/corneltek/pearx/src/PEARX/ChannelParser.php',
    'PEARX\\Core' => $vendorDir . '/corneltek/pearx/src/PEARX/Core.php',
    'PEARX\\Installer' => $vendorDir . '/corneltek/pearx/src/PEARX/Installer.php',
    'PEARX\\Package' => $vendorDir . '/corneltek/pearx/src/PEARX/Package.php',
    'PEARX\\PackageCollection' => $vendorDir . '/corneltek/pearx/src/PEARX/PackageCollection.php',
    'PEARX\\PackageXml\\ContentFile' => $vendorDir . '/corneltek/pearx/src/PEARX/PackageXml/ContentFile.php',
    'PEARX\\PackageXml\\Parser' => $vendorDir . '/corneltek/pearx/src/PEARX/PackageXml/Parser.php',
    'PEARX\\Utils' => $vendorDir . '/corneltek/pearx/src/PEARX/Utils.php',
    'PhpBrew\\Build' => $baseDir . '/src/PhpBrew/Build.php',
    'PhpBrew\\BuildFinder' => $baseDir . '/src/PhpBrew/BuildFinder.php',
    'PhpBrew\\BuildSettings\\BuildSettings' => $baseDir . '/src/PhpBrew/BuildSettings/BuildSettings.php',
    'PhpBrew\\Buildable' => $baseDir . '/src/PhpBrew/Buildable.php',
    'PhpBrew\\CommandBuilder' => $baseDir . '/src/PhpBrew/CommandBuilder.php',
    'PhpBrew\\Command\\CdCommand' => $baseDir . '/src/PhpBrew/Command/CdCommand.php',
    'PhpBrew\\Command\\CleanCommand' => $baseDir . '/src/PhpBrew/Command/CleanCommand.php',
    'PhpBrew\\Command\\ConfigCommand' => $baseDir . '/src/PhpBrew/Command/ConfigCommand.php',
    'PhpBrew\\Command\\CtagsCommand' => $baseDir . '/src/PhpBrew/Command/CtagsCommand.php',
    'PhpBrew\\Command\\DownloadCommand' => $baseDir . '/src/PhpBrew/Command/DownloadCommand.php',
    'PhpBrew\\Command\\EachCommand' => $baseDir . '/src/PhpBrew/Command/EachCommand.php',
    'PhpBrew\\Command\\EnvCommand' => $baseDir . '/src/PhpBrew/Command/EnvCommand.php',
    'PhpBrew\\Command\\ExtensionCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\BaseCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/BaseCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\CleanCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/CleanCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\ConfigCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/ConfigCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\DisableCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/DisableCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\EnableCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/EnableCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\InstallCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/InstallCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\KnownCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/KnownCommand.php',
    'PhpBrew\\Command\\ExtensionCommand\\ShowCommand' => $baseDir . '/src/PhpBrew/Command/ExtensionCommand/ShowCommand.php',
    'PhpBrew\\Command\\FpmCommand' => $baseDir . '/src/PhpBrew/Command/FpmCommand.php',
    'PhpBrew\\Command\\FpmCommand\\RestartCommand' => $baseDir . '/src/PhpBrew/Command/FpmCommand/RestartCommand.php',
    'PhpBrew\\Command\\FpmCommand\\SetupCommand' => $baseDir . '/src/PhpBrew/Command/FpmCommand/SetupCommand.php',
    'PhpBrew\\Command\\FpmCommand\\StartCommand' => $baseDir . '/src/PhpBrew/Command/FpmCommand/StartCommand.php',
    'PhpBrew\\Command\\FpmCommand\\StopCommand' => $baseDir . '/src/PhpBrew/Command/FpmCommand/StopCommand.php',
    'PhpBrew\\Command\\HelpCommand' => $baseDir . '/src/PhpBrew/Command/HelpCommand.php',
    'PhpBrew\\Command\\InfoCommand' => $baseDir . '/src/PhpBrew/Command/InfoCommand.php',
    'PhpBrew\\Command\\InitCommand' => $baseDir . '/src/PhpBrew/Command/InitCommand.php',
    'PhpBrew\\Command\\InstallCommand' => $baseDir . '/src/PhpBrew/Command/InstallCommand.php',
    'PhpBrew\\Command\\KnownCommand' => $baseDir . '/src/PhpBrew/Command/KnownCommand.php',
    'PhpBrew\\Command\\ListCommand' => $baseDir . '/src/PhpBrew/Command/ListCommand.php',
    'PhpBrew\\Command\\ListIniCommand' => $baseDir . '/src/PhpBrew/Command/ListIniCommand.php',
    'PhpBrew\\Command\\MigratedCommand' => $baseDir . '/src/PhpBrew/Command/MigratedCommand.php',
    'PhpBrew\\Command\\OffCommand' => $baseDir . '/src/PhpBrew/Command/OffCommand.php',
    'PhpBrew\\Command\\PathCommand' => $baseDir . '/src/PhpBrew/Command/PathCommand.php',
    'PhpBrew\\Command\\PurgeCommand' => $baseDir . '/src/PhpBrew/Command/PurgeCommand.php',
    'PhpBrew\\Command\\RemoveCommand' => $baseDir . '/src/PhpBrew/Command/RemoveCommand.php',
    'PhpBrew\\Command\\SelfUpdateCommand' => $baseDir . '/src/PhpBrew/Command/SelfUpdateCommand.php',
    'PhpBrew\\Command\\SwitchCommand' => $baseDir . '/src/PhpBrew/Command/SwitchCommand.php',
    'PhpBrew\\Command\\SwitchOffCommand' => $baseDir . '/src/PhpBrew/Command/SwitchOffCommand.php',
    'PhpBrew\\Command\\SystemCommand' => $baseDir . '/src/PhpBrew/Command/SystemCommand.php',
    'PhpBrew\\Command\\SystemOffCommand' => $baseDir . '/src/PhpBrew/Command/SystemOffCommand.php',
    'PhpBrew\\Command\\UpdateCommand' => $baseDir . '/src/PhpBrew/Command/UpdateCommand.php',
    'PhpBrew\\Command\\UseCommand' => $baseDir . '/src/PhpBrew/Command/UseCommand.php',
    'PhpBrew\\Command\\VariantsCommand' => $baseDir . '/src/PhpBrew/Command/VariantsCommand.php',
    'PhpBrew\\Command\\VirtualCommand' => $baseDir . '/src/PhpBrew/Command/VirtualCommand.php',
    'PhpBrew\\Config' => $baseDir . '/src/PhpBrew/Config.php',
    'PhpBrew\\ConfigureParameters' => $baseDir . '/src/PhpBrew/ConfigureParameters.php',
    'PhpBrew\\Console' => $baseDir . '/src/PhpBrew/Console.php',
    'PhpBrew\\Distribution\\DistributionUrlPolicy' => $baseDir . '/src/PhpBrew/Distribution/DistributionUrlPolicy.php',
    'PhpBrew\\Downloader\\BaseDownloader' => $baseDir . '/src/PhpBrew/Downloader/BaseDownloader.php',
    'PhpBrew\\Downloader\\CurlCommandDownloader' => $baseDir . '/src/PhpBrew/Downloader/CurlCommandDownloader.php',
    'PhpBrew\\Downloader\\DownloadFactory' => $baseDir . '/src/PhpBrew/Downloader/DownloadFactory.php',
    'PhpBrew\\Downloader\\PhpCurlDownloader' => $baseDir . '/src/PhpBrew/Downloader/PhpCurlDownloader.php',
    'PhpBrew\\Downloader\\PhpStreamDownloader' => $baseDir . '/src/PhpBrew/Downloader/PhpStreamDownloader.php',
    'PhpBrew\\Downloader\\WgetCommandDownloader' => $baseDir . '/src/PhpBrew/Downloader/WgetCommandDownloader.php',
    'PhpBrew\\Exception\\OopsException' => $baseDir . '/src/PhpBrew/Exception/OopsException.php',
    'PhpBrew\\Exception\\SystemCommandException' => $baseDir . '/src/PhpBrew/Exception/SystemCommandException.php',
    'PhpBrew\\ExtensionList' => $baseDir . '/src/PhpBrew/ExtensionList.php',
    'PhpBrew\\Extension\\ConfigureOption' => $baseDir . '/src/PhpBrew/Extension/ConfigureOption.php',
    'PhpBrew\\Extension\\Extension' => $baseDir . '/src/PhpBrew/Extension/Extension.php',
    'PhpBrew\\Extension\\ExtensionDownloader' => $baseDir . '/src/PhpBrew/Extension/ExtensionDownloader.php',
    'PhpBrew\\Extension\\ExtensionFactory' => $baseDir . '/src/PhpBrew/Extension/ExtensionFactory.php',
    'PhpBrew\\Extension\\ExtensionInstaller' => $baseDir . '/src/PhpBrew/Extension/ExtensionInstaller.php',
    'PhpBrew\\Extension\\ExtensionManager' => $baseDir . '/src/PhpBrew/Extension/ExtensionManager.php',
    'PhpBrew\\Extension\\M4Extension' => $baseDir . '/src/PhpBrew/Extension/M4Extension.php',
    'PhpBrew\\Extension\\PeclExtension' => $baseDir . '/src/PhpBrew/Extension/PeclExtension.php',
    'PhpBrew\\Extension\\Provider\\BitbucketProvider' => $baseDir . '/src/PhpBrew/Extension/Provider/BitbucketProvider.php',
    'PhpBrew\\Extension\\Provider\\GithubProvider' => $baseDir . '/src/PhpBrew/Extension/Provider/GithubProvider.php',
    'PhpBrew\\Extension\\Provider\\PeclProvider' => $baseDir . '/src/PhpBrew/Extension/Provider/PeclProvider.php',
    'PhpBrew\\Extension\\Provider\\Provider' => $baseDir . '/src/PhpBrew/Extension/Provider/Provider.php',
    'PhpBrew\\Extension\\Provider\\RepositoryDslParser' => $baseDir . '/src/PhpBrew/Extension/Provider/RepositoryDslParser.php',
    'PhpBrew\\InvalidVariantSyntaxException' => $baseDir . '/src/PhpBrew/InvalidVariantSyntaxException.php',
    'PhpBrew\\PatchKit\\DiffPatchRule' => $baseDir . '/src/PhpBrew/PatchKit/DiffPatchRule.php',
    'PhpBrew\\PatchKit\\Patch' => $baseDir . '/src/PhpBrew/PatchKit/Patch.php',
    'PhpBrew\\PatchKit\\PatchRule' => $baseDir . '/src/PhpBrew/PatchKit/PatchRule.php',
    'PhpBrew\\PatchKit\\RegExpPatchRule' => $baseDir . '/src/PhpBrew/PatchKit/RegExpPatchRule.php',
    'PhpBrew\\Patches\\Apache2ModuleNamePatch' => $baseDir . '/src/PhpBrew/Patches/Apache2ModuleNamePatch.php',
    'PhpBrew\\Patches\\FreeTypePatch' => $baseDir . '/src/PhpBrew/Patches/FreeTypePatch.php',
    'PhpBrew\\Patches\\IntlWith64bitPatch' => $baseDir . '/src/PhpBrew/Patches/IntlWith64bitPatch.php',
    'PhpBrew\\Patches\\OpenSSLDSOPatch' => $baseDir . '/src/PhpBrew/Patches/OpenSSLDSOPatch.php',
    'PhpBrew\\Patches\\PHP56WithOpenSSL11Patch' => $baseDir . '/src/PhpBrew/Patches/PHP56WithOpenSSL11Patch.php',
    'PhpBrew\\Patches\\ReadlinePatch' => $baseDir . '/src/PhpBrew/Patches/ReadlinePatch.php',
    'PhpBrew\\PrefixFinder' => $baseDir . '/src/PhpBrew/PrefixFinder.php',
    'PhpBrew\\PrefixFinder\\BrewPrefixFinder' => $baseDir . '/src/PhpBrew/PrefixFinder/BrewPrefixFinder.php',
    'PhpBrew\\PrefixFinder\\ExecutablePrefixFinder' => $baseDir . '/src/PhpBrew/PrefixFinder/ExecutablePrefixFinder.php',
    'PhpBrew\\PrefixFinder\\IncludePrefixFinder' => $baseDir . '/src/PhpBrew/PrefixFinder/IncludePrefixFinder.php',
    'PhpBrew\\PrefixFinder\\LibPrefixFinder' => $baseDir . '/src/PhpBrew/PrefixFinder/LibPrefixFinder.php',
    'PhpBrew\\PrefixFinder\\PkgConfigPrefixFinder' => $baseDir . '/src/PhpBrew/PrefixFinder/PkgConfigPrefixFinder.php',
    'PhpBrew\\PrefixFinder\\UserProvidedPrefix' => $baseDir . '/src/PhpBrew/PrefixFinder/UserProvidedPrefix.php',
    'PhpBrew\\ReleaseList' => $baseDir . '/src/PhpBrew/ReleaseList.php',
    'PhpBrew\\Tasks\\AfterConfigureTask' => $baseDir . '/src/PhpBrew/Tasks/AfterConfigureTask.php',
    'PhpBrew\\Tasks\\Apxs2CheckTask' => $baseDir . '/src/PhpBrew/Tasks/Apxs2CheckTask.php',
    'PhpBrew\\Tasks\\BaseTask' => $baseDir . '/src/PhpBrew/Tasks/BaseTask.php',
    'PhpBrew\\Tasks\\BeforeConfigureTask' => $baseDir . '/src/PhpBrew/Tasks/BeforeConfigureTask.php',
    'PhpBrew\\Tasks\\BuildConfTask' => $baseDir . '/src/PhpBrew/Tasks/BuildConfTask.php',
    'PhpBrew\\Tasks\\BuildTask' => $baseDir . '/src/PhpBrew/Tasks/BuildTask.php',
    'PhpBrew\\Tasks\\ConfigureTask' => $baseDir . '/src/PhpBrew/Tasks/ConfigureTask.php',
    'PhpBrew\\Tasks\\DSymTask' => $baseDir . '/src/PhpBrew/Tasks/DSymTask.php',
    'PhpBrew\\Tasks\\DownloadTask' => $baseDir . '/src/PhpBrew/Tasks/DownloadTask.php',
    'PhpBrew\\Tasks\\ExtractTask' => $baseDir . '/src/PhpBrew/Tasks/ExtractTask.php',
    'PhpBrew\\Tasks\\FetchReleaseListTask' => $baseDir . '/src/PhpBrew/Tasks/FetchReleaseListTask.php',
    'PhpBrew\\Tasks\\InstallTask' => $baseDir . '/src/PhpBrew/Tasks/InstallTask.php',
    'PhpBrew\\Tasks\\MakeTask' => $baseDir . '/src/PhpBrew/Tasks/MakeTask.php',
    'PhpBrew\\Tasks\\PrepareDirectoryTask' => $baseDir . '/src/PhpBrew/Tasks/PrepareDirectoryTask.php',
    'PhpBrew\\Tasks\\TestTask' => $baseDir . '/src/PhpBrew/Tasks/TestTask.php',
    'PhpBrew\\Testing\\CommandTestCase' => $baseDir . '/src/PhpBrew/Testing/CommandTestCase.php',
    'PhpBrew\\Testing\\PatchTestCase' => $baseDir . '/src/PhpBrew/Testing/PatchTestCase.php',
    'PhpBrew\\Testing\\VCRAdapter' => $baseDir . '/src/PhpBrew/Testing/VCRAdapter.php',
    'PhpBrew\\Utils' => $baseDir . '/src/PhpBrew/Utils.php',
    'PhpBrew\\VariantBuilder' => $baseDir . '/src/PhpBrew/VariantBuilder.php',
    'PhpBrew\\VariantParser' => $baseDir . '/src/PhpBrew/VariantParser.php',
    'PhpBrew\\VersionDslParser' => $baseDir . '/src/PhpBrew/VersionDslParser.php',
    'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
    'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
    'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
    'Pimple\\Exception\\InvalidServiceIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php',
    'Pimple\\Exception\\UnknownIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php',
    'Pimple\\Psr11\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/Container.php',
    'Pimple\\Psr11\\ServiceLocator' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php',
    'Pimple\\ServiceIterator' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceIterator.php',
    'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php',
    'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
    'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
    'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
    'Symfony\\Component\\ClassLoader\\ApcClassLoader' => $vendorDir . '/symfony/class-loader/ApcClassLoader.php',
    'Symfony\\Component\\ClassLoader\\ApcUniversalClassLoader' => $vendorDir . '/symfony/class-loader/ApcUniversalClassLoader.php',
    'Symfony\\Component\\ClassLoader\\ClassCollectionLoader' => $vendorDir . '/symfony/class-loader/ClassCollectionLoader.php',
    'Symfony\\Component\\ClassLoader\\ClassLoader' => $vendorDir . '/symfony/class-loader/ClassLoader.php',
    'Symfony\\Component\\ClassLoader\\ClassMapGenerator' => $vendorDir . '/symfony/class-loader/ClassMapGenerator.php',
    'Symfony\\Component\\ClassLoader\\DebugClassLoader' => $vendorDir . '/symfony/class-loader/DebugClassLoader.php',
    'Symfony\\Component\\ClassLoader\\DebugUniversalClassLoader' => $vendorDir . '/symfony/class-loader/DebugUniversalClassLoader.php',
    'Symfony\\Component\\ClassLoader\\MapClassLoader' => $vendorDir . '/symfony/class-loader/MapClassLoader.php',
    'Symfony\\Component\\ClassLoader\\Psr4ClassLoader' => $vendorDir . '/symfony/class-loader/Psr4ClassLoader.php',
    'Symfony\\Component\\ClassLoader\\UniversalClassLoader' => $vendorDir . '/symfony/class-loader/UniversalClassLoader.php',
    'Symfony\\Component\\ClassLoader\\WinCacheClassLoader' => $vendorDir . '/symfony/class-loader/WinCacheClassLoader.php',
    'Symfony\\Component\\ClassLoader\\XcacheClassLoader' => $vendorDir . '/symfony/class-loader/XcacheClassLoader.php',
    'Symfony\\Component\\Finder\\Adapter\\AbstractAdapter' => $vendorDir . '/symfony/finder/Adapter/AbstractAdapter.php',
    'Symfony\\Component\\Finder\\Adapter\\AbstractFindAdapter' => $vendorDir . '/symfony/finder/Adapter/AbstractFindAdapter.php',
    'Symfony\\Component\\Finder\\Adapter\\AdapterInterface' => $vendorDir . '/symfony/finder/Adapter/AdapterInterface.php',
    'Symfony\\Component\\Finder\\Adapter\\BsdFindAdapter' => $vendorDir . '/symfony/finder/Adapter/BsdFindAdapter.php',
    'Symfony\\Component\\Finder\\Adapter\\GnuFindAdapter' => $vendorDir . '/symfony/finder/Adapter/GnuFindAdapter.php',
    'Symfony\\Component\\Finder\\Adapter\\PhpAdapter' => $vendorDir . '/symfony/finder/Adapter/PhpAdapter.php',
    'Symfony\\Component\\Finder\\Comparator\\Comparator' => $vendorDir . '/symfony/finder/Comparator/Comparator.php',
    'Symfony\\Component\\Finder\\Comparator\\DateComparator' => $vendorDir . '/symfony/finder/Comparator/DateComparator.php',
    'Symfony\\Component\\Finder\\Comparator\\NumberComparator' => $vendorDir . '/symfony/finder/Comparator/NumberComparator.php',
    'Symfony\\Component\\Finder\\Exception\\AccessDeniedException' => $vendorDir . '/symfony/finder/Exception/AccessDeniedException.php',
    'Symfony\\Component\\Finder\\Exception\\AdapterFailureException' => $vendorDir . '/symfony/finder/Exception/AdapterFailureException.php',
    'Symfony\\Component\\Finder\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/finder/Exception/ExceptionInterface.php',
    'Symfony\\Component\\Finder\\Exception\\OperationNotPermitedException' => $vendorDir . '/symfony/finder/Exception/OperationNotPermitedException.php',
    'Symfony\\Component\\Finder\\Exception\\ShellCommandFailureException' => $vendorDir . '/symfony/finder/Exception/ShellCommandFailureException.php',
    'Symfony\\Component\\Finder\\Expression\\Expression' => $vendorDir . '/symfony/finder/Expression/Expression.php',
    'Symfony\\Component\\Finder\\Expression\\Glob' => $vendorDir . '/symfony/finder/Expression/Glob.php',
    'Symfony\\Component\\Finder\\Expression\\Regex' => $vendorDir . '/symfony/finder/Expression/Regex.php',
    'Symfony\\Component\\Finder\\Expression\\ValueInterface' => $vendorDir . '/symfony/finder/Expression/ValueInterface.php',
    'Symfony\\Component\\Finder\\Finder' => $vendorDir . '/symfony/finder/Finder.php',
    'Symfony\\Component\\Finder\\Glob' => $vendorDir . '/symfony/finder/Glob.php',
    'Symfony\\Component\\Finder\\Iterator\\CustomFilterIterator' => $vendorDir . '/symfony/finder/Iterator/CustomFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\DateRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DateRangeFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\DepthRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/DepthRangeFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\ExcludeDirectoryFilterIterator' => $vendorDir . '/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\FilePathsIterator' => $vendorDir . '/symfony/finder/Iterator/FilePathsIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\FileTypeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FileTypeFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\FilecontentFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilecontentFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\FilenameFilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilenameFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\FilterIterator' => $vendorDir . '/symfony/finder/Iterator/FilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\MultiplePcreFilterIterator' => $vendorDir . '/symfony/finder/Iterator/MultiplePcreFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\PathFilterIterator' => $vendorDir . '/symfony/finder/Iterator/PathFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator' => $vendorDir . '/symfony/finder/Iterator/RecursiveDirectoryIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\SizeRangeFilterIterator' => $vendorDir . '/symfony/finder/Iterator/SizeRangeFilterIterator.php',
    'Symfony\\Component\\Finder\\Iterator\\SortableIterator' => $vendorDir . '/symfony/finder/Iterator/SortableIterator.php',
    'Symfony\\Component\\Finder\\Shell\\Command' => $vendorDir . '/symfony/finder/Shell/Command.php',
    'Symfony\\Component\\Finder\\Shell\\Shell' => $vendorDir . '/symfony/finder/Shell/Shell.php',
    'Symfony\\Component\\Finder\\SplFileInfo' => $vendorDir . '/symfony/finder/SplFileInfo.php',
    'Symfony\\Component\\Yaml\\Command\\LintCommand' => $vendorDir . '/symfony/yaml/Command/LintCommand.php',
    'Symfony\\Component\\Yaml\\Dumper' => $vendorDir . '/symfony/yaml/Dumper.php',
    'Symfony\\Component\\Yaml\\Escaper' => $vendorDir . '/symfony/yaml/Escaper.php',
    'Symfony\\Component\\Yaml\\Exception\\DumpException' => $vendorDir . '/symfony/yaml/Exception/DumpException.php',
    'Symfony\\Component\\Yaml\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/yaml/Exception/ExceptionInterface.php',
    'Symfony\\Component\\Yaml\\Exception\\ParseException' => $vendorDir . '/symfony/yaml/Exception/ParseException.php',
    'Symfony\\Component\\Yaml\\Exception\\RuntimeException' => $vendorDir . '/symfony/yaml/Exception/RuntimeException.php',
    'Symfony\\Component\\Yaml\\Inline' => $vendorDir . '/symfony/yaml/Inline.php',
    'Symfony\\Component\\Yaml\\Parser' => $vendorDir . '/symfony/yaml/Parser.php',
    'Symfony\\Component\\Yaml\\Tag\\TaggedValue' => $vendorDir . '/symfony/yaml/Tag/TaggedValue.php',
    'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Unescaper.php',
    'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Yaml.php',
    'Symfony\\Polyfill\\Apcu\\Apcu' => $vendorDir . '/symfony/polyfill-apcu/Apcu.php',
    'Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php',
    'Twig\\Cache\\CacheInterface' => $vendorDir . '/twig/twig/src/Cache/CacheInterface.php',
    'Twig\\Cache\\FilesystemCache' => $vendorDir . '/twig/twig/src/Cache/FilesystemCache.php',
    'Twig\\Cache\\NullCache' => $vendorDir . '/twig/twig/src/Cache/NullCache.php',
    'Twig\\Compiler' => $vendorDir . '/twig/twig/src/Compiler.php',
    'Twig\\Environment' => $vendorDir . '/twig/twig/src/Environment.php',
    'Twig\\Error\\Error' => $vendorDir . '/twig/twig/src/Error/Error.php',
    'Twig\\Error\\LoaderError' => $vendorDir . '/twig/twig/src/Error/LoaderError.php',
    'Twig\\Error\\RuntimeError' => $vendorDir . '/twig/twig/src/Error/RuntimeError.php',
    'Twig\\Error\\SyntaxError' => $vendorDir . '/twig/twig/src/Error/SyntaxError.php',
    'Twig\\ExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser.php',
    'Twig\\Extension\\AbstractExtension' => $vendorDir . '/twig/twig/src/Extension/AbstractExtension.php',
    'Twig\\Extension\\CoreExtension' => $vendorDir . '/twig/twig/src/Extension/CoreExtension.php',
    'Twig\\Extension\\DebugExtension' => $vendorDir . '/twig/twig/src/Extension/DebugExtension.php',
    'Twig\\Extension\\EscaperExtension' => $vendorDir . '/twig/twig/src/Extension/EscaperExtension.php',
    'Twig\\Extension\\ExtensionInterface' => $vendorDir . '/twig/twig/src/Extension/ExtensionInterface.php',
    'Twig\\Extension\\GlobalsInterface' => $vendorDir . '/twig/twig/src/Extension/GlobalsInterface.php',
    'Twig\\Extension\\InitRuntimeInterface' => $vendorDir . '/twig/twig/src/Extension/InitRuntimeInterface.php',
    'Twig\\Extension\\OptimizerExtension' => $vendorDir . '/twig/twig/src/Extension/OptimizerExtension.php',
    'Twig\\Extension\\ProfilerExtension' => $vendorDir . '/twig/twig/src/Extension/ProfilerExtension.php',
    'Twig\\Extension\\RuntimeExtensionInterface' => $vendorDir . '/twig/twig/src/Extension/RuntimeExtensionInterface.php',
    'Twig\\Extension\\SandboxExtension' => $vendorDir . '/twig/twig/src/Extension/SandboxExtension.php',
    'Twig\\Extension\\StagingExtension' => $vendorDir . '/twig/twig/src/Extension/StagingExtension.php',
    'Twig\\Extension\\StringLoaderExtension' => $vendorDir . '/twig/twig/src/Extension/StringLoaderExtension.php',
    'Twig\\FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/src/FileExtensionEscapingStrategy.php',
    'Twig\\Lexer' => $vendorDir . '/twig/twig/src/Lexer.php',
    'Twig\\Loader\\ArrayLoader' => $vendorDir . '/twig/twig/src/Loader/ArrayLoader.php',
    'Twig\\Loader\\ChainLoader' => $vendorDir . '/twig/twig/src/Loader/ChainLoader.php',
    'Twig\\Loader\\ExistsLoaderInterface' => $vendorDir . '/twig/twig/src/Loader/ExistsLoaderInterface.php',
    'Twig\\Loader\\FilesystemLoader' => $vendorDir . '/twig/twig/src/Loader/FilesystemLoader.php',
    'Twig\\Loader\\LoaderInterface' => $vendorDir . '/twig/twig/src/Loader/LoaderInterface.php',
    'Twig\\Loader\\SourceContextLoaderInterface' => $vendorDir . '/twig/twig/src/Loader/SourceContextLoaderInterface.php',
    'Twig\\Markup' => $vendorDir . '/twig/twig/src/Markup.php',
    'Twig\\NodeTraverser' => $vendorDir . '/twig/twig/src/NodeTraverser.php',
    'Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
    'Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
    'Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
    'Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
    'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
    'Twig\\NodeVisitor\\SandboxNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php',
    'Twig\\Node\\AutoEscapeNode' => $vendorDir . '/twig/twig/src/Node/AutoEscapeNode.php',
    'Twig\\Node\\BlockNode' => $vendorDir . '/twig/twig/src/Node/BlockNode.php',
    'Twig\\Node\\BlockReferenceNode' => $vendorDir . '/twig/twig/src/Node/BlockReferenceNode.php',
    'Twig\\Node\\BodyNode' => $vendorDir . '/twig/twig/src/Node/BodyNode.php',
    'Twig\\Node\\CheckSecurityCallNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityCallNode.php',
    'Twig\\Node\\CheckSecurityNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityNode.php',
    'Twig\\Node\\CheckToStringNode' => $vendorDir . '/twig/twig/src/Node/CheckToStringNode.php',
    'Twig\\Node\\DeprecatedNode' => $vendorDir . '/twig/twig/src/Node/DeprecatedNode.php',
    'Twig\\Node\\DoNode' => $vendorDir . '/twig/twig/src/Node/DoNode.php',
    'Twig\\Node\\EmbedNode' => $vendorDir . '/twig/twig/src/Node/EmbedNode.php',
    'Twig\\Node\\Expression\\AbstractExpression' => $vendorDir . '/twig/twig/src/Node/Expression/AbstractExpression.php',
    'Twig\\Node\\Expression\\ArrayExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ArrayExpression.php',
    'Twig\\Node\\Expression\\ArrowFunctionExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ArrowFunctionExpression.php',
    'Twig\\Node\\Expression\\AssignNameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/AssignNameExpression.php',
    'Twig\\Node\\Expression\\Binary\\AbstractBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AbstractBinary.php',
    'Twig\\Node\\Expression\\Binary\\AddBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AddBinary.php',
    'Twig\\Node\\Expression\\Binary\\AndBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AndBinary.php',
    'Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
    'Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
    'Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
    'Twig\\Node\\Expression\\Binary\\ConcatBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ConcatBinary.php',
    'Twig\\Node\\Expression\\Binary\\DivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/DivBinary.php',
    'Twig\\Node\\Expression\\Binary\\EndsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php',
    'Twig\\Node\\Expression\\Binary\\EqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/EqualBinary.php',
    'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
    'Twig\\Node\\Expression\\Binary\\GreaterBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
    'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
    'Twig\\Node\\Expression\\Binary\\InBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
    'Twig\\Node\\Expression\\Binary\\LessBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
    'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
    'Twig\\Node\\Expression\\Binary\\MatchesBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MatchesBinary.php',
    'Twig\\Node\\Expression\\Binary\\ModBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ModBinary.php',
    'Twig\\Node\\Expression\\Binary\\MulBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MulBinary.php',
    'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php',
    'Twig\\Node\\Expression\\Binary\\NotInBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php',
    'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
    'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
    'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
    'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
    'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
    'Twig\\Node\\Expression\\BlockReferenceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
    'Twig\\Node\\Expression\\CallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/CallExpression.php',
    'Twig\\Node\\Expression\\ConditionalExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConditionalExpression.php',
    'Twig\\Node\\Expression\\ConstantExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConstantExpression.php',
    'Twig\\Node\\Expression\\FilterExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FilterExpression.php',
    'Twig\\Node\\Expression\\Filter\\DefaultFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php',
    'Twig\\Node\\Expression\\FunctionExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FunctionExpression.php',
    'Twig\\Node\\Expression\\GetAttrExpression' => $vendorDir . '/twig/twig/src/Node/Expression/GetAttrExpression.php',
    'Twig\\Node\\Expression\\InlinePrint' => $vendorDir . '/twig/twig/src/Node/Expression/InlinePrint.php',
    'Twig\\Node\\Expression\\MethodCallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/MethodCallExpression.php',
    'Twig\\Node\\Expression\\NameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/NameExpression.php',
    'Twig\\Node\\Expression\\NullCoalesceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/NullCoalesceExpression.php',
    'Twig\\Node\\Expression\\ParentExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ParentExpression.php',
    'Twig\\Node\\Expression\\TempNameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/TempNameExpression.php',
    'Twig\\Node\\Expression\\TestExpression' => $vendorDir . '/twig/twig/src/Node/Expression/TestExpression.php',
    'Twig\\Node\\Expression\\Unary\\AbstractUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/AbstractUnary.php',
    'Twig\\Node\\Expression\\Unary\\NegUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
    'Twig\\Node\\Expression\\Unary\\NotUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
    'Twig\\Node\\Expression\\Unary\\PosUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
    'Twig\\Node\\FlushNode' => $vendorDir . '/twig/twig/src/Node/FlushNode.php',
    'Twig\\Node\\ForLoopNode' => $vendorDir . '/twig/twig/src/Node/ForLoopNode.php',
    'Twig\\Node\\ForNode' => $vendorDir . '/twig/twig/src/Node/ForNode.php',
    'Twig\\Node\\IfNode' => $vendorDir . '/twig/twig/src/Node/IfNode.php',
    'Twig\\Node\\ImportNode' => $vendorDir . '/twig/twig/src/Node/ImportNode.php',
    'Twig\\Node\\IncludeNode' => $vendorDir . '/twig/twig/src/Node/IncludeNode.php',
    'Twig\\Node\\MacroNode' => $vendorDir . '/twig/twig/src/Node/MacroNode.php',
    'Twig\\Node\\ModuleNode' => $vendorDir . '/twig/twig/src/Node/ModuleNode.php',
    'Twig\\Node\\Node' => $vendorDir . '/twig/twig/src/Node/Node.php',
    'Twig\\Node\\NodeCaptureInterface' => $vendorDir . '/twig/twig/src/Node/NodeCaptureInterface.php',
    'Twig\\Node\\NodeOutputInterface' => $vendorDir . '/twig/twig/src/Node/NodeOutputInterface.php',
    'Twig\\Node\\PrintNode' => $vendorDir . '/twig/twig/src/Node/PrintNode.php',
    'Twig\\Node\\SandboxNode' => $vendorDir . '/twig/twig/src/Node/SandboxNode.php',
    'Twig\\Node\\SandboxedPrintNode' => $vendorDir . '/twig/twig/src/Node/SandboxedPrintNode.php',
    'Twig\\Node\\SetNode' => $vendorDir . '/twig/twig/src/Node/SetNode.php',
    'Twig\\Node\\SetTempNode' => $vendorDir . '/twig/twig/src/Node/SetTempNode.php',
    'Twig\\Node\\SpacelessNode' => $vendorDir . '/twig/twig/src/Node/SpacelessNode.php',
    'Twig\\Node\\TextNode' => $vendorDir . '/twig/twig/src/Node/TextNode.php',
    'Twig\\Node\\WithNode' => $vendorDir . '/twig/twig/src/Node/WithNode.php',
    'Twig\\Parser' => $vendorDir . '/twig/twig/src/Parser.php',
    'Twig\\Profiler\\Dumper\\BaseDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/BaseDumper.php',
    'Twig\\Profiler\\Dumper\\BlackfireDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/BlackfireDumper.php',
    'Twig\\Profiler\\Dumper\\HtmlDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/HtmlDumper.php',
    'Twig\\Profiler\\Dumper\\TextDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/TextDumper.php',
    'Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => $vendorDir . '/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
    'Twig\\Profiler\\Node\\EnterProfileNode' => $vendorDir . '/twig/twig/src/Profiler/Node/EnterProfileNode.php',
    'Twig\\Profiler\\Node\\LeaveProfileNode' => $vendorDir . '/twig/twig/src/Profiler/Node/LeaveProfileNode.php',
    'Twig\\Profiler\\Profile' => $vendorDir . '/twig/twig/src/Profiler/Profile.php',
    'Twig\\RuntimeLoader\\ContainerRuntimeLoader' => $vendorDir . '/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
    'Twig\\RuntimeLoader\\FactoryRuntimeLoader' => $vendorDir . '/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
    'Twig\\RuntimeLoader\\RuntimeLoaderInterface' => $vendorDir . '/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
    'Twig\\Sandbox\\SecurityError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityError.php',
    'Twig\\Sandbox\\SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
    'Twig\\Sandbox\\SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
    'Twig\\Sandbox\\SecurityNotAllowedMethodError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
    'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
    'Twig\\Sandbox\\SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php',
    'Twig\\Sandbox\\SecurityPolicy' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicy.php',
    'Twig\\Sandbox\\SecurityPolicyInterface' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php',
    'Twig\\Source' => $vendorDir . '/twig/twig/src/Source.php',
    'Twig\\Template' => $vendorDir . '/twig/twig/src/Template.php',
    'Twig\\TemplateWrapper' => $vendorDir . '/twig/twig/src/TemplateWrapper.php',
    'Twig\\Token' => $vendorDir . '/twig/twig/src/Token.php',
    'Twig\\TokenParser\\AbstractTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
    'Twig\\TokenParser\\ApplyTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ApplyTokenParser.php',
    'Twig\\TokenParser\\AutoEscapeTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AutoEscapeTokenParser.php',
    'Twig\\TokenParser\\BlockTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/BlockTokenParser.php',
    'Twig\\TokenParser\\DeprecatedTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/DeprecatedTokenParser.php',
    'Twig\\TokenParser\\DoTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/DoTokenParser.php',
    'Twig\\TokenParser\\EmbedTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/EmbedTokenParser.php',
    'Twig\\TokenParser\\ExtendsTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ExtendsTokenParser.php',
    'Twig\\TokenParser\\FilterTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FilterTokenParser.php',
    'Twig\\TokenParser\\FlushTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FlushTokenParser.php',
    'Twig\\TokenParser\\ForTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ForTokenParser.php',
    'Twig\\TokenParser\\FromTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FromTokenParser.php',
    'Twig\\TokenParser\\IfTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/IfTokenParser.php',
    'Twig\\TokenParser\\ImportTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ImportTokenParser.php',
    'Twig\\TokenParser\\IncludeTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/IncludeTokenParser.php',
    'Twig\\TokenParser\\MacroTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/MacroTokenParser.php',
    'Twig\\TokenParser\\SandboxTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SandboxTokenParser.php',
    'Twig\\TokenParser\\SetTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SetTokenParser.php',
    'Twig\\TokenParser\\SpacelessTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SpacelessTokenParser.php',
    'Twig\\TokenParser\\TokenParserInterface' => $vendorDir . '/twig/twig/src/TokenParser/TokenParserInterface.php',
    'Twig\\TokenParser\\UseTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/UseTokenParser.php',
    'Twig\\TokenParser\\WithTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/WithTokenParser.php',
    'Twig\\TokenStream' => $vendorDir . '/twig/twig/src/TokenStream.php',
    'Twig\\TwigFilter' => $vendorDir . '/twig/twig/src/TwigFilter.php',
    'Twig\\TwigFunction' => $vendorDir . '/twig/twig/src/TwigFunction.php',
    'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php',
    'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php',
    'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
    'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
    'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
    'Twig_Cache_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Cache/Filesystem.php',
    'Twig_Cache_Null' => $vendorDir . '/twig/twig/lib/Twig/Cache/Null.php',
    'Twig_Compiler' => $vendorDir . '/twig/twig/lib/Twig/Compiler.php',
    'Twig_CompilerInterface' => $vendorDir . '/twig/twig/lib/Twig/CompilerInterface.php',
    'Twig_ContainerRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
    'Twig_Environment' => $vendorDir . '/twig/twig/lib/Twig/Environment.php',
    'Twig_Error' => $vendorDir . '/twig/twig/lib/Twig/Error.php',
    'Twig_Error_Loader' => $vendorDir . '/twig/twig/lib/Twig/Error/Loader.php',
    'Twig_Error_Runtime' => $vendorDir . '/twig/twig/lib/Twig/Error/Runtime.php',
    'Twig_Error_Syntax' => $vendorDir . '/twig/twig/lib/Twig/Error/Syntax.php',
    'Twig_ExistsLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/ExistsLoaderInterface.php',
    'Twig_ExpressionParser' => $vendorDir . '/twig/twig/lib/Twig/ExpressionParser.php',
    'Twig_Extension' => $vendorDir . '/twig/twig/lib/Twig/Extension.php',
    'Twig_ExtensionInterface' => $vendorDir . '/twig/twig/lib/Twig/ExtensionInterface.php',
    'Twig_Extension_Core' => $vendorDir . '/twig/twig/lib/Twig/Extension/Core.php',
    'Twig_Extension_Debug' => $vendorDir . '/twig/twig/lib/Twig/Extension/Debug.php',
    'Twig_Extension_Escaper' => $vendorDir . '/twig/twig/lib/Twig/Extension/Escaper.php',
    'Twig_Extension_GlobalsInterface' => $vendorDir . '/twig/twig/lib/Twig/Extension/GlobalsInterface.php',
    'Twig_Extension_InitRuntimeInterface' => $vendorDir . '/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php',
    'Twig_Extension_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/Extension/Optimizer.php',
    'Twig_Extension_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Extension/Profiler.php',
    'Twig_Extension_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Extension/Sandbox.php',
    'Twig_Extension_Staging' => $vendorDir . '/twig/twig/lib/Twig/Extension/Staging.php',
    'Twig_Extension_StringLoader' => $vendorDir . '/twig/twig/lib/Twig/Extension/StringLoader.php',
    'Twig_FactoryRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
    'Twig_FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
    'Twig_Filter' => $vendorDir . '/twig/twig/lib/Twig/Filter.php',
    'Twig_FilterCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterCallableInterface.php',
    'Twig_FilterInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterInterface.php',
    'Twig_Filter_Function' => $vendorDir . '/twig/twig/lib/Twig/Filter/Function.php',
    'Twig_Filter_Method' => $vendorDir . '/twig/twig/lib/Twig/Filter/Method.php',
    'Twig_Filter_Node' => $vendorDir . '/twig/twig/lib/Twig/Filter/Node.php',
    'Twig_Function' => $vendorDir . '/twig/twig/lib/Twig/Function.php',
    'Twig_FunctionCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
    'Twig_FunctionInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionInterface.php',
    'Twig_Function_Function' => $vendorDir . '/twig/twig/lib/Twig/Function/Function.php',
    'Twig_Function_Method' => $vendorDir . '/twig/twig/lib/Twig/Function/Method.php',
    'Twig_Function_Node' => $vendorDir . '/twig/twig/lib/Twig/Function/Node.php',
    'Twig_Lexer' => $vendorDir . '/twig/twig/lib/Twig/Lexer.php',
    'Twig_LexerInterface' => $vendorDir . '/twig/twig/lib/Twig/LexerInterface.php',
    'Twig_LoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/LoaderInterface.php',
    'Twig_Loader_Array' => $vendorDir . '/twig/twig/lib/Twig/Loader/Array.php',
    'Twig_Loader_Chain' => $vendorDir . '/twig/twig/lib/Twig/Loader/Chain.php',
    'Twig_Loader_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Loader/Filesystem.php',
    'Twig_Loader_String' => $vendorDir . '/twig/twig/lib/Twig/Loader/String.php',
    'Twig_Markup' => $vendorDir . '/twig/twig/lib/Twig/Markup.php',
    'Twig_Node' => $vendorDir . '/twig/twig/lib/Twig/Node.php',
    'Twig_NodeCaptureInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
    'Twig_NodeInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeInterface.php',
    'Twig_NodeOutputInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeOutputInterface.php',
    'Twig_NodeTraverser' => $vendorDir . '/twig/twig/lib/Twig/NodeTraverser.php',
    'Twig_NodeVisitorInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
    'Twig_NodeVisitor_Escaper' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Escaper.php',
    'Twig_NodeVisitor_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Optimizer.php',
    'Twig_NodeVisitor_SafeAnalysis' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
    'Twig_NodeVisitor_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Sandbox.php',
    'Twig_Node_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/Node/AutoEscape.php',
    'Twig_Node_Block' => $vendorDir . '/twig/twig/lib/Twig/Node/Block.php',
    'Twig_Node_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/BlockReference.php',
    'Twig_Node_Body' => $vendorDir . '/twig/twig/lib/Twig/Node/Body.php',
    'Twig_Node_CheckSecurity' => $vendorDir . '/twig/twig/lib/Twig/Node/CheckSecurity.php',
    'Twig_Node_Deprecated' => $vendorDir . '/twig/twig/lib/Twig/Node/Deprecated.php',
    'Twig_Node_Do' => $vendorDir . '/twig/twig/lib/Twig/Node/Do.php',
    'Twig_Node_Embed' => $vendorDir . '/twig/twig/lib/Twig/Node/Embed.php',
    'Twig_Node_Expression' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression.php',
    'Twig_Node_Expression_Array' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Array.php',
    'Twig_Node_Expression_AssignName' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/AssignName.php',
    'Twig_Node_Expression_Binary' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary.php',
    'Twig_Node_Expression_Binary_Add' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Add.php',
    'Twig_Node_Expression_Binary_And' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/And.php',
    'Twig_Node_Expression_Binary_BitwiseAnd' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
    'Twig_Node_Expression_Binary_BitwiseOr' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
    'Twig_Node_Expression_Binary_BitwiseXor' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
    'Twig_Node_Expression_Binary_Concat' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php',
    'Twig_Node_Expression_Binary_Div' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Div.php',
    'Twig_Node_Expression_Binary_EndsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
    'Twig_Node_Expression_Binary_Equal' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php',
    'Twig_Node_Expression_Binary_FloorDiv' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
    'Twig_Node_Expression_Binary_Greater' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php',
    'Twig_Node_Expression_Binary_GreaterEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
    'Twig_Node_Expression_Binary_In' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/In.php',
    'Twig_Node_Expression_Binary_Less' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Less.php',
    'Twig_Node_Expression_Binary_LessEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
    'Twig_Node_Expression_Binary_Matches' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php',
    'Twig_Node_Expression_Binary_Mod' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php',
    'Twig_Node_Expression_Binary_Mul' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php',
    'Twig_Node_Expression_Binary_NotEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
    'Twig_Node_Expression_Binary_NotIn' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
    'Twig_Node_Expression_Binary_Or' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Or.php',
    'Twig_Node_Expression_Binary_Power' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Power.php',
    'Twig_Node_Expression_Binary_Range' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Range.php',
    'Twig_Node_Expression_Binary_StartsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
    'Twig_Node_Expression_Binary_Sub' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php',
    'Twig_Node_Expression_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/BlockReference.php',
    'Twig_Node_Expression_Call' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Call.php',
    'Twig_Node_Expression_Conditional' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
    'Twig_Node_Expression_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
    'Twig_Node_Expression_ExtensionReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
    'Twig_Node_Expression_Filter' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
    'Twig_Node_Expression_Filter_Default' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
    'Twig_Node_Expression_Function' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Function.php',
    'Twig_Node_Expression_GetAttr' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/GetAttr.php',
    'Twig_Node_Expression_MethodCall' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/MethodCall.php',
    'Twig_Node_Expression_Name' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Name.php',
    'Twig_Node_Expression_NullCoalesce' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php',
    'Twig_Node_Expression_Parent' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Parent.php',
    'Twig_Node_Expression_TempName' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/TempName.php',
    'Twig_Node_Expression_Unary' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary.php',
    'Twig_Node_Expression_Unary_Neg' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php',
    'Twig_Node_Expression_Unary_Not' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Not.php',
    'Twig_Node_Expression_Unary_Pos' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php',
    'Twig_Node_Flush' => $vendorDir . '/twig/twig/lib/Twig/Node/Flush.php',
    'Twig_Node_For' => $vendorDir . '/twig/twig/lib/Twig/Node/For.php',
    'Twig_Node_ForLoop' => $vendorDir . '/twig/twig/lib/Twig/Node/ForLoop.php',
    'Twig_Node_If' => $vendorDir . '/twig/twig/lib/Twig/Node/If.php',
    'Twig_Node_Import' => $vendorDir . '/twig/twig/lib/Twig/Node/Import.php',
    'Twig_Node_Include' => $vendorDir . '/twig/twig/lib/Twig/Node/Include.php',
    'Twig_Node_Macro' => $vendorDir . '/twig/twig/lib/Twig/Node/Macro.php',
    'Twig_Node_Module' => $vendorDir . '/twig/twig/lib/Twig/Node/Module.php',
    'Twig_Node_Print' => $vendorDir . '/twig/twig/lib/Twig/Node/Print.php',
    'Twig_Node_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Node/Sandbox.php',
    'Twig_Node_SandboxedPrint' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
    'Twig_Node_Set' => $vendorDir . '/twig/twig/lib/Twig/Node/Set.php',
    'Twig_Node_SetTemp' => $vendorDir . '/twig/twig/lib/Twig/Node/SetTemp.php',
    'Twig_Node_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/Node/Spaceless.php',
    'Twig_Node_Text' => $vendorDir . '/twig/twig/lib/Twig/Node/Text.php',
    'Twig_Node_With' => $vendorDir . '/twig/twig/lib/Twig/Node/With.php',
    'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
    'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
    'Twig_Profiler_Dumper_Base' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
    'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
    'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
    'Twig_Profiler_Dumper_Text' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
    'Twig_Profiler_NodeVisitor_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
    'Twig_Profiler_Node_EnterProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php',
    'Twig_Profiler_Node_LeaveProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
    'Twig_Profiler_Profile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Profile.php',
    'Twig_RuntimeLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/RuntimeLoaderInterface.php',
    'Twig_Sandbox_SecurityError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityError.php',
    'Twig_Sandbox_SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
    'Twig_Sandbox_SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
    'Twig_Sandbox_SecurityNotAllowedMethodError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
    'Twig_Sandbox_SecurityNotAllowedPropertyError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
    'Twig_Sandbox_SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
    'Twig_Sandbox_SecurityPolicy' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php',
    'Twig_Sandbox_SecurityPolicyInterface' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
    'Twig_SimpleFilter' => $vendorDir . '/twig/twig/lib/Twig/SimpleFilter.php',
    'Twig_SimpleFunction' => $vendorDir . '/twig/twig/lib/Twig/SimpleFunction.php',
    'Twig_Source' => $vendorDir . '/twig/twig/lib/Twig/Source.php',
    'Twig_SourceContextLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
    'Twig_Template' => $vendorDir . '/twig/twig/lib/Twig/Template.php',
    'Twig_TemplateInterface' => $vendorDir . '/twig/twig/lib/Twig/TemplateInterface.php',
    'Twig_TemplateWrapper' => $vendorDir . '/twig/twig/lib/Twig/TemplateWrapper.php',
    'Twig_TestCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/TestCallableInterface.php',
    'Twig_TestInterface' => $vendorDir . '/twig/twig/lib/Twig/TestInterface.php',
    'Twig_Token' => $vendorDir . '/twig/twig/lib/Twig/Token.php',
    'Twig_TokenParser' => $vendorDir . '/twig/twig/lib/Twig/TokenParser.php',
    'Twig_TokenParserBroker' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBroker.php',
    'Twig_TokenParserBrokerInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
    'Twig_TokenParserInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserInterface.php',
    'Twig_TokenParser_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
    'Twig_TokenParser_Block' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Block.php',
    'Twig_TokenParser_Deprecated' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Deprecated.php',
    'Twig_TokenParser_Do' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Do.php',
    'Twig_TokenParser_Embed' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Embed.php',
    'Twig_TokenParser_Extends' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Extends.php',
    'Twig_TokenParser_Filter' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Filter.php',
    'Twig_TokenParser_Flush' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Flush.php',
    'Twig_TokenParser_For' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/For.php',
    'Twig_TokenParser_From' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/From.php',
    'Twig_TokenParser_If' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/If.php',
    'Twig_TokenParser_Import' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Import.php',
    'Twig_TokenParser_Include' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Include.php',
    'Twig_TokenParser_Macro' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Macro.php',
    'Twig_TokenParser_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Sandbox.php',
    'Twig_TokenParser_Set' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Set.php',
    'Twig_TokenParser_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Spaceless.php',
    'Twig_TokenParser_Use' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Use.php',
    'Twig_TokenParser_With' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/With.php',
    'Twig_TokenStream' => $vendorDir . '/twig/twig/lib/Twig/TokenStream.php',
    'Twig_Util_DeprecationCollector' => $vendorDir . '/twig/twig/lib/Twig/Util/DeprecationCollector.php',
    'Twig_Util_TemplateDirIterator' => $vendorDir . '/twig/twig/lib/Twig/Util/TemplateDirIterator.php',
    'Universal\\ClassLoader\\ApcClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/ApcClassLoader.php',
    'Universal\\ClassLoader\\BasePathClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/BasePathClassLoader.php',
    'Universal\\ClassLoader\\BytecodeClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/BytecodeClassLoader.php',
    'Universal\\ClassLoader\\ChainedClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/ChainedClassLoader.php',
    'Universal\\ClassLoader\\ClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/ClassLoader.php',
    'Universal\\ClassLoader\\MapClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/MapClassLoader.php',
    'Universal\\ClassLoader\\PathIncluder' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/PathIncluder.php',
    'Universal\\ClassLoader\\Psr0ClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/Psr0ClassLoader.php',
    'Universal\\ClassLoader\\Psr4ClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/Psr4ClassLoader.php',
    'Universal\\ClassLoader\\SplClassLoader' => $vendorDir . '/corneltek/universal/src/Universal/ClassLoader/SplClassLoader.php',
    'Universal\\Container\\ObjectContainer' => $vendorDir . '/corneltek/universal/src/Universal/Container/ObjectContainer.php',
    'Universal\\Event\\PhpEvent' => $vendorDir . '/corneltek/universal/src/Universal/Event/PhpEvent.php',
    'Universal\\Exception\\InvalidUploadFileException' => $vendorDir . '/corneltek/universal/src/Universal/Exception/InvalidUploadFileException.php',
    'Universal\\Exception\\UploadErrorException' => $vendorDir . '/corneltek/universal/src/Universal/Exception/UploadErrorException.php',
    'Universal\\Exception\\UploadException' => $vendorDir . '/corneltek/universal/src/Universal/Exception/UploadException.php',
    'Universal\\Exception\\UploadedFileMoveFailException' => $vendorDir . '/corneltek/universal/src/Universal/Exception/UploadedFileMoveFailException.php',
    'Universal\\FileSystem\\PathUtils' => $vendorDir . '/corneltek/universal/src/Universal/FileSystem/PathUtils.php',
    'Universal\\Http\\Cookie' => $vendorDir . '/corneltek/universal/src/Universal/Http/Cookie.php',
    'Universal\\Http\\FilesParameter' => $vendorDir . '/corneltek/universal/src/Universal/Http/FilesParameter.php',
    'Universal\\Http\\HttpRequest' => $vendorDir . '/corneltek/universal/src/Universal/Http/HttpRequest.php',
    'Universal\\Http\\HttpResponse' => $vendorDir . '/corneltek/universal/src/Universal/Http/HttpResponse.php',
    'Universal\\Http\\Parameter' => $vendorDir . '/corneltek/universal/src/Universal/Http/Parameter.php',
    'Universal\\Http\\PutHandle' => $vendorDir . '/corneltek/universal/src/Universal/Http/PutHandle.php',
    'Universal\\Http\\StreamResponse' => $vendorDir . '/corneltek/universal/src/Universal/Http/StreamResponse.php',
    'Universal\\Http\\UploadedFile' => $vendorDir . '/corneltek/universal/src/Universal/Http/UploadedFile.php',
    'Universal\\Requirement\\Requirement' => $vendorDir . '/corneltek/universal/src/Universal/Requirement/Requirement.php',
);
<?php

// platform_check.php @generated by Composer

$issues = array();

if (!(PHP_VERSION_ID >= 70205)) {
    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.';
}

if ($issues) {
    if (!headers_sent()) {
        header('HTTP/1.1 500 Internal Server Error');
    }
    if (!ini_get('display_errors')) {
        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
        } elseif (!headers_sent()) {
            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
        }
    }
    trigger_error(
        'Composer detected issues in your platform: ' . implode(' ', $issues),
        E_USER_ERROR
    );
}
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit365e25e34522fee120bee0a71e662cb3
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    /**
     * @return \Composer\Autoload\ClassLoader
     */
    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        require __DIR__ . '/platform_check.php';

        spl_autoload_register(array('ComposerAutoloaderInit365e25e34522fee120bee0a71e662cb3', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
        spl_autoload_unregister(array('ComposerAutoloaderInit365e25e34522fee120bee0a71e662cb3', 'loadClassLoader'));

        require __DIR__ . '/autoload_static.php';
        call_user_func(\Composer\Autoload\ComposerStaticInit365e25e34522fee120bee0a71e662cb3::getInitializer($loader));

        $loader->setClassMapAuthoritative(true);
        $loader->register(true);

        $includeFiles = \Composer\Autoload\ComposerStaticInit365e25e34522fee120bee0a71e662cb3::$files;
        foreach ($includeFiles as $fileIdentifier => $file) {
            composerRequire365e25e34522fee120bee0a71e662cb3($fileIdentifier, $file);
        }

        return $loader;
    }
}

/**
 * @param string $fileIdentifier
 * @param string $file
 * @return void
 */
function composerRequire365e25e34522fee120bee0a71e662cb3($fileIdentifier, $file)
{
    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

        require $file;
    }
}
The MIT License (MIT)

Copyright (c) 2013-2016 container-interop
Copyright (c) 2016 PHP Framework Interoperability Group

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<?php

declare(strict_types=1);

namespace Psr\Container;




interface ContainerInterface
{










public function get(string $id);












public function has(string $id): bool;
}
<?php

namespace Psr\Container;




interface NotFoundExceptionInterface extends ContainerExceptionInterface
{
}
<?php

namespace Psr\Container;




interface ContainerExceptionInterface
{
}
Copyright (c) 2009-2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

























namespace Pimple\Psr11;

use Pimple\Container as PimpleContainer;
use Pimple\Exception\UnknownIdentifierException;
use Psr\Container\ContainerInterface;






class ServiceLocator implements ContainerInterface
{
private $container;
private $aliases = [];





public function __construct(PimpleContainer $container, array $ids)
{
$this->container = $container;

foreach ($ids as $key => $id) {
$this->aliases[\is_int($key) ? $id : $key] = $id;
}
}




public function get(string $id)
{
if (!isset($this->aliases[$id])) {
throw new UnknownIdentifierException($id);
}

return $this->container[$this->aliases[$id]];
}




public function has(string $id): bool
{
return isset($this->aliases[$id]) && isset($this->container[$this->aliases[$id]]);
}
}
<?php

























namespace Pimple\Psr11;

use Pimple\Container as PimpleContainer;
use Psr\Container\ContainerInterface;






final class Container implements ContainerInterface
{
private $pimple;

public function __construct(PimpleContainer $pimple)
{
$this->pimple = $pimple;
}

public function get(string $id)
{
return $this->pimple[$id];
}

public function has(string $id): bool
{
return isset($this->pimple[$id]);
}
}
<?php

























namespace Pimple;







interface ServiceProviderInterface
{






public function register(Container $pimple);
}
<?php

























namespace Pimple;

use Pimple\Exception\ExpectedInvokableException;
use Pimple\Exception\FrozenServiceException;
use Pimple\Exception\InvalidServiceIdentifierException;
use Pimple\Exception\UnknownIdentifierException;






class Container implements \ArrayAccess
{
private $values = [];
private $factories;
private $protected;
private $frozen = [];
private $raw = [];
private $keys = [];








public function __construct(array $values = [])
{
$this->factories = new \SplObjectStorage();
$this->protected = new \SplObjectStorage();

foreach ($values as $key => $value) {
$this->offsetSet($key, $value);
}
}

















#[\ReturnTypeWillChange]
public function offsetSet($id, $value)
{
if (isset($this->frozen[$id])) {
throw new FrozenServiceException($id);
}

$this->values[$id] = $value;
$this->keys[$id] = true;
}










#[\ReturnTypeWillChange]
public function offsetGet($id)
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}

if (
isset($this->raw[$id])
|| !\is_object($this->values[$id])
|| isset($this->protected[$this->values[$id]])
|| !\method_exists($this->values[$id], '__invoke')
) {
return $this->values[$id];
}

if (isset($this->factories[$this->values[$id]])) {
return $this->values[$id]($this);
}

$raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw;

$this->frozen[$id] = true;

return $val;
}








#[\ReturnTypeWillChange]
public function offsetExists($id)
{
return isset($this->keys[$id]);
}








#[\ReturnTypeWillChange]
public function offsetUnset($id)
{
if (isset($this->keys[$id])) {
if (\is_object($this->values[$id])) {
unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);
}

unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);
}
}










public function factory($callable)
{
if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.');
}

$this->factories->attach($callable);

return $callable;
}












public function protect($callable)
{
if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
throw new ExpectedInvokableException('Callable is not a Closure or invokable object.');
}

$this->protected->attach($callable);

return $callable;
}










public function raw($id)
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}

if (isset($this->raw[$id])) {
return $this->raw[$id];
}

return $this->values[$id];
}

















public function extend($id, $callable)
{
if (!isset($this->keys[$id])) {
throw new UnknownIdentifierException($id);
}

if (isset($this->frozen[$id])) {
throw new FrozenServiceException($id);
}

if (!\is_object($this->values[$id]) || !\method_exists($this->values[$id], '__invoke')) {
throw new InvalidServiceIdentifierException($id);
}

if (isset($this->protected[$this->values[$id]])) {
@\trigger_error(\sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), E_USER_DEPRECATED);
}

if (!\is_object($callable) || !\method_exists($callable, '__invoke')) {
throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.');
}

$factory = $this->values[$id];

$extended = function ($c) use ($callable, $factory) {
return $callable($factory($c), $c);
};

if (isset($this->factories[$factory])) {
$this->factories->detach($factory);
$this->factories->attach($extended);
}

return $this[$id] = $extended;
}






public function keys()
{
return \array_keys($this->values);
}








public function register(ServiceProviderInterface $provider, array $values = [])
{
$provider->register($this);

foreach ($values as $key => $value) {
$this[$key] = $value;
}

return $this;
}
}
<?php

























namespace Pimple;






final class ServiceIterator implements \Iterator
{
private $container;
private $ids;

public function __construct(Container $container, array $ids)
{
$this->container = $container;
$this->ids = $ids;
}




#[\ReturnTypeWillChange]
public function rewind()
{
\reset($this->ids);
}




#[\ReturnTypeWillChange]
public function current()
{
return $this->container[\current($this->ids)];
}




#[\ReturnTypeWillChange]
public function key()
{
return \current($this->ids);
}




#[\ReturnTypeWillChange]
public function next()
{
\next($this->ids);
}




#[\ReturnTypeWillChange]
public function valid()
{
return null !== \key($this->ids);
}
}
<?php

























namespace Pimple\Exception;

use Psr\Container\NotFoundExceptionInterface;






class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
{



public function __construct($id)
{
parent::__construct(\sprintf('Identifier "%s" is not defined.', $id));
}
}
<?php

























namespace Pimple\Exception;

use Psr\Container\ContainerExceptionInterface;






class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface
{
}
<?php

























namespace Pimple\Exception;

use Psr\Container\NotFoundExceptionInterface;






class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface
{



public function __construct($id)
{
parent::__construct(\sprintf('Identifier "%s" does not contain an object definition.', $id));
}
}
<?php

























namespace Pimple\Exception;

use Psr\Container\ContainerExceptionInterface;






class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface
{



public function __construct($id)
{
parent::__construct(\sprintf('Cannot override frozen service "%s".', $id));
}
}
Copyright (c) 2011 Yo-An Lin 

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
   must display the following acknowledgement:
     This product includes software developed by the University of
     California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
<?php
namespace CLIFramework;
use CLIFramework\ValueCollection;

class ArgInfo
{
public $name;

public $isa;

public $optional;

public $multiple;

public $suggestions;

public $validValues;

protected $validator;


public $glob;

public function __construct($name, $desc = null)
{
$this->name = $name;
if ($desc) {
$this->desc = $desc;
}
}

public function isa($isa) {
$this->isa = $isa;
return $this;
}

public function desc($desc) {
$this->desc = $desc;
return $this;
}

public function optional($optional = true) {
$this->optional = $optional;
return $this;
}

public function multiple($a = true) {
$this->multiple = $a;
return $this;
}

public function validValues($val) {
$this->validValues = $val;
return $this;
}

public function validator($cb) {
$this->validator = $cb;
return $this;
}










public function suggestions($values) {
$this->suggestions = $values;
return $this;
}





public function glob($g) {
$this->glob = $g;
return $this;
}


public function getSuggestions() {
if ($this->suggestions) {
if (is_callable($this->suggestions)) {
return call_user_func($this->suggestions);
}
return $this->suggestions;
}
}


public function getValidValues() {
if ($this->validValues) {
if (is_callable($this->validValues)) {
return call_user_func($this->validValues);
}
return $this->validValues;
}
}




public function validate($value) {
if ($this->isa) {
switch($this->isa) {
case "number":
return is_numeric($value);
case "boolean":
return is_bool($value);
case "string":
return is_string($value);
}
}
$validValues = $this->getValidValues();
if ($validValues && $validValues instanceof ValueCollection) {
return $validValues->containsValue($value);
} elseif ( is_array($validValues) ) {
return in_array($value, $validValues);
}
if ($this->validator) {
return call_user_func($this->validator);
}
return true;
}

}


<?php









namespace CLIFramework;
use CLIFramework\Exception\CommandClassNotFoundException;
use Exception;

class CommandLoader
{
public $namespaces = array();

public function addNamespace( $ns )
{
$nss = (array) $ns;
foreach ($nss as $n) {
$this->namespaces[] = $n;
}
}













public function translate($command)
{
$args = explode('-',$command);
foreach($args as & $a) {
$a = ucfirst($a);
}
return join('',$args) . 'Command';
}












public function inverseTranslate($className)
{
if (substr($className, -7) !== 'Command')
throw new \InvalidArgumentException("Command class name need to end with 'Command'");

$className = lcfirst(substr($className, 0, -7));
return preg_replace_callback(
'/[A-Z]/',
function ($matches) { return '-' . strtolower($matches[0]); },
$className
);
}







public function load($command)
{
$subclass = $this->translate($command);
return $this->loadClass( $subclass );
}







public function loadClass($class)
{
if (class_exists($class)) {
return $class;
}



foreach ($this->namespaces as $ns) {
$fullclass = $ns . '\\' . $class;
if (class_exists($fullclass)) {
return $fullclass;
}
}
throw new CommandClassNotFoundException($class, $this->namespaces);
}









public function loadSubcommand($subcommand, $parent)
{
$parent_class = get_class($parent);
$class = '\\' . $parent_class . '\\' . $this->translate($subcommand);
return $this->loadClass($class);
}

static public function getInstance() {
static $instance;
if ( $instance ) {
return $instance;
}
return $instance = new self;
}

}
<?php








namespace CLIFramework;
use Exception;
use CLIFramework\CommandInterface;
use CLIFramework\Exception\CommandClassNotFoundException;
use CLIFramework\Application;





abstract class Command extends CommandBase
implements CommandInterface
{



public $application;

public $name;

public function __construct(CommandBase $parent = null)
{
parent::__construct($parent);
}

public function setApplication(Application $application)
{
$this->application = $application;
}







public function getApplication() {
if ($this->application) {
return $this->application;
}
$p = $this->parent;
while (true) {
if ( ! $p ) {
return null;
}
if ($p instanceof Application) {
return $p;
}
$p = $p->parent;
}
}

public function hasApplication() {
return $this->getApplication() !== null;
}

public function setName($name)
{
$this->name = $name;
}






public function getName()
{
if ($this->name) {
return $this->name;
}


$class = get_class($this);

$parts = explode('\\',$class);
$class = end($parts);
$class = preg_replace( '/Command$/','', $class );
return strtolower( preg_replace( '/(?<=[a-z])([A-Z])/', '-\1' , $class ) );
}







public function getLogger()
{
return $this->getApplication()->getLogger();
}








public function getFormatter()
{
return $this->getApplication()->getFormatter();
}




public function aliases() {
return array();
}








public function __get($k)
{
if ($k === 'logger') {
return $this->getLogger();
}
elseif( $k === 'formatter' ) {
return $this->getFormatter();
}
throw new Exception( "$k is not defined." );
}

}
<?php
namespace CLIFramework;
use CLIFramework\Command;
use CLIFramework\CommandBase;

class CommandGroup
{
public $id;

public $name;

public $desc;

public $commands = array();

public $isHidden = false;

public function __construct($groupName, $commands = array())
{
$this->name = $groupName;
$this->commands = $commands;
}

public function setId($id)
{
$this->id = $id;
return $this;
}

public function getId()
{
return $this->id ?: $this->getName();
}

public function getName() {
return $this->name;
}

public function addCommand($name, CommandBase $command) {
$this->commands[$name] = $command;
return $this;
}

public function getCommands() {
return $this->commands;
}

public function getCommandNames() {
return array_keys($this->commands);
}







public function setDesc($desc)
{
$this->desc = $desc;
return $this;
}




public function getDesc() {
return $this->desc;
}

public function hidden() {
$this->isHidden = true;
return $this;
}
}


<?php









namespace CLIFramework;
use GetOptionKit\ContinuousOptionParser;
use GetOptionKit\OptionCollection;

use CLIFramework\CommandLoader;
use CLIFramework\CommandBase;
use CLIFramework\Logger;
use CLIFramework\CommandInterface;
use CLIFramework\Prompter;
use CLIFramework\CommandGroup;
use CLIFramework\Formatter;
use CLIFramework\Corrector;
use CLIFramework\ServiceContainer;
use CLIFramework\Exception\CommandNotFoundException;
use CLIFramework\Exception\CommandArgumentNotEnoughException;
use CLIFramework\Exception\ExecuteMethodNotDefinedException;
use Pimple\Container;

use CLIFramework\ExceptionPrinter\ProductionExceptionPrinter;
use CLIFramework\ExceptionPrinter\DevelopmentExceptionPrinter;

use Exception;
use ReflectionClass;
use InvalidArgumentException;
use BadMethodCallException;

class Application extends CommandBase
implements CommandInterface
{
const CORE_VERSION = '2.5.4';
const VERSION = "2.8.1";
const NAME = 'CLIFramework';





public $startedAt;


public $supportReadline;


public $showAppSignature = true;





public $topics = array();




public $formatter;








public $logger;


public $programName;







protected $serviceContainer;





protected $eventService;





protected $globalConfig;



protected $commandAutoloadEnabled = false;

public function __construct(Container $container = null, CommandBase $parent = null)
{
parent::__construct($parent);

$this->serviceContainer = $container ?: ServiceContainer::getInstance();

if (isset($this->serviceContainer['event'])) {
$this->eventService = $this->serviceContainer['event'];
} else {
$this->eventService = PhpEvent::getInstance();
}



$this->loader = $this->serviceContainer['command_loader'];
$this->logger = $this->serviceContainer['logger'];
$this->formatter = $this->serviceContainer['formatter'];
$this->globalConfig = $this->serviceContainer['config'];


$appRefClass = new ReflectionClass($this);
$appNs = $appRefClass->getNamespaceName();
$this->loader->addNamespace( '\\' . $appNs . '\\Command' );
$this->loader->addNamespace( array('\\CLIFramework\\Command' ));

$this->supportReadline = extension_loaded('readline');
}





public function getService()
{
return $this->serviceContainer;
}

public function getEventService()
{
return $this->eventService;
}






public function enableCommandAutoload()
{
$this->commandAutoloadEnabled = true;
}






public function disableCommandAutoload()
{
$this->commandAutoloadEnabled = false;
}







public function getCurrentAppNamespace() {
$refClass = new ReflectionClass($this);
return $refClass->getNamespaceName();
}





public function brief()
{
return 'application brief';
}

public function usage()
{
}




public function options($opts)
{
$opts->add('v|verbose','Print verbose message.');
$opts->add('d|debug' ,'Print debug message.');
$opts->add('q|quiet' ,'Be quiet.');
$opts->add('h|help' ,'Show help.');
$opts->add('version' ,'Show version.');

$opts->add('p|profile','Display timing and memory usage information.');
$opts->add('log-path?', 'The path of a log file.');

$opts->add('no-interact','Do not ask any interactive question.');

}

public function topics(array $topics) 
{
foreach($topics as $key => $val) {
if (is_numeric($key)) {
$this->topics[$val] = $this->loadTopic($val);
} else {
$this->topics[$key] = $this->loadTopic($val);
}
}
}

public function topic($topicId, $topicClass = null) 
{
$this->topics[$topicId] = $topicClass ? new $topicClass: $this->loadTopic($topicId);
}

public function getTopic($topicId) 
{
if (isset($this->topics[$topicId])) {
return $this->topics[$topicId];
}
}

public function loadTopic($topicId) 
{

if (class_exists($topicId, true)) {
return new $topicId;
}
if (!preg_match('/Topic$/', $topicId)) {
$className = ucfirst($topicId) . 'Topic';
} else {
$className = ucfirst($topicId);
}
$possibleNs = array($this->getCurrentAppNamespace(), 'CLIFramework');
foreach($possibleNs as $ns) {
$class = $ns . '\\' . 'Topic' . '\\' . $className;
if (class_exists($class, true)) {
return new $class;
}
}
throw new InvalidArgumentException("Topic $topicId not found.");
}






public function init()
{

parent::init();
$this->command('help','CLIFramework\\Command\\HelpCommand');
$this->commandGroup("Development Commands", array(
'zsh' => 'CLIFramework\\Command\\ZshCompletionCommand',
'bash' => 'CLIFramework\\Command\\BashCompletionCommand',
'meta' => 'CLIFramework\\Command\\MetaCommand',
'compile' => 'CLIFramework\\Command\\CompileCommand',
'archive' => 'CLIFramework\\Command\\ArchiveCommand',
'github:build-topics' => 'CLIFramework\\Command\\BuildGitHubWikiTopicsCommand',
))->setId('dev');
}









public function runWithTry(array $argv)
{
try {
return $this->run($argv);
} catch (CommandArgumentNotEnoughException $e) {
$this->logger->error( $e->getMessage() );
$this->logger->writeln("Expected argument prototypes:");
foreach($e->getCommand()->getAllCommandPrototype() as $p) {
$this->logger->writeln("\t" . $p);
}
$this->logger->newline();
} catch (CommandNotFoundException $e) {
$this->logger->error( $e->getMessage() . " available commands are: " . join(', ', $e->getCommand()->getVisibleCommandList()) );
$this->logger->newline();

$this->logger->writeln("Please try the command below to see the details:");
$this->logger->newline();
$this->logger->writeln("\t" . $this->getProgramName() . ' help ' );
$this->logger->newline();
} catch (BadMethodCallException $e) {

$this->logger->error($e->getMessage());
$this->logger->error("Seems like an application logic error, please contact the developer.");

} catch (Exception $e) {

if ($this->options && $this->options->debug) {
$printer = new DevelopmentExceptionPrinter($this->getLogger());
$printer->dump($e);
} else {
$printer = new ProductionExceptionPrinter($this->getLogger());
$printer->dump($e);
}
}

return false;
}










public function run(Array $argv)
{
$this->setProgramName($argv[0]);

$currentCmd = $this;



$currentCmd->_init();


$getopt = new ContinuousOptionParser($currentCmd->optionSpecs);









$appOptions = $getopt->parse( $argv );
$currentCmd->setOptions($appOptions);
if (false === $currentCmd->prepare()) {
return false;
}


$command_stack = array();
$arguments = array();


while ( ! $getopt->isEnd() ) {
$a = $getopt->getCurrentArgument();



if ($currentCmd->hasCommands()) {
$a = $getopt->getCurrentArgument();

if (!$currentCmd->hasCommand($a) ) {
if (!$appOptions->noInteract && ($guess = $currentCmd->guessCommand($a)) !== NULL) {
$a = $guess;
} else {
throw new CommandNotFoundException($currentCmd, $a);
}
}

$getopt->advance(); 


$currentCmd = $currentCmd->getCommand($a);
$getopt->setSpecs($currentCmd->optionSpecs);


$currentCmd->setOptions($getopt->continueParse());
$command_stack[] = $currentCmd; 

} else {
$a = $getopt->advance();
$arguments[] = $a;
}
}

foreach ($command_stack as $cmd) {
if (false === $cmd->prepare()) {
return false;
}
}


if ( $last_cmd = array_pop( $command_stack ) ) {
$return = $last_cmd->executeWrapper( $arguments );
$last_cmd->finish();
while ( $cmd = array_pop( $command_stack ) ) {

$cmd->finish();
}
} else {

return $this->executeWrapper( $arguments );
}
$currentCmd->finish();
$this->finish();

return $return !== false;
}





public function prepare()
{
$this->startedAt = microtime(true);
$options = $this->getOptions();
$config = $this->getGlobalConfig();

if ($options->debug || $options->verbose || $options->quiet) {

if ($options->debug) {
$this->getLogger()->setDebug();
} else if ($options->verbose) {
$this->getLogger()->setVerbose();
} else if ($options->quiet) {
$this->getLogger()->setLevel(2);
}

} else {

if ($config->isDebug()) {
$this->getLogger()->setDebug();
} else if ($config->isVerbose()) {
$this->getLogger()->setVerbose();
}

}

return true;
}

public function finish() {
if ($this->options->profile) {
$this->logger->info(
sprintf('Memory usage: %.2fMB (peak: %.2fMB), time: %.4fs',
memory_get_usage(true) / (1024 * 1024),
memory_get_peak_usage(true) / (1024 * 1024),
(microtime(true) - $this->startedAt)
)
);
}
}

public function getCoreVersion()
{
if ( defined('static::core_version') ) {
return static::core_version;
}
if ( defined('static::CORE_VERSION') ) {
return static::CORE_VERSION;
}
}

public function getVersion()
{
if ( defined('static::VERSION') ) {
return static::VERSION;
}
if ( defined('static::version') ) {
return static::version;
}
}

public function setProgramName($programName) {
$this->programName = $programName;
}

public function getProgramName() {
return $this->programName;
}

public function getName()
{
if ( defined('static::NAME') ) {
return static::NAME;
}
if ( defined('static::name') ) {
return static::name;
}
}







public function execute()
{
$options = $this->getOptions();
if ($options->version) {
$this->logger->writeln($this->getName() . ' - ' . $this->getVersion());
$this->logger->writeln("cliframework core: " . $this->getCoreVersion());
return true;
}

$arguments = func_get_args();


$help = $this->getCommand('help');
$help->setOptions($options);
if ($help || $options->help) {
$help->executeWrapper($arguments);
return true;
}
throw new CommandNotFoundException($this, 'help');
}

public function getFormatter()
{
return $this->formatter;
}

public function getLogger()
{
return $this->logger;
}

public function getGlobalConfig()
{
return $this->globalConfig;
}





public function __get($name) 
{
if (isset($this->serviceContainer[$name])) {
return $this->serviceContainer[$name];
}
throw new InvalidArgumentException("Application class doesn't have `$name` service or property.");
}

public static function getInstance()
{
static $app;
if( $app )
return $app;
return $app = new static;
}


}
<?php
namespace CLIFramework;
use IteratorAggregate;
use ArrayIterator;




class ValueCollection implements IteratorAggregate
{

public $groups = array();




public $labels = array();










public function group($groupId, $label, $values) {

if (is_array($values)) {
if ( !isset($this->groups[ $groupId ])) {
$this->groups[$groupId] = $values;
} else {
$this->groups[ $groupId ] = array_merge(
$this->groups[ $groupId ], $values );
}
} else {
$this->groups[ $groupId ][] = $values;
}
$this->setGroupLabel($groupId, $label);
}



public function getGroups() {
return $this->groups;
}


public function setGroup($groupId, $values) {
$this->groups[ $groupId ] = $values;
}

public function getGroup($groupId) {
return $this->groups[ $groupId ];
}

public function setGroupLabel($groupId, $label) {
$this->labels[ $groupId ] = $label;
}

public function getGroupLabel($groupId) {
if ( isset($this->labels[ $groupId ]) ) {
return $this->labels[ $groupId ];
}
}

public function containsValue($value) {
foreach($this->groups as $groupId => $values) {
if (in_array($value, $values)) {
return true;
}
}
return false;
}

public function getGroupLabels() {
return $this->labels;
}

public function toJson() {
return json_encode($this->groups);
}

public function getIterator() {
return new ArrayIterator( $this->groups );
}
}


<?php
namespace CLIFramework\Component\Progress;

class ProgressStar implements ProgressReporter
{
public $stars = array('-','\\','|','/');

public $i = 0;

public $url;

public $done = false;

public function prettySize($bytes)
{
if ($bytes > 1000000) {
return round( $bytes / 1000000, 2) . 'M';
}
elseif ($bytes > 1000) {
return round($bytes / 1000, 2) . 'K';
}
return round($bytes,2) . 'B';
}

public function reset() {
$this->done = false;
}

public function setUrl($url)
{
$this->url = $url;
}

public function curlCallback($ch, $downloadSize, $downloaded, $uploadSize, $uploaded)
{

if ($this->done || $downloadSize == 0) {
return;
}


if ($downloadSize != 0 && $downloadSize === $downloaded) {
$this->done = true;
printf("\r\t%-60s                           \n",$this->url);
} else {
$percent = ($downloaded > 0 ? (float) ($downloaded / $downloadSize) : 0.0 );
if( ++$this->i > 3 )
$this->i = 0;


printf("\r\tFetching %-60s %s % -3.1f%% %s", $this->url,
$this->stars[ $this->i ], 
$percent * 100, $this->prettySize($downloaded) );
}
}
}


<?php
namespace CLIFramework\Component\Progress;
use Exception;
use CLIFramework\Formatter;
use CLIFramework\ConsoleInfo\EnvConsoleInfo;
use CLIFramework\ConsoleInfo\ConsoleInfoFactory;

class ProgressBarStyle
{
public $leftDecorator = "|";

public $rightDecorator = "|";

public $barCharacter = '#';
}
<?php
namespace CLIFramework\Component\Progress;

interface ProgressReporter
{
public function update($finishedValue, $totalValue);
}

<?php
namespace CLIFramework\Component\Progress;

class ETACalculator
{
static public function calculateRemainingSeconds($proceeded, $total, $start, $now)
{
$secondDiff = ($now - $start);
$speed = $secondDiff > 0 ? $proceeded / $secondDiff : 0;
$remaining = $total - $proceeded;
if ($speed > 0) {
$remainingSeconds = $remaining / $speed;
return $remainingSeconds;
}
}

static public function calculateEstimatedPeriod($proceeded, $total, $start, $now)
{
$str = '--';
if ($remainingSeconds = self::calculateRemainingSeconds($proceeded, $total, $start, $now)) {
$str = '';

$days = 0;
$hours = 0;
$minutes = 0;
if ($remainingSeconds > (3600 * 24)) {
$days = ceil($remainingSeconds / (3600 * 24));
$remainingSeconds = $remainingSeconds % (3600 * 24);
}

if ($remainingSeconds > 3600) {
$hours = ceil($remainingSeconds / 3600);
$remainingSeconds = $remainingSeconds % 3600;
}

if ($remainingSeconds > 60) {
$minutes = ceil($remainingSeconds / 60);
$remainingSeconds = $remainingSeconds % 60;
}

if ($days > 0) {
$str .= $days . 'd'; 
}
if ($hours) {
$str .= $hours . 'h';
}
if ($minutes) {
$str .= $minutes . 'm';
}
if ($remainingSeconds > 0) {
$str .= intval($remainingSeconds) . 's';
}
}
return $str;
}

static public function calculateEstimatedTime($proceeded, $total, $start, $now)
{
if ($remainingSeconds = self::calculateRemainingSeconds($proceeded, $total, $start, $now)) {
return $now + $remainingSeconds;
}
}
}




<?php
namespace CLIFramework\Component\Progress;
use Exception;
use CLIFramework\Formatter;
use CLIFramework\ConsoleInfo\EnvConsoleInfo;
use CLIFramework\ConsoleInfo\ConsoleInfoFactory;

class SharpProgressBarStyle extends ProgressBarStyle
{
public $leftDecorator = "[";

public $rightDecorator = "]";

public $barCharacter = '#';
}
<?php
namespace CLIFramework\Component\Progress;
use Exception;
use CLIFramework\Formatter;
use CLIFramework\ConsoleInfo\EnvConsoleInfo;
use CLIFramework\ConsoleInfo\ConsoleInfoFactory;
use CLIFramework\Component\Progress\ETACalculator;
use CLIFramework\Ansi\Colors;

class LaserProgressBarStyle extends ProgressBarStyle
{
public $leftDecorator = "❰";

public $rightDecorator = "❱";

public $barCharacter = '#';
}

class ProgressBar implements ProgressReporter
{
protected $terminalWidth = 78;

protected $formatter;

protected $stream;

protected $console;


protected $leftDecorator = "[";


protected $rightDecorator = "]";

protected $columnDecorator = " | ";

protected $barCharacter = '#';

protected $descFormat = '%finished%/%total% %unit% | %percentage% | %eta_period%';

protected $unit;

protected $title;

protected $start;

protected $etaTime = '--:--';

protected $etaPeriod = '--';

public function __construct($stream, $container = null)
{
$this->stream = $stream;

if ($container) {
$this->formatter = $container['formatter'];
if (isset($container['consoleInfo'])) {
$this->console = $container['consoleInfo'];
}
} else {
$this->formatter = new Formatter;
$this->console = ConsoleInfoFactory::create();
$this->updateLayout();
}
}

public function updateLayout()
{
if ($this->console) {
$this->terminalWidth = $this->console->getColumns();
}
}

public function setTitle($title)
{
$this->title = $title;
}

public function setUnit($unit)
{
$this->unit = $unit;
}

public function start($title = null)
{
if ($title) {
$this->setTitle($title);
}
$this->start = microtime(true);
}

public function update($finished, $total)
{
$percentage = $total > 0 ? round($finished / $total, 2) : 0.0;
$trigger = $finished % 3;

if ($trigger) {
$this->etaTime = date('H:i',ETACalculator::calculateEstimatedTime($finished, $total, $this->start, microtime(true)));
$this->etaPeriod = ETACalculator::calculateEstimatedPeriod($finished, $total, $this->start, microtime(true));
}
$desc = str_replace([
'%finished%', '%total%', '%unit%', '%percentage%', '%eta_time%', '%eta_period%',
], [
$finished,
$total,
$this->unit,
($percentage * 100) . '%',
'ETA: ' . $this->etaTime,
'ETA: ' . $this->etaPeriod,
], $this->descFormat);

$barSize = $this->terminalWidth 
- mb_strlen($desc) 
- mb_strlen($this->leftDecorator) 
- mb_strlen($this->rightDecorator)
- mb_strlen($this->columnDecorator)
;

if ($this->title) {
$barSize -= (mb_strlen($this->title) + mb_strlen($this->columnDecorator));
}

$sharps = ceil($barSize * $percentage);

fwrite($this->stream, "\r"
. ( $this->title ? $this->title . $this->columnDecorator : "")
. Colors::decorate($this->leftDecorator, $trigger ? 'purple' : 'light_purple')
. Colors::decorate(str_repeat($this->barCharacter, $sharps), $trigger ? 'purple' : 'light_purple')
. str_repeat(' ', max($barSize - $sharps,0))
. Colors::decorate($this->rightDecorator, $trigger ? 'purple' : 'light_purple')
. $this->columnDecorator 
. Colors::decorate($desc, $trigger ? 'light_gray' : 'white')
);






}

public function finish($title = null)
{
if ($title) {
$this->setTitle($title);
}
fwrite($this->stream, PHP_EOL);
}

}

<?php
namespace CLIFramework\Component\Table;
use InvalidArgumentException;

use CLIFramework\Component\Table\TableStyle;
use CLIFramework\Component\Table\MarkdownTableStyle;
use CLIFramework\Component\Table\CellAttribute;

interface Separator { }




class RowSeparator implements Separator { }




class TableSeparator implements Separator { }







class Table
{






protected $rows = array();




protected $rowIndex = array();

protected $columnWidths = array();

protected $headers = array();

protected $style;

protected $numberOfColumns;

protected $maxColumnWidth = 50;

protected $predefinedStyles = array();






protected $columnCellAttributes = array();





protected $defaultCellAttribute;






protected $trimSpaces = true;

protected $trimLeadingSpaces = false;

protected $trimTrailingSpaces = false;

protected $footer;

public function __construct() {
$this->style = new TableStyle;
$this->defaultCellAttribute = new CellAttribute;
}

public function setHeaders(array $headers) {
$this->headers = $headers;
return $this;
}

public function setFooter($footer)
{
$this->footer = $footer;
return $this;
}

public function setColumnCellAttribute($colIndex, CellAttribute $cellAttribute)
{
$this->columnCellAttributes[$colIndex] = $cellAttribute;
}

public function getColumnCellAttribute($colIndex)
{
if (isset($this->columnCellAttributes[$colIndex])) {
return $this->columnCellAttributes[$colIndex];
}
}

public function getDefaultCellAttribute()
{
return $this->defaultCellAttribute;
}

public function setMaxColumnWidth($width)
{
$this->maxColumnWidth = $width;
}






private function getNumberOfColumns()
{
if (null !== $this->numberOfColumns) {
return $this->numberOfColumns;
}

$columns = array(count($this->headers));
foreach ($this->rows as $row) {
if (!is_array($row)) {
$row = [];
}
$columns[] = count($row);
}
return $this->numberOfColumns = max($columns);
}

public function addRow($row) {
$this->rows[] = $row;

if ($row instanceof RowSeparator) {
return $this;
}


$lastRowIdx = count($this->rows) - 1;

$this->rowIndex[$lastRowIdx] = 1;

$cells = array_values($row);
foreach ($cells as $col => $cell) {
$attribute = $this->defaultCellAttribute;

$expandAttribute = false;
if (is_array($cell)) {
if ($cell[0] instanceof CellAttribute) {
$attribute = array_shift($cell);
$expandAttribute = true;
}
$cell = join("\n", $cell);
} elseif (isset($this->columnCellAttributes[$col])) {
$attribute = $this->columnCellAttributes[$col];
}

$lines = $attribute->handleTextOverflow($cell, $this->maxColumnWidth);

if (count($lines) == 1) {
$lines[0] = $attribute->format($lines[0]);
}


$extraRowIdx = $lastRowIdx;
foreach($lines as $line) {

if ($this->trimSpaces) {
$line = trim($line);
} else {
if ($this->trimLeadingSpaces) {
$line = ltrim($line);
}
if ($this->trimTrailingSpaces) {
$line = rtrim($line);
}
}

if (isset($this->rows[$extraRowIdx])) {
$this->rows[$extraRowIdx][ $col ] = $expandAttribute ? array($attribute, $line) : $line;
} else {
$this->rows[$extraRowIdx] = array($col => $expandAttribute ? array($attribute, $line) : $line);
}
$extraRowIdx++;
}
}
return $this;
}

public function getColumnWidth($col)
{
$lengths = array();
foreach($this->rows as $row) {
if ($row instanceof RowSeparator) {
continue;
}
if (isset($row[$col])) {
if (is_array($row[$col])) {
if (!isset($row[$col][1])) {
throw new InvalidArgumentException('Incorrect cell structure. Expecting [attribute, text].');
}
$lengths[] = mb_strlen(preg_replace('/\033.*?m/','',$row[$col][1]));
} else {
$lengths[] = mb_strlen(preg_replace('/\033.*?m/','',$row[$col]));
}
}
}

$headerColumnWidth = isset($this->headers[$col]) ? mb_strlen($this->headers[$col]) : 0;
$maxContentWidth = max($lengths);;

if (empty($lengths) || $headerColumnWidth > $maxContentWidth) {
return $this->columnWidth[$col] = $headerColumnWidth;
}
return $this->columnWidth[$col] = max($lengths);
}

public function renderRow($rowIndex, $row) {
$out = $this->style->verticalBorderChar;
$columnNumber = $this->getNumberOfColumns();
for ($c = 0 ; $c < $columnNumber ; $c++) {
if (isset($row[$c])) {
$cell = $row[$c];
} else {
$cell = '';
}
$out .= $this->renderCell($c, $cell);
$out .= $this->style->verticalBorderChar;

}
if ($rowIndex > 0 && isset($this->rowIndex[$rowIndex]) && $this->style->drawRowSeparator) {
return $this->renderSeparator() . $out . "\n";
} else {
return $out . "\n";
}
}

public function setStyle($style)
{
if (is_string($style)) {
if (isset($this->predefinedStyles[$style])) {
$this->style = $this->predefinedStyles[$style];
} else {
throw new InvalidArgumentException("Undefined style $style");
}
} else {
$this->style = $style;
}
return $this;
}

public function renderSeparator() {
$columnNumber = $this->getNumberOfColumns();
$out = $this->style->rowSeparatorLeftmostCrossChar;
for ($c = 0 ; $c < $columnNumber ; $c++) {
$columnWidth = $this->getColumnWidth($c);
$out .= str_repeat($this->style->rowSeparatorBorderChar, $columnWidth + $this->style->cellPadding * 2);

if ($c + 1 < $columnNumber) {
$out .= $this->style->rowSeparatorCrossChar;
} else {
$out .= $this->style->rowSeparatorRightmostCrossChar;
}
}
return $out . "\n";
}

public function renderHeader() {
$out = '';

if ($this->style->drawTableBorder) {
$out .= $this->renderSeparator();
}

$out .= $this->style->verticalBorderChar;
$columnNumber = $this->getNumberOfColumns();
for ($c = 0 ; $c < $columnNumber ; $c++) {
if (isset($this->headers[$c])) {
$cell = $this->headers[$c];
} else {
$cell = '';
}
$out .= $this->renderCell($c, $cell);
$out .= $this->style->verticalBorderChar;
}
$out .= "\n";
$out .= $this->renderSeparator();
return $out;
}


public function getTableInnerWidth() 
{
$columnNumber = $this->getNumberOfColumns();
$width = 0;
for ($c = 0 ; $c < $columnNumber ; $c++) {
$width += $this->getColumnWidth($c) + $this->style->cellPadding * 2 + 1;
}
return $width - 1;
}

public function renderCell($cellIndex, $cell)
{
$attribute = $this->defaultCellAttribute;

if (is_array($cell)) {
if ($cell[0] instanceof CellAttribute) {
$attribute = array_shift($cell);
}
$cell = join("\n", $cell);
} elseif (isset($this->columnCellAttributes[$cellIndex])) {
$attribute = $this->columnCellAttributes[$cellIndex];
}

$width = $this->getColumnWidth($cellIndex);
if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($cell)) {
$width += strlen($cell) - mb_strlen($cell, $encoding);
}
return $attribute->renderCell($cell, $width, $this->style);
}

public function renderFooter()
{
if (!is_array($this->footer)) {
$columnNumber = $this->getNumberOfColumns();
$out = '';
$width = $this->getTableInnerWidth();
$out .= $this->renderSeparator();
$out .= $this->style->verticalBorderChar 
. str_repeat($this->style->cellPaddingChar, $this->style->cellPadding)
. str_pad($this->footer, $width - $this->style->cellPadding * 2) 
. str_repeat($this->style->cellPaddingChar, $this->style->cellPadding)
. $this->style->verticalBorderChar . "\n";

if ($this->style->drawTableBorder) {
$out .= $this->style->rowSeparatorLeftmostCrossChar . str_repeat($this->style->rowSeparatorBorderChar, $width) 
. $this->style->rowSeparatorRightmostCrossChar . "\n";
}
return $out;
}

$out = '';


$out .= $this->style->verticalBorderChar;
$columnNumber = $this->getNumberOfColumns();
for ($c = 0 ; $c < $columnNumber ; $c++) {
if (isset($this->footer[$c])) {
$cell = $this->footer[$c];
} else {
$cell = '';
}
$out .= $this->renderCell($c, $cell);
$out .= $this->style->verticalBorderChar;
}
$out .= "\n";

if ($this->style->drawTableBorder) {
$out .= $this->renderSeparator();
}
return $out;
}

public function render() {
$out = '';

if (!empty($this->headers)) {
$out .= $this->renderHeader();
} else {
$out .= $this->renderSeparator();
}

foreach($this->rows as $rowIndex => $row) {
if ($row instanceof RowSeparator) {
$out .= $this->renderSeparator();
} else {
$out .= $this->renderRow($rowIndex, $row);
}
}


if ($this->style && ! $this->style instanceof MarkdownTableStyle) {
if (!empty($this->footer)) {
$out .= $this->renderFooter();
} else {
$out .= $this->renderSeparator();
}
}
return $out;
}

}




<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Ansi\Colors;

class CellAttribute { 

const ALIGN_RIGHT = 1;

const ALIGN_LEFT = 2;

const ALIGN_CENTER = 3;

const WRAP = 1;

const CLIP = 2;

const ELLIPSIS = 3;

protected $alignment = 2;

protected $formatter;

protected $textOverflow = CellAttribute::WRAP;

protected $backgroundColor;

protected $foregroundColor;
















public function setAlignment($alignment) 
{
$this->alignment = $alignment;
}

public function setFormatter($formatter)
{
$this->formatter = $formatter;
}

public function getFormatter()
{
return $this->formatter;
}

public function setTextOverflow($overflowType)
{
$this->textOverflow = $overflowType;
}




public function format($cell) { 
if ($this->formatter) {
return call_user_func($this->formatter, $cell);
}
return $cell;
}

public function setBackgroundColor($color) {
$this->backgroundColor = $color;
}

public function setForegroundColor($color) {
$this->foregroundColor = $color;
}

public function getForegroundColor() 
{
return $this->foregroundColor; 
}

public function getBackgroundColor() 
{
return $this->backgroundColor; 
}





public function handleTextOverflow($cell, $maxWidth)
{
$lines = explode("\n",$cell);
if ($this->textOverflow == self::WRAP) {
$maxLineWidth = max(array_map('mb_strlen', $lines));
if ($maxLineWidth > $maxWidth) {
$cell = wordwrap($cell, $maxWidth, "\n");

$lines = explode("\n",$cell);
}
} elseif ($this->textOverflow == self::ELLIPSIS) {
if (mb_strlen($lines[0]) > $maxWidth) {
$lines = array(mb_substr($lines[0], 0, $maxWidth - 2) . '..');
}
} elseif ($this->textOverflow == self::CLIP) {
if (mb_strlen($lines[0]) > $maxWidth) {
$lines = array(mb_substr($lines[0], 0, $maxWidth));
}
}
return $lines;
}

public function renderCell($cell, $width, $style)
{
$out = '';
$out .= str_repeat($style->cellPaddingChar, $style->cellPadding);








if ($this->alignment === CellAttribute::ALIGN_LEFT) {
$out .= str_pad($cell, $width, ' '); 
} elseif ($this->alignment === CellAttribute::ALIGN_RIGHT) {
$out .= str_pad($cell, $width, ' ', STR_PAD_LEFT);
} elseif ($this->alignment === CellAttribute::ALIGN_CENTER) {
$out .= str_pad($cell, $width, ' ', STR_PAD_BOTH);
} else {
$out .= str_pad($cell, $width, ' '); 
}

$out .= str_repeat($style->cellPaddingChar, $style->cellPadding);

if ($this->backgroundColor || $this->foregroundColor) {
return Colors::decorate($out, $this->foregroundColor, $this->backgroundColor);
}
return $out;
}
}

<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Component\Table\CellAttribute;
use NumberFormatter;

class CurrencyFormatCell extends NumberFormatCell
{
protected $currency;

public function __construct($locale, $currency) {
parent::__construct($locale);
$this->currency = $currency;
}

public function format($cell) {
return $this->formatter->formatCurrency($cell, $this->currency);
}
}


<?php
namespace CLIFramework\Component\Table;

class BorderlessTableStyle extends TableStyle
{
public $cellPadding = 1;

public $cellPaddingChar = ' ';

public $verticalBorderChar = ' ';

public $drawTableBorder = false;

public $drawRowSeparator = false;

public $rowSeparatorCrossChar = ' ';

public $rowSeparatorBorderChar = ' ';

public $rowSeparatorLeftmostCrossChar = ' ';

public $rowSeparatorRightmostCrossChar = ' ';
}

<?php
namespace CLIFramework\Component\Table;

class TableStyle
{
public $cellPadding = 1;

public $cellPaddingChar = ' ';

public $verticalBorderChar = '|';


public $rowSeparatorBorderChar = '-';

public $rowSeparatorCrossChar = '+';

public $rowSeparatorLeftmostCrossChar = '+';

public $rowSeparatorRightmostCrossChar = '+';

public $drawTableBorder = true;

public $drawRowSeparator = false;

public function setCellPadding($padding) 
{
$this->cellPadding = $padding;
}

public function setCellPaddingChar($c) 
{
$this->cellPaddingChar = $c;
}

public function setVerticalBorderChar($c) 
{
$this->verticalBorderChar = $c;
}

public function setRowSeparatorCrossChar($c)
{
$this->rowSeparatorCrossChar = $c;
}

public function setRowSeparatorRightmostCrossChar($c)
{
$this->rowSeparatorRightmostCrossChar = $c;
}

public function setRowSeparatorLeftmostCrossChar($c)
{
$this->rowSeparatorLeftmostCrossChar = $c;
}

public function setRowSeparatorBorderChar($c) {
$this->rowSeparatorBorderChar = $c;
}

}
<?php
namespace CLIFramework\Component\Table;

class MarkdownTableStyle extends TableStyle
{
public $cellPadding = 1;

public $cellPaddingChar = ' ';

public $verticalBorderChar = '|';

public $rowSeparatorCrossChar = '|';

public $rowSeparatorBorderChar = '-';

public $rowSeparatorLeftmostCrossChar = '|';

public $rowSeparatorRightmostCrossChar = '|';

public $drawTableBorder = false;
}

<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Component\Table\CellAttribute;
use NumberFormatter;

class SpellOutNumberFormatCell extends NumberFormatCell
{
public function __construct($locale) {
$this->locale = $locale;
$this->formatter = new NumberFormatter($locale, NumberFormatter::SPELLOUT); 
$this->formatter->setTextAttribute(NumberFormatter::DEFAULT_RULESET, "%financial");
}
}


<?php
namespace CLIFramework\Component\Table;

class CompactTableStyle extends TableStyle
{
public $cellPadding = 1;

public $cellPaddingChar = ' ';

public $verticalBorderChar = ' ';

public $drawTableBorder = false;

public $drawRowSeparator = false;

public $rowSeparatorCrossChar = '-';

public $rowSeparatorBorderChar = '-';

public $rowSeparatorLeftmostCrossChar = '-';

public $rowSeparatorRightmostCrossChar = '-';
}

<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Component\Table\CellAttribute;
use NumberFormatter;
use IntlDateFormatter;
use DateTime;

class DateFormatCell extends NumberFormatCell
{











public function __construct($locale, $datetype = IntlDateFormatter::FULL, $timetype = IntlDateFormatter::FULL, $timezone = NULL, $calendar = IntlDateFormatter::GREGORIAN, $pattern = "")
{
$this->locale = $locale;
$this->formatter = new IntlDateFormatter($locale , $datetype, $timetype, $timezone, $calendar);
}

public function format($cell) {
if ($cell instanceof DateTime) {
return $this->formatter->formatObject($cell);
}
return $this->formatter->format($cell);
}
}


<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Component\Table\CellAttribute;
use NumberFormatter;

class DurationFormatCell extends NumberFormatCell
{
public function __construct($locale) {
$this->locale = $locale;
$this->formatter = new NumberFormatter($locale, NumberFormatter::PERCENT); 
}
}


<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Component\Table\CellAttribute;
use NumberFormatter;

class NumberFormatCell extends CellAttribute
{
protected $locale;

protected $formatter;

public function __construct($locale) {
$this->locale = $locale;
$this->formatter = new NumberFormatter($locale, NumberFormatter::DECIMAL); 
}

public function format($cell) {
if (is_numeric($cell)) {
return $this->formatter->format($cell);
}
return $cell;
}
}


<?php
namespace CLIFramework\Component\Table;
use CLIFramework\Component\Table\CellAttribute;
use NumberFormatter;

class DurationFormatCell extends NumberFormatCell
{
public function __construct($locale) {
$this->locale = $locale;
$this->formatter = new NumberFormatter($locale, NumberFormatter::DURATION); 
}
}


<?php
namespace CLIFramework\ExceptionPrinter;
use Exception;
use CLIFramework\ServiceContainer;
use CLIFramework\Logger;

class ProductionExceptionPrinter extends DevelopmentExceptionPrinter
{
public $reportUrl;

public function dump(Exception $e) 
{
$this->dumpBrief($e);
$this->dumpTraceInPhar($e);
}
}




<?php
namespace CLIFramework\ExceptionPrinter;
use Exception;
use CLIFramework\ServiceContainer;
use CLIFramework\Logger;

function is_assoc_array(array $a) {
return ! is_indexed_array($a);
}

function is_indexed_array(array $a) {
$keys = array_keys($a);
$indexes = array_filter($keys, 'is_numeric');
return count($indexes) ? True : False;
}

function output_var($a) {
if (is_array($a)) {
if (is_indexed_array($a)) {
$out = array();
foreach ($a as $i) {
$out[] = output_var($i);
}
return '[' . join(', ',$out) . ']';
} else {

$out = '[';
foreach ($a as $k => $i) {
$out .= $k . ' => ' . output_var($i);
}
$out .= ']';
return $out;

}
} else if (is_scalar($a)) {

return var_export($a, true);

} else if (is_object($a)) {

if (method_exists($a, '__toString')) {
return $a->__toString();
} else {
return get_class($a);
}

} else {
return '...';
}
}

class DevelopmentExceptionPrinter
{
public $reportUrl;

public $logger;

public function __construct(Logger $logger)
{
$this->logger = $logger;
}

public function dumpVar($var)
{
return output_var($var);
}

public function dumpArgs(array $args)
{
if (empty($args)) {
return '';
}

$desc = array();
foreach($args as $a) {
$desc[] = output_var($a);
}
return join(', ', $desc);
}

public function dumpTraceInPhar(Exception $e)
{
$this->logger->info("Trace:\n");
$trace = $e->getTrace();
foreach($trace as $idx => $entry) {
$argDesc = $this->dumpArgs($entry['args']);
$this->logger->info(sprintf("    %d) %s%s%s(%s)", $idx, @$entry['class'], @$entry['type'], $entry['function'], $argDesc));
}
$this->logger->newline();
}

public function dumpTrace(Exception $e)
{
$this->logger->info("Trace:\n");
$trace = $e->getTrace();
foreach($trace as $idx => $entry) {

$argDesc = $this->dumpArgs($entry['args']);

$this->logger->info(sprintf(
"    %d) %s%s%s(%s)",
$idx + 1,
@$entry['class'],
@$entry['type'],
$entry['function'],
$argDesc
));

if (isset($entry['file'], $entry['line'])) {
$this->logger->info(sprintf(
"        from %s: %d",
$entry['file'],
$entry['line']
));
}

$this->logger->newline();
}
$this->logger->newline();
}

public function dumpCodeBlock(Exception $e)
{
$line = $e->getLine();
$file = $e->getFile();
$this->logger->info("Thrown from $file at line $line:\n");

$lines = file($file);
$indexRange = range(max($line - 4, 0), min($line + 3, count($lines)));
foreach($indexRange as $index) {
if ($index == ($line - 1)) {
$this->logger->warn(sprintf("> % 3d", $index + 1) . rtrim($lines[$index]));
} else {
$this->logger->info(sprintf("  % 3d", $index + 1) . rtrim($lines[$index]));
}
}

$this->logger->newline();
}

public function dumpBrief(Exception $e)
{
$logger = $this->logger;
$code = $e->getCode();
$message = $e->getMessage();

$file = $e->getFile();
$line = $e->getLine();

$class = get_class($e);

if ($code) {
$logger->error("$class: ($code) $message");
} else {
$logger->error("$class: $message");
}
}

public function dump(Exception $e)
{
$this->dumpBrief($e);
$this->dumpCodeBlock($e);
$this->dumpTrace($e);
}
}




<?php









namespace CLIFramework;
use CLIFramework\Formatter;
use CLIFramework\ServiceContainer;
use CLIFramework\IO\Writer;

class Logger
{











public $logLevels = array(
'critical' => 1,
'error' => 2,
'warn' => 3,
'info' => 4,
'info2' => 5,
'debug' => 6,
'debug2' => 7,
);

public $levelStyles = array(
'critical' => 'strong_red',
'error' => 'strong_red',
'warn' => 'red',
'info' => 'green',
'info2' => 'green',
'debug' => 'white',
'debug2' => 'white',
);






public $level = 4;

protected $indent = 0;

protected $indentCharacter = '  ';






public $formatter;






private $writer;

public function __construct(ServiceContainer $container = null)
{
$container = $container ?: ServiceContainer::getInstance();
$this->formatter = $container['formatter']; 
$this->writer = $container['writer'];
}

public function setLevel($level, $indent = 0)
{
$this->level = $level;
}

public function getLevel()
{
return $this->level;
}

public function quiet()
{
$this->level = 0;
}

public function setAbsoluteQuiet()
{
$this->level = 0;
}

public function setQuiet()
{
$this->level = 2;
}

public function setVerbose()
{
$this->level = $this->getLevelByName('info2');
}

public function isVerbose()
{
return $this->level == $this->getLevelByName('info2');
}

public function setDebug()
{
$this->level = $this->getLevelByName('debug2');
}

public function isDebug()
{
return $this->level == $this->getLevelByName('debug2') || $this->level == $this->getLevelByName('debug');
}

public function isQuiet() {
return $this->level == 2;
}







public function setFormatter(Formatter $formatter)
{
$this->formatter = $formatter;
}

public function getFormatter()
{
return $this->formatter;
}






public function setWriter(Writer $writer)
{
$this->writer = $writer;
}

public function indent($level = 1) {
$this->indent += $level;
}

public function unIndent($level = 1) {
$this->indent = max(0 ,$this->indent - $level);
}

public function resetIndent() {
$this->indent = 0;
}

public function __call($method, $args)
{
$msg = $args[0];
$indent = isset($args[1]) ? $args[1] : 0;
$level = $this->getLevelByName($method);
$style = $this->getStyleByName($method);
if ($level > $this->level) {

return;
}

if ($this->level <= 4 && $level >= 4) {
$style = 'dim';
}

if ($this->indent) {
$this->writer->write(str_repeat($this->indentCharacter, $this->indent));
}


if (is_object($msg) || is_array($msg)) {
$this->writer->writeln($this->formatter->format(print_r($msg , 1), $style));
} else {
$this->writer->writeln($this->formatter->format($msg , $style));
}
}








public function writef($format) {
$args = func_get_args();
$this->writer->write(call_user_func_array('sprintf', $args));
}




public function write($text) {
$this->writer->write($text);
}




public function writeln($text)
{
$this->writer->writeln($text);
}




public function newline()
{
$this->writer->writeln('');
}




public function logException(\Exception $exception)
{
echo $exception->getMessage();
$this->newline();
}






public function getStyleByName($levelName)
{
if (isset($this->levelStyles[$levelName])) {
return $this->levelStyles[$levelName];
}
}






public function getLevelByName($levelName)
{
if (isset($this->logLevels[$levelName])) {
return $this->logLevels[$levelName];
}
}

public static function getInstance()
{
static $instance;
return $instance ? $instance : $instance = new static;
}
}
<?php
namespace CLIFramework;
use CLIFramework\Command;









class ChainedCommand extends Command
{



public $commands = array();

public function options($opts) 
{
$cmds = $this->getChainedCommands();
foreach($cmds as $cmd)
$cmd->options($opts);
}

public function getChainedCommands() 
{
$cmds = array();
foreach( $this->commands as $command ) {
$cmd = new $command($this->application);
$cmd->logger = $this->logger;
$cmd->parent = $this;
$cmds[] = $cmd;
}
return $cmds;
}

public function execute() 
{
$this->logger->info('Executing chained commands: ' . join(',', $this->commands ));
$args = func_get_args();
$cmds = $this->getChainedCommands();
foreach( $cmds as $cmd ) {
$cmd->options = $this->options;
$cmd->executeWrapper($args);
}
$this->logger->info('Done');
}
}

<?php
namespace CLIFramework;
use ArrayAccess;
use IteratorAggregate;
use Countable;
use ArrayIterator;
use ArrayObject;

class ArgInfoList extends ArrayObject {

public function add($name) {
$arginfo = new ArgInfo($name);
$this->append($arginfo);
return $arginfo;
}

}




<?php
namespace CLIFramework;

class CompletionUtils
{
public static function split_words($line) {
return preg_split("#\s+#", trim($line));
}

public static function paths($dir) {
$names = scandir($dir);
return array_filter($names, function($n) {
return $n != '.' && $n != '..';
});
}

public static function classnames($pattern = null) {
$classes = get_declared_classes();
if ($pattern) {
return array_filter($classes, function($class) use ($pattern) {
return preg_match($pattern, $class);
});
}
return $classes;
}

}


<?php
namespace CLIFramework\Completion;
use CLIFramework\Buffer;
use CLIFramework\Application;
use CLIFramework\ArgInfo;
use CLIFramework\CommandBase;
use CLIFramework\Command;
use CLIFramework\Completion\Utils;
use GetOptionKit\Option;
use Exception;

function indent($level) {
return str_repeat('  ', $level);
}

function str_indent($content, $level = 1) {
$space = str_repeat('  ', $level);
$lines = explode("\n", $content);
$lines = array_map(function($line) use ($space) { return $space . $line; }, $lines);
return join("\n", $lines);
}

function array_indent(array $lines, $level = 1) {
$space = str_repeat('  ', $level);
return array_map(function($line) use ($space) {
return $space . $line;
}, $lines);
}

function join_indent(array $lines, $level = 1) {
return join("\n",array_indent($lines, $level));
}




function zsh_comp_function($name, $code , $guard = false) {
$buf = new Buffer;
if ($guard) {
$buf->appendLine("(( \$+functions[$name] )) ||");
}
$buf->appendLine("$name () {");
$buf->indent();
$buf->appendBuffer($code);
$buf->unindent();
$buf->appendLine("}");
return $buf;
}

function case_in($name, $code) {
return "case $name in\n"
. str_indent($code, 1) . "\n"
. "esac\n"
;
}


function case_case($pattern, $code) {
return "($pattern)\n"
. str_indent($code, 1) . "\n"
. ";;\n"
;
}

function zsh_comp_desc_array(array $array) {
$out = new Buffer;
$out->appendLine('(');
$out->indent();
foreach($array as $item => $desc) {
$out->appendLine("'" . addslashes("$item:$desc") . "'");
}
$out->unindent();
$out->appendLine(')');
return $out;
}


class ZshGenerator
{
public $app;




public $programName;




public $compName;




public $bindName;

public $buffer;

public function __construct(Application $app, $programName, $bindName, $compName)
{
$this->app = $app;
$this->programName = $programName;
$this->compName = $compName;
$this->bindName = $bindName;
$this->buffer = new Buffer;
}


public function output() {
return $this->complete_application();
}

public function visible_commands(array $cmds) {
$visible = array();
foreach ($cmds as $name => $cmd) {
if (! preg_match('#^_#', $name) ) {
$visible[$name] = $cmd;
}
}
return $visible;
}

public function command_desc_array(array $cmds) {
$args = array();
foreach ( $cmds as $name => $cmd ) {
if ( preg_match('#^_#', $name) ) {
continue;
}
$args[] = "$name:" . Utils::q($cmd->brief());
}
return $args;
}


public function describe_commands(array $cmds, $level = 0) {
$buf = new Buffer;
$buf->setIndent($level);
$buf->appendLine("local commands; commands=(");
$buf->indent();
$buf->appendLines($this->command_desc_array($cmds));
$buf->unindent();
$buf->appendLine(")");
$buf->appendLine("_describe -t commands 'command' commands && ret=0");
return $buf;
}




















public function option_flag_item(Option $opt, $cmdSignature) {

$str = "";

$optspec = $opt->flag || $opt->optional ? '' : '=';
$optName = $opt->long ? $opt->long : $opt->short;

if ($opt->short && $opt->long) {
if (!$opt->multiple) {
$str .= "'(-" . $opt->short . " --" . $opt->long . ")'"; 
}
$str .= "{-" . $opt->short . ',' . '--' . $opt->long . $optspec . "}";
$str .= "'";
} else if ($opt->long) {
$str .= "'--" . $opt->long . $optspec;
} else if ($opt->short) {
$str .= "'-" . $opt->short . $optspec;
} else {
throw new Exception('undefined option type');
}


$str .= "[" . addcslashes($opt->desc,'[]:') . "]";

$placeholder = (($opt->valueName) ? $opt->valueName : $opt->isa) ? $opt->isa : null;


if ($opt->validValues || $opt->suggestions || $opt->isa) {

$str .= ':'; 

if ($placeholder) {
$str .= $placeholder;
}

if ($opt->validValues || $opt->suggestions) {
if ($opt->validValues) {
if ( is_callable($opt->validValues) ) {
$str .= ':{' . join(' ', array($this->meta_command_name(), Utils::qq($placeholder), $cmdSignature, 'opt', $optName, 'valid-values')) . '}';
} elseif ($values = $opt->getValidValues()) {

$str .= ':(' . join(' ', Utils::array_qq($values)) . ')';
}
} elseif ($opt->suggestions) {
if ( is_callable($opt->suggestions) ) {
$str .= ':{' . join(' ', array($this->meta_command_name(), Utils::qq($placeholder), $cmdSignature, 'opt', $optName, 'suggestions') ) . '}';
} elseif ($values = $opt->getSuggestions()) {

$str .= ':(' . join(' ', Utils::array_qq($values)) . ')';
}
}

} elseif ( in_array($opt->isa, array('file', 'dir', 'path')) ) {
switch($opt->isa) {
case 'file':
$str .= ':_files';
break;
case 'dir':
$str .= ':_directories';
break;
case 'path':
$str .= ':_path_files';
break;
}
if ( isset($opt->glob) ) {
$str .= ' -g "' . $opt->glob . '"';
}
}
}


$str .= "'"; 
return $str;
}







public function command_args(CommandBase $cmd, $cmdSignature) {
$args = array();
$arginfos = $cmd->getArgInfoList();


if (empty($arginfos)) {
return array("*:default:_files");
}

$idx = 0;
foreach($arginfos as $a) {
$comp = '';

if ($a->multiple) {
$comp .= '*:' . $a->name;
} else {
$comp .= ':' . $a->name;
}

if ($a->validValues || $a->suggestions) {
$values = array();
if ($a->validValues) {
if (is_callable($a->validValues)) {
$comp .= ':{' . join(' ', array($this->meta_command_name(), Utils::qq($a->name), $cmdSignature, 'arg', $idx, 'valid-values')) . '}';
} elseif ($values = $a->getValidValues()) {
$comp .= ':(' . join(" ", Utils::array_qq($values)) . ')';
}
} elseif ($a->suggestions ) {
if (is_callable($a->suggestions)) {
$comp .= ':{' . join(' ', array($this->meta_command_name(), Utils::qq($a->name), $cmdSignature, 'arg', $idx, 'suggestions')) . '}';
} elseif ($values = $a->getSuggestions()) {
$comp .= ':(' . join(" ", Utils::array_qq($values)) . ')';
}
}
} elseif (in_array($a->isa,array('file','path','dir'))) {
switch($a->isa) {
case "file":
$comp .= ":_files";
break;
case "path":
$comp .= ":_path_files";
break;
case "dir":
$comp .= ":_directories";
break;
}
if ($a->glob) {
$comp .= " -g \"{$a->glob}\"";
}
}
$args[] = Utils::q($comp);
$idx++;
}
return empty($args) ? NULL : $args;
}





public function complete_command_options_arguments(CommandBase $subcmd, $level = 1) {
$cmdSignature = $subcmd->getSignature();


$buf = new Buffer;
$buf->setIndent($level);

$args = $this->command_args($subcmd, $cmdSignature);
$flags = $this->command_flags($subcmd, $cmdSignature);

if ( $flags || $args ) {
$buf->appendLine("_arguments -w -S -s \\");
$buf->indent();

if ($flags) {
foreach($flags as $line) {
$buf->appendLine($line . " \\");
}
}
if ($args) {
foreach($args as $line) {
$buf->appendLine($line . " \\");
}
}
$buf->appendLine(" && ret=0");
$buf->unindent();
}
return $buf->__toString();
}

public function render_argument_completion_handler(ArgInfo $a) {
$comp = '';
switch($a->isa) {
case "file":
$comp .= "_files";
break;
case "path":
$comp .= "_path_files";
break;
case "dir":
$comp .= "_directories";
break;
}
if ($a->glob) {
$comp .= " -g \"{$a->glob}\"";
}
return $comp;
}



public function render_argument_completion_values(ArgInfo $a) {
if ($a->validValues || $a->suggestions) {
$values = array();
if ($a->validValues) {
$values = $a->getValidValues();
} elseif ($a->suggestions ) {
$values = $a->getSuggestions();
}
return join(" ", $values);
}
return '';
}







public function command_args_case(CommandBase $cmd) {
$buf = new Buffer;
$arginfos = $cmd->getArgInfoList();
$buf->appendLine("case \$state in");

foreach($arginfos as $a) {
$buf->appendLine("({$a->name})");

if ($a->validValues || $a->suggestions) {
$buf->appendLine("_values " . $this->render_argument_completion_values($a) . ' && ret=0');
} elseif (in_array($a->isa,array('file','path','dir'))) {
$buf->appendLine($this->render_argument_completion_handler($a) . ' && ret=0');
}
$buf->appendLine(";;");
}
$buf->appendLine("esac");
return $buf->__toString();
}






public function command_flags(CommandBase $cmd, $cmdSignature) {
$args = array();
$specs = $cmd->getOptionCollection();




foreach ($specs->options as $opt ) {
$args[] = $this->option_flag_item($opt, $cmdSignature);
}
return empty($args) ? NULL : $args;
}









public function command_subcommand_states(CommandBase $cmd) {
$args = array();
$cmds = $this->visible_commands($cmd->getCommands());
foreach($cmds as $c) {
$args[] = sprintf("'%s:->%s'", $c->getName(), $c->getName()); 
}
return $args;
}

public function commandmeta_function() {
$buf = new Buffer;
$buf->indent();
$buf->appendLine("local curcontext=\$curcontext state line ret=1");
$buf->appendLine("typeset -A opt_args");
$buf->appendLine("typeset -A val_args");

$buf->appendLine("declare -a lines");
$buf->appendLine("declare -a args");

$buf->appendLine("local ret=1");
$buf->appendLine("local desc=\$1");
$buf->appendLine("local cmdsig=\$2");
$buf->appendLine("local valtype=\$3");
$buf->appendLine("local pos=\$4");
$buf->appendLine("local completion=\$5");

$metaCommand = array($this->programName, 'meta', '--zsh', '$cmdsig', '$valtype', '$pos', '$completion');

$buf->appendLine('output=$(' . join(" ",$metaCommand) . ')');




$buf->appendLine('lines=("${(@f)output}")');
$buf->appendLine('output_type=${lines[1]}');


$buf->appendLine('if [[ $lines[1] == "#groups" ]] ; then');

$buf->appendLine('    eval $output');
$buf->appendLine('    for tag in ${(k)groups} ; do');
$buf->appendLine('        complete_values=(${(z)${groups[$tag]}})');
$buf->appendLine('        label=${labels[$tag]}');
$buf->appendLine('        if [[ -z $label ]] ; then');
$buf->appendLine('            label=$tag');
$buf->appendLine('        fi');
$buf->appendLine('        _describe -t $tag $label complete_values && ret=0');
$buf->appendLine('    done');

$buf->appendLine('elif [[ $lines[1] == "#values" ]] ; then');
$buf->appendLine('    args=(${lines:1})');
$buf->appendLine('   _values "$desc" ${=args} && ret=0');
$buf->appendLine('elif [[ $lines[1] == "#descriptions" ]] ; then');
$buf->appendLine('    args=(${lines:1})');
$buf->appendLine('    _describe "$desc" args && ret=0');
$buf->appendLine('else');
$buf->appendLine('   _values "$desc" ${=lines} && ret=0');
$buf->appendLine('fi');

$buf->appendLine('return ret');
return zsh_comp_function($this->meta_command_name(), $buf);
}

public function meta_command_name() {
return '__' . preg_replace('/\W/','_',$this->compName) . 'meta';
}








public function commandmeta_callback_function(CommandBase $cmd) {
$cmdSignature = $cmd->getSignature();


$buf = new Buffer;
$buf->indent();

$buf->appendLine("local curcontext=\$curcontext state line ret=1");
$buf->appendLine("declare -A opt_args");
$buf->appendLine("declare -A values");
$buf->appendLine("local ret=1");






$buf->appendLine("local desc=\$1");
$buf->appendLine("local valtype=\$3");
$buf->appendLine("local pos=\$4");
$buf->appendLine("local completion=\$5");

$metaCommand = array($this->programName,'meta', $cmdSignature, '$valtype', '$pos', '$completion');
$buf->appendLine('$(' . join(" ",$metaCommand) . ')');
$buf->appendLine('_values $desc ${=values} && ret=0'); 
$buf->appendLine('return ret');

$funcName = $this->command_function_name($cmdSignature);
return zsh_comp_function($funcName, $buf);
}

public function commandmeta_callback_functions(CommandBase $cmd) {
$cmdSignature = $cmd->getSignature();



$buf = new Buffer;
$subcmds = $this->visible_commands($cmd->getCommands());
foreach($subcmds as $subcmd) {
$buf->append($this->commandmeta_callback_function($subcmd));

if ($subcmd->hasCommands()) {
$buf->appendBuffer( $this->commandmeta_callback_functions($subcmd) );
}
}
return $buf;
}

public function complete_application() {
$buf = new Buffer;
$buf->appendLines(array(
"# {$this->programName} zsh completion script generated by CLIFramework",
"# Web: http://github.com/c9s/php-CLIFramework",
"# THIS IS AN AUTO-GENERATED FILE, PLEASE DON'T MODIFY THIS FILE DIRECTLY.",
));

$metaName = '_' . $this->programName . 'meta';

$buf->append( $this->commandmeta_function() );

$buf->appendLines(array(
"{$this->compName}() {",
"local curcontext=\$curcontext state line",
"typeset -A opt_args",
"local ret=1",
$this->complete_with_subcommands($this->app), 
"return ret",
"}",
"compdef {$this->compName} {$this->bindName}"
));
return $buf->__toString();
}







public function command_function_name($signature) {
return '__' . $this->compName . '_' . preg_replace('#\W#','_', $signature);
}


public function complete_with_subcommands(CommandBase $cmd, $level = 1) {
$cmdSignature = $cmd->getSignature();

$buf = new Buffer;
$buf->setIndent($level);

$subcmds = $this->visible_commands($cmd->getCommands());
$descsBuf = $this->describe_commands($subcmds, $level);

$code = array();



$buf->appendLine("_arguments -C \\");
$buf->indent();

if ($args = $this->command_flags($cmd, $cmdSignature)) {
foreach ($args as $arg) {
$buf->appendLine($arg . " \\");
}
}
$buf->appendLine("': :->cmds' \\");
$buf->appendLine("'*:: :->option-or-argument' \\");
$buf->appendLine(" && return");
$buf->unindent();

$buf->appendLine("case \$state in");
$buf->indent();

$buf->appendLine("(cmds)");
$buf->appendBuffer($descsBuf);
$buf->appendLine(";;");

$buf->appendLine("(option-or-argument)");




$buf->indent();
$buf->appendLine("curcontext=\${curcontext%:*}-\$line[1]:");
$buf->appendLine("case \$line[1] in");
$buf->indent();
foreach ($subcmds as $k => $subcmd) {

$buf->appendLine("($k)");

if ($subcmd->hasCommands()) {
$buf->appendBlock($this->complete_with_subcommands($subcmd, $level + 1));
} else {
$buf->appendBlock($this->complete_command_options_arguments($subcmd, $level + 1));
}
$buf->appendLine(";;");
}
$buf->unindent();
$buf->appendLine("esac");
$buf->appendLine(";;");
$buf->unindent();
$buf->appendLine("esac");
return $buf->__toString();
}
}


<?php
namespace CLIFramework\Completion;
use CLIFramework\Buffer;
use Exception;
use CLIFramework\Application;
use CLIFramework\ArgInfo;
use CLIFramework\CommandBase;






function array_to_bash(array $array) {
$out = '(';
foreach($array as $key => $value) {
$out .= '["' . addcslashes($key, '"') . '"]="' . addcslashes($value,'"') . '"';
$out .= ' ';
}
$out .= ')';
return $out;
}

function set_bash_array($name, array $array)
{
return $name . '=' . array_to_bash($array);
}

function set_bash_var($name, $value) 
{
return $name . '=' . $value;
}

function local_bash_var($name, $value) 
{
return 'local ' . $name . '=' . $value;
}

function command_signature_suffix(CommandBase $command) {
return $command->getSignature();

}

class BashGenerator
{
public $app;




public $programName;




public $compName;




public $bindName;

public $buffer;

public function __construct(Application $app, $programName, $bindName, $compName)
{
$this->app = $app;
$this->programName = $programName;
$this->compName = $compName;
$this->bindName = $bindName;
$this->buffer = new Buffer;
}

public function output() {
return $this->complete_application();
}

public function visible_commands(array $cmds) {
$visible = array();
foreach ($cmds as $name => $cmd) {
if ( ! preg_match('#^_#', $name) ) {
$visible[$name] = $cmd;
}
}
return $visible;
}

public function render_argument_completion_values(ArgInfo $a) {
if ($a->validValues || $a->suggestions) {
$values = array();
if ($a->validValues) {
$values = $a->getValidValues();
} elseif ($a->suggestions ) {
$values = $a->getSuggestions();
}
return join(" ", $values);
}
return '';
}

public function complete_application() {
$bindName = $this->bindName;
$compName = $this->compName;

$compPrefix = "__" . $compName;

$buf = new Buffer;
$buf->appendLines(array(
"#!/bin/bash",
"# bash completion script generated by CLIFramework",
"# Web: http://github.com/c9s/php-CLIFramework",
"# THIS IS AN AUTO-GENERATED FILE, PLEASE DON'T MODIFY THIS FILE DIRECTLY.",
));
$buf->append('
# This function can be used to access a tokenized list of words
# on the command line:
#
#   __demo_reassemble_comp_words_by_ref \'=:\'
#   if test "${words_[cword_-1]}" = -w
#   then
#       ...
#   fi
#
# The argument should be a collection of characters from the list of
# word completion separators (COMP_WORDBREAKS) to treat as ordinary
# characters.
#
# This is roughly equivalent to going back in time and setting
# COMP_WORDBREAKS to exclude those characters.  The intent is to
# make option types like --date=<type> and <rev>:<path> easy to
# recognize by treating each shell word as a single token.
#
# It is best not to set COMP_WORDBREAKS directly because the value is
# shared with other completion scripts.  By the time the completion
# function gets called, COMP_WORDS has already been populated so local
# changes to COMP_WORDBREAKS have no effect.
#
# Output: words_, cword_, cur_.

__demo_reassemble_comp_words_by_ref()
{
    local exclude i j first
    # Which word separators to exclude?
    exclude="${1//[^$COMP_WORDBREAKS]}"
    cword_=$COMP_CWORD
    if [ -z "$exclude" ]; then
        words_=("${COMP_WORDS[@]}")
        return
    fi
    # List of word completion separators has shrunk;
    # re-assemble words to complete.
    for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
        # Append each nonempty word consisting of just
        # word separator characters to the current word.
        first=t
        while
            [ $i -gt 0 ] &&
            [ -n "${COMP_WORDS[$i]}" ] &&
            # word consists of excluded word separators
            [ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
        do
            # Attach to the previous token,
            # unless the previous token is the command name.
            if [ $j -ge 2 ] && [ -n "$first" ]; then
                ((j--))
            fi
            first=
            words_[$j]=${words_[j]}${COMP_WORDS[i]}
            if [ $i = $COMP_CWORD ]; then
                cword_=$j
            fi
            if (($i < ${#COMP_WORDS[@]} - 1)); then
                ((i++))
            else
                # Done.
                return
            fi
        done
        words_[$j]=${words_[j]}${COMP_WORDS[i]}
        if [ $i = $COMP_CWORD ]; then
            cword_=$j
        fi
    done
}

if ! type _get_comp_words_by_ref >/dev/null 2>&1; then
_get_comp_words_by_ref ()
{
    local exclude cur_ words_ cword_
    if [ "$1" = "-n" ]; then
        exclude=$2
        shift 2
    fi
    __demo_reassemble_comp_words_by_ref "$exclude"
    cur_=${words_[cword_]}
    while [ $# -gt 0 ]; do
        case "$1" in
        cur)
            cur=$cur_
            ;;
        prev)
            prev=${words_[$cword_-1]}
            ;;
        words)
            words=("${words_[@]}")
            ;;
        cword)
            cword=$cword_
            ;;
        esac
        shift
    done
}
fi


# Generates completion reply, appending a space to possible completion words,
# if necessary.
# It accepts 1 to 4 arguments:
# 1: List of possible completion words.
# 2: A prefix to be added to each possible completion word (optional).
# 3: Generate possible completion matches for this word (optional).
# 4: A suffix to be appended to each possible completion word (optional).
__mycomp ()
{
	local cur_="${3-$cur}"

	case "$cur_" in
	--*=)
		;;
	*)
		local c i=0 IFS=$\' \t\n\'
		for c in $1; do
			c="$c${4-}"
			if [[ $c == "$cur_"* ]]; then
				case $c in
				--*=*|*.) ;;
				*) c="$c " ;;
				esac
				COMPREPLY[i++]="${2-}$c"
			fi
		done
		;;
	esac
}

__mycompappend ()
{
	local i=${#COMPREPLY[@]}
	for x in $1; do
		if [[ "$x" == "$3"* ]]; then
			COMPREPLY[i++]="$2$x$4"
		fi
	done
}
');

$completeMeta =<<<"BASH"
__complete_meta ()
{
    local app="{$this->programName}"
    local command_signature=\$1
    local complete_for=\$2
    local arg=\$3  # could be "--dir", 0 for argument index
    local complete_type=\$4
    local IFS=\$'\n'

    # When completing argument valid values, we need to eval
    lines=(\$(\$app meta --bash --flat \$command_signature \$complete_for \$arg \$complete_type))

    # Get the first line to return the compreply
    # Complete the rest lines as words
    COMPREPLY=(\$(compgen -W "\${lines[*]:1}" -- \$cur))
}


BASH;
$buf->append($completeMeta);

$this->generateCommandCompletionRecursively($buf, $this->app, $compPrefix);

$funcSuffix = command_signature_suffix($this->app);

$buf->append("
{$compPrefix}_main_wrapper()
{
    {$compPrefix}_complete_{$funcSuffix} \"app\" 0
}
complete -o bashdefault -o default -o nospace -F {$compPrefix}_main_wrapper {$bindName} 2>/dev/null
");
return $buf->__toString();
}

public function generateCompleteFunction(Buffer $buf, CommandBase $cmd, $compPrefix)
{
$funcSuffix = command_signature_suffix($cmd);
$buf->appendLine("{$compPrefix}_complete_{$funcSuffix} ()");
$buf->appendLine("{");
$buf->appendLine(local_bash_var('comp_prefix',$compPrefix));
$buf->append('
        local cur words cword prev
        _get_comp_words_by_ref -n =: cur words cword prev

        local command_signature=$1
        local command_index=$2

        ((command_index++))

        # Output application command alias mapping 
        # aliases[ alias ] = command
        declare -A subcommand_alias

        # Define the command names
        declare -A subcommands

        declare -A subcommand_signs

        # option names defines the available options of this command
        declare -A options
        # options_require_value: defines the required completion type for each
        # option that requires a value.
        declare -A options_require_value
        ');


$subcommands = $cmd->getCommands();
$subcommandAliasMap = array();
$subcommandDescMap = array();
$commandOptionMap = array();
$commandOptionRequireValueMap = array();
$commandSignMap = array();
foreach($subcommands as $subcommand) {
foreach( $subcommand->aliases() as $alias) {
$subcommandAliasMap[$alias] = $subcommand->getName();
}
$subcommandDescMap[ $subcommand->getName() ] = $subcommand->brief();
$commandSignMap[ $subcommand->getName() ] = command_signature_suffix($subcommand);
}







$buf->appendLine(set_bash_array('subcommands',$subcommandDescMap));
$buf->appendLine(set_bash_array('subcommand_alias',$subcommandAliasMap));
$buf->appendLine(set_bash_array('subcommand_signs', $commandSignMap));





$options = $cmd->getOptionCollection();
foreach($options as $option) {
if ($option->short) {
$commandOptionMap[ '-' . $option->short ] = 1;
}
if ($option->long) {
$commandOptionMap[ '--' . $option->long ] = 1;
}

if ($option->required || $option->multiple) {
if ($option->short ) {
$commandOptionRequireValueMap[ '-' . $option->short ] = 1;
}
if ($option->long ) {
$commandOptionRequireValueMap[ '--' . $option->long ] = 1;
}
}
}
$buf->appendLine(set_bash_array('options',$commandOptionMap));


$buf->appendLine(set_bash_array('options_require_value', $commandOptionRequireValueMap));



$argInfos = $cmd->getArgInfoList();

$buf->appendLine(local_bash_var('argument_min_length', count($argInfos)));


$buf->append('
    # Get the command name chain of the current input, e.g.
    # 
    #     app asset install [arg1] [arg2] [arg3]
    #     app commit add
    #  
    # The subcommand dispatch should be done in the command complete function,
    # not in the root completion function. 
    # We should pass the argument index to the complete function.

    # command_index=1 start from the first argument, not the application name
    # Find the command position
    local argument_index=0
    local i
    local command
    local found_options=0

    # echo "[DEBUG] command_index: [$command_signature] [$command_index]"

    while [ $command_index -lt $cword ]; do
        i="${words[command_index]}"
        case "$i" in
            # Ignore options
            --=*) found_options=1 ;;
            --*) found_options=1 ;;
            -*) found_options=1 ;;
            *)
                # looks like my command, that\'s break the loop and dispatch to the next complete function
                if [[ -n "$i" && -n "${subcommands[$i]}" ]] ; then
                    command="$i"
                    break
                elif [[ -n "$i" && -n "${subcommand_alias[$i]}" ]] ; then
                    command="$i"
                    break
                elif [[ $command_index -gt 1 ]] ; then
                    # If the command is not found, check if the previous argument is an option expecting a value
                    # or it is an argument

                    # the previous argument (might be)
                    p="${words[command_index-1]}"

                    # not an option value, push to the argument list
                    if [[ -z "${options_require_value[$p]}" ]] ; then
                        # echo "[DEBUG] argument_index++ because of [$i]"
                        ((argument_index++))
                    fi
                fi
            ;;
        esac
        ((command_index++))
    done
');

$buf->append('
    # If the first command name is not found, we do complete...
    if [[ -z "$command" ]] ; then
        case "$cur" in
            # If the current argument $cur looks like an option, then we should complete
            -*)
                __mycomp "${!options[*]}"
                return
            ;;
            *)
                # The argument here can be an option value. e.g. --output-dir /tmp
                # The the previous one...
                if [[ -n "$prev" && -n "${options_require_value[$prev]}" ]] ; then
                    # TODO: local complete_type="${options_require_value[$prev]"}
        ');
$buf->appendLine('          __complete_meta "$command_signature" "opt" "${prev##*(-)}" "valid-values"');
$buf->appendLine('          return');
$buf->appendLine('      fi');
$buf->appendLine('      # If the command requires at least $argument_min_length to run, we check the argument');

if (count($argInfos) > 0) {
$buf->appendLine('if [[ $argument_min_length > 0 ]] ; then');





$buf->appendLine('  case $argument_index in');
foreach($argInfos as $index => $a) {

$pattern = $index;
if ($a->multiple) {
$pattern = '*';
}
$buf->appendLine("      $pattern)");

if ($a->validValues || $a->suggestions) {
$values = array();
if ($a->validValues) {
if (is_callable($a->validValues)) {
$buf->appendLine("      __complete_meta \"\$command_signature\" \"arg\" $index \"valid-values\"");
$buf->appendLine('      return');
} elseif ($values = $a->getValidValues()) {
$buf->appendLine('      COMPREPLY=( $(compgen -W "' . join("\n",$values) . '" -- $cur) )');
$buf->appendLine('      return');
}
} elseif ($a->suggestions) {
if (is_callable($a->suggestions)) {
$buf->appendLine("      __complete_meta \"\$command_signature\" \"arg\" $index \"suggestions\"");
$buf->appendLine('      return');
} elseif ($values = $a->getSuggestions()) {
$buf->appendLine('      COMPREPLY=( $(compgen -W "' . join("\n", $values) . '" -- $cur) )');
$buf->appendLine('      return');
}
}
} elseif (in_array($a->isa,array('file','path','dir'))) {
$compopt = '';
switch($a->isa) {
case "file":
$compopt .= ' -A file';

break;
case "path":
$compopt .= ' -A file';
break;
case "command":
$compopt .= ' -A command';
break;
case "user":
$compopt .= ' -A user';
break;
case "service":
$compopt .= ' -A service';
break;
case "hostname":
$compopt .= ' -A hostname';
break;
case "job":
$compopt .= ' -A job';
break;
case "dir":
case "directory":
$compopt .= ' -A directory';
break;
}

if ($a->glob) {
$compopt = " -G \"{$a->glob}\"";
}
$buf->appendLine("COMPREPLY=(\$(compgen $compopt -- \$cur))");
$buf->appendLine("return");
}


$buf->appendLine("      ;;");
}
$buf->appendLine('  esac');
$buf->appendLine('  fi');
}

$buf->append('
                # If there is no argument support, then user is supposed to give a subcommand name or an option
                __mycomp "${!options[*]} ${!subcommands[*]} ${!subcommand_alias[*]}"
                return
            ;;
        esac
');

$buf->append('
    else
        # We just found the first command, we are going to dispatch the completion handler to the next level...
        # Rewrite command alias to command name to get the correct response
        if [[ -n "${subcommand_alias[$command]}" ]] ; then
            command="${subcommand_alias[$command]}"
        fi

        if [[ -n "${subcommand_signs[$command]}" ]] ; then
            local suffix="${subcommand_signs[$command]}"
            local completion_func="${comp_prefix}_complete_${suffix//-/_}"

            # Declare the completion function name and dispatch rest arguments to the complete function
            command_signature="${command_signature}.${command}"
            declare -f $completion_func >/dev/null && \
                $completion_func $command_signature $command_index && return
        else
            echo "Command \'$command\' not found"
        fi
    fi
');

$buf->appendLine("};");
}


public function generateCommandCompletionRecursively(Buffer $buf, $command, $compPrefix) {
foreach($command->getCommands() as $subcommand) {
if ($subcommand->hasCommands()) {
$this->generateCommandCompletionRecursively($buf, $subcommand, $compPrefix);
}
$this->generateCompleteFunction($buf, $subcommand, $compPrefix);
}
$this->generateCompleteFunction($buf, $command, $compPrefix);
}





}


<?php
namespace CLIFramework\Completion;

class Utils
{

static public function qq($str) {
return '"' . addcslashes($str , '"') . '"';
}

static public function q($str) {
return "'" . addcslashes($str, "'") . "'";
}

static public function array_qq(array $array) {
return array_map("CLIFramework\\Completion\\Utils::qq", $array);
}

static public function array_q(array $array) {
return array_map("CLIFramework\\Completion\\Utils::q", $array);
}

static public function array_escape_space(array $array)
{
return array_map(function($a) { return addcslashes($a, ' '); }, $array);
}

static public function array_indent(array $lines, $level = 1) 
{
$space = str_repeat('  ', $level);
return array_map(function($line) use ($space) {
return $space . $line;
}, $lines);
}
}




<?php
namespace CLIFramework;

class LevenshteinCorrector extends Corrector
{
public function match($input) {

$shortest = -1;


foreach ($this->possibleTokens as $word) {



$lev = levenshtein($input, $word);


if ($lev == 0) {


$closest = $word;
$shortest = 0;


break;
}



if ($lev <= $shortest || $shortest < 0) {

$closest = $word;
$shortest = $lev;
}
}
return $closet;
}
}



<?php
namespace CLIFramework;
use ArrayObject;

class ValueGroup extends ArrayObject
{

public function values() {
return array_values($this->getArrayCopy());
}

public function keys() {
return array_keys($this->getArrayCopy());
}

public function append($val) { 
parent::append($val);
return $this;
}


public function add($val) {
parent::append($val);
return $this;
}
}


<?php

namespace CLIFramework\IO;

interface Writer
{



public function write($text);




public function writeln($text);




public function writef($format);
}
<?php

namespace CLIFramework\IO;




class ReadlineConsole implements Console
{



private $stty;

public function __construct(Stty $stty)
{
$this->stty = $stty;
}

public static function isAvailable()
{
return extension_loaded('readline');
}

public function readLine($prompt)
{
$line = $this->doReadLine($prompt);
readline_add_history($line);

return $line;
}

public function readPassword($prompt)
{
return $this->noEcho(function () use ($prompt) {
return $this->doReadLine($prompt);
});
}

public function noEcho(\Closure $callback)
{
return $this->stty->withoutEcho($callback);
}

private function doReadLine($prompt)
{
return readline($prompt);
}
}
<?php

namespace CLIFramework\IO;

class EchoWriter implements Writer
{
public function write($text)
{
echo $text;
}

public function writeln($text)
{
echo $text."\n";
}

public function writef($format)
{
$args = func_get_args();
$this->write(call_user_func_array('sprintf', $args));
}
}
<?php

namespace CLIFramework\IO;





class StreamWriter implements Writer
{
private $stream;

public function __construct($stream)
{
if (!is_resource($stream)) {
throw new \RuntimeException('invalid stream');
}

$this->stream = $stream;
}

public function write($text)
{
fwrite($this->stream, $text);
}

public function writeln($text)
{
fwrite($this->stream, $text."\n");
}

public function writef($format)
{
$args = func_get_args();
$this->write(call_user_func_array('sprintf', $args));
}
}
<?php

namespace CLIFramework\IO;

class UnixStty implements Stty
{
public function enableEcho()
{
shell_exec('stty echo');
}

public function disableEcho()
{
shell_exec('stty -echo');
}

public function dump()
{
return shell_exec('stty -g');
}

public function withoutEcho(\Closure $callback)
{
$oldStyle = $this->dump();

$this->disableEcho();
$result = null;

try {
$result = $callback();
$this->restoreStyle($oldStyle);
} catch (\Exception $e) {
$this->restoreStyle($oldStyle);
throw $e;
}

return $result;
}

private function restoreStyle($style)
{
if (is_null($style)) {
return;
}

shell_exec('stty '.$style);
}
}
<?php

namespace CLIFramework\IO;




interface Stty
{



public function enableEcho();




public function disableEcho();






public function dump();








public function withoutEcho(\Closure $callback);
}
<?php

namespace CLIFramework\IO;




class StandardConsole implements Console
{



private $stty;

public function __construct(Stty $stty)
{
$this->stty = $stty;
}

public function readLine($prompt)
{
echo $prompt;

return $this->read();
}

public function readPassword($prompt)
{
echo $prompt;

return $this->noEcho(function () use ($prompt) {
return $this->read();
});
}

public function noEcho(\Closure $callback)
{
return $this->stty->withoutEcho($callback);
}

private function read()
{
return rtrim(fgets(STDIN), "\n");
}
}
<?php

namespace CLIFramework\IO;

class NullStty implements Stty
{
public function enableEcho()
{
}

public function disableEcho()
{
}

public function dump()
{
return '';
}

public function withoutEcho(\Closure $callback)
{
return $callback();
}
}
<?php

namespace CLIFramework\IO;

interface Console
{





public function readLine($prompt);






public function readPassword($prompt);








public function noEcho(\Closure $callback);
}
<?php

namespace CLIFramework\Logger;

use CLIFramework\Formatter;
use CLIFramework\Ansi\CursorControl;

class LogAction
{
public $title;

public $desc;

public $status;

protected $logger;

protected $cursorControl;

protected $actionColumnWidth = 38;

public function __construct($logger, $title, $desc, $status = 'waiting')
{
$this->logger = $logger;
$this->title = $title;
$this->desc = $desc;
$this->status = $status;

$this->cursorControl = new CursorControl($this->logger->fd);
$this->cursorControl->hide();
}

public function setStatus($status, $style = 'green')
{
$this->status = $status;
$this->update($style);
}

public function setActionColumnWidth($width)
{
$this->actionColumnWidth = $width;
}

protected function update($style = 'green')
{
$padding = max($this->actionColumnWidth - strlen($this->title), 1);
$buf = sprintf('  %s % -20s',
$this->logger->formatter->format(sprintf('%s', $this->title), $style).str_repeat(' ', $padding),
$this->status
);
fwrite($this->logger->fd, $buf."\r");
fflush($this->logger->fd);
}

public function finalize()
{
fwrite($this->logger->fd, "\n");
fflush($this->logger->fd);
$this->cursorControl->show();
}

public function done()
{
$this->setStatus('done');
$this->finalize();
}
}

class ActionLogger
{
public $fd;

public $formatter;

public function __construct($fd = null, $formatter = null)
{
$this->fd = $fd ?: fopen('php://stderr', 'w');
$this->formatter = $formatter ?: new Formatter();
}

public function newAction($title, $desc = '', $status = 'waiting')
{
$logAction = new LogAction($this, $title, $desc);
return $logAction;
}
}
<?php

namespace CLIFramework\Logger;

interface Logger
{
}
<?php
namespace CLIFramework\PharKit;
use Phar;
use CLIFramework\Logger;

use CodeGen\Block;
use CodeGen\Expr\NewObjectExpr;
use CodeGen\Statement\UseStatement;
use CodeGen\Statement\FunctionCallStatement;
use CodeGen\Statement\AssignStatement;
use CodeGen\Statement\MethodCallStatement;
use GetOptionKit\OptionResult;


class PharGenerator
{
protected $pharFile;

protected $alias;

protected $map;

protected $phar;

protected $shellbang = '#!/usr/bin/env php';

protected $logger;

protected $options;

public function __construct(Logger $logger, OptionResult $options, $pharFile, $alias = null)
{
$this->logger = $logger;
$this->options = $options;
$this->pharFile = $pharFile;

if ($alias) {
$this->alias = $alias;
} else {
$this->alias = basename($pharFile);
}

$this->phar = new Phar($this->pharFile, 0, $this->alias);
$this->phar->setSignatureAlgorithm(Phar::SHA1);
}

public function shellbang($shellbang)
{
$this->shellbang = $shellbang;
}

public function getPhar()
{
return $this->phar;
}

public function generate()
{




$this->phar->stopBuffering();

$compressType = Phar::GZ;
if ($this->options->{'no-compress'} ) {
$compressType = null;
} else if ($type = $this->options->compress) {
switch ($type) {
case 'gz':
$compressType = Phar::GZ;
break;
case 'bz2':
$compressType = Phar::BZ2;
break;
default:
throw new Exception("Phar compression: $type is not supported, valid values are gz, bz2");
break;
}
}
if ($compressType) {
$this->logger->info( "Compressing phar files...");
$this->phar->compressFiles($compressType);
}
}





}

<?php
namespace CLIFramework\PharKit;
use CodeGen\Renderable;

class PharURI implements Renderable
{
protected $alias;

protected $localPath;

public function __construct($alias, $localPath)
{
$this->alias = $alias;
$this->localPath = $localPath;
}

public function getLocalPath()
{
return $this->localPath;
}

public function getAlias()
{
return $this->alias;
}





public function render(array $args = array())
{
return $this->__toString();
}


public function __toString()
{

return var_export('phar://' . $this->alias . '/' . $this->localPath, true);
}

}




<?php

namespace CLIFramework\Ansi;

use InvalidArgumentException;






class Colors
{
const CODE_PATTERN = '#\033\[\d{0,1}[,;]?\d*(?:;\d2)?m#x';

protected static $foregroundColors = array(
'black' => '0;30',
'dark_gray' => '1;30',
'blue' => '0;34',
'light_blue' => '1;34',
'green' => '0;32',
'light_green' => '1;32',
'cyan' => '0;36',
'light_cyan' => '1;36',
'red' => '0;31',
'light_red' => '1;31',
'purple' => '0;35',
'light_purple' => '1;35',
'brown' => '0;33',
'yellow' => '1;33',
'light_gray' => '0;37',
'white' => '1;37',
);

protected static $backgroundColors = array(
'black' => '40',
'red' => '41',
'green' => '42',
'yellow' => '43',
'blue' => '44',
'magenta' => '45',
'cyan' => '46',
'light_gray' => '47',
);

protected static $attributes = array(
'bold' => 1,
'dim' => 2,
'underline' => 4,
'blink' => 5,
'reverse' => 7,
'hidden' => 8,
);

public static function stripAnsiEscapeCode($str)
{
return preg_replace(self::CODE_PATTERN, '', $str);
}

public static function strlenWithoutAnsiEscapeCode($str)
{
$plain = preg_replace(self::CODE_PATTERN, '', $str);

return mb_strlen($plain);
}

public static function reset()
{
return "\033[0m";
}

public static function attribute($text, $attribute)
{
if (!isset(self::$attributes[$attribute])) {
throw new InvalidArgumentException("Undefined attribute $attribute");
}
$str = "\033[".self::$attributes[$attribute].'m';
$str .= $text;
$str = "\033[0m";

return $str;
}


public static function decorate($string, $fg = null, $bg = null, $attribute = null)
{
$coloredString = '';


if ($fg && isset(self::$foregroundColors[$fg])) {
$coloredString .= "\033[".self::$foregroundColors[$fg].'m';
}

if ($bg && isset(self::$backgroundColors[$bg])) {
$coloredString .= "\033[".self::$backgroundColors[$bg].'m';
}

if ($attribute) {
$coloredString .= "\033[".self::$attributes[$attribute].'m';
}


$coloredString .= $string;

if ($fg || $bg) {
$coloredString .= "\033[0m";
}

return $coloredString;
}


public static function getForegroundColors()
{
return array_keys(self::$foregroundColors);
}


public static function getBackgroundColors()
{
return array_keys(self::$backgroundColors);
}
}
<?php

namespace CLIFramework\Ansi;




class CursorControl
{
protected $fd;

public function __construct($fd = null)
{
$this->fd = $fd ?: fopen('php://stderr', 'w');
}






public function home($row, $col)
{
fwrite($this->fd, "\e[{$row};{$column}H");
}

public function up($count = 1)
{
fwrite($this->fd, "\e[{$count}A");
}

public function down($count = 1)
{
fwrite($this->fd, "\e[{$count}B");
}

public function forward($count = 1)
{
fwrite($this->fd, "\e[{$count}C");
}

public function backward($count = 1)
{
fwrite($this->fd, "\e[{$count}D");
}






public function position($row, $column)
{
fwrite($this->fd, "\e[{$row},{$column}f");
}






public function save($attrs = true)
{
if ($attrs) {
fwrite($this->fd, "\e7");
}
fwrite($this->fd, "\e[s");
}






public function restore($attrs = true)
{
if ($attrs) {
fwrite($this->fd, "\e8");
}
fwrite($this->fd, "\e[u");
}

public function hide()
{
fwrite($this->fd, "\e[?25l");
}

public function show()
{
fwrite($this->fd, "\e[?25h");
}
}
<?php









namespace CLIFramework;











class Formatter
{


protected $styles = array(
'dim' => array('dim' => 1),
'red' => array('fg' => 'red'),
'green' => array('fg' => 'green'),
'white' => array('fg' => 'white'),
'yellow' => array('fg' => 'yellow'),
'strong_red' => array('fg' => 'red', 'bold' => 1),
'strong_green' => array('fg' => 'green', 'bold' => 1),
'strong_white' => array('fg' => 'white', 'bold' => 1),
'ask' => array('fg' => 'white', 'bold' => 1 , 'underline' => 1 ),
'choose' => array('fg' => 'white', 'bold' => 1 , 'underline' => 1 ),

'bold' => array('fg' => 'white', 'bold' => 1 ),
'underline' => array( 'fg' => 'white' , 'underline' => 1 ),


'info' => array('fg' => 'white', 'bold' => 1 ),
'debug' => array('fg' => 'white' ),
'notice' => array('fg' => 'yellow' ),
'warn' => array('fg' => 'red' ),
'error' => array('fg' => 'red', 'bold' => 1 ),

'done' => array('fg' => 'black', 'bg' => 'green' ),
'success' => array('fg' => 'black', 'bg' => 'green' ),
'fail' => array('fg' => 'black', 'bg' => 'red' ),

'action' => array('fg' => 'white', 'bg' => 'green' ),
);

protected $options = array(
'bold' => 1,
'dim' => 2,
'underline' => 4,
'blink' => 5,
'reverse' => 7,
'conceal' => 8
);

protected $foreground = array(
'black' => 30,
'red' => 31,
'green' => 32,
'yellow' => 33,
'blue' => 34,
'magenta' => 35,
'cyan' => 36,
'white' => 37
);

protected $background = array(
'black' => 40,
'red' => 41,
'green' => 42,
'yellow' => 43,
'blue' => 44,
'magenta' => 45,
'cyan' => 46,
'white' => 47
);

protected $supportsColors;

public function __construct()
{
$this->supportsColors = DIRECTORY_SEPARATOR != '\\'
&& function_exists('posix_isatty') && @posix_isatty(STDOUT);
}

public function preferRawOutput()
{
$this->supportsColors = false;
}

public function addStyle( $name, $style )
{
$this->styles[ $name ] = $style;
}

public function hasStyle( $name )
{
return isset($this->styles[ $name ]);
}

public function getStartMark($style)
{
if (!$this->supportsColors) {
return;
}

if ($style == 'none' || ! isset($this->styles[$style])) {
return '';
}

$parameters = $this->styles[$style];
$codes = array();

if (isset($parameters['fg'])) {
$codes[] = $this->foreground[$parameters['fg']];
}

if (isset($parameters['bg'])) {
$codes[] = $this->background[$parameters['bg']];
}

foreach ($this->options as $option => $value) {
if (isset($parameters[$option]) && $parameters[$option]) {
$codes[] = $value;
}
}

return "\033[".implode(';', $codes).'m';
}

public function getClearMark()
{
if (! $this->supportsColors) {
return '';
}
return "\033[0m";
}









public function format($text = '', $style = 'none')
{
return $this->getStartMark($style) . $text . $this->getClearMark();
}
}
<?php









namespace CLIFramework;
use GetOptionKit\OptionCollection;
use GetOptionKit\Option;
use GetOptionKit\OptionPrinter\OptionPrinter as OptionPrinterInterface;
use CLIFramework\Formatter;

class OptionPrinter implements OptionPrinterInterface
{
public $screenWidth = 78;

public $formatter;

public function __construct() {
$this->formatter = new Formatter;
}




public function renderOption(Option $opt)
{
$columns = array();
if ($opt->short) {
$columns[] = $this->formatter->format(sprintf('-%s',$opt->short), 'strong_white') 
. $this->renderOptionValueHint($opt, false);
}
if ($opt->long) {
$columns[] = $this->formatter->format(sprintf('--%s',$opt->long ), 'strong_white')
. $this->renderOptionValueHint($opt, true);
}
return join(', ', $columns);
}

public function renderOptionValueHint(Option $opt, $assign = true)
{
$n = 'value';
if ($opt->valueName) {
$n = $opt->valueName;
} elseif ($opt->isa) {
$n = $opt->isa;
}

if ( $opt->isRequired() ) {
return sprintf('%s<%s>', $assign ? '=' : ' ', $this->formatter->format($n, 'underline') );
} elseif ( $opt->isOptional() ) {
return sprintf('%s[<%s>]', $assign ? '=' : ' ', $this->formatter->format($n, 'underline'));
}

return '';
}






public function render(OptionCollection $options)
{

$lines = array();
foreach( $options as $option ) {
$c1 = $this->renderOption($option);
$lines[] = "\t" . $c1;
$lines[] = wordwrap("\t\t" . $option->desc, $this->screenWidth, "\n\t\t"); 
$lines[] = "";
}
return join("\n",$lines);
}
}


<?php
namespace CLIFramework\Config;

class GlobalConfig
{



private $config;




private $isVerbose = false;




private $isDebug = false;




private $pidDir;

public function __construct($config)
{
$this->config = $config;
}





public function isVerbose()
{
if (isset($this->config['core']['verbose'])) {
$this->isVerbose = $this->config['core']['verbose'] === '1';
}
return $this->isVerbose;
}





public function isDebug()
{
if (isset($this->config['core']['debug'])) {
$this->isDebug = $this->config['core']['debug'] === '1';
}
return $this->isDebug;
}




public function getPidDirectory()
{
if (isset($this->config['core']['pid_dir'])) {
$this->pidDir = $this->config['core']['pid_dir'];
}
return $this->pidDir;
}
}
<?php

namespace CLIFramework\ArgumentEditor;

class ArgumentEditor
{
public $args = array();

public function __construct($args = array())
{
$this->args = $args;
}

public function append($arg)
{
$args = func_get_args();
foreach ($args as $arg) {
$this->args[] = trim($arg);
}

return $this;
}

public function remove($arg)
{
$p = 0;
$removed = 0;
while ($p !== false) {

$p = array_search($arg, $this->args);
if ($p !== false) {
array_splice($this->args, $p);
++$removed;
}
}

return $removed;
}

public function replace($needle, $newarg)
{
$p = array_search($needle, $this->args);
if ($p !== false) {
$spliced = array_splice($this->args, $p, 1, $newarg);

return $spliced[0];
}

return false;
}

public function replaceRegExp($regexp, $newarg)
{
$regexp = '/'.preg_quote($regexp, '/').'/';
$this->args = preg_replace($regexp, $newarg, $this->args);
}






public function removeRegExp($regexp)
{
$regexp = '/'.preg_quote($regexp, '/').'/';
$this->args = preg_grep($regexp, $this->args, PREG_GREP_INVERT);
}






public function filter($callback)
{
$this->args = array_map($callback, $this->args);

return $this;
}




public function escape()
{
$this->args = array_map(function ($arg) {
return escapeshellarg($arg);
}, $this->args);
}




public function __toString()
{
return implode(' ', $this->args);
}
}
<?php
namespace CLIFramework;
use CLIFramework\ServiceContainer;




class Prompter
{
private $style;
private $formatter;
private $console;

public function __construct(ServiceContainer $container = null)
{
$container = $container ?: ServiceContainer::getInstance();
$this->formatter = $container['formatter'];
$this->console = $container['console'];
}




public function setStyle($style)
{
return $this->style = $style;
}




public function ask($prompt, $validAnswers = NULL, $default = NULL)
{
if ($validAnswers) {
$prompt .= ' [' . join('/',$validAnswers) . ']';
}
$prompt .= ' ';

if ($this->style) {
echo $this->formatter->getStartMark( $this->style );

}

$answer = null;
while (1) {
$answer = trim($this->console->readLine( $prompt ));
if ($validAnswers) {
if (in_array($answer,$validAnswers) ) {
break;
} else {
if (trim($answer) === "" && $default ) {
$answer = $default;
break;
}
continue;
}
}
break;
}
if ($this->style) {
echo $this->formatter->getClearMark();
}
return $answer;
}




public function password($prompt)
{
if ($this->style) {
echo $this->formatter->getStartMark( $this->style );
}

$result = $this->console->readPassword($prompt);

if ($this->style) {
echo $this->formatter->getClearMark();
}

return $result;
}
}
<?php









namespace CLIFramework;

interface CommandInterface
{
public function getLogger();
public function getFormatter();
}
<?php








namespace CLIFramework;
use Exception;
use LogicException;
use InvalidArgumentException;
use ReflectionObject;
use ArrayAccess;
use IteratorAggregate;
use GetOptionKit\OptionCollection;
use GetOptionKit\OptionResult;
use CLIFramework\Prompter;
use CLIFramework\Application;
use CLIFramework\Chooser;
use CLIFramework\CommandLoader;
use CLIFramework\CommandGroup;
use CLIFramework\Exception\CommandNotFoundException;
use CLIFramework\Exception\InvalidCommandArgumentException;
use CLIFramework\Exception\CommandArgumentNotEnoughException;
use CLIFramework\Exception\CommandClassNotFoundException;
use CLIFramework\Exception\ExecuteMethodNotDefinedException;
use CLIFramework\Exception\ExtensionException;
use CLIFramework\ArgInfo;
use CLIFramework\ArgInfoList;
use CLIFramework\Corrector;
use CLIFramework\Extension\Extension;
use CLIFramework\Extension\ExtensionBase;
use CLIFramework\Extension\CommandExtension;
use CLIFramework\Extension\ApplicationExtension;






abstract class CommandBase
implements ArrayAccess, IteratorAggregate, CommandInterface
{











protected $commands = array();





protected $commandGroups = array();

protected $aliases = array();




public $options;






public $parent;

public $optionSpecs;

protected $argInfos = array();

protected $extensions = array();

public function __construct(CommandBase $parent = null) 
{

if ($parent) {
$this->setParent($parent);
}
}







public function brief()
{
return 'awesome brief for your app.';
}






public function usage()
{

}






public function help()
{
return '';
}







public function aliases() 
{ 
}










public function addExtension(ExtensionBase $extension)
{
if (!$extension->isAvailable()) {
throw new ExtensionException("Extension " . get_class($extension) . " is not available", $extension);
}
$this->bindExtension($extension);
$this->extensions[] = $extension;
}






public function extension($extension)
{
if (is_string($extension)) {
$extension = new $extension;
} else if (! $extension instanceof ExtensionBase) {
throw new LogicException("Not an extension object or an extension class name.");
}
return $this->addExtension($extension);
}


protected function bindExtension(ExtensionBase $extension)
{
if ($extension instanceof CommandExtension) {
$extension->bindCommand($this);
} else if ($extension instanceof ApplicationExtension) {
$extension->bindApplication($this->getApplication());
}
}

protected function initExtensions()
{
foreach ($this->extensions as $extension) {

}
}








public function addCommandGroup($groupName, $commands = array() ) {
$group = new CommandGroup($groupName);
foreach($commands as $key => $val) {
$name = $val;
if (is_numeric($key)) {
$cmd = $this->addCommand($val);
} else {
$cmd = $this->addCommand($key, $val);
$name = $key;
}
$group->addCommand($name, $cmd);
}
$this->commandGroups[] = $group;
return $group;
}

public function getCommandGroups() {
return $this->commandGroups;
}

public function isApplication() {
return $this instanceof Application;
}





public function getFormattedHelpText()
{
$text = $this->help();


$formatter = $this->getFormatter();
$text = preg_replace_callback( '#<(\w+)>(.*?)</\1>#i', function($matches) use ($formatter) {
$style = $matches[1];
$text = $matches[2];

switch ($style) {
case 'b': $style = 'bold'; break;
case 'u': $style = 'underline'; break;
}

if ( $formatter->hasStyle($style) ) {
return $formatter->format( $text , $style );
}

return $matches[0];
}, $text );


$text = preg_replace_callback( '#[*]([^*]*?)[*]#' , function($matches) use ($formatter) {
return $formatter->format( $matches[1] , 'bold' );
} , $text );

$text = preg_replace_callback( '#[_]([^_]*?)[_]#' , function($matches) use ($formatter) {
return $formatter->format( $matches[1] , 'underline' );
} , $text );

return $text;
}
















public function options($getopt)
{

}






public function init()
{
if ($this->isCommandAutoloadEnabled())
$this->autoloadCommands();
}


public function isCommandAutoloadEnabled()
{
return $this->isApplication()
? $this->commandAutoloadEnabled
: $this->getApplication()->commandAutoloadEnabled;
}






public function getApplication() {
if ($this instanceof Application) {
return $this;
}

$p = $this->parent;
while ($p) {
if ($p instanceof Application) {
return $p;
}
$p = $p->parent;
}
}








protected function autoloadCommands($path = null)
{
$autoloader = new CommandAutoloader($this);
$autoloader->autoload($path);
}


public function _init() 
{

$this->optionSpecs = new OptionCollection;



$this->options = new OptionResult;


$this->options($this->optionSpecs);



$args = new ArgInfoList;
$this->arguments($args);
if (count($args) > 0) {
$this->argInfos = $args;
} else {
$this->argInfos = $this->getArgInfoListByReflection();
}


$this->init();
$this->initExtensions();
}









public function registerCommand($command, $class = null)
{
$trace = debug_backtrace(false, 2);
$call = $trace[0]['file'].':'.$trace[0]['line'];
trigger_error("'registerCommand' method is deprecated, please use 'addCommand' instead. Called on $call\n");
return $this->addCommand($command, $class);
}

public function setParent(CommandBase $parent)
{
$this->parent = $parent;
}

public function getParent() 
{
return $this->parent;
}




public function getLoader() 
{
return CommandLoader::getInstance();
}










public function commandGroup($groupName, $commands = array())
{
if (is_string($commands)) {
$commands = explode(' ',$commands);
}
return $this->addCommandGroup($groupName, $commands);
}









public function command($command, $class = null) 
{
return $this->addCommand($command, $class);
}















public function addCommand($command,$class = null)
{


if ($class) {
if ($this->getLoader()->loadClass($class) === false )
throw CommandClassNotFoundException("Command class $class not found.");
} else {
if ($this->parent) {

$class = $this->getLoader()->loadSubcommand($command,$this);
} else {

$class = $this->getLoader()->load($command);
}
}
if (! $class) {
throw new CommandClassNotFoundException("command class $class for command $command not found");
}

$cmd = $this->createCommand($class);
$this->connectCommand($command, $cmd);
return $cmd;
}










public function getAllCommandPrototype() {
$lines = array();

if (method_exists($this,'execute')) {
$lines[] = $this->getCommandPrototype();
}
if ($this->hasCommands()) {
foreach( $this->commands as $name => $subcmd) {
$lines[] = $subcmd->getCommandPrototype();
}
}
return $lines;
}

public function getCommandPrototype() {
$out = array();

$out[] = $this->getApplication()->getProgramName();


foreach($this->getCommandNameTraceArray() as $n) {
$out[] = $n;
}

if (! empty($this->getOptionCollection()->options) ) {
$out[] = "[options]";
}
if ($this->hasCommands() ) {
$out[] = "<subcommand>";
} else {
$argInfos = $this->getArgInfoList();
foreach( $argInfos as $argInfo ) {
$out[] = "<" . $argInfo->name . ">";
}
}
return join(" ",$out);
}









protected function connectCommand($name, CommandBase $cmd) {
$cmd->setName($name);
$this->commands[$name] = $cmd;


$aliases = $cmd->aliases();
if (is_string($aliases)) {
$aliases = preg_split('/\s+/', $aliases);
}
if (!is_array($aliases)) {
throw new InvalidArgumentException("Aliases needs to be an array or a space-separated string.");
}
foreach( $aliases as $alias) {
$this->aliases[$alias] = $cmd;
}
}






public function aggregate() {
$groups = array();
$commands = array();
foreach($this->getVisibleCommands() as $name => $cmd) {
$commands[ $name ] = $cmd;
}

foreach($this->commandGroups as $g) {
if ($g->isHidden) {
continue;
}
foreach($g->getCommands() as $name => $cmd) {
unset($commands[$name]);
}
}

uasort($this->commandGroups, function($a, $b) { 
if ($a->getId() == "dev") return 1;
return 0;
});

return array(
'groups' => $this->commandGroups,
'commands' => $commands,
);
}







public function hasCommands() {
return ! empty($this->commands);
}








public function hasCommand($command)
{
return isset($this->commands[$command]) || isset($this->aliases[$command]);
}






public function getCommandList()
{
return array_keys( $this->commands );
}









public function getVisibleCommands() 
{
$cmds = array();
foreach( $this->getVisibleCommandList() as $name ) {
$cmds[ $name ] = $this->commands[ $name ];
}
return $cmds;
}









public function getVisibleCommandList() 
{
return array_filter(array_keys($this->commands), function($name) {
return !preg_match('#^_#', $name);
});
}







public function getCommandNameTraceArray() {
$cmdStacks = array( $this->getName() );
$p = $this->parent;
while($p) {
if (! $p instanceof Application) {
$cmdStacks[] = $p->getName();
}
$p = $p->parent;
}
return array_reverse($cmdStacks);
}

public function getSignature() {
return join('.', $this->getCommandNameTraceArray());
}







public function getCommands() 
{
return $this->commands;
}









public function getCommand($commandName)
{
if ( isset($this->aliases[$commandName]) ) {
return $this->aliases[$commandName];
}
if ( isset($this->commands[ $commandName ]) ) {
return $this->commands[ $commandName ];
}
throw new CommandNotFoundException($this, $commandName);
}

public function guessCommand($commandName) {

$words = array_keys($this->commands);
$correction = new Corrector($words);
return $correction->correct($commandName);
}









public function createCommand($commandClass)
{
$cmd = new $commandClass($this);
$cmd->_init();
return $cmd;
}






public function getOptions()
{
return $this->options;
}






public function setOptions(OptionResult $options)
{
$this->options = $options;
}






public function getOptionCollection()
{
return $this->optionSpecs;
}




public function prepare()
{
foreach ($this->extensions as $extension) { 
$extension->prepare();
}
}




public function finish() 
{
foreach ($this->extensions as $extension) { 
$extension->finish();
}
}






public function arguments($args) { }

public function getArgInfoList() 
{
return $this->argInfos;
}




public function getArgInfoListByReflection() { 
$argInfo = new ArgInfoList;

$ro = new ReflectionObject($this);
if (!method_exists($this,'execute')) {
throw new ExecuteMethodNotDefinedException($this);
}

$method = $ro->getMethod('execute');
$requiredNumber = $method->getNumberOfRequiredParameters();
$parameters = $method->getParameters();
foreach ($parameters as $param) {

$a = new ArgInfo($param->getName());
if ($param->isOptional()) {
$a->optional(true);
}
$argInfo->append($a);
}
return $argInfo;
}











public function executeWrapper(array $args)
{

$argInfos = $this->getArgInfoList();

for ($i = 0; $i < count($argInfos); $i++ ) {
$argInfo = $argInfos[$i];
if (isset($args[$i])) {
$arg = $args[$i];

$valid = false;
$message = NULL;
$ret = $argInfo->validate($arg);

if (is_array($ret)) {
$valid = $ret[0];
$message = $ret[1];
} elseif (is_bool($ret)) {
$valid = $ret;
}

if ($valid === FALSE) {
$this->logger->error($message ?: "Invalid argument $arg");

return false;
}
}
}



$refl = new ReflectionObject($this);
if (!method_exists( $this,'execute' )) {
throw new ExecuteMethodNotDefinedException($this);
}

$reflMethod = $refl->getMethod('execute');
$requiredNumber = $reflMethod->getNumberOfRequiredParameters();
if ( count($args) < $requiredNumber ) {
throw new CommandArgumentNotEnoughException($this, count($args), $requiredNumber);
}

$event = $this->getApplication()->getEventService();


$event->trigger('execute.before');

$event->trigger('execute');
foreach ($this->extensions as $extension) { 
$extension->execute();
}

$ret = call_user_func_array(array($this,'execute'), $args);

$event->trigger('execute.after');


return $ret;
}












public function ask($prompt, $validAnswers = null )
{
$prompter = new Prompter;
$prompter->setStyle('ask');
return $prompter->ask( $prompt , $validAnswers );
}




















public function choose($prompt, $choices)
{
$chooser = new Chooser;
$chooser->setStyle('choose');
return $chooser->choose( $prompt, $choices );
}

#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return isset($this->commands[$key]);
}

#[\ReturnTypeWillChange]
public function offsetSet($key,$value)
{
$this->commands[$key] = $value;
}

#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->commands[$key];
}

#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
unset($this->commands[$key]);
}

#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->commands);
}

}
<?php
namespace CLIFramework\Extension;
use CLIFramework\Command;

interface Extension
{
}
<?php
namespace CLIFramework\Extension;
use CLIFramework\Command;
use CLIFramework\Extension\Extension;
use CLIFramework\Extension\ExtensionBase;

abstract class CommandExtension extends ExtensionBase
{
protected $config;

protected $command;

public function bindCommand(Command $command)
{
$this->command = $command;
$this->options($command->getOptionCollection());


$this->config = $command->getApplication()->getGlobalConfig();
$this->setServiceContainer($command->getApplication()->getService());
$this->init();
}

}
<?php
namespace CLIFramework\Extension;
use CLIFramework\ServiceContainer;
use CLIFramework\Command;
use CLIFramework\CommandBase;
use CLIFramework\Logger;
use GetOptionKit\OptionCollection;
use LogicException;
use CLIFramework\ArgInfoList;

abstract class ExtensionBase
{
protected $container;

public function __construct()
{

}

public function setServiceContainer(ServiceContainer $container)
{
$this->container = $container;
}





public function init()
{

}

static public function isSupported()
{
return true;
}

public function isAvailable()
{
return true;
}

public function options($opts)
{
}

public function arguments($args) 
{

}

public function prepare() 
{

}

public function execute() 
{

}

public function finish() 
{

}

public function __get($accessor) 
{
if (isset($this->container[$accessor])) {
return $this->container[$accessor];
}
throw new LogicException("Undefined accessor '$accessor'");
}

}




<?php
namespace CLIFramework\Extension;
use CLIFramework\ServiceContainer;
use CLIFramework\Command;
use CLIFramework\CommandBase;
use CLIFramework\Logger;
use CLIFramework\Exception\ExtensionException;
use CLIFramework\Extension\CommandExtension;
use CLIFramework\IO\StreamWriter;
use GetOptionKit\OptionCollection;

class DaemonExtension extends CommandExtension
{
protected $logger;




protected $detach = false;

protected $chdir = false;

public function isAvailable()
{
return function_exists('pcntl_fork');
}


static public function isSupported()
{
return function_exists('pcntl_fork');
}


public function finish()
{
$pidFile = $this->getPidFilePath();
if (file_exists($pidFile)) {
@unlink($pidFile);
}
}

public function execute()
{
if (!$this->isAvailable()) {
throw new ExtensionException("pcntl_fork() is not supported.");
}
$this->prepareLogger();
$logger = $this->getLogger();
$this->daemonize();

}




public function detach()
{
$this->detach = true;
}




protected function changeDirectory()
{
$this->chdir = true;
}

public function getPidFilePath()
{
if ($this->getCommandOptions() && $this->getCommandOptions()->{'pid-file'}) {
return $this->getCommandOptions()->{'pid-file'};
}
$pid = getmypid();
$pidFile = $this->command ? $this->command->getName() : $pid;
return $this->config->getPidDirectory() . "/$pidFile.pid";
}

public function options($opts)
{
$opts->add('pid-file?', '(daemon) Path of pid file.');
$opts->add('log-path?', '(daemon) Path of log file when running with daemon extension.');
$opts->add('detach', '(daemon) Detach from the shell.');
}

protected function prepareLogger()
{
$logPath = $this->getLogPath();
$logger = $this->getLogger();

if (!$logPath || !$logger) {
return;
}

$resource = fopen($logPath, "a+");
if ($resource === false) {
throw new ExtensionException("Can't open file: $logPath", $this);
}


$logger->setWriter(new StreamWriter($resource));
}

protected function daemonize()
{
if ($this->detach || $this->command->options->{'detach'}) {
$this->command->logger->debug('forking process to background..');







switch (pcntl_fork()) {
case -1:
throw new ExtensionException("pcntl_fork() failed");


case 0:
break;


default:
if (!fclose(STDIN)) {
throw new ExtensionException("fclose(STDIN) failed");
}

if (!fclose(STDOUT)) {
throw new ExtensionException("fclose(STDOUT) failed");
}

if (!fclose(STDERR)) {
throw new ExtensionException("fclose(STDERR) failed");
}
exit(0);
}
}


if ($this->savePid() === false) {
throw new ExtensionException("pid file create failed");
}

if ($this->chdir) {
$this->chdir();
}
}

private function chdir()
{
if ($this->chdir && !chdir("/")) {
throw new ExtensionException("chdir failed");
}
}

protected function savePid()
{
$pidFile = $this->getPidFilePath();
$pid = getmypid();
$this->command->logger->debug("pid {$pid} saved in $pidFile");
return file_put_contents($pidFile, $pid);
}

protected function getLogPath()
{

if ($logPath = $this->command->options->{'log-path'}) {
return $logPath;
}

if ($options = $this->getApplicationOptions()) {
if ($logPath = $options->{'log-path'}) {
return $logPath;
}
}
return null;
}

protected function getLogger()
{
if ($this->hasApplication()) {
$this->logger = $this->command->getLogger();
}
if (!$this->logger) {
$this->logger = new Logger();
}
return $this->logger;
}

protected function getApplicationOptions()
{
if (!$this->hasApplication()) {
return null;
}
return $this->command->getApplication()->getOptions();
}

private function getCommandOptions()
{
return $this->command ? $this->command->getOptions() : null;
}

private function hasApplication()
{
return $this->command && $this->command->hasApplication();
}
}
<?php
namespace CLIFramework\Extension;
use CLIFramework\Application;

interface ApplicationExtension extends Extension {

public function bindApplication(Application $app);

}

<?php

namespace CLIFramework\Autoload;

use RuntimeException;
use CodeGen\Expr\NewObjectExpr;
use CodeGen\Block;
use CodeGen\Statement\UseStatement;
use CodeGen\Statement\AssignStatement;
use CodeGen\Statement\MethodCallStatement;
use CodeGen\Statement\RequireStatement;
use Symfony\Component\Finder\Finder;
use Symfony\Component\ClassLoader\ClassMapGenerator;
use CLIFramework\Logger;

class ComposerAutoloadGenerator
{



protected $packages = array();

protected $workingDir = '';

protected $vendorDir = 'vendor';

protected $logger;

protected $includeDevDependencies = false;

public function __construct(Logger $logger)
{
$this->workingDir = getcwd(); 
$this->logger = $logger;
}

public function setWorkingDir($workingDir)
{
$this->workingDir = $workingDir;
}

public function setVendorDir($vendorDir)
{
$this->vendorDir = $vendorDir;
}

public function traceAutoloadsWithComposerJson($composerJson = 'composer.json', $isRoot = false)
{
$json = file_get_contents($composerJson);
$config = json_decode($json, true);
if ($isRoot) {
$config['root'] = true;
}
if (isset($config['name'])) {
$this->packages[ $config['name'] ] = $config;
}

return $this->traceAutoloads($config, $isRoot);
}

public function traceAutoloadsWithRequirements(array $config, array $requirements = array())
{
$this->logger->debug('Tracing autoload from package: '.@$config['name']);

$autoloads = array();
foreach ($requirements as $packageName => $requirement) {
if (in_array($packageName, array('php', 'hhvm'))) {
continue;
} elseif (preg_match('/^(?:ext|lib)-/', $packageName)) {
continue;
}


if (isset($config['name']) && $config['name'] === $packageName) {
$packageComposerJson = $this->workingDir.DIRECTORY_SEPARATOR.'composer.json';
} else {
$packageComposerJson = $this->workingDir.DIRECTORY_SEPARATOR.$this->vendorDir.DIRECTORY_SEPARATOR.$packageName.DIRECTORY_SEPARATOR.'composer.json';
}

if (file_exists($packageComposerJson)) {
$packageAutoloads = $this->traceAutoloadsWithComposerJson($packageComposerJson, false); 
$autoloads = array_merge($autoloads, $packageAutoloads);
} elseif (isset($this->packages[ $packageName ])) {
$config = $this->packages[ $packageName ];
$autoloads = array_merge($autoloads, $this->traceAutoloads($config, false));
} else {

throw new RuntimeException("Missing composer.json file: $packageComposerJson");
}
}

return $autoloads;
}

public function traceAutoloads(array $config, $isRoot = false)
{
$autoloads = array();


if (isset($config['require'])) {
$this->logger->debug('Tracing package autoload from "require" section');
$autoloads = array_merge($autoloads, $this->traceAutoloadsWithRequirements($config, $config['require']));
}
if ($isRoot && $this->includeDevDependencies && isset($config['require-dev'])) {
$this->logger->debug('Tracing package autoload from "require-dev" section');
$autoloads = array_merge($autoloads, $this->traceAutoloadsWithRequirements($config, $config['require-dev']));
}

if (isset($config['autoload'])) {
if ($isRoot) {
$baseDir = $this->workingDir;
} else {
$baseDir = $this->workingDir.DIRECTORY_SEPARATOR.$this->vendorDir.DIRECTORY_SEPARATOR.$config['name'];
}




if (isset($config['target-dir'])) {
$this->logger->warn("Found deprecated property 'target-dir' in package ".$config['name']);

$baseDir = $config['target-dir'];
$autoloads[$config['name']] = $this->prependAutoloadPathPrefix($config['autoload'], $config['target-dir']);
}

if (isset($config['autoload']['classmap'])) {


$map = array();
foreach ($config['autoload']['classmap'] as $path) {
$this->logger->debug("Scanning classmap in $path");
$map = array_merge($map, ClassMapGenerator::createMap($baseDir.DIRECTORY_SEPARATOR.$path));
}




foreach ($map as $k => $filepath) {
$map[$k] = str_replace($baseDir.DIRECTORY_SEPARATOR, '', $filepath);
}

$config['autoload']['classmap'] = $map;
}

$autoloads[$config['name'] ] = $config;
}

return $autoloads;
}





public function prependAutoloadPathPrefix(array $autoloads, $prefix)
{
$newAutoloads = array();
foreach ($autoloads as $autoloadType => &$autoloadConfig) {
$newConfig = array();
foreach ($autoloadConfig as $ns => $path) {
if (is_array($path)) {
$newConfig[ $ns ] = array_map($path, function ($p) use ($prefix) {
return $prefix.$p;
});
} else {
$newConfig[ $ns ] = $prefix.$path;
}
}
$newAutoloads[ $autoloadType ] = $newConfig;
}

return $newAutoloads;
}

public function scanComposerJsonFiles()
{

$finder = new Finder();
$finder->name('composer.json');
$finder->in($this->workingDir.DIRECTORY_SEPARATOR.$this->vendorDir);
foreach ($finder as $file) {
$config = json_decode(file_get_contents($file), true);
if (isset($config['name'])) {
$this->packages[ $config['name'] ] = $config;
}
}
}

public function generate($composerConfigFile, $pharFile = 'output.phar')
{
$pharMap = 'phar://'.$pharFile.'/';
$autoloads = $this->traceAutoloadsWithComposerJson($composerConfigFile, $this->vendorDir, true);

$psr0 = array();
$psr4 = array();
$files = array();
$map = array();

foreach ($autoloads as $packageName => $config) {
$autoload = $config['autoload'];



if (!isset($config['root'])) {
$autoload = $this->prependAutoloadPathPrefix($autoload, $pharMap.$this->vendorDir.DIRECTORY_SEPARATOR.$packageName.DIRECTORY_SEPARATOR);
} else {
$autoload = $this->prependAutoloadPathPrefix($autoload, $pharMap);
}

if (isset($autoload['psr-4'])) {
$psr4 = array_merge($psr4, $autoload['psr-4']);
}
if (isset($autoload['psr-0'])) {
$psr0 = array_merge($psr0, $autoload['psr-0']);
}
if (isset($autoload['files'])) {
$files = array_merge($files, $autoload['files']);
}
if (isset($autoload['classmap'])) {


$map = array_merge($map, $autoload['classmap']);
}
}

$this->logger->debug('Generating class loader code...');


$block = new Block();
$block[] = new UseStatement('Universal\\ClassLoader\\Psr0ClassLoader');
$block[] = new UseStatement('Universal\\ClassLoader\\Psr4ClassLoader');
$block[] = new UseStatement('Universal\\ClassLoader\\MapClassLoader');

if (!empty($files)) {
foreach ($files as $file) {
$block[] = new RequireStatement($file);
}
}

if (!empty($map)) {
$this->logger->debug('Found classmap autoload, adding MapClassLoader...');

$block[] = new AssignStatement('$map', new NewObjectExpr('MapClassLoader', array($map)));
$block[] = new MethodCallStatement('$map', 'register', array(false));
}

if (!empty($psr4)) {
$this->logger->debug('Found PSR-4 autoload, adding Psr4ClassLoader...');


$arg = array();
foreach ($psr4 as $prefix => $paths) {
$arg[] = array($prefix, $paths);
}
$block[] = new AssignStatement('$psr4', new NewObjectExpr('Psr4ClassLoader', array($arg)));
$block[] = new MethodCallStatement('$psr4', 'register', array(false));
}

if (!empty($psr0)) {
$this->logger->debug('Found PSR-0 autoload, adding Psr0ClassLoader...');

$arg = array();
foreach ($psr0 as $prefix => $paths) {
$arg[$prefix] = (array) $paths;
}
$block[] = new AssignStatement('$psr0', new NewObjectExpr('Psr0ClassLoader', array($arg)));
$block[] = new MethodCallStatement('$psr0', 'register', array(false));
}

$this->logger->debug('Rendering code using CodeGen...');

return $block->render();
}
}
<?php
namespace CLIFramework;
use CLIFramework\Formatter;







class Chooser
{

public $style;
public $formatter;

public function __construct()
{
$this->formatter = new Formatter;
}




public function setStyle($style)
{
return $this->style = $style;
}





public function choose($prompt, $choices )
{
echo $prompt . ": \n";

$choicesMap = array();


if (! isset($choices[0])) {
$i = 0;
foreach ($choices as $choice => $value) {
$i++;
$choicesMap[ $i ] = $value;
echo "\t" . ($i) . "  $choice\n";
}
} else {
foreach ($choices as $choice => $desc) {
$choicesMap[$choice] = $choice;
echo "\t$choice: $desc\n";
}
}

if ($this->style) {
echo $this->formatter->getStartMark( $this->style );
}

$completionItems = array_keys($choicesMap);
$choosePrompt = "Please Choose 1-$i > ";
while (1) {
if (extension_loaded('readline')) {
$success = readline_completion_function(function($string, $index) use ($completionItems) { 
return $completionItems;
});
$answer = readline($choosePrompt);
readline_add_history($answer);
} else {
echo $choosePrompt;
$answer = rtrim( fgets( STDIN ), "\n" );
}

$answer = (int) trim( $answer );
if (is_integer($answer)) {
if ( isset( $choicesMap[$answer] ) ) {
if( $this->style )
echo $this->formatter->getClearMark();

return $choicesMap[$answer];
} else {
continue;
}
}
break;
}
}

}
<?php

namespace CLIFramework\Command;

use CLIFramework\Command;
use CLIFramework\Autoload\ComposerAutoloadGenerator;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use FilesystemIterator;
use RuntimeException;
use Exception;
use Phar;
use CodeGen\Block;
use CodeGen\Expr\NewObjectExpr;
use CodeGen\Statement\AssignStatement;
use CodeGen\Statement\MethodCallStatement;
use CodeGen\Statement\RequireStatement;
use CLIFramework\PharKit\PharGenerator;
use CLIFramework\PharKit\PharURI;
use CLIFramework\Utils;
use ReflectionClass;
use ReflectionObject;
use SplFileInfo;










class ArchiveCommand extends Command
{
public function brief()
{
return 'Build executable phar file from composer.json';
}

public function options($opts)
{
$opts->add('d|working-dir:', 'If specified, use the given directory as working directory.')
->isa('dir')
;

$opts->add('c|composer:', 'The composer.json file. If --working-dir is ignored, dirname of the composer.json will be used.')
->isa('file')
->defaultValue('composer.json')
;

$opts->add('vendor:', 'Vendor directory name')
->defaultValue('vendor')
;


$opts->add('bootstrap?', 'bootstrap or executable php file')
->multiple()
->isa('file')
;

$opts->add('executable', 'make the phar file executable')
->isa('boolean')
->defaultValue(true)
;

$opts->add('compress?', 'compress type: gz, bz2')
->defaultValue('gz')
->validValues(array('gz', 'bz2'))
;

$opts->add('no-compress', 'do not compress phar file.');

$opts->add('add+', 'add a path respectively');

$opts->add('exclude+', 'exclude pattern');

$opts->add('no-classloader', 'do not embed a built-in classloader in the generated phar file.')
;

$opts->add('app-bootstrap', 'Include CLIFramework bootstrap script.');





}

public function arguments($args)
{
$args->add('phar-file');
}

public function aliases()
{
return array('a', 'ar');
}

public function execute($pharFile = 'output.phar')
{
if (!extension_loaded('json')) {
throw new RuntimeException('json extension is required.');
}


$composerConfigFile = $this->options->{'composer'} ?: 'composer.json';
if (!file_exists($composerConfigFile)) {
throw new Exception("composer config '$composerConfigFile' doesn't exist.");
}
$composerConfigFile = new SplFileInfo(realpath($composerConfigFile));
$this->logger->debug("Found composer config at $composerConfigFile");


$workingDir = $this->options->{'working-dir'} ?: new SplFileInfo($composerConfigFile->getPath());
if (!file_exists($workingDir)) {
throw new Exception("working directory '$workingDir' doesn't exist.");
}
$this->logger->debug('Working directory: '.$workingDir->getPathname());

$vendorDirName = $this->options->vendor ?: 'vendor';

$pharGenerator = new PharGenerator($this->logger, $this->options, $pharFile);
$phar = $pharGenerator->getPhar();
ini_set('phar.readonly', 0);
$this->logger->info("Creating phar file $pharFile...");

$phar->startBuffering();

$stubs = new Block();
if ($this->options->executable) {
$this->logger->debug('Adding shell bang...');
$stubs[] = '#!/usr/bin/env php';
}

$stubs[] = '<?php';

$this->logger->info('Setting up stub...');
$stubs[] = "Phar::mapPhar('$pharFile');";







$classPaths = array(
Utils::getClassPath('Universal\\ClassLoader\\ClassLoader'),
Utils::getClassPath('Universal\\ClassLoader\\Psr0ClassLoader'),
Utils::getClassPath('Universal\\ClassLoader\\Psr4ClassLoader'),
Utils::getClassPath('Universal\\ClassLoader\\MapClassLoader'),
);


$this->logger->debug('Adding class loader files...');
foreach ($classPaths as $classPath) {
$phar->addFile($classPath, basename($classPath));
}








foreach ($classPaths as $classPath) {
$this->logger->debug('Adding require statment for class loader: '.basename($classPath));
$stubs[] = new RequireStatement(new PharURI($pharFile, basename($classPath)));
}

if (!$this->options->{'no-classloader'}) {
$this->logger->info('Generating classLoader stubs');
$autoloadGenerator = new ComposerAutoloadGenerator($this->logger);
$autoloadGenerator->setVendorDir('vendor');
$autoloadGenerator->setWorkingDir($workingDir->getPathname());
$autoloadGenerator->scanComposerJsonFiles($workingDir.DIRECTORY_SEPARATOR.$vendorDirName);

$autoloads = $autoloadGenerator->traceAutoloadsWithComposerJson($composerConfigFile, $workingDir.DIRECTORY_SEPARATOR.$vendorDirName, true);
foreach ($autoloads as $packageName => $config) {
if (!isset($config['autoload'])) {
continue;
}

$autoload = $config['autoload'];

if (!isset($config['root'])) {
$autoload = $autoloadGenerator->prependAutoloadPathPrefix($autoload, $vendorDirName.DIRECTORY_SEPARATOR.$packageName.DIRECTORY_SEPARATOR);
}

foreach ($autoload as $type => $map) {
foreach ($map as $mapPaths) {
$paths = (array) $mapPaths;
foreach ($paths as $path) {
$absolutePath = $workingDir.DIRECTORY_SEPARATOR.$path;

if (is_dir($absolutePath)) {
$this->logger->debug("Add files from directory $absolutePath under $workingDir");

$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($absolutePath, FilesystemIterator::SKIP_DOTS)
);

foreach ($it as $fileinfo) {
$pathName = $fileinfo->getPathname();
if (preg_match('/(\.(?:git|svn|hg)|Tests|Test\.php)/', $pathName)) {
continue;
}
$localPath = str_replace($workingDir.DIRECTORY_SEPARATOR, '', $pathName);
$this->logger->debug("Adding $localPath");
$phar->addFile($pathName, $localPath);
}









} elseif (is_file($absolutePath)) {
$this->logger->debug("Add file $absolutePath under $path");
$phar->addFile($absolutePath, $path);
} else {
$this->logger->error("File '$absolutePath' is not found.");
}
}
}
}
}
$classloaderStub = $autoloadGenerator->generate($composerConfigFile, $pharFile);
$this->logger->debug('ClassLoader stub:');
$this->logger->debug($classloaderStub);
$stubs[] = $autoloadGenerator->generate($composerConfigFile, $pharFile);
}

if ($bootstraps = $this->options->bootstrap) {
foreach ($bootstraps as $bootstrap) {
$this->logger->info("Adding bootstrap: $bootstrap");
$content = php_strip_whitespace($bootstrap);
$content = preg_replace('{^#!/usr/bin/env\s+php\s*}', '', $content);

$localPath = str_replace($workingDir->getPathname(), '', $bootstrap->getRealPath());

$phar->addFromString($localPath, $content);

$stubs[] = new RequireStatement(new PharURI($pharFile, $localPath));
}
}

if ($this->options->{'app-bootstrap'}) {
$app = $this->getApplication();
$refObject = new ReflectionObject($app);
$appClassName = $refObject->getName();

$block = new Block();
$block[] = new AssignStatement('$app', new NewObjectExpr($appClassName));
$block[] = new MethodCallStatement('$app', 'run', array('$argv'));
$stubs[] = $block;
}

$stubs[] = '__HALT_COMPILER();';

$stubstr = $stubs->render();
$this->logger->debug($stubstr);
$phar->setStub($stubstr);


if ($adds = $this->options->add) {
foreach ($adds as $add) {
$phar->buildFromIterator(
new RecursiveIteratorIterator(new RecursiveDirectoryIterator($add)),
$workingDir
);
}
}

$pharGenerator->generate();

$this->logger->info('Done');
}
}
<?php











namespace CLIFramework\Command;

use CLIFramework\Command;
use CLIFramework\CommandInterface;
use CLIFramework\Completion\ZshGenerator;

class ZshCompletionCommand extends Command implements CommandInterface
{
public function brief()
{
return 'This function generate a zsh-completion script automatically';
}

public function options($opts)
{
$opts->add('bind:', 'bind complete to command');
$opts->add('program:', 'programe name');
}

public function execute()
{
$programName = $this->options->program ?: $this->getApplication()->getProgramName();
$bind = $this->options->bind ?: $programName;
$compName = '_'.preg_replace('#\W+#', '_', $programName);
$generator = new ZshGenerator($this->getApplication(), $programName, $bind, $compName);
echo $generator->output();
}
}
<?php











namespace CLIFramework\Command;

use CLIFramework\Command;
use CLIFramework\CommandInterface;
use CLIFramework\OptionPrinter;
use CLIFramework\Corrector;

class HelpCommand extends Command implements CommandInterface
{



public function brief()
{
return 'Show help message of a command';
}

public function options($opts)
{
$opts->add('dev', 'Show development commands');
}

public function displayTopic($topic)
{
$this->logger->write($this->formatter->format('TOPIC', 'strong_white')."\n");
$this->logger->write("\t".$topic->getTitle()."\n\n");
$this->logger->write($this->formatter->format('DESCRIPTION', 'strong_white')."\n");
$this->logger->write($topic->getContent()."\n\n");

if ($footer = $topic->getFooter()) {
$this->logger->write($this->formatter->format('MORE', 'strong_white')."\n");
$this->logger->write($footer."\n");
}
}

public function calculateColumnWidth($words, $min = 0)
{
$maxWidth = $min;
foreach ($words as $word) {
if (strlen($word) > $maxWidth) {
$maxWidth = strlen($word);
}
}

return $maxWidth;
}

public function layoutCommands($commands, $indent = 4)
{
$cmdNames = array_filter(array_keys($commands), function ($n) {
return !preg_match('#^_#', $n);
});
$maxWidth = $this->calculateColumnWidth($cmdNames, 12);
foreach ($commands as $name => $class) {
$cmd = new $class();
$brief = $cmd->brief();
$this->logger->writeln(str_repeat(' ', $indent)
.sprintf('%'.($maxWidth + $indent).'s    %s',
$name,
$brief
));
}
$this->logger->newline();
}






public function execute()
{
$logger = $this->logger;
$app = $this->getApplication();
$progname = basename($app->getProgramName());

$printer = new OptionPrinter();
$formatter = $this->getFormatter();


$commandNames = func_get_args();

if (count($commandNames) == 1) {

if ($topic = $app->getTopic($commandNames[0])) {
return $this->displayTopic($topic);
} elseif (!$app->hasCommand($commandNames[0])) {
$corrector = new Corrector(array_keys($app->topics));
if ($match = $corrector->correct($commandNames[0])) {
return $this->displayTopic($app->topics[$match]);
}

return;
}
}

if (count($commandNames)) {
$subcommand = $commandNames[0];
$cmd = $app;
for ($i = 0; $cmd && $i < count($commandNames); ++$i) {
$cmd = $cmd->getCommand($commandNames[$i]);
}
if (!$cmd) {
throw new Exception('Command entry '.implode(' ', $commandNames).' not found');
}

$usage = $cmd->usage();

if ($brief = $cmd->brief()) {
$logger->write($formatter->format('NAME', 'strong_white')."\n");
$logger->write("\t".$formatter->format($cmd->getName(), 'strong_white').' - '.$brief."\n\n");
}

if ($aliases = $cmd->aliases()) {
$logger->write($formatter->format('ALIASES', 'strong_white')."\n");
$logger->write("\t".$formatter->format(implode(', ', $aliases), 'strong_white')."\n\n");
}

if ($usage = trim($cmd->usage())) {
$logger->write($formatter->format('USAGE', 'strong_white')."\n");
$logger->write("\t".$usage);
$logger->write("\n\n");
}

$logger->write($formatter->format('SYNOPSIS', 'strong_white')."\n");
$prototypes = $cmd->getAllCommandPrototype();
foreach ($prototypes as $prototype) {
$logger->writeln("\t".' '.$prototype);
}
$logger->write("\n");

if ($optionLines = $printer->render($cmd->optionSpecs)) {
$logger->write($formatter->format('OPTIONS', 'strong_white')."\n");
$logger->write($optionLines);
$logger->write("\n");
}

$logger->write($cmd->getFormattedHelpText());
} else {
$cmd = $this->parent;
$logger->write($formatter->format(ucfirst($cmd->brief()), 'strong_white')."\n\n");

if ($usage = trim($cmd->usage())) {
$logger->write($formatter->format('USAGE', 'strong_white')."\n");
$logger->write($usage);
$logger->write("\n\n");
}

$logger->write($formatter->format('SYNOPSIS', 'strong_white')."\n");
$logger->write("\t".$progname);
if (!empty($cmd->getOptionCollection()->options)) {
$logger->write(' [options]');
}

if ($cmd->hasCommands()) {
$logger->write(' <command>');
} else {
$argInfos = $cmd->getArgInfoList();
foreach ($argInfos as $argInfo) {
$logger->write(' <'.$argInfo->name.'>');
}
}

$logger->write("\n\n");


$logger->write($formatter->format('OPTIONS', 'strong_white')."\n");
$logger->write($printer->render($cmd->optionSpecs));
$logger->write("\n\n");


$classes = get_declared_classes();
$command_classes = array();
foreach ($classes as $class) {
if (version_compare(phpversion(), '5.3.9') >= 0) {
if (is_subclass_of($class, 'CLIFramework\\Command', true)) {
$command_classes[] = $class;
}
} else {
if (is_subclass_of($class, 'CLIFramework\\Command')) {
$command_classes[] = $class;
}
}
}

$logger->write($formatter->format("COMMANDS\n", 'strong_white'));
$ret = $app->aggregate();


if (count($ret['groups']) > 1 || $this->options->dev) {
$this->logger->writeln('  '.$formatter->format('General Commands', 'strong_white'));
}
$this->layoutCommands($ret['commands']);

foreach ($ret['groups'] as $group) {
if (!$this->options->dev && $group->getId() == 'dev') {
continue;
}
$this->logger->writeln('  '.$formatter->format($group->getName(), 'strong_white'));
$this->layoutCommands($group->getCommands());
}

$this->logger->write($this->getFormattedHelpText());

if ($app->topics) {
$logger->write($formatter->format("TOPICS\n", 'strong_white'));
$maxWidth = $this->calculateColumnWidth(array_keys($app->topics), 8);
foreach ($app->topics as $topicId => $topic) {
printf('%'.($maxWidth + 8)."s    %s\n", $topicId, $topic->getTitle());
}
$logger->newline();
}

$logger->write($formatter->format("HELP\n", 'strong_white'));
$this->logger->writeln(wordwrap(
"\t'$progname help' lists available subcommands and some".
" topics. See '$progname help <command>' or '$progname help <topic>'".
" to read about a specific subcommand or $progname.", 70, "\n\t"));
}

if ($app->showAppSignature) {
$logger->newline();
$logger->write($formatter->format("{$app->getName()} {$app->getVersion()}", 'gray'));
$logger->writeln($formatter->format("\t\tpowered by https://github.com/c9s/CLIFramework", 'gray'));
}

return true;
}
}
<?php

namespace CLIFramework\Command;

use CLIFramework\Command;
use CodeGen\Block;
use ClassTemplate\TemplateClassFile;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Exception;

class BuildGitHubWikiTopicsCommand extends Command
{
public function brief()
{
return 'Build topic classes from the wiki of a GitHub Project.';
}

public function options($opts)
{
$opts->add('ns:', 'Class namespace');
$opts->add('dir:', 'Output directory')
;
$opts->add('update', 'Update wiki repository');
}

public function arguments($args)
{
$args->add('user')->desc('GitHub Account');
$args->add('repo')->desc('GitHub Repository');
}

public function execute($user, $repo)
{
$ns = '';
if ($appNs = $this->options->ns) {
$ns = rtrim(str_replace(':', '\\', $appNs), '\\').'\\';
} elseif ($appNs = $this->getApplication()->getCurrentAppNamespace()) {
$ns = $appNs.'\\Topic\\';
} else {
$this->logger->notice('Namespace is defined.');
}


$wikiGitURI = "https://github.com/$user/$repo.wiki.git";
$wikiBaseUrl = "https://github.com/$user/$repo/wiki";
$localRepoPath = "tmp/$repo.wiki";

$currentDir = getcwd();

if (is_dir($localRepoPath)) {
if ($this->options->update) {
$this->logger->info("Fetching $wikiGitURI...");
system("git -C $localRepoPath pull origin", $retval);
if ($retval != 0) {
return $this->logger->error("Can't clone wiki repository");
}
}
} else {
$dirname = dirname($localRepoPath);
if (!file_exists($dirname)) {
mkdir($dirname, 0755, true);
}

$this->logger->info("Cloning $wikiGitURI...");
system("git clone $wikiGitURI $localRepoPath", $retval);
if ($retval != 0) {
return $this->logger->error("Can't clone wiki repository");
}
}


$this->logger->info('Building topic classes from GitHub pages...');

$outputDir = $this->options->dir ?: '.';

$directory = new RecursiveDirectoryIterator($localRepoPath);
$iterator = new RecursiveIteratorIterator($directory);

$topics = array();
foreach ($iterator as $file) {
if (preg_match('/\.git/', $file->getPathName())) {
continue;
}
if (preg_match('/\.md$/', $file->getPathName())) {
$topicRemoteUrl = $wikiBaseUrl.'/'.$file->getFileName();






$entryName = preg_replace('/.md$/', '', $file->getFileName());
$entryNameNonEnChars = trim(preg_replace('/[^a-zA-Z0-9-\s]/', '', $entryName));
$topicClassName = implode('', array_map('ucfirst', explode('-', str_replace(' ', '', $entryNameNonEnChars)))).'Topic';
$topicId = strtolower(preg_replace('/\s+/', '-', $entryNameNonEnChars));
$topicTitle = preg_replace('/-/', ' ', $entryName);
$topicFullClassName = $ns.$topicClassName;

$topics[ $topicId ] = $topicFullClassName;

$classFile = $outputDir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $topicFullClassName).'.php';

$cTemplate = new TemplateClassFile($topicFullClassName, array(
'template' => 'Class.php.twig',
));

$cTemplate->addProperty('id', $topicId);
$cTemplate->addProperty('url', $topicRemoteUrl);
$cTemplate->addProperty('title', $topicTitle);

$cTemplate->extendClass('\\CLIFramework\\Topic\\GitHubTopic');

$cTemplate->addMethod('public', 'getRemoteUrl', array(), 'return $this->remoteUrl;');
$cTemplate->addMethod('public', 'getId', array(), 'return $this->id;');

$content = file_get_contents($file);
$cTemplate->addMethod('public', 'getContent', array(), 'return '.var_export($content, true).';', array(), false);

$classDir = dirname($classFile);
if (!file_exists($classDir)) {
mkdir($classDir, 0755, true);
}
$this->logger->info("Creating $classFile");
if (false === file_put_contents($classFile, $cTemplate->render())) {
throw new Exception("Can't write file $classFile.");
}
}
}

$this->logger->info(wordwrap("You may now copy the below content to the 'init' method in your application class:"));

$this->logger->writeln('-------');
$block = new Block();
$block->appendLine('$this->topics('.var_export($topics, true).');');
$this->logger->write($block->render());
$this->logger->writeln('-------');

chdir($currentDir);
$this->logger->info('Done');
}
}
<?php











namespace CLIFramework\Command;

use CLIFramework\Command;
use CLIFramework\CommandInterface;
use CLIFramework\Completion\BashGenerator;

class BashCompletionCommand extends Command implements CommandInterface
{
public function brief()
{
return 'This command generate a bash completion script automatically';
}

public function options($opts)
{
$opts->add('bind:', 'bind complete to command');
$opts->add('program:', 'programe name');
}

public function execute()
{
$programName = $this->options->program ?: $this->getApplication()->getProgramName();
$bind = $this->options->bind ?: $programName;
$compName = '_'.preg_replace('#\W+#', '_', $programName);
$generator = new BashGenerator($this->getApplication(), $programName, $bind, $compName);
echo $generator->output();
}
}
<?php

namespace CLIFramework\Command;

use CLIFramework\Command;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use Phar;












class CompileCommand extends Command
{
public function options($opts)
{

$opts->add('classloader?', 'embed classloader source file');


$opts->add('bootstrap?', 'bootstrap or executable source file');

$opts->add('executable', 'is a executable script ?');

$opts->add('lib+', 'library path');

$opts->add('include+', 'include path');

$opts->add('exclude+', 'exclude pattern');

$opts->add('output:', 'output');

$opts->add('c|compress?', 'phar file compress type: gz, bz2');

$opts->add('no-compress', 'do not compress phar file.');
}

public function brief()
{
return 'compile current source into Phar format library file.';
}

public function execute()
{
ini_set('phar.readonly', 0);

$options = $this->options;
$logger = $this->logger;

$bootstrap = null;
$lib_dirs = array('src'); 
$output = 'output.phar';
$classloader = null;

if ($options->bootstrap) {
$bootstrap = $options->bootstrap;
}

if ($options->lib) {
$lib_dirs = $options->lib;
}

if ($options->output) {
$output = $options->output;
}

$logger->info('Compiling Phar...');

$pharFile = $output;
$src_dirs = $lib_dirs;

$logger->debug2("Creating phar file $pharFile...");

$phar = new Phar($pharFile, 0, $pharFile);
$phar->setSignatureAlgorithm(Phar::SHA1);
$phar->startBuffering();

$excludePatterns = $this->options->exclude ? $options->exclude : null;
if ($this->options->include) {
foreach ($options->include as $include) {
$phar->buildFromIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($include)),
getcwd()
);
}
}


foreach ($lib_dirs as $src_dir) {
if (!file_exists($src_dir)) {
die("$src_dir does not exist.");
}

$src_dir = realpath($src_dir);
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($src_dir),
RecursiveIteratorIterator::CHILD_FIRST);


foreach ($iterator as $path) {
if ($path->isFile()) {
$rel_path = substr($path->getPathname(), strlen($src_dir) + 1);

if ($excludePatterns) {
$exclude = false;
foreach ($excludePatterns as $pattern) {
if (preg_match('#'.$pattern.'#', $rel_path)) {
$exclude = true;
break;
}
}
if ($exclude) {
$logger->debug2('exclude '.$rel_path);
continue;
}
}


if (preg_match('/\.php$/', $path->getFilename())) {
$content = php_strip_whitespace($path->getRealPath());

$logger->debug2('add '.$rel_path);
$phar->addFromString($rel_path, $content);
} else {
$logger->debug2('add '.$rel_path);
$phar->addFile($path->getPathname(), $rel_path);
}
}
}
}


if ($bootstrap) {
$logger->info2("Compile $bootstrap");
$content = php_strip_whitespace($bootstrap);
$content = preg_replace('{^#!/usr/bin/env\s+php\s*}', '', $content);
$phar->addFromString($bootstrap, $content);
}

$stub = '';
if ($options->executable) {
$logger->debug2('Adding shell bang...');
$stub .= "#!/usr/bin/env php\n";
}

$logger->info2('Setting up stub...');
$stub .= <<<"EOT"
<?php
Phar::mapPhar('$pharFile');
EOT;


if ($options->has('classloader')) {
$logger->info2('Adding classloader...');

if (is_string($options->classloader) && file_exists($options->classloader)) {
$classloader_file = $options->classloader;
$content = php_strip_whitespace($classloader_file);
$phar->addFromString($classloader_file, $content);
$stub .= <<<"EOT"
require 'phar://$pharFile/$classloader_file';
EOT;
} else {
$classloader_interface = 'Universal/ClassLoader/ClassLoader.php';
$classloader_file = 'Universal/ClassLoader/SplClassLoader.php';
$stub .= <<<"EOT"
require 'phar://$pharFile/$classloader_interface';
require 'phar://$pharFile/$classloader_file';
\$classLoader = new \\Universal\\ClassLoader\\SplClassLoader;
\$classLoader->addFallback( 'phar://$pharFile' );
\$classLoader->register(true);
EOT;
}
}

if ($bootstrap) {
$logger->info2('Adding bootstrap script...');
$stub .= <<<"EOT"
require 'phar://$pharFile/$bootstrap';
EOT;
}

$stub .= <<<"EOT"
__HALT_COMPILER();
EOT;

$phar->setStub($stub);
$phar->stopBuffering();

$compress_type = Phar::GZ;
if ($options->{'no-compress'}) {
$compress_type = null;
} elseif ($options->compress) {
switch ($v = $options->compress) {
case 'gz':
$compress_type = Phar::GZ;
break;
case 'bz2':
$compress_type = Phar::BZ2;
break;
default:
throw new Exception("Compress type: $v is not supported, valids are gz, bz2");
break;
}
}

if ($compress_type) {
$logger->info('Compressing phar ...');
$phar->compressFiles($compress_type);
}

$logger->info('Done');
}
}
<?php

namespace CLIFramework\Command;

use CLIFramework\Command;
use CLIFramework\Zsh;
use CLIFramework\ValueCollection;
use CLIFramework\Buffer;
use CLIFramework\CommandBase;
use GetOptionKit\OptionCollection;
use GetOptionKit\OptionResult;
use Exception;
use InvalidArgumentException;

class UnsupportedShellException extends Exception
{
}

class UndefinedArgumentException extends Exception
{
}

class UndefinedOptionException extends Exception
{
public $options;
public $command;

public function __construct($message, CommandBase $command, OptionCollection $options)
{
$this->command = $command;
$this->options = $options;
parent::__construct($message);
}
}

function output($str, OptionResult $opts = null)
{
echo $str;
}

function array_escape_space(array $array)
{
return array_map(function ($c) {
return addcslashes($c, ' ');
}, $array);
}

function is_indexed_array(array $array)
{
$keys = array_keys($array);
$numericKey = true;
foreach ($keys as $key) {
if (!is_numeric($key)) {
$numericKey = false;
}
}

return $numericKey;
}

function is_assoc_array(array $array)
{
if (empty($array)) {
return false;
}
$keys = array_keys($array);
$numericKey = true;
foreach ($keys as $key) {
if (!is_numeric($key)) {
$numericKey = false;
}
}

return !$numericKey;
}

function as_shell_string($str)
{
return '"'.addcslashes($str, '"').'"';
}




function encode_array_as_shell_string($array)
{
if (is_assoc_array($array)) {
$output = array();
foreach ($array as $key => $val) {
$output[] = $key.':'.addcslashes($val, ': ');
}

return '"'.addcslashes(implode(' ', $output), '"').'"';
} else {
$output = array();
foreach ($array as $val) {
$output[] = addcslashes($val, ': ');
}

return '"'.addcslashes(implode(' ', $output), '"').'"';
}
}

class MetaCommand extends Command
{
public function brief()
{
return 'Return the meta data of a commands.';
}

public function options($opts)
{
$opts->add('flat', 'flat list format. work for both zsh and bash.');
$opts->add('zsh', 'output for zsh');
$opts->add('bash', 'output for bash');
$opts->add('json', 'output in JSON format (un-implemented)');
}








public function execute($commandlist, $type, $arg = null, $attr = null)
{
$commandNames = explode('.', $commandlist);

$app = $this->getApplication();

$cmd = $app;

if ($commandNames[0] === 'app') {
array_shift($commandNames);
}

$this->logger->debug('Finding command '.get_class($cmd));

while (!empty($commandNames) && $cmd->hasCommands()) {
$commandName = array_shift($commandNames);
$this->logger->debug('Finding command '.$commandName);
$cmd = $cmd->getCommand($commandName);
$this->logger->debug('Found command class '.get_class($cmd));
}


if (in_array($type, array('arg', 'opt')) && $arg === null || $attr === null) {
throw new InvalidArgumentException("'arg' or 'opt' require the attribute type.");
}

try {
if (!$cmd) {
throw new Exception('Can not find command.');
}

switch ($type) {
case 'arg':
$idx = intval($arg);
$arginfos = $cmd->getArgInfoList();

if (!isset($arginfos[ $idx ])) {
throw new UndefinedArgumentException("Undefined argument at $idx");
}

$argInfo = $arginfos[$idx];

switch ($attr) {
case 'suggestions':
if ($values = $argInfo->getSuggestions()) {
return $this->outputValues($values, $this->options);
}
break;

case 'valid-values':
if ($values = $argInfo->getValidValues()) {
return $this->outputValues($values, $this->options);
}
break;
}
break;
case 'opts':
$options = $cmd->getOptionCollection();
$values = array();
foreach ($options as $opt) {
if ($opt->short) {
$values[] = '-'.$opt->short;
} elseif ($opt->long) {
$values[] = '--'.$opt->long;
}
}
echo implode(' ', $values) , "\n";

return;
break;
case 'opt':
$options = $cmd->getOptionCollection();
$option = $options->find($arg);
if (!$option) {
throw new UndefinedOptionException("Option '$arg' not found", $cmd, $options);
}
switch ($attr) {
case 'isa':
return output($option->isa);
break;
case 'valid-values':
if ($values = $option->getValidValues()) {
return $this->outputValues($values, $this->options);
}
break;
case 'suggestions':
if ($values = $option->getSuggestions()) {
return $this->outputValues($values, $this->options);
}
break;
}
break;
default:
throw new Exception("Invalid type '$type', valid types are 'arg', 'opt', 'opts'");
break;
}
} catch (UnsupportedShellException $e) {
fwrite(STDERR, $e->getMessage()."\n");
fwrite(STDERR, "Supported shells: zsh, bash\n");
} catch (UndefinedOptionException $e) {
fwrite(STDERR, $e->command->getSignature()."\n");
fwrite(STDERR, $e->getMessage()."\n");
fwrite(STDERR, "Valid options:\n");
foreach ($e->options as $opt) {
if ($opt->short && $opt->long) {
fwrite(STDERR, ' '.$opt->short.'|'.$opt->long);
} elseif ($opt->short) {
fwrite(STDERR, ' '.$opt->short);
} elseif ($opt->long) {
fwrite(STDERR, ' '.$opt->long);
}
fwrite(STDERR, "\n");
}
}
}

public function outputValues($values, OptionResult $opts)
{

if (is_array($values) && empty($values)) {
return;
}


if ($values instanceof ValueCollection) {


if ($opts->flat) {
$buf = new Buffer();
$buf->appendLine('#flat');
foreach ($values as $groupId => $groupValues) {
foreach ($groupValues as $val) {
$buf->appendLine($val);
}
}
$this->logger->write($buf);
} elseif ($opts->zsh || $opts->bash) {
$buf = new Buffer();
$buf->appendLine('#groups');
$buf->appendLine('declare -A groups');
$buf->appendLine('declare -A labels');


foreach ($values as $groupId => $groupValues) {
$buf->appendLine("groups[$groupId]=".encode_array_as_shell_string($groupValues));
}
foreach ($values->getGroupLabels() as $groupId => $label) {
$buf->appendLine("labels[$groupId]=".as_shell_string($label));
}
$this->logger->write($buf);
} elseif ($opts->json) {
$this->logger->write($values->toJson());
} else {
throw new UnsupportedShellException();
}

return;
}


if (is_array($values) && is_indexed_array($values) && is_array(end($values))) {
$this->logger->writeln('#descriptions');
if ($opts->zsh) {

foreach ($values as $value) {
list($key, $val) = $value;
$this->logger->writeln("$key:".addcslashes($val, ':'));
}
} else {
foreach ($values as $value) {
$this->logger->writeln($value[0]);
}
}
} elseif (is_array($values) && is_indexed_array($values)) { 
$this->logger->writeln('#values');
$this->logger->writeln(implode("\n", $values));
} else { 
$this->logger->writeln('#descriptions');
if ($opts->zsh) {
foreach ($values as $key => $desc) {
$this->logger->writeln("$key:".addcslashes($desc, ':'));
}
} else {
foreach ($values as $key => $desc) {
$this->logger->writeln($key);
}
}
}
}
}
<?php
namespace CLIFramework\Debug;

class LineIndicator
{
protected $contextLines = 4;

protected $indicatedLineFormat = "> % 4d| %s";

protected $contextLineFormat = "  % 4d| %s";

public function __construct()
{

}






public function indicateFile($file, $line)
{
$lines = file($file);
$fromIndex = max($line - 1 - $this->contextLines, 0);
$toIndex = min($line - 1 + $this->contextLines, count($lines));

if ($fromIndex === $toIndex) {
$indexRange = [ $fromIndex ];
} else {
$indexRange = range($fromIndex, $toIndex);
}

$output = [];
$output[] = "$file @ line " . join(',', (array) $line);
$output[] = str_repeat('=', strlen($output[0]) );
foreach($indexRange as $index) {
if ((is_integer($line) && $index + 1 == $line) || (is_array($line) && in_array($index + 1, $line) ) ) {
$output[] = sprintf($this->indicatedLineFormat, $index + 1, rtrim($lines[$index]));
} else {
$output[] = sprintf($this->contextLineFormat, $index + 1, rtrim($lines[$index]));
}
}
return join(PHP_EOL, $output) . PHP_EOL;
}
}





<?php
namespace CLIFramework\Debug;
use CLIFramework\Component\Table\Table;
use CLIFramework\Component\Table\TableStyle;
use CLIFramework\Component\Table\CompactTableStyle;
use CLIFramework\Component\Table\MarkdownTableStyle;
use CLIFramework\Component\Table\CellAttribute;
use CLIFramework\Component\Table\NumberFormatCell;
use CLIFramework\Component\Table\CurrencyCellAttribute;
use CLIFramework\Component\Table\SpellOutNumberFormatCell;
use CLIFramework\Component\Table\RowSeparator;
use LazyRecord\BaseCollection;
use Exception;

class ConsoleDebug
{
static public function dumpException(Exception $e)
{
$indicator = new LineIndicator;
$output = [];
$output[] = '[' . get_class($e) . '] was thrown with "' . $e->getMessage() . '".';
$output[] = $indicator->indicateFile($e->getFile(), $e->getLine());

$output[] = "Exception Stack Trace";
$output[] = "=====================";
$output[] = "";
$output[] = $e->getTraceAsString();
return join(PHP_EOL, $output);
}





static public function dumpCollection(BaseCollection $collection, array $options = array())
{
return self::dumpRows($collection->toArray(), $options);
}


static public function dumpRows(array $array, array $options = array())
{
$table = new Table;

$keys = null;
if (isset($options['keys'])) {
$keys = $options['keys'];
} else if (isset($array[0])) {
$keys = array_keys($array[0]);
}

if ($keys) {
$table->setHeaders($keys);
}

if (empty($array)) {
return '0 rows.' . PHP_EOL;
}

foreach ($array as $item) {
$values = [];
foreach ($keys as $key) {
$values[] = $item[$key];
}
$table->addRow($values);
}
return $table->render() . PHP_EOL
. count($array) . ' rows.' . PHP_EOL;
}
}



<?php
namespace CLIFramework\ConsoleInfo;

class EnvConsoleInfo implements ConsoleInfoInterface
{
public function getColumns() 
{
return intval(getenv('COLUMNS'));
}

public function getRows() 
{
return intval(getenv('LINES'));
}

static public function hasSupport()
{
return getenv('COLUMNS') && getenv('LINES');
}
}



<?php
namespace CLIFramework\ConsoleInfo;
use CLIFramework\ConsoleInfo\EnvConsoleInfo;
use CLIFramework\ConsoleInfo\TputConsoleInfo;

class ConsoleInfoFactory
{

static public function create()
{
if (EnvConsoleInfo::hasSupport()) {
return new EnvConsoleInfo;
} else if (TputConsoleInfo::hasSupport()) {
return new TputConsoleInfo;
}
}


}



<?php
namespace CLIFramework\ConsoleInfo;

interface ConsoleInfoInterface
{
public function getColumns();
public function getRows();
static public function hasSupport();
}


<?php
namespace CLIFramework\ConsoleInfo;

class TputConsoleInfo implements ConsoleInfoInterface
{
public function getColumns() 
{
return intval(exec('tput cols'));
}

public function getRows() 
{
return intval(exec('tput lines'));
}

static public function hasSupport()
{
$paths = explode(':',getenv('PATH'));
foreach($paths as $path) {
$bin = $path . DIRECTORY_SEPARATOR . 'tput';
if (file_exists($bin) && is_executable($bin)) {
return true;
}
}
return false;
}

}



<?php
namespace CLIFramework;
use Exception;

class CommandException extends Exception { }
<?php
namespace CLIFramework;



class Buffer {
public $content = '';

public $indent = 0;

protected $indentCache = '';

public $indentChar = '  ';

public $format;

const FORMAT_UNIX = 0;
const FORMAT_DOS = 1;

public $newline = "\n";

public function __construct($content = '') {
$this->content = $content;
$this->format = self::FORMAT_UNIX;
}

public function indent() {
$this->indent++;
$this->_updateIndentCache();
}






public function setIndent($indent) {
$this->indent = $indent;
$this->_updateIndentCache();
}






public function getIndent() {
return $this->indent;
}

public function setIndentChar($char) {
$this->indentChar = $char;
}

public function getIndentChar() {
return $this->indentChar;
}

public function unindent() {
if ($this->indent > 0) {
$this->indent--;
$this->_updateIndentCache();
}
}

public function _updateIndentCache() {
$this->indentCache = str_repeat($this->indentChar, $this->indent);
}

public function makeIndent($level) {
return str_repeat($this->indentChar, $level);
}




public function append($text)
{
$this->content .= $text;
}








public function appendLine($line, $indent = 0) {
$this->content .= ($indent ? $this->makeIndent($indent) : $this->indentCache) . $line . $this->newline;
}








public function appendLines($lines, $indent = 0) {
foreach($lines as $line) {
$this->appendLine($line, $indent);
}
}







public function appendEscape($line, $charlist) {
$this->content .= addcslashes($line, $charlist);
}






public function appendEscapeSlash($line) {
$this->content .= addslashes($line);
}






public function appendQuoteString($str) {
$this->content .= '"' . addcslashes($str , '"') . '"';
}







public function appendSingleQuoteString($str) {
$this->content .= "'" . addslashes($str) . "'";
}





public function newLine() {
$this->content .= $this->newline;
}







public function setFormat($format) {
$this->format = $format;
if ($this->format == self::FORMAT_UNIX) {
$this->newline = "\n";
} elseif ($this->format == self::FORMAT_DOS) {
$this->newline = "\r\n";
}
}








public function appendBlock($block, $indent = 0) {
$lines = explode("\n", $block);
foreach($lines as $line) {
$this->appendLine($line, $indent);
}
}








public function appendBuffer(Buffer $buf, $indent = 0) {
if ( $indent ) {
$this->setIndent($indent);
$lines = $buf->lines();
foreach( $lines as $line ) {
$this->appendLine($line);
}
} else {
$this->content .= $buf->__toString();
}
}







public function lines() {
return $this->explode($this->newline, $this->content);
}




public function __toString() {
return $this->content;
}
}

<?php
namespace CLIFramework;







class CommandAutoloader
{

private $parent;







public function __construct(CommandBase $parent)
{
$this->parent = $parent;
}








public function autoload($path = null)
{
if (is_null($path))
$path = $this->getCurrentCommandDirectory();
$commands = $this->scanCommandsInPath($path);
$this->addCommandsForParent($commands);
}

private function getCurrentCommandDirectory()
{
$reflector = new \ReflectionClass(get_class($this->parent));
$classDir = dirname($reflector->getFileName());







$commandDirectoryBase= $this->parent->isApplication()
? 'Command'
: $reflector->getShortName();
return $classDir . DIRECTORY_SEPARATOR . $commandDirectoryBase;
}

private function scanCommandsInPath($path)
{
if (!is_dir($path))
return array();
$files = scandir($path);
return $this->translateFileNamesToCommands($files);
}

private function translateFileNamesToCommands(array $fileNames)
{
$commands = array_map(
array($this, 'translateFileNameToCommand'),
$fileNames
);
return array_filter(
$commands,
function ($command) { return $command !== false; }
);
}

private function translateFileNameToCommand($fileName)
{
$extensions = explode(',', spl_autoload_extensions());
$isCommandClassFile = ($fileName[0] !== '.'
and preg_match('/(^.*Command)(\..*)$/', $fileName, $matches) === 1
and in_array($matches[2], $extensions));
return $isCommandClassFile
? $this->parent->getLoader()->inverseTranslate($matches[1])
: false;
}

private function addCommandsForParent($commands)
{
foreach ($commands as $command)
$this->parent->addCommand($command);
}
}
<?php
namespace CLIFramework\Topic;

class GitHubTopic extends BaseTopic
{
}



<?php
namespace CLIFramework\Topic;

abstract class BaseTopic
{

public $title = 'Untitled Topic';

public $url;

public $id;

public function getUrl() { return $this->url; }
public function getId() { return $this->id; }

public function getTitle() { return $this->title; }
public function getContent() { return ''; }
public function getFooter() { 
if ($url = $this->getUrl() ) {
return "\tYou may view this topic at " . $url . "\n";
}
return '';
}
}



<?php
namespace CLIFramework\Testing;

class Parser
{
public static function getArguments($command)
{
$command = self::normalizeCommand($command);
$result = array();
$i = 0;
$next = strpos($command, " ");
while ($next)
{
if ($command[$i] == "\"")
{
$i = $i + 1;
$next = strpos($command, "\"", $i);
}

$result[] = substr($command, $i, $next - $i);
$i = $next + 1;
$next = strpos($command, " ", $i);
}

$result[] = substr($command, $i, strlen($command) - $i);
return $result;
}

public static function normalizeCommand($command)
{
$command = preg_replace('/\s+/', ' ', $command);
return preg_replace('/"\s+/', '"', $command);
}
}
?>
<?php
namespace CLIFramework\Testing;

use PHPUnit\Framework\TestCase;

class ConsoleTestCase extends TestCase
{
protected function runScript($path, $input, $callback)
{
$descriptors = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$pipes = array();
$process = proc_open("php $path", $descriptors, $pipes, null, $_ENV);

$this->assertTrue(is_resource($process));

fwrite($pipes[0], $input);
fflush($pipes[0]);
$content = trim(stream_get_contents($pipes[1]));
@fclose($pipes[0]);
@fclose($pipes[1]);
@fclose($pipes[2]);
@proc_close($process);
$callback($content);
}
}
<?php
namespace CLIFramework\Testing;
use PHPUnit\Framework\TestCase;

abstract class CommandTestCase extends TestCase
{
public $app;

public $outputBufferingActive = false;

abstract public function setupApplication();

public function getApplication()
{
return $this->app;
}

protected function setUp(): void
{
if ($this->outputBufferingActive) {
ob_start();
}
$this->app = $this->setupApplication();
}

protected function tearDown(): void
{
$this->app = NULL;
if ($this->outputBufferingActive) {
ob_end_clean();
}
}

public function runCommand($args) {
if (is_string($args)) {
$args = Parser::getArguments($args);
}
return $this->app->run($args);
}
}
<?php
namespace CLIFramework;








class Corrector
{
protected $possibleTokens = array();






public function __construct(array $possibleTokens = array())
{
$this->possibleTokens = $possibleTokens;
}







public function correct($input) {
$guess = $this->match($input);
if ($guess === $input)
return $guess;
else
return $this->askForGuess($guess) ? $guess : $input;
}







public function match($input)
{
if (empty($this->possibleTokens))
return $input;

$bestSimilarity = -1;
$bestGuess = $input;
foreach ($this->possibleTokens as $possibleToken) {
similar_text($input, $possibleToken, $similarity);
if ($similarity > $bestSimilarity) {
$bestSimilarity = $similarity;
$bestGuess = $possibleToken;
}
}
return $bestGuess;
}

private function askForGuess($guess)
{
$prompter = new Prompter;
$answer = $prompter->ask("Did you mean '$guess'?", array('Y','n'), 'Y');
return !$answer || strtolower($answer) == 'y';
}

}
<?php
namespace CLIFramework;
use Pimple\Container;
use CLIFramework\Logger;
use CLIFramework\CommandLoader;
use CLIFramework\Config\GlobalConfig;
use CLIFramework\IO\StreamWriter;
use CLIFramework\IO\NullStty;
use CLIFramework\IO\UnixStty;
use CLIFramework\IO\ReadlineConsole;
use CLIFramework\IO\StandardConsole;
use Universal\Event\PhpEvent;

















class ServiceContainer extends Container
{
public function __construct()
{
$that = $this;
$this['config.path'] = function($c) {

$filename = 'cliframework.ini';
$configAtCurrentDirectory = getcwd() . DIRECTORY_SEPARATOR . $filename;
$configAtHomeDirectory = getenv('HOME') . DIRECTORY_SEPARATOR . $filename;

if (file_exists($configAtCurrentDirectory)) {
return $configAtCurrentDirectory;
}

if (file_exists($configAtHomeDirectory)) {
return $configAtHomeDirectory;
}
return null;
};

$this['event'] = function() {
return new PhpEvent;
};

$this['config'] = function($c) {
if (empty($c['config.path']) || !$c['config.path']) {
return new GlobalConfig(array());
}
return new GlobalConfig(parse_ini_file($c['config.path'], true));
};
$this['writer'] = function($c) {

$output = fopen("php://output", "w");
return new StreamWriter($output);
};
$this['logger'] = function($c) use ($that) {
return new Logger($that);
};
$this['formatter'] = function($c) {
return new Formatter;
};
$this['console.stty'] = function($c) use ($that){
if ($that->isWindows()) {

return new NullStty();
}
return new UnixStty();
};
$this['console'] = function($c) {
if (ReadlineConsole::isAvailable()) {
return new ReadlineConsole($c['console.stty']);
}
return new StandardConsole($c['console.stty']);
};
$this['command_loader'] = function($c) {
return CommandLoader::getInstance();
};
parent::__construct();
}

public function isWindows()
{
return preg_match('/^Win/', PHP_OS);
}

static public function getInstance()
{
static $instance;

if (!$instance) {
$instance = new static;
}

return $instance;
}
}


<?php
namespace CLIFramework\Exception;
use Exception;

class ExecuteMethodNotDefinedException extends CommandBaseException { }





<?php
namespace CLIFramework\Exception;
use Exception;
use CLIFramework\Exception\CommandBaseException;
use CLIFramework\CommandBase;

class InvalidCommandArgumentException extends CommandBaseException
{
public $arg;

public $argIndex;

public function __construct(CommandBase $command, $argIndex, $arg) {
$this->argIndex = $argIndex;
$this->arg = $arg;
parent::__construct($command, "Invalid '{$command->getName()}' command argument '$arg' at position $argIndex");
}
}

<?php
namespace CLIFramework\Exception;
use Exception;

class CommandClassNotFoundException extends Exception
{
public $class;

public $registeredNamespaces = array();

public $possibleClasses = array();

public function __construct($class, $registeredNamespaces = array()) {
$this->class = $class;
$this->registeredNamespaces = $registeredNamespaces;

$this->possibleClasses[] = $class;
foreach( $registeredNamespaces as $ns ) {
$this->possibleClasses[] = $ns . '\\' . ltrim($class, '\\');
}

$desc = "Command $class not found.";
if (!empty($this->registeredNamespaces)) {
$desc .= "\nRegistered namespaces: [" . join(',', $this->registeredNamespaces) . "]";
}
if (!empty($this->possibleClasses)) {
$desc .= "\nPossible classnames: [" . join(',', $this->possibleClasses) . "]";
}
parent::__construct($desc);
}

public function getRegisteredNamespaces() {
return $this->registeredNamespaces;
}

public function getPossibleClasses() {
return $this->possibleClasses;
}
}


<?php
namespace CLIFramework\Exception;
use Exception;
use CLIFramework\CommandBase;

class CommandBaseException extends Exception
{
public $command;

public function __construct(CommandBase $command, $message = "", $code = 0, $previous = NULL) {
$this->command = $command;
parent::__construct($message, $code, $previous);
}

public function getCommand() {
return $this->command;
}
}



<?php
namespace CLIFramework\Exception;
use CLIFramework\Extension\ExtensionBase;
use Exception;

class ExtensionException extends \Exception
{
protected $extension;

public function __construct($message, ExtensionBase $extension = null)
{
parent::__construct($message);

$this->extension = $extension;
}

public function getExtension()
{
return $this->extension;
}
}
<?php
namespace CLIFramework\Exception;
use Exception;
use CLIFramework\CommandBase;
use CLIFramework\Exception\CommandBaseException;

class CommandNotFoundException extends CommandBaseException
{
public $name;

public function __construct(CommandBase $command, $name) {
$this->name = $name;
parent::__construct($command, "Command $name not found.");
}
}


<?php
namespace CLIFramework\Exception;
use Exception;
use CLIFramework\CommandBase;

class CommandArgumentNotEnoughException extends CommandBaseException
{
public $given;

public $required;

public function __construct(CommandBase $command, $given, $required) {
$this->given = $given;
$this->required = $required;
parent::__construct($command, "Insufficient arguments for command '{$command->getName()}', which requires $required arguments, $given given.");
}


}
<?php









namespace CLIFramework;
use ReflectionClass;

class Utils
{







public static function translateCommandClassName($command)
{
$args = explode('-',$command);
foreach($args as & $a)
$a = ucfirst($a);
$subclass = join('',$args) . 'Command';

return $subclass;
}

public static function getClassPath($class, $baseDir = null) 
{
$refclass = new ReflectionClass($class);
$path = $refclass->getFilename();
if ($path && $baseDir) {
return str_replace(
rtrim(realpath($baseDir),DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR,
'', 
$path);
}
return $path;
}


}
<?php
if (isset($argv[1])) {
$file = $argv[1];
} else {
$file = 'app.phar';
}
$phar = new Phar($file, 0);
foreach (new RecursiveIteratorIterator($phar) as $file) {
if ($file->isDir()) {
echo "D ";
} else {
echo "F ";
}
echo $file->getPathname(), PHP_EOL;
}
echo "Stub:\n";
echo $phar->getStub();
#!/bin/sh
declare -A values
values[foo]='"111" "222" "333"'
values[bar]="222"

echo "keys: " ${(@k)values}
echo "values: " ${(@v)values}
echo "keys and values: " ${(@kv)values}
echo "index foo: " ${=values[foo]}
echo "index bar: " ${values[bar]}
# demo zsh completion script generated by CLIFramework
# Web: http://github.com/c9s/php-CLIFramework
# THIS IS AN AUTO-GENERATED FILE, PLEASE DON'T MODIFY THIS FILE DIRECTLY.

(( $+functions[__foometa] )) ||
__foometa () {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args
    local ret=1
    declare -a values

    desc=$1
    cmd=$2
    valtype=$3
    pos=$4
    completion=$5

    # $1 = -M, $2 = m:{[:lower:][:upper:]}={[:upper:][:lower:]}, $3 = -J, $4= option--author-1
    echo "example/demo meta $4"
    # values=$(example/demo meta $cmd $valtype $pos $completion)
    values=($(example/demo meta commit $valtype $pos $completion))

    # =values to expand values
    _values $desc ${=values} && ret=0
    # _arguments $desc ${=values} && ret=0
    return ret
}

# (( $+functions[__foo_commit] )) ||
__foo_commit () {
    local curcontext=$curcontext state line ret=1
    declare -A opt_args
    declare -a lines
    local ret=1
    lines=("#values" "c7a559c" "f135f61" "2f662" "572e9a7a31cb03e9caa97")

    lines=(
        '#descriptions'
        aaa:'aaa'
        bbb:'bbb'
        ccc:'ccc'
        ddd:'ddd'
        eee:'eee'
    )

    if [[ $lines[1] == "#values" ]] ; then
        declare -a commits
        commits=(${lines:1})
         _values "commits" ${=commits} && ret=0
    elif [[ $lines[1] == "#descriptions" ]] ; then
        declare -a commits
        commits=(${lines:1})
        # _describe -t commits commit commits && ret=0
        _describe commit commits && ret=0
    fi
    return ret
}

_foo () {
    local curcontext=$curcontext state line
    # typeset -A opt_args
    typeset -A val_args
    # typeset -A values
    declare -A opt_args
    local ret=1
    _arguments -w -C -S -s \
        '--author=[Override the commit author. Specify an explicit author using the standard A U Thor <author@example.com> format.]:author name:{__foometa dddd commit arg 1 valid-values}' \
        '--commit=[commit with description]:commit:{ __foo_commit }' \
        '--test=[commit with description]:test:(("foo\:foo desc" "bar\:bar desc"))' \
        && ret=0
    return ret
}
compdef _foo foo

_foo () {
    local curcontext=$curcontext state line
    typeset -A val_args
    declare -A opt_args
    local ret=1

    eval "$(php example/demo meta --zsh commit arg 0 valid-values)"
    for k in ${(k)groups} ; do
        values=(${(z)${groups[$k]}})
        label=${labels[$k]}
        if [[ -z $label ]] ; then
            label=$k
        fi
        _describe -t $k $label values && ret=0
    done

    # _describe -t commits commit commits && ret=0
    # commitdesca=("a:a" "b:b" "c:c")
    # commitdesca=(${(z)a:a b:b c:c})
    # commitdescb=("z:a" "x:b" "y:c")
    # _describe -t commitb commitb commitdescb && ret=0
    return ret
}
compdef _foo foo
<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://phpdox.de/config" silent="false">
    <project name="CLIFramework" source="src" workdir="build/phpdox">
        <collector publiconly="false">
            <include mask="*.php" />
            <exclude mask="*Autoload.php" />
        </collector>

        <generator output="build">
            <build engine="html" enabled="true" output="api"/>
            <build engine="graph" enabled="true" output="graph">
                <dot executable="/usr/bin/dot" render="true" format="png" />
            </build>
        </generator>
    </project>
</phpdox>
Steps = BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
VersionFrom = src/CLIFramework/Application.php
[package]
name           = CLIFramework
desc           = A Powerful Command Line Application Framework
version        = 1.5.10
author         = Yo-An Lin <cornelius.howl@gmail.com>
channel        = pear.corneltek.com
stability      = stable

[require]
php = 5.3
pearinstaller = 1.4

; packages
pear.corneltek.com/GetOptionKit = 1.1.2
pear.corneltek.com/Universal = 0

[resources]
git = git://github.com/c9s/CLIFramework.git
[core]
verbose = false
debug = false
pid_dir = /tmp
<?php
namespace CurlKit\Progress;
use CurlKit\Progress\CurlProgressInterface;

class ProgressStar
implements CurlProgressInterface
{
public $stars = array('-','\\','|','/');
public $i = 0;
public $url;
public $done = false;

public function prettySize($bytes)
{
if ($bytes > 1000000) {
return round( $bytes / 1000000, 2) . 'M';
}
elseif ($bytes > 1000) {
return round($bytes / 1000, 2) . 'K';
}
return round($bytes,2) . 'B';
}

public function reset() {
$this->done = false;
}

public function setUrl($url) {
$this->url = $url;
}

public function curlCallback($ch, $downloadSize, $downloaded, $uploadSize, $uploaded)
{

if ($this->done || $downloadSize == 0) {
return;
}


if ($downloadSize != 0 && $downloadSize === $downloaded) {
$this->done = true;
printf("\r\t%-60s                           \n",$this->url);
} else {
$percent = ($downloaded > 0 ? (float) ($downloaded / $downloadSize) : 0.0 );
if( ++$this->i > 3 )
$this->i = 0;


printf("\r\tFetching %-60s %s % -3.1f%% %s", $this->url,
$this->stars[ $this->i ], 
$percent * 100, $this->prettySize($downloaded) );
}
}
}


<?php
namespace CurlKit\Progress;

interface CurlProgressInterface {
public function curlCallback($ch, $downloadSize, $downloaded, $uploadSize, $uploaded);
}


<?php
namespace CurlKit\Progress;
use Exception;
use CurlKit\Progress\CurlProgressInterface;
use CLIFramework\Formatter;

class ProgressBar
implements CurlProgressInterface
{

public $done = false;

public $terminalWidth = 78;

public $formatter;

public function __construct() {
$this->formatter = new Formatter;
}

public function reset() {
$this->done = false;
}




public function curlCallback($ch, $downloadSize, $downloaded, $uploadSize, $uploaded)
{
if ($this->done || $downloadSize == 0) {
return;
}
$unit = 'B';
if ($downloadSize > 1024 * 1024 ) {
$unit = 'MB';
$downloadSize /= (1024 * 1024.0);
$downloaded /= (1024 * 1024.0);
} elseif ($downloadSize > 1024) {
$unit = 'KB';
$downloadSize /= 1024.0;
$downloaded /= 1024.0;
}

$barSize = $this->terminalWidth - 12;
$percentage = ($downloaded > 0 && $downloadSize > 0 ? round($downloaded / $downloadSize, 2) : 0.0);
$sharps = ceil($barSize * $percentage);

fwrite(STDOUT,"\r"
. $this->formatter->format('[','strong_white')
. str_repeat('=', $sharps)
. str_repeat(' ', $barSize - $sharps )
. $this->formatter->format(']','strong_white')
. sprintf( ' %.2f/%.2f%s %2d%%', $downloaded, $downloadSize, $unit, $percentage * 100 )
);

if ($downloadSize === $downloaded && $downloadSize > 0) {
$this->done = true;
fwrite(STDOUT,"\n");
}
}
}

<?php

namespace CurlKit;

use CurlKit\Progress\CurlProgressInterface;




















class CurlDownloader 
{
protected $userAgent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.A.B.C Safari/525.13';

public $options = array( 
CURLOPT_HEADER => 1,
CURLOPT_RETURNTRANSFER => 1, 
CURLOPT_FORBID_REUSE => 1,
CURLOPT_NOPROGRESS => true,
CURLOPT_FAILONERROR => 1,
);

public $refreshConnect = 1;

public $followLocation = 1;

public $bufferSize = 512;

public $connectionTimeout;

public $timeout;

public $progress;

public $proxy;

public $proxyAuth;

public function __construct($options = array() )
{
if (isset($options['progress'])) {
$this->setProgressHandler($options['progress']);
}
}

public function createCurlResource( $extra = array() ) 
{
$ch = curl_init();

if ($this->connectionTimeout !== null) {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout);
}

if ($this->timeout !== null) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
}

curl_setopt_array($ch, (
$this->options 
+ array( 
CURLOPT_FRESH_CONNECT => $this->refreshConnect,


CURLOPT_BUFFERSIZE => $this->bufferSize,


CURLOPT_USERAGENT => $this->userAgent,
) 
+ $extra
)); 

if ($this->proxy) {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
if ( $this->proxyAuth ) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->proxyAuth);
}
}
return $ch;
}

public function setBufferSize($bytes) {
$this->bufferSize = $bytes;
}

public function setTimeout($seconds)
{
$this->timeout = $seconds;
}

public function setConnectionTimeout( $seconds )
{
$this->connectionTimeout = $seconds;
}






public function setProgressHandler(CurlProgressInterface $handler)
{
$this->progress = $handler;
$this->options[ CURLOPT_NOPROGRESS ] = false;


if (version_compare(phpversion(),"5.5.0") >= 0) {
$this->options[ CURLOPT_PROGRESSFUNCTION ] = array($this,'updateProgress5');
} else {
$this->options[ CURLOPT_PROGRESSFUNCTION ] = array($this,'updateProgress4');
}
}

public function updateProgress4($downloaded, $totalDownload, $upload, $totalUpload) {
$this->progress->curlCallback(NULL, $downloaded, $totalDownload, $upload, $totalUpload);
}

public function updateProgress5($ch, $downloaded, $totalDownload, $upload, $totalUpload) {
$this->progress->curlCallback($ch, $downloaded, $totalDownload, $upload, $totalUpload);
}

public function getProgressHandler()
{
return $this->progress;
}

public function fetch($url)
{
return $this->request( $url );
}

public function request($url, $params = array(), $options = array() ) 
{
if ($this->progress) {
$this->progress->done = false;
}
$options[ CURLOPT_URL ] = $url;
$ch = $this->createCurlResource($options);
$data = curl_exec($ch);
if (!$data) {
throw new CurlException($ch, $url . ":" . curl_error($ch) );
}



$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

$headers = '';
$body = '';






if ($this->proxy !== null) {
list(, $headers, $body) = explode("\r\n\r\n", $data, 3);
} else {
list($headers, $body) = explode("\r\n\r\n", $data, 2);
}
if ($code == 301 || $code == 302) {
if (preg_match('/Location:\s*(\S+)/i', $headers, $matches)) {
$newurl = trim(array_pop($matches));
curl_close($ch);
echo "Redirecting to $newurl\n";
return $this->request($newurl, $params, $options);
} else {
throw new CurlException($ch, "The Location header can not be found: " . $headers);
}
}
curl_close($ch); 
return $body;
}






public function setProxy($proxy) {
$this->proxy = $proxy;
}

public function setProxyAuth($auth) {
$this->proxyAuth = $auth;
}

public function redirectExec($ch, &$redirects, $curlopt_header = false) {
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 301 || $http_code == 302) {
list($header) = explode("\r\n\r\n", $data, 2);
$matches = array();
preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches);
$url = trim(array_pop($matches));
$url_parsed = parse_url($url);
if (isset($url_parsed)) {
$ch = $this->createCurlResource(array( CURLOPT_URL => $url));
$redirects++;
return $this->redirectExec($ch, $redirects);
}
}
if ($curlopt_header) {
return $data;
} else {
list($headers,$body) = explode("\r\n\r\n", $data, 2);
return $body;
}
}
















}

<?php
namespace CurlKit;
use ArrayAccess;
use Exception;

class CurlResponse { 

public $rawHeaderBody;

public $headers = array();

public $body;

public function __construct($body, $rawHeaderBody = null) {
$this->body = $body;
if ( $rawHeaderBody ) {
$this->rawHeaderBody = $rawHeaderBody;
$this->headers = $this->parseHttpHeader($rawHeaderBody);
}
}





public static function createFromRawResponse($ch, $rawResponse) {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$rawHeader = substr($rawResponse, 0, $headerSize);
$body = substr($rawResponse, $headerSize);
return new self($body, $rawHeader);
}

public function hasHeader($field) {
return isset($this->headers[$field]);
}

public function getHeader($field) {
if ( isset($this->headers[$field]) ) {
return $this->headers[$field];
}
}

public function parseHttpHeader($rawHeaderBody) {
$headers = array();
$lines = explode("\r\n", $rawHeaderBody);
$status = array_shift($lines);
foreach( $lines as $line ) {
if ( strpos($line,':') !== false ) {
list($key, $value) = explode(':', $line);
$headers[strtolower($key)] = trim($value);
}
}
return $headers;
}

public function decodeBody() {
if ($contentType = $this->getHeader('content-type') ) {

if ( preg_match('#(?:application|text)/json#', $contentType) ) {

return json_decode($this->body);
}
}
return $this->body;
}

}
<?php
namespace CurlKit;

class CurlRequest
{




public $url;




public $method = 'GET';

public $parameters = array();








public $headers = array();

public $response;





public $curlResource;

public function __construct($url, $method = 'GET', $parameters = array(), $headers = array() ) {
$this->url = $url;
$this->method = $method;
$this->parameters = $parameters;
$this->headers = $headers;
}

public function setHeaders(array $headers) {
$this->headers = $headers;
}

public function getHeaders() {
return $this->headers;
}

public function setResponse(CurlResponse $resp) {
$this->response = $resp;
}

public function getResponse() {
return $this->response;
}

public function getEncodedParameters() {
if (is_array($this->parameters)) {
return http_build_query($this->parameters);
}
return $this->parameters;

}

public function getParameters() {
return $this->parameters;
}

public function getParameterCount() {
return count($this->parameters);
}

public function applyCurlResource($ch) {
if ( $this->method == 'GET' ) {
$url = $this->url;
if ( $query = $this->getEncodedParameters() ) {
$url .= '?' . $query;
}
curl_setopt($ch, CURLOPT_URL, $url);
} elseif ( $this->method == 'POST' ) {
$postBody = $this->getEncodedParameters();
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
} elseif ( $this->method === 'HEAD' ) {
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_NOBODY, true);
} else {
curl_setopt($ch, CURLOPT_URL, $this->url);
}


if ( ! empty($this->headers) ) {
$headerLines = array();
foreach ($this->headers as $key => $value) {
if (is_numeric($key)) {
$headerLines[] = $value;
} else {
$headerLines[] = $key . ':' . $value;
}
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerLines);
}
$this->curlResource = $ch;
}

public function send() {
if ( ! $this->curlResource ) {
throw new RuntimeException('');
}
return curl_exec($this->curlResource);
}

protected function _encodeFields(array & $fields) {
$fieldsString = '';
foreach( $fields as $key => $value ) { 
$fieldsString .= $key.'='. urlencode($value) .'&'; 
}
return rtrim($fieldsString, '&');
}


}

<?php
namespace CurlKit;
use Exception;



class CurlException extends Exception
{
protected $url;


public function __construct($ch, $url = null)
{
parent::__construct(curl_error($ch) . ' at [' . $url . ']', curl_errno($ch));
curl_close($ch); 
}
}
<?php
namespace CurlKit;
use ArrayAccess;
use Exception;
use CurlKit\CurlException;
use CurlKit\CurlRequest;
use CurlKit\CurlResponse;


define('CRLF', "\r\n");

class CurlAgent implements ArrayAccess {

public $throwException = true;

public $cookieFile;

public $sslVerifyhost = 0;

public $sslVerifypeer = 0;

public $followLocation = 1;

public $receiveHeader = true;

public $userAgent;

public $proxy;

public $proxyAuth;

public $connectionTimeout = 30;

public $timeout = 0;

public $failOnError = true;

protected $_curlOptions = array();

public function __construct() {
$this->cookieFile = tempnam("/tmp", str_replace('\\','_',get_class($this)) . mt_rand());
}






public function setProxy($proxy, $auth = null) {
$this->proxy = $proxy;
if ($auth) {
$this->proxyAuth = $auth;
}
}

public function setProxyAuth($auth) {
$this->proxyAuth = $auth;
}

public function setTimeout($secs) {
$this->timeout = $secs;
}

public function setConnectionTimeout($secs) {
$this->connectionTimeout = $secs;
}

protected function _handleCurlError($ch) {
if ( $this->throwException ) {

throw new CurlException($ch);
}
return FALSE;
}

protected function _handleCurlResponse($ch, $rawResponse) {
$ret = null;
if ($rawResponse) {
if ( $this->receiveHeader ) {
$ret = CurlResponse::createFromRawResponse($ch, $rawResponse);
} else {
$ret = new CurlResponse($rawResponse);
}

if (getenv('DEBUG_RESPONSE')) {
echo "RESPONSE:\n";
print_r($ret->decodeBody());
}

} else {
$ret = $this->_handleCurlError($ch);
}



curl_close($ch);
return $ret;
}



protected function _createCurlInstance() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookieFile);
curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookieFile);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $this->sslVerifyhost);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->sslVerifypeer);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->followLocation);


curl_setopt($ch, CURLOPT_FAILONERROR, $this->failOnError);



if ($this->connectionTimeout) {
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout );
}
if ($this->timeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
}

curl_setopt($ch, CURLINFO_HEADER_OUT, true );

if ( $this->proxy ) {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_setopt($ch, CURLOPT_PROXY, $this->proxy);
if ( $this->proxyAuth ) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $this->proxyAuth);
}
}

if ( $this->userAgent ) {
curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent );
}
if ( $this->receiveHeader ) {
curl_setopt($ch, CURLOPT_HEADER, true);
}

foreach( $this->_curlOptions as $k => $v) {
curl_setopt($ch, $k, $v);
}

return $ch;
}

protected function _readResponseBody($responseBody) {
return explode( CRLF . CRLF, $responseBody);
}

protected function _separateResponse($ch, $rawResponse) {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$rawHeader = substr($rawResponse, 0, $headerSize);
$body = substr($rawResponse, $headerSize);
return new CurlResponse($body, $rawHeader);
}

public function get($url, $fields = array(), $headers = array() ) {
$ch = $this->_createCurlInstance();
$request = new CurlRequest($url, 'GET', $fields, $headers);
$request->applyCurlResource($ch);
if ( getenv('DEBUG_REQUEST') ) {
echo "REQUEST:\n";
print_r($fields);
}
return $this->sendRequest($request);
}

public function post($url, $fields = array() , $headers = array()) {
$ch = $this->_createCurlInstance();
$request = new CurlRequest($url, 'POST', $fields, $headers);
$request->applyCurlResource($ch);
if ( getenv('DEBUG_REQUEST') ) {
echo "REQUEST: $url\n";
print_r($fields);
}
return $this->sendRequest($request);
}

public function head($url, $fields = array() , $headers = array() ) {
$ch = $this->_createCurlInstance();
$request = new CurlRequest($url, 'HEAD', $fields, $headers);
$request->applyCurlResource($ch);
if ( getenv('DEBUG_REQUEST') ) {
echo "REQUEST:\n";
print_r($fields);
}
return $this->sendRequest($request);
}

public function sendRequest(CurlRequest $request) {
$rawResponse = $request->send();
$response = $this->_handleCurlResponse($request->curlResource, $rawResponse);
$request->setResponse($response);
return $response;
}


public function __destruct() {
if( file_exists($this->cookieFile) ) {
unlink($this->cookieFile);
}
}



public function offsetSet($name,$value)
{
$this->_curlOptions[ $name ] = $value;
}

public function offsetExists($name)
{
return isset($this->_curlOptions[ $name ]);
}

public function offsetGet($name)
{
return $this->_curlOptions[ $name ];
}

public function offsetUnset($name)
{
unset($this->_curlOptions[$name]);
}

}

; phprelease tool from http://github.com/c9s/PHPRelease
; Steps = PHPUnit, scripts/update-init-script, BumpVersion, scripts/compile, GitCommit, GitTag, GitPush, GitPushTags
Steps = PHPUnit, BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
Copyright (c) 2011 Yo-An Lin

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
   must display the following acknowledgement:
     This product includes software developed by the University of
     California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its contributors
   may be used to endorse or promote products derived from this software
   without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
#!/usr/bin/env php
<?php
if( ! extension_loaded('bcompiler') ) {
    die('bcompiler extension is required.');
}

if( count($argv) < 2 ) {
    die("Usage: phpbc [path1 path2 path3 ...]\n");
}

$dirs = array_splice($argv,1);
foreach( $dirs as $dir ) {
    // compile
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
                                                RecursiveIteratorIterator::CHILD_FIRST);
    $examine = true;
    foreach ($iterator as $path) {
        if( $path->isFile() ) {
            if( $path->getExtension() !== 'php' )
                continue;

            echo "Compiling PHP " , $path , "\n";
            $bytePath = str_replace( '.php', '.phpb', $path->__toString() );
            $fh = fopen( $bytePath , 'w');
            bcompiler_write_header($fh) || die('bcompiler: write header failed.');
            bcompiler_write_file($fh, $path->__toString() ) || die('bcompiler: write file failed.');
            bcompiler_write_footer($fh) || die('bcompiler: write footer failed.');
            fclose($fh);

            if( $examine ) {
                echo "Examing $bytePath ...\n";
                $fp = fopen($bytePath,'r');
                bcompiler_read( $fp ) || die('bcompiler: read failed.');
                fclose($fp);
            }
        }
    }
}

<?php 
namespace Universal\Http;
use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;
use SplFileInfo;

class FilesParameter extends Parameter
implements ArrayAccess, IteratorAggregate
{
public function __construct($hash = null)
{
if ($hash) {
$this->hash = $hash;
} else if (isset($_FILES)) {
$this->hash = self::fix_files_array($_FILES);
}
}

public function getIterator()
{
return new ArrayIterator($this->hash);
}

public function offsetSet($name,$value)
{
$this->hash[ $name ] = $value;
}

public function offsetExists($name)
{
return isset($this->hash[ $name ]);
}

public function offsetGet($name)
{
return $this->hash[ $name ];
}

public function offsetUnset($name)
{
unset($this->hash[$name]);
}

public static function _move_indexes_right($files) {
if( ! is_array($files['name']) )
return $files;
$results = array(); 
foreach($files['name'] as $index => $name) { 
$reordered = array( 
'name' => $files['name'][$index], 
'tmp_name' => $files['tmp_name'][$index], 
'size' => $files['size'][$index], 
'type' => $files['type'][$index], 
'error' => $files['error'][$index], 
); 


if (is_array($name)) {
$reordered = FilesParameter::_move_indexes_right($reordered); 
}
$results[$index] = $reordered; 
} 
return $results; 
}

public static function fix_files_array($files)
{

if (isset($files['name'], $files['tmp_name'], $files['size'], $files['type'], $files['error'])){ 
return FilesParameter::_move_indexes_right($files); 
}

array_walk($files, function(&$sub) {
if (is_array($sub)) {
$sub = FilesParameter::fix_files_array($sub); 
}
});
return $files;
}
}
<?php 
namespace Universal\Http;
use ArrayAccess;

class Parameter implements ArrayAccess
{
public $hash = array();

public function __construct( & $hash = array() )
{
$this->hash = $hash;
}

public function has( $name )
{
return isset( $this->hash[ $name ] );
}

public function __isset( $name )
{
return isset( $this->hash[ $name ] );
}

public function __get( $name )
{
if( isset($this->hash[$name]) ) {
return $this->hash[ $name ];
}
}

public function __set( $name , $value )
{
$this->hash[ $name ] = $value;
}


public function offsetGet($key)
{
return $this->hash[ $key ];
}

public function offsetSet($key,$value)
{
$this->hash[ $key ] = $value;
}

public function offsetExists($key)
{
return isset( $this->hash[ $key ] );
}

public function offsetUnset($key)
{
unset( $this->hash[ $key ] );
}

}
<?php
namespace Universal\Http;










class PutHandle
{
private $handle;

function __construct()
{
$this->handle = fopen('php://input','r');
}

function read($i = 1024)
{
return fread($this->handle, $i);
}

function close()
{
fclose($this->handle);
}

}
<?php
namespace Universal\Http;
use Universal\Exception\InvalidUploadFileException;
use Universal\Exception\UploadedFileMoveFailException;
use Universal\Exception\UploadErrorException;
use Exception;
use SplFileObject;
use ArrayAccess;











class UploadedFile implements ArrayAccess
{





protected $originalFileName;







protected $tmpName;







protected $type;

protected $size;

protected $error;

protected $savedPath;

protected $stash = array();

public function __construct($tmpName, $originalFileName = null, $type = null, $savedPath = null)
{
$this->tmpName = $tmpName;
$this->originalFileName = $originalFileName ?: $this->tmpName;
$this->type = $type;
$this->savedPath = $savedPath;
$file = $this->savedPath ?: $this->tmpName;
if (file_exists($file)) {
$this->size = filesize($file);
}
}

static public function createFromArray(array & $stash)
{
$file = new self($stash['tmp_name'], $stash['name'], $stash['type']);
if (isset($stash['saved_path'])) {
$file->savedPath = $stash['saved_path'];
}
$file->setStashedArray($stash);
return $file;
}

protected function setStashedArray(array & $stash)
{
$this->stash = $stash;
}

protected function getStashedArray()
{
return $this->stash;
}

public function getSplFileObject()
{
$path = $this->getCurrentPath();
return new SplFileObject($path);
}








public function getCurrentPath()
{
if ($this->savedPath) {
return $this->savedPath;
}
return $this->tmpName;
}

public function getOriginalFileName()
{
return $this->originalFileName;
}







public function getTmpName()
{
return $this->tmpName;
}






public function getExtension()
{
$parts = explode('.',$this->originalFileName);
return end($parts);
}







public function validateSize($limitSize)
{
return ($this->size / 1024) < $limitSize;
}

public function validateExtension(array $exts)
{
$ext = strtolower($this->getExtension());
return in_array($ext, $exts);
}

public function getSavedPath()
{
return $this->savedPath;
}

public function getType()
{
return $this->type;
}





public function getSize()
{
return $this->size;
}








public function isMoved()
{
return $this->getSavedPath() ? true : false;
}







public function isUploadedFile()
{
return is_uploaded_file($this->tmpName);
}



















public function move($newPath, $rename = false)
{
if ($this->savedPath) {
return $this->savedPath;
}











$ret = false;
if ($rename) {
$tmpFile = $this->tmpName;
$ret = rename($tmpFile, $newPath);
} else {
$ret = $this->moveUploadedFile($newPath);
}
$this->savedPath = $this->stash['saved_path'] = $newPath;

if ($ret === false) {
return $ret;
}
return $newPath;
}






public function copy($targetPath)
{
if ($this->savedPath) {
return copy($this->savedPath, $targetPath);
}
return copy($this->tmpName, $targetPath);
}







public function copyTo($targetDir)
{


$targetFileName = basename($this->originalFileName);


$newPath = $targetDir . DIRECTORY_SEPARATOR . $targetFileName;
return $this->copy($newPath);
}












public function moveTo($targetDir, $rename = false)
{


$targetFileName = basename($this->originalFileName);


$newPath = $targetDir . DIRECTORY_SEPARATOR . $targetFileName;
return $this->move($newPath, $rename);
}

public function moveUploadedFile($target)
{

if ($this->savedPath) {
return $this->savedPath;
}
if ($this->stash['error'] != 0) {
throw new UploadErrorException($this->stash,"An error occured when uploading file {$this->tmpName}.", $this->stash['error']);
}
if (!is_uploaded_file($this->tmpName)) {
throw new InvalidUploadFileException($this->stash, "File {$this->tmpName} is not an uploaded file.");
}
if (false === move_uploaded_file($this->tmpName, $target)) {
throw new UploadedFileMoveFailException($this->stash, "File {$this->tmpName} upload failed.");
}

return $this->savedPath = $this->stash['saved_path'] = $target;
}

public function deleteTmp()
{
unlink($this->tmpName);
}

public function found()
{
return $this->name ? true : false;
}

public function hasError()
{
return intval($this->error) != 0;
}

public function getUserErrorMessage()
{

switch ($this->error) {
case UPLOAD_ERR_OK:
return "OK";
case UPLOAD_ERR_INI_SIZE || UPLOAD_ERR_FORM_SIZE:
return "The upload file exceeds the limit.";
case UPLOAD_ERR_PARTIAL:
return "The uploaded file was only partially uploaded.";
case UPLOAD_ERR_NO_FILE:
return "No file was uploaded.";
case UPLOAD_ERR_CANT_WRITE:
return "Failed to write file to disk.";
case UPLOAD_ERR_EXTENSION:
return "A PHP extension stopped the file upload.";
default:
return "Unknown error.";
}
}






public function getSystemErrorMessage()
{

switch ($this->error) {
case UPLOAD_ERR_OK:
return "There is no error, the file uploaded with success.";
case UPLOAD_ERR_INI_SIZE:
return "The uploaded file exceeds the upload_max_filesize directive in php.ini.";
case UPLOAD_ERR_FORM_SIZE:
return "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.";
case UPLOAD_ERR_PARTIAL:
return "The uploaded file was only partially uploaded.";
case UPLOAD_ERR_NO_FILE:
return "No file was uploaded.";
case UPLOAD_ERR_NO_TMP_DIR:
return "Missing a temporary folder. Introduced in PHP 4.3.10 and PHP 5.0.3.";
case UPLOAD_ERR_CANT_WRITE:
return "Failed to write file to disk. Introduced in PHP 5.1.0.";
case UPLOAD_ERR_EXTENSION:
return "A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help. Introduced in PHP 5.2.0.";
default:
return "Unknown Error.";
}
}


public function offsetSet($name,$value)
{
$this->stash[ $name ] = $value;
}

public function offsetExists($name)
{
return isset($this->stash[ $name ]);
}

public function offsetGet($name)
{
return $this->stash[ $name ];
}

public function offsetUnset($name)
{
unset($this->stash[$name]);
}

}
<?php
namespace Universal\Http;
use Exception;






class Cookie
{

public $expire = 0;

public $path;

public $domain;

public $secure = false;

public $httponly = false;













public function __construct($options = array() ) {
foreach( array('expire','path','domain','secure','httponly') as $k ) {
if( isset($options[$k]) )
$this->$k = $options[$k];
}
}







public function setPath($path) { $this->path = $path; }

public function setSecure($secure) { $this->secure = $secure; }



public function calculateExpireTime($expire) {
if( is_string($expire) ) {

if( preg_match('#(\d+)\s+(days?|hours?|minutes?|seconds?)#',$expire,$regs) ) {
$num = (int) $regs[1];
$length = $regs[2];
$seconds = 1;
switch($length) {
case 'day':
case 'days':
$seconds = 3600 * 24;
break;
case 'hour':
case 'hours':
$seconds = 3600;
break;
case 'minute':
case 'minutes':
$seconds = 60;
break;
case 'second':
case 'seconds':
default:
$seconds = 1;
break;
}
return time() + ($seconds * $num);
} else {
throw new \Exception('Unknown expire format');
}
}
elseif( $expire < 0 || $expire > 1000000000 ) {

return $expire;
}

return time() + $expire;
}






















public function setExpire($expire) { 
$this->expire = $this->calculateExpireTime($expire);
}

public function setDomain($domain) { 
$this->domain = $domain; 
}

public function remove($name) 
{
setcookie($name, NULL, -1);
}

public function set($name,$value, $expire = null , $path = null)
{

$args = array($name,$value);
if( $expire !== null || $this->expire ) {
$args[] = $expire ? $this->calculateExpireTime($expire) : $this->expire;
if( $path || $this->path ) {
$args[] = $path ? $path : $this->path;
if( $this->domain ) {
$args[] = $this->domain;
$args[] = $this->secure;
$args[] = $this->httponly;
}
}
}

return @call_user_func_array('setcookie',$args);
}

public function __set($name,$value) 
{
return $this->set($name,$value);
}

public function __get($name) {
return $this->get($name);
}

public function get($name) {
if( isset($_COOKIE[$name]) ) {
return $_COOKIE[$name];
}
}
}

<?php 
namespace Universal\Http;
use ArrayAccess;
use Universal\Http\FilesParameter;













class HttpRequest
implements ArrayAccess
{
protected $_requestBodyFp;

protected $_parameterBags = [];


static $httpHeaderMapping = array(
'HTTP_ACCEPT' => 'Accept',
'HTTP_ACCEPT_CHARSET' => 'Accept-Charset',
'HTTP_ACCEPT_ENCODING' => 'Accept-Encoding',
'HTTP_ACCEPT_LANGUAGE' => 'Accept-Language',
'HTTP_CONNECTION' => 'Connection',
'HTTP_CACHE_CONTROL' => 'Cache-Control',
'HTTP_UPGRADE_INSECURE_REQUESTS' => 'Upgrade-Insecure-Requests',
'HTTP_HOST' => 'Host',
'HTTP_REFERER' => 'Referer',
'HTTP_USER_AGENT' => 'User-Agent',
);




public $files = array();





public $parameters = array();





public $bodyParameters = array();




public $queryParameters = array();


public $cookieParameters = array();





public $serverParameters = array();

public $sessionParameters = array();









public function __construct(array $parameters = array(), array $files = array())
{
$this->parameters = $parameters;
$this->files = FilesParameter::fix_files_array($files);
}


public function openRequestBodyStream()
{
$input = 'php://input';
if (isset($this->serverParameters['phpsgi.input'])) {
$input = $this->serverParameters['phpsgi.input'];
}
return $this->_requestBodyFp = fopen($input);
}

public function closeRequestBodyStream()
{
if ($this->_requestBodyFp) {
fclose($this->_requestBodyFp);
}
}

public function getRequestBody()
{
$input = 'php://input';
if (isset($this->serverParameters['phpsgi.input'])) {
$input = $this->serverParameters['phpsgi.input'];
}
return file_get_contents($input);
}







public function getRequestMethod()
{
if (isset($this->serverParameters['REQUEST_METHOD'])) {
return $this->serverParameters['REQUEST_METHOD'];
}
return 'GET';
}







public function hasParam($name)
{
return isset($this->parameters[$name]);
}

public function existsParam($name)
{
return array_key_exists($name, $this->parameters);
}





public function param($field)
{
if (isset($this->parameters[$field])) {
return $this->parameters[$field];
}
}

public function getFiles() 
{
return $this->files;
}

public function file($field)
{
if (isset($this->files[$field])) {
return $this->files[$field];
}
}







public function getInput()
{
return file_get_contents('php://input');
}







public function getInputParams()
{
$params = array();
parse_str($this->getInput(), $params);
return $params;
}


public function offsetSet($name,$value)
{
$this->parameters[ $name ] = $value;
}

public function offsetExists($name)
{
return isset($this->parameters[ $name ]);
}

public function offsetGet($name)
{
return $this->parameters[ $name ];
}

public function offsetUnset($name)
{
unset($this->paramemters[$name]);
}

public function getQueryParameters()
{
return $this->queryParameters;
}

public function getBodyParameters()
{
return $this->bodyParameters;
}

public function getParameters()
{
return $this->parameters;
}


public function __get($key)
{
if (isset($_parameterBags[$key])) {
return $_parameterBags[$key];
}


switch($key)
{
case 'files':
return $this->_parameterBags[$key] = new FilesParameter($this->files);
case 'post':
return $this->_parameterBags[$key] = new Parameter($this->bodyParameters);
case 'get':
return $this->_parameterBags[$key] = new Parameter($this->queryParameters);
case 'session':
return $this->_parameterBags[$key] = new Parameter($this->sessionParameters);
case 'server':
return $this->_parameterBags[$key] = new Parameter($this->serverParameters);
case 'request':
return $this->_parameterBags[$key] = new Parameter($this->parameters);
case 'cookie':
return $this->_parameterBags[$key] = new Parameter($this->cookieParameters);
}
}

public function cookieParam($name)
{
if (isset($this->cookieParameters[$name])) {
return $this->cookieParameters[$name];
}
}







public static function createHeadersFromServerGlobal(array $server)
{
$headers = array();
foreach (self::$httpHeaderMapping as $serverKey => $headerKey) {
if (isset($server[$serverKey])) {
$headers[$headerKey] = $server[$serverKey];
}
}

foreach ($server as $key => $value) {
if (isset(self::$httpHeaderMapping[$key])) {
continue;
}
if ('HTTP_' === substr($key,0,5)) {
$headerField = join('-',array_map('ucfirst',explode('_', strtolower(substr($key,5)))));
$headers[$headerField] = $value;
}
}
return $headers;
}




public function __destruct()
{


if ($this->_requestBodyFp) {
$this->closeRequestBodyStream();
}
}








static public function createFromGlobals(array $globals)
{
$request = new self;
if (isset($globals['_POST'])) {
$request->bodyParameters = $globals['_POST'];
}
if (isset($globals['_GET'])) {
$request->queryParameters = $globals['_GET'];
}
if (isset($globals['_REQUEST'])) {
$request->parameters = $globals['_REQUEST'];
}
if (isset($globals['_COOKIE'])) {
$request->cookieParameters = $globals['_COOKIE'];
}
if (isset($globals['_SESSION'])) {
$request->sessionParameters = $globals['_SESSION'];
}
if (isset($globals['_FILES'])) {
$request->files = FilesParameter::fix_files_array($globals['_FILES']);
}
if (isset($globals['_SERVER'])) {
$request->serverParameters = $globals['_SERVER'];
}
return $request;
}







}

<?php
namespace Universal\Http;

class HttpResponse
{




public $code;





public $status; 





public $contentType;





public $cacheControl;






public $expires;





public $body;







public function __construct($code = 200, $status = 'OK') 
{
$this->code = $code;
$this->status = $status;
}








public function code($code)
{
$this->code = $code;
}








public function status($status)
{
$this->status = $status;
}








public function location($url)
{
header( 'Location: ' . $url );
}






public function redirect($url) 
{
$this->code(302);
$this->location($url);
}







public function redirectPermanently($url)
{
$this->code(301);
$this->status('Moved Permanently');
$this->location($url);
}







public function redirectLater($url, $seconds = 1) 
{
header( "refresh: $seconds; url=$url" );
}













public function contentType($contentType)
{
$this->contentType = $contentType;
}

public function body($body)
{
$this->body = $body;
}







public function cacheControl($desc) 
{
$this->cacheControl = $desc;
}





public function noCache() 
{
$this->cacheControl = 'no-cache, must-revalidate';
}






public function cacheExpiryTime($seconds) 
{
$this->expires = time() + $seconds;
}











public function codeOk() 
{
$this->code = 200;
$this->status = 'OK';
}

public function codeCreated()
{
$this->code = 201;
$this->status = 'Created';
}

public function codeAccepted()
{
$this->code = 202;
$this->status = 'Accepted';
}

public function codeNoContent() 
{
$this->code = 204;
$this->status = 'No Content';
}

public function codeBadRequest()
{
$this->code = 400;
$this->status = 'Bad Request';
}

public function codeForbidden()
{
$this->code = 403;
$this->status = 'Forbidden';
}

public function codeNotFound()
{
$this->code = 404;
$this->status = 'Not found';
}


public function finalize()
{
if( $this->code ) {
@header('HTTP/1.1 ' . $this->code . ' ' . $this->status );
}
if( $this->contentType ) {
@header("Content-type: " . $this->contentType );
}
if( $this->cacheControl ) {
@header('Cache-Control: ' . $this->cacheControl); 
}
if( $this->expires ) {
$datestr = gmdate(DATE_RFC822, $this->expires );

@header( "Expires: $datestr" );
}
return $this->body;
}

public function __toString() 
{
return $this->finalize();
}

}



<?php
namespace Universal\Http;

class StreamResponse
{
public $boundary;





function __construct() {
$this->boundary = md5(mt_rand() . time());


set_error_handler(function() { return false; });

header("Content-Type: multipart/mixed; boundary=\"{$this->boundary}\"");

if( function_exists('apache_setenv') ) {
apache_setenv('no-gzip', 1);
}
ini_set('zlib.output_compression', 0);
ini_set('implicit_flush', 1);
set_time_limit(0);



while( ob_get_level() ) { 
ob_end_flush(); 
}
ob_implicit_flush(1);
restore_error_handler();
}








public function write($content, $headers = array() ) {
echo "--{$this->boundary}\n";

if( is_array($headers) ) {
foreach( $headers as $k => $v ) {
echo $k . ':';
if( is_array($v) ) {
echo join(';',$v);
} else {
echo $v;
}
echo "\n\n";
}
} else {
echo $headers;
echo "\n";
}
echo $content;
echo PHP_EOL;
flush();
}

public function finalize()
{
echo "--{$this->boundary}--\n";
}
}


<?php
namespace Universal\FileSystem;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;

class PathUtils {

static function path_join($list)
{
$args = null;
if( is_array($list) ) {
$args = $list;
} else {
$args = func_get_args();
}
return call_user_func( 'join' , DIRECTORY_SEPARATOR , $args );
}

static function mkdir( $path , $verbose = false , $mode = 0777 )
{
if( $verbose )
echo "Creating dir: $path\n";
mkdir($path,$mode);
}

static function rmtree( $paths , $verbose = false )
{
$paths = (array) $paths;
foreach( $paths as $path ) {

if( ! file_exists( $path ) )
die( "$path does not exist." );

if( is_dir( $path ) ) 
{
$iterator = new \DirectoryIterator($path);
foreach ($iterator as $fileinfo) 
{
if( $fileinfo->isDir() ) {
if( $fileinfo->getFilename() == "." )
continue;

if( $fileinfo->getFilename() == ".." )
continue;
self::rmtree( $fileinfo->getPathname() );

if( $verbose )
echo "\trmdir: " . $fileinfo->getPathname() . "\n";
}
elseif ($fileinfo->isFile()) {
if( $verbose )
echo "\tunlink file: " . $fileinfo->getPathname() . "\n";

if( unlink( $fileinfo->getPathname() ) == false )
die( "File delete error: {$fileinto->getPathname()}" );
}
}
rmdir( $path );
} 
elseif( is_file( $path ) ) {
unlink( $path );
}


}

}

static function mkpath( $paths , $verbose = false , $mode = 0777 )
{
$paths = (array) $paths;
foreach( $paths as $path ) {
if( $verbose )
echo "\tCreating directory $path\n";
if( file_exists( $path ) )
continue;
mkdir( $path, $mode , true ); 
}
}

static function create_keepfile( $path )
{
$keepfile = static::path_join( $path , '.keep' );
touch( $keepfile );
}


static function relative_path( $abspath ) 
{
$path = realpath( $abspath );
$cwd = getcwd();
return substr( $path , strlen( $cwd ) + 1 );
}


static function remove_base( $path , $base )
{
return substr( $path , strlen( $base ) + 1 );
}

static function expand_path( $path ) 
{
$start = strpos( $path , '{' );
$end = strpos( $path , '}' , $start );

if( $start === false || $end === false )
return (array) $path;

$expand = explode(',',substr( $path , $start + 1 , $end - $start - 1 ));
$wstr_start = substr( $path , 0 , $start );
$wstr_end = substr( $path , $end + 1 );
$paths = array();
foreach( $expand as $item )
{
$paths[] = $wstr_start . $item . $wstr_end;
}
return $paths;
}






static function expand_dir($dir)
{
if( is_dir($dir) ) {
$files = array();
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir),
\RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $path) {
if ($path->isDir()) {

} elseif( $path->isFile() ) { 
array_push( $files , $path->__toString() );
}
}
return $files;
}
return array($dir);
}




static function concat_files( $files )
{
$content = '';
foreach( $files as $file ) {
$content .= file_get_contents( $file );
}
return $content;
}

static function filename_append_md5( $filename , $filePath = null )
{
$suffix = $filePath ? md5( $filePath ) : md5( time() );
$pos = strrpos( $filename , '.' );
if( $pos ) {
return 
substr( $filename , 0 , $pos )
. $suffix 
. substr( $filename , $pos );
}
return $filename . $suffix;
}

static function filename_suffix( $filename , $suffix )
{
$pos = strrpos( $filename , '.' );
if( $pos ) {
return 
substr( $filename , 0 , $pos )
. $suffix 
. substr( $filename , $pos );
}
return $filename . $suffix;
}

static function mimetype( $file )
{
$fi = new \finfo( FILEINFO_MIME );
$mime_type = $fi->buffer(file_get_contents($file));
return $mime_type;
}

}

<?php









namespace Universal\Container;
use Exception;

class ObjectContainerException extends Exception { }

class ObjectContainer 
{
public $_builders = array();

public $_singletonObjects = array();

public $throwIfNotFound = false;







public function hasBuilder($key)
{
return isset($this->_builders[ $key ]);
}








public function getObject($key,$args = array())
{
if( isset( $this->_singletonObjects[ $key ] ) ) {
return $this->_singletonObjects[ $key ];
}
elseif( $build = $this->getBuilder($key) ) {
if( isset($build['singleton']) && $build['singleton'] ) {
return $this->_singletonObjects[ $key ] = $this->_buildObject($build['builder'],$args);
}
return $this->_buildObject($build['builder'],$args);
}
else {
if( $this->throwIfNotFound ) {
throw new ObjectContainerException("object builder not found: $key");
}
}
}

protected function _buildObject($b,$args = array())
{
if( is_callable($b) ) {
return call_user_func_array($b,$args);
} 
elseif( is_array($b) ) {
return call_user_func_array($b,$args);
}
elseif( is_string($b) ) {
$callable = explode('#',$b);
$class = $callable[0];
if( class_exists($class,true) ) {
if( isset($callable[1]) ) {
return call_user_func_array($callable,$args);
} else {
return new $b;
}
}
else {
throw new ObjectContainerException("Can not build object from $b");
}
}
return $b;
}





public function build($key,$args = array())
{
if( $builder = $this->getBuilder($key) ) {
return $this->_buildObject($builder['builder'], $args);
}
}







public function getBuilder($key)
{
if( isset($this->_builders[$key]) ) {
return $this->_builders[ $key ];
}
}








public function setBuilder($key,$builder,$singleton = true)
{
$this->_builders[ $key ] = array( 
'singleton' => $singleton,
'builder' => $builder,
);
}





public function registerFactory($key,$builder)
{
$this->_builders[ $key ] = array( 
'singleton' => false,
'builder' => $builder,
);
}

public function __get($key)
{
return $this->getObject($key);
}

public function __set($key,$builder) 
{
$this->setBuilder($key,$builder);
}

public function __isset($key)
{
return $this->hasBuilder($key);
}

}
<?php









namespace Universal\ClassLoader;
use Universal\ClassLoader\ClassLoader;

class Psr4ClassLoader implements ClassLoader
{
protected $prefixes = array();

public function __construct(array $prefixes = array())
{
$this->prefixes = $prefixes;
}

public function addPrefix($prefix, $baseDir, $trim = false)
{
if ($trim) {
$prefix = trim($prefix, '\\') . '\\';
$baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
}
$this->prefixes[] = array($prefix, (array) $baseDir);
}

public function addPrefixes(array $prefixes, $trim = false)
{
foreach ($prefixes as $prefix => $baseDir) {
$this->addPrefix($prefix, $baseDir, $trim);
}
}







public function resolveClass($fullclass)
{

foreach ($this->prefixes as $prefixMap) {
list($prefix, $dirs) = $prefixMap;
if (strpos($fullclass, $prefix) === 0) {
$len = strlen($prefix);
$classSuffix = substr($fullclass, $len);
$subpath = str_replace('\\', DIRECTORY_SEPARATOR, $classSuffix) . '.php';

foreach ($dirs as $dir) {
$classPath = $dir . $subpath;
if (file_exists($classPath)) {
return $classPath;
}
}
}
}
}

public function loadClass($class)
{
if ($file = $this->resolveClass($class)) {
require $file;
return true;
}
return false;
}








public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}

public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}

}

<?php
namespace Universal\ClassLoader;

class ChainedClassLoader implements ClassLoader
{
protected $classloaders = array();

public function __construct(array $classloaders = array())
{
$this->classloaders = $classloaders;
}

public function resolveClass($fullClass)
{
foreach ($this->classloaders as $loader) {
if ($classPath = $loader->resolveClass($fullClass)) {
return $classPath;
}
}
}

public function loadClass($class)
{
if ($file = $this->resolveClass($class)) {
require $file;
}
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}

}



<?php
namespace Universal\ClassLoader;
use Universal\ClassLoader\ClassLoader;

class BytecodeClassLoader
{

}

<?php 
namespace Universal\ClassLoader;
if( ! class_exists('\Universal\ClassLoader\PathIncluder') ) {










class PathIncluder 
{




private $paths;




private $origPaths;

function __construct($paths) 
{
$this->origPaths = explode(PATH_SEPARATOR,get_include_path());
$this->paths = array_merge( (array) $paths , $this->origPaths );
}




function getPaths()
{
return $this->paths;
}







function remove($path)
{

if( ($index = array_search( $path , $this->paths )) !== FALSE ) {
unset( $this->paths[ $index ] );
}
}






function insert($path)
{
array_unshift( $this->paths, $path );
}







function add($path)
{
$this->paths[] = $path;
}




function inflate()
{
return join( PATH_SEPARATOR , $this->paths );
}




function setup()
{
set_include_path( join( PATH_SEPARATOR , $this->paths ) );
}

}

}
<?php























namespace Universal\ClassLoader;
use Exception;
use InvalidArgumentException;
use Universal\ClassLoader\ClassLoader;

if( ! class_exists('\Universal\ClassLoader\SplClassLoader') ) {






class SplClassLoader implements ClassLoader
{
static $instance;






public $namespaces = array();






public $prefixes = array();



public $fallbacks = array();






public $useIncludePath;




public $mode;







public function __construct($namespaces = null)
{
if( $namespaces )
$this->addNamespace( $namespaces );
self::$instance = $this;
}

public function getInstance() 
{
return self::$instance ?: self::$instance = new self;
}







public function addNamespace($ns = array())
{
if( is_array($ns) ) {
foreach( $ns as $n => $dirs )
$this->namespaces[ $n ] = (array) $dirs;
return;
} 
else {
$args = func_get_args();
if( count( $args ) == 2 ) {
$this->namespaces[ $args[0] ] = (array) $args[1];
return;
}

}
throw new InvalidArgumentException;
}







public function addPrefix($ps = array())
{
if (is_array($ps)) {
foreach ($ps as $prefix => $dirs) {
$this->prefixes[$prefix] = (array) $dirs;
}
} else {
list($prefix, $dirs) = func_get_args();
$this->prefixes[$prefix] = (array) $dirs;
}
}

public function addFallback($path)
{
$this->fallbacks[] = $path;
}






public function useIncludePath($bool)
{
$this->useIncludePath = $bool;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}





public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}







public function resolveClass($fullclass)
{
$fullclass = ltrim($fullclass,'\\');


$subpath = null;
if( ($r = strrpos($fullclass,'\\')) !== false ) {
$namespace = substr($fullclass,0,$r);
$classname = substr($fullclass,$r + 1);
$subpath = str_replace('\\', DIRECTORY_SEPARATOR, $namespace )
. DIRECTORY_SEPARATOR . str_replace( '_' , DIRECTORY_SEPARATOR , $classname ) 
. '.php';
foreach ($this->namespaces as $ns => $dirs) {


if( strpos($namespace,$ns) !== 0 )
continue;

foreach( $dirs as $d ) {
$path = $d . DIRECTORY_SEPARATOR . $subpath;
if( file_exists($path) )
return $path;
}
}
}
else {

$subpath = str_replace('_', DIRECTORY_SEPARATOR, $fullclass).'.php';
foreach ($this->prefixes as $p => $dirs) {
if (strpos($fullclass, $p) !== 0)
continue;
foreach ($dirs as $dir) {
$file = $dir . DIRECTORY_SEPARATOR . $subpath;
if (file_exists($file))
return $file;
}
}
}

foreach( $this->fallbacks as $fallback ) {
$file = $fallback . DIRECTORY_SEPARATOR . $subpath;
if( file_exists($file) )
return $file;
}

if ($this->useIncludePath && $file = stream_resolve_include_path($subpath)) {
return $file;
}
}

public function loadClass($class)
{
if ($file = $this->resolveClass($class)) {
require $file;
return true;
}
return false;
}

}

}
<?php
namespace Universal\ClassLoader;


class MapClassLoader
{

protected $classMap;

public function __construct(array $map)
{
$this->classMap = $map;
}







public function resolveClass($fullclass)
{
if (isset($this->classMap[$fullclass])) {
return $this->classMap[$fullclass];
}
}

public function loadClass($class)
{
if ($file = $this->resolveClass($class)) {
require $file;
return true;
}
return false;
}







public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}

public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}

}


<?php 
namespace Universal\ClassLoader;
use Universal\ClassLoader\ClassLoader;












class BasePathClassLoader implements ClassLoader
{

static $instance;




public $paths = array();






public $useIncludePath;

public function __construct($paths)
{
$this->paths = $paths;
self::$instance = $this;
}

public function getInstance() 
{
return self::$instance ?: self::$instance = new self;
}




public function useEnvPhpLib()
{
if ($lib = getenv('PHP5LIB')) {
$paths = explode( ':' , $lib );
foreach( $paths as $path )
$this->paths[] = $path;
}
}






public function resolveClass($fullclass)
{
$fullclass = ltrim($fullclass,'\\');


$subpath = null;
if( ($r = strrpos($fullclass,'\\')) !== false ) {
$namespace = substr($fullclass,0,$r);
$classname = substr($fullclass,$r + 1);
$subpath = str_replace('\\', DIRECTORY_SEPARATOR, $namespace )
. DIRECTORY_SEPARATOR . str_replace( '_' , DIRECTORY_SEPARATOR , $classname ) 
. '.php';


foreach( $this->paths as $d ) {
$path = $d . DIRECTORY_SEPARATOR . $subpath;
if( file_exists($path) )
return $path;
}
}
else {

$subpath = str_replace('_', DIRECTORY_SEPARATOR, $fullclass).'.php';
foreach ($this->paths as $dir ) {
$file = $dir.DIRECTORY_SEPARATOR.$subpath;
if (file_exists($file))
return $file;
}
}

if ($this->useIncludePath && $file = stream_resolve_include_path($subpath))
return $file;
}

public function loadClass($class)
{
if ($file = $this->resolveClass($class)) {

require $file;
}
}







public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}





public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}







public function useIncludePath($bool)
{
$this->useIncludePath = $bool;
}
}

<?php









namespace Universal\ClassLoader;

interface ClassLoader { 

public function register($prepend = false);

public function unregister();

public function resolveClass($fullclass);

public function loadClass($class);

}


<?php








namespace Universal\ClassLoader;

class Psr0ClassLoader implements ClassLoader
{






protected $namespaces = array();

public function __construct(array $namespaces = array()) 
{
$this->namespaces = $namespaces;
}

public function addNamespaces(array $namespaceMaps) 
{
$this->namespaces = array_merge($this->namespaces, $namespaceMaps);
}


public function addNamespace($ns, $dirs)
{
$this->namespaces[$ns] = (array) $dirs;
}







public function resolveClass($fullclass)
{
if (($r = strrpos($fullclass,'\\')) !== false) {
$namespace = substr($fullclass,0,$r);
$classname = substr($fullclass,$r + 1);
$subpath = strtr($fullclass, '\\', DIRECTORY_SEPARATOR) . '.php';
foreach ($this->namespaces as $ns => $dirs) {
if (strpos($namespace,$ns) === 0) {
foreach ((array) $dirs as $dir) {
$path = $dir . DIRECTORY_SEPARATOR . $subpath;
if (file_exists($path)) {
return $path;
}
}
}
}
}
}

public function loadClass($class)
{
if ($file = $this->resolveClass($class)) {
require $file;
return true;
}
return false;
}






public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}




public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
}




<?php
namespace Universal\ClassLoader;
use Universal\ClassLoader\ClassLoader;
use Exception;

class ApcClassLoader extends SplClassLoader
{
public $apcprefix = 'apc';

public function __construct($prefix = '_apc', $namespaces = null)
{
parent::__construct( $namespaces );
$this->apcPrefix = $prefix;
}

public function setApcPrefix($prefix)
{
$this->apcPrefix = $prefix;
}

public function loadClass($class)
{
if( ($file = apc_fetch($this->apcPrefix . $class) ) !== false ) {
require $file;
return true;
}

if ($file = $this->resolveClass($class)) {
apc_store( $this->apcPrefix . $class , $file );
require $file;
return true;
}
return false;
}
}

<?php









namespace Universal\Event;








class PhpEvent
{





public $eventPool = array();







public function register($ev,$cb)
{
if (! isset($this->eventPool[ $ev ] )) {
$this->eventPool[ $ev ] = array();
}
$this->eventPool[ $ev ][] = $cb;
}







public function bind($ev,$cb)
{
if (! isset($this->eventPool[ $ev ] )) {
$this->eventPool[ $ev ] = array();
}
$this->eventPool[ $ev ][] = $cb;
}










public function trigger($evname)
{
$results = array();
if( isset( $this->eventPool[ $evname ] ) ) {
$args = func_get_args();
array_shift( $args );
foreach( $this->eventPool[ $evname ] as $cb ) {



if( ($ret = call_user_func_array( $cb , $args )) === false ) 
break;
$results[] = $ret;
}
}
return $results;
}





public function clear()
{

$this->eventPool = array();
}





static function getInstance()
{
static $instance;
return $instance ? $instance : $instance = new static;
}

}
<?php 
namespace Universal\Requirement;

use Exception;

class RequirePhpException extends Exception {}
class RequireExtensionException extends Exception {} 
class RequireFunctionException extends Exception {}
class RequireClassException extends Exception {}




















class Requirement
{






function php($version)
{
if( version_compare( phpversion() , $version ) < 0 ) {
throw new RequirePhpException( "PHP Version $version is required." );
}
return true;
}





function extensions()
{
$extensions = func_get_args();
foreach( $extensions as $extensionName ) {
if( ! extension_loaded( $extensionName ) )
throw new RequireExtensionException( "Extension $extensionName is required" );
}
return true;
}




function functions()
{
$functions = func_get_args();
foreach( $functions as $function ) {
if( ! function_exists( $function ) )
throw new RequireFunctionException( "Function $function is required" );
}
return true;
}





function classes()
{
$classes = func_get_args();
foreach( $classes as $class ) {
if( ! class_exists( $class ) )
throw new RequireClassException( "Class $class is required" );
}
return true;
}

}


<?php
namespace Universal\Exception;
use Universal\Exception\UploadException;

class UploadedFileMoveFailException extends UploadException
{
}






<?php
namespace Universal\Exception;
use Universal\Exception\UploadException;

class InvalidUploadFileException extends UploadException
{
}



<?php
namespace Universal\Exception;
use Universal\Exception\UploadException;

class UploadErrorException extends UploadException
{
}






<?php
namespace Universal\Exception;
use RuntimeException;

class UploadException extends RuntimeException
{
protected $file = array();

public function __construct(array $filestash = array(), $message, $code = 0, $previous = null) {
$this->file = $filestash;
parent::__construct($message, $code, $previous);
}













}




<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://phpdox.de/config" silent="false">
    <project name="Universal" source="src" workdir="build/phpdox">
        <collector publiconly="false">
            <include mask="*.php" />
            <exclude mask="*Autoload.php" />
        </collector>

        <generator output="build">
            <build engine="html" enabled="true" output="api"/>
            <build engine="graph" enabled="true" output="graph">
                <dot executable="/usr/bin/dot" render="true" format="png" />
            </build>
        </generator>
    </project>
</phpdox>
Steps = PHPUnit, BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
<?xml version="1.0"?>
<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.10" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0               http://pear.php.net/dtd/tasks-1.0.xsd               http://pear.php.net/dtd/package-2.0               http://pear.php.net/dtd/package-2.0.xsd">
  <name>Universal</name>
  <channel>pear.corneltek.com</channel>
  <summary>Universal PHP Library</summary>
  <description>Universal PHP Library</description>
  <lead>
    <name>Yo-An Lin</name>
    <user/>
    <email>cornelius.howl@gmail.com</email>
    <active>yes</active>
  </lead>
  <date>2012-10-20</date>
  <time>00:22:47</time>
  <version>
    <release>1.3.1</release>
    <api>1.3.1</api>
  </version>
  <stability>
    <release>stable</release>
    <api>stable</api>
  </stability>
  <license>PHP</license>
  <notes>-</notes>
  <contents>
    <dir name="/">
      <file name="tests/bootstrap.php" role="test" md5sum="bbba1757577fcdde93c35ec0143b7a53"/>
      <file name="tests/data/cat.jpg" role="test" md5sum="8ac0c103985355e168a8a82ae0aa6c02"/>
      <file name="tests/data/cat.txt" role="test" md5sum="cae78661f93d71cb9c8063d20eb49614"/>
      <file name="tests/data/cat2.txt" role="test" md5sum="2feb58ce968973263c41aa937529bc5b"/>
      <file name="tests/helpers.php" role="test" md5sum="b5e0733acd23bf976409fbe22191062f"/>
      <file name="tests/lib/Foo/Bar.php" role="test" md5sum="5f8f23b743db5afaeffc09002c2913eb"/>
      <file name="tests/lib/Foo/Foo.php" role="test" md5sum="c0de68180ed4c4d58791dfcf50b72da3"/>
      <file name="tests/Universal/ClassLoader/BasePathClassLoaderTest.php" role="test" md5sum="a16187aac04bfd9c9cc7b1e35bd6e396"/>
      <file name="tests/Universal/Container/ObjectContainerTest.php" role="test" md5sum="eae22a9b5bca27ac7cce76c66012be21"/>
      <file name="tests/Universal/Event/PhpEventTest.php" role="test" md5sum="66b4e6a331c81a42a50c16dd04b50a18"/>
      <file name="tests/Universal/Http/CookieTest.php" role="test" md5sum="9437019ee969e96e1d919fb520040315"/>
      <file name="tests/Universal/Http/FilesParameterTest.php" role="test" md5sum="1a478a204ad3420a4730d813391ee321"/>
      <file name="tests/Universal/Http/HttpResponseTest.php" role="test" md5sum="68b6b54cd1977475871eb0c12863ad21"/>
      <file name="tests/Universal/Requirement/RequirementTest.php" role="test" md5sum="ae823109f36b73a103cf20de49b2bc86"/>
      <file name="tests/UniversalClassLoader/SplClassLoaderTest.php" role="test" md5sum="ce71c53629c0b5f8098fb54ba23dd9f6"/>
      <file name="src/Universal/ClassLoader/ApcClassLoader.php" role="php" md5sum="adc0e3c635ff84737c5da1d1fefd9473"/>
      <file name="src/Universal/ClassLoader/BasePathClassLoader.php" role="php" md5sum="04e696852d93857b388e7fcc28401594"/>
      <file name="src/Universal/ClassLoader/BytecodeClassLoader.php" role="php" md5sum="f31ffb9b57d5453de621f0b8a6b29686"/>
      <file name="src/Universal/ClassLoader/PathIncluder.php" role="php" md5sum="dc8c2c90c8ae9e87fa78f776a4b7f508"/>
      <file name="src/Universal/ClassLoader/SplClassLoader.php" role="php" md5sum="617f0811a259a2986a5148a541a18f57"/>
      <file name="src/Universal/Container/ObjectContainer.php" role="php" md5sum="aed4a79e95e1e3952fb55cfb54a9e106"/>
      <file name="src/Universal/Event/PhpEvent.php" role="php" md5sum="02e646f2ea2b87c1cdbf0fa9c6e292e4"/>
      <file name="src/Universal/FileSystem/PathUtils.php" role="php" md5sum="91c0c341683b82f7997363fee165a3bb"/>
      <file name="src/Universal/Http/Cookie.php" role="php" md5sum="7d8d76ec1f505a73042c5c37b25dc463"/>
      <file name="src/Universal/Http/File.php" role="php" md5sum="a6317b8b0d08018446a15c00223dc2fb"/>
      <file name="src/Universal/Http/FilesParameter.php" role="php" md5sum="84b0bc73cea3f558ca802a42701ba185"/>
      <file name="src/Universal/Http/HttpRequest.php" role="php" md5sum="9729a986980e03fd90ff03bd61217909"/>
      <file name="src/Universal/Http/HttpResponse.php" role="php" md5sum="a129d6ddbd0837bf6e58459842821efc"/>
      <file name="src/Universal/Http/Parameter.php" role="php" md5sum="4715fa1f1998b0ec0f12ba2bb52cf21a"/>
      <file name="src/Universal/Http/PutHandle.php" role="php" md5sum="b689e8c38911d88802b96eeffc70da99"/>
      <file name="src/Universal/Http/StreamResponse.php" role="php" md5sum="ac18b31f078ab62c48da795a93474a8e"/>
      <file name="src/Universal/Requirement/Requirement.php" role="php" md5sum="d4994ed4847e02d4af06b9a542d384c7"/>
      <file name="Changes.md" role="doc" md5sum="32950b0efe3160809c7a669aaeb67d4e"/>
      <file name="README.md" role="doc" md5sum="26534a78b2b912c027544bda387e3940"/>
      <file name="REF.md" role="doc" md5sum="ad778c0a94993cf81fd02d03eef3952a"/>
    </dir>
  </contents>
  <dependencies>
    <required>
      <php>
        <min>5.3</min>
      </php>
      <pearinstaller>
        <min>1.4</min>
      </pearinstaller>
    </required>
  </dependencies>
  <phprelease>
    <filelist>
      <install name="tests/bootstrap.php" as="bootstrap.php"/>
      <install name="tests/data/cat.jpg" as="data/cat.jpg"/>
      <install name="tests/data/cat.txt" as="data/cat.txt"/>
      <install name="tests/data/cat2.txt" as="data/cat2.txt"/>
      <install name="tests/helpers.php" as="helpers.php"/>
      <install name="tests/lib/Foo/Bar.php" as="lib/Foo/Bar.php"/>
      <install name="tests/lib/Foo/Foo.php" as="lib/Foo/Foo.php"/>
      <install name="tests/Universal/ClassLoader/BasePathClassLoaderTest.php" as="Universal/ClassLoader/BasePathClassLoaderTest.php"/>
      <install name="tests/Universal/Container/ObjectContainerTest.php" as="Universal/Container/ObjectContainerTest.php"/>
      <install name="tests/Universal/Event/PhpEventTest.php" as="Universal/Event/PhpEventTest.php"/>
      <install name="tests/Universal/Http/CookieTest.php" as="Universal/Http/CookieTest.php"/>
      <install name="tests/Universal/Http/FilesParameterTest.php" as="Universal/Http/FilesParameterTest.php"/>
      <install name="tests/Universal/Http/HttpResponseTest.php" as="Universal/Http/HttpResponseTest.php"/>
      <install name="tests/Universal/Requirement/RequirementTest.php" as="Universal/Requirement/RequirementTest.php"/>
      <install name="tests/UniversalClassLoader/SplClassLoaderTest.php" as="UniversalClassLoader/SplClassLoaderTest.php"/>
      <install name="src/Universal/ClassLoader/ApcClassLoader.php" as="Universal/ClassLoader/ApcClassLoader.php"/>
      <install name="src/Universal/ClassLoader/BasePathClassLoader.php" as="Universal/ClassLoader/BasePathClassLoader.php"/>
      <install name="src/Universal/ClassLoader/BytecodeClassLoader.php" as="Universal/ClassLoader/BytecodeClassLoader.php"/>
      <install name="src/Universal/ClassLoader/PathIncluder.php" as="Universal/ClassLoader/PathIncluder.php"/>
      <install name="src/Universal/ClassLoader/SplClassLoader.php" as="Universal/ClassLoader/SplClassLoader.php"/>
      <install name="src/Universal/Container/ObjectContainer.php" as="Universal/Container/ObjectContainer.php"/>
      <install name="src/Universal/Event/PhpEvent.php" as="Universal/Event/PhpEvent.php"/>
      <install name="src/Universal/FileSystem/PathUtils.php" as="Universal/FileSystem/PathUtils.php"/>
      <install name="src/Universal/Http/Cookie.php" as="Universal/Http/Cookie.php"/>
      <install name="src/Universal/Http/File.php" as="Universal/Http/File.php"/>
      <install name="src/Universal/Http/FilesParameter.php" as="Universal/Http/FilesParameter.php"/>
      <install name="src/Universal/Http/HttpRequest.php" as="Universal/Http/HttpRequest.php"/>
      <install name="src/Universal/Http/HttpResponse.php" as="Universal/Http/HttpResponse.php"/>
      <install name="src/Universal/Http/Parameter.php" as="Universal/Http/Parameter.php"/>
      <install name="src/Universal/Http/PutHandle.php" as="Universal/Http/PutHandle.php"/>
      <install name="src/Universal/Http/StreamResponse.php" as="Universal/Http/StreamResponse.php"/>
      <install name="src/Universal/Requirement/Requirement.php" as="Universal/Requirement/Requirement.php"/>
      <install name="Changes.md" as="Changes.md"/>
      <install name="README.md" as="README.md"/>
      <install name="REF.md" as="REF.md"/>
    </filelist>
  </phprelease>
</package>
[package]
name = Universal
desc = Universal PHP Library
version = 1.3.1
author = Yo-An Lin <cornelius.howl@gmail.com>
channel = pear.corneltek.com
stability = stable

[roles]
*.md = doc
example = data
The MIT License (MIT)

Copyright (C) 2014 Yo-An Lin <yoanlin93@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php
namespace CodeGen;




class Argument implements Renderable
{
protected $name;

protected $default;

public function __construct($name, $default = NULL)
{
$this->name = $name;
$this->default = $default;
}

public function getName()
{
return $this->name;
}

public function getDefault()
{
return $this->default;
}

public function render(array $args = array())
{
$code = $this->name;
if ($this->default) {
$code .= ' = ' . VariableDeflator::deflate($this->default);
}
return $code;
}

}




<?php
namespace CodeGen;

class ClassName implements Renderable
{
public $name;

public $namespace;

public $root = false;

public function __construct($className)
{
if ($className[0] === '\\') {
$this->root = true;
$className = substr($className, 1);
}


if (strpos($className, '\\') !== false) {
$p = explode('\\', ltrim($className, '\\'));
$this->name = end($p);
$this->namespace = implode('\\', array_splice($p, 0, count($p) - 1));
} else {
$this->name = $className;
}
}





public function getName()
{
return $this->name;
}


public function setNamespace($ns)
{
$this->namespace = $ns;
return $this;
}






public function inNamespace()
{
return $this->namespace ? true : false;
}






public function getNamespaceName()
{
return $this->namespace;
}


public function getFullName()
{
if ($this->namespace) {
return ($this->root ? '\\' : '') . $this->namespace . '\\' . $this->name;
} else {
return ($this->root ? '\\' : '') . $this->name;
}
}

public function render(array $args = array())
{
return $this->getFullName();
}

public function __toString()
{
return $this->render();
}
}

<?php
namespace CodeGen;

class ClassStaticVariable extends ClassProperty implements Renderable
{




public function render(array $args = array())
{
return Indenter::indent($this->indentLevel) . $this->scope . ' static $' . $this->name . ' = ' . var_export($this->value, true) . ';';
}

public function __toString()
{
return $this->render();
}
}

<?php
namespace CodeGen\Frameworks\PHPUnit;

use CodeGen\ClassMethod;
use CodeGen\UserClass;
use Doctrine\Common\Inflector\Inflector;

class PHPUnitFrameworkTestCase extends UserClass
{
public function __construct($title)
{
$class = Inflector::classify(preg_replace('/\W+/', ' ', $title));
parent::__construct($class);
$this->extendClass('PHPUnit_Framework_TestCase', true);
}

public function addTest($testName)
{
$methodName = 'test' . Inflector::classify($testName);
$testMethod = new ClassMethod($methodName, array(), array());
$testMethod->setScope('public');
$this->methods[] = $testMethod;
return $testMethod;
}
}




<?php
namespace CodeGen\Frameworks\PHPUnit;

use CodeGen\Expr\SelfMethodCall;
use CodeGen\Statement\Statement;

function push_if($array, $element)
{
if ($element) {
$array[] = $element;
}
return $array;
}

class Assertions
{
static public function assertEquals($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertEquals', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertRegExp($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertRegExp', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertStringMatchesFormat($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertStringMatchesFormat', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertStringMatchesFormatFile($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertStringMatchesFormatFile', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertStringEqualsFile($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertStringEqualsFile', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertStringStartsWith($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertStringStartsWith', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertStringEndsWith($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertStringEndsWith', push_if(array($expected, $actual), $message));
return new Statement($expr);
}


static public function assertSame($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertSame', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertNull($actual, $message = '')
{
$expr = new SelfMethodCall('assertNull', push_if(array($actual), $message));
return new Statement($expr);
}

static public function assertNotEmpty($actual, $message = '')
{
$expr = new SelfMethodCall('assertNotEmpty', push_if(array($actual), $message));
return new Statement($expr);
}

static public function assertEmpty($actual, $message = '')
{
$expr = new SelfMethodCall('assertEmpty', push_if(array($actual), $message));
return new Statement($expr);
}

static public function assertArrayHasKey($key, array $array, $message = '')
{
$expr = new SelfMethodCall('assertArrayHasKey', push_if(array($key, $array), $message));
return new Statement($expr);
}

static public function assertClassHasAttribute($attribute, $class, $message = '')
{
$expr = new SelfMethodCall('assertClassHasAttribute', push_if(array($attribute, $class), $message));
return new Statement($expr);
}

static public function assertClassHasStaticAttribute($attribute, $class, $message = '')
{
$expr = new SelfMethodCall('assertClassHasStaticAttribute', push_if(array($attribute, $class), $message));
return new Statement($expr);
}

static public function assertContains($element, $array, $message = '')
{
$expr = new SelfMethodCall('assertContains', push_if(array($element, $array), $message));
return new Statement($expr);
}

static public function assertContainsOnly($element, $array, $message = '')
{
$expr = new SelfMethodCall('assertContainsOnly', push_if(array($element, $array), $message));
return new Statement($expr);
}

static public function assertCount($count, $array, $message = '')
{
$expr = new SelfMethodCall('assertCount', push_if(array($count, $array), $message));
return new Statement($expr);
}

static public function assertTrue($val, $message = '')
{
$expr = new SelfMethodCall('assertTrue', push_if(array($val), $message));
return new Statement($expr);
}

static public function assertFalse($val, $message = '')
{
$expr = new SelfMethodCall('assertFalse', push_if(array($val), $message));
return new Statement($expr);
}

static public function assertFileEquals($fileExpected, $fileActual, $message = '')
{
$expr = new SelfMethodCall('assertFileEquals', push_if(array($fileExpected, $fileActual), $message));
return new Statement($expr);
}

static public function assertJsonFileEqualsJsonFile($fileExpected, $fileActual, $message = '')
{
$expr = new SelfMethodCall('assertJsonFileEqualsJsonFile', push_if(array($fileExpected, $fileActual), $message));
return new Statement($expr);
}

static public function assertFileExists($fileActual, $message = '')
{
$expr = new SelfMethodCall('assertFileExists', push_if(array($fileActual), $message));
return new Statement($expr);
}

static public function assertGreaterThan($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertGreaterThan', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertGreaterThanOrEqual($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertGreaterThanOrEqual', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertLessThan($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertLessThan', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertLessThanOrEqual($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertLessThanOrEqual', push_if(array($expected, $actual), $message));
return new Statement($expr);
}


static public function assertInstanceOf($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertInstanceOf', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

static public function assertInternalType($expected, $actual, $message = '')
{
$expr = new SelfMethodCall('assertInternalType', push_if(array($expected, $actual), $message));
return new Statement($expr);
}

}



<?php
namespace CodeGen;




class BracketedBlock extends Block
{
public function render(array $args = array())
{
$tab = Indenter::indent($this->indentLevel);
$this->increaseIndentLevel(); 
$body = '';
$body .= $tab . "{\n";
$body .= parent::render($args);
$body .= $tab . "}\n";
return $body;
}

}




<?php
namespace CodeGen\Generator;

use CodeGen\UserClass;





class ArrayAccessGenerator
{
public function __construct()
{

}







public function generate($arrayPropertyName, UserClass $class)
{
$class->implementInterface('ArrayAccess');


$class->addMethod('public', 'offsetSet', array('$key', '$val'), array(
"\$this->{$arrayPropertyName}[\$key] = \$val;"
));
$class->addMethod('public', 'offsetGet', array('$key'), array(
"return \$this->{$arrayPropertyName}[\$key];"
));
$class->addMethod('public', 'offsetExists', array('$key'), array(
"return isset(\$this->{$arrayPropertyName}[\$key]);",
));
$class->addMethod('public', 'offsetUnset', array('$key'), array(
"unsetset(\$this->{$arrayPropertyName}[\$key]);",
));
return $class;
}
}




<?php
namespace CodeGen\Generator;

use CodeGen\UserClass;
use ReflectionObject;
use ReflectionProperty;




class AppClassGenerator
{
protected $options = array();

public function __construct(array $options = array())
{
$this->options = array_merge(array(
'namespace' => null,
'prefix' => 'App',
'reflection_property_filter' => ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED,
'property_filter' => null,
), $options);
}


protected function isValueExportable($value)
{
return is_array($value) || is_scalar($value) || is_null($value);
}


public function generate($object, UserClass $userClass = null)
{
$reflObject = new ReflectionObject($object);

if (!$userClass) {
$className = $this->options['prefix'] . $reflObject->getShortName();
if (!$this->options['namespace'] && $reflObject->inNamespace()) {
$namespace = $reflObject->getNamespaceName();
$className = '\\' . $namespace . '\\' . $className;
} else {
$className = $this->options['namespace'] . '\\' . $className;
}
$userClass = new UserClass($className);
$userClass->extendClass('\\' . $reflObject->getName(), false);
}

$properties = $reflObject->getProperties($this->options['reflection_property_filter']);
$propertyFilter = $this->options['property_filter'];
foreach ($properties as $reflProperty) {
$reflProperty->setAccessible(true);

if ($propertyFilter && !$propertyFilter($reflProperty)) {
continue;
}

$propertyName = $reflProperty->getName();
$propertyValue = $reflProperty->getValue($object);




if (!$this->isValueExportable($propertyValue)) {
continue;
}

if ($reflProperty->isPublic()) {
$userClass->addPublicProperty($propertyName, $propertyValue);
} else if ($reflProperty->isProtected()) {
$userClass->addProtectedProperty($propertyName, $propertyValue);
}

}
return $userClass;
}
}




<?php
namespace CodeGen;

trait Annotator
{




public $comment;

public function annotate($comment)
{
$lines = explode("\n", $comment);
if (count($lines) === 0) {
return;
}
if (count($lines) == 1) {
$this->comment = new Comment($comment);
} else {
$this->comment = new CommentBlock($comment);
}
}

public function renderAnnotate(array $args = array())
{
return $this->comment->render($args) . "\n";
}

}



<?php
namespace CodeGen;

class Raw
{



protected $code;

public function __construct($code)
{
$this->code = $code;
}

public function __toString()
{
return (string)$this->code;
}
}




<?php
namespace CodeGen;

interface Renderable
{
public function render(array $args = array());
}


<?php
namespace CodeGen;

class LicenseBlock extends CommentBlock
{

const GPL = 'Copyright (C) {{year}} {{holder|raw}}

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>. ';


const MIT = 'Copyright (c) {{year}} {{holder|raw}}

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
';
const BSD3 = 'Copyright (c) {{year}}, {{holder|raw}} All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.';

public function __construct($license, $year, $holder)
{
$license = strtolower($license);
$content = '';
switch ($license) {
case 'gpl':
$content = self::GPL;
break;
case 'mit':
$content = self::MIT;
break;
case 'bsd-3':
$content = self::BSD3;
break;
}
$content = Utils::renderStringTemplate($content, array(
'year' => $year,
'holder' => $holder,
));
parent::__construct(explode("\n", $content));
}

}




<?php
namespace CodeGen;

use Exception;

class UserClass implements Renderable
{




public $class;

public $extends;

public $interfaces = array();

public $uses = array();

public $methods = array();

public $consts = array();

public $properties = array();

public $staticVars = array();





public $final;




public $traits = array();

public $usedClasses = array();











public function __construct($className)
{
$this->setClass($className);
}

public function setClass($className)
{
$this->class = new ClassName($className);
}

public function in($namespace)
{
$this->class->setNamespace($namespace);
return $this;
}


public function useClass($className, $as = null)
{
if ($as) {
if (isset($this->usedClasses[$as])) {
return;
}
$this->usedClasses[$as] = $className;
} else {
if (isset($this->usedClasses[$className])) {
return;
}
$this->usedClasses[$className] = $className;
}
$this->uses[] = new UseClass($className, $as);
}







public function extendClass($className, $useAlias = true)
{
if ($className[0] === '\\' && $useAlias) {
$className = ltrim($className, '\\');
$this->useClass($className);

$_p = explode('\\', $className);
$shortClassName = end($_p);
$this->extends = new ClassName($shortClassName);
} else {
$this->extends = new ClassName($className);
}
}

public function implementInterface($interface)
{
$class = new ClassName($interface);
$this->useClass($interface);
$this->interfaces[] = $class;
}

public function implementClass($className)
{
$class = new ClassName($className);
$this->useClass($className);
$this->interfaces[] = $class;
}

public function addMethod($scope, $methodName, array $arguments = array(), $body = array(), array $bodyArguments = array())
{
$method = new ClassMethod($methodName, $arguments, $body, $bodyArguments);
$method->setScope($scope);
$this->methods[$methodName] = $method;
return $method;
}

public function addMethodObject(ClassMethod $method)
{
$this->methods[$method->getName()] = $method;
}

public function addConst($name, $value)
{
$this->consts[] = new ClassConst($name, $value);
}

public function addConstObject(ClassConst $const)
{
$this->consts[] = $const;
}

public function addConsts($array)
{
foreach ($array as $name => $value) {
$this->consts[] = new ClassConst($name, $value);
}
}

public function addProperty($name, $value, $scope = 'public')
{
$this->properties[] = new ClassProperty($name, $value, $scope);
return $this;
}

public function addPublicProperty($name, $value)
{
return $this->addProperty($name, $value, 'public');
}

public function addProtectedProperty($name, $value)
{
return $this->addProperty($name, $value, 'protected');
}

public function addPrivateProperty($name, $value)
{
return $this->addProperty($name, $value, 'private');
}


public function addStaticVar($name, $value, $scope = 'public')
{
$this->staticVars[] = new ClassStaticVariable($name, $value, $scope);
return $this;
}







public function getShortClassName()
{
return $this->class->getName();
}

public function getClassName()
{
return $this->class->getFullName();
}

public function render(array $args = array())
{
$lines = array(); 
if ($this->class->namespace) {
$lines[] = 'namespace ' . $this->class->namespace . ';';
}


if ($this->uses) {
foreach ($this->uses as $u) {

if (!$this->class->namespace && count($u->getComponents()) == 1) {
continue;
}
$lines[] = $u->render();
}
}

$classDeclare = ($this->final ? 'final ' : '')
. 'class ' . $this->class->name
;

$lines[] = $classDeclare;
if ($this->extends) {
$lines[] = Indenter::indent(1) . 'extends ' . $this->extends->render();
}
if ($this->interfaces) {
$lines[] = Indenter::indent(1) . 'implements ' . implode(', ', array_map(function ($class) {
return $class->name;
}, $this->interfaces));
}

$block = new BracketedBlock;
foreach ($this->traits as $trait) {
$block[] = $trait;
}

foreach ($this->consts as $const) {
$block[] = $const;
}

foreach ($this->staticVars as $var) {
$block[] = $var;
}

foreach ($this->properties as $property) {
$block[] = $property;
}

foreach ($this->methods as $method) {
$method->getBlock()->setIndentLevel(1);
$block[] = $method;
}
$lines[] = $block->render($args);
return implode("\n", $lines);
}

public function getPsr0ClassPath()
{
return str_replace('\\', DIRECTORY_SEPARATOR, $this->class->getFullName()) . '.php';
}

public function makeFinal()
{
$this->final = true;
}

public function requireAt($path, array $args = array())
{
$code = "<?php\n" . $this->render($args);
if (file_put_contents($path, $code) === false) {
return false;
}
require $path;
return $path;

}

public function generateAt($path, array $args = array())
{
$code = "<?php\n" . $this->render($args);
if (file_put_contents($path, $code) === false) {
return false;
}
return $path;
}

public function generatePsr4ClassUnder($directory, array $args = array())
{
$className = $this->class->name;


if (is_array($directory)) {
$fullClassName = $this->class->getFullName();
foreach ($directory as $nsprefix => $nsdir) {

if (strpos($fullClassName, $nsprefix) === 0) {
$className = ltrim(substr($fullClassName, strlen($nsprefix)), '\\');
$directory = rtrim($nsdir, DIRECTORY_SEPARATOR);
continue;
}
}
if (is_array($directory)) {
throw new Exception("Can't translate class name into corresponding directory.");
}
}

$className = str_replace('\\', DIRECTORY_SEPARATOR, $className);


$code = "<?php\n" . $this->render($args);
$path = $directory . DIRECTORY_SEPARATOR . $className . '.php';
if ($dir = dirname($path)) {
if (!file_exists($dir)) {
mkdir($dir, 0755, true);
}
}
if (file_put_contents($path, $code) === false) {
return false;
}
return $path;
}








public function generatePsr0ClassUnder($directory, array $args = array())
{
$code = "<?php\n" . $this->render($args);
$classPath = $this->getPsr0ClassPath();
$path = $directory . DIRECTORY_SEPARATOR . $classPath;
if ($dir = dirname($path)) {
if (!file_exists($dir)) {
mkdir($dir, 0755, true);
}
}
if (file_put_contents($path, $code) === false) {
return false;
}
return $path;
}






public function getSplFilePath()
{
return str_replace('\\', '_', $this->class->getFullName());
}

public function addTrait(ClassTrait $trait)
{
$this->traits[] = $trait;
}

public function useTrait($class)
{
$classes = func_get_args();
$self = $this;
$classes = array_map(function ($fullClassName) use ($self) {

$p = explode('\\', ltrim($fullClassName, '\\'));
$className = end($p);
if (count($p) > 1) {
$this->useClass($fullClassName);
}
return $className;
}, $classes);
$trait = new ClassTrait($classes);
$this->addTrait($trait);
return $trait;
}
}

<?php
namespace CodeGen;

use ArrayAccess;

class ClassMethod extends UserFunction implements Renderable, ArrayAccess
{
public $scope = 'public';

public function setScope($scope)
{
$this->scope = $scope;
}





public function render(array $args = array())
{
$block = $this->getBlock();
$block->setIndentLevel($this->indentLevel);
return Indenter::indent($this->indentLevel) . $this->scope . ' function ' . $this->name . '(' . $this->renderArguments() . ")\n"
. $block->render($args);
}

public function __toString()
{
return $this->render();
}

public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->block[] = $value;
} else {
$this->block[$offset] = $value;
}
}

public function offsetExists($offset)
{
return isset($this->block[$offset]);
}

public function offsetGet($offset)
{
return $this->block[$offset];
}

public function offsetUnset($offset)
{
unset($this->block[$offset]);
}


}

<?php
namespace CodeGen;

use ArrayAccess;
use ArrayIterator;
use CodeGen\Exception\InvalidArgumentTypeException;
use IteratorAggregate;










class Block implements IteratorAggregate, ArrayAccess, Renderable
{
public $lines = array();

public $args = array();

public function __construct(array $lines = array())
{
$this->lines = $lines;
}




public $indentLevel = 0;

public function setDefaultArguments(array $args)
{
$this->args = $args;
return $this;
}

public function setLines(array $lines)
{
$this->lines = $lines;
return $this;
}




public function setBody($text)
{
if (is_string($text)) {
$this->lines = explode("\n", $text);
} elseif (is_array($text)) {
$this->lines = $text;
} else {
throw new InvalidArgumentTypeException('Invalid body type', $text, array('string', 'array'));
}
}

public function appendRenderable(Renderable $obj)
{
$this->lines[] = $obj;
}

public function appendLine($line)
{
$this->lines[] = $line;
}

public function increaseIndentLevel()
{
$this->indentLevel++;
return $this;
}

public function decreaseIndentLevel()
{
$this->indentLevel--;
return $this;
}

public function indent()
{
$this->indentLevel++;
}

public function unindent()
{
$this->indentLevel--;
}

public function splice($from, $length, array $replacement = array())
{
return array_splice($this->lines, $from, $length, $replacement);
}


public function setIndentLevel($indent)
{
$this->indentLevel = $indent;
}

public function render(array $args = array())
{
$tab = Indenter::indent($this->indentLevel);
$body = '';
foreach ($this->lines as $line) {
if (is_string($line)) {
$body .= $tab . $line . "\n";
} else if ($line instanceof Renderable) {
$subbody = rtrim($line->render()); 
$sublines = explode("\n", $subbody);
foreach ($sublines as $subline) {
$body .= $tab . $subline . "\n";
}
} else {

throw new InvalidArgumentTypeException('Unsupported line object type', $line, array('string', 'Renderable'));
}
}
return Utils::renderStringTemplate($body, array_merge($this->args, $args));
}


public function getIterator()
{
return new ArrayIterator($this->lines);
}


public function offsetSet($key, $value)
{
if ($key) {
$this->lines[$key] = $value;
} else {
$this->lines[] = $value;
}
}

public function offsetExists($key)
{
return isset($this->lines[$key]);
}

public function offsetGet($key)
{
return $this->lines[$key];
}

public function offsetUnset($key)
{
unset($this->lines[$key]);
}


}




<?php
namespace CodeGen;

use CodeGen\Statement\Statement;

class UseClass extends Statement implements Renderable
{
public $as;
public $class;

public function __construct($class, $as = null)
{
$this->class = ltrim($class, '\\');
$this->as = $as ? ltrim($as, '\\') : null;
}

public function getComponents()
{
return explode('\\', $this->class);
}

public function render(array $args = array())
{
$code = 'use ' . $this->class;
if ($this->as) {
$code .= ' as ' . $this->as;
}
return $code . ';';
}
}
<?php
namespace CodeGen;

use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;




class ArgumentList implements Renderable, ArrayAccess, IteratorAggregate
{
protected $arguments;

public function __construct(array $arguments = array())
{
$this->arguments = $arguments;
}

public function setArguments(array $args)
{
$this->arguments = $args;
}

public function add($arg)
{
$this->arguments[] = $arg;
return $this;
}


public function offsetExists($offset)
{
return isset($this->arguments[$offset]);
}

public function offsetGet($offset)
{
return $this->arguments[$offset];
}

public function offsetUnset($offset)
{
unset($this->arguments[$offset]);
}

public function offsetSet($offset, $value)
{
if ($offset) {
$this->arguments[$offset] = $value;
} else {
$this->arguments[] = $value;
}
}

public function getIterator()
{
return new ArrayIterator($this->arguments);
}

public function render(array $args = array())
{
$strs = array();
foreach ($this->arguments as $arg) {
$strs[] = VariableDeflator::deflate($arg);
}
return implode(', ', $strs);
}
}

<?php
namespace CodeGen;

use Exception;

class CommentBlock extends Block implements Renderable
{
public function render(array $args = array())
{
$tab = Indenter::indent($this->indentLevel);
$body = '';

$body .= $tab . "/**\n";

foreach ($this->lines as $line) {
if (is_string($line)) {
$body .= $tab . ' * ' . $line . "\n";
} else if ($line instanceof Renderable) {
$subbody = rtrim($line->render()); 
$sublines = explode("\n", $subbody);
foreach ($sublines as $subline) {
$body .= $tab . ' * ' . $subline . "\n";
}
} else {
throw new Exception('Unsupported line object.');
}
}
$body .= " */\n";
return Utils::renderStringTemplate($body, array_merge($this->args, $args));
}

}




<?php
namespace CodeGen;

interface Exportable
{
public function __get_state();
}




<?php
namespace CodeGen;

class Variable implements Renderable
{
protected $name;

protected $templateApply = false;

protected $templateArgs = array();

public function __construct($name)
{
$this->name = $name;
}

public function templateApply(array $templateArgs = array())
{
$this->templateApply = true;
$this->templateArgs = $templateArgs;
}

static public function template($name, array $args = array())
{
$var = new self($name);
$var->templateApply($args);
return $var;
}

public function render(array $args = array())
{
if ($this->templateApply) {
return Utils::renderStringTemplate($this->name, array_merge($this->templateArgs, $args));
}
return $this->name;
}
}





<?php
namespace CodeGen;

class Constant implements Renderable
{
protected $val;

public function __construct($val)
{
$this->val = $val;
}

public function render(array $args = array())
{
if (is_scalar($this->val)) {
return var_export($this->val, true);
}
return $this->val;
}
}





<?php
namespace CodeGen;

use CodeGen\Statement\Statement;


















class ClassTrait extends Statement implements Renderable
{
public $classes = array();

public $definitions = array();

public function __construct(array $classes)
{
$this->classes = $classes;
}

public function useInsteadOf($aMethod, $b)
{
$this->definitions[] = "$aMethod insteadof $b;";
return $this;
}

public function useAs($aMethod, $methodB)
{
$this->definitions[] = "$aMethod as $methodB;";
return $this;
}

public function render(array $args = array())
{
$out = Indenter::indent($this->indentLevel) . 'use ' . implode(', ', $this->classes);
if (0 === count($this->definitions)) {
$out .= ';';
} else {
$block = new BracketedBlock;
foreach ($this->definitions as $def) {
$block[] = $def;
}
$out .= $block->render($args);
}
return $out;
}
}



<?php
namespace CodeGen;

use LogicException;

class VariableDeflator
{
static public function deflate($arg)
{

if (is_string($arg)) {
if ($arg[0] === '$') {
return $arg;
}
return var_export($arg, true);
} else if ($arg instanceof Renderable) {
return $arg->render(array());
} else if ($arg instanceof Raw) {
return (string)$arg;
} else if ($arg instanceof Exportable || method_exists($arg, '__get_state')) {
$class = get_class($arg);
return $class . '::__set_state(' . var_export($arg->__get_state(), true) . ')';
} else if (is_array($arg) || is_scalar($arg) || method_exists($arg, '__set_state')) {
return var_export($arg, true);
} else if ($arg === null) {
return '';
} else {
throw new LogicException('Can\'t deflate variable');
}
}
}




<?php
namespace CodeGen;

use CodeGen\Statement\Statement;

class ClassConst extends Statement implements Renderable
{



public $name;

public $value;

public function __construct($name, $value)
{
$this->name = $name;
$this->value = $value;
}

public function render(array $args = array())
{
return Indenter::indent($this->indentLevel) . 'const ' . $this->name . ' = ' . var_export($this->value, true) . ';';
}

public function __toString()
{
return $this->render();
}

}

<?php
namespace CodeGen\Expr;

class NewObjectExpr extends NewObject
{
}

<?php
namespace CodeGen\Expr;




class SelfMethodCallExpr extends SelfMethodCall
{
}

<?php
namespace CodeGen\Expr;

use CodeGen\Renderable;
use CodeGen\Variable;

class ObjectProperty implements Renderable
{



public $objectName;
public $property;


protected $op = '->';

public function __construct($objectName, $property)
{
$this->objectName = $objectName;
$this->property = $property;
}

public function render(array $args = array())
{
$out = '';

if ($this->objectName instanceof Renderable) {
$out .= $this->objectName->render($args);
} else {
$out .= $this->objectName;
}
$out .= $this->op . $this->property;
return $out;
}

public function __toString()
{
return $this->render();
}

}



<?php
namespace CodeGen\Expr;




class SelfMethodCall extends MethodCall
{
public function __construct($method = NULL, array $arguments = array())
{
parent::__construct('$this', $method, $arguments);
}
}

<?php
namespace CodeGen\Expr;

use CodeGen\ArgumentList;
use CodeGen\Renderable;
use CodeGen\Variable;

class MethodCall implements Renderable
{



public $objectName;

public $method;

public $arguments;

protected $op = '->';

public function __construct($objectName = '$this', $method = NULL, array $arguments = array())
{
$this->objectName = $objectName;
if ($method) {
$this->method = $method;
}
$this->arguments = new ArgumentList($arguments);
}

public function method($name)
{
$this->method = $name;
return $this;
}

public function setArguments(array $args)
{
$this->arguments = new ArgumentList($args);
}

public function addArgument($arg)
{
$this->arguments[] = $arg;
return $this;
}

public function render(array $args = array())
{
$out = '';

if ($this->objectName instanceof Renderable) {
$out .= $this->objectName->render($args);
} else {
$out .= $this->objectName;
}
$out .= $this->op . $this->method . '(' . $this->arguments->render($args) . ')';
return $out;
}

public function __toString()
{
return $this->render();
}

}



<?php
namespace CodeGen\Expr;

use CodeGen\Renderable;
use CodeGen\VariableDeflator;

class AssignExpr implements Renderable
{

protected $lvalue;

protected $expr;

public function __construct($lvalue, $expr)
{
$this->lvalue = $lvalue;
$this->expr = $expr;
}


public function render(array $args = array())
{
return VariableDeflator::deflate($this->lvalue) . ' = ' . VariableDeflator::deflate($this->expr);
}

}




<?php
namespace CodeGen\Expr;

use CodeGen\ArgumentList;
use CodeGen\Renderable;
use CodeGen\Variable;





class CallExpr implements Renderable
{



public $objectName;

public $method;

public $arguments;

protected $op;

public function __construct($objectName = null, $op = '->', $method, array $arguments = array())
{
$this->objectName = $objectName;
$this->op = $op;
$this->method = $method;
$this->arguments = new ArgumentList($arguments);
}

public function method($method)
{
$this->method = $method;
return $this;
}

public function op($op)
{
$this->op = $op;
return $this;
}

public function setArguments(array $args)
{
$this->arguments = new ArgumentList($args);
}

public function addArgument($arg)
{
$this->arguments[] = $arg;
return $this;
}

public function render(array $args = array())
{
$out = '';
if ($this->objectName) {
if ($this->objectName instanceof Renderable) {
$out .= $this->objectName->render($args);
} else {
$out .= $this->objectName;
}
$out .= $this->op;
}
$out .= $this->method . '(' . $this->arguments->render($args) . ')';
return $out;
}

public function __toString()
{
return $this->render();
}

}



<?php
namespace CodeGen\Expr;

use CodeGen\ArgumentList;
use CodeGen\Renderable;

class StaticMethodCall implements Renderable
{
public $className;

public $method;

public $arguments;

public function __construct($className, $method = NULL, array $arguments = array())
{
$this->className = $className;
if ($method) {
$this->method = $method;
}
$this->arguments = new ArgumentList($arguments);
}

public function method($name)
{
$this->method = $name;
return $this;
}

public function setArguments(array $args)
{
$this->arguments = new ArgumentList($args);
}

public function addArgument($arg)
{
$this->arguments[] = $arg;
return $this;
}

public function render(array $args = array())
{
return $this->className . '::' . $this->method . '(' . $this->arguments->render($args) . ')';
}

public function __toString()
{
return $this->render();
}

}



<?php
namespace CodeGen\Expr;



class MethodCallExpr extends MethodCall
{
}




<?php
namespace CodeGen\Expr;

use CodeGen\ArgumentList;
use CodeGen\Renderable;
use CodeGen\Variable;





class FunctionCall implements Renderable
{



public $function;

public $arguments;

public function __construct($function, array $arguments = array())
{
$this->function = $function;
$this->arguments = new ArgumentList($arguments);
}

public function setArguments(array $args)
{
$this->arguments = new ArgumentList($args);
}

public function addArgument($arg)
{
$this->arguments[] = $arg;
return $this;
}

public function render(array $args = array())
{
return $this->function . '(' . $this->arguments->render($args) . ')';
}

public function __toString()
{
return $this->render();
}

}



<?php
namespace CodeGen\Expr;

use CodeGen\ArgumentList;
use CodeGen\Renderable;

class NewObject implements Renderable
{
public $className;

public $arguments;

public function __construct($className, array $arguments = array())
{
$this->className = $className;
$this->arguments = new ArgumentList($arguments);
}

public function setArguments(array $args)
{
$this->arguments = new ArgumentList($args);
}

public function addArgument($arg)
{
$this->arguments[] = $arg;
return $this;
}

public function render(array $args = array())
{
return 'new ' . $this->className . '(' . $this->arguments->render($args) . ')';
}

public function __toString()
{
return $this->render();
}

}



<?php
namespace CodeGen;

class Indenter
{
static public $expandTab = true;

static public $spaceWidth = 4;





static public function indent($level = 1)
{
if (self::$expandTab) {
$tab = str_repeat(' ', self::$spaceWidth);
return str_repeat($tab, $level);
} else {
return str_repeat("\t", $level);
}

}
}




<?php
namespace CodeGen;

use CodeGen\Statement\Statement;

class ClassProperty extends Statement implements Renderable
{
public $name;
public $scope = 'public';
public $value;

public function __construct($name, $value, $scope = 'public')
{
$this->name = $name;
$this->value = $value;
$this->scope = $scope;
}


public function render(array $args = array())
{
$code = Indenter::indent($this->indentLevel) . $this->scope . ' $' . $this->name;
if ($this->value) {
$code .= ' = ' . var_export($this->value, true);
}
return $code . ';';
}

public function __toString()
{
return $this->render();
}


}

<?php
namespace CodeGen;





abstract class Line implements Renderable
{

public $indentLevel = 0;


public $content;

public function __construct($content = NULL)
{
$this->content = $content;
}

public function setIndentLevel($level)
{
$this->indentLevel = $level;
}

public function increaseIndentLevel()
{
$this->indentLevel++;
}

public function decreaseIndentLevel()
{
$this->indentLevel--;
}

public function render(array $args = array())
{

return $this->content;
}

public function __toString()
{
return $this->render();
}
}



<?php
namespace CodeGen;

class UserFunction extends Block implements Renderable
{
public $name;

public $arguments = array();

public $bodyArguments = array();

public $indentLevel = 0;






public $block;









public function __construct($name, array $arguments = array(), $body = '', array $bodyArguments = array())
{
$this->name = $name;
$this->arguments = $arguments;

$this->block = new BracketedBlock;
if ($body) {
$this->block->setBody($body);
}
if ($bodyArguments) {
$this->block->setDefaultArguments($bodyArguments);
}
}

public function getName()
{
return $this->name;
}

public function setIndentLevel($level)
{
$this->indentLevel = $level;
}

public function increaseIndentLevel()
{
$this->indentLevel++;
}

public function decreaseIndentLevel()
{
$this->indentLevel--;
}


public function setBlock(Block $block)
{
$this->block = $block;
}

public function getBlock()
{
return $this->block;
}

public function setArguments(array $args)
{
$this->arguments = $args;
}

protected function renderArguments()
{
return implode(', ', $this->arguments);
}

public function render(array $args = array())
{
return 'function ' . $this->name . '(' . $this->renderArguments() . ")\n"
. $this->block->render($args);
}

}





<?php
namespace CodeGen\Statement;

use CodeGen\Block;
use CodeGen\Renderable;
use CodeGen\Utils;

class TryCatchStatement extends Block implements Renderable
{



public $tryBlock;



public $catchBlock;



protected $catchClass;



protected $catchClassAlias;

public function __construct($catchClass = '\Exception', $catchClassAlias = '$e', $tryBlock = NULL, $catchBlock = NULL)
{
parent::__construct();
$this->catchClass = $catchClass;
$this->catchClassAlias = $catchClassAlias;
if ($tryBlock) {
$this->tryBlock = Utils::evalCallback($tryBlock);
} else {
$this->tryBlock = new Block();
}
if ($catchBlock) {
$this->catchBlock = Utils::evalCallback($catchBlock);
} else {
$this->catchBlock = new Block();
}
}

public function render(array $args = array())
{
$this->tryBlock->setIndentLevel($this->indentLevel + 1);
$this->catchBlock->setIndentLevel($this->indentLevel + 1);

$this->lines[] = 'try {';
$this->lines[] = $this->tryBlock;
$this->lines[] = '}catch  (' . $this->catchClass . ' ' . $this->catchClassAlias . ') {';
$this->lines[] = $this->catchBlock;
$this->lines[] = '}';

return parent::render($args);
}

}







<?php
namespace CodeGen\Statement;

use CodeGen\Renderable;

class ElseIfStatement extends IfStatement implements Renderable
{
public function __construct(Renderable $condition, $elseifblock = NULL)
{
parent::__construct($condition, $elseifblock);
}

public function render(array $args = array())
{
return ' else ' . parent::render($args);
}
}
<?php
namespace CodeGen\Statement;

use CodeGen\Block;
use CodeGen\Renderable;
use CodeGen\Utils;

class ElseStatement extends Block implements Renderable
{
public $else;

public function __construct($block)
{
$this->else = Utils::evalCallback($block);
}

public function render(array $args = array())
{
$this->else->setIndentLevel($this->indentLevel + 1);
$this[] = ' else {';
$this[] = $this->else;
$this[] = '}';
return parent::render($args);
}
}
<?php
namespace CodeGen\Statement;

use CodeGen\Block;
use CodeGen\Renderable;
use CodeGen\Utils;
use CodeGen\VariableDeflator;

class IfStatement extends Block implements Renderable
{
protected $condition;

public $if;

protected $else;

protected $elseifs = array();

public function __construct(Renderable $condition, $block = NULL)
{
$this->condition = $condition;
if ($block) {
$this->if = Utils::evalCallback($block);
} else {
$this->if = new Block;
}
}








public function elif($condition, $block)
{
$this->elseifs[] = new ElseIfStatement($condition, $block);
return $this;
}

public function __call($method, $args)
{
if ($method === 'else') {
return $this->_else($args[0]);
}
}

public function _else($block)
{
$this->else = new ElseStatement($block);
return $this;
}

public function render(array $args = array())
{
$this->if->setIndentLevel($this->indentLevel + 1);
$this[] = 'if (' . VariableDeflator::deflate($this->condition) . ') {';
$this[] = $this->if;

$trailingBlocks = array();
if (!empty($this->elseifs)) {
foreach ($this->elseifs as $elseIf) {
$trailingBlocks[] = rtrim($elseIf->render($args));
}
}
if ($this->else) {
$trailingBlocks[] = rtrim($this->else->render($args));
}

$this[] = '}' . join('', $trailingBlocks);
return parent::render($args);
}

}







<?php
namespace CodeGen\Statement;

use CodeGen\Renderable;
use CodeGen\Variable;
use CodeGen\VariableDeflator;

class ArrayIssetExpr implements Renderable
{
protected $keys;

protected $var;

public function __construct(Variable $var, $keys)
{
$this->var = $var;
$this->keys = (array)$keys;
}

public function render(array $args = array())
{
$out = 'isset(' . $this->var->render($args);
foreach ($this->keys as $key) {
if ($key === null) {
$out .= '[]';
} else {
$out .= '[' . VariableDeflator::deflate($key) . ']';
}
}
$out .= ')';
return $out;
}
}


class IfIssetStatement extends IfStatement
{
public function __construct(Variable $var, $keys, $block = NULL)
{
parent::__construct(new ArrayIssetExpr($var, $keys), $block);
}
}





<?php
namespace CodeGen\Statement;

use CodeGen\Expr\AssignExpr;
use CodeGen\Renderable;

class AssignStatement extends Statement implements Renderable
{
public function __construct($lvalue, $expr)
{
$this->expr = new AssignExpr($lvalue, $expr);
}
}




<?php
namespace CodeGen\Statement;

use ReflectionClass;

class RequireClassStatement extends RequireStatement
{
public function __construct($class)
{
$refl = new ReflectionClass($class);
$file = $refl->getFileName();
$this->expr = $file;
}
}



<?php
namespace CodeGen\Statement;

use CodeGen\Expr\CallExpr;
use CodeGen\Renderable;

class FunctionCallStatement extends Statement implements Renderable
{
public function __construct($function, array $arguments = array())
{
$this->expr = new CallExpr(null, null, $function, $arguments);
}
}




<?php
namespace CodeGen\Statement;

use CodeGen\Expr\MethodCall;
use CodeGen\Renderable;

class MethodCallStatement extends Statement implements Renderable
{
public function __construct($objectName = '$this', $method = NULL, array $arguments = array())
{
$this->expr = new MethodCall($objectName, $method, $arguments);
}
}




<?php
namespace CodeGen\Statement;

use CodeGen\Renderable;

class RequireOnceStatement extends Statement implements Renderable
{
public function render(array $args = array())
{
if ($this->expr instanceof Renderable) {
return 'require_once ' . $this->expr->render($args) . ';';
} else {
return 'require_once ' . var_export($this->expr, true) . ';';
}
}
}



<?php
namespace CodeGen\Statement;

use CodeGen\Line;
use CodeGen\Renderable;

class Statement extends Line implements Renderable
{



public $expr;

public function __construct(Renderable $expr)
{
$this->expr = $expr;
}





public function render(array $args = array())
{
return $this->expr->render($args) . ';';
}

}



<?php
namespace CodeGen\Statement;

use CodeGen\Expr\FunctionCall;
use CodeGen\Renderable;

class ConstStatement extends Statement implements Renderable
{
protected $symbol;

protected $value;

public function __construct($symbol, $value)
{
$this->symbol = $symbol;
$this->value = $value;
}

public function render(array $args = array())
{
$out = 'CONST ' . $this->symbol . ' = ';
if ($this->value instanceof Renderable) {
$out .= $this->value->render($args);
} else {
$out .= var_export($this->value, true);
}
return $out . ';';
}

}





<?php
namespace CodeGen\Statement;

use CodeGen\Block;
use CodeGen\Renderable;
use CodeGen\Utils;

class ForEachStatement extends Block implements Renderable
{



public $forEachBlock;

protected $forVariable;
protected $asVariable;
protected $keyVariable;

public function __construct($forVariable, $asVariable = '$item', $keyVariable = NULL, $forEachBlock = NULL)
{
parent::__construct();

$this->forVariable = $forVariable;
$this->asVariable = $asVariable;
$this->keyVariable = $keyVariable;

if ($forEachBlock) {
$this->forEachBlock = Utils::evalCallback($forEachBlock);
} else {
$this->forEachBlock = new Block();
}
}

public function render(array $args = array())
{
$this->forEachBlock->setIndentLevel($this->indentLevel + 1);

if ($this->keyVariable) {
$this->lines[] = 'foreach (' . $this->forVariable . ' as ' . $this->keyVariable . ' => ' . $this->asVariable . ') {';
} else {
$this->lines[] = 'foreach (' . $this->forVariable . ' as ' . $this->asVariable . ') {';
}

$this->lines[] = $this->forEachBlock;
$this->lines[] = '}';

return parent::render($args);
}

}







<?php
namespace CodeGen\Statement;

use CodeGen\Block;
use CodeGen\Renderable;
use CodeGen\Utils;
use CodeGen\VariableDeflator;

class IfElseStatement extends IfStatement implements Renderable
{
public $else;

protected $elifs = array();

public function __construct(Renderable $condition, $ifBlock = NULL, $elseBlock = NULL)
{
parent::__construct($condition, $ifBlock);

if ($elseBlock) {
$this->else = Utils::evalCallback($elseBlock);
} else {
$this->else = new Block;
}
}

public function render(array $args = array())
{
$this->if->setIndentLevel($this->indentLevel + 1);
$this->else->setIndentLevel($this->indentLevel + 1);

$this[] = 'if (' . VariableDeflator::deflate($this->condition) . ') {';
$this[] = $this->if;
$this[] = '} else {';
$this[] = $this->else;
$this[] = '}';

return Block::render($args);
}
}
<?php
namespace CodeGen\Statement;

use CodeGen\Renderable;

class RequireComposerAutoloadStatement extends RequireStatement
{



public function __construct(array $prefixes = array())
{
$prefixes[] = getcwd();
foreach ($prefixes as $prefix) {
$path = $prefix . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
if (file_exists($path)) {
$this->expr = $path;
break;
}
}
}

public function render(array $args = array())
{
if ($this->expr instanceof Renderable) {
return 'require ' . $this->expr->render($args) . ';';
} else {
return 'require ' . var_export($this->expr, true) . ';';
}
}

}



<?php
namespace CodeGen\Statement;

use CodeGen\Renderable;

class UseStatement extends Statement implements Renderable
{
protected $as;

protected $class;

public function __construct($class, $as = null)
{
$this->class = ltrim($class, '\\');
$this->as = $as ? ltrim($as, '\\') : null;
}

public function getComponents()
{
return explode('\\', $this->class);
}

public function render(array $args = array())
{
$code = 'use ' . $this->class;
if ($this->as) {
$code .= ' ' . $this->as;
}
return $code . ';';
}
}
<?php
namespace CodeGen\Statement;

use CodeGen\Expr\FunctionCall;
use CodeGen\Renderable;

class DefineStatement extends Statement implements Renderable
{
public function __construct($symbol, $value)
{
$this->expr = new FunctionCall('define', [$symbol, $value]);
}

public function render(array $args = array())
{
return $this->expr->render($args) . ';';
}

}





<?php
namespace CodeGen\Statement;

use CodeGen\Exception\InvalidArgumentTypeException;
use CodeGen\Renderable;

class ConditionalStatement extends Statement implements Renderable
{
protected $conditions = array();

protected $elseBlock;

public function __construct($expr, $then, $elseBlock = null)
{
$this->conditions[] = array($expr, $then);
$this->elseBlock = $elseBlock;
}

public function when($expr, $then)
{
$this->conditions[] = array($expr, $then);
}

public function render(array $args = array())
{
foreach ($this->conditions as $condition) {
list($expr, $code) = $condition;

$ret = false;
if (is_callable($expr)) {
$ret = call_user_func($expr);
} else if (is_bool($expr)) {
$ret = $expr;
} else {
$ret = $expr ? true : false;
}

if ($ret) {
if (is_callable($code)) {
$code = call_user_func($code);
}

if (is_string($code)) {
return $code;
} else if ($code instanceof Renderable) {
return $code->render($args);
} else {
throw new InvalidArgumentTypeException('Unsupported line object type', $code, array('string', 'Renderable'));
}
}
}

if ($this->elseBlock) {
if (is_string($this->elseBlock)) {
return $this->elseBlock;
} else if ($this->elseBlock instanceof Renderable) {
return $this->elseBlock->render($args);
} else {
throw new InvalidArgumentTypeException('Unsupported line object type', $this->elseBlock, array('string', 'Renderable'));
}
}
return $ret;
}
}





<?php
namespace CodeGen\Statement;

use CodeGen\Renderable;

class RequireStatement extends Statement implements Renderable
{
public function __construct($file)
{
$this->expr = $file;
}

public function render(array $args = array())
{
if ($this->expr instanceof Renderable) {
return 'require ' . $this->expr->render($args) . ';';
} else {
return 'require ' . var_export($this->expr, true) . ';';
}
}

}



<?php
namespace CodeGen\Testing;

use CodeGen\Renderable;
use PHPUnit_Framework_TestCase;

abstract class CodeGenTestCase extends PHPUnit_Framework_TestCase
{

public function assertCodeEquals($expected, Renderable $code, array $args = array())
{
$out = $code->render($args);
static::assertEquals($expected, $out);
}


public function assertCodeEqualsFile($fixtureFile, Renderable $code, array $args = array())
{
$out = $code->render($args);
if (!file_exists($fixtureFile) || getenv('OVERRIDE_FIXTURE')) {
echo "\nGenerating fixture file with below content: $fixtureFile\n";
echo "======================\n";
echo $out . "\n";
echo "======================\n";
file_put_contents($fixtureFile, $out);
}
static::assertStringEqualsFile($fixtureFile, $out, "Testing $fixtureFile");
}
}



<?php
namespace CodeGen\Exception;

use InvalidArgumentException;

class InvalidArgumentTypeException extends InvalidArgumentException
{
public $expectingTypes = array();

public $givenType;

public function __construct($message, $givenVariable, array $expectingTypes = array())
{
parent::__construct($message);
if (is_object($givenVariable)) {
$this->givenType = get_class($givenVariable);
} else {
$this->givenType = gettype($givenVariable);
}
$this->expectingTypes = $expectingTypes;
}
}



<?php
namespace CodeGen;

use Closure;
use Twig_Environment;
use Twig_Loader_Array;


class Utils
{
protected static $stringloader;

protected static $twig;

static public function renderStringTemplate($templateContent, array $args = array(), Twig_Environment $env = null)
{
if (!$env) {
if (self::$twig) {
$env = self::$twig;
} else {
$env = new Twig_Environment(new Twig_Loader_Array(array()));
}
}
$template = $env->createTemplate($templateContent);

if (is_callable($args)) {
$args = call_user_func($args);
} elseif ($args instanceof Closure) {
$args = $args();
}
return $template->render($args);
}

static public function evalCallback($cb)
{
return is_callable($cb) ? $cb() : $cb;
}

static public function indent($indent = 1, $spaces = 4)
{
return str_repeat(' ', $spaces * $indent);
}
}




<?php
namespace CodeGen;

use CodeGen\Exception\InvalidArgumentTypeException;

class Comment extends Line implements Renderable
{
public $comment;

public function __construct($comment)
{
$this->comment = $comment;
}

public function render(array $args = array())
{
$tab = Indenter::indent($this->indentLevel);
$out = $tab . '// ';
if (is_string($this->comment)) {
$out .= $this->comment;
} else if ($this->comment instanceof Renderable) {
$out .= $this->comment->render($args);
} else {
throw new InvalidArgumentTypeException('Invalid type for comment.', $this->comment, ['string', 'Renderable']);
}
return $out;
}

}




Steps = PHPUnit, BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
; VersionFrom = src/LazyRecord/Console.php
Copyright (c) 2013 Yo-An Lin <yoan.lin@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Bitdeli Chef <chef@bitdeli.com>
Dlussky Kirill <kirill@dlussky.ru>
Francois Lajoie <snake386@hotmail.com>
Gasol Wu <gasol.wu@gmail.com>
Igor Santos <igorsantos07@gmail.com>
Jevon Wright <jevon@jevon.org>
MartyIX <vseticka.martin@gmail.com>
Michał Kniotek <michal.kniotek@uj.edu.pl>
Robbert Klarenbeek <robbertkl@renbeek.nl>
Yo-An Lin <cornelius.howl@gmail.com>
Yo-An Lin <yoanlin93@gmail.com>
<?php










namespace GetOptionKit;

class Argument
{
public $arg;

public function __construct($arg)
{
$this->arg = $arg;
}

public function isLongOption()
{
return substr($this->arg, 0, 2) === '--';
}

public function isShortOption()
{
return (substr($this->arg, 0, 1) === '-')
&& (substr($this->arg, 1, 1) !== '-');
}

public function isEmpty()
{
return $this->arg === null || empty($this->arg) && ('0' !== $this->arg);
}




public function anyOfOptions(OptionCollection $options)
{
$name = $this->getOptionName();
$keys = $options->keys();

return in_array($name, $keys);
}








public function isOption()
{
return $this->isShortOption() || $this->isLongOption();
}








public function getOptionName()
{
if (preg_match('/^[-]+([a-zA-Z0-9-]+)/', $this->arg, $regs)) {
return $regs[1];
}
}

public function splitAsOption()
{
return explode('=', $this->arg, 2);
}

public function containsOptionValue()
{
return preg_match('/=.+/', $this->arg);
}

public function getOptionValue()
{
if (preg_match('/=(.+)/', $this->arg, $regs)) {
return $regs[1];
}

return;
}






public function withExtraFlagOptions()
{
return preg_match('/^-[a-zA-Z0-9]{2,}/', $this->arg);
}

public function extractExtraFlagOptions()
{
$args = array();
for ($i = 2;$i < strlen($this->arg); ++$i) {
$args[] = '-'.$this->arg[$i];
}
$this->arg = substr($this->arg, 0, 2); 
return $args;
}

public function __toString()
{
return $this->arg;
}
}
<?php










namespace GetOptionKit;

use Exception;
use GetOptionKit\Exception\InvalidOptionException;
use GetOptionKit\Exception\RequireValueException;

class OptionParser
{
public $specs;
public $longOptions;
public $shortOptions;

public function __construct(OptionCollection $specs)
{
$this->specs = $specs;
}

public function setSpecs(OptionCollection $specs)
{
$this->specs = $specs;
}






protected function consumeOptionToken(Option $spec, $arg, $next, & $success = false)
{


if ($spec->isFlag()) {

if ($spec->isIncremental()) {
$spec->increaseValue();
} else {
$spec->setValue(true);
}
return 0;

} else if ($spec->isRequired()) {

if ($next && !$next->isEmpty() && !$next->anyOfOptions($this->specs)) {
$spec->setValue($next->arg);
return 1;
} else {
throw new RequireValueException("Option '{$arg->getOptionName()}' requires a value.");
}

} else if ($spec->isMultiple()) {

if ($next && !$next->isEmpty() && !$next->anyOfOptions($this->specs)) {
$this->pushOptionValue($spec, $arg, $next);
return 1;
}

} else if ($spec->isOptional() && $next && !$next->isEmpty() && !$next->anyOfOptions($this->specs)) {

$spec->setValue($next->arg);
return 1;

}
return 0;
}




protected function pushOptionValue(Option $spec, $arg, $next)
{
if ($next && !$next->anyOfOptions($this->specs)) {
$spec->pushValue($next->arg);
}
}







protected function preprocessingArguments(array $argv)
{

$newArgv = array();
$afterDash = false;
foreach ($argv as $arg) {
if ($arg === '--') {
$afterDash = true;
}
if ($afterDash) {
$newArgv[] = $arg;
continue;
}

$a = new Argument($arg);
if ($a->anyOfOptions($this->specs) && $a->containsOptionValue()) {
list($opt, $val) = $a->splitAsOption();
array_push($newArgv, $opt, $val);
} else {
array_push($newArgv, $arg);
}
}
return $newArgv;
}

protected function fillDefaultValues(OptionCollection $opts, OptionResult $result)
{

foreach ($opts as $opt) {
if ($opt->value === null && $opt->defaultValue !== null) {
$opt->setValue($opt->getDefaultValue());
$result->set($opt->getId(), $opt);
}
}
}










public function parse(array $argv)
{
$result = new OptionResult();

$argv = $this->preprocessingArguments($argv);

$len = count($argv);


$first = new Argument($argv[0]);
if ($first->isOption()) {
throw new Exception('parse(argv) expects the first argument to be the program name.');
}

for ($i = 1; $i < $len; ++$i) {
$arg = new Argument($argv[$i]);



if (!$arg->isOption()) {
$result->addArgument($arg);
continue;
}



if ($arg->withExtraFlagOptions()) {
$extra = $arg->extractExtraFlagOptions();
array_splice($argv, $i + 1, 0, $extra);
$argv[$i] = $arg->arg; 
$len = count($argv); 
}

$next = null;
if ($i + 1 < count($argv)) {
$next = new Argument($argv[$i + 1]);
}

$spec = $this->specs->get($arg->getOptionName());

if ($arg->arg === '--') {
continue;
}

if (!$spec) {
throw new InvalidOptionException('Invalid option: '.$arg);
}



$i += $this->consumeOptionToken($spec, $arg, $next);
$result->set($spec->getId(), $spec);
}

$this->fillDefaultValues($this->specs, $result);

return $result;
}
}
<?php










namespace GetOptionKit;

use ArrayIterator;
use ArrayAccess;
use IteratorAggregate;
use Countable;










class OptionResult
implements IteratorAggregate, ArrayAccess, Countable
{



public $keys = array();

private $currentKey;


public $arguments = array();

#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->keys);
}

#[\ReturnTypeWillChange]
public function count()
{
return count($this->keys);
}

public function merge(OptionResult $a)
{
$this->keys = array_merge($this->keys, $a->keys);
$this->arguments = array_merge($this->arguments, $a->arguments);
}

public function __isset($key)
{
return isset($this->keys[$key]);
}

public function __get($key)
{
return $this->get($key);
}

public function get($key)
{
if (isset($this->keys[$key])) {
return $this->keys[$key]->getValue();
}



$parts = preg_split('/(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/', $key);
if (sizeof($parts) > 1) {
$key = implode('-', array_map('strtolower', $parts));
}
if (isset($this->keys[$key])) {
return $this->keys[$key]->getValue();
}
}

public function __set($key, $value)
{
$this->keys[ $key ] = $value;
}

public function has($key)
{
return isset($this->keys[ $key ]);
}

public function set($key, Option $value)
{
$this->keys[ $key ] = $value;
}

public function addArgument(Argument $arg)
{
$this->arguments[] = $arg;
}

public function getArguments()
{
return array_map(function ($e) { return $e->__toString(); }, $this->arguments);
}

#[\ReturnTypeWillChange]
public function offsetSet($name, $value)
{
$this->keys[ $name ] = $value;
}

#[\ReturnTypeWillChange]
public function offsetExists($name)
{
return isset($this->keys[ $name ]);
}

#[\ReturnTypeWillChange]
public function offsetGet($name)
{
return $this->keys[ $name ];
}

#[\ReturnTypeWillChange]
public function offsetUnset($name)
{
unset($this->keys[$name]);
}

public function toArray()
{
$array = array();
foreach ($this->keys as $key => $option) {
$array[ $key ] = $option->getValue();
}

return $array;
}

public static function create($specs, array $values = array(), array $arguments = null)
{
$new = new self();
foreach ($specs as $spec) {
$id = $spec->getId();
if (isset($values[$id])) {
$new->$id = $spec;
$spec->setValue($values[$id]);
}
if ($arguments) {
foreach ($arguments as $arg) {
$new->addArgument(new Argument($arg));
}
}
}

return $new;
}
}
<?php










namespace GetOptionKit;

use Exception;
use LogicException;
use GetOptionKit\Exception\InvalidOptionException;
use GetOptionKit\Exception\RequireValueException;


































































class ContinuousOptionParser extends OptionParser
{
public $index;
public $length;
public $argv;


public function __construct(OptionCollection $specs)
{
parent::__construct($specs);
$this->index = 1;
}




public function startFrom($index)
{
$this->index = $index;
}

public function isEnd()
{

return $this->index >= $this->length;
}






public function advance()
{
if ($this->index >= $this->length) {
throw new LogicException("Argument index out of bounds.");
}
return $this->argv[$this->index++];
}






public function getCurrentArgument()
{
return $this->argv[$this->index];
}

public function continueParse()
{
return $this->parse($this->argv);
}


protected function fillDefaultValues(OptionCollection $opts, OptionResult $result)
{

foreach ($opts as $opt) {
if ($opt->value === null && $opt->defaultValue !== null) {
$opt->setValue($opt->getDefaultValue());
$result->set($opt->getId(), $opt);
}
}
}


public function parse(array $argv)
{

$result = new OptionResult();
$this->argv = $this->preprocessingArguments($argv);
$this->length = count($this->argv);


for (; $this->index < $this->length; ++$this->index) {
$arg = new Argument($this->argv[$this->index]);


if (!$arg->isOption()) {

$this->fillDefaultValues($this->specs, $result);
return $result;
}





if ($arg->withExtraFlagOptions()) {
$extra = $arg->extractExtraFlagOptions();
array_splice($this->argv, $this->index + 1, 0, $extra);
$this->argv[$this->index] = $arg->arg; 
$this->length = count($this->argv); 
}

$next = null;
if ($this->index + 1 < count($this->argv)) {
$next = new Argument($this->argv[$this->index + 1]);
}

$spec = $this->specs->get($arg->getOptionName());
if (!$spec) {
throw new InvalidOptionException('Invalid option: '.$arg);
}



$this->index += $this->consumeOptionToken($spec, $arg, $next);
$result->set($spec->getId(), $spec);
}

$this->fillDefaultValues($this->specs, $result);

return $result;
}
}
<?php









namespace GetOptionKit\OptionPrinter;

use GetOptionKit\OptionCollection;
use GetOptionKit\Option;

class ConsoleOptionPrinter implements OptionPrinter
{
public $screenWidth = 78;




public function renderOption(Option $opt)
{
$c1 = '';
if ($opt->short && $opt->long) {
$c1 = sprintf('-%s, --%s', $opt->short, $opt->long);
} else if ($opt->short) {
$c1 = sprintf('-%s', $opt->short);
} else if ($opt->long) {
$c1 = sprintf('--%s', $opt->long);
}
$c1 .= $opt->renderValueHint();

return $c1;
}






public function render(OptionCollection $options)
{

$lines = array();
foreach ($options as $option) {
$c1 = $this->renderOption($option);
$lines[] = "\t".$c1;
$lines[] = wordwrap("\t\t".$option->desc, $this->screenWidth, "\n\t\t"); 
$lines[] = '';
}

return implode("\n", $lines);
}
}
<?php

namespace GetOptionKit\OptionPrinter;

use GetOptionKit\OptionCollection;
use GetOptionKit\Option;

interface OptionPrinter
{
public function renderOption(Option $option);
public function render(OptionCollection $options);
}
<?php

namespace GetOptionKit\ValueType;

class RegexType extends BaseType
{
public $matches = array();

public function __construct($option)
{
$this->option = $option;
}

public function test($value)
{
return preg_match($this->option, $value) !== 0;
}

public function parse($value)
{
preg_match($this->option, $value, $this->matches);
return strval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

class Ipv6Type extends BaseType
{
public function test($value)
{
return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
}

public function parse($value)
{
return strval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

class UrlType extends BaseType
{
public function test($value)
{
return filter_var($value, FILTER_VALIDATE_URL) !== false;
}

public function parse($value)
{
return strval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

use DateTime;

class DateTimeType extends BaseType
{
public $option = array(
'format' => DateTime::ATOM,
);

public function test($value)
{
return DateTime::createFromFormat($this->option['format'], $value) !== false;
}

public function parse($value)
{
return DateTime::createFromFormat($this->option['format'], $value);
}
}
<?php

namespace GetOptionKit\ValueType;

class BooleanType extends BaseType
{
public function test($value)
{
if (is_string($value)) {
$value = strtolower($value);
return '0' === $value || '1' === $value 
|| 'true' === $value || 'false' === $value;
}

return is_bool($value);
}

public function parse($value)
{
$value = strtolower($value);
if ($value === '0' || $value === 'false') {
return false;
}
if ($value === '1' || $value === 'true') {
return true;
}

return false;
}
}
<?php

namespace GetOptionKit\ValueType;

class Ipv4Type extends BaseType
{
public function test($value)
{
return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
}

public function parse($value)
{
return strval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

class DateType extends BaseType
{
public function test($value)
{
$a = date_parse($value);
if ($a === false || $a['error_count'] > 0) {
return false;
}
return true;
}

public function parse($value)
{
return date_parse($value);
}
}
<?php

namespace GetOptionKit\ValueType;

use SplFileInfo;

class PathType extends BaseType
{
public function test($value)
{
return file_exists($value);
}

public function parse($value)
{
return new SplFileInfo($value);
}
}
<?php

namespace GetOptionKit\ValueType;




class BoolType extends BooleanType
{
}
<?php

namespace GetOptionKit\ValueType;

use SplFileInfo;

class DirType extends BaseType
{
public function test($value)
{
return is_dir($value);
}

public function parse($value)
{
return new SplFileInfo($value);
}
}
<?php

namespace GetOptionKit\ValueType;

abstract class BaseType
{





public $option;

public function __construct($option = null)
{
if ($option) {
$this->option = $option;
}
}






abstract public function test($value);






abstract public function parse($value);
}
<?php

namespace GetOptionKit\ValueType;

class EmailType extends BaseType
{
public function test($value)
{
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false;
}

public function parse($value)
{
return strval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

class IpType extends BaseType
{
public function test($value)
{
return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6) !== false;
}

public function parse($value)
{
return strval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

class NumberType extends BaseType
{
public function test($value)
{
return is_numeric($value);
}

public function parse($value)
{
return intval($value);
}
}
<?php

namespace GetOptionKit\ValueType;

use SplFileInfo;

class FileType extends BaseType
{
public function test($value)
{
return is_file($value);
}

public function parse($value)
{
return new SplFileInfo($value);
}
}
<?php

namespace GetOptionKit\ValueType;

class StringType extends BaseType
{
public function test($value)
{
return is_string($value);
}

public function parse($value)
{
return strval($value);
}
}
<?php










namespace GetOptionKit;


use Exception;
use LogicException;
use InvalidArgumentException;
use GetOptionKit\Exception\InvalidOptionValueException;

class Option
{
public $short;

public $long;




public $desc;




public $key; 

public $value;

public $type;

public $valueName; 

public $isa;

public $isaOption;

public $validValues;

public $suggestions;

public $defaultValue;

public $incremental = false;




public $filter;

public $validator;

public $multiple = false;

public $optional = false;

public $required = false;

public $flag = false;




protected $trigger;

public function __construct($spec)
{
$this->initFromSpecString($spec);
}






protected function initFromSpecString($specString)
{
$pattern = '/
        (
                (?:[a-zA-Z0-9-]+)
                (?:
                    \|
                    (?:[a-zA-Z0-9-]+)
                )?
        )

        # option attribute operators
        ([:+?])?

        # value types
        (?:=(boolean|string|number|date|file|dir|url|email|ip|ipv6|ipv4))?
        /x';
$ret = preg_match($pattern, $specString, $regs);
if ($ret === false || $ret === 0) {
throw new Exception('Incorrect spec string');
}

$orig = $regs[0];
$name = $regs[1];
$attributes = isset($regs[2]) ? $regs[2] : null;
$type = isset($regs[3]) ? $regs[3] : null;

$short = null;
$long = null;


if (strpos($name, '|') !== false) {
list($short, $long) = explode('|', $name);
} else if (strlen($name) === 1) {
$short = $name;
} else if (strlen($name) > 1) {
$long = $name;
}

$this->short = $short;
$this->long = $long;

if ($attributes === null) {
$this->flag();
} else if (strpos($attributes, ':') !== false) {

$this->required();
} else if (strpos($attributes, '+') !== false) {

$this->multiple();
} else if (strpos($attributes, '?') !== false) {

$this->optional();
} else {
$this->flag();
}
if ($type) {
$this->isa($type);
}
}




public function getId()
{
return $this->key ?: $this->long ?: $this->short;
}




public function incremental()
{
$this->incremental = true;

return $this;
}

public function required()
{
$this->required = true;

return $this;
}






public function defaultValue($value)
{
$this->defaultValue = $value;

return $this;
}

public function multiple()
{
$this->multiple = true;
$this->value = array(); 
return $this;
}

public function optional()
{
$this->optional = true;

return $this;
}

public function flag()
{
$this->flag = true;

return $this;
}

public function trigger(callable $trigger)
{
$this->trigger = $trigger;

return $this;
}

public function isIncremental()
{
return $this->incremental;
}

public function isFlag()
{
return $this->flag;
}

public function isMultiple()
{
return $this->multiple;
}

public function isRequired()
{
return $this->required;
}

public function isOptional()
{
return $this->optional;
}

public function isTypeNumber()
{
return $this->isa == 'number';
}

public function isType($type)
{
return $this->isa === $type;
}

public function getTypeClass()
{
$class = 'GetOptionKit\\ValueType\\'.ucfirst($this->isa).'Type';
if (class_exists($class, true)) {
return new $class($this->isaOption);
}
throw new Exception("Type class '$class' not found.");
}

public function testValue($value)
{
$type = $this->getTypeClass();
return $type->test($value);
}

protected function _preprocessValue($value)
{
$val = $value;

if ($isa = ucfirst((string) $this->isa)) {
$type = $this->getTypeClass();
if ($type->test($value)) {
$val = $type->parse($value);
} else {
if (strtolower($isa) === 'regex') {
$isa .= '('.$this->isaOption.')';
}
throw new InvalidOptionValueException("Invalid value for {$this->renderReadableSpec(false)}. Requires a type $isa.");
}
}


if ($this->filter) {
$val = call_user_func($this->filter, $val);
}


if ($validValues = $this->getValidValues()) {
if (!in_array($value, $validValues)) {
throw new InvalidOptionValueException('valid values are: '.implode(', ', $validValues));
}
}

if (!$this->validate($value)[0]) {
throw new InvalidOptionValueException('option is invalid');
}

return $val;
}

protected function callTrigger()
{
if ($this->trigger) {
if ($ret = call_user_func($this->trigger, $this->value)) {
$this->value = $ret;
}
}
}




public function setValue($value)
{
$this->value = $this->_preprocessValue($value);
$this->callTrigger();
}




public function increaseValue()
{
if (!$this->value) {
$this->value = 1;
} else {
++$this->value;
}
$this->callTrigger();
}






public function pushValue($value)
{
$value = $this->_preprocessValue($value);
$this->value[] = $value;
$this->callTrigger();
}

public function desc($desc)
{
$this->desc = $desc;
}






public function valueName($name)
{
$this->valueName = $name;

return $this;
}

public function renderValueHint()
{
$n = null;
if ($this->valueName) {
$n = $this->valueName;
} else if ($values = $this->getValidValues()) {
$n = '('.implode(',', $values).')';
} else if ($values = $this->getSuggestions()) {
$n = '['.implode(',', $values).']';
} else if ($val = $this->getDefaultValue()) {

if ((is_scalar($val) && strlen((string) $val)) || is_bool($val)) {
if (is_bool($val)) {
$n = ($val ? 'true' : 'false');
} else {
$n = $val;
}
}
}

if (!$n && $this->isa !== null) {
$n = '<'.$this->isa.'>';
}
if ($this->isRequired()) {
return sprintf('=%s', $n);
} else if ($this->isOptional() || $this->defaultValue) {
return sprintf('[=%s]', $n);
} else if ($n) {
return '='.$n;
}

return '';
}

public function getDefaultValue()
{
if (is_callable($this->defaultValue)) {
return $this->defaultValue;
}

return $this->defaultValue;
}

public function getValue()
{
if (null !== $this->value) {
if (is_callable($this->value)) {
return call_user_func($this->value);
}
return $this->value;
}

return $this->getDefaultValue();
}






public function renderReadableSpec($renderHint = true)
{
$c1 = '';
if ($this->short && $this->long) {
$c1 = sprintf('-%s, --%s', $this->short, $this->long);
} else if ($this->short) {
$c1 = sprintf('-%s', $this->short);
} else if ($this->long) {
$c1 = sprintf('--%s', $this->long);
}
if ($renderHint) {
return $c1.$this->renderValueHint();
}

return $c1;
}

public function __toString()
{
$c1 = $this->renderReadableSpec();
$return = '';
$return .= sprintf('* key:%-8s spec:%s  desc:%s', $this->getId(), $c1, $this->desc)."\n";
$val = $this->getValue();
if (is_array($val)) {
$return .= '  value => ' . join(',', array_map(function($v) { return var_export($v, true); }, $val))."\n";
} else {
$return .= sprintf('  value => %s', $val)."\n";
}

return $return;
}








public function isa($type, $option = null)
{

if ($type === 'bool') {
$type = 'boolean';
}
$this->isa = $type;
$this->isaOption = $option;

return $this;
}




public function validValues($values)
{
$this->validValues = $values;

return $this;
}






public function suggestions($suggestions)
{
$this->suggestions = $suggestions;

return $this;
}






public function getValidValues()
{
if ($this->validValues) {
if (is_callable($this->validValues)) {
return call_user_func($this->validValues);
}

return $this->validValues;
}

return;
}






public function getSuggestions()
{
if ($this->suggestions) {
if (is_callable($this->suggestions)) {
return call_user_func($this->suggestions);
}

return $this->suggestions;
}

return;
}

public function validate($value)
{
if ($this->validator) {
$ret = call_user_func($this->validator, $value);
if (is_array($ret)) {
return $ret;
} else if ($ret === false) {
return array(false, "Invalid value: $value");
} else if ($ret === true) {
return array(true, 'Successfully validated.');
}
throw new InvalidArgumentException('Invalid return value from the validator.');
}

return array(true);
}

public function validator($cb)
{
$this->validator = $cb;

return $this;
}






public function filter($cb)
{
$this->filter = $cb;

return $this;
}
}
<?php










namespace GetOptionKit;


use ArrayIterator;
use IteratorAggregate;
use Countable;
use Exception;
use LogicException;
use GetOptionKit\Exception\OptionConflictException;

class OptionCollection
implements IteratorAggregate, Countable
{
public $data = array();






public $longOptions = array();






public $shortOptions = array();






public $options = array();

public function __construct()
{
$this->data = array();
}

public function __clone()
{
foreach ($this->data as $k => $v) {
$this->data[ $k ] = clone $v;
}
foreach ($this->longOptions as $k => $v) {
$this->longOptions[ $k ] = clone $v;
}
foreach ($this->shortOptions as $k => $v) {
$this->shortOptions[ $k ] = clone $v;
}
foreach ($this->options as $k => $v) {
$this->options[ $k ] = clone $v;
}
}






public function add()
{
$num = func_num_args();
$args = func_get_args();
$first = $args[0];

if ($first instanceof Option) {

$this->addOption($first);

} else if (is_string($first)) {

$specString = $args[0];
$desc = isset($args[1]) ? $args[1] : null;
$key = isset($args[2]) ? $args[2] : null;


$spec = new Option($specString);
if ($desc) {
$spec->desc($desc);
}
if ($key) {
$spec->key = $key;
}
$this->addOption($spec);
return $spec;

} else {

throw new LogicException('Unknown Spec Type');

}
}






public function addOption(Option $spec)
{
$this->data[$spec->getId()] = $spec;
if ($spec->long) {
if (isset($this->longOptions[$spec->long])) {
throw new OptionConflictException('Option conflict: --'.$spec->long.' is already defined.');
}
$this->longOptions[$spec->long] = $spec;
}
if ($spec->short) {
if (isset($this->shortOptions[$spec->short])) {
throw new OptionConflictException('Option conflict: -'.$spec->short.' is already defined.');
}
$this->shortOptions[$spec->short] = $spec;
}
$this->options[] = $spec;
if (!$spec->long && !$spec->short) {
throw new Exception('Neither long option name nor short name is not given.');
}
}

public function getLongOption($name)
{
return isset($this->longOptions[ $name ]) ? $this->longOptions[ $name ] : null;
}

public function getShortOption($name)
{
return isset($this->shortOptions[ $name ]) ? $this->shortOptions[ $name ] : null;
}


public function get($id)
{
if (isset($this->data[$id])) {
return $this->data[$id];
} else if (isset($this->longOptions[$id])) {
return $this->longOptions[$id];
} else if (isset($this->shortOptions[$id])) {
return $this->shortOptions[$id];
}
}

public function find($name)
{
foreach ($this->options as $option) {
if ($option->short === $name || $option->long === $name) {
return $option;
}
}
}

public function size()
{
return count($this->data);
}

public function all()
{
return $this->data;
}

public function toArray()
{
$array = array();
foreach ($this->data as $k => $spec) {
$item = array();
if ($spec->long) {
$item['long'] = $spec->long;
}
if ($spec->short) {
$item['short'] = $spec->short;
}
$item['desc'] = $spec->desc;
$array[] = $item;
}

return $array;
}

public function keys()
{
return array_merge(array_keys($this->longOptions), array_keys($this->shortOptions));
}

#[\ReturnTypeWillChange]
public function count()
{
return count($this->data);
}

#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->data);
}
}
<?php










namespace GetOptionKit\Exception;

use Exception;

class RequireValueException extends Exception
{
}
<?php










namespace GetOptionKit\Exception;

use Exception;

class InvalidOptionValueException extends Exception
{
}
<?php










namespace GetOptionKit\Exception;

use Exception;

class NonNumericException extends Exception
{
}
<?php










namespace GetOptionKit\Exception;

use Exception;

class InvalidOptionException extends Exception
{
}
<?php










namespace GetOptionKit\Exception;

use Exception;

class OptionConflictException extends Exception
{
}
<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://phpdox.de/config" silent="false">
    <project name="GetOptionKit" source="src" workdir="build/phpdox">
        <collector publiconly="false">
            <include mask="*.php" />
            <exclude mask="*Autoload.php" />
        </collector>

        <generator output="build">
            <build engine="html" enabled="true" output="api"/>
            <build engine="graph" enabled="true" output="graph">
                <dot executable="/usr/bin/dot" render="true" format="png" />
            </build>
        </generator>
    </project>
</phpdox>
Steps = PHPUnit, BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
; VersionFrom = src/PHPRelease/Console.php[package]
name = GetOptionKit
version = 1.2.2
desc = "A powerful GetOpt toolkit for PHP, which supports type constraints, flag,
multiple flag, multiple values, required value checking."

author         = "Yo-An Lin (c9s) <cornelius.howl@gmail.com>"
channel        = pear.corneltek.com
stability      = stable

[require]
php = 5.3
pearinstaller = 1.4.1
pear.corneltek.com/Universal = 
pear.corneltek.com/PHPUnit_TestMore = 
The MIT License (MIT)

Copyright (C) 2014 Yo-An Lin <yoanlin93@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php
namespace ClassTemplate;
use Exception;
use ReflectionClass;
use ReflectionObject;
use ClassTemplate\ClassTrait;
use CodeGen\Renderable;
use ClassTemplate\ClassFile;

class TemplateClassFile extends ClassFile implements Renderable
{



protected $view;

public $templateFile;
public $templateDirs;
public $options = array();
public $msgIds = array();

public function __construct($className, array $options = array())
{
if( !isset($options['template_dirs']) ) {
$ro = new ReflectionObject($this);
$dir = dirname($ro->getFilename()) . DIRECTORY_SEPARATOR . 'Templates';
$options['template_dirs'] = array($dir);
}
if( !isset($options['template']) ) {
$options['template'] = 'Class.php.twig';
}

$this->options = $options;
$this->templateFile = $options['template'];
$this->templateDirs = $options['template_dirs'];
$this->setClass($className);

$this->view = new TemplateView($this->templateDirs, 
(isset($options['twig']) ? $options['twig'] : array()),
(isset($options['template_args']) ? $options['template_args'] : array())
);
$this->view->class = $this;
}

public function __set($n,$v) {
$this->view->__set($n,$v);
}

public function render(array $args = array())
{
foreach ($args as $n => $v) {
$this->view->__set($n,$v);
}
$content = $this->view->renderFile($this->templateFile);
if ( isset($this->options['trim_tag']) && strpos($content, '<?php') === 0 ) {
return substr($content, 5);
}
return $content;
}

public function getView() {
return $this->view;
}

public function setView($view) {
$this->view = $view;
}


public function addMsgId($msgId) {
$this->msgIds[] = $msgId;
}

public function setMsgIds($msgIds) {
$this->msgIds = $msgIds;
}
}
<?php
namespace ClassTemplate;
use Exception;
use SerializerKit\PhpSerializer;
use Twig_Loader_Filesystem;
use Twig_Environment;
use Twig_SimpleFilter;

function twig_var_export($obj)
{
$ser = new PhpSerializer;
$ser->return = false;
return $ser->encode( $obj );
}

class TemplateView
{
private $loader;
private $twig;

public $stash = array();
public $overwrite = false;

public function __construct( $dirs , $options = array(), $stash = array() )
{
$this->loader = new \Twig_Loader_Filesystem( $dirs );
$this->twig = new \Twig_Environment($this->loader, array(
'cache' => false,
'auto_reload' => true,
'autoescape' => false,
'debug' => true,
) + $options );
$this->stash = $stash;
$this->twig->addFilter(new Twig_SimpleFilter('export','\ClassTemplate\twig_var_export'));
}

public function __set($n,$v)
{
$this->stash[ $n ] = $v;
}

public function __get($n)
{
return $this->stash[ $n ];
}

public function renderFile($file)
{
$template = $this->twig->loadTemplate($file);
return $template->render( $this->stash );
}

}

<?php
/**
This is an auto-generated file,
Please DO NOT modify this file directly.
*/
{% if class.class.namespace %}
namespace {{ class.class.namespace }};
{% endif %}

{% for u in class.uses %}
{{u|raw}}
{% endfor %}

class {{ class.class.name }} {% if class.extends %} extends {{ class.extends }} {% endif %}
{
{% for t in class.traits %}
{{t|raw}}
{% endfor %}

{% for con in class.consts %}
{{con|raw}}
{% endfor %}

{% for property in class.properties %}
{{property|raw}}
{% endfor %}

{% for con in class.staticVars %}
{{con|raw}}
{% endfor %}

{% for method in class.methods %}
{{method|raw}}
{% endfor %}
}

<?php
namespace ClassTemplate;
use Exception;
use ReflectionClass;
use ReflectionObject;
use CodeGen\UserClass;
use CodeGen\Renderable;

class ClassFile extends UserClass
{
public $templateFile;
public $templateDirs;
public $options = array();

















public function __construct($className, array $options = array())
{
parent::__construct($className);
$this->setOptions($options);
}

public function setOptions(array $options)
{
$this->options = $options;
}

public function setOption($key, $val) {
$this->options[$key] = $val;
}

public function render(array $args = array())
{
return "<?php\n" . parent::render($args);
}

public function writeTo($file)
{
return file_put_contents($file, $this->render());
}

public function getSplFilePath()
{
return str_replace('\\', DIRECTORY_SEPARATOR, ltrim($this->class->getFullName(),'\\'));
}

public function load() {
$tmpname = tempnam('/tmp', $this->getSplFilePath());
if (file_put_contents($tmpname, $this->render()) != false) {
return require $tmpname;
}
throw new Exception("Can not load class file $tmpname");
}
}

<?php
namespace ClassTemplate;
use ReflectionClass;

class ClassInjection
{
public $lines = array();




public $contents = array();





public $contentLength = 0;





public $boundary;





public $boundaryStartLine;





public $boundaryEndLine;





public $targetClass;





public $filename;








public function __construct($class)
{
$this->targetClass = $class;
$this->reflection = new ReflectionClass($class);
$this->filename = $this->reflection->getFilename();
}


public function replaceContent($content)
{
$this->contents = array($content);
}


public function appendContent($content) 
{
$this->contents[] = $content;
}

public function getBoundary() 
{
if($this->boundary)
return $this->boundary;
$content = join("\n",$this->contents);
$this->boundary = md5($content);
return $this->boundary;
}

public function read() 
{
$filename = $this->reflection->getFilename();

$this->lines = array();
$this->contents = array();
$this->lines = explode("\n",file_get_contents($filename));
$this->contentLength = 0;
$inBoundary = false;
for ( $i = 0; $i < count($this->lines); $i++ ) {
$line = $this->lines[$i];

if( preg_match('/^\s*#boundary start (\w+)/',$line,$regs) ) {
$inBoundary = true;
$this->boundary = $regs[1];
$this->boundaryStartLine = $i + 1;
}
elseif( preg_match('/^\s*#boundary end (\w+)/',$line,$regs) ) {
$inBoundary = false;
$this->boundaryEndLine = $i + 1;
}
elseif( $inBoundary ) {
$this->contentLength++;
$this->contents[] = $line;
}
}
}





public function buildContent()
{
$contents = $this->contents;
array_unshift( $contents, '#boundary start ' . $this->getBoundary() );
array_push( $contents, '#boundary end ' . $this->getBoundary() );
return $contents;
}

public function removeContent()
{
$this->contents = array();
}

public function write() {
if($this->boundaryStartLine && $this->boundaryEndLine ) {
array_splice($this->lines, $this->boundaryStartLine - 1, $this->contentLength + 2, $this->buildContent() );
file_put_contents($this->filename, join("\n",$this->lines) );
}
else {
$endline = $this->reflection->getEndLine();
array_splice($this->lines,$endline - 1,0, $this->buildContent() );
file_put_contents( $this->filename, join("\n",$this->lines) );
}


$this->read();
}

public function __toString()
{
return join("\n",$this->lines);
}
}

<?php
namespace ClassTemplate;
use Exception;
use ReflectionClass;
use ReflectionObject;
use CodeGen\Renderable;
use CodeGen\Block;

class File extends Block
{

public function render(array $args = array())
{
return "<?php\n" . parent::render($args);
}

public function writeTo($file)
{
return file_put_contents($file, $this->render());
}

}


Steps = PHPUnit, BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
; VersionFrom = src/LazyRecord/Console.php
<?php
namespace PEARX;
use Phar;
use PharData;
use Exception;
use PEARX\PackageXml\Parser as PackageXmlParser;

class Installer 
{
public $workspace = 'workspace';

public function setWorkspace($path)
{
$this->workspace = $path;
}

public function getWorkspace()
{
return $this->workspace;
}








public function getWorkspaceForPackage($distPath)
{
$name = strtolower(preg_replace('#\W+#','_',basename($distPath))) . '_' . time();
return $this->getWorkspace() . DIRECTORY_SEPARATOR . $name;
}

public function install($distPath,$targetDir)
{
$distFile = basename($distPath);
$packageDir = $this->getWorkspaceForPackage($distPath);

$this->extract($distPath,$packageDir);

if( ! file_exists($targetDir) )
mkdir( $targetDir , 0755, true );
if( ! file_exists($packageDir) )
mkdir( $packageDir , 0755, true );


$parser = new PackageXmlParser;
$package = $parser->parse( $packageDir . DIRECTORY_SEPARATOR . 'package.xml' );

$sourceDir = $packageDir . DIRECTORY_SEPARATOR . $package->getName() . '-' . $package->getReleaseVersion();
$filelist = $package->getInstallFileList( $sourceDir, $targetDir );


foreach( $filelist as $install ) {
$dir = dirname( $install->to );
if( ! file_exists( $dir ) )
mkdir( $dir , 0755 , true );


copy( $install->from , $install->to );
}
return $filelist;
}

public function extract($file,$targetPath)
{
$archive = new PharData($file);
$archive->extractTo( $targetPath );
return $archive;
}


}



<?php
namespace PEARX;
use PEARX\Utils;

class Category
{

public $channel;


public $name;

public $infoUrl;

public $packagesInfoUrl;

public $infoXml;

public $packagesInfoXml;

public function __construct($channel,$name,$infoPath)
{
$this->channel = $channel;
$this->name = $name;
$this->infoUrl = $this->channel->getBaseUrl() . $infoPath;
$this->packagesInfoUrl = str_replace('info.xml', 'packagesinfo.xml', $this->channel->getBaseUrl() . $infoPath );
}

public function fetchInfoXml()
{
$xmlstr = $this->channel->core->request( $this->infoUrl );
$this->infoXml = Utils::create_dom();
$this->infoXml->loadXml( $xmlstr );

}

public function getPackages()
{
$xmlstr = $this->channel->core->request( $this->packagesInfoUrl );

$xml = Utils::create_dom();
if( false === $xml->loadXml( $xmlstr ) ) {
throw new Exception( "Package Info XML load failed: " . $this->packagesInfoUrl );
}

$this->packagesInfoXml = $xml;

try {

$packageNodes = $xml->getElementsByTagName('pi');
$packages = array();
foreach( $packageNodes as $node ) {
$package = new PackageCollection;

$p = $node->getElementsByTagName('p')->item(0);
$package->name = $p->getElementsByTagName('n')->item(0)->nodeValue;
$package->summary = $p->getElementsByTagName('s')->item(0)->nodeValue;
$package->description = $p->getElementsByTagName('d')->item(0)->nodeValue;

$package->channel = $this->channel;
$package->license = $p->getElementsByTagName('l')->item(0)->nodeValue;

$depsList = $node->getElementsByTagName('deps');
foreach( $depsList as $depsNode ) {
$v = $depsNode->getElementsByTagName('v')->item(0)->nodeValue;
$d = unserialize($depsNode->getElementsByTagName('d')->item(0)->nodeValue); 
$package->deps[$v] = $d;
}

$latestStable = 0;
$latestAlpha = 0;
$latestBeta = 0;
$latest = 0;
$a = $node->getElementsByTagName('a')->item(0);
if( $a && $releases = $a->getElementsByTagName('r') ) {
foreach( $releases as $release ) {
$version = $release->getElementsByTagName('v')->item(0)->nodeValue;
$stability = $release->getElementsByTagName('s')->item(0)->nodeValue;

$package->addRelease( $version , $stability );

if( version_compare( $version , $latest ) === 1 ) {
$latest = $version;
}

switch( $stability ) {
case 'stable':
if( version_compare( $version , $latestStable ) === 1 ) {
$latestStable = $version;
}
break;
case 'alpha':
if( version_compare( $version , $latestAlpha ) === 1 ) {
$latestAlpha = $version;
}
break;
case 'beta':
if( version_compare( $version , $latestBeta ) === 1 ) {
$latestBeta = $version;
}
break;
}
}
}

$package->stable = $latestStable;
$package->alpha = $latestAlpha;
$package->beta = $latestBeta;
$package->latest = $latest;

$packages[ $package->name ] = $package;
}

} catch ( Exception $e ) {
die( "Package parsing failed: {$this->packagesInfoUrl}" . $e->getMessage() );
}
return $packages;
}

}


<?php
namespace PEARX;
use PEARX\Package;

class PackageCollection extends Package
{




public $releases = array();





public $versions = array();




public $deps = array();




public $stable;





public $alpha;




public $beta;




public $latest;





public function addRelease( $version , $stability )
{
$this->releases[] = (object) array( 
'version' => $version,
'stability' => $stability,
);
$this->versions[ $version ] = $stability;
}

public function getRelease( $version ) 
{
if( isset( $this->versions[ $version ] ) )
return $this->versions[ $version ];
}

public function getReleaseDistUrl($version, $extension = 'tgz' )
{


return sprintf('%s/get/%s-%s.%s',$this->channel->getBaseUrl(), $this->name , $version , $extension );
}

public function getLastReleaseDistUrl()
{
return $this->getReleaseDistUrl( $this->latest );
}

}


<?php
namespace PEARX;

class Core
{
public $downloader;
public $cache;

function __construct( $options = array() )
{
if( isset($options['cache']) ) {
$this->cache = $options['cache'];
}

if( isset($options['downloader']) ) {
$this->downloader = $options['downloader'];
}

if( isset($options['retry']) ) {
$this->retry = $options['retry'];
}
}

public function request($url, $force = false)
{
if( false == $force && $this->cache && $content = $this->cache->get( $url ) ) {
if( $content )
return $content;
}

if( $this->downloader ) {
$content = $this->downloader->fetch( $url );
}
ini_set('default_socket_timeout', 120);
$content = file_get_contents($url);

if( $this->cache ) {
$this->cache->set( $url , $content );
}
return $content;
}


}


<?php

namespace PEARX;

use DOMDocument;
use Exception;










class Channel
{



public $name;




public $alias;




public $summary;




public $primary = array();




public $rest; 

public $cache;

public $downloader;

public $retry = 3;

public $channelXml;




public $scheme = 'http';

public $core;

private $host;
private $init = false;





public function __construct($host, $options = array() )
{
$this->core = new Core( $options );
$this->host = $host;
}




public function getBaseUrl()
{
$this->init();

return $this->scheme . '://' . $this->name;
}






public function getRestBaseUrl($version = null)
{
$this->init();

if( $version && $this->primary[$version] ) {
return rtrim($this->primary[ $version ],'/');
}

return rtrim($this->primary[ $this->rest ],'/');
}








public function fetchPackageReleaseXml($packageName, $version = 'stable')
{
$baseUrl = $this->getRestBaseUrl();
$url = "$baseUrl/r/" . strtolower($packageName);

if ( $version === 'stable'
|| $version === 'latest'
|| $version === 'beta'
) {

$ret = file_get_contents($url . '/' . $version . '.txt');
if ($ret === false) {
throw new Exception("Invalid package version: $packageName with version '$version'.");
}
$version = $ret;
}

$url = $url . '/' . $version . '.xml';
$xmlStr = $this->core->request($url);


$xml = Utils::create_dom();
if( false === $xml->loadXml( $xmlStr ) ) {
throw new Exception("Error in XMl document: $url");
}
return $xml;
}








public function fetchChannelXml($host)
{
$xmlstr = $this->core->cache ? $this->core->cache->get( $host ) : null;


if( null !== $xmlstr ) {
return $xmlstr;
}

$httpUrl = 'http://' . $host . '/channel.xml';
$httpsUrl = 'https://' . $host . '/channel.xml';
while( $this->retry-- ) {
try {
if( $xmlstr = $this->core->request($httpUrl) ) {
$this->scheme = 'http';
break;
}
if( $xmlstr = $this->core->request( $httpsUrl ) ) {
$this->scheme = 'https';
break;
}
} catch( Exception $e ) {
fwrite( STDERR , "PEAR Channel discover failed: $host\n" );
fwrite( STDERR , $e->getMessage() . "\n" );
}
}

if( ! $xmlstr ) {
throw new Exception('channel.xml fetch failed.');
}


if( $this->cache ) {
$this->cache->set($host, $xmlstr );
}
return $xmlstr;
}




public function getCategories()
{
$baseUrl = $this->getRestBaseUrl();
$url = $baseUrl . '/c/categories.xml';
$xmlStr = $this->core->request($url);


$xml = Utils::create_dom();
if( false === $xml->loadXml( $xmlStr ) ) {
throw new Exception("Error in XMl document: $url");
}

$list = array();
$nodes = $xml->getElementsByTagName('c');
foreach ($nodes as $node) {

$link = $node->getAttribute("xlink:href");
$name = $node->nodeValue;
$category = new Category( $this, $name , $link );
$list[] = $category;
}
return $list;
}







public function getPackages()
{
$packages = array();
foreach( $this->getCategories() as $category ) {
$packages[ $category->name ] = $category->getPackages();
}
return $packages;
}







public function findPackage($name)
{
foreach( $this->getCategories() as $category ) {
$packages = $category->getPackages();
if( isset($packages[$name]) ) {
return $packages[$name];
}
}
}






private function init()
{
if ($this->init) {
return;
}

$this->channelXml = $this->fetchChannelXml( $this->host );

$parser = new ChannelParser;
$info = $parser->parse( $this->channelXml );

$this->name = $info->name;
$this->summary = $info->summary;
$this->alias = $info->alias;
$this->primary = $info->primary;
$this->rest = $info->rest;

$this->init = true;
}
}


<?php
namespace PEARX;
use Exception;
use DateTime;
use PEARX\Channel;

class Package
{
public $name;

public $summary;

public $description;





public $date;




public $time;


private $_datetime;




public $channel;





public $license;

public $authors = array();

public $apiVersion;

public $releaseVersion;

public $apiStability;

public $releaseStability;

public $contents = array();

public $requiredDependencies = array();

public $optionalDependencies = array();

public $phpReleaseFileList = array();

public $providesExtension;

public $zendExtSrcRelease;






public $configureOptions = array();


public function setName($name) 
{
$this->name = $name;
}

public function getName()
{
return $this->name;
}

public function setVersion($version)
{
$this->apiVersion = $version;
$this->releaseVersion = $version;
}

public function setApiVersion($version)
{
$this->apiVersion = $version;
}

public function getApiVersion()
{
return $this->apiVersion;
}

public function setReleaseVersion($version)
{
$this->releaseVersion = $version;
}

public function getReleaseVersion()
{
return $this->releaseVersion;
}


public function setStability($s) 
{
$this->apiStability = $s;
$this->releaseStability = $s;
}

public function setReleaseStability($s)
{
$this->releaseStability = $s;
}

public function setApiStability($s)
{
$this->apiStability = $s;
}

public function setProvidesExtension($extName) {
$this->providesExtension = $extName;
}

public function setZendExtSrcRelease() {
$this->zendExtSrcRelease = true;
}

public function getProvidesExtension() {
return $this->providesExtension;
}

public function getZendExtSrcRelease() {
return $this->zendExtSrcRelease;
}


public function getDate()
{
return $this->date;
}

public function getTime()
{
return $this->time;
}

public function getDateTime()
{
if( $this->date && $this->time ) {
return new DateTime( 
sprintf('%s %s', $this->date, $this->time)
);
}
if( $this->_datetime ) {
return $this->_datetime;
}
}

public function setDateTime($datetime)
{
if ( is_string($datetime) ) {

$datetime = new DateTime($datetime);
}

if( $datetime instanceof DateTime ) {
$this->date = $datetime->format('Y-m-d');
$this->time = $datetime->format('H:i:s');
$this->_datetime = $datetime;
} else {
throw new Exception("Invalid DateTime format.");
}
}

public function setDate($date) 
{
$this->date = $date;
}

public function setTime($time)
{
$this->time = $time;
}

public function getChannel()
{
return $this->channel;
}

public function setChannel($c)
{
if( is_string($c) ) {
$this->channel = new Channel($c);
} elseif( $c instanceof Channel ) {
$this->channel = $c;
} else {
throw new Exception("Unknown channel argument.");
}
}

public function setLicense($license)
{
$this->license = $license;
}

public function getLicense()
{
return $this->license;
}

public function setSummary($summary)
{
$this->summary = $summary;
}


public function getSummary()
{
return $this->summary;
}


public function setDescription($desc)
{
$this->description = $desc;
}

public function getDescription()
{
return $this->description;
}

public function getId()
{
return $this->name;
}

public function addContent(PackageXml\ContentFile $content)
{
$this->contents[] = $content;
}

public function setContents($contents)
{
$this->contents = $contents;
}

public function getContents()
{
return $this->contents;
}








public function getContentsByRole($role)
{
return array_filter($this->contents , function($item) use ($role) {
return $item->role === $role;
});
}

public function validateDependencyType($type)
{
switch ($type) {
case 'arch':
case 'extension':
case 'os':
case 'package':
case 'pearinstaller':
case 'php':
return;
}

throw new Exception('Unsupported pear dependency type: ' . $type);
}


























public function addRequiredDependency($type,$dep)
{

$this->validateDependencyType($type);
$dep['type'] = $type;
$this->requiredDependencies[] = $dep;
}

public function addOptionalDependency($type,$dep)
{
$this->validateDependencyType($type);
$dep['type'] = $type;
$this->optionalDependencies[] = $dep;
}

public function addFileToReleaseFileList($name,$as)
{
$this->phpReleaseFileList[$name] = $as;
}

public function getReleaseFileList()
{
return $this->phpReleaseFileList;
}








public function getInstallFileList($sourceDir = null, $distDir = null)
{
$installMap = $this->getReleaseFileList();
$filelist = array();
foreach( $this->getContents() as $file ) 
{
if( $file->role == 'php' ) {
$installFrom = $sourceDir 
? $sourceDir . DIRECTORY_SEPARATOR . $file->file
: $file->file;
if( isset($installMap[ $file->file ]) ) {
$installAs = $installMap[ $file->file ];
} else {
$installAs = $file->getInstallAs();
}

if ( $distDir ) {
$installAs = $distDir . DIRECTORY_SEPARATOR . $installAs;
}

$filelist[] = (object) array(
'from' => $installFrom,
'to' => $installAs,
);
}
}
return $filelist;
}

public function addConfigureOption($optName, $prompt, $default = NULL) {
$this->configureOptions[] = (object) array(
'name' => $optName,
'prompt' => $prompt,
'default' => $default,
);
}

public function getConfigureOptions() {
return $this->configureOptions;
}
}

<?php
namespace PEARX;
use SimpleXMLElement;
use Exception;












class ChannelParser 
{

function parse($arg)
{
$xmlstr = null;
if( strpos($arg,'<?xml') === 0 ) {
$xmlstr = $arg;
} elseif( is_file($arg) || preg_match('#^https?://#',$arg) ) {
$xmlstr = file_get_contents($arg);
} else {
throw new Exception("Unexpected argument for channel parser.");
}


$xml = new SimpleXMLElement($xmlstr);

$channel = array();
$channel['name'] = (string) $xml->name;
$channel['summary'] = (string) $xml->summary;
$channel['alias'] = (string) $xml->suggestedalias;


$channel['primary'] = array();
$channel['rest'] = 'REST1.0';
foreach( $xml->servers->primary->rest->baseurl as $element ) {
$attrs = $element->attributes();
$version = (string) $attrs->type; 
$channel['primary'][ $version ] = (string) $element;
if( version_compare( $version , $channel['rest'] ) >= 0 ) {
$channel['rest'] = $version;
}
}
return (object) $channel;
}

}

<?php









namespace PEARX\PackageXml;
use SimpleXMLElement;
use Exception;
use PEARX\PackageXml\ContentFile;

class XmlException extends Exception { }






class Parser
{
public $xml;

public function __construct()
{
}

public function parse($arg) 
{
if( strpos($arg,'<?xml') === 0 ) {
$this->xml = new SimpleXMLElement( $arg );
}
elseif( file_exists($arg) || preg_match('#^https?://#',$arg) ) {
$this->xml = new SimpleXMLElement( file_get_contents( $arg ) );
}
else {
throw new XmlException('Invalid xml argument.');
}
$xml = $this->xml;

$package = new \PEARX\Package;

if ($xml->channel) {
$package->setChannel( $xml->channel->__toString() );
}

$package->setName( $xml->name->__toString() );
$package->setSummary( $xml->summary->__toString() );
$package->setDescription( $xml->description->__toString() );
$package->setDate( $xml->date->__toString() );
$package->setTime( $xml->time->__toString() );

if ($xml->version) {
if ($xml->version->api) {
$package->setApiVersion( $xml->version->api->__toString() );
}
if ($xml->version->release) {
$package->setReleaseVersion( $xml->version->release->__toString() );
}
}

if ($xml->stability) {
$package->setApiStability( $xml->stability->api->__toString() );
$package->setReleaseStability( $xml->stability->release->__toString() );
}

if ($extName = $xml->providesextension->__toString()) {
$package->setProvidesExtension($extName);
}

if ($extsrcrelease = $xml->extsrcrelease) {
foreach ($extsrcrelease->children() as $opt) {
$package->addConfigureOption( (string)$opt['name'], (string)$opt['prompt'], (string)$opt['default']);
}
}

if ($xml->zendextsrcrelease) {
$package->setZendExtSrcRelease();
}




if ($xml->contents) {
if ($contents = $this->parseContents($xml)) {
$package->setContents($contents);
}
}

if( $xml->dependencies->required ) {
$deps = $this->parseDependencyElement($xml->dependencies->required);
foreach( $deps as $dep )
$package->addRequiredDependency($dep['type'],$dep);
}

if( $xml->dependencies->optional ) {
$deps = $this->parseDependencyElement($xml->dependencies->optional);
foreach( $deps as $dep )
$package->addOptionalDependency($dep['type'],$dep);
}


if( $phprelease = $xml->phprelease ) {
if( $phprelease->filelist ) {
foreach( $phprelease->filelist->children() as $install ) {
$package->addFileToReleaseFileList( $install['name']->__toString(), $install['as']->__toString() );
}
}
}
return $package;
}






public function traverseContents($children, $parentPath = null )
{
$files = array();
if (!$children)
return $files;

foreach($children as $node) {
if( $node->getName() == 'dir' ) {
$dirname = $node['name'];
$baseInstallDir = @$node['baseinstalldir'];

$dirpath = $parentPath;
if ($dirname != '/')
$dirpath .= $dirname . DIRECTORY_SEPARATOR;


if ($baseInstallDir)
$dirpath .= ltrim($baseInstallDir,DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;

$subfiles = $this->traverseContents($node->children(), $dirpath );
$files = array_merge( $files , $subfiles );
}
elseif( $node->getName() == 'file' ) {
$filename = (string) $node['name'];
$installAs = (string) @$node['install-as'];
$baseInstallDir = (string) @$node['baseinstalldir'];
$role = (string) @$node['role'];
$md5sum = (string) @$node['md5sum'];

$file = $baseInstallDir
? new ContentFile( $parentPath . ltrim($baseInstallDir,DIRECTORY_SEPARATOR). $filename )
: new ContentFile( $parentPath . $filename );

if( $installAs )
$file->installAs = $parentPath . $installAs;

$file->setRole($role);
$file->md5sum = $md5sum;
$files[] = $file;
}
}
return $files;
}






public function getPhpReleaseFileList()
{

$phprelease = $this->xml->phprelease;
$filelist = array();
if( $phprelease->filelist ) {
foreach( $phprelease->filelist->children() as $install ) 
{
$filelist[] = (object) array(
'file' => (string) $install['name'], 
'as' => (string) @$install['as']
);
}
}
return $filelist;
}








public function getContentsByRole($role)
{
$files = $this->getContentFiles();
return array_filter( $files , function($item) use ($role) { 
return $item->role == $role;
});
}





public function parseContents($xml)
{
return $this->traverseContents( 
$xml->contents->children()
);
}


public function parseDependencyElement($parent)
{
$children = $parent->children();
$deps = array();
foreach( $children as $element ) {
$attrs = array();
foreach( $element->children() as $attr ) {
$attrs[ $attr->getName() ] = $attr->__toString();
}
$attrs['type'] = $element->getName();
$deps[] = $attrs;
}
return $deps;
}




public function getContentFiles()
{
return $this->parseContents($this->xml);
}


public function getContentFilesByRole($role)
{
return $this->getContentsByRole($role);
}




}

<?php









namespace PEARX\PackageXml;

class ContentFile
{



public $file;

public $installAs;

public $role;

public $md5sum;





public function __construct($file)
{
$this->file = $file;
}


public function getFile()
{
return $this->file;
}

public function setFile($file)
{
$this->file = $file;
}

public function getRole()
{
return $this->role;
}

public function setRole($role)
{
$this->role = $role;
}

public function getInstallAs()
{
if( $this->installAs )
return $this->installAs;
return $this->file;
}
}

<?php









namespace PEARX\PackageXml;

use SimpleXMLElement;
use DOMDocument;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Onion\SpecUtils;
use SplFileInfo;











class PackageXmlGenerator
{
public $package;
public $reformat = true;
public $useDefault = true;




public function __construct($package)
{
$this->package = $package;
}

public function setUseDefault($bool)
{
$this->useDefault = $bool;
}

public function setReformat($bool)
{
$this->reformat = $bool;
}

public function generate()
{
try {
$package = $this->package;
$config = $this->package->config;

$xmlstr = <<<XML
<package packagerversion="1.4.10" version="2.0"
    xmlns="http://pear.php.net/dtd/package-2.0"
    xmlns:tasks="http://pear.php.net/dtd/tasks-1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
              http://pear.php.net/dtd/tasks-1.0.xsd
              http://pear.php.net/dtd/package-2.0
              http://pear.php.net/dtd/package-2.0.xsd">
</package>
XML;

$xml = new SimpleXMLElement($xmlstr);
$xml->name = $config->{ 'package.name' };
$xml->channel = $config->{ 'package.channel' };
$xml->summary = $config->{ 'package.summary' };
$xml->description = $config->{ 'package.desc' };

if ($config->has('package.extends'))
$xml->extends = $config->get('package.extends');

$author_data = SpecUtils::parseAuthor($config->get('package.author'));
$lead = $xml->addChild('lead');
foreach ($author_data as $k => $v)
$lead->$k = $v;
$lead->active = 'yes';

if ($config->has('package.authors')) {
foreach ($config->get('package.authors') as $author) {
$lead = $xml->addChild('lead');
$data = SpecUtils::parseAuthor($author);
foreach ($data as $k => $v)
$lead->$k = $v;
$lead->active = 'yes';
}
}

$xml->date = date('Y-m-d');
$xml->time = strftime('%T');


$version = $xml->addChild('version');
$version->release = $config->get('package.version');
$version->api = $config->get('package.version.api');


$stability = $xml->addChild('stability');
$stability->release = $config->get('package.stability.release'); 
$stability->api = $config->get('package.stability.api');



$xml->license = $config->get('package.license');

$xml->notes = $config->get('package.notes') ? : '-';



$roles = $package->getDefaultStructureConfig();

$filelist = array();
foreach ($roles as $role => $paths) {
foreach ($paths as $path) {
$files = $this->addPathByRole($path, $role);
$filelist = array_merge($filelist, $files);
}
}

$customRoles = $config->get('roles');
if ($customRoles) {
foreach ($customRoles as $pattern => $role) {
if (in_array($pattern, $roles['test'])) {
continue;
}
$files = $this->addPathByRole($pattern, $role);
$filelist = array_merge($filelist, $files);
}
}

$contentsXml = $xml->addChild('contents');
$dir = $contentsXml->addChild('dir');
$dir->addAttribute('name', '/');
foreach ($filelist as $contentFile) { 
$file = $dir->addChild('file');
$file->addAttribute('name', $contentFile->file);
$file->addAttribute('role', $contentFile->role);
$file->addAttribute('md5sum', $contentFile->md5sum);
}

$deps = $xml->addChild('dependencies');
$required = $deps->addChild('required');


foreach ($package->deps as $dep) {







$logger->debug2(sprintf("dependency %-10s %s", $dep['type'], $dep['name']), 1);


switch ($dep['type']) {

case 'core':
$name = $dep['name'];
$depCore = $required->addChild($name);
if ($dep['version']) {
foreach ($dep['version'] as $k => $v) {
$depCore->addChild($k, $v);
}
}
break;

case 'pear':
$depPackage = $required->addChild('package');
$depPackage->addChild('name', $dep['name']);

if ($dep['resource']['type'] == 'channel') {
$channelHost = $dep['resource']['channel'];
$depPackage->addChild('channel', $channelHost);
}
if ($dep['version']) {
foreach ($dep['version'] as $k => $v) {
$depPackage->addChild($k, $v);
}
}
break;
case 'extension':
$depExtension = $required->addChild('extension');
$depExtension->addChild('name', $dep['name']);
if ($dep['version']) {
foreach ($dep['version'] as $k => $v) {
$depExtension->addChild($k, $v);
}
}
break;
}
}





$logger->info("Building phprelease section..."); {
$phprelease = $xml->addChild('phprelease');
$filelistNode = $phprelease->addChild('filelist');
foreach ($filelist as $contentFile) { 
$file = $filelistNode->addChild('install');
$file->addAttribute('name', $contentFile->file);
$file->addAttribute('as', $contentFile->installAs);
}
}
} catch (Exception $e) {
$logger->error($e->getMessage());
exit(1);
}


if (class_exists('DOMDocument')) {
$logger->info2("* Re-formating XML...", 1);
$dom = new \DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
return $dom->saveXML();
}
return $xml->asXML();
}

public function addPathByRole($path, $role)
{
$list = array();
if (is_dir($path)) {
$baseDir = $path;
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($baseDir),
RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $path) {
if ($path->isFile()) {
$filepath = $path->getPathname();
$list[(string) $path] = $this->buildContentFile($path, $role, $baseDir);
}
}
} else {
$files = glob($path);
foreach ($files as $filename) {
$fileinfo = new SplFileInfo($filename);
$list[(string) $filename] = $this->buildContentFile($fileinfo, $role);
}
}
return $list;
}

public function buildContentFile($fileinfo, $role, $baseDir = '')
{
$filepath = $fileinfo->getPathname();
$contentFile = new PackageXml\ContentFile($filepath);
$contentFile->role = $role;
$contentFile->md5sum = md5_file($filepath);

$contentFile->installAs = basename($filepath);
if ($baseDir)
$contentFile->installAs = substr($filepath, strlen($baseDir) + 1);

$this->logger->debug2(sprintf('%s  %-5s  %s', substr($contentFile->md5sum, 0, 6), $contentFile->role, $contentFile->file
), 1);
return $contentFile;
}
}
<?php
namespace PEARX;
use DOMDocument;
use Exception;

class Utils
{

static function create_dom()
{
$dom = new DOMDocument('1.0');
$dom->strictErrorChecking = false;
$dom->preserveWhiteSpace = false;
$dom->resolveExternals = false;
return $dom;
}

static function load_xml($xml)
{
$dom = self::create_dom();
if( false === $dom->loadXml( $xml ) ) {
throw new Exception( "XML Document load failed." );
}
return $dom;
}

}




<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://phpdox.de/config" silent="false">
    <project name="PEARX" source="src" workdir="build/phpdox">
        <collector publiconly="false">
            <include mask="*.php" />
            <exclude mask="*Autoload.php" />
        </collector>

        <generator output="build">
            <build engine="html" enabled="true" output="api"/>
            <build engine="graph" enabled="true" output="graph">
                <dot executable="/usr/bin/dot" render="true" format="png" />
            </build>
        </generator>
    </project>
</phpdox>
Steps = PHPUnit, BumpVersion, GitCommit, GitTag, GitPush, GitPushTags
; VersionFrom = src/PHPRelease/Console.php<?xml version="1.0"?>
<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.10" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0               http://pear.php.net/dtd/tasks-1.0.xsd               http://pear.php.net/dtd/package-2.0               http://pear.php.net/dtd/package-2.0.xsd">
  <name>PEARX</name>
  <channel>pear.corneltek.com</channel>
  <summary>A Non-PEAR-Installer-Dependency PEAR Channel Library.</summary>
  <description>A Non-PEAR-Installer-Dependency PEAR Channel Library.</description>
  <lead>
    <name>Yo-An Lin</name>
    <user/>
    <email>cornelius.howl@gmail.com</email>
    <active>yes</active>
  </lead>
  <date>2013-03-08</date>
  <time>18:06:59</time>
  <version>
    <release>1.2.3</release>
    <api>1.2.3</api>
  </version>
  <stability>
    <release>stable</release>
    <api>stable</api>
  </stability>
  <license>PHP</license>
  <notes>-</notes>
  <contents>
    <dir name="/">
      <file name="src/PEARX/Category.php" role="php" md5sum="2a1de9272848403f88895498084c8b08"/>
      <file name="src/PEARX/Channel.php" role="php" md5sum="8c7c87f9ac21b4c08b7b9c1d58b96c24"/>
      <file name="src/PEARX/ChannelParser.php" role="php" md5sum="7c5b3c92273ef7afd89f7fa3b147ce98"/>
      <file name="src/PEARX/Core.php" role="php" md5sum="e9029e883f8dfc9e7d63ec8f6ceff42f"/>
      <file name="src/PEARX/Installer.php" role="php" md5sum="81ec5a78ebc102b61d3f201270f65cc6"/>
      <file name="src/PEARX/Package.php" role="php" md5sum="2ec472d451d5fe1126c6c04c509c6c9d"/>
      <file name="src/PEARX/PackageCollection.php" role="php" md5sum="5bd0374c113ae773ec578566547bcd45"/>
      <file name="src/PEARX/PackageXml/ContentFile.php" role="php" md5sum="7d2947a90d6c63091ee6549360f2a5c8"/>
      <file name="src/PEARX/PackageXml/Generator.php" role="php" md5sum="701c66d2acf87d1bf658b198a08e9df8"/>
      <file name="src/PEARX/PackageXml/Parser.php" role="php" md5sum="38a35c3922f118ccaadbd5075f276acd"/>
      <file name="src/PEARX/Utils.php" role="php" md5sum="36dc09cc50971c50bf24df76bb169103"/>
    </dir>
  </contents>
  <dependencies>
    <required>
      <php>
        <min>5.3</min>
      </php>
      <pearinstaller>
        <min>1.4</min>
      </pearinstaller>
      <package>
        <name>Universal</name>
        <channel>pear.corneltek.com</channel>
        <min>0.0.0</min>
      </package>
      <package>
        <name>CacheKit</name>
        <channel>pear.corneltek.com</channel>
        <min>0.0.0</min>
      </package>
    </required>
  </dependencies>
  <phprelease>
    <filelist>
      <install name="src/PEARX/Category.php" as="PEARX/Category.php"/>
      <install name="src/PEARX/Channel.php" as="PEARX/Channel.php"/>
      <install name="src/PEARX/ChannelParser.php" as="PEARX/ChannelParser.php"/>
      <install name="src/PEARX/Core.php" as="PEARX/Core.php"/>
      <install name="src/PEARX/Installer.php" as="PEARX/Installer.php"/>
      <install name="src/PEARX/Package.php" as="PEARX/Package.php"/>
      <install name="src/PEARX/PackageCollection.php" as="PEARX/PackageCollection.php"/>
      <install name="src/PEARX/PackageXml/ContentFile.php" as="PEARX/PackageXml/ContentFile.php"/>
      <install name="src/PEARX/PackageXml/Generator.php" as="PEARX/PackageXml/Generator.php"/>
      <install name="src/PEARX/PackageXml/Parser.php" as="PEARX/PackageXml/Parser.php"/>
      <install name="src/PEARX/Utils.php" as="PEARX/Utils.php"/>
    </filelist>
  </phprelease>
</package>
[package]
name = PEARX
version = 1.2.3
desc = "A Non-PEAR-Installer-Dependency PEAR Channel Library."
stability = stable
channel = pear.corneltek.com
author = Yo-An Lin <cornelius.howl@gmail.com>

[require]
php = 5.3
pearinstaller = 1.4
pear.corneltek.com/Universal = 0
pear.corneltek.com/CacheKit = 0
# Doxyfile 1.7.5.1

# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a hash (#) is considered a comment and will be ignored.
# The format is:
#       TAG = value [value, ...]
# For lists items can also be appended using:
#       TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ").

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------

# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.

DOXYFILE_ENCODING      = UTF-8

# The PROJECT_NAME tag is a single word (or sequence of words) that should
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.

PROJECT_NAME           = Phifty

# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.

PROJECT_NUMBER         =

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
# a quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF          =

# With the PROJECT_LOGO tag one can specify an logo or icon that is
# included in the documentation. The maximum height of the logo should not
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
# Doxygen will copy the logo to the output directory.

PROJECT_LOGO           =

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.

OUTPUT_DIRECTORY       = build/doxygen

# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
# format and will distribute the generated files over these directories.
# Enabling this option can be useful when feeding doxygen a huge amount of
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.

CREATE_SUBDIRS         = NO

# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.

OUTPUT_LANGUAGE        = English

# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.

BRIEF_MEMBER_DESC      = YES

# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.

REPEAT_BRIEF           = YES

# This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string
# in this list, if found as the leading text of the brief description, will be
# stripped from the text and the result after processing the whole list, is
# used as the annotated text. Otherwise, the brief description is used as-is.
# If left blank, the following values are used ("$name" is automatically
# replaced with the name of the entity): "The $name class" "The $name widget"
# "The $name file" "is" "provides" "specifies" "contains"
# "represents" "a" "an" "the"

ABBREVIATE_BRIEF       =

# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.

ALWAYS_DETAILED_SEC    = NO

# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.

INLINE_INHERITED_MEMB  = NO

# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.

FULL_PATH_NAMES        = YES

# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the
# path to strip.

STRIP_FROM_PATH        =

# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
# the reader which header file to include in order to use a class.
# If left blank only the name of the header file containing the class
# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.

STRIP_FROM_INC_PATH    =

# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
# (but less readable) file names. This can be useful if your file system
# doesn't support long names like on DOS, Mac, or CD-ROM.

SHORT_NAMES            = NO

# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)

JAVADOC_AUTOBRIEF      = YES

# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
# interpret the first line (until the first dot) of a Qt-style
# comment as the brief description. If set to NO, the comments
# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)

QT_AUTOBRIEF           = NO

# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.

MULTILINE_CPP_IS_BRIEF = NO

# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# re-implements.

INHERIT_DOCS           = YES

# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
# a new page for each member. If set to NO, the documentation of a member will
# be part of the file/class/namespace that contains it.

SEPARATE_MEMBER_PAGES  = NO

# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.

TAB_SIZE               = 4

# This tag can be used to specify a number of aliases that acts
# as commands in the documentation. An alias has the form "name=value".
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
# put the command \sideeffect (or @sideeffect) in the documentation, which
# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.

ALIASES                =

# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.

OPTIMIZE_OUTPUT_FOR_C  = NO

# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
# sources only. Doxygen will then generate output that is more tailored for
# Java. For instance, namespaces will be presented as packages, qualified
# scopes will look different, etc.

OPTIMIZE_OUTPUT_JAVA   = NO

# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources only. Doxygen will then generate output that is more tailored for
# Fortran.

OPTIMIZE_FOR_FORTRAN   = NO

# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for
# VHDL.

OPTIMIZE_OUTPUT_VHDL   = NO

# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given extension.
# Doxygen has a built-in mapping, but you can override or extend it using this
# tag. The format is ext=language, where ext is a file extension, and language
# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.

EXTENSION_MAPPING      = .php

# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
# func(std::string) {}). This also makes the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.

BUILTIN_STL_SUPPORT    = NO

# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.

CPP_CLI_SUPPORT        = NO

# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
# Doxygen will parse them like normal C++ but will assume all classes use public
# instead of private inheritance when no explicit protection keyword is present.

SIP_SUPPORT            = NO

# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.

IDL_PROPERTY_SUPPORT   = YES

# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.

DISTRIBUTE_GROUP_DOC   = NO

# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
# the same type (for instance a group of public functions) to be put as a
# subgroup of that type (e.g. under the Public Functions section). Set it to
# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.

SUBGROUPING            = YES

# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
# unions are shown inside the group in which they are included (e.g. using
# @ingroup) instead of on a separate page (for HTML and Man pages) or
# section (for LaTeX and RTF).

INLINE_GROUPED_CLASSES = NO

# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
# unions with only public data fields will be shown inline in the documentation
# of the scope in which they are defined (i.e. file, namespace, or group
# documentation), provided this scope is documented. If set to NO (the default),
# structs, classes, and unions are shown on a separate page (for HTML and Man
# pages) or section (for LaTeX and RTF).

INLINE_SIMPLE_STRUCTS  = NO

# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically
# be useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.

TYPEDEF_HIDES_STRUCT   = NO

# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
# determine which symbols to keep in memory and which to flush to disk.
# When the cache is full, less often used symbols will be written to disk.
# For small to medium size projects (<1000 input files) the default value is
# probably good enough. For larger projects a too small cache size can cause
# doxygen to be busy swapping symbols to and from disk most of the time
# causing a significant performance penalty.
# If the system has enough physical memory increasing the cache will improve the
# performance by keeping more symbols in memory. Note that the value works on
# a logarithmic scale so increasing the size by one will roughly double the
# memory usage. The cache size is given by this formula:
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols

SYMBOL_CACHE_SIZE      = 0

#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------

# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES

EXTRACT_ALL            = YES

# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.

EXTRACT_PRIVATE        = NO

# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.

EXTRACT_STATIC         = NO

# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.

EXTRACT_LOCAL_CLASSES  = YES

# This flag is only useful for Objective-C code. When set to YES local
# methods, which are defined in the implementation section but not in
# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.

EXTRACT_LOCAL_METHODS  = NO

# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base
# name of the file that contains the anonymous namespace. By default
# anonymous namespaces are hidden.

EXTRACT_ANON_NSPACES   = NO

# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.

HIDE_UNDOC_MEMBERS     = NO

# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.

HIDE_UNDOC_CLASSES     = NO

# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
# friend (class|struct|union) declarations.
# If set to NO (the default) these declarations will be included in the
# documentation.

HIDE_FRIEND_COMPOUNDS  = NO

# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
# documentation blocks found inside the body of a function.
# If set to NO (the default) these blocks will be appended to the
# function's detailed documentation block.

HIDE_IN_BODY_DOCS      = NO

# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.

INTERNAL_DOCS          = NO

# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
# file names in lower-case letters. If set to YES upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.

CASE_SENSE_NAMES       = NO

# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.

HIDE_SCOPE_NAMES       = NO

# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put a list of the files that are included by a file in the documentation
# of that file.

SHOW_INCLUDE_FILES     = YES

# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
# will list include files with double quotes in the documentation
# rather than with sharp brackets.

FORCE_LOCAL_INCLUDES   = NO

# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.

INLINE_INFO            = YES

# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.

SORT_MEMBER_DOCS       = YES

# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
# brief documentation of file, namespace and class members alphabetically
# by member name. If set to NO (the default) the members will appear in
# declaration order.

SORT_BRIEF_DOCS        = NO

# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
# will sort the (brief and detailed) documentation of class members so that
# constructors and destructors are listed first. If set to NO (the default)
# the constructors will appear in the respective orders defined by
# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.

SORT_MEMBERS_CTORS_1ST = NO

# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
# hierarchy of group names into alphabetical order. If set to NO (the default)
# the group names will appear in their defined order.

SORT_GROUP_NAMES       = NO

# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
# sorted by fully-qualified names, including namespaces. If set to
# NO (the default), the class list will be sorted only by class name,
# not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the
# alphabetical list.

SORT_BY_SCOPE_NAME     = NO

# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
# do proper type resolution of all parameters of a function it will reject a
# match between the prototype and the implementation of a member function even
# if there is only one candidate or it is obvious which candidate to choose
# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
# will still accept a match between prototype and implementation in such cases.

STRICT_PROTO_MATCHING  = NO

# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.

GENERATE_TODOLIST      = YES

# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.

GENERATE_TESTLIST      = YES

# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.

GENERATE_BUGLIST       = YES

# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
# disable (NO) the deprecated list. This list is created by putting
# \deprecated commands in the documentation.

GENERATE_DEPRECATEDLIST= YES

# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.

ENABLED_SECTIONS       =

# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
# the initial value of a variable or macro consists of for it to appear in
# the documentation. If the initializer consists of more lines than specified
# here it will be hidden. Use a value of 0 to hide initializers completely.
# The appearance of the initializer of individual variables and macros in the
# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.

MAX_INITIALIZER_LINES  = 30

# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.

SHOW_USED_FILES        = YES

# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.

SHOW_DIRECTORIES       = NO

# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
# Folder Tree View (if specified). The default is YES.

SHOW_FILES             = YES

# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
# Namespaces page.
# This will remove the Namespaces entry from the Quick Index
# and from the Folder Tree View (if specified). The default is YES.

SHOW_NAMESPACES        = YES

# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command <command> <input-file>, where <command> is the value of
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
# provided by doxygen. Whatever the program writes to standard output
# is used as the file version. See the manual for examples.

FILE_VERSION_FILTER    =

# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. The create the layout file
# that represents doxygen's defaults, run doxygen with the -l option.
# You can optionally specify a file name after the option, if omitted
# DoxygenLayout.xml will be used as the name of the layout file.

LAYOUT_FILE            =

# The CITE_BIB_FILES tag can be used to specify one or more bib files
# containing the references data. This must be a list of .bib files. The
# .bib extension is automatically appended if omitted. Using this command
# requires the bibtex tool to be installed. See also
# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
# of the bibliography can be controlled using LATEX_BIB_STYLE.

CITE_BIB_FILES         =

#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------

# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.

QUIET                  = YES

# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.

WARNINGS               = YES

# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.

WARN_IF_UNDOCUMENTED   = YES

# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some
# parameters in a documented function, or documenting parameters that
# don't exist or using markup commands wrongly.

WARN_IF_DOC_ERROR      = YES

# The WARN_NO_PARAMDOC option can be enabled to get warnings for
# functions that are documented, but have no documentation for their parameters
# or return value. If set to NO (the default) doxygen will only warn about
# wrong or incomplete parameter documentation, but not about the absence of
# documentation.

WARN_NO_PARAMDOC       = NO

# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text. Optionally the format may contain
# $version, which will be replaced by the version of the file (if it could
# be obtained via FILE_VERSION_FILTER)

WARN_FORMAT            = "$file : $line: $text"

# The WARN_LOGFILE tag can be used to specify a file to which warning
# and error messages should be written. If left blank the output is written
# to stderr.

WARN_LOGFILE           = doxygen.log

#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------

# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.

INPUT                  = src applications plugins

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# also the default input encoding. Doxygen uses libiconv (or the iconv built
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
# the list of possible encodings.

INPUT_ENCODING         = UTF-8

# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
# *.f90 *.f *.for *.vhd *.vhdl

FILE_PATTERNS          = *.php

# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.

RECURSIVE              = YES

# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
# Note that relative paths are relative to directory from which doxygen is run.

EXCLUDE                = 

# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.

EXCLUDE_SYMLINKS       = NO

# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories. Note that the wildcards are matched
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*

EXCLUDE_PATTERNS       = .git cache dists/*

# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test

EXCLUDE_SYMBOLS        =

# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).

EXAMPLE_PATH           =

# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.

EXAMPLE_PATTERNS       =

# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.

EXAMPLE_RECURSIVE      = NO

# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).

IMAGE_PATH             =

# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
# If FILTER_PATTERNS is specified, this tag will be
# ignored.

INPUT_FILTER           =

# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis.
# Doxygen will compare the file name with each pattern and apply the
# filter if there is a match.
# The filters are a list of the form:
# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
# info on how filters are used. If FILTER_PATTERNS is empty or if
# non of the patterns match the file name, INPUT_FILTER is applied.

FILTER_PATTERNS        =

# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).

FILTER_SOURCE_FILES    = NO

# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
# and it is also possible to disable source filtering for a specific pattern
# using *.ext= (so without naming a filter). This option only has effect when
# FILTER_SOURCE_FILES is enabled.

FILTER_SOURCE_PATTERNS =

#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------

# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.

SOURCE_BROWSER         = YES

# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.

INLINE_SOURCES         = YES

# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.

STRIP_CODE_COMMENTS    = YES

# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.

REFERENCED_BY_RELATION = NO

# If the REFERENCES_RELATION tag is set to YES
# then for each documented function all documented entities
# called/used by that function will be listed.

REFERENCES_RELATION    = NO

# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
# link to the source code.
# Otherwise they will link to the documentation.

REFERENCES_LINK_SOURCE = YES

# If the USE_HTAGS tag is set to YES then the references to source code
# will point to the HTML generated by the htags(1) tool instead of doxygen
# built-in source browser. The htags tool is part of GNU's global source
# tagging system (see http://www.gnu.org/software/global/global.html). You
# will need version 4.8.6 or higher.

USE_HTAGS              = NO

# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.

VERBATIM_HEADERS       = YES

#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------

# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.

ALPHABETICAL_INDEX     = YES

# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])

COLS_IN_ALPHA_INDEX    = 5

# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.

IGNORE_PREFIX          =

#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------

# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.

GENERATE_HTML          = YES

# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.

HTML_OUTPUT            = html

# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.

HTML_FILE_EXTENSION    = .html

# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header. Note that when using a custom header you are responsible
#  for the proper inclusion of any scripts and style sheets that doxygen
# needs, which is dependent on the configuration options used.
# It is adviced to generate a default header using "doxygen -w html
# header.html footer.html stylesheet.css YourConfigFile" and then modify
# that header. Note that the header is subject to change so you typically
# have to redo this when upgrading to a newer version of doxygen or when
# changing the value of configuration settings such as GENERATE_TREEVIEW!

HTML_HEADER            =

# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.

HTML_FOOTER            =

# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet. Note that doxygen will try to copy
# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!

HTML_STYLESHEET        =

# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
# the files will be copied as-is; there are no commands or markers available.

HTML_EXTRA_FILES       =

# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
# Doxygen will adjust the colors in the stylesheet and background images
# according to this color. Hue is specified as an angle on a colorwheel,
# see http://en.wikipedia.org/wiki/Hue for more information.
# For instance the value 0 represents red, 60 is yellow, 120 is green,
# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
# The allowed range is 0 to 359.

HTML_COLORSTYLE_HUE    = 220

# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
# the colors in the HTML output. For a value of 0 the output will use
# grayscales only. A value of 255 will produce the most vivid colors.

HTML_COLORSTYLE_SAT    = 100

# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
# the luminance component of the colors in the HTML output. Values below
# 100 gradually make the output lighter, whereas values above 100 make
# the output darker. The value divided by 100 is the actual gamma applied,
# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
# and 100 does not change the gamma.

HTML_COLORSTYLE_GAMMA  = 80

# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting
# this to NO can help when comparing the output of multiple runs.

HTML_TIMESTAMP         = YES

# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.

HTML_ALIGN_MEMBERS     = YES

# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).

HTML_DYNAMIC_SECTIONS  = NO

# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
# integrated development environment, introduced with OSX 10.5 (Leopard).
# To create a documentation set, doxygen will generate a Makefile in the
# HTML output directory. Running make will produce the docset in that
# directory and running "make install" will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
# it at startup.
# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.

GENERATE_DOCSET        = NO

# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
# feed. A documentation feed provides an umbrella under which multiple
# documentation sets from a single provider (such as a company or product suite)
# can be grouped.

DOCSET_FEEDNAME        = "Doxygen generated docs"

# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
# should uniquely identify the documentation set bundle. This should be a
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
# will append .docset to the name.

DOCSET_BUNDLE_ID       = org.doxygen.Project

# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.

DOCSET_PUBLISHER_ID    = org.doxygen.Publisher

# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.

DOCSET_PUBLISHER_NAME  = Publisher

# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.

GENERATE_HTMLHELP      = NO

# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# can add a path in front of the file if the result should not be
# written to the html output directory.

CHM_FILE               =

# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
# be used to specify the location (absolute path including file name) of
# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
# the HTML help compiler on the generated index.hhp.

HHC_LOCATION           =

# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).

GENERATE_CHI           = NO

# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# content.

CHM_INDEX_ENCODING     =

# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.

BINARY_TOC             = NO

# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.

TOC_EXPAND             = NO

# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
# that can be used as input for Qt's qhelpgenerator to generate a
# Qt Compressed Help (.qch) of the generated HTML documentation.

GENERATE_QHP           = NO

# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
# be used to specify the file name of the resulting .qch file.
# The path specified is relative to the HTML output folder.

QCH_FILE               =

# The QHP_NAMESPACE tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#namespace

QHP_NAMESPACE          = org.doxygen.Project

# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
# Qt Help Project output. For more information please see
# http://doc.trolltech.com/qthelpproject.html#virtual-folders

QHP_VIRTUAL_FOLDER     = doc

# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
# add. For more information please see
# http://doc.trolltech.com/qthelpproject.html#custom-filters

QHP_CUST_FILTER_NAME   =

# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see
# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
# Qt Help Project / Custom Filters</a>.

QHP_CUST_FILTER_ATTRS  =

# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's
# filter section matches.
# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
# Qt Help Project / Filter Attributes</a>.

QHP_SECT_FILTER_ATTRS  =

# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
# be used to specify the location of Qt's qhelpgenerator.
# If non-empty doxygen will try to run qhelpgenerator on the generated
# .qhp file.

QHG_LOCATION           =

# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
#  will be generated, which together with the HTML files, form an Eclipse help
# plugin. To install this plugin and make it available under the help contents
# menu in Eclipse, the contents of the directory containing the HTML and XML
# files needs to be copied into the plugins directory of eclipse. The name of
# the directory within the plugins directory should be the same as
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
# the help appears.

GENERATE_ECLIPSEHELP   = NO

# A unique identifier for the eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have
# this name.

ECLIPSE_DOC_ID         = org.doxygen.Project

# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.

DISABLE_INDEX          = NO

# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
# (range [0,1..20]) that doxygen will group on one line in the generated HTML
# documentation. Note that a value of 0 will completely suppress the enum
# values from appearing in the overview section.

ENUM_VALUES_PER_LINE   = 4

# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information.
# If the tag value is set to YES, a side panel will be generated
# containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
# Windows users are probably better off using the HTML help feature.

GENERATE_TREEVIEW      = NO

# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
# and Class Hierarchy pages using a tree view instead of an ordered list.

USE_INLINE_TREES       = NO

# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
# is shown.

TREEVIEW_WIDTH         = 250

# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
# links to external symbols imported via tag files in a separate window.

EXT_LINKS_IN_WINDOW    = NO

# Use this tag to change the font size of Latex formulas included
# as images in the HTML documentation. The default is 10. Note that
# when you change the font size after a successful doxygen run you need
# to manually remove any form_*.png images from the HTML output directory
# to force them to be regenerated.

FORMULA_FONTSIZE       = 10

# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are
# not supported properly for IE 6.0, but are supported on all modern browsers.
# Note that when changing this option you need to delete any form_*.png files
# in the HTML output before the changes have effect.

FORMULA_TRANSPARENT    = YES

# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
# (see http://www.mathjax.org) which uses client side Javascript for the
# rendering instead of using prerendered bitmaps. Use this if you do not
# have LaTeX installed or if you want to formulas look prettier in the HTML
# output. When enabled you also need to install MathJax separately and
# configure the path to it using the MATHJAX_RELPATH option.

USE_MATHJAX            = NO

# When MathJax is enabled you need to specify the location relative to the
# HTML output directory using the MATHJAX_RELPATH option. The destination
# directory should contain the MathJax.js script. For instance, if the mathjax
# directory is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the
# mathjax.org site, so you can quickly see the result without installing
# MathJax, but it is strongly recommended to install a local copy of MathJax
# before deployment.

MATHJAX_RELPATH        = http://www.mathjax.org/mathjax

# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
# names that should be enabled during MathJax rendering.

MATHJAX_EXTENSIONS     =

# When the SEARCHENGINE tag is enabled doxygen will generate a search box
# for the HTML output. The underlying search engine uses javascript
# and DHTML and should work on any modern browser. Note that when using
# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
# (GENERATE_DOCSET) there is already a search function so this one should
# typically be disabled. For large projects the javascript based search engine
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.

SEARCHENGINE           = YES

# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
# using Javascript. Doxygen will generate the search PHP script and index
# file to put on the web server. The advantage of the server
# based approach is that it scales better to large projects and allows
# full text search. The disadvantages are that it is more difficult to setup
# and does not have live searching capabilities.

SERVER_BASED_SEARCH    = NO

#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------

# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.

GENERATE_LATEX         = NO

# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.

LATEX_OUTPUT           = latex

# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
# Note that when enabling USE_PDFLATEX this option is only used for
# generating bitmaps for formulas in the HTML output, but not in the
# Makefile that is written to the output directory.

LATEX_CMD_NAME         = latex

# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.

MAKEINDEX_CMD_NAME     = makeindex

# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.

COMPACT_LATEX          = NO

# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, letter, legal and
# executive. If left blank a4wide will be used.

PAPER_TYPE             = a4

# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.

EXTRA_PACKAGES         =

# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!

LATEX_HEADER           =

# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
# the generated latex document. The footer should contain everything after
# the last chapter. If it is left blank doxygen will generate a
# standard footer. Notice: only use this tag if you know what you are doing!

LATEX_FOOTER           =

# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.

PDF_HYPERLINKS         = YES

# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.

USE_PDFLATEX           = YES

# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.

LATEX_BATCHMODE        = NO

# If LATEX_HIDE_INDICES is set to YES then doxygen will not
# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.

LATEX_HIDE_INDICES     = NO

# If LATEX_SOURCE_CODE is set to YES then doxygen will include
# source code with syntax highlighting in the LaTeX output.
# Note that which sources are shown also depends on other settings
# such as SOURCE_BROWSER.

LATEX_SOURCE_CODE      = NO

# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
# http://en.wikipedia.org/wiki/BibTeX for more info.

LATEX_BIB_STYLE        = plain

#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------

# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.

GENERATE_RTF           = NO

# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.

RTF_OUTPUT             = rtf

# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.

COMPACT_RTF            = NO

# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using WORD or other
# programs which support those fields.
# Note: wordpad (write) and others do not support links.

RTF_HYPERLINKS         = NO

# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.

RTF_STYLESHEET_FILE    =

# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.

RTF_EXTENSIONS_FILE    =

#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------

# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages

GENERATE_MAN           = NO

# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.

MAN_OUTPUT             = man

# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)

MAN_EXTENSION          = .3

# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
# then it will generate one additional man file for each entity
# documented in the real man page(s). These additional files
# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.

MAN_LINKS              = NO

#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------

# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation.

GENERATE_XML           = NO

# The XML_OUTPUT tag is used to specify where the XML pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `xml' will be used as the default path.

XML_OUTPUT             = xml

# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.

XML_SCHEMA             =

# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.

XML_DTD                =

# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.

XML_PROGRAMLISTING     = YES

#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------

# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
# generate an AutoGen Definitions (see autogen.sf.net) file
# that captures the structure of the code including all
# documentation. Note that this feature is still experimental
# and incomplete at the moment.

GENERATE_AUTOGEN_DEF   = NO

#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------

# If the GENERATE_PERLMOD tag is set to YES Doxygen will
# generate a Perl module file that captures the structure of
# the code including all documentation. Note that this
# feature is still experimental and incomplete at the
# moment.

GENERATE_PERLMOD       = NO

# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
# the necessary Makefile rules, Perl scripts and LaTeX code to be able
# to generate PDF and DVI output from the Perl module output.

PERLMOD_LATEX          = NO

# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
# nicely formatted so it can be parsed by a human reader.
# This is useful
# if you want to understand what is going on.
# On the other hand, if this
# tag is set to NO the size of the Perl module output will be much smaller
# and Perl will parse it just the same.

PERLMOD_PRETTY         = YES

# The names of the make variables in the generated doxyrules.make file
# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
# This is useful so different doxyrules.make files included by the same
# Makefile don't overwrite each other's variables.

PERLMOD_MAKEVAR_PREFIX =

#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------

# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.

ENABLE_PREPROCESSING   = YES

# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.

MACRO_EXPANSION        = NO

# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.

EXPAND_ONLY_PREDEF     = NO

# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# pointed to by INCLUDE_PATH will be searched when a #include is found.

SEARCH_INCLUDES        = YES

# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.

INCLUDE_PATH           =

# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.

INCLUDE_FILE_PATTERNS  =

# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed. To prevent a macro definition from being
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.

PREDEFINED             =

# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition that
# overrules the definition found in the source code.

EXPAND_AS_DEFINED      =

# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all references to function-like macros
# that are alone on a line, have an all uppercase name, and do not end with a
# semicolon, because these will confuse the parser if not removed.

SKIP_FUNCTION_MACROS   = YES

#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------

# The TAGFILES option can be used to specify one or more tagfiles.
# Optionally an initial location of the external documentation
# can be added for each tagfile. The format of a tag file without
# this location is as follows:
#
# TAGFILES = file1 file2 ...
# Adding location for the tag files is done as follows:
#
# TAGFILES = file1=loc1 "file2 = loc2" ...
# where "loc1" and "loc2" can be relative or absolute paths or
# URLs. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
# If a tag file is not located in the directory in which doxygen
# is run, you must also specify the path to the tagfile here.

TAGFILES               =

# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.

GENERATE_TAGFILE       =

# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.

ALLEXTERNALS           = NO

# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will
# be listed.

EXTERNAL_GROUPS        = YES

# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').

PERL_PATH              = /usr/bin/perl

#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------

# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
# or super classes. Setting the tag to NO turns the diagrams off. Note that
# this option also works with HAVE_DOT disabled, but it is recommended to
# install and use dot, since it yields more powerful graphs.

CLASS_DIAGRAMS         = YES

# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.

MSCGEN_PATH            =

# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.

HIDE_UNDOC_RELATIONS   = YES

# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)

HAVE_DOT               = YES

# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
# allowed to run in parallel. When set to 0 (the default) doxygen will
# base this on the number of processors available in the system. You can set it
# explicitly to a value larger than 0 to get control over the balance
# between CPU load and processing speed.

DOT_NUM_THREADS        = 0

# By default doxygen will use the Helvetica font for all dot files that
# doxygen generates. When you want a differently looking font you can specify
# the font name using DOT_FONTNAME. You need to make sure dot is able to find
# the font, which can be done by putting it in a standard location or by setting
# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
# directory containing the font.

DOT_FONTNAME           = Helvetica

# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.

DOT_FONTSIZE           = 10

# By default doxygen will tell dot to use the Helvetica font.
# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
# set the path where dot can find it.

DOT_FONTPATH           =

# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.

CLASS_GRAPH            = YES

# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.

COLLABORATION_GRAPH    = YES

# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for groups, showing the direct groups dependencies

GROUP_GRAPHS           = YES

# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.

UML_LOOK               = NO

# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.

TEMPLATE_RELATIONS     = NO

# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
# tags are set to YES then doxygen will generate a graph for each documented
# file showing the direct and indirect include dependencies of the file with
# other documented files.

INCLUDE_GRAPH          = YES

# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
# documented header file showing the documented files that directly or
# indirectly include this file.

INCLUDED_BY_GRAPH      = YES

# If the CALL_GRAPH and HAVE_DOT options are set to YES then
# doxygen will generate a call dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable call graphs
# for selected functions only using the \callgraph command.

CALL_GRAPH             = YES

# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
# doxygen will generate a caller dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable caller
# graphs for selected functions only using the \callergraph command.

CALLER_GRAPH           = YES

# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will generate a graphical hierarchy of all classes instead of a textual one.

GRAPHICAL_HIERARCHY    = YES

# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
# then doxygen will show the dependencies a directory has on other directories
# in a graphical way. The dependency relations are determined by the #include
# relations between the files in the directories.

DIRECTORY_GRAPH        = YES

# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are svg, png, jpg, or gif.
# If left blank png will be used. If you choose svg you need to set
# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible in IE 9+ (other browsers do not have this requirement).

DOT_IMAGE_FORMAT       = png

# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
# Note that this requires a modern browser other than Internet Explorer.
# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
# visible. Older versions of IE do not have SVG support.

INTERACTIVE_SVG        = NO

# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.

DOT_PATH               =

# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).

DOTFILE_DIRS           =

# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the
# \mscfile command).

MSCFILE_DIRS           =

# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
# nodes that will be shown in the graph. If the number of nodes in a graph
# becomes larger than this value, doxygen will truncate the graph, which is
# visualized by representing a node as a red box. Note that doxygen if the
# number of direct children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.

DOT_GRAPH_MAX_NODES    = 50

# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes
# that lay further from the root node will be omitted. Note that setting this
# option to 1 or 2 may greatly reduce the computation time needed for large
# code bases. Also note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.

MAX_DOT_GRAPH_DEPTH    = 0

# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not
# seem to support this out of the box. Warning: Depending on the platform used,
# enabling this option may lead to badly anti-aliased labels on the edges of
# a graph (i.e. they become hard to read).

DOT_TRANSPARENT        = NO

# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10)
# support this, this feature is disabled by default.

DOT_MULTI_TARGETS      = NO

# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.

GENERATE_LEGEND        = YES

# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
# remove the intermediate dot files that are used to generate
# the various graphs.

DOT_CLEANUP            = YES
<?php

// autoload.php @generated by Composer

if (PHP_VERSION_ID < 50600) {
    if (!headers_sent()) {
        header('HTTP/1.1 500 Internal Server Error');
    }
    $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
    if (!ini_get('display_errors')) {
        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
            fwrite(STDERR, $err);
        } elseif (!headers_sent()) {
            echo $err;
        }
    }
    trigger_error(
        $err,
        E_USER_ERROR
    );
}

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit365e25e34522fee120bee0a71e662cb3::getLoader();
#!/usr/bin/env fish
# Authors:
#   - Yo-An Lin
#   - Márcio Almada
#   - Rack Lin

# PHPBrew defaults:
# PHPBREW_HOME: contains the phpbrew config (for users)
# PHPBREW_ROOT: contains installed php(s) and php source files.
# PHPBREW_SKIP_INIT: if you need to skip loading config from the init file.
# PHPBREW_PHP:  the current php version.
# PHPBREW_PATH: the bin path of the current php.
# PHPBREW_SYSTEM_PHP: the path to the system php binary.

# export alias for bourne shell compatibility.
# From PR https://github.com/fish-shell/fish-shell/pull/1833
if not functions --query export
  function export --description 'Set global variable. Alias for set -g, made for bash compatibility'
          if test -z "$argv"
             set
             return 0
          end
          for arg in $argv
              set -l v (echo $arg|tr '=' \n)
              set -l c (count $v)
              switch $c
                      case 1
                              set -gx $v $$v
                      case 2
                              set -gx $v[1] $v[2]
              end
          end
  end
end

function __phpbrew_set_path
    functions --query php ; and functions -e php
    set PATH_WITHOUT_PHPBREW

    if set -q PHPBREW_ROOT
        for i in $PATH
            if [ (expr $i : $PHPBREW_ROOT) -eq 0 ]
                set PATH_WITHOUT_PHPBREW $PATH_WITHOUT_PHPBREW $i
            end
        end
    else
        set PATH_WITHOUT_PHPBREW $PATH
    end

    if set -q PHPBREW_PATH
        set -gx PATH $PHPBREW_PATH $PATH_WITHOUT_PHPBREW
    else
        set -gx PATH $PATH_WITHOUT_PHPBREW
        return 0
    end
end

function __phpbrew_load_user_config
    # load user-defined config
    if [ -f $PHPBREW_HOME/init ]
        source $PHPBREW_HOME/init
        __phpbrew_set_path
    end
end

# The minimal PHP version that PhpBrew supports as interpreter
set MIN_PHP_VERSION    "7.2.0"
set MIN_PHP_VERSION_ID 70200

# Returns the absolute path corresponding to the command excluding the alias
function __phpbrew_which
    command which $argv
end

# Executes the given command via the PHP implementation
function __phpbrew_php_exec
    # Force the usage of the system PHP interpreter if it's set
    if set -q PHPBREW_SYSTEM_PHP
        set cmd $PHPBREW_SYSTEM_PHP
    end

    # Check if we are in a PHPBrew source directory (this is only for development)
    if [ -e bin/phpbrew ]
        set -a cmd bin/phpbrew
    else
        set -a cmd (__phpbrew_which phpbrew)
    end

    command $cmd $argv
end

# Normalizes a PHP build by adding the "php-" prefix if it's missing
function __phpbrew_normalize_build
    if begin ; [ ! -d "$PHPBREW_ROOT/php/$argv" ]; and echo $argv | egrep -q -e '^([[:digit:]]+\.){2}[[:digit:]]+(-dev|((alpha|beta|RC)[[:digit:]]+))?$'; end
        echo "php-$argv"
    else
        echo $argv
    end
end

# Returns the PHP binary path for a given version
function __phpbrew_get_version_bin
    if not string match -q "/*" $argv
        set -l build (__phpbrew_normalize_build $argv)
        echo "$PHPBREW_ROOT/php/$build/bin/php"
    else
        echo $argv
    end
end

# Validates the PHP binary that is to be used as interpreter
function __phpbrew_validate_interpreter
    if [ -d $argv[1] ]
        echo $argv[1] "is a directory"
        return 1
    end

    if [ ! -f $argv[1] ]
        echo $argv[1] "not found"
        return 1
    end

    if [ ! -x $argv[1] ]
        echo $argv[1] "is not executable"
        return 1
    end

    set PHP_VERSION_ID (command $argv[1] -r "echo PHP_VERSION_ID;")
    or return 1

    if [ $PHP_VERSION_ID -lt $MIN_PHP_VERSION_ID ]
        echo "Only PHP $MIN_PHP_VERSION or newer can be used as PHPBrew interpreter"
        return 1
    end
end

# Checks whether the given PHP build can be currently used or switched to
function __phpbrew_can_use_build
    if set -q PHPBREW_SYSTEM_PHP
        # Can use any version since the system interpreter is set
        return
    end

    if not __phpbrew_validate_interpreter (__phpbrew_get_version_bin $argv[1])
        echo "The system interpreter is not currently set"
        echo "Please execute 'phpbrew system' using PHP $MIN_PHP_VERSION or newer before using an older one"
        return 1
    end
end

function __phpbrew_set_lookup_prefix
    switch (echo $argv[1])
        case debian ubuntu linux
            # echo /usr/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu
            echo /usr
        case macosx
            echo /usr
        case macports
            echo /opt/local
        case homebrew
            echo /usr/local/Cellar:/usr/local
        case '*'
            if [ -e $argv[1] ]
                echo $argv[1]
            else
                for dir in /opt/local /usr/local/Cellar /usr/local /usr
                    if [ -e $dir ]
                        echo $dir
                        return
                    end
                end
            end
    end
end

function phpbrew
    set short_option
    # export SHELL
    if [ (echo $argv[1] | awk 'BEGIN{FS=""}{print $1}') = '-' ]
        set short_option $argv[1]
        set -e argv[1]
    else
        set short_option ""
    end

    switch (echo $argv[1])
        case use
            if [ (count $argv) -eq 1 ]
                if [ -z "$PHPBREW_PHP" ]
                    echo "Currently using system php"
                else
                    echo "Currently using $PHPBREW_PHP"
                end

                return
            end

            set -l IFS
            if not set -l output (__phpbrew_php_exec env (__phpbrew_normalize_build $argv[2]))
                echo $output
                return 1
            end

            eval $output
            __phpbrew_set_path
        case cd-src
            set -l SOURCE_DIR $PHPBREW_HOME/build/$PHPBREW_PHP
            if [ -d $SOURCE_DIR ]
                cd $SOURCE_DIR
            end
        case 'switch'
            if [ (count $argv) -eq 1 ]
                echo "Please specify the php version."
                return 1
            end

            __phpbrew_reinit (__phpbrew_normalize_build $argv[2])
        case lookup-prefix
            if [ (count $argv) -eq 1 ]
                if [ -n "$PHPBREW_LOOKUP_PREFIX" ]
                    echo $PHPBREW_LOOKUP_PREFIX
                end
            else
                set -gx PHPBREW_LOOKUP_PREFIX (__phpbrew_set_lookup_prefix $argv[2])
                echo $PHPBREW_LOOKUP_PREFIX
                __phpbrew_update_config
            end
        case cd
            if [ (count $argv) -eq 1 ]; return 0; end

            switch $argv[2]
                case var
                    set chdir $PHPBREW_ROOT/php/$PHPBREW_PHP/var
                case etc
                    set chdir $PHPBREW_ROOT/php/$PHPBREW_PHP/etc
                case dist
                    set chdir $PHPBREW_ROOT/php/$PHPBREW_PHP
                case build
                    set chdir $PHPBREW_ROOT/build/$PHPBREW_PHP
                case '*'
                    echo "$argv[2] not found"
                    return 0
            end
            echo "Switching to $chdir, run 'cd -' to go back."
            cd $chdir
            return 0

        case each
            __phpbrew_each $argv[2..-1]

        case fpm
            if [ (count $argv) -ge 3 ]
              set -g PHP_BUILD $argv[3]
            else
              set -g PHP_BUILD $PHPBREW_PHP
            end

            mkdir -p $PHPBREW_ROOT/php/$PHP_BUILD/var/run
            set -g PHPFPM_BIN $PHPBREW_ROOT/php/$PHP_BUILD/sbin/php-fpm
            set -g PHPFPM_PIDFILE $PHPBREW_ROOT/php/$PHP_BUILD/var/run/php-fpm.pid

            function fpm_start
              echo "Starting php-fpm..."
              set -l regex '^php-5\.2.*'

              if [ (count $argv) -ge 4 ]
                set _PHPFPM_APPEND $argv[4..-1]
              else
                set _PHPFPM_APPEND ""
              end


              if echo $PHP_BUILD | egrep -q -e $regex
                eval $PHPFPM_BIN start
              else
                 eval $PHPFPM_BIN --php-ini $PHPBREW_ROOT/php/$PHP_BUILD/etc/fpm/php.ini --fpm-config $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf --pid $PHPFPM_PIDFILE $_PHPFPM_APPEND
              end

              if [ "$status" != "0" ]
                echo "php-fpm start failed."
              end
            end

            function fpm_stop
              set -l regex '^php-5\.2.*'

              if echo $PHP_BUILD | egrep -q -e $regex
                eval $PHPFPM_BIN stop
              else if [ -e $PHPFPM_PIDFILE ]
                echo "Stopping php-fpm..."
                kill (cat $PHPFPM_PIDFILE)
                rm -f $PHPFPM_PIDFILE
              end
            end

            [ (count $argv) -lt 2 ]; and $argv[2] = ''

            switch $argv[2]
              case start
                    fpm_start $argv
              case stop
                    fpm_stop
              case restart
                    fpm_stop
                    fpm_start $argv
              case module
                     eval $PHPFPM_BIN --php-ini $PHPBREW_ROOT/php/$PHP_BUILD/etc/fpm/php.ini --fpm-config $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf -m | less
              case info
                     eval $PHPFPM_BIN --php-ini $PHPBREW_ROOT/php/$PHP_BUILD/etc/fpm/php.ini --fpm-config $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf -i
              case config
                    if [ -n "$EDITOR" ]
                        eval $EDITOR $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf
                    else
                        echo "Please set EDITOR environment variable for your favor."
                        nano $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf
                    end
              case help
                     eval $PHPFPM_BIN --php-ini $PHPBREW_ROOT/php/$PHP_BUILD/etc/fpm/php.ini --fpm-config $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf --help
              case test
                     eval $PHPFPM_BIN --php-ini $PHPBREW_ROOT/php/$PHP_BUILD/etc/fpm/php.ini --fpm-config $PHPBREW_ROOT/php/$PHP_BUILD/etc/php-fpm.conf --test
              case '*'
                    echo "Usage: phpbrew fpm [start|stop|restart|module|test|help|config]"
            end

        case info
            __phpbrew_php_exec info | php

        case off
            set -e PHPBREW_PHP
            set -e PHPBREW_PATH
            eval (__phpbrew_php_exec env)
            __phpbrew_set_path

        case switch-off
            set -e PHPBREW_PHP
            set -e PHPBREW_PATH
            eval (__phpbrew_php_exec env)
            __phpbrew_reinit
            echo "phpbrew is switched off."

        case system
            if [ (count $argv) -lt 2 ]
                __phpbrew_php_exec system
            else
                set -l bin (__phpbrew_get_version_bin $argv[2])
                __phpbrew_validate_interpreter $bin
                or return 1

                set -gx PHPBREW_SYSTEM_PHP $bin
                __phpbrew_update_config
            end

        case system-off
            if not __phpbrew_validate_interpreter (__phpbrew_which php)
                echo "The currently used PHP build $PHPBREW_PHP cannot be used as PhpBrew interpreter"
                echo "Please execute `phpbrew switch` using PHP $MIN_PHP_VERSION or newer before switching the system interpreter off"
                return 1
            end

            set -e PHPBREW_SYSTEM_PHP
            __phpbrew_update_config

        case rehash
            echo "Rehashing..."
            source ~/.phpbrew/phpbrew.fish

        case purge
            if [ (count $argv) -ge 2 ]
              __phpbrew_purge $argv[2] purge
            else
                __phpbrew_php_exec help
            end

        case '*'
            if [ -z "$short_option" ]
                __phpbrew_php_exec $argv
            else
                __phpbrew_php_exec $short_option $argv
            end
            ;;
    end
end

function __phpbrew_update_config
    set -l IFS
    if not set -l output (__phpbrew_php_exec env $argv)
        echo $output
        return 1
    end

    begin
        echo "# DO NOT EDIT THIS FILE"
        echo $output
    end > "$PHPBREW_HOME/init"

    source "$PHPBREW_HOME/init"
end

function __phpbrew_reinit
    __phpbrew_update_config $argv && __phpbrew_set_path
end

function __phpbrew_each
    set result 0

    if set -q PHPBREW_PHP
        set current $PHPBREW_PHP
    end

    for build in $PHPBREW_ROOT/php/*
        if test -x $build/bin/php
            phpbrew use (basename $build)
            eval $argv || set result $status
        end
    end;

    if set -q current
        phpbrew use $current
    else
        phpbrew off
    end

    return $result
end

function __phpbrew_purge
    set -l PHP_BUILD (__phpbrew_normalize_build $argv[1])

    if [ "$PHP_BUILD" = "$PHPBREW_PHP" ]
        echo "php version: $PHP_BUILD is already in use."
        return 1
    end

    set -l bin (__phpbrew_get_version_bin $PHP_BUILD)

    if [ "$bin" = "$PHPBREW_SYSTEM_PHP" ]
        echo "PHP build $PHP_BUILD is used as the system interpreter"
        return 1
    end

    set _PHP_BIN_PATH $PHPBREW_ROOT/php/$PHP_BUILD
    set _PHP_SOURCE_FILE $PHPBREW_ROOT/build/$PHP_BUILD.tar.bz2
    set _PHP_BUILD_PATH $PHPBREW_ROOT/build/$PHP_BUILD

    if [ -d $_PHP_BIN_PATH ]

        if begin; [ (count $argv) -ge 2 ]; and [ "$argv[2]" = "purge" ]; end
            rm -f $_PHP_SOURCE_FILE
            rm -fr $_PHP_BUILD_PATH
            rm -fr $_PHP_BIN_PATH
            echo "php version: $PHP_BUILD is removed and purged."
        else
            rm -f $_PHP_SOURCE_FILE
            rm -fr $_PHP_BUILD_PATH

            for FILE1 in $_PHP_BIN_PATH/*
                if begin; [ "$FILE1" != "$_PHP_BIN_PATH/etc" ]; and [ "$FILE1" != "$_PHP_BIN_PATH/var" ]; end
                    rm -fr $FILE1
                end
            end

            echo "php version: $PHP_BUILD is removed."
        end

    else
        echo "php version: $PHP_BUILD not installed."
    end

    return 0
end

function phpbrew_current_php_version
  if type "php" > /dev/null
    set -l version (php -v | grep "PHP 5" | sed 's/.*PHP \([^-]*\).*/\1/' | cut -c 1-6)
    if [ -z "$PHPBREW_PHP" ]
      echo "php:$version-system"
    else
      echo "php:$version-phpbrew"
    end
  else
     echo "php:not-installed"
  end
end

if begin ; [ -n "$PHPBREW_SET_PROMPT" ]; and [ "$PHPBREW_SET_PROMPT" = "1" ]; end
    # export PS1="\w > \u@\h [$(phpbrew_current_php_version)]\n\\$ "
    # non supports in fish now
end

function _phpbrewrc_load --on-variable PWD --description 'Load configuration based on .phpbrewrc'
    set -q PHPBREW_RC_ENABLE
    or return

    status --is-command-substitution;
    and return

    set curr_dir "$PWD"
    set prev_dir ""
    set curr_fs 0
    set prev_fs 0

    while [ -n $curr_dir -a -d $curr_dir ]
        set prev_fs $curr_fs
        set curr_fs (stat -c %d $curr_dir 2>/dev/null) # GNU version
        if [ $status -ne 0 ]
            set curr_fs (stat -f %d $curr_dir 2>/dev/null) # BSD version
        end

        # check if top level directory or filesystem boundary is reached
        if begin; [ "$curr_dir" = "/" ]; or [ -z "$PHPBREW_RC_DISCOVERY_ACROSS_FILESYSTEM" -a $prev_fs -ne 0 -a $curr_fs -ne $prev_fs ]; end
            # check if there's a previously loaded .phpbrewrc
            if [ ! -z "$PHPBREW_LAST_RC_DIR" ]
                set -e PHPBREW_LAST_RC_DIR
                __phpbrew_load_user_config
            end
            break
        end

        # check if .phpbrewrc present
        if [ -r "$curr_dir/.phpbrewrc" ]
            # check if it's not the same .phpbrewrc which was previously loaded
            if [ "$curr_dir" != "$PHPBREW_LAST_RC_DIR" ]
                __phpbrew_load_user_config
                set -g PHPBREW_LAST_RC_DIR "$curr_dir"
                source "$curr_dir/.phpbrewrc"
            end
            break
        end

        set curr_dir (dirname "$curr_dir")
    end
end

###
# phpbrew completions
###
function __fish_phpbrew_command
    set -l tokens (commandline -opc)
    test (count $tokens) -le 1; and return 1
    set -l command

    for token in $tokens[2..-1]
        switch $token
            case "-*"
            case "*"
                set -a command "$token"
        end
    end

    test (count $command) -eq 0; and return 1

    for token in $command
        echo $token
    end
end

function __fish_phpbrew_needs_command
    not __fish_phpbrew_command >/dev/null
end

function __fish_phpbrew_using_command
    set -l expected
    set -l position 0
    set -l multiple

    for arg in $argv
        switch $arg
            case "--position=*"
                string replace -- "--position=" "" "$arg" | read position
            case "--multiple"
                set multiple yes
            case "*"
                set -a expected "$arg"
        end
    end

    set -l exp_count (count $expected)
    set exp_count (math "$exp_count+$position")

    set -l actual (__fish_phpbrew_command)

    if [ -n "$multiple" ]
        if [ (count $actual) -lt $exp_count ]
            return 1
        end
    else
        if [ (count $actual) -ne $exp_count ]
            return 1
        end
    end

    set -l slice $actual[1..(count $expected)]

    test "$slice" = "$expected"
end

function __fish_phpbrew_arg_meta
    __phpbrew_php_exec meta --flat $argv[1] arg $argv[2] $argv[3] | grep -v "^#"
end

[ -z "$PHPBREW_ROOT" ]; and set -gx PHPBREW_ROOT "$HOME/.phpbrew"
[ -z "$PHPBREW_HOME" ]; and set -gx PHPBREW_HOME "$HOME/.phpbrew"

if [ -z "$PHPBREW_SKIP_INIT" ]
    __phpbrew_load_user_config
end

[ -z "$PHPBREW_ROOT" ]; and set -gx PHPBREW_ROOT "$HOME/.phpbrew"

[ ! -d "$PHPBREW_ROOT" ]; and mkdir $PHPBREW_ROOT
[ ! -d "$PHPBREW_HOME" ]; and mkdir $PHPBREW_HOME

# top level options
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -s v -l verbose -d "Print verbose message"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -s d -l debug -d "Print debug message"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -s q -l quiet -d "Be quiet"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -s h -l help -d "Show help"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -l version -d "Show version"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -s p -l profile -d "Display timing and memory usage information"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -l log-path -d "The path of a log file"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -l no-interact -d "Do not ask any interactive question"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -l no-progress -d "Do not display progress bar"

# commands
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a archive -d "Build executable phar file from composer.json"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a bash -d "This command generate a bash completion script automatically"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a cd -d "Change to directories"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a clean -d "Clean up the source directory of a PHP distribution"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a compile -d "compile current source into Phar format library file"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a config -d "Edit your current php.ini in your favorite $EDITOR"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a ctags -d "Run ctags at current php source dir for extension development"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a download -d "Download php"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a each -d "Iterate and run a given shell command over all php versions managed by PHPBrew"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a env -d "Export environment variables"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a ext -d "List extensions or execute extension subcommands"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a fpm -d "fpm commands"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a github:build-topics -d "Build topic classes from the wiki of a GitHub Project"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a help -d "Show help message of a command"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a info -d "Show current php information"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a init -d "Initialize phpbrew config file"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a install -d "Install php"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a known -d "List known PHP versions"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a list -d "List installed PHPs"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a list-ini -d "List loaded ini config files"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a meta -d "Return the meta data of a commands"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a off -d "Temporarily go back to the system php"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a path -d "Show paths of the current PHP"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a purge -d "Remove installed php version and config files"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a remove -d "Remove installed php build"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a self-update -d "Self-update, default to master version"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a switch -d "Switch default php version"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a switch-off -d "Definitely go back to the system php"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a system -d "Get or set the internally used PHP binary"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a system-off -d "Use the currently effective PHP binary internally"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a update -d "Update PHP release source file"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a use -d "Use php, switch version temporarily"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a variants -d "List php variants"
complete -f -c phpbrew -n "__fish_phpbrew_needs_command" -a zsh -d "This function generate a zsh-completion script automatically"

# archive
complete -x -c phpbrew -n "__fish_phpbrew_using_command archive" -s d -l working-dir -d "If specified, use the given directory as working directory"
complete -x -c phpbrew -n "__fish_phpbrew_using_command archive" -s c -l composer -d "The composer.json file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command archive" -l vendor -d "Vendor directory name"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l bootstrap -d "bootstrap or executable php file"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l executable -d "make the phar file executable"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -s c -l compress -d "compress type: gz, bz2"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l no-compress -d "do not compress phar file"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l add -d "add a path respectively"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l exclude -d "exclude pattern"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l no-classloader -d "do not embed a built-in classloader in the generated phar file"
complete -f -c phpbrew -n "__fish_phpbrew_using_command archive" -l app-bootstrap -d "Include CLIFramework bootstrap script"

# bash
complete -x -c phpbrew -n "__fish_phpbrew_using_command bash" -l bind -d "bind complete to command"
complete -x -c phpbrew -n "__fish_phpbrew_using_command bash" -l program -d "programe name"

# cd
complete -x -c phpbrew -n "__fish_phpbrew_using_command cd" -a "(__fish_phpbrew_arg_meta cd 0 valid-values)"

# clean
complete -f -c phpbrew -n "__fish_phpbrew_using_command clean" -s a -l all -d "Remove all the files in the source directory of the PHP distribution"
complete -x -c phpbrew -n "__fish_phpbrew_using_command clean" -a "(__fish_phpbrew_arg_meta clean 0 valid-values)"

# compile
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l classloader -d "embed classloader source file"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l bootstrap -d "bootstrap or executable source file"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l executable -d "is a executable script \?"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l lib -d "library path"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l include -d "include path"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l exclude -d "exclude pattern"
complete -x -c phpbrew -n "__fish_phpbrew_using_command compile" -l output -d "output"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -s c -l compress -d "phar file compress type: gz, bz2"
complete -f -c phpbrew -n "__fish_phpbrew_using_command compile" -l no-compress -d "do not compress phar file"

# ctags
complete -x -c phpbrew -n "__fish_phpbrew_using_command ctags" -a "(__fish_phpbrew_arg_meta ctags 0 valid-values)"

# download
complete -f -c phpbrew -n "__fish_phpbrew_using_command download" -s f -l force -d "Force extraction"
complete -f -c phpbrew -n "__fish_phpbrew_using_command download" -l old -d "enable old phps \(less than 5.3\)"
complete -x -c phpbrew -n "__fish_phpbrew_using_command download" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command download" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command download" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command download" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command download" -l connect-timeout -d "Connection timeout"
complete -x -c phpbrew -n "__fish_phpbrew_using_command download" -a "(__fish_phpbrew_arg_meta download 0 suggestions)"

# env
complete -f -c phpbrew -n "__fish_phpbrew_using_command env" -a "(__fish_phpbrew_arg_meta env 0 valid-values)"

# ext
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -s so -l show-options -d "Show extension configure options"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -s sp -l show-path -d "Show extension config.m4 path"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a clean -d "Clean up the compiled objects in the extension source directory"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a config -d "Edit extension-specific configuration file"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a disable -d "Disable PHP extension"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a enable -d "Enable PHP extension"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a install -d "Install PHP extension"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a known -d "List known versions"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext" -a show -d "Show information of a PHP extension"

# ext clean
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext clean" -s p -l purge -d "Remove all the source files"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext clean" -a "(__fish_phpbrew_arg_meta extension.clean 0 suggestions)"

# ext config
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext config" -a "(__fish_phpbrew_arg_meta extension.config 0 suggestions)"

# ext disable
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext disable" -a "(__fish_phpbrew_arg_meta extension.disable 0 suggestions)"

# ext enable
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext enable" -a "(__fish_phpbrew_arg_meta extension.enable 0 suggestions)"

# ext install
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext install" -l pecl -d "Try to download from PECL even when ext source is bundled with php-src"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext install" -l redownload -d "Force to redownload extension source even if it is already available"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext install" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext install" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext install" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext install" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext install" -l connect-timeout -d "Connection timeout"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext install" -a "(__fish_phpbrew_arg_meta extension.install 0 suggestions)"

# ext known
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext known" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext known" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext known" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext known" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext known" -l connect-timeout -d "Connection timeout"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext known" -a "(__fish_phpbrew_arg_meta extension.known 0 suggestions)"

# ext show
complete -f -c phpbrew -n "__fish_phpbrew_using_command ext show" -l download -d "Download the extension source if extension not found"
complete -x -c phpbrew -n "__fish_phpbrew_using_command ext show" -a "(__fish_phpbrew_arg_meta extension.show 0 suggestions)"

# fpm
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm" -a restart -d "Restart FPM server"
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm" -a setup -d "Generate and setup FPM startup config"
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm" -a start -d "Start FPM server"
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm" -a stop -d "Stop FPM server"

# fpm setup
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm setup" -l systemctl -d "Generate systemd service entry"
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm setup" -l initd -d "Generate init.d script"
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm setup" -l launchctl -d "Generate plist for launchctl \(OS X\)"
complete -f -c phpbrew -n "__fish_phpbrew_using_command fpm setup" -l stdout -d "Print config to STDOUT instead of writing to the file"

# github:build-topics
complete -x -c phpbrew -n "__fish_phpbrew_using_command github:build-topics" -l ns -d "Class namespace"
complete -x -c phpbrew -n "__fish_phpbrew_using_command github:build-topics" -l dir -d "Output directory"
complete -f -c phpbrew -n "__fish_phpbrew_using_command github:build-topics" -l update -d "Update wiki repository"

# help
complete -f -c phpbrew -n "__fish_phpbrew_using_command help" -l dev -d "Show development commands"

# init
complete -x -c phpbrew -n "__fish_phpbrew_using_command init" -s c -l config -d "The YAML config file which should be copied into phpbrew home.The config file is used for creating custom virtual variants"
complete -x -c phpbrew -n "__fish_phpbrew_using_command init" -l root -d "Override the default PHPBREW_ROOT path setting.This option is usually used to load system-wide build pool"

# install
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l test -d "Run tests after the installation"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l name -d "The name of the installation"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l post-clean -d "Run make clean after the installation"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l production -d "Use production configuration file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l build-dir -d "Specify the build directory"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l root -d "Specify PHPBrew root instead of PHPBREW_ROOT"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l home -d "Specify PHPBrew home instead of PHPBREW_HOME"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l no-config-cache -d "Do not use config.cache for configure script"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l no-clean -d "Do not clean previously compiled objects before building PHP"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l no-patch -d "Do not apply any patch"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l no-configure -d "Do not run configure script"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l no-install -d "Do not install, just run build the target"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -s n -l nice -d "Runs build processes at an altered scheduling priority"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l patch -d "Apply patch before build"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l old -d "Install phpbrew incompatible phps \(< 5.3\)"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l user-config -d "Allow users create their own config file \(php.ini or extension config init files\)"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l connect-timeout -d "Connection timeout"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -s f -l force -d "Force the installation \(redownloads source\)"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -s d -l dryrun -d "Do not build, but run through all the tasks"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -l like -d "Inherit variants from an existing build"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -s j -l jobs -d "Specifies the number of jobs to run build simultaneously \(make -jN\)"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l stdout -d "Outputs install logs to stdout"
complete -f -c phpbrew -n "__fish_phpbrew_using_command install" -l sudo -d "sudo to run install command"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install" -a "(__fish_phpbrew_arg_meta install 0 suggestions)"
complete -x -c phpbrew -n "__fish_phpbrew_using_command install --position=1 --multiple" -a "(__fish_phpbrew_arg_meta install 1 suggestions)"

# known
complete -f -c phpbrew -n "__fish_phpbrew_using_command known" -s m -l more -d "Show more older versions"
complete -f -c phpbrew -n "__fish_phpbrew_using_command known" -s o -l old -d "List old phps \(less than 5.3\)"
complete -f -c phpbrew -n "__fish_phpbrew_using_command known" -s u -l update -d "Update release list"
complete -x -c phpbrew -n "__fish_phpbrew_using_command known" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command known" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command known" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command known" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command known" -l connect-timeout -d "Connection timeout"

# list
complete -f -c phpbrew -n "__fish_phpbrew_using_command list" -s d -l dir -d "Show php directories"
complete -f -c phpbrew -n "__fish_phpbrew_using_command list" -s v -l variants -d "Show used variants"

# meta
complete -f -c phpbrew -n "__fish_phpbrew_using_command meta" -l flat -d "flat list format"
complete -f -c phpbrew -n "__fish_phpbrew_using_command meta" -l zsh -d "output for zsh"
complete -f -c phpbrew -n "__fish_phpbrew_using_command meta" -l bash -d "output for bash"
complete -f -c phpbrew -n "__fish_phpbrew_using_command meta" -l json -d "output in JSON format \(un-implemented\)"

# path
complete -x -c phpbrew -n "__fish_phpbrew_using_command path" -a "(__fish_phpbrew_arg_meta path 0 valid-values)"

# purge
complete -x -c phpbrew -n "__fish_phpbrew_using_command purge --multiple" -a "(__fish_phpbrew_arg_meta purge 0 valid-values)"

# remove
complete -x -c phpbrew -n "__fish_phpbrew_using_command remove" -a "(__fish_phpbrew_arg_meta remove 0 valid-values)"

# self-update
complete -x -c phpbrew -n "__fish_phpbrew_using_command self-update" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command self-update" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command self-update" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command self-update" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command self-update" -l connect-timeout -d "Connection timeout"

# switch
complete -x -c phpbrew -n "__fish_phpbrew_using_command switch" -a "(__fish_phpbrew_arg_meta switch 0 valid-values)"

# system
complete -x -c phpbrew -n "__fish_phpbrew_using_command system" -a "(__fish_phpbrew_arg_meta system 0 suggestions)"

# update
complete -f -c phpbrew -n "__fish_phpbrew_using_command update" -s o -l old -d "List old phps \(less than 5.3\)"
complete -x -c phpbrew -n "__fish_phpbrew_using_command update" -l downloader -d "Use alternative downloader"
complete -f -c phpbrew -n "__fish_phpbrew_using_command update" -l continue -d "Continue getting a partially downloaded file"
complete -x -c phpbrew -n "__fish_phpbrew_using_command update" -l http-proxy -d "HTTP proxy address"
complete -x -c phpbrew -n "__fish_phpbrew_using_command update" -l http-proxy-auth -d "HTTP proxy authentication"
complete -x -c phpbrew -n "__fish_phpbrew_using_command update" -l connect-timeout -d "Connection timeout"

# use
complete -x -c phpbrew -n "__fish_phpbrew_using_command use" -a "(__fish_phpbrew_arg_meta use 0 valid-values)"

# zsh
complete -x -c phpbrew -n "__fish_phpbrew_using_command zsh" -l bind -d "bind complete to command"
complete -x -c phpbrew -n "__fish_phpbrew_using_command zsh" -l program -d "programe name"
#!/bin/bash
# Brought from gugod's perlbrew.
# Authors:
#   - Yo-An Lin
#   - Márcio Almada

# PHPBrew defaults:
# PHPBREW_HOME: contains the phpbrew config (for users)
# PHPBREW_ROOT: contains installed php(s) and php source files.
# PHPBREW_SKIP_INIT: if you need to skip loading config from the init file.
# PHPBREW_PHP:  the current php version.
# PHPBREW_PATH: the bin path of the current php.
# PHPBREW_SYSTEM_PHP: the path to the system php binary.

[[ -z "$PHPBREW_ROOT" ]] && export PHPBREW_ROOT="$HOME/.phpbrew"
[[ -z "$PHPBREW_HOME" ]] && export PHPBREW_HOME="$HOME/.phpbrew"

# The minimal PHP version that PhpBrew supports as interpreter
MIN_PHP_VERSION="7.2.0"
MIN_PHP_VERSION_ID=70200

# Returns the absolute path corresponding to the command excluding the alias
function __phpbrew_which()
{
    command which "$1"
}

# Executes the given command via the PHP implementation
function __phpbrew_php_exec()
{
    local cmd

    # Check if we are in a PHPBrew source directory (this is only for development)
    if [[ -e bin/phpbrew ]] ; then
        cmd=bin/phpbrew
    else
        cmd="$(__phpbrew_which phpbrew)"
    fi

    # Force the usage of the system PHP interpreter if it's set
    if [[ -n "$PHPBREW_SYSTEM_PHP" ]] ; then
        command "$PHPBREW_SYSTEM_PHP" "$cmd" "$@"
    else
        command "$cmd" "$@"
    fi
}

# Normalizes a PHP build by adding the "php-" prefix if it's missing
function __phpbrew_normalize_build()
{
    if [[ ! -d "$PHPBREW_ROOT/php/$1" && "$1" =~ ^([[:digit:]]+\.){2}[[:digit:]]+(-dev|((alpha|beta|RC)[[:digit:]]+))?$ ]] ; then
        echo "php-$1"
    else
        echo "$1"
    fi
}

# Returns the PHP binary path for a given version
function __phpbrew_get_version_bin()
{
    if [[ ! "$1" == /* ]] ; then
        echo "$PHPBREW_ROOT/php/$(__phpbrew_normalize_build $1)/bin/php"
    else
        echo "$1"
    fi
}

# Validates the PHP binary that is to be used as interpreter
function __phpbrew_validate_interpreter()
{
    if [[ -d "$1" ]] ; then
        echo "$1 is a directory"
        return 1
    fi

    if [[ ! -f "$1" ]] ; then
        echo "$1 not found"
        return 1
    fi

    if [[ ! -x "$1" ]] ; then
        echo "$1 is not executable"
        return 1
    fi

    local PHP_VERSION_ID=$(command "$1" -r "echo PHP_VERSION_ID;")

    if [[ $? -ne 0 ]] ; then
        return 1
    fi

    if [[ $PHP_VERSION_ID -lt $MIN_PHP_VERSION_ID ]] ; then
        echo "Only PHP $MIN_PHP_VERSION or newer can be used as PHPBrew interpreter"
        return 1
    fi
}

# Checks whether the given PHP build can be currently used or switched to
function __phpbrew_can_use_build()
{
    if [[ ! -z "$PHPBREW_SYSTEM_PHP" ]] ; then
        # Can use any version since the system interpreter is set
        return
    fi

    __phpbrew_validate_interpreter "$(__phpbrew_get_version_bin $1)"

    if [[ $? -ne 0 ]] ; then
        echo "The system interpreter is not currently set"
        echo "Please execute 'phpbrew system' using PHP $MIN_PHP_VERSION or newer before using an older one"
        return 1
    fi
}

function __phpbrew_set_path()
{
    local PATH_WITHOUT_PHPBREW

    if [[ -n "$PHPBREW_ROOT" ]] ; then
        PATH_WITHOUT_PHPBREW=$(p=$(echo $PATH | tr ":" "\n" | grep -v "^$PHPBREW_ROOT" | tr "\n" ":"); echo ${p%:})
    else
        PATH_WITHOUT_PHPBREW=$PATH
    fi

    if [[ -z "$PHPBREW_PATH" ]]
    then
        export PATH=$PATH_WITHOUT_PHPBREW
    else
        export PATH=$PHPBREW_PATH:$PATH_WITHOUT_PHPBREW
    fi
}

function __phpbrew_load_user_config()
{
    # load user-defined config
    if [[ -f $PHPBREW_HOME/init ]]; then
        . $PHPBREW_HOME/init
        __phpbrew_set_path
    fi
}

if [[ -z "$PHPBREW_SKIP_INIT" ]]; then
    __phpbrew_load_user_config
fi

[[ -e "$PHPBREW_ROOT" ]] || mkdir "$PHPBREW_ROOT"
[[ -e "$PHPBREW_HOME" ]] || mkdir "$PHPBREW_HOME"

# When setting lookup prefix, the alias name will be translated into the real
# path.
#
# Homebrew uses it's own prefix system with cellars, it's more dynamic then
# others.
#
# Detect package system automatically
function __phpbrew_set_lookup_prefix ()
{
    case $1 in
        debian|ubuntu|linux)
            # echo /usr/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu
            echo /usr
        ;;
        macosx)
            echo /usr
        ;;
        macports)
            echo /opt/local
        ;;
        homebrew)
            # TODO: make this more dynamic. with brew --prefix call.
            echo /usr/local/opt:/usr/local
        ;;
        *)
            if [[ -e $1 ]] ; then
                echo $1
            else
                for dir in /opt/local /usr/local/Cellar /usr/local /usr ; do
                    if [[ -e $dir ]] ; then
                        echo $dir
                        return
                    fi
                done
            fi
        ;;
    esac
}

function phpbrew ()
{
    local short_option
    if [[ `echo $1 | awk 'BEGIN{FS=""}{print $1}'` = '-' ]]
    then
        short_option=$1
        shift
    else
        short_option=""
    fi

    case $1 in
        use)
            if [[ -z "$2" ]] ; then
                if [[ -z "$PHPBREW_PHP" ]]
                then
                    echo "Currently using system php"
                else
                    echo "Currently using $PHPBREW_PHP"
                fi

                return
            fi

            if ! output="$(__phpbrew_php_exec env $(__phpbrew_normalize_build $2))"; then
                echo "$output"
                return 1
            fi

            eval "$output"
            __phpbrew_set_path
            ;;
        cd-src)
            local SOURCE_DIR=$PHPBREW_HOME/build/$PHPBREW_PHP
            if [[ -d $SOURCE_DIR ]] ; then
                builtin cd $SOURCE_DIR
            fi
            ;;
        switch)
            if [[ -z "$2" ]]; then
                echo "Please specify the php version."
                return 1
            fi

            __phpbrew_reinit $(__phpbrew_normalize_build $2)
            ;;
        lookup-prefix)
            if [[ -z "$2" ]] ; then
                if [[ -n $PHPBREW_LOOKUP_PREFIX ]] ; then
                    echo $PHPBREW_LOOKUP_PREFIX
                fi
            else
                export PHPBREW_LOOKUP_PREFIX=$(__phpbrew_set_lookup_prefix $2)
                echo $PHPBREW_LOOKUP_PREFIX
                __phpbrew_update_config
            fi
            ;;
        cd)
            case $2 in
                var)
                    local chdir=$PHPBREW_ROOT/php/$PHPBREW_PHP/var
                    ;;
                etc)
                    local chdir=$PHPBREW_ROOT/php/$PHPBREW_PHP/etc
                    ;;
                dist)
                    local chdir=$PHPBREW_ROOT/php/$PHPBREW_PHP
                    ;;
                build)
                    local chdir=$PHPBREW_ROOT/build/$PHPBREW_PHP
                    ;;
                *)
                    echo "$2 not found"
                    return 0
                ;;
            esac
            echo "Switching to $chdir, run 'cd -' to go back."
            builtin cd $chdir
            return 0
            ;;
        each)
            shift
            __phpbrew_each "$@"
            ;;
        fpm)
            if ! [[ -z $3 ]]; then
                PHP_BUILD=$3
            else
                PHP_BUILD=${PHPBREW_PHP}
            fi

            mkdir -p ${PHPBREW_ROOT}/php/${PHP_BUILD}/var/run
            PHPFPM_BIN=${PHPBREW_ROOT}/php/${PHP_BUILD}/sbin/php-fpm
            PHPFPM_PIDFILE=${PHPBREW_ROOT}/php/${PHP_BUILD}/var/run/php-fpm.pid

            function fpm_start()
            {
              echo "Starting php-fpm..."
              local regex="^php-5\.2.*"

              if [[ ${PHP_BUILD} =~ ${regex} ]]; then
                ${PHPFPM_BIN} start
              else
                ${PHPFPM_BIN} --php-ini ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/fpm/php.ini \
                  --fpm-config ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf \
                  --pid ${PHPFPM_PIDFILE} \
                  "$@"
              fi

              if [[ $? != "0" ]] ; then
                echo "php-fpm start failed."
              fi
            }
            function fpm_stop()
            {
              local regex="^php-5\.2.*"

              if [[ ${PHPBREW_PHP} =~ ${regex} ]]; then
                ${PHPFPM_BIN} stop
              elif [[ -e ${PHPFPM_PIDFILE} ]] ; then
                echo "Stopping php-fpm..."
                kill $(cat ${PHPFPM_PIDFILE})
                rm -f ${PHPFPM_PIDFILE}
              fi
            }
            case $2 in
                start)
                    fpm_start "${@:4}"
                    ;;
                stop)
                    fpm_stop
                    ;;
                setup)
                    __phpbrew_php_exec $short_option "$@"
                    ;;
                restart)
                    fpm_stop
                    fpm_start "${@:4}"
                    ;;
                current)
                    if [[ -f $PHPFPM_PIDFILE ]] ; then
                        ps ux -p "$(cat $PHPFPM_PIDFILE)"
                    fi
                    ;;
                module)
                    $PHPFPM_BIN --php-ini ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/fpm/php.ini \
                            --fpm-config ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf \
                            -m | less
                    ;;
                info)
                    $PHPFPM_BIN --php-ini ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/fpm/php.ini \
                            --fpm-config ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf \
                            -i
                    ;;
                config)
                    if [[ -n $EDITOR ]] ; then
                        $EDITOR ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf
                    else
                        echo "Please set EDITOR environment variable for your favor."
                        nano ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf
                    fi
                    ;;
                which)
                    echo $PHPFPM_BIN
                    ;;
                help)
                    $PHPFPM_BIN --php-ini ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/fpm/php.ini \
                            --fpm-config ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf --help
                    ;;
                test)
                    $PHPFPM_BIN --php-ini ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/fpm/php.ini \
                            --fpm-config ${PHPBREW_ROOT}/php/${PHP_BUILD}/etc/php-fpm.conf --test
                    ;;
                *)
                    echo "Usage: phpbrew fpm [start|stop|restart|module|test|config|setup|info|current|which|help]"
                    ;;
            esac
            ;;
        info)
            __phpbrew_php_exec info | php
            ;;
        off)
            unset PHPBREW_PHP
            unset PHPBREW_PATH
            eval $(__phpbrew_php_exec env)
            __phpbrew_set_path
            ;;
        switch-off)
            unset PHPBREW_PHP
            unset PHPBREW_PATH
            eval $(__phpbrew_php_exec env)
            __phpbrew_reinit
            echo "phpbrew is switched off."
            ;;
        system)
            if [[ -z "$2" ]] ; then
                __phpbrew_php_exec system
            else
                local bin="$(__phpbrew_get_version_bin $2)"

                __phpbrew_validate_interpreter "$bin" || return 1

                export PHPBREW_SYSTEM_PHP="$bin"
                __phpbrew_update_config
            fi
            ;;
        system-off)
            __phpbrew_validate_interpreter "$(__phpbrew_which php)"

            if [[ $? -ne 0 ]] ; then
                echo "The currently used PHP build $PHPBREW_PHP cannot be used as PhpBrew interpreter"
                echo "Please execute `phpbrew switch` using PHP $MIN_PHP_VERSION or newer before switching the system interpreter off"
                return 1
            fi

            unset PHPBREW_SYSTEM_PHP
            __phpbrew_update_config
            ;;
        rehash)
            echo "Rehashing..."
            . ~/.phpbrew/bashrc
            ;;
        purge)
            if [[ -z "$2" ]]
            then
                __phpbrew_php_exec help
            else
                shift
                __phpbrew_purge "$@"
            fi
            ;;
        *)
            __phpbrew_php_exec $short_option "$@"
            ;;
    esac

    local exit_status=$?

    if [[ $exit_status -ne 0 ]]; then
        return $exit_status
    fi

    hash -r
}

function __phpbrew_update_config ()
{
    if ! output="$(__phpbrew_php_exec env $(__phpbrew_normalize_build $1))"; then
        echo "$output"
        return 1
    fi

    (
        echo "# DO NOT EDIT THIS FILE"
        echo "$output"
    ) > "$PHPBREW_HOME/init"

    . "$PHPBREW_HOME/init"
}

function __phpbrew_reinit ()
{
    __phpbrew_update_config "$@" && __phpbrew_set_path
}

function __phpbrew_each()
{
    local result=0

    current="$PHPBREW_PHP"
    for build in ${PHPBREW_ROOT}/php/* ; do
        if [ -x "$build/bin/php" ]; then
            phpbrew use $(basename "$build")
            eval "$@" || result=$?
        fi
    done;

    if ! [[ -z "$current" ]]
        then
            phpbrew use $current
        else
            phpbrew off
    fi

    return $result
}

function __phpbrew_purge()
{
    local result=0

    for arg in "$@"
    do
        __phpbrew_purge_build "$arg" || result=$?
    done

    return $result
}

function __phpbrew_purge_build ()
{
    local PHP_BUILD=$(__phpbrew_normalize_build $1)

    if [[ "$PHP_BUILD" = "$PHPBREW_PHP" ]]
    then
        echo "php version: $PHP_BUILD is already in use."
        return 1
    fi

    local bin="$(__phpbrew_get_version_bin $PHP_BUILD)"

    if [[ "$bin" = "$PHPBREW_SYSTEM_PHP" ]] ; then
        echo "PHP build $PHP_BUILD is used as the system interpreter"
        return 1
    fi

    _PHP_BIN_PATH=$PHPBREW_ROOT/php/$PHP_BUILD

    if [ ! -d $_PHP_BIN_PATH ]; then
        echo "php version: $PHP_BUILD not installed."
        return 1
    fi

    _PHP_SOURCE_FILE=$PHPBREW_ROOT/build/$PHP_BUILD.tar.bz2
    _PHP_BUILD_PATH=$PHPBREW_ROOT/build/$PHP_BUILD

    rm -fr $_PHP_SOURCE_FILE $_PHP_BUILD_PATH $_PHP_BIN_PATH

    echo "php version: $PHP_BUILD is removed and purged."

    return 0
}

function phpbrew_current_php_version() {
  if type "php" > /dev/null; then
    local version=$(php -v | grep -E "PHP [578]" | sed 's/.*PHP \([^-]*\).*/\1/' | cut -c 1-6)
    if [[ -z "$PHPBREW_PHP" ]]; then
      echo "php:$version-system"
    else
      echo "php:$version-phpbrew"
    fi
  else
     echo "php:not-installed"
  fi
}

if [[ -n "$PHPBREW_SET_PROMPT" && "$PHPBREW_SET_PROMPT" == "1" ]]; then
    export PS1="\w > \u@\h [\$(phpbrew_current_php_version)]\n\\$ "
fi

# the _phpbrewrc_load will be called after *every simple command* executed in bash,
# this will make the start up process slower if you have many commands to be run in your .bashrc or .zshrc
# so this function simply compares the directory and return if nothing neccessary to do.
#
# here is the description of trap from bash manual page:
#
#   If one of the signals is DEBUG, the list of COMMANDS is executed after
#   every simple command.
#
function _phpbrewrc_load ()
{
    # check if working dir has changed
    if [[ "$PWD" == "$PHPBREW_LAST_DIR" ]]; then
        return
    fi
    local curr_dir="$PWD"
    local prev_dir=""
    local curr_fs=0
    local prev_fs=0

    while [[ -n "$curr_dir" && -d "$curr_dir" ]] ; do
        prev_fs=$curr_fs
        curr_fs=$(stat -c %d "$curr_dir" 2>/dev/null)  # GNU version
        if [ $? -ne 0 ]; then
            curr_fs=$(stat -f %d "$curr_dir" 2>/dev/null)  # BSD version
        fi

        # check if top level directory or filesystem boundary is reached
        if [[ "$curr_dir" == "/" ]] || [ -z "$PHPBREW_RC_DISCOVERY_ACROSS_FILESYSTEM" -a $prev_fs -ne 0 -a $curr_fs -ne $prev_fs ]; then
            # check if there's a previously loaded .phpbrewrc
            if [[ ! -z "$PHPBREW_LAST_RC_DIR" ]]; then
                unset PHPBREW_LAST_RC_DIR
                __phpbrew_load_user_config
            fi
            break
        fi

        # check if .phpbrewrc present
        if [[ -r "$curr_dir/.phpbrewrc" ]]; then
            # check if it's not the same .phpbrewrc which was previously loaded
            if [[ "$curr_dir" != "$PHPBREW_LAST_RC_DIR" ]]; then
                __phpbrew_load_user_config
                PHPBREW_LAST_RC_DIR="$curr_dir"
                source "$curr_dir/.phpbrewrc"
            fi
            break
        fi
        curr_dir=$(dirname "$curr_dir")
    done
    PHPBREW_LAST_DIR="$PWD"
}

if [[ -n "$PHPBREW_RC_ENABLE" ]]; then
    if [[ -n "$BASH_VERSION" ]]; then
        trap "_phpbrewrc_load" DEBUG
    fi

    # zsh has easy-to-extend cd hooks, so we migth as well use them instead
    # of running _phpbrewrc_load after EVERY command.
    if [[ -n "$ZSH_VERSION" ]]; then
        if [[ -n "$chpwd_functions" ]]; then
            if [[ ${chpwd_functions[(ie)_phpbrewrc_load]} -gt ${#chpwd_functions} ]]; then
                chpwd_functions+=_phpbrewrc_load
            fi
        else
            chpwd_functions=( _phpbrewrc_load )
        fi
    fi
fi

Copyright (c) Nils Adermann, Jordi Boggiano

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'HumbugBox3150\\KevinGH\\RequirementChecker\\' => array($baseDir . '/src'),
    'HumbugBox3150\\Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
);
<?php

namespace HumbugBox3150\Composer\Semver\Constraint;

interface ConstraintInterface
{
    public function matches(ConstraintInterface $provider);
    public function compile($operator);
    public function getUpperBound();
    public function getLowerBound();
    public function getPrettyString();
    public function setPrettyString($prettyString);
    public function __toString();
}
<?php

namespace HumbugBox3150\Composer\Semver\Constraint;

class Constraint implements ConstraintInterface
{
    const OP_EQ = 0;
    const OP_LT = 1;
    const OP_LE = 2;
    const OP_GT = 3;
    const OP_GE = 4;
    const OP_NE = 5;
    /**
    @phpstan-var
    */
    private static $transOpStr = array('=' => self::OP_EQ, '==' => self::OP_EQ, '<' => self::OP_LT, '<=' => self::OP_LE, '>' => self::OP_GT, '>=' => self::OP_GE, '<>' => self::OP_NE, '!=' => self::OP_NE);
    /**
    @phpstan-var
    */
    private static $transOpInt = array(self::OP_EQ => '==', self::OP_LT => '<', self::OP_LE => '<=', self::OP_GT => '>', self::OP_GE => '>=', self::OP_NE => '!=');
    /**
    @phpstan-var
    */
    protected $operator;
    protected $version;
    protected $prettyString;
    protected $lowerBound;
    protected $upperBound;
    public function __construct($operator, $version)
    {
        if (!isset(self::$transOpStr[$operator])) {
            throw new \InvalidArgumentException(\sprintf('Invalid operator "%s" given, expected one of: %s', $operator, \implode(', ', self::getSupportedOperators())));
        }
        $this->operator = self::$transOpStr[$operator];
        $this->version = $version;
    }
    public function getVersion()
    {
        return $this->version;
    }
    public function getOperator()
    {
        return self::$transOpInt[$this->operator];
    }
    public function matches(ConstraintInterface $provider)
    {
        if ($provider instanceof self) {
            return $this->matchSpecific($provider);
        }
        return $provider->matches($this);
    }
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return $this->__toString();
    }
    public static function getSupportedOperators()
    {
        return \array_keys(self::$transOpStr);
    }
    /**
    @phpstan-return
    */
    public static function getOperatorConstant($operator)
    {
        return self::$transOpStr[$operator];
    }
    public function versionCompare($a, $b, $operator, $compareBranches = \false)
    {
        if (!isset(self::$transOpStr[$operator])) {
            throw new \InvalidArgumentException(\sprintf('Invalid operator "%s" given, expected one of: %s', $operator, \implode(', ', self::getSupportedOperators())));
        }
        $aIsBranch = 'dev-' === \substr($a, 0, 4);
        $bIsBranch = 'dev-' === \substr($b, 0, 4);
        if ($operator === '!=' && ($aIsBranch || $bIsBranch)) {
            return $a !== $b;
        }
        if ($aIsBranch && $bIsBranch) {
            return $operator === '==' && $a === $b;
        }
        if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
            return \false;
        }
        return \version_compare($a, $b, $operator);
    }
    public function compile($otherOperator)
    {
        if ($this->version[0] === 'd' && 'dev-' === \substr($this->version, 0, 4)) {
            if (self::OP_EQ === $this->operator) {
                if (self::OP_EQ === $otherOperator) {
                    return \sprintf('$b && $v === %s', \var_export($this->version, \true));
                }
                if (self::OP_NE === $otherOperator) {
                    return \sprintf('!$b || $v !== %s', \var_export($this->version, \true));
                }
                return 'false';
            }
            if (self::OP_NE === $this->operator) {
                if (self::OP_EQ === $otherOperator) {
                    return \sprintf('!$b || $v !== %s', \var_export($this->version, \true));
                }
                if (self::OP_NE === $otherOperator) {
                    return 'true';
                }
                return '!$b';
            }
            return 'false';
        }
        if (self::OP_EQ === $this->operator) {
            if (self::OP_EQ === $otherOperator) {
                return \sprintf('\\version_compare($v, %s, \'==\')', \var_export($this->version, \true));
            }
            if (self::OP_NE === $otherOperator) {
                return \sprintf('$b || \\version_compare($v, %s, \'!=\')', \var_export($this->version, \true));
            }
            return \sprintf('!$b && \\version_compare(%s, $v, \'%s\')', \var_export($this->version, \true), self::$transOpInt[$otherOperator]);
        }
        if (self::OP_NE === $this->operator) {
            if (self::OP_EQ === $otherOperator) {
                return \sprintf('$b || (!$b && \\version_compare($v, %s, \'!=\'))', \var_export($this->version, \true));
            }
            if (self::OP_NE === $otherOperator) {
                return 'true';
            }
            return '!$b';
        }
        if (self::OP_LT === $this->operator || self::OP_LE === $this->operator) {
            if (self::OP_LT === $otherOperator || self::OP_LE === $otherOperator) {
                return '!$b';
            }
        } elseif (self::OP_GT === $this->operator || self::OP_GE === $this->operator) {
            if (self::OP_GT === $otherOperator || self::OP_GE === $otherOperator) {
                return '!$b';
            }
        }
        if (self::OP_NE === $otherOperator) {
            return 'true';
        }
        $codeComparison = \sprintf('\\version_compare($v, %s, \'%s\')', \var_export($this->version, \true), self::$transOpInt[$this->operator]);
        if ($this->operator === self::OP_LE) {
            if ($otherOperator === self::OP_GT) {
                return \sprintf('!$b && \\version_compare($v, %s, \'!=\') && ', \var_export($this->version, \true)) . $codeComparison;
            }
        } elseif ($this->operator === self::OP_GE) {
            if ($otherOperator === self::OP_LT) {
                return \sprintf('!$b && \\version_compare($v, %s, \'!=\') && ', \var_export($this->version, \true)) . $codeComparison;
            }
        }
        return \sprintf('!$b && %s', $codeComparison);
    }
    public function matchSpecific(Constraint $provider, $compareBranches = \false)
    {
        $noEqualOp = \str_replace('=', '', self::$transOpInt[$this->operator]);
        $providerNoEqualOp = \str_replace('=', '', self::$transOpInt[$provider->operator]);
        $isEqualOp = self::OP_EQ === $this->operator;
        $isNonEqualOp = self::OP_NE === $this->operator;
        $isProviderEqualOp = self::OP_EQ === $provider->operator;
        $isProviderNonEqualOp = self::OP_NE === $provider->operator;
        if ($isNonEqualOp || $isProviderNonEqualOp) {
            if ($isNonEqualOp && !$isProviderNonEqualOp && !$isProviderEqualOp && 'dev-' === \substr($provider->version, 0, 4)) {
                return \false;
            }
            if ($isProviderNonEqualOp && !$isNonEqualOp && !$isEqualOp && 'dev-' === \substr($this->version, 0, 4)) {
                return \false;
            }
            if (!$isEqualOp && !$isProviderEqualOp) {
                return \true;
            }
            return $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
        }
        if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) {
            if ('dev-' === \substr($this->version, 0, 4) || 'dev-' === \substr($provider->version, 0, 4)) {
                return \false;
            }
            return \true;
        }
        $version1 = $isEqualOp ? $this->version : $provider->version;
        $version2 = $isEqualOp ? $provider->version : $this->version;
        $operator = $isEqualOp ? $provider->operator : $this->operator;
        if ($this->versionCompare($version1, $version2, self::$transOpInt[$operator], $compareBranches)) {
            return !(self::$transOpInt[$provider->operator] === $providerNoEqualOp && self::$transOpInt[$this->operator] !== $noEqualOp && \version_compare($provider->version, $this->version, '=='));
        }
        return \false;
    }
    public function __toString()
    {
        return self::$transOpInt[$this->operator] . ' ' . $this->version;
    }
    public function getLowerBound()
    {
        $this->extractBounds();
        return $this->lowerBound;
    }
    public function getUpperBound()
    {
        $this->extractBounds();
        return $this->upperBound;
    }
    private function extractBounds()
    {
        if (null !== $this->lowerBound) {
            return;
        }
        if (\strpos($this->version, 'dev-') === 0) {
            $this->lowerBound = Bound::zero();
            $this->upperBound = Bound::positiveInfinity();
            return;
        }
        switch ($this->operator) {
            case self::OP_EQ:
                $this->lowerBound = new Bound($this->version, \true);
                $this->upperBound = new Bound($this->version, \true);
                break;
            case self::OP_LT:
                $this->lowerBound = Bound::zero();
                $this->upperBound = new Bound($this->version, \false);
                break;
            case self::OP_LE:
                $this->lowerBound = Bound::zero();
                $this->upperBound = new Bound($this->version, \true);
                break;
            case self::OP_GT:
                $this->lowerBound = new Bound($this->version, \false);
                $this->upperBound = Bound::positiveInfinity();
                break;
            case self::OP_GE:
                $this->lowerBound = new Bound($this->version, \true);
                $this->upperBound = Bound::positiveInfinity();
                break;
            case self::OP_NE:
                $this->lowerBound = Bound::zero();
                $this->upperBound = Bound::positiveInfinity();
                break;
        }
    }
}
<?php

namespace HumbugBox3150\Composer\Semver\Constraint;

class MultiConstraint implements ConstraintInterface
{
    protected $constraints;
    protected $prettyString;
    protected $string;
    protected $conjunctive;
    protected $lowerBound;
    protected $upperBound;
    public function __construct(array $constraints, $conjunctive = \true)
    {
        if (\count($constraints) < 2) {
            throw new \InvalidArgumentException('Must provide at least two constraints for a MultiConstraint. Use ' . 'the regular Constraint class for one constraint only or MatchAllConstraint for none. You may use ' . 'MultiConstraint::create() which optimizes and handles those cases automatically.');
        }
        $this->constraints = $constraints;
        $this->conjunctive = $conjunctive;
    }
    public function getConstraints()
    {
        return $this->constraints;
    }
    public function isConjunctive()
    {
        return $this->conjunctive;
    }
    public function isDisjunctive()
    {
        return !$this->conjunctive;
    }
    public function compile($otherOperator)
    {
        $parts = array();
        foreach ($this->constraints as $constraint) {
            $code = $constraint->compile($otherOperator);
            if ($code === 'true') {
                if (!$this->conjunctive) {
                    return 'true';
                }
            } elseif ($code === 'false') {
                if ($this->conjunctive) {
                    return 'false';
                }
            } else {
                $parts[] = '(' . $code . ')';
            }
        }
        if (!$parts) {
            return $this->conjunctive ? 'true' : 'false';
        }
        return $this->conjunctive ? \implode('&&', $parts) : \implode('||', $parts);
    }
    public function matches(ConstraintInterface $provider)
    {
        if (\false === $this->conjunctive) {
            foreach ($this->constraints as $constraint) {
                if ($provider->matches($constraint)) {
                    return \true;
                }
            }
            return \false;
        }
        foreach ($this->constraints as $constraint) {
            if (!$provider->matches($constraint)) {
                return \false;
            }
        }
        return \true;
    }
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return (string) $this;
    }
    public function __toString()
    {
        if ($this->string !== null) {
            return $this->string;
        }
        $constraints = array();
        foreach ($this->constraints as $constraint) {
            $constraints[] = (string) $constraint;
        }
        return $this->string = '[' . \implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']';
    }
    public function getLowerBound()
    {
        $this->extractBounds();
        return $this->lowerBound;
    }
    public function getUpperBound()
    {
        $this->extractBounds();
        return $this->upperBound;
    }
    public static function create(array $constraints, $conjunctive = \true)
    {
        if (0 === \count($constraints)) {
            return new MatchAllConstraint();
        }
        if (1 === \count($constraints)) {
            return $constraints[0];
        }
        $optimized = self::optimizeConstraints($constraints, $conjunctive);
        if ($optimized !== null) {
            list($constraints, $conjunctive) = $optimized;
            if (\count($constraints) === 1) {
                return $constraints[0];
            }
        }
        return new self($constraints, $conjunctive);
    }
    private static function optimizeConstraints(array $constraints, $conjunctive)
    {
        if (!$conjunctive) {
            $left = $constraints[0];
            $mergedConstraints = array();
            $optimized = \false;
            for ($i = 1, $l = \count($constraints); $i < $l; $i++) {
                $right = $constraints[$i];
                if ($left instanceof MultiConstraint && $left->conjunctive && $right instanceof MultiConstraint && $right->conjunctive && ($left0 = (string) $left->constraints[0]) && $left0[0] === '>' && $left0[1] === '=' && ($left1 = (string) $left->constraints[1]) && $left1[0] === '<' && ($right0 = (string) $right->constraints[0]) && $right0[0] === '>' && $right0[1] === '=' && ($right1 = (string) $right->constraints[1]) && $right1[0] === '<' && \substr($left1, 2) === \substr($right0, 3)) {
                    $optimized = \true;
                    $left = new MultiConstraint(\array_merge(array($left->constraints[0], $right->constraints[1]), \array_slice($left->constraints, 2), \array_slice($right->constraints, 2)), \true);
                } else {
                    $mergedConstraints[] = $left;
                    $left = $right;
                }
            }
            if ($optimized) {
                $mergedConstraints[] = $left;
                return array($mergedConstraints, \false);
            }
        }
        return null;
    }
    private function extractBounds()
    {
        if (null !== $this->lowerBound) {
            return;
        }
        foreach ($this->constraints as $constraint) {
            if (null === $this->lowerBound && null === $this->upperBound) {
                $this->lowerBound = $constraint->getLowerBound();
                $this->upperBound = $constraint->getUpperBound();
                continue;
            }
            if ($constraint->getLowerBound()->compareTo($this->lowerBound, $this->isConjunctive() ? '>' : '<')) {
                $this->lowerBound = $constraint->getLowerBound();
            }
            if ($constraint->getUpperBound()->compareTo($this->upperBound, $this->isConjunctive() ? '<' : '>')) {
                $this->upperBound = $constraint->getUpperBound();
            }
        }
    }
}
<?php

namespace HumbugBox3150\Composer\Semver;

use HumbugBox3150\Composer\Semver\Constraint\Constraint;
class Semver
{
    const SORT_ASC = 1;
    const SORT_DESC = -1;
    private static $versionParser;
    public static function satisfies($version, $constraints)
    {
        if (null === self::$versionParser) {
            self::$versionParser = new VersionParser();
        }
        $versionParser = self::$versionParser;
        $provider = new Constraint('==', $versionParser->normalize($version));
        $parsedConstraints = $versionParser->parseConstraints($constraints);
        return $parsedConstraints->matches($provider);
    }
    public static function satisfiedBy(array $versions, $constraints)
    {
        $versions = \array_filter($versions, function ($version) use($constraints) {
            return Semver::satisfies($version, $constraints);
        });
        return \array_values($versions);
    }
    public static function sort(array $versions)
    {
        return self::usort($versions, self::SORT_ASC);
    }
    public static function rsort(array $versions)
    {
        return self::usort($versions, self::SORT_DESC);
    }
    private static function usort(array $versions, $direction)
    {
        if (null === self::$versionParser) {
            self::$versionParser = new VersionParser();
        }
        $versionParser = self::$versionParser;
        $normalized = array();
        foreach ($versions as $key => $version) {
            $normalizedVersion = $versionParser->normalize($version);
            $normalizedVersion = $versionParser->normalizeDefaultBranch($normalizedVersion);
            $normalized[] = array($normalizedVersion, $key);
        }
        \usort($normalized, function (array $left, array $right) use($direction) {
            if ($left[0] === $right[0]) {
                return 0;
            }
            if (Comparator::lessThan($left[0], $right[0])) {
                return -$direction;
            }
            return $direction;
        });
        $sorted = array();
        foreach ($normalized as $item) {
            $sorted[] = $versions[$item[1]];
        }
        return $sorted;
    }
}
<?php

namespace HumbugBox3150\Composer\Semver;

use HumbugBox3150\Composer\Semver\Constraint\ConstraintInterface;
use HumbugBox3150\Composer\Semver\Constraint\MatchAllConstraint;
use HumbugBox3150\Composer\Semver\Constraint\MultiConstraint;
use HumbugBox3150\Composer\Semver\Constraint\Constraint;
class VersionParser
{
    private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\\d+)*+)?)?([.-]?dev)?';
    private static $stabilitiesRegex = 'stable|RC|beta|alpha|dev';
    public static function parseStability($version)
    {
        $version = \preg_replace('{#.+$}i', '', $version);
        if (\strpos($version, 'dev-') === 0 || '-dev' === \substr($version, -4)) {
            return 'dev';
        }
        \preg_match('{' . self::$modifierRegex . '(?:\\+.*)?$}i', \strtolower($version), $match);
        if (!empty($match[3])) {
            return 'dev';
        }
        if (!empty($match[1])) {
            if ('beta' === $match[1] || 'b' === $match[1]) {
                return 'beta';
            }
            if ('alpha' === $match[1] || 'a' === $match[1]) {
                return 'alpha';
            }
            if ('rc' === $match[1]) {
                return 'RC';
            }
        }
        return 'stable';
    }
    public static function normalizeStability($stability)
    {
        $stability = \strtolower($stability);
        return $stability === 'rc' ? 'RC' : $stability;
    }
    public function normalize($version, $fullVersion = null)
    {
        $version = \trim($version);
        $origVersion = $version;
        if (null === $fullVersion) {
            $fullVersion = $version;
        }
        if (\preg_match('{^([^,\\s]++) ++as ++([^,\\s]++)$}', $version, $match)) {
            $version = $match[1];
        }
        if (\preg_match('{@(?:' . self::$stabilitiesRegex . ')$}i', $version, $match)) {
            $version = \substr($version, 0, \strlen($version) - \strlen($match[0]));
        }
        if (\in_array($version, array('master', 'trunk', 'default'), \true)) {
            $version = 'dev-' . $version;
        }
        if (\stripos($version, 'dev-') === 0) {
            return 'dev-' . \substr($version, 4);
        }
        if (\preg_match('{^([^,\\s+]++)\\+[^\\s]++$}', $version, $match)) {
            $version = $match[1];
        }
        if (\preg_match('{^v?(\\d{1,5})(\\.\\d++)?(\\.\\d++)?(\\.\\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = $matches[1] . (!empty($matches[2]) ? $matches[2] : '.0') . (!empty($matches[3]) ? $matches[3] : '.0') . (!empty($matches[4]) ? $matches[4] : '.0');
            $index = 5;
        } elseif (\preg_match('{^v?(\\d{4}(?:[.:-]?\\d{2}){1,6}(?:[.:-]?\\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = \preg_replace('{\\D}', '.', $matches[1]);
            $index = 2;
        }
        if (isset($index)) {
            if (!empty($matches[$index])) {
                if ('stable' === $matches[$index]) {
                    return $version;
                }
                $version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? \ltrim($matches[$index + 1], '.-') : '');
            }
            if (!empty($matches[$index + 2])) {
                $version .= '-dev';
            }
            return $version;
        }
        if (\preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
            try {
                $normalized = $this->normalizeBranch($match[1]);
                if (\strpos($normalized, 'dev-') === \false) {
                    return $normalized;
                }
            } catch (\Exception $e) {
            }
        }
        $extraMessage = '';
        if (\preg_match('{ +as +' . \preg_quote($version) . '(?:@(?:' . self::$stabilitiesRegex . '))?$}', $fullVersion)) {
            $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version';
        } elseif (\preg_match('{^' . \preg_quote($version) . '(?:@(?:' . self::$stabilitiesRegex . '))? +as +}', $fullVersion)) {
            $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
        }
        throw new \UnexpectedValueException('Invalid version string "' . $origVersion . '"' . $extraMessage);
    }
    public function parseNumericAliasPrefix($branch)
    {
        if (\preg_match('{^(?P<version>(\\d++\\.)*\\d++)(?:\\.x)?-dev$}i', $branch, $matches)) {
            return $matches['version'] . '.';
        }
        return \false;
    }
    public function normalizeBranch($name)
    {
        $name = \trim($name);
        if (\preg_match('{^v?(\\d++)(\\.(?:\\d++|[xX*]))?(\\.(?:\\d++|[xX*]))?(\\.(?:\\d++|[xX*]))?$}i', $name, $matches)) {
            $version = '';
            for ($i = 1; $i < 5; ++$i) {
                $version .= isset($matches[$i]) ? \str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
            }
            return \str_replace('x', '9999999', $version) . '-dev';
        }
        return 'dev-' . $name;
    }
    public function normalizeDefaultBranch($name)
    {
        if ($name === 'dev-master' || $name === 'dev-default' || $name === 'dev-trunk') {
            return '9999999-dev';
        }
        return $name;
    }
    public function parseConstraints($constraints)
    {
        $prettyConstraint = $constraints;
        $orConstraints = \preg_split('{\\s*\\|\\|?\\s*}', \trim($constraints));
        $orGroups = array();
        foreach ($orConstraints as $constraints) {
            $andConstraints = \preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
            if (\count($andConstraints) > 1) {
                $constraintObjects = array();
                foreach ($andConstraints as $constraint) {
                    foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
                        $constraintObjects[] = $parsedConstraint;
                    }
                }
            } else {
                $constraintObjects = $this->parseConstraint($andConstraints[0]);
            }
            if (1 === \count($constraintObjects)) {
                $constraint = $constraintObjects[0];
            } else {
                $constraint = new MultiConstraint($constraintObjects);
            }
            $orGroups[] = $constraint;
        }
        $constraint = MultiConstraint::create($orGroups, \false);
        $constraint->setPrettyString($prettyConstraint);
        return $constraint;
    }
    private function parseConstraint($constraint)
    {
        if (\preg_match('{^([^,\\s]++) ++as ++([^,\\s]++)$}', $constraint, $match)) {
            $constraint = $match[1];
        }
        if (\preg_match('{^([^,\\s]*?)@(' . self::$stabilitiesRegex . ')$}i', $constraint, $match)) {
            $constraint = '' !== $match[1] ? $match[1] : '*';
            if ($match[2] !== 'stable') {
                $stabilityModifier = $match[2];
            }
        }
        if (\preg_match('{^(dev-[^,\\s@]+?|[^,\\s@]+?\\.x-dev)#.+$}i', $constraint, $match)) {
            $constraint = $match[1];
        }
        if (\preg_match('{^(v)?[xX*](\\.[xX*])*$}i', $constraint, $match)) {
            if (!empty($match[1]) || !empty($match[2])) {
                return array(new Constraint('>=', '0.0.0.0-dev'));
            }
            return array(new MatchAllConstraint());
        }
        $versionRegex = 'v?(\\d++)(?:\\.(\\d++|[xX*]))?(?:\\.(\\d++|[xX*]))?(?:\\.(\\d++|[xX*]))?' . self::$modifierRegex . '(?:\\+[^\\s]+)?';
        if (\preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
            if (\strpos($constraint, '~>') === 0) {
                throw new \UnexpectedValueException('Could not parse version constraint ' . $constraint . ': ' . 'Invalid operator "~>", you probably meant to use the "~" operator');
            }
            if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
                $position = 4;
            } elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }
            for ($i = $position; $i >= 0; $i--) {
                if ($matches[$i] === 'x' || $matches[$i] === 'X' || $matches[$i] === '*') {
                    $matches[$i] = '9999999';
                }
            }
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7])) {
                $stabilitySuffix .= '-dev';
            }
            $lowVersion = $this->normalize(\substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);
            $highPosition = \max(1, $position - 1);
            $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);
            return array($lowerBound, $upperBound);
        }
        if (\preg_match('{^\\^' . $versionRegex . '($)}i', $constraint, $matches)) {
            if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
                $position = 1;
            } elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
                $position = 2;
            } else {
                $position = 3;
            }
            if ($position === 2 && ($matches[2] === 'x' || $matches[2] === 'X' || $matches[2] === '*')) {
                $position = 1;
            }
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7])) {
                $stabilitySuffix .= '-dev';
            }
            $lowVersion = $this->normalize(\substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);
            return array($lowerBound, $upperBound);
        }
        if (\preg_match('{^v?(\\d++)(?:\\.(\\d++))?(?:\\.(\\d++))?(?:\\.[xX*])++$}', $constraint, $matches)) {
            if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }
            $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            if ($lowVersion === '0.0.0.0-dev') {
                return array(new Constraint('<', $highVersion));
            }
            return array(new Constraint('>=', $lowVersion), new Constraint('<', $highVersion));
        }
        if (\preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
            $lowStabilitySuffix = '';
            if (empty($matches[6]) && empty($matches[8])) {
                $lowStabilitySuffix = '-dev';
            }
            $lowVersion = $this->normalize($matches['from']);
            $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);
            $empty = function ($x) {
                return $x === 0 || $x === '0' ? \false : empty($x);
            };
            if (!$empty($matches[11]) && !$empty($matches[12]) || !empty($matches[14]) || !empty($matches[16])) {
                $highVersion = $this->normalize($matches['to']);
                $upperBound = new Constraint('<=', $highVersion);
            } else {
                $highMatch = array('', $matches[10], $matches[11], $matches[12], $matches[13]);
                $this->normalize($matches['to']);
                $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[11]) ? 1 : 2, 1) . '-dev';
                $upperBound = new Constraint('<', $highVersion);
            }
            return array($lowerBound, $upperBound);
        }
        if (\preg_match('{^(<>|!=|>=?|<=?|==?)?\\s*(.*)}', $constraint, $matches)) {
            try {
                try {
                    $version = $this->normalize($matches[2]);
                } catch (\UnexpectedValueException $e) {
                    if (\substr($matches[2], -4) === '-dev') {
                        $version = $this->normalize('dev-' . \substr($matches[2], 0, -4));
                    } else {
                        throw $e;
                    }
                }
                $op = $matches[1] ?: '=';
                if ($op !== '==' && $op !== '=' && !empty($stabilityModifier) && self::parseStability($version) === 'stable') {
                    $version .= '-' . $stabilityModifier;
                } elseif ('<' === $op || '>=' === $op) {
                    if (!\preg_match('/-' . self::$modifierRegex . '$/', \strtolower($matches[2]))) {
                        if (\strpos($matches[2], 'dev-') !== 0) {
                            $version .= '-dev';
                        }
                    }
                }
                return array(new Constraint($matches[1] ?: '=', $version));
            } catch (\Exception $e) {
            }
        }
        $message = 'Could not parse version constraint ' . $constraint;
        if (isset($e)) {
            $message .= ': ' . $e->getMessage();
        }
        throw new \UnexpectedValueException($message);
    }
    private function manipulateVersionString($matches, $position, $increment = 0, $pad = '0')
    {
        for ($i = 4; $i > 0; --$i) {
            if ($i > $position) {
                $matches[$i] = $pad;
            } elseif ($i === $position && $increment) {
                $matches[$i] += $increment;
                if ($matches[$i] < 0) {
                    $matches[$i] = $pad;
                    --$position;
                    if ($i === 1) {
                        return null;
                    }
                }
            }
        }
        return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
    }
    private function expandStability($stability)
    {
        $stability = \strtolower($stability);
        switch ($stability) {
            case 'a':
                return 'alpha';
            case 'b':
                return 'beta';
            case 'p':
            case 'pl':
                return 'patch';
            case 'rc':
                return 'RC';
            default:
                return $stability;
        }
    }
}
<?php

namespace HumbugBox3150\Composer\Semver;

use HumbugBox3150\Composer\Semver\Constraint\Constraint;
class Comparator
{
    public static function greaterThan($version1, $version2)
    {
        return self::compare($version1, '>', $version2);
    }
    public static function greaterThanOrEqualTo($version1, $version2)
    {
        return self::compare($version1, '>=', $version2);
    }
    public static function lessThan($version1, $version2)
    {
        return self::compare($version1, '<', $version2);
    }
    public static function lessThanOrEqualTo($version1, $version2)
    {
        return self::compare($version1, '<=', $version2);
    }
    public static function equalTo($version1, $version2)
    {
        return self::compare($version1, '==', $version2);
    }
    public static function notEqualTo($version1, $version2)
    {
        return self::compare($version1, '!=', $version2);
    }
    public static function compare($version1, $operator, $version2)
    {
        $constraint = new Constraint($operator, $version2);
        return $constraint->matchSpecific(new Constraint('==', $version1), \true);
    }
}
<?php

// autoload_static.php @generated by Composer

namespace Composer\Autoload;

class ComposerStaticInit7b1918d23e69dc64db20ca1f98396893
{
    public static $prefixLengthsPsr4 = array (
        'H' => 
        array (
            'HumbugBox3150\\KevinGH\\RequirementChecker\\' => 41,
            'HumbugBox3150\\Composer\\Semver\\' => 30,
        ),
    );

    public static $prefixDirsPsr4 = array (
        'HumbugBox3150\\KevinGH\\RequirementChecker\\' => 
        array (
            0 => __DIR__ . '/../..' . '/src',
        ),
        'HumbugBox3150\\Composer\\Semver\\' => 
        array (
            0 => __DIR__ . '/..' . '/composer/semver/src',
        ),
    );

    public static $classMap = array (
        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
        'HumbugBox3150\\Composer\\Semver\\Comparator' => __DIR__ . '/..' . '/composer/semver/src/Comparator.php',
        'HumbugBox3150\\Composer\\Semver\\CompilingMatcher' => __DIR__ . '/..' . '/composer/semver/src/CompilingMatcher.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\Bound' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Bound.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\Constraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Constraint.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\ConstraintInterface' => __DIR__ . '/..' . '/composer/semver/src/Constraint/ConstraintInterface.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchAllConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MatchAllConstraint.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchNoneConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MatchNoneConstraint.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\MultiConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MultiConstraint.php',
        'HumbugBox3150\\Composer\\Semver\\Interval' => __DIR__ . '/..' . '/composer/semver/src/Interval.php',
        'HumbugBox3150\\Composer\\Semver\\Intervals' => __DIR__ . '/..' . '/composer/semver/src/Intervals.php',
        'HumbugBox3150\\Composer\\Semver\\Semver' => __DIR__ . '/..' . '/composer/semver/src/Semver.php',
        'HumbugBox3150\\Composer\\Semver\\VersionParser' => __DIR__ . '/..' . '/composer/semver/src/VersionParser.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Checker' => __DIR__ . '/../..' . '/src/Checker.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IO' => __DIR__ . '/../..' . '/src/IO.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IsExtensionFulfilled' => __DIR__ . '/../..' . '/src/IsExtensionFulfilled.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IsFulfilled' => __DIR__ . '/../..' . '/src/IsFulfilled.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IsPhpVersionFulfilled' => __DIR__ . '/../..' . '/src/IsPhpVersionFulfilled.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Printer' => __DIR__ . '/../..' . '/src/Printer.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Requirement' => __DIR__ . '/../..' . '/src/Requirement.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\RequirementCollection' => __DIR__ . '/../..' . '/src/RequirementCollection.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Terminal' => __DIR__ . '/../..' . '/src/Terminal.php',
    );

    public static function getInitializer(ClassLoader $loader)
    {
        return \Closure::bind(function () use ($loader) {
            $loader->prefixLengthsPsr4 = ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::$prefixLengthsPsr4;
            $loader->prefixDirsPsr4 = ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::$prefixDirsPsr4;
            $loader->classMap = ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::$classMap;

        }, null, ClassLoader::class);
    }
}
<?php

// autoload_namespaces.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
);
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Autoload;

/**
 * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 *
 *     $loader = new \Composer\Autoload\ClassLoader();
 *
 *     // register classes with namespaces
 *     $loader->add('Symfony\Component', __DIR__.'/component');
 *     $loader->add('Symfony',           __DIR__.'/framework');
 *
 *     // activate the autoloader
 *     $loader->register();
 *
 *     // to enable searching the include path (eg. for PEAR packages)
 *     $loader->setUseIncludePath(true);
 *
 * In this example, if you try to use a class in the Symfony\Component
 * namespace or one of its children (Symfony\Component\Console for instance),
 * the autoloader will first look for the class under the component/
 * directory, and it will then fallback to the framework/ directory if not
 * found before giving up.
 *
 * This class is loosely based on the Symfony UniversalClassLoader.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @see    https://www.php-fig.org/psr/psr-0/
 * @see    https://www.php-fig.org/psr/psr-4/
 */
class ClassLoader
{
    /** @var ?string */
    private $vendorDir;

    // PSR-4
    /**
     * @var array[]
     * @psalm-var array<string, array<string, int>>
     */
    private $prefixLengthsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, array<int, string>>
     */
    private $prefixDirsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr4 = array();

    // PSR-0
    /**
     * @var array[]
     * @psalm-var array<string, array<string, string[]>>
     */
    private $prefixesPsr0 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr0 = array();

    /** @var bool */
    private $useIncludePath = false;

    /**
     * @var string[]
     * @psalm-var array<string, string>
     */
    private $classMap = array();

    /** @var bool */
    private $classMapAuthoritative = false;

    /**
     * @var bool[]
     * @psalm-var array<string, bool>
     */
    private $missingClasses = array();

    /** @var ?string */
    private $apcuPrefix;

    /**
     * @var self[]
     */
    private static $registeredLoaders = array();

    /**
     * @param ?string $vendorDir
     */
    public function __construct($vendorDir = null)
    {
        $this->vendorDir = $vendorDir;
    }

    /**
     * @return string[]
     */
    public function getPrefixes()
    {
        if (!empty($this->prefixesPsr0)) {
            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
        }

        return array();
    }

    /**
     * @return array[]
     * @psalm-return array<string, array<int, string>>
     */
    public function getPrefixesPsr4()
    {
        return $this->prefixDirsPsr4;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirs()
    {
        return $this->fallbackDirsPsr0;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirsPsr4()
    {
        return $this->fallbackDirsPsr4;
    }

    /**
     * @return string[] Array of classname => path
     * @psalm-return array<string, string>
     */
    public function getClassMap()
    {
        return $this->classMap;
    }

    /**
     * @param string[] $classMap Class to filename map
     * @psalm-param array<string, string> $classMap
     *
     * @return void
     */
    public function addClassMap(array $classMap)
    {
        if ($this->classMap) {
            $this->classMap = array_merge($this->classMap, $classMap);
        } else {
            $this->classMap = $classMap;
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix, either
     * appending or prepending to the ones previously set for this prefix.
     *
     * @param string          $prefix  The prefix
     * @param string[]|string $paths   The PSR-0 root directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @return void
     */
    public function add($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            if ($prepend) {
                $this->fallbackDirsPsr0 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr0
                );
            } else {
                $this->fallbackDirsPsr0 = array_merge(
                    $this->fallbackDirsPsr0,
                    (array) $paths
                );
            }

            return;
        }

        $first = $prefix[0];
        if (!isset($this->prefixesPsr0[$first][$prefix])) {
            $this->prefixesPsr0[$first][$prefix] = (array) $paths;

            return;
        }
        if ($prepend) {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                (array) $paths,
                $this->prefixesPsr0[$first][$prefix]
            );
        } else {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                $this->prefixesPsr0[$first][$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace, either
     * appending or prepending to the ones previously set for this namespace.
     *
     * @param string          $prefix  The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths   The PSR-4 base directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function addPsr4($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            // Register directories for the root namespace.
            if ($prepend) {
                $this->fallbackDirsPsr4 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr4
                );
            } else {
                $this->fallbackDirsPsr4 = array_merge(
                    $this->fallbackDirsPsr4,
                    (array) $paths
                );
            }
        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
            // Register directories for a new namespace.
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        } elseif ($prepend) {
            // Prepend directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                (array) $paths,
                $this->prefixDirsPsr4[$prefix]
            );
        } else {
            // Append directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                $this->prefixDirsPsr4[$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix,
     * replacing any others previously set for this prefix.
     *
     * @param string          $prefix The prefix
     * @param string[]|string $paths  The PSR-0 base directories
     *
     * @return void
     */
    public function set($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr0 = (array) $paths;
        } else {
            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace,
     * replacing any others previously set for this namespace.
     *
     * @param string          $prefix The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths  The PSR-4 base directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function setPsr4($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr4 = (array) $paths;
        } else {
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        }
    }

    /**
     * Turns on searching the include path for class files.
     *
     * @param bool $useIncludePath
     *
     * @return void
     */
    public function setUseIncludePath($useIncludePath)
    {
        $this->useIncludePath = $useIncludePath;
    }

    /**
     * Can be used to check if the autoloader uses the include path to check
     * for classes.
     *
     * @return bool
     */
    public function getUseIncludePath()
    {
        return $this->useIncludePath;
    }

    /**
     * Turns off searching the prefix and fallback directories for classes
     * that have not been registered with the class map.
     *
     * @param bool $classMapAuthoritative
     *
     * @return void
     */
    public function setClassMapAuthoritative($classMapAuthoritative)
    {
        $this->classMapAuthoritative = $classMapAuthoritative;
    }

    /**
     * Should class lookup fail if not found in the current class map?
     *
     * @return bool
     */
    public function isClassMapAuthoritative()
    {
        return $this->classMapAuthoritative;
    }

    /**
     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
     *
     * @param string|null $apcuPrefix
     *
     * @return void
     */
    public function setApcuPrefix($apcuPrefix)
    {
        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
    }

    /**
     * The APCu prefix in use, or null if APCu caching is not enabled.
     *
     * @return string|null
     */
    public function getApcuPrefix()
    {
        return $this->apcuPrefix;
    }

    /**
     * Registers this instance as an autoloader.
     *
     * @param bool $prepend Whether to prepend the autoloader or not
     *
     * @return void
     */
    public function register($prepend = false)
    {
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);

        if (null === $this->vendorDir) {
            return;
        }

        if ($prepend) {
            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
        } else {
            unset(self::$registeredLoaders[$this->vendorDir]);
            self::$registeredLoaders[$this->vendorDir] = $this;
        }
    }

    /**
     * Unregisters this instance as an autoloader.
     *
     * @return void
     */
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));

        if (null !== $this->vendorDir) {
            unset(self::$registeredLoaders[$this->vendorDir]);
        }
    }

    /**
     * Loads the given class or interface.
     *
     * @param  string    $class The name of the class
     * @return true|null True if loaded, null otherwise
     */
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            includeFile($file);

            return true;
        }

        return null;
    }

    /**
     * Finds the path to the file where the class is defined.
     *
     * @param string $class The name of the class
     *
     * @return string|false The path if found, false otherwise
     */
    public function findFile($class)
    {
        // class map lookup
        if (isset($this->classMap[$class])) {
            return $this->classMap[$class];
        }
        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
            return false;
        }
        if (null !== $this->apcuPrefix) {
            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
            if ($hit) {
                return $file;
            }
        }

        $file = $this->findFileWithExtension($class, '.php');

        // Search for Hack files if we are running on HHVM
        if (false === $file && defined('HHVM_VERSION')) {
            $file = $this->findFileWithExtension($class, '.hh');
        }

        if (null !== $this->apcuPrefix) {
            apcu_add($this->apcuPrefix.$class, $file);
        }

        if (false === $file) {
            // Remember that this class does not exist.
            $this->missingClasses[$class] = true;
        }

        return $file;
    }

    /**
     * Returns the currently registered loaders indexed by their corresponding vendor directories.
     *
     * @return self[]
     */
    public static function getRegisteredLoaders()
    {
        return self::$registeredLoaders;
    }

    /**
     * @param  string       $class
     * @param  string       $ext
     * @return string|false
     */
    private function findFileWithExtension($class, $ext)
    {
        // PSR-4 lookup
        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

        $first = $class[0];
        if (isset($this->prefixLengthsPsr4[$first])) {
            $subPath = $class;
            while (false !== $lastPos = strrpos($subPath, '\\')) {
                $subPath = substr($subPath, 0, $lastPos);
                $search = $subPath . '\\';
                if (isset($this->prefixDirsPsr4[$search])) {
                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
                        if (file_exists($file = $dir . $pathEnd)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-4 fallback dirs
        foreach ($this->fallbackDirsPsr4 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
                return $file;
            }
        }

        // PSR-0 lookup
        if (false !== $pos = strrpos($class, '\\')) {
            // namespaced class name
            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
        } else {
            // PEAR-like class name
            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
        }

        if (isset($this->prefixesPsr0[$first])) {
            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                if (0 === strpos($class, $prefix)) {
                    foreach ($dirs as $dir) {
                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-0 fallback dirs
        foreach ($this->fallbackDirsPsr0 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                return $file;
            }
        }

        // PSR-0 include paths.
        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
            return $file;
        }

        return false;
    }
}

/**
 * Scope isolated include.
 *
 * Prevents access to $this/self from included files.
 *
 * @param  string $file
 * @return void
 * @private
 */
function includeFile($file)
{
    include $file;
}
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    'HumbugBox3150\\Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php',
    'HumbugBox3150\\Composer\\Semver\\CompilingMatcher' => $vendorDir . '/composer/semver/src/CompilingMatcher.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\Bound' => $vendorDir . '/composer/semver/src/Constraint/Bound.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\Constraint' => $vendorDir . '/composer/semver/src/Constraint/Constraint.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\ConstraintInterface' => $vendorDir . '/composer/semver/src/Constraint/ConstraintInterface.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchAllConstraint' => $vendorDir . '/composer/semver/src/Constraint/MatchAllConstraint.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchNoneConstraint' => $vendorDir . '/composer/semver/src/Constraint/MatchNoneConstraint.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\MultiConstraint' => $vendorDir . '/composer/semver/src/Constraint/MultiConstraint.php',
    'HumbugBox3150\\Composer\\Semver\\Interval' => $vendorDir . '/composer/semver/src/Interval.php',
    'HumbugBox3150\\Composer\\Semver\\Intervals' => $vendorDir . '/composer/semver/src/Intervals.php',
    'HumbugBox3150\\Composer\\Semver\\Semver' => $vendorDir . '/composer/semver/src/Semver.php',
    'HumbugBox3150\\Composer\\Semver\\VersionParser' => $vendorDir . '/composer/semver/src/VersionParser.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Checker' => $baseDir . '/src/Checker.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IO' => $baseDir . '/src/IO.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IsExtensionFulfilled' => $baseDir . '/src/IsExtensionFulfilled.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IsFulfilled' => $baseDir . '/src/IsFulfilled.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IsPhpVersionFulfilled' => $baseDir . '/src/IsPhpVersionFulfilled.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Printer' => $baseDir . '/src/Printer.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Requirement' => $baseDir . '/src/Requirement.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\RequirementCollection' => $baseDir . '/src/RequirementCollection.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Terminal' => $baseDir . '/src/Terminal.php',
);
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    /**
     * @return \Composer\Autoload\ClassLoader
     */
    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
        spl_autoload_unregister(array('ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893', 'loadClassLoader'));

        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require __DIR__ . '/autoload_static.php';

            call_user_func(\Composer\Autoload\ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::getInitializer($loader));
        } else {
            $classMap = require __DIR__ . '/autoload_classmap.php';
            if ($classMap) {
                $loader->addClassMap($classMap);
            }
        }

        $loader->setClassMapAuthoritative(true);
        $loader->register(true);

        return $loader;
    }
}
<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893::getLoader();
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

require __DIR__ . '/../vendor/autoload.php';
if (\false === \in_array(\PHP_SAPI, array('cli', 'phpdbg', 'embed'), \true)) {
    echo \PHP_EOL . 'The application may only be invoked from a command line, got "' . \PHP_SAPI . '"' . \PHP_EOL;
    exit(1);
}
if ((\false === isset($_SERVER['BOX_REQUIREMENT_CHECKER']) || \true === (bool) $_SERVER['BOX_REQUIREMENT_CHECKER']) && \false === Checker::checkRequirements()) {
    exit(1);
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class Printer
{
    private $styles = array('reset' => "\x1b[0m", 'red' => "\x1b[31m", 'green' => "\x1b[32m", 'yellow' => "\x1b[33m", 'title' => "\x1b[33m", 'error' => "\x1b[37;41m", 'success' => "\x1b[30;42m");
    private $verbosity;
    private $supportColors;
    private $width;
    public function __construct($verbosity, $supportColors, $width = null)
    {
        if (null === $width) {
            $terminal = new Terminal();
            $width = $terminal->getWidth();
        }
        $this->verbosity = $verbosity;
        $this->supportColors = $supportColors;
        $this->width = $width ?: 80;
    }
    public function getVerbosity()
    {
        return $this->verbosity;
    }
    public function setVerbosity($verbosity)
    {
        $this->verbosity = $verbosity;
    }
    public function title($title, $verbosity, $style = null)
    {
        if (null === $style) {
            $style = 'title';
        }
        $this->printvln('', $verbosity, $style);
        $this->printvln($title, $verbosity, $style);
        $this->printvln(\str_repeat('=', \min(\strlen($title), $this->width)), $verbosity, $style);
        $this->printvln('', $verbosity, $style);
    }
    public function getRequirementErrorMessage(Requirement $requirement)
    {
        if ($requirement->isFulfilled()) {
            return null;
        }
        $errorMessage = \wordwrap($requirement->getTestMessage(), $this->width - 3, \PHP_EOL . '   ') . \PHP_EOL;
        return $errorMessage;
    }
    public function block($title, $message, $verbosity, $style = null)
    {
        $prefix = ' [' . $title . '] ';
        $lineLength = $this->width - \strlen($prefix) - 1;
        if ($lineLength < 0) {
            $lineLength = 0;
        }
        $message = $prefix . \trim($message);
        $lines = array();
        $remainingMessage = $message;
        $wrapped = \wordwrap($remainingMessage, $lineLength, '¬');
        $wrapped = \explode('¬', $wrapped);
        do {
            $line = \array_shift($wrapped);
            if ($lines && $lineLength > 0) {
                $line = \str_repeat(' ', \strlen($prefix)) . \ltrim($line);
            }
            $lines[] = \str_pad($line, $this->width, ' ', \STR_PAD_RIGHT);
        } while (\count($wrapped));
        $this->printvln('', $verbosity);
        $this->printvln(\str_repeat(' ', $this->width), $verbosity, $style);
        foreach ($lines as $line) {
            $this->printvln($line, $verbosity, $style);
        }
        $this->printv(\str_repeat(' ', $this->width), $verbosity, $style);
        $this->printvln('', $verbosity);
    }
    public function printvln($message, $verbosity, $style = null)
    {
        $this->printv($message, $verbosity, $style);
        $this->printv(\PHP_EOL, $verbosity, null);
    }
    public function printv($message, $verbosity, $style = null)
    {
        if ($verbosity > $this->verbosity) {
            return;
        }
        $message = \wordwrap($message, $this->width);
        $message = \sprintf('%s%s%s', $this->supportColors && isset($this->styles[$style]) ? $this->styles[$style] : '', $message, $this->supportColors ? $this->styles['reset'] : '');
        echo $message;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

class Terminal
{
    private static $width;
    private static $height;
    private static $stty;
    public function getWidth()
    {
        $width = \getenv('COLUMNS');
        if (\false !== $width) {
            return (int) \trim($width);
        }
        if (null === self::$width) {
            self::initDimensions();
        }
        return self::$width ?: 80;
    }
    public function getHeight()
    {
        $height = \getenv('LINES');
        if (\false !== $height) {
            return (int) \trim($height);
        }
        if (null === self::$height) {
            self::initDimensions();
        }
        return self::$height ?: 50;
    }
    public static function hasSttyAvailable()
    {
        if (null !== self::$stty) {
            return self::$stty;
        }
        if (!\function_exists('exec')) {
            return \false;
        }
        \exec('stty 2>&1', $output, $exitcode);
        return self::$stty = 0 === $exitcode;
    }
    private static function initDimensions()
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            if (\preg_match('/^(\\d+)x(\\d+)(?: \\((\\d+)x(\\d+)\\))?$/', \trim(\getenv('ANSICON')), $matches)) {
                self::$width = (int) $matches[1];
                self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
            } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) {
                self::initDimensionsUsingStty();
            } elseif (null !== ($dimensions = self::getConsoleMode())) {
                self::$width = (int) $dimensions[0];
                self::$height = (int) $dimensions[1];
            }
        } else {
            self::initDimensionsUsingStty();
        }
    }
    private static function hasVt100Support()
    {
        return \function_exists('sapi_windows_vt100_support') && \sapi_windows_vt100_support(\fopen('php://stdout', 'wb'));
    }
    private static function initDimensionsUsingStty()
    {
        if ($sttyString = self::getSttyColumns()) {
            if (\preg_match('/rows.(\\d+);.columns.(\\d+);/i', $sttyString, $matches)) {
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            } elseif (\preg_match('/;.(\\d+).rows;.(\\d+).columns/i', $sttyString, $matches)) {
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            }
        }
    }
    private static function getConsoleMode()
    {
        $info = self::readFromProcess('mode CON');
        if (null === $info || !\preg_match('/--------+\\r?\\n.+?(\\d+)\\r?\\n.+?(\\d+)\\r?\\n/', $info, $matches)) {
            return null;
        }
        return array((int) $matches[2], (int) $matches[1]);
    }
    private static function getSttyColumns()
    {
        return self::readFromProcess('stty -a | grep columns');
    }
    private static function readFromProcess($command)
    {
        if (!\function_exists('proc_open')) {
            return null;
        }
        $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
        $process = \proc_open($command, $descriptorspec, $pipes, null, null, array('suppress_errors' => \true));
        if (!\is_resource($process)) {
            return null;
        }
        $info = \stream_get_contents($pipes[1]);
        \fclose($pipes[1]);
        \fclose($pipes[2]);
        \proc_close($process);
        return $info;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class IsExtensionFulfilled implements IsFulfilled
{
    private $requiredExtension;
    public function __construct($requiredExtension)
    {
        $this->requiredExtension = $requiredExtension;
    }
    public function __invoke()
    {
        return \extension_loaded($this->requiredExtension);
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

interface IsFulfilled
{
    public function __invoke();
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class IO
{
    const VERBOSITY_QUIET = 16;
    const VERBOSITY_NORMAL = 32;
    const VERBOSITY_VERBOSE = 64;
    const VERBOSITY_VERY_VERBOSE = 128;
    const VERBOSITY_DEBUG = 256;
    private $interactive;
    private $verbosity = self::VERBOSITY_NORMAL;
    private $colorSupport;
    private $options;
    public function __construct()
    {
        $this->options = \implode(' ', $_SERVER['argv']);
        $shellVerbosity = $this->configureVerbosity();
        $this->interactive = $this->checkInteractivity($shellVerbosity);
        $this->colorSupport = $this->checkColorSupport();
    }
    public function isInteractive()
    {
        return $this->interactive;
    }
    public function getVerbosity()
    {
        return $this->verbosity;
    }
    public function hasColorSupport()
    {
        return $this->colorSupport;
    }
    public function hasParameter($values)
    {
        $values = (array) $values;
        foreach ($values as $value) {
            $regexp = \sprintf('/\\s%s\\b/', \str_replace(' ', '\\s+', \preg_quote($value, '/')));
            if (1 === \preg_match($regexp, $this->options)) {
                return \true;
            }
        }
        return \false;
    }
    private function checkInteractivity($shellVerbosity)
    {
        if (-1 === $shellVerbosity) {
            return \false;
        }
        if (\true === $this->hasParameter(array('--no-interaction', '-n'))) {
            return \false;
        }
        if (\function_exists('posix_isatty') && !@\posix_isatty(\STDOUT) && \false === \getenv('SHELL_INTERACTIVE')) {
            return \false;
        }
        return \true;
    }
    private function configureVerbosity()
    {
        switch ($shellVerbosity = (int) \getenv('SHELL_VERBOSITY')) {
            case -1:
                $this->verbosity = self::VERBOSITY_QUIET;
                break;
            case 1:
                $this->verbosity = self::VERBOSITY_VERBOSE;
                break;
            case 2:
                $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
                break;
            case 3:
                $this->verbosity = self::VERBOSITY_DEBUG;
                break;
            default:
                $shellVerbosity = 0;
                break;
        }
        if ($this->hasParameter(array('--quiet', '-q'))) {
            $this->verbosity = self::VERBOSITY_QUIET;
            $shellVerbosity = -1;
        } elseif ($this->hasParameter(array('-vvv', '--verbose=3', '--verbose 3'))) {
            $this->verbosity = self::VERBOSITY_DEBUG;
            $shellVerbosity = 3;
        } elseif ($this->hasParameter(array('-vv', '--verbose=2', '--verbose 2'))) {
            $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
            $shellVerbosity = 2;
        } elseif ($this->hasParameter(array('-v', '--verbose=1', '--verbose 1', '--verbose'))) {
            $this->verbosity = self::VERBOSITY_VERBOSE;
            $shellVerbosity = 1;
        }
        return $shellVerbosity;
    }
    private function checkColorSupport()
    {
        if ($this->hasParameter(array('--ansi'))) {
            return \true;
        }
        if ($this->hasParameter(array('--no-ansi'))) {
            return \false;
        }
        if (\DIRECTORY_SEPARATOR === '\\') {
            return \function_exists('sapi_windows_vt100_support') && \sapi_windows_vt100_support(\STDOUT) || \false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM');
        }
        if (\function_exists('stream_isatty')) {
            return \stream_isatty(\STDOUT);
        }
        if (\function_exists('posix_isatty')) {
            return \posix_isatty(\STDOUT);
        }
        $stat = \fstat(\STDOUT);
        return $stat ? 020000 === ($stat['mode'] & 0170000) : \false;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

use HumbugBox3150\Composer\Semver\Semver;
final class IsPhpVersionFulfilled implements IsFulfilled
{
    private $requiredPhpVersion;
    public function __construct($requiredPhpVersion)
    {
        $this->requiredPhpVersion = $requiredPhpVersion;
    }
    public function __invoke()
    {
        return Semver::satisfies(\sprintf('%d.%d.%d', \PHP_MAJOR_VERSION, \PHP_MINOR_VERSION, \PHP_RELEASE_VERSION), $this->requiredPhpVersion);
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class Checker
{
    private static $requirementsConfig;
    public static function checkRequirements()
    {
        $requirements = self::retrieveRequirements();
        $checkPassed = $requirements->evaluateRequirements();
        $io = new IO();
        self::printCheck($checkPassed, new Printer($io->getVerbosity(), $io->hasColorSupport()), $requirements);
        return $checkPassed;
    }
    public static function printCheck($checkPassed, Printer $printer, RequirementCollection $requirements)
    {
        if (\false === $checkPassed && IO::VERBOSITY_VERY_VERBOSE > $printer->getVerbosity()) {
            $printer->setVerbosity(IO::VERBOSITY_VERY_VERBOSE);
        }
        $verbosity = IO::VERBOSITY_VERY_VERBOSE;
        $iniPath = $requirements->getPhpIniPath();
        $printer->title('Box Requirements Checker', $verbosity);
        $printer->printv('> Using PHP ', $verbosity);
        $printer->printvln(\PHP_VERSION, $verbosity, 'green');
        $printer->printvln('> PHP is using the following php.ini file:', $verbosity);
        if ($iniPath) {
            $printer->printvln('  ' . $iniPath, $verbosity, 'green');
        } else {
            $printer->printvln('  WARNING: No configuration file (php.ini) used by PHP!', $verbosity, 'yellow');
        }
        $printer->printvln('', $verbosity);
        if (\count($requirements) > 0) {
            $printer->printvln('> Checking Box requirements:', $verbosity);
            $printer->printv('  ', $verbosity);
        } else {
            $printer->printvln('> No requirements found.', $verbosity);
        }
        $errorMessages = array();
        foreach ($requirements->getRequirements() as $requirement) {
            if ($errorMessage = $printer->getRequirementErrorMessage($requirement)) {
                if (IO::VERBOSITY_DEBUG === $printer->getVerbosity()) {
                    $printer->printvln('✘ ' . $requirement->getTestMessage(), IO::VERBOSITY_DEBUG, 'red');
                    $printer->printv('  ', IO::VERBOSITY_DEBUG);
                    $errorMessages[] = $errorMessage;
                } else {
                    $printer->printv('E', $verbosity, 'red');
                    $errorMessages[] = $errorMessage;
                }
                continue;
            }
            if (IO::VERBOSITY_DEBUG === $printer->getVerbosity()) {
                $printer->printvln('✔ ' . $requirement->getHelpText(), IO::VERBOSITY_DEBUG, 'green');
                $printer->printv('  ', IO::VERBOSITY_DEBUG);
            } else {
                $printer->printv('.', $verbosity, 'green');
            }
        }
        if (IO::VERBOSITY_DEBUG !== $printer->getVerbosity() && \count($requirements) > 0) {
            $printer->printvln('', $verbosity);
        }
        if ($requirements->evaluateRequirements()) {
            $printer->block('OK', 'Your system is ready to run the application.', $verbosity, 'success');
        } else {
            $printer->block('ERROR', 'Your system is not ready to run the application.', $verbosity, 'error');
            $printer->title('Fix the following mandatory requirements:', $verbosity, 'red');
            foreach ($errorMessages as $errorMessage) {
                $printer->printv(' * ' . $errorMessage, $verbosity);
            }
        }
        $printer->printvln('', $verbosity);
    }
    private static function retrieveRequirements()
    {
        if (null === self::$requirementsConfig) {
            self::$requirementsConfig = __DIR__ . '/../.requirements.php';
        }
        $config = (require self::$requirementsConfig);
        $requirements = new RequirementCollection();
        foreach ($config as $constraint) {
            $requirements->addRequirement('php' === $constraint['type'] ? new IsPhpVersionFulfilled($constraint['condition']) : new IsExtensionFulfilled($constraint['condition']), $constraint['message'], $constraint['helpMessage']);
        }
        return $requirements;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

use ArrayIterator;
use Countable;
use IteratorAggregate;
use ReturnTypeWillChange;
use Traversable;
final class RequirementCollection implements IteratorAggregate, Countable
{
    private $requirements = array();
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new ArrayIterator($this->requirements);
    }
    #[\ReturnTypeWillChange]
    public function count()
    {
        return \count($this->requirements);
    }
    public function add(Requirement $requirement)
    {
        $this->requirements[] = $requirement;
    }
    public function addRequirement($checkIsFulfilled, $testMessage, $helpText)
    {
        $this->add(new Requirement($checkIsFulfilled, $testMessage, $helpText));
    }
    public function getRequirements()
    {
        return $this->requirements;
    }
    public function getPhpIniPath()
    {
        return \get_cfg_var('cfg_file_path');
    }
    public function evaluateRequirements()
    {
        return \array_reduce($this->requirements, function ($checkPassed, Requirement $requirement) {
            return $checkPassed && $requirement->isFulfilled();
        }, \true);
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class Requirement
{
    private $checkIsFulfilled;
    private $fulfilled;
    private $testMessage;
    private $helpText;
    public function __construct($checkIsFulfilled, $testMessage, $helpText)
    {
        $this->checkIsFulfilled = $checkIsFulfilled;
        $this->testMessage = $testMessage;
        $this->helpText = $helpText;
    }
    public function isFulfilled()
    {
        if (null === $this->fulfilled) {
            $this->fulfilled = $this->checkIsFulfilled->__invoke();
        }
        return (bool) $this->fulfilled;
    }
    public function getIsFullfilledChecker()
    {
        return $this->checkIsFulfilled;
    }
    public function getTestMessage()
    {
        return $this->testMessage;
    }
    public function getHelpText()
    {
        return $this->helpText;
    }
}
<?php

return array (
  0 => 
  array (
    'type' => 'php',
    'condition' => '^7.2.5 || <8.2.0',
    'message' => 'The application requires the version "^7.2.5 || <8.2.0" or greater.',
    'helpMessage' => 'The application requires the version "^7.2.5 || <8.2.0" or greater.',
  ),
  1 => 
  array (
    'type' => 'extension',
    'condition' => 'simplexml',
    'message' => 'The application requires the extension "simplexml". Enable it or install a polyfill.',
    'helpMessage' => 'The application requires the extension "simplexml".',
  ),
);<?php

if (PHP_VERSION_ID < 70200 && function_exists('posix_isatty') && posix_isatty(STDOUT)) {
    fwrite(STDOUT, "\033[33mWarning! The usage of PHP older than 7.2.0 as the interpreter is deprecated.\n");
    fwrite(STDOUT, "Please set the system interpreter using \033[0m'phpbrew system <version>'\033[33m.\n");
    fwrite(STDOUT, "See https://github.com/phpbrew/phpbrew/wiki/System-Interpreter for details.\033[0m\n");
}

$includeIfExists = function($file)
{
    return file_exists($file) ? include $file : false;
};

if (
    (!$loader = $includeIfExists(__DIR__.'/../vendor/autoload.php'))
    && (!$loader = $includeIfExists(__DIR__.'/../../../autoload.php'))
) {
    echo 'You must set up the project dependencies, run the following commands:'.PHP_EOL.
        'curl -sS https://getcomposer.org/installer | php'.PHP_EOL.
        'php composer.phar install'.PHP_EOL;
    exit(1);
}

$console = PhpBrew\Console::getInstance();
if (isset($argv)) {
    if (!$console->runWithTry($argv)) {
        exit(-1);
    }
}
<?php

namespace PhpBrew\PatchKit;

use CLIFramework\Logger;
use PhpBrew\Buildable;






abstract class Patch
{



abstract public function desc();

abstract public function match(Buildable $build, Logger $logger);






abstract public function rules();




public function apply(Buildable $build, Logger $logger)
{
$cnt = 0;
if ($rules = $this->rules()) {

foreach ($rules as $rule) {
$rule->backup($build, $logger);
}
foreach ($rules as $rule) {
if ($patched = $rule->apply($build, $logger)) {
$cnt += $patched;
}
}
}

return $cnt;
}
}
<?php

namespace PhpBrew\PatchKit;

use CLIFramework\Logger;
use PhpBrew\Buildable;

interface PatchRule
{
public function apply(Buildable $build, Logger $logger);

public function backup(Buildable $build, Logger $logger);
}
<?php

namespace PhpBrew\PatchKit;

use CLIFramework\Logger;
use PhpBrew\Buildable;




final class DiffPatchRule implements PatchRule
{



private $patch;




private $strip = 0;

private function __construct()
{
}






public function strip($level)
{
$this->strip = $level;

return $this;
}




public static function fromPatch($patch)
{
$instance = new self();
$instance->patch = $patch;

return $instance;
}

public function backup(Buildable $build, Logger $logger)
{
}

public function apply(Buildable $build, Logger $logger)
{
$logger->info('---> Applying patch...');

$process = proc_open(
sprintf('patch --forward --backup -p%d', $this->strip),
array(
array('pipe', 'r'),
array('pipe', 'w'),
array('pipe', 'w'),
),
$pipes,
$build->getSourceDirectory()
);

if (fwrite($pipes[0], $this->patch) === false) {
return 0;
}

fclose($pipes[0]);

$output = stream_get_contents($pipes[1]);

if ($output !== '') {
$logger->info($output);
}

$error = stream_get_contents($pipes[2]);

if ($error !== '') {
$logger->error($error);
}

if (proc_close($process) !== 0) {
$logger->error('Patch failed');

return 0;
}

$logger->info('Done.');

return 1;
}
}
<?php

namespace PhpBrew\PatchKit;

use CLIFramework\Logger;
use PhpBrew\Buildable;




class RegExpPatchRule implements PatchRule
{
private $files;




private $pattern;




private $replacement;




public function __construct(array $files)
{
$this->files = $files;
}




public function allOf(array $patterns)
{
$this->predicator = function ($line) use ($patterns) {
foreach ($patterns as $pattern) {
if (!preg_match($pattern, $line)) {
return false;
}
}

return true;
};

return $this;
}

public function anyOf(array $patterns)
{
if (count($patterns) === 0) {
$this->predicator = true;
}
$this->predicator = function ($line) use ($patterns) {
foreach ($patterns as $pattern) {
if (preg_match($pattern, $line)) {
return true;
}
}

return false;
};

return $this;
}

public function always()
{
$this->predicator = true;

return $this;
}

public function replaces($pattern, $replacement)
{
$this->pattern = $pattern;
$this->replacement = $replacement;

return $this;
}

public static function files($files)
{
return new self((array) $files);
}

protected function applyLines(array $lines, &$patched)
{
$size = count($lines);
for ($i = 0; $i < $size; ++$i) {
if ($this->predicator === true || call_user_func($this->predicator, $lines[$i])) {
$lines[$i] = preg_replace($this->pattern, $this->replacement, $lines[$i], -1, $count);
$patched += $count;
}
}

return implode(PHP_EOL, $lines);
}






protected function applyTextContent($content, &$patched)
{

return $this->applyLines(preg_split("/(?:\r\n|\n|\r)/", $content), $patched);
}

public function backup(Buildable $build, Logger $logger)
{
foreach ($this->files as $file) {
$path = $build->getSourceDirectory() . DIRECTORY_SEPARATOR . $file;
if (!file_exists($path)) {
$logger->error("file $path doesn't exist in the build directory.");
continue;
}
$this->backupFile($path);
}
}

protected function backupFile($path)
{
$bakPath = $path . '.' . time() . '.bak';
copy($path, $bakPath);
}

public function apply(Buildable $build, Logger $logger)
{
$patched = 0;
foreach ($this->files as $file) {
$path = $build->getSourceDirectory() . DIRECTORY_SEPARATOR . $file;
if (!file_exists($path)) {
$logger->error("file $path doesn't exist in the build directory.");
continue;
}
if ($content = file_get_contents($path)) {
$content = $this->applyTextContent($content, $patched);
if (false === file_put_contents($path, $content)) {
$logger->error("Patch on $path write failed.");
}
}
}

return $patched;
}
}
<?php

namespace PhpBrew;

use PhpBrew\BuildSettings\BuildSettings;
















class Build implements Buildable
{



const STATE_NONE = 0;
const STATE_DOWNLOAD = 1;
const STATE_EXTRACT = 2;
const STATE_CONFIGURE = 3;
const STATE_BUILD = 4;
const STATE_INSTALL = 5;

public $name;

public $version;




public $sourceDirectory;




public $installPrefix;




public $settings;






public $state;




public $osName;

public $osRelease;










public function __construct($version, $name = null, $installPrefix = null)
{
if (substr($version, 0, 4) === 'php-') {
$version = substr($version, 4);
}

if ($name === null) {
$name = 'php-' . $version;
}

$this->version = $version;
$this->name = $name;

if ($installPrefix) {
$this->setInstallPrefix($installPrefix);
}

$this->setBuildSettings(new BuildSettings());
$this->osName = php_uname('s');
$this->osRelease = php_uname('r');
}

public function getName()
{
return $this->name;
}

public function getVersion()
{
return $this->version;
}

public function compareVersion($version)
{
return version_compare($this->version, $version);
}




public function setSourceDirectory($dir)
{
$this->sourceDirectory = $dir;
}

public function getSourceDirectory()
{
if ($this->sourceDirectory && !file_exists($this->sourceDirectory)) {
mkdir($this->sourceDirectory, 0755, true);
}

return $this->sourceDirectory;
}

public function isBuildable()
{
return file_exists($this->sourceDirectory . DIRECTORY_SEPARATOR . 'Makefile');
}

public function getBuildLogPath()
{
$dir = $this->getSourceDirectory() . DIRECTORY_SEPARATOR . 'build.log';
return $dir;
}

public function setInstallPrefix($prefix)
{
$this->installPrefix = $prefix;
}

public function getBinDirectory()
{
return $this->installPrefix . DIRECTORY_SEPARATOR . 'bin';
}

public function getEtcDirectory()
{
$etc = $this->installPrefix . DIRECTORY_SEPARATOR . 'etc';
if (!file_exists($etc)) {
mkdir($etc, 0755, true);
}

return $etc;
}

public function getInstallPrefix()
{
return $this->installPrefix;
}

public function getPath($subpath)
{
return $this->installPrefix . DIRECTORY_SEPARATOR . $subpath;
}

public function setBuildSettings(BuildSettings $settings)
{
$this->settings = $settings;
if (!$this->getInstallPrefix()) {
return;
}




$variantFile = $this->getInstallPrefix() . DIRECTORY_SEPARATOR . 'phpbrew.variants';
if (file_exists($variantFile)) {
$this->settings->loadVariantInfoFile($variantFile);
}
}










public static function findByName($name)
{
$prefix = Config::getVersionInstallPrefix($name);
if (file_exists($prefix)) {

return new self($name, null, $prefix);
}

return;
}













public function getStateFile()
{
if ($dir = $this->getInstallPrefix()) {
return $dir . DIRECTORY_SEPARATOR . 'phpbrew_status';
}
}

public function setState($state)
{
$this->state = $state;
if ($path = $this->getStateFile()) {
file_put_contents($path, $state);
}
}

public function getState()
{
if ($this->state) {
return $this->state;
}
if ($path = $this->getStateFile()) {
if (file_exists($path)) {
return $this->state = intval(file_get_contents($path)) || self::STATE_NONE;
}
}

return self::STATE_NONE;
}

public function __call($m, $a)
{
return call_user_func_array(array($this->settings, $m), $a);
}
}
<?php

namespace PhpBrew;




final class ConfigureParameters
{





private $options = array();






private $pkgConfigPaths = array();











public function withOption($option, $value = null)
{
if (array_key_exists($option, $this->options) && $this->options[$option] === $value) {
return $this;
}

$new = clone $this;
$new->options[$option] = $value;

return $new;
}










public function withoutOption($option)
{
if (!array_key_exists($option, $this->options)) {
return $this;
}

$new = clone $this;
unset($new->options[$option]);

return $new;
}










public function withPkgConfigPath($path)
{
if (array_key_exists($path, $this->pkgConfigPaths)) {
return $this;
}

$new = clone $this;
$new->pkgConfigPaths[$path] = null;

return $new;
}










public function withOptionOrPkgConfigPath(Build $build, $option, $value)
{
if ($build->compareVersion('7.4') < 0) {
return $this->withOption($option, $value);
}

$new = $this->withOption($option);

if ($value !== null) {
$new = $new->withPkgConfigPath($value . '/lib/pkgconfig');
}

return $new;
}




public function getOptions()
{
return $this->options;
}




public function getPkgConfigPaths()
{
return array_keys($this->pkgConfigPaths);
}
}
<?php

namespace PhpBrew;

class CommandBuilder
{

public $nice;


public $script;


public $args = array();

public $stdout;

public $stderr;

public $append = true;

public $logPath;

public function __construct($script)
{
$this->script = $script;
}

public function args($args)
{
$this->args = $args;
}

public function addArg($arg)
{
$this->args[] = $arg;
}

public function arg($arg)
{
$this->args[] = $arg;
}

public function nice($nice)
{
$this->nice = $nice;
}

public function passthru(&$lastline = null)
{
$ret = null;
$command = $this->buildCommand(false);
$lastline = passthru($command, $ret);
if ($lastline === false) {
return $ret;
}

return $ret;
}

public function execute(&$lastline = null)
{
$ret = null;
$command = $this->buildCommand();
$lastline = system($command, $ret);
if ($lastline === false) {
return $ret;
}

return $ret;
}

public function __toString()
{
return $this->buildCommand();
}

public function setStdout($stdout = true)
{
$this->stdout = $stdout;
}

public function setAppendLog($append = true)
{
$this->append = $append;
}

public function setLogPath($logPath)
{
$this->logPath = $logPath;
}

public function buildCommand($handleRedirect = true)
{
$cmd = array();

if ($this->nice) {
$cmd[] = 'nice';
$cmd[] = '-n';
$cmd[] = $this->nice;
}
$cmd[] = $this->script;

if ($this->args) {
foreach ($this->args as $arg) {
$cmd[] = escapeshellarg($arg);
}
}


if ($handleRedirect) {
if ($this->stdout) {









$cmd[] = '2>&1';
} elseif ($this->logPath) {
$cmd[] = $this->append ? '>>' : '>';
$cmd[] = escapeshellarg($this->logPath);
$cmd[] = '2>&1';
}
}

return implode(' ', $cmd);
}
}
<?php

namespace PhpBrew;

interface Buildable
{



public function getSourceDirectory();




public function isBuildable();




public function getBuildLogPath();
}
<?php

namespace PhpBrew\BuildSettings;

use Exception;

class BuildSettings
{



private $enabledVariants = array();




private $disabledVariants = array();




private $extraOptions = array();

public function __construct(array $settings = array())
{
if (isset($settings['enabled_variants'])) {
$this->enableVariants($settings['enabled_variants']);
}
if (isset($settings['disabled_variants'])) {
$this->disableVariants($settings['disabled_variants']);
}
if (isset($settings['extra_options'])) {
$this->extraOptions = array_merge($this->extraOptions, $settings['extra_options']);
}
}

public function toArray()
{
return array(
'enabled_variants' => $this->enabledVariants,
'disabled_variants' => $this->disabledVariants,
'extra_options' => $this->extraOptions,
);
}

public function enableVariants(array $settings)
{
foreach ($settings as $name => $value) {
$this->enableVariant($name, $value);
}
}

public function enableVariant($name, $value = null)
{
$this->enabledVariants[$name] = $value;
}

public function disableVariants(array $settings)
{
foreach ($settings as $name => $value) {
$this->disableVariant($name);
}
}






public function disableVariant($name)
{
$this->disabledVariants[$name] = null;
}





public function resolveVariants()
{
foreach ($this->disabledVariants as $name => $_) {
$this->removeVariant($name);
}
}

public function isEnabledVariant($name)
{
return array_key_exists($name, $this->enabledVariants);
}

public function isDisabledVariant($name)
{
return array_key_exists($name, $this->disabledVariants);
}




public function removeVariant($name)
{
unset($this->enabledVariants[$name]);
}




public function getEnabledVariants()
{
return $this->enabledVariants;
}




public function getDisabledVariants()
{
return $this->disabledVariants;
}

public function getExtraOptions()
{
return $this->extraOptions;
}




public function loadVariantInfoFile($variantFile)
{
if (!is_readable($variantFile)) {
throw new Exception(
"Can't load variant info! Variants file {$variantFile} is not readable."
);
}
$variantInfo = unserialize(file_get_contents($variantFile));

$this->loadVariantInfo($variantInfo);
}

public function writeVariantInfoFile($variantInfoFile)
{
return file_put_contents($variantInfoFile, serialize(array(
'enabled_variants' => $this->enabledVariants,
'disabled_variants' => $this->disabledVariants,
'extra_options' => array_unique($this->extraOptions),
)));
}

public function loadVariantInfo(array $variantInfo)
{
if (isset($variantInfo['enabled_variants'])) {
foreach ($variantInfo['enabled_variants'] as $variant => $value) {
if ($value === true) {

$this->enableVariant($variant);
} else {
$this->enableVariant($variant, $value);
}
}
}

if (isset($variantInfo['disabled_variants'])) {
$this->disableVariants($variantInfo['disabled_variants']);
}

if (isset($variantInfo['extra_options'])) {
$this->extraOptions = array_unique(array_merge($this->extraOptions, $variantInfo['extra_options']));
}

$this->resolveVariants();
}
}
<?php

namespace PhpBrew;




interface PrefixFinder
{





public function findPrefix();
}
<?php

namespace PhpBrew;

use Exception;
use Symfony\Component\Yaml\Yaml;





class Config
{
protected static $currentPhpVersion = null;








public static function getHome()
{
if ($custom = getenv('PHPBREW_HOME')) {
if (!file_exists($custom)) {
mkdir($custom, 0755, true);
}

return $custom;
}
if ($home = getenv('HOME')) {
$path = $home . DIRECTORY_SEPARATOR . '.phpbrew';
if (!file_exists($path)) {
mkdir($path, 0755, true);
}

return $path;
}
throw new Exception('Environment variable PHPBREW_HOME or HOME is required');
}

public static function setPhpbrewHome($home)
{
putenv('PHPBREW_HOME=' . $home);
}

public static function setPhpbrewRoot($root)
{
putenv('PHPBREW_ROOT=' . $root);
}

public static function getRoot()
{
if ($root = getenv('PHPBREW_ROOT')) {
if (!file_exists($root)) {
mkdir($root, 0755, true);
}

return $root;
}
if ($home = getenv('HOME')) {
return $home . DIRECTORY_SEPARATOR . '.phpbrew';
}
throw new Exception('Environment variable PHPBREW_ROOT is required');
}




public static function getCacheDir()
{
return self::getRoot() . DIRECTORY_SEPARATOR . 'cache';
}




public static function getBuildDir()
{
return self::getRoot() . DIRECTORY_SEPARATOR . 'build';
}

public static function getCurrentBuildDir()
{
return self::getRoot() . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . self::getCurrentPhpName();
}

public static function getDistFileDir()
{
$dir = self::getRoot() . DIRECTORY_SEPARATOR . 'distfiles';
if (!file_exists($dir)) {
mkdir($dir, 0755, true);
}

return $dir;
}

public static function getTempFileDir()
{
$dir = self::getRoot() . DIRECTORY_SEPARATOR . 'tmp';
if (!file_exists($dir)) {
mkdir($dir, 0755, true);
}

return $dir;
}

public static function getPHPReleaseListPath()
{

return self::getRoot() . DIRECTORY_SEPARATOR . 'php-releases.json';
}










public static function getInstallPrefix()
{
return self::getRoot() . DIRECTORY_SEPARATOR . 'php';
}

public static function getVersionInstallPrefix($buildName)
{
return self::getInstallPrefix() . DIRECTORY_SEPARATOR . $buildName;
}








public static function getVersionEtcPath($buildName)
{
return self::getVersionInstallPrefix($buildName) . DIRECTORY_SEPARATOR . 'etc';
}

public static function getVersionBinPath($buildName)
{
return self::getVersionInstallPrefix($buildName) . DIRECTORY_SEPARATOR . 'bin';
}

public static function getCurrentPhpConfigBin()
{
return self::getCurrentPhpDir() . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'php-config';
}

public static function getCurrentPhpizeBin()
{
return self::getCurrentPhpDir() . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'phpize';
}

public static function getSapis()
{
return array(
'cli',
'fpm',
'apache'
);
}




public static function getCurrentPhpConfigScanPath($home = false)
{
return self::getCurrentPhpDir($home) . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'db';
}

public static function getCurrentPhpDir($home = false)
{
if ($home) {
return self::getHome() . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . self::getCurrentPhpName();
}

return self::getRoot() . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . self::getCurrentPhpName();
}







public static function getCurrentPhpName()
{
if (self::$currentPhpVersion !== null) {
return self::$currentPhpVersion;
}

return getenv('PHPBREW_PHP');
}

public static function getLookupPrefix()
{
return getenv('PHPBREW_LOOKUP_PREFIX');
}

public static function getCurrentPhpBin()
{
return getenv('PHPBREW_PATH');
}

public static function getConfig()
{
$configFile = self::getRoot() . DIRECTORY_SEPARATOR . 'config.yaml';
if (!file_exists($configFile)) {
return array();
}

return Yaml::parse(file_get_contents($configFile));
}

public static function getConfigParam($param = null)
{
$config = self::getConfig();
if ($param && isset($config[$param])) {
return $config[$param];
}

return $config;
}
}
<?php

namespace PhpBrew\Distribution;

class DistributionUrlPolicy
{




public function buildUrl($version, $filename, $museum = false)
{

if ($museum || $this->isDistributedAtMuseum($version)) {
return 'https://museum.php.net/php5/' . $filename;
}

return 'https://www.php.net/distributions/' . $filename;
}

private function isDistributedAtMuseum($version)
{
return version_compare($version, '5.4.21', '<=');
}
}
<?php

namespace PhpBrew;

use CLIFramework\Logger;
use Exception;
use GetOptionKit\OptionResult;
use PhpBrew\Downloader\DownloadFactory;
use RuntimeException;

defined('JSON_UNESCAPED_SLASHES') || define('JSON_UNESCAPED_SLASHES', 0);
defined('JSON_PRETTY_PRINT') || define('JSON_PRETTY_PRINT', 128);

class ReleaseList
{





public $releases = array();

public $versions = array();

public function __construct($releases = array())
{
$this->setReleases($releases);
}

public function setReleases(array $releases)
{
$this->releases = $releases;
foreach ($this->releases as $major => $versionReleases) {
foreach ($versionReleases as $version => $release) {
$this->versions[ $version ] = $release;
}
}
}

public function getReleases()
{
return $this->releases;
}

public function loadJson($json)
{
if (!$json) {
throw new RuntimeException("Can't load releases. Empty JSON given.");
}
if ($releases = json_decode($json, true)) {
$this->setReleases($releases);

return $releases;
} else {
throw new RuntimeException("Can't decode release json, invalid JSON string: " . substr($json, 0, 125));
}
}

public function loadJsonFile($file)
{
$this->loadJson(file_get_contents($file));
}




public function getLatestVersion()
{
$releases = $this->getReleases();
$latestMajor = array_shift($releases);
$latest = array_shift($latestMajor);
if (!$latest) {
throw new Exception('Latest major version not found.');
}

return $latest['version'];
}

public function getLatestPatchVersion($version)
{
if (isset($this->releases[$version])) {
reset($this->releases[$version]);

return current($this->releases[$version]);
}
}

public function getVersion($version)
{
if (isset($this->releases[$version])) {
return $this->getLatestPatchVersion($version);
} elseif (isset($this->versions[$version])) {
return $this->versions[$version];
}

return false;
}




public function getVersions($key)
{
if (isset($this->releases[$key])) {
return $this->releases[$key];
}
}

public function foundLocalReleaseList()
{
$releasesFile = Config::getPHPReleaseListPath();

return file_exists($releasesFile);
}

public function loadLocalReleaseList()
{
if ($this->foundLocalReleaseList()) {
$this->loadJsonFile(Config::getPHPReleaseListPath());

return $this->releases;
}
}

public function save()
{
$localFilepath = Config::getPHPReleaseListPath();
$json = json_encode($this->releases, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
if (false === file_put_contents($localFilepath, $json)) {
throw new Exception("Can't store release json file");
}
}

public function fetchRemoteReleaseList(OptionResult $options)
{
$releases = self::buildReleaseListFromOfficialSite($options);
$this->setReleases($releases);
$this->save();
}

public static function getReadyInstance(OptionResult $options = null)
{
static $instance;

if ($instance) {
return $instance;
}

$instance = new self();

if ($instance->foundLocalReleaseList()) {
$instance->setReleases($instance->loadLocalReleaseList());
} else {
$instance->fetchRemoteReleaseList($options);
}

return $instance;
}

private static function downloadReleaseListFromOfficialSite($version, $max, OptionResult $options)
{
$url = 'https://www.php.net/releases/index.php?' . http_build_query(array(
'json' => true,
'version' => $version,
'max' => $max,
));

$file = DownloadFactory::getInstance(Logger::getInstance(), $options)->download($url);
$json = file_get_contents($file);

return json_decode($json, true);
}

private static function buildReleaseListFromOfficialSite(OptionResult $options)
{
$obj = array_merge(
self::downloadReleaseListFromOfficialSite(8, 100, $options),
self::downloadReleaseListFromOfficialSite(7, 100, $options)
);

if ($options->get('old')) {
$obj = array_merge($obj, self::downloadReleaseListFromOfficialSite(5, 1000, $options));
}

$releaseVersions = array();
foreach ($obj as $k => $v) {
if (preg_match('/^(\d+)\.(\d+)\./', $k, $matches)) {
list(, $major, $minor) = $matches;
$release = array('version' => $k);
if (isset($v['announcement']['English'])) {
$release['announcement'] = 'https://php.net' . $v['announcement']['English'];
}

if (isset($v['date'])) {
$release['date'] = $v['date'];
}
foreach ($v['source'] as $source) {
if (isset($source['filename']) && preg_match('/\.tar\.bz2$/', $source['filename'])) {
$release['filename'] = $source['filename'];
$release['name'] = $source['name'];
if (isset($source['md5'])) {
$release['md5'] = $source['md5'];
}
if (isset($source['sha256'])) {
$release['sha256'] = $source['sha256'];
}
if (isset($source['date'])) {
$release['date'] = $source['date'];
}
}
}
$release['museum'] = isset($v['museum']) && $v['museum'];
$releaseVersions["$major.$minor"][$k] = $release;
}
}

foreach ($releaseVersions as $key => $_) {
uksort($releaseVersions[$key], function ($a, $b) {
return version_compare($b, $a);
});
}

return $releaseVersions;
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\CommandBuilder;
use PhpBrew\Exception\SystemCommandException;




class TestTask extends BaseTask
{
public function run(Build $build, $nice = null)
{
$this->info('===> Running tests...');
$cmd = new CommandBuilder('make test');

if ($nice) {
$cmd->nice($nice);
}

$cmd->setAppendLog(true);
$cmd->setLogPath($build->getBuildLogPath());
$cmd->setStdout($this->options->{'stdout'});

putenv('NO_INTERACTION=1');
$this->debug('' . $cmd);
$code = $cmd->execute($lastline);
if ($code !== 0) {
throw new SystemCommandException("Test failed: $lastline", $build);
}
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\Exception\SystemCommandException;




class ExtractTask extends BaseTask
{





private $rmDirs = array();









public function extract(Build $build, $targetFilePath, $extractDir = null)
{
if (empty($extractDir)) {
$extractDir = dirname($targetFilePath);
}

$extractedDir = $extractDir . DIRECTORY_SEPARATOR . $build->getName();

if (
$build->getState() >= Build::STATE_EXTRACT
&& file_exists($extractedDir . DIRECTORY_SEPARATOR . 'configure')
) {
$this->info('===> Distribution file was successfully extracted, skipping...');

return $extractedDir;
}

$extractDirTemp = $extractDir . DIRECTORY_SEPARATOR . 'tmp.' . time();

if (!file_exists($extractDirTemp)) {
mkdir($extractDirTemp, 0755, true);
}

$this->rmDirs[] = $extractDirTemp;



$distBaseName = preg_replace('#\.tar\.(gz|bz2)$#', '', basename($targetFilePath));
$extractedDirTemp = $extractDirTemp . DIRECTORY_SEPARATOR . $distBaseName;


$this->info("===> Extracting $targetFilePath to $extractedDirTemp");
$lastLine = system(
'tar -C ' . escapeshellarg($extractDirTemp) . ' -xf ' . escapeshellarg($targetFilePath),
$ret
);

if ($ret !== 0) {
throw new SystemCommandException("Extract failed: $lastLine", $build);
}

clearstatcache(true);

if (!is_dir($extractedDirTemp)) {

$extractedDirTemp = $extractDirTemp . DIRECTORY_SEPARATOR . 'php-src-' . $distBaseName;

if (!is_dir($extractedDirTemp)) {
throw new SystemCommandException("Unable to find $extractedDirTemp", $build);
}
}

if (is_dir($extractedDir)) {
$this->info("===> Found existing build directory, removing $extractedDir ...");
$lastLine = $this->rmDir($extractedDir, $ret);

if ($ret !== 0) {
throw new SystemCommandException("Unable to remove $extractedDir: $lastLine", $build);
}
}

$this->info("===> Moving $extractedDirTemp to $extractedDir");

if (!rename($extractedDirTemp, $extractedDir)) {
throw new SystemCommandException("Unable to move $extractedDirTemp to $extractedDir", $build);
}

$build->setState(Build::STATE_EXTRACT);

return $extractedDir;
}

public function __destruct()
{
foreach ($this->rmDirs as $dir) {
$this->rmDir($dir);
}

parent::__destruct();
}

private function rmDir($dir, &$return = null)
{
return system('rm -rf ' . escapeshellarg($dir), $return);
}
}
<?php

namespace PhpBrew\Tasks;

use Exception;
use PhpBrew\Downloader\DownloadFactory;




class DownloadTask extends BaseTask
{
public function download($url, $dir, $algo = 'md5', $hash = null)
{
if (!is_writable($dir)) {
throw new Exception("Directory is not writable: $dir");
}

$downloader = DownloadFactory::getInstance($this->logger, $this->options);
$basename = $downloader->resolveDownloadFileName($url);
if (!$basename) {
throw new Exception("Can not parse url: $url");
}
$targetFilePath = $dir . DIRECTORY_SEPARATOR . $basename;

if (!$this->options->force && file_exists($targetFilePath)) {
$this->logger->info('Checking distribution checksum...');
$hash2 = hash_file($algo, $targetFilePath);
if ($hash && $hash2 != $hash) {
$this->logger->warn("Checksum mismatch: $hash2 != $hash");
$this->logger->info('Re-Downloading...');
$downloader->download($url, $targetFilePath);
} else {
$this->logger->info('Checksum matched: ' . $hash);
}
} else {
$downloader->download($url, $targetFilePath);
}

return $targetFilePath;
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\Patches\IntlWith64bitPatch;
use PhpBrew\Patches\OpenSSLDSOPatch;
use PhpBrew\Patches\PHP56WithOpenSSL11Patch;




class AfterConfigureTask extends BaseTask
{
public function run(Build $build)
{
if (!$this->options->{'no-patch'}) {
$this->logger->info('===> Checking patches...');
$patches = array();
$patches[] = new IntlWith64bitPatch();
$patches[] = new OpenSSLDSOPatch();
$patches[] = new PHP56WithOpenSSL11Patch();
foreach ($patches as $patch) {
$this->logger->info('Checking patch for ' . $patch->desc());
if ($patch->match($build, $this->logger)) {
$patched = $patch->apply($build, $this->logger);
$this->logger->info("$patched changes patched.");
}
}
}
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\CommandBuilder;
use PhpBrew\Exception\SystemCommandException;




class BuildTask extends BaseTask
{
public function run(Build $build, $targets = array())
{
if ($build->getState() >= Build::STATE_BUILD) {
$this->info('===> Already built, skipping...');

return;
}

$this->info('===> Building...');
$cmd = new CommandBuilder('make');

$cmd->setAppendLog(true);
$cmd->setLogPath($build->getBuildLogPath());
$cmd->setStdout($this->options->{'stdout'});

if (!empty($targets)) {
foreach ($targets as $t) {
$cmd->addArg($t);
}
}

if ($this->options->nice) {
$cmd->nice($this->options->nice);
}

if ($makeJobs = $this->options->{'jobs'}) {
$cmd->addArg("-j{$makeJobs}");
}

$this->debug($cmd->buildCommand());

if (!$this->options->dryrun) {
$startTime = microtime(true);
$code = $cmd->execute($lastline);
if ($code !== 0) {
throw new SystemCommandException("Make failed: $lastline", $build, $build->getBuildLogPath());
}
$buildTime = round((microtime(true) - $startTime) / 60, 1);
$this->info("Build finished: $buildTime minutes.");
}
$build->setState(Build::STATE_BUILD);
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\Config;

class PrepareDirectoryTask extends BaseTask
{
public function run(Build $build = null)
{
$dirs = array();
$dirs[] = Config::getRoot();
$dirs[] = Config::getHome();
$dirs[] = Config::getBuildDir();
$dirs[] = Config::getDistFileDir();

if ($build) {
$dirs[] = Config::getInstallPrefix() . DIRECTORY_SEPARATOR . $build->getName();
}
foreach ($dirs as $dir) {
if (!file_exists($dir)) {
$this->logger->debug("Creating directory $dir");
mkdir($dir, 0755, true);
}
}
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;

class DSymTask extends BaseTask
{







public function check(Build $build)
{
$phpbin = $build->getBinDirectory() . DIRECTORY_SEPARATOR . 'php';
$dSYM = $build->getBinDirectory() . DIRECTORY_SEPARATOR . 'php.dSYM';

return !file_exists($phpbin) && file_exists($dSYM);
}

public function patch(Build $build, $options)
{
if ($this->check($build)) {
$this->logger->info('---> Moving php.dSYM to php ');
if (!$options->dryrun) {
$phpBin = $build->getBinDirectory() . DIRECTORY_SEPARATOR . 'php';
$dSYM = $build->getBinDirectory() . DIRECTORY_SEPARATOR . 'php.dSYM';
rename($dSYM, $phpBin);
}
}
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\ReleaseList;

class FetchReleaseListTask extends BaseTask
{
public function fetch()
{
$this->logger->info('===> Fetching release list...');
$releaseList = new ReleaseList();
$releaseList->fetchRemoteReleaseList($this->options);

return $releaseList->getReleases();
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\ConfigureParameters;
use PhpBrew\Patches\Apache2ModuleNamePatch;
use PhpBrew\Patches\FreeTypePatch;
use PhpBrew\Patches\ReadlinePatch;
use PhpBrew\PatchKit\Patch;




class BeforeConfigureTask extends BaseTask
{
public function run(Build $build, ConfigureParameters $parameters)
{
if (!file_exists($build->getSourceDirectory() . DIRECTORY_SEPARATOR . 'configure')) {
$this->debug("configure file not found, running './buildconf --force'...");

$buildConf = new BuildConfTask($this->logger);
$buildConf->run($build);
}

foreach ((array) $this->options->patch as $patchPath) {

$this->info("===> Applying patch file from $patchPath ...");


for ($i = 0; $i <= 16; ++$i) {
ob_start();
system("patch -p$i --dry-run < $patchPath", $return);
ob_end_clean();

if ($return === 0) {
system("patch -p$i < $patchPath");
break;
}
}
}


if ($build->isEnabledVariant('apxs2')) {
$apxs2Checker = new Apxs2CheckTask($this->logger);
$apxs2Checker->check($parameters);
}

if (!$this->options->{'no-patch'}) {
$this->logger->info('===> Checking patches...');

$freeTypePatch = new FreeTypePatch();
$readlinePatch = new ReadlinePatch();
$needBuildConf = false;


$patches = array(
new Apache2ModuleNamePatch($build->getVersion()),
$freeTypePatch,
$readlinePatch
);

foreach ($patches as $patch) {
$this->logger->info('Checking patch for ' . $patch->desc());
if ($patch->match($build, $this->logger)) {
$patched = $patch->apply($build, $this->logger);
$this->logger->info("$patched changes patched.");

if ($patch === $freeTypePatch || $patch === $readlinePatch) {
$needBuildConf = $patched;
}
}
}

if ($needBuildConf) {
$this->logger->info('Need to run buildconf');

$buildConf = new BuildConfTask($this->logger);
$buildConf->run($build);
}
}
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Buildable;
use PhpBrew\Utils;




class MakeTask extends BaseTask
{
private $buildLogPath;
private $isQuiet = false;

public function run(Buildable $build)
{
return $this->make($build->getSourceDirectory(), 'all', $build);
}

public function install(Buildable $build)
{
return $this->make($build->getSourceDirectory(), 'install', $build);
}

public function clean(Buildable $build)
{
return $this->make($build->getSourceDirectory(), 'clean', $build);
}

public function setBuildLogPath($buildLogPath)
{
$this->buildLogPath = $buildLogPath;
}

public function setQuiet()
{
$this->isQuiet = true;
}

public function isQuiet()
{
return $this->isQuiet;
}

private function isGNUMake($bin)
{
return preg_match('/GNU Make/', shell_exec("$bin --version"));
}





private function make($path, $target = 'all', $build = null)
{
if (!file_exists($path . DIRECTORY_SEPARATOR . 'Makefile')) {
$this->logger->error("Makefile not found in path $path");

return false;
}




$gmake = Utils::findBin('gmake');
$make = null;
if (!$gmake) {
$make = Utils::findBin('make');
if ($make && $this->isGNUMake($make)) {
$gmake = $make;
}
}


$cmd = array($gmake ?: $make, '-C', escapeshellarg($path));

if ($this->isQuiet()) {
if ($gmake) {
$cmd[] = '--quiet';
} else {


if (php_uname('s') === 'FreeBSD') {
$cmd[] = '-Q';
}
}
}

$cmd[] = escapeshellarg($target);
if (!$this->logger->isDebug() && $this->buildLogPath) {
$cmd[] = ' >> ' . escapeshellarg($this->buildLogPath) . ' 2>&1';
}

$this->logger->info("===> Running make $target: " . implode(' ', $cmd));

return Utils::system($cmd, $this->logger, $build) === 0;
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\CommandBuilder;
use PhpBrew\Config;
use PhpBrew\ConfigureParameters;
use PhpBrew\Exception\SystemCommandException;




class ConfigureTask extends BaseTask
{
public function run(Build $build, ConfigureParameters $parameters)
{
$this->debug('Enabled variants: [' . implode(', ', array_keys($build->getEnabledVariants())) . ']');
$this->debug('Disabled variants: [' . implode(', ', array_keys($build->getDisabledVariants())) . ']');

$cmd = new CommandBuilder('./configure');
$cmd->args($this->renderOptions($parameters));

$buildLogPath = $build->getBuildLogPath();
if (file_exists($buildLogPath)) {
$newPath = $buildLogPath . '.' . filemtime($buildLogPath);
$this->info("Found existing build.log, renaming it to $newPath");
rename($buildLogPath, $newPath);
}

$this->info("===> Configuring {$build->version}...");
$cmd->setAppendLog(true);
$cmd->setLogPath($buildLogPath);
$cmd->setStdout($this->options->{'stdout'});

if (!$this->options->{'stdout'}) {
$this->logger->info(PHP_EOL);
$this->logger->info("Use tail command to see what's going on:");
$this->logger->info('   $ tail -F ' . escapeshellarg($buildLogPath) . PHP_EOL . PHP_EOL);
}

$this->debug($cmd->buildCommand());

if ($this->options->nice) {
$cmd->nice($this->options->nice);
}

if (!$this->options->dryrun) {
$code = $cmd->execute($lastline);
if ($code !== 0) {
throw new SystemCommandException("Configure failed: $lastline", $build, $buildLogPath);
}
}
$build->setState(Build::STATE_CONFIGURE);
}

private function renderOptions(ConfigureParameters $parameters)
{
$args = array();

foreach ($parameters->getOptions() as $option => $value) {
$arg = $option;

if ($value !== null) {
$arg .= '=' . $value;
}

$args[] = $arg;
}

$pkgConfigPaths = $parameters->getPkgConfigPaths();

if (count($pkgConfigPaths) > 0) {
$args[] = 'PKG_CONFIG_PATH=' . implode(PATH_SEPARATOR, $pkgConfigPaths);
}

return $args;
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\CommandBuilder;
use PhpBrew\Exception\SystemCommandException;




class InstallTask extends BaseTask
{
public function install(Build $build)
{
$this->info('Installing...');

if ($this->options->sudo) {
$cmd = new CommandBuilder('sudo make install');
if (!$this->options->dryrun) {
$code = $cmd->passthru($lastline);
if ($code !== 0) {
throw new SystemCommandException("Install failed: $lastline", $build, $build->getBuildLogPath());
}
}
} else {
$cmd = new CommandBuilder('make install');
$cmd->setAppendLog(true);
$cmd->setLogPath($build->getBuildLogPath());
$cmd->setStdout($this->options->{'stdout'});
if (!$this->options->dryrun) {
$code = $cmd->execute($lastline);
if ($code !== 0) {
throw new SystemCommandException("Install failed: $lastline", $build, $build->getBuildLogPath());
}
}
}
$build->setState(Build::STATE_INSTALL);
}
}
<?php

namespace PhpBrew\Tasks;

use PhpBrew\Build;
use PhpBrew\Exception\SystemCommandException;




class BuildConfTask extends BaseTask
{
public function run(Build $build)
{
$lastLine = system('./buildconf --force', $status);

if ($status !== 0) {
throw new SystemCommandException(
sprintf('buildconf error: %s', $lastLine),
$build
);
}
}
}
<?php

namespace PhpBrew\Tasks;

use Exception;
use PhpBrew\ConfigureParameters;
use PhpBrew\Utils;

class Apxs2CheckTask extends BaseTask
{
public function check(ConfigureParameters $parameters)
{
$options = $parameters->getOptions();

if (isset($options['--with-apxs2'])) {
$apxs = $options['--with-apxs2'];
} else {

$apxs = Utils::findbin('apxs');
$this->logger->debug("Found apxs2 binary: $apxs");
}

if (!is_executable($apxs)) {
throw new Exception("apxs binary is not executable: $apxs");
}


if ($libdir = exec("$apxs -q LIBEXECDIR")) {
if (false === is_writable($libdir)) {
$this->logger->error(
<<<EOF
Apache module dir $libdir is not writable.
Please consider using chmod to change the folder permission:
    \$ sudo chmod -R oga+rw $libdir
Warnings: the command above is not safe for public systems. Please use with discretion.
EOF
);

throw new Exception();
}
}

if ($confdir = exec("$apxs -q SYSCONFDIR")) {
if (false === is_writable($confdir)) {
$this->logger->error(
<<<EOF
Apache conf dir $confdir is not writable for phpbrew.
Please consider using chmod to change the folder permission:
    \$ sudo chmod -R oga+rw $confdir
Warnings: the command above is not safe for public systems. Please use with discretion.
EOF
);

throw new Exception();
}
}
}
}
<?php

namespace PhpBrew\Tasks;

use CLIFramework\Logger;
use GetOptionKit\OptionResult;

abstract class BaseTask
{



public $logger;

public $options;

public $startedAt;

public $finishedAt;

public function __construct(Logger $logger, OptionResult $options = null)
{
$this->startedAt = microtime(true);
$this->logger = $logger;
if ($options) {
$this->options = $options;
} else {
$this->options = new OptionResult();
}
}

public function info($msg)
{
if ($this->logger) {
$this->logger->info($msg);
}
}

public function debug($msg)
{
if ($this->logger) {
$this->logger->debug($msg);
}
}

public function __destruct()
{
$this->finishedAt = microtime(true);
}
}
<?php

namespace PhpBrew\Extension;

class M4Extension extends Extension
{
}
<?php

namespace PhpBrew\Extension;

use PEARX\Package;

class PeclExtension extends Extension
{
public $package;

public function setPackage(Package $pkg)
{
$this->package = $pkg;
$this->setVersion($pkg->getReleaseVersion());

if ($pkg->getZendExtSrcRelease()) {
$this->setZend(true);
}

if ($n = strtolower($pkg->getProvidesExtension())) {
$this->setExtensionName($n);
$this->setSharedLibraryName($n . '.so');
}

if ($options = $pkg->getConfigureOptions()) {
$this->configureOptions = array();
foreach ($options as $option) {
$this->addConfigureOption(new ConfigureOption('--' . $option->name, $option->prompt, $option->default));
}
}
}

public function findConfigM4FileFromPackageXml()
{
if ($contents = $this->package->getContents()) {
foreach ($contents as $content) {
if (preg_match('#config[0-9]*.m4$#', $content->file)) {

return $content->file;
}
}
}
}

public function findConfigM4File($dir)
{
if ($file = parent::findConfigM4File($dir)) {
return $file;
}
if ($file = $this->findConfigM4FileFromPackageXml()) {
return $file;
}
}
}
<?php

namespace PhpBrew\Extension;

use PhpBrew\Buildable;
use PhpBrew\Config;

class Extension implements Buildable
{






protected $name;

protected $extensionName;

protected $version;




protected $configM4File = 'config.m4';




protected $sharedLibraryName;

protected $sourceDirectory;

protected $isZend = false;






protected $configureOptions = array();

protected static $nameMap = array(
'libsodium' => 'sodium',
);

public function __construct($name)
{
$this->name = $name;
$this->extensionName = strtolower($name);
}

public function setName($name)
{
return $this->name = $name;
}

public function getName()
{
return $this->name;
}

public function setVersion($version)
{
$this->version = $version;
}

public function getVersion()
{
return $this->version;
}

public function setZend($zendExtension = true)
{
$this->isZend = $zendExtension;
}

public function isZend()
{
return $this->isZend;
}

public function setSharedLibraryName($n)
{
$this->sharedLibraryName = $n;
}

public function getSharedLibraryName()
{
if ($this->sharedLibraryName) {
return $this->sharedLibraryName;
}

$name = strtolower($this->extensionName);
if (isset(self::$nameMap[$name])) {
$name = self::$nameMap[$name];
}

return $name . '.so'; 
}

public function setExtensionName($name)
{
$this->extensionName = $name;
}

public function getExtensionName()
{
return $this->extensionName;
}

public function setSourceDirectory($dir)
{
$this->sourceDirectory = $dir;

if ($configM4File = $this->findConfigM4File($dir)) {
$this->configM4File = $configM4File;
}
}

public function getConfigM4File()
{
return $this->configM4File;
}

public function getConfigM4Path()
{
return $this->sourceDirectory . DIRECTORY_SEPARATOR . $this->configM4File;
}

public function findConfigM4File($dir)
{
$configM4Path = $dir . DIRECTORY_SEPARATOR . 'config.m4';
if (file_exists($configM4Path)) {
return 'config.m4';
}

for ($i = 0; $i < 10; ++$i) {
$filename = "config{$i}.m4";
$configM4Path = $dir . DIRECTORY_SEPARATOR . $filename;
if (file_exists($configM4Path)) {
return $filename;
}
}
}

public function isBuildable()
{
return file_exists($this->sourceDirectory . DIRECTORY_SEPARATOR . 'Makefile');
}

public function getSourceDirectory()
{
return $this->sourceDirectory;
}

public function getBuildLogPath()
{
return $this->sourceDirectory . DIRECTORY_SEPARATOR . 'build.log';
}

public function getSharedLibraryPath()
{
return ini_get('extension_dir') . DIRECTORY_SEPARATOR . $this->getSharedLibraryName();
}

public function getConfigFilePath($sapi = null)
{
$sapiPath = '';
if ($sapi) {
$sapiPath = '/' . $sapi;
}
return Config::getCurrentPhpConfigScanPath() . $sapiPath . '/' . $this->getName() . '.ini';
}






public function isLoaded()
{
return extension_loaded($this->extensionName);
}

public function addConfigureOption(ConfigureOption $opt)
{
$this->configureOptions[] = $opt;
}

public function getConfigureOptions()
{
return $this->configureOptions;
}
}
<?php

namespace PhpBrew\Extension\Provider;

use Exception;

class BitbucketProvider implements Provider
{
public $site = 'bitbucket.org';
public $owner = null;
public $repository = null;
public $packageName = null;
public $defaultVersion = 'master';

public static function getName()
{
return 'bitbucket';
}

public function buildPackageDownloadUrl($version = 'stable')
{
if (($this->getOwner() == null) || ($this->getRepository() == null)) {
throw new Exception('Username or Repository invalid.');
}

return sprintf(
'https://%s/%s/%s/get/%s.tar.gz',
$this->site,
$this->getOwner(),
$this->getRepository(),
$version
);
}

public function getOwner()
{
return $this->owner;
}

public function setOwner($owner)
{
$this->owner = $owner;
}

public function getRepository()
{
return $this->repository;
}

public function setRepository($repository)
{
$this->repository = $repository;
}

public function getPackageName()
{
return $this->packageName;
}

public function setPackageName($packageName)
{
$this->packageName = $packageName;
}

public function exists($dsl, $packageName = null)
{
$dslparser = new RepositoryDslParser();
$info = $dslparser->parse($dsl);

$this->setOwner($info['owner']);
$this->setRepository($info['package']);
$this->setPackageName($packageName ?: $info['package']);

return $info['repository'] == 'bitbucket';
}

public function isBundled($name)
{
return false;
}

public function buildKnownReleasesUrl()
{
return sprintf(
'https://bitbucket.org/api/2.0/repositories/%s/%s/refs/tags',
rawurlencode($this->getOwner()),
rawurlencode($this->getRepository())
);
}

public function parseKnownReleasesResponse($content)
{
$info = json_decode($content, true);
$versionList = array_keys($info);

return $versionList;
}

public function getDefaultVersion()
{
return $this->defaultVersion;
}

public function setDefaultVersion($version)
{
$this->defaultVersion = $version;
}

public function shouldLookupRecursive()
{
return true;
}

public function resolveDownloadFileName($version)
{
return sprintf('%s-%s-%s.tar.gz', $this->getOwner(), $this->getRepository(), $version);
}

public function extractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
{
$cmds = array(
"tar -C $currentPhpExtensionDirectory -xzf $targetFilePath",
);

return $cmds;
}

public function postExtractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
{
$targetPkgDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $this->getPackageName();
$extractDir = $currentPhpExtensionDirectory
. DIRECTORY_SEPARATOR
. $this->getOwner()
. '-'
. $this->getRepository()
. '-*';

$cmds = array(
"rm -rf $targetPkgDir",
"mv $extractDir $targetPkgDir",
);

return $cmds;
}
}
<?php

namespace PhpBrew\Extension\Provider;

interface Provider
{
public static function getName();
public function getOwner();
public function setOwner($owner);
public function getRepository();
public function setRepository($repository);
public function getPackageName();
public function setPackageName($packageName);
public function buildKnownReleasesUrl();
public function parseKnownReleasesResponse($content);
public function buildPackageDownloadUrl($version);
public function exists($url, $packageName = null);
public function isBundled($packageName);

public function getDefaultVersion();
public function setDefaultVersion($version);
public function shouldLookupRecursive();
public function resolveDownloadFileName($version);

public function extractPackageCommands($currentPhpExtensionDirectory, $targetFilePath);
public function postExtractPackageCommands($currentPhpExtensionDirectory, $targetFilePath);
}
<?php

namespace PhpBrew\Extension\Provider;

use Exception;

class GithubProvider implements Provider
{
public $auth = null;
public $site = 'github.com';
public $owner = null;
public $repository = null;
public $packageName = null;
public $defaultVersion = 'master';

public static function getName()
{
return 'github';
}




public function buildPackageDownloadUrl($version = 'master')
{
if (($this->getOwner() == null) || ($this->getRepository() == null)) {
throw new Exception('Username or Repository invalid.');
}

return sprintf(
'https://%s/%s/%s/archive/%s.tar.gz',
$this->site,
$this->getOwner(),
$this->getRepository(),
$version
);
}




public function getAuth()
{
return $this->auth;
}




public function setAuth($auth)
{
$this->auth = $auth;
}


public function getOwner()
{
return $this->owner;
}

public function setOwner($owner)
{
$this->owner = $owner;
}

public function getRepository()
{
return $this->repository;
}

public function setRepository($repository)
{
$this->repository = $repository;
}

public function getPackageName()
{
return $this->packageName;
}

public function setPackageName($packageName)
{
$this->packageName = $packageName;
}

public function exists($dsl, $packageName = null)
{
$dslparser = new RepositoryDslParser();
$info = $dslparser->parse($dsl);

$this->setOwner($info['owner']);
$this->setRepository($info['package']);
$this->setPackageName($packageName ?: $info['package']);

return $info['repository'] == 'github';
}

public function isBundled($name)
{
return false;
}

public function buildKnownReleasesUrl()
{
return sprintf(
'https://%sapi.github.com/repos/%s/%s/tags',
($this->auth ? $this->auth . '@' : ''),
$this->getOwner(),
$this->getRepository()
);
}

public function parseKnownReleasesResponse($content)
{
$info = json_decode($content, true);
$versionList = array_map(function ($version) {
return $version['name'];
}, $info);

return $versionList;
}

public function getDefaultVersion()
{
return $this->defaultVersion;
}

public function setDefaultVersion($version)
{
$this->defaultVersion = $version;
}

public function shouldLookupRecursive()
{
return true;
}

public function resolveDownloadFileName($version)
{
return sprintf('%s-%s.tar.gz', $this->getRepository(), $version);
}

public function extractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
{
$cmds = array(
"tar -C $currentPhpExtensionDirectory -xzf $targetFilePath",
);

return $cmds;
}

public function postExtractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
{
$targetPkgDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $this->getPackageName();
$extractDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $this->getRepository() . '-*';

$cmds = array(
"rm -rf $targetPkgDir",
"mv $extractDir $targetPkgDir",
);

return $cmds;
}
}
<?php

namespace PhpBrew\Extension\Provider;

use CLIFramework\Logger;
use Exception;
use GetOptionKit\OptionResult;
use PEARX\Channel as PeclChannel;
use PhpBrew\Downloader\DownloadFactory;

class PeclProvider implements Provider
{
public $site = 'pecl.php.net';
public $owner = null;
public $repository = null;
public $packageName = null;
public $defaultVersion = 'stable';

private $logger;
private $options;

public function __construct(Logger $logger, OptionResult $options)
{
$this->logger = $logger;
$this->options = $options;
}

public static function getName()
{
return 'pecl';
}

public function buildPackageDownloadUrl($version = 'stable')
{
$packageName = $this->getPackageName();

if ($packageName === null) {
throw new Exception('Repository invalid.');
}

$channel = new PeclChannel($this->site);
$baseUrl = $channel->getRestBaseUrl();
$url = "$baseUrl/r/" . strtolower($packageName);

$downloader = DownloadFactory::getInstance($this->logger, $this->options);


if (in_array($version, array('stable', 'latest', 'beta'))) {
$stabilityTxtUrl = $url . '/' . $version . '.txt';
if ($ret = $downloader->request($stabilityTxtUrl)) {
$version = (string) $ret;
} else {
throw new Exception("Can not translate stability {$version} into exact version name.");
}
}

$xmlUrl = $url . '/' . $version . '.xml';
$ret = $downloader->request($xmlUrl);

if ($ret === false) {
throw new Exception('Unable to fetch package xml');
}

$xml = simplexml_load_string($ret);

if ($xml === false) {
throw new Exception("Error in XMl document: $url");
}


return $xml->g . '.tgz';
}

public function getOwner()
{
return $this->owner;
}

public function setOwner($owner)
{
$this->owner = $owner;
}

public function getRepository()
{
return $this->repository;
}

public function setRepository($repository)
{
$this->repository = $repository;
}

public function getPackageName()
{
return $this->packageName;
}

public function setPackageName($packageName)
{
$this->packageName = $packageName;
}

public function exists($url, $packageName = null)
{
$this->setOwner(null);
$this->setRepository(null);
$this->setPackageName($url);

return true;
}

public function isBundled($name)
{
return in_array(strtolower($name), array(
'bcmath', 'bz2', 'calendar', 'com_dotnet', 'ctype', 'curl', 'date',
'dba', 'dom', 'enchant', 'exif', 'fileinfo', 'filter', 'ftp', 'gd',
'gettext', 'gmp', 'hash', 'iconv', 'imap', 'interbase', 'intl',
'json', 'ldap', 'libxml', 'mbstring', 'mcrypt', 'mssql', 'mysqli',
'mysqlnd', 'oci8', 'odbc', 'opcache', 'openssl', 'pcntl', 'pcre',
'pdo', 'pdo_dblib', 'pdo_firebird', 'pdo_mysql', 'pdo_oci', 'pdo_odbc',
'pdo_pgsql', 'pdo_sqlite', 'pgsql', 'phar', 'posix', 'pspell',
'readline', 'recode', 'reflection', 'session', 'shmop', 'simplexml',
'skeleton', 'snmp', 'soap', 'sockets', 'spl', 'sqlite3', 'standard',
'sysvmsg', 'sysvsem', 'sysvshm', 'tidy', 'tokenizer', 'wddx', 'xml',
'xmlreader', 'xmlrpc', 'xmlwriter', 'xsl', 'zip', 'zlib', 'ext_skel',
'ext_skel_win32',
));
}

public function buildKnownReleasesUrl()
{
return sprintf('https://pecl.php.net/rest/r/%s/allreleases.xml', $this->getPackageName());
}

public function parseKnownReleasesResponse($content)
{
$xml = simplexml_load_string($content);
$releases = array();

foreach ($xml->r as $r) {
$releases[] = (string) $r->v;
}

return $releases;
}

public function getDefaultVersion()
{
return $this->defaultVersion;
}

public function setDefaultVersion($version)
{
$this->defaultVersion = $version;
}

public function shouldLookupRecursive()
{
return false;
}

public function resolveDownloadFileName($version)
{
$url = $this->buildPackageDownloadUrl($version);

if (preg_match('/php-.+\.tar\.(bz2|gz|xz)/', $url, $parts)) {
return $parts[0];
}


$path = parse_url($url, PHP_URL_PATH);
if (false === $path || false === strpos($path, '.')) {
return;
}

return basename($path);
}

public function extractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
{
$cmds = array(
"tar -C $currentPhpExtensionDirectory -xzf $targetFilePath",
);

return $cmds;
}

public function postExtractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
{
$targetPkgDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $this->getPackageName();
$info = pathinfo($targetFilePath);
$packageName = $this->getPackageName();

$cmds = array(
"rm -rf $targetPkgDir",

"mv $currentPhpExtensionDirectory/{$info['filename']} $currentPhpExtensionDirectory/$packageName",

"mv $currentPhpExtensionDirectory/package.xml $currentPhpExtensionDirectory/$packageName/package.xml",
);

return $cmds;
}
}
<?php

namespace PhpBrew\Extension\Provider;

class RepositoryDslParser
{
protected static $macros = array(
'https://bitbucket.org/' => array(
'git@bitbucket.org:',
'bitbucket:',
),
'https://github.com/' => array(
'github:',
'git@github.com:',
),
);

public function parse($dsl)
{
$ast = array(
'repository' => 'pecl',
'owner' => null,
'package' => $dsl,
);

$url = $this->toUrl($dsl);


if (preg_match("#https?://(?:www\.)?([0-9a-zA-Z-_]*).+/([0-9a-zA-Z-._]*)/([0-9a-zA-Z-._]*)#", $url, $matches)) {
$ast['repository'] = $matches[1];
$ast['owner'] = $matches[2];
$ast['package'] = $matches[3];
}

return $ast;
}

protected function toUrl($dsl)
{
$url = $dsl;
foreach (self::$macros as $target => $sources) {
$url = str_replace($sources, $target, $url);
}

return preg_replace('#\.git$#', '', $url);
}
}
<?php

namespace PhpBrew\Extension;

use CLIFramework\Logger;
use Exception;
use PhpBrew\Config;
use PhpBrew\Tasks\MakeTask;
use PhpBrew\Utils;

class ExtensionManager
{
public $logger;








protected $conflicts = array(
'json' => array('jsonc'), 
'jsonc' => array('json'), 
);

public function __construct(Logger $logger)
{
$this->logger = $logger;
}

public function purgeExtension(Extension $ext)
{
if ($sourceDir = $ext->getSourceDirectory()) {
$currentPhpExtensionDirectory = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';
$extName = $ext->getExtensionName();
$extensionDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $extName;
if (file_exists($extensionDir)) {
Utils::system("rm -rvf $extensionDir");
}
}
}

public function cleanExtension(Extension $ext)
{
$make = new MakeTask($this->logger);
$make->setQuiet();
$code = !is_dir($sourceDir = $ext->getSourceDirectory()) ||
!$ext->isBuildable() ||
!$make->clean($ext);

if ($code != 0) {
$this->logger->error("Could not clean extension: {$ext->getName()}.");
}

return $code == 0;
}





public function installExtension(Extension $ext, array $options = array())
{
$this->disableExtension($ext);

$sourceDir = $ext->getSourceDirectory();
$name = $ext->getName();

if (!file_exists($sourceDir)) {
throw new Exception("Source directory $sourceDir does not exist.");
}


$installer = new ExtensionInstaller($this->logger);
$this->logger->info("===> Installing {$name} extension...");
$this->logger->debug("Extension path $sourceDir");

$installer->install($ext, $options);

$this->createExtensionConfig($ext);
$this->enableExtension($ext);
$this->logger->info('Done.');

return $sourceDir;
}

public function createExtensionConfig(Extension $ext)
{
$ini = $ext->getConfigFilePath();
$this->logger->info("===> Creating config file {$ini}");

if (!file_exists(dirname($ini))) {
if (!mkdir($concurrentDirectory = dirname($ini), 0755, true) && !is_dir($concurrentDirectory)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
}
}

if (file_exists($ini)) {
return true;
}


$content = sprintf(
'%s=%s' . PHP_EOL,
$ext->isZend() ? 'zend_extension' : 'extension',
$ext->isZend() && PHP_VERSION_ID < 50500
? $ext->getSharedLibraryPath()
: $ext->getSharedLibraryName()
);


if (file_put_contents($ini, $content) === false) {
return false;
}

$this->logger->debug("{$ini} is created.");

return true;
}

public function disable($extensionName, $sapi = null)
{
$ext = ExtensionFactory::lookup($extensionName);
if (!$ext) {
$ext = ExtensionFactory::lookupRecursive($extensionName);
}
if ($ext) {
return $this->disableExtension($ext, $sapi);
} else {
$this->logger->info("{$extensionName} extension is not installed. ");
}
}

public function enable($extensionName, $sapi = null)
{
$ext = ExtensionFactory::lookup($extensionName);
if (!$ext) {
$ext = ExtensionFactory::lookupRecursive($extensionName);
}
if ($ext) {
return $this->enableExtension($ext, $sapi);
} else {
$this->logger->info("{$extensionName} extension is not installed. ");
}
}






public function enableExtension(Extension $ext, $sapi = null)
{
$name = $ext->getExtensionName();
$this->logger->info("===> Enabling extension $name");

if ($sapi) {
return $this->enableSapiExtension($ext, $name, $sapi, true);
}

$first = true;
$result = true;
foreach (Config::getSapis() as $availableSapi) {
$result = $result && $this->enableSapiExtension($ext, $name, $availableSapi, $first);
$first = false;
}

return $result;
}

private function enableSapiExtension(Extension $ext, $name, $sapi, $first = false)
{
$default_file = $ext->getConfigFilePath();
$enabled_file = $ext->getConfigFilePath($sapi);
if (file_exists($enabled_file) && ($ext->isLoaded() && !$this->hasConflicts($ext))) {
$this->logger->info("[*] {$name} extension is already enabled for SAPI {$sapi}.");

return true;
}

if (
$first
&& !file_exists($default_file)
&& !(file_exists($ext->getSharedLibraryPath())
&& $this->createExtensionConfig($ext))
) {
$this->logger->info("{$name} extension is not installed. Suggestions:");
$this->logger->info("\t\$ phpbrew ext install {$name}");

return false;
}

if (!file_exists(dirname($enabled_file))) {
return true;
}

$this->disableAntagonists($ext, $sapi);

$disabled_file = $enabled_file . '.disabled';
if (file_exists($disabled_file)) {
if (!rename($disabled_file, $enabled_file)) {
$this->logger->warning("failed to re-enable {$name} extension for SAPI {$sapi}.");

return false;
}

$this->logger->info("[*] {$name} extension is re-enabled for SAPI {$sapi}.");
return true;
}

if (!copy($default_file, $enabled_file)) {
$this->logger->warning("failed to enable {$name} extension for SAPI {$sapi}.");

return false;
}

$this->logger->info("[*] {$name} extension is enabled for SAPI {$sapi}.");

return true;
}






public function disableExtension(Extension $ext, $sapi = null)
{
$name = $ext->getExtensionName();

if (null !== $sapi) {
return $this->disableSapiExtension($ext->getConfigFilePath($sapi), $name, $sapi);
}

$result = true;
foreach (Config::getSapis() as $availableSapi) {
$result = $result && $this->disableSapiExtension($ext->getConfigFilePath($availableSapi), $name, $sapi);
}

return $result;
}

private function disableSapiExtension($extension_file, $name, $sapi)
{
if (!file_exists(dirname($extension_file))) {
return true;
}

if (!file_exists($extension_file)) {
$this->logger->info("[ ] {$name} extension is already disabled for SAPI {$sapi}.");

return true;
}

if (file_exists($extension_file)) {
if (rename($extension_file, $extension_file . '.disabled')) {
$this->logger->info("[ ] {$name} extension is disabled for SAPI {$sapi}.");

return true;
}
$this->logger->warning("failed to disable {$name} extension for SAPI {$sapi}.");
}

return false;
}




public function disableAntagonists(Extension $ext, $sapi = null)
{
$name = $ext->getName();
if (isset($this->conflicts[$name])) {
$conflicts = $this->conflicts[$name];
$this->logger->info('===> Applying conflicts resolution (' . implode(', ', $conflicts) . '):');
foreach ($conflicts as $extensionName) {
$ext = ExtensionFactory::lookup($extensionName);
$this->disableExtension($ext, $sapi);
}
}
}

public function hasConflicts(Extension $ext)
{
return array_key_exists($ext->getName(), $this->conflicts);
}
}
<?php

namespace PhpBrew\Extension;

use CLIFramework\Logger;
use GetOptionKit\OptionResult;
use PhpBrew\Config;
use PhpBrew\Tasks\MakeTask;
use PhpBrew\Utils;

class ExtensionInstaller
{
public $logger;

public $options;

public function __construct(Logger $logger, OptionResult $options = null)
{
$this->logger = $logger;
$this->options = $options ?: new OptionResult();
}

public function install(Extension $ext, array $configureOptions = array())
{
$sourceDir = $ext->getSourceDirectory();
$pwd = getcwd();
$buildLogPath = $sourceDir . DIRECTORY_SEPARATOR . 'build.log';
$make = new MakeTask($this->logger, $this->options);

$make->setBuildLogPath($buildLogPath);

$this->logger->info("Log stored at: $buildLogPath");

$this->logger->info("Changing directory to $sourceDir");
chdir($sourceDir);

if (!$this->options->{'no-clean'} && $ext->isBuildable()) {
$clean = new MakeTask($this->logger, $this->options);
$clean->setQuiet();
$clean->clean($ext);
}

if ($ext->getConfigM4File() !== 'config.m4' && !file_exists($sourceDir . DIRECTORY_SEPARATOR . 'config.m4')) {
symlink($ext->getConfigM4File(), $sourceDir . DIRECTORY_SEPARATOR . 'config.m4');
}


$this->logger->info('===> Phpize...');
Utils::system("phpize > $buildLogPath 2>&1", $this->logger);

$this->logger->info('===> Configuring...');

$phpConfig = Config::getCurrentPhpConfigBin();
if (file_exists($phpConfig)) {
$this->logger->debug("Appending argument: --with-php-config=$phpConfig");
$configureOptions[] = '--with-php-config=' . $phpConfig;
}

$cmd = './configure ' . implode(' ', array_map('escapeshellarg', $configureOptions));

if (!$this->logger->isDebug()) {
$cmd .= ' >> ' . escapeshellarg($buildLogPath) . ' 2>&1';
}

Utils::system($cmd, $this->logger);

$this->logger->info('===> Building...');

if ($this->logger->isDebug()) {
passthru('make');
} else {
$make->run($ext);
}

$this->logger->info('===> Installing...');


if ($this->logger->isDebug()) {
passthru('make install');
} else {
$make->install($ext);
}


$this->logger->debug('Installed extension library: ' . $ext->getSharedLibraryPath());



chdir($pwd);
$this->logger->info('===> Extension is installed.');
}
}
<?php

namespace PhpBrew\Extension;

use CLIFramework\Logger;
use GetOptionKit\OptionResult;
use PhpBrew\Config;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\Extension\Provider\Provider;
use PhpBrew\Utils;

class ExtensionDownloader
{
public $logger;

public $options;

public function __construct(Logger $logger, OptionResult $options)
{
$this->logger = $logger;
$this->options = $options;
}

public function download(Provider $provider, $version = 'stable')
{
$url = $provider->buildPackageDownloadUrl($version);
$basename = $provider->resolveDownloadFileName($version);
$distDir = Config::getDistFileDir();
$targetFilePath = $distDir . DIRECTORY_SEPARATOR . $basename;
DownloadFactory::getInstance($this->logger, $this->options)->download($url, $targetFilePath);

$currentPhpExtensionDirectory = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';


$extensionDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $provider->getPackageName();
if (!file_exists($extensionDir)) {
mkdir($extensionDir, 0755, true);
}

$this->logger->info("===> Extracting to $currentPhpExtensionDirectory...");

$cmds = array_merge(
$provider->extractPackageCommands($currentPhpExtensionDirectory, $targetFilePath),
$provider->postExtractPackageCommands($currentPhpExtensionDirectory, $targetFilePath)
);

foreach ($cmds as $cmd) {
$this->logger->debug($cmd);
Utils::system($cmd);
}

return $extensionDir;
}

public function knownReleases(Provider $provider)
{
$url = $provider->buildKnownReleasesUrl();
$file = DownloadFactory::getInstance($this->logger, $this->options)->download($url);
$info = file_get_contents($file);

return $provider->parseKnownReleasesResponse($info);
}

public function renameSourceDirectory(Extension $ext)
{
$currentPhpExtensionDirectory = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';
$extName = $ext->getExtensionName();
$name = $ext->getName();
$extensionDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $extName;
$extensionExtractDir = $currentPhpExtensionDirectory . DIRECTORY_SEPARATOR . $name;

if ($name != $extName) {
$this->logger->info("===> Rename source directory to $extensionDir...");

$cmds = array(
"rm -rf $extensionDir",
"mv $extensionExtractDir $extensionDir",
);

foreach ($cmds as $cmd) {
$this->logger->debug($cmd);
Utils::system($cmd);
}


$sourceDir = str_replace($extensionExtractDir, $extensionDir, $ext->getSourceDirectory());
$ext->setSourceDirectory($sourceDir);
$ext->setName($extName);
}
}
}
<?php

namespace PhpBrew\Extension;

class ConfigureOption
{
public $option;

public $desc;

public $valueHint;

public $defaultValue;

public function __construct($option, $desc, $valueHint = null)
{
$this->option = $option;
$this->desc = $desc;
$this->valueHint = $valueHint;
}

public function getOption()
{
return $this->option;
}

public function getDescription()
{
return $this->desc;
}

public function getValueHint()
{
return $this->valueHint;
}

public function setDefaultValue($value)
{
$this->defaultValue = $value;
}
}
<?php

namespace PhpBrew\Extension;

use Exception;
use PEARX\PackageXml\Parser as PackageXmlParser;
use PhpBrew\Config;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;




class ExtensionFactory
{




public static function configM4Exists($extensionDir)
{
$files = array();
$configM4Path = $extensionDir . DIRECTORY_SEPARATOR . 'config.m4';
if (file_exists($configM4Path)) {
$files[] = $configM4Path;
}
for ($i = 0; $i < 10; ++$i) {
$configM4Path = $extensionDir . DIRECTORY_SEPARATOR . "config{$i}.m4";
if (file_exists($configM4Path)) {
$files[] = $configM4Path;
}
}

return $files;
}

public static function createFromDirectory($packageName, $extensionDir)
{
$packageXmlPath = $extensionDir . DIRECTORY_SEPARATOR . 'package.xml';






if (file_exists($packageXmlPath)) {

if ($ext = self::createPeclExtension($packageName, $packageXmlPath)) {
return $ext;
}
}
















$configM4Paths = self::configM4Exists($extensionDir);
foreach ($configM4Paths as $m4path) {
if (file_exists($m4path)) {
try {
$ext = self::createM4Extension($packageName, $m4path);
if ($ext) {
return $ext;
}
} catch (Exception $e) {

}
}
}
}

public static function lookupRecursive($packageName, array $lookupDirs = array(), $fallback = true)
{
if ($fallback) {

$lookupDirs[] = Config::getBuildDir()
. DIRECTORY_SEPARATOR . Config::getCurrentPhpName()
. DIRECTORY_SEPARATOR . 'ext'
. DIRECTORY_SEPARATOR . $packageName;
}

foreach ($lookupDirs as $lookupDir) {
if (!file_exists($lookupDir)) {
continue;
}

if ($ext = self::createFromDirectory($packageName, $lookupDir)) {
return $ext;
}




$di = new RecursiveDirectoryIterator($lookupDir, RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);






foreach ($it as $fileinfo) {
if (!$fileinfo->isDir()) {
continue;
}
if ($ext = self::createFromDirectory($packageName, $fileinfo->getPathName())) {
return $ext;
}
}
}
}

public static function lookup($packageName, array $lookupDirectories = array(), $fallback = true)
{
if ($fallback) {

$lookupDirectories[] = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';
}

foreach ($lookupDirectories as $lookupDir) {
if (!file_exists($lookupDir)) {
continue;
}

$extensionDir = $lookupDir . DIRECTORY_SEPARATOR . $packageName;
if ($ext = self::createFromDirectory($packageName, $extensionDir)) {
return $ext;
}
}

return new Extension($packageName);
}

public static function createM4Extension($packageName, $m4Path)
{
if (!file_exists($m4Path)) {
return;
}

$m4 = file_get_contents($m4Path);


if (
preg_match('/PHP_NEW_EXTENSION \( \s* 
                \[?
                    (\w+)   # The extension name
                \]?

                \s*,\s*

                \[?
                    ([^,]*)  # Source files
                \]?

                (?:
                    \s*,\s* ([^,\)]*)  # Ext Shared

                    (?:
                        \s*,\s* ([^,\)]*)  # SAPI class

                        (?:
                            \s*,\s* ([^,\)]*)  # Extra cflags

                            (?:
                                \s*,\s* ([^,\)]*)  # CXX
                                \s*,\s* ([^,\)]*)  # zend extension
                            )?
                        )?
                    )?
                )?
                /x', $m4, $matches)
) {
array_shift($matches);
$ext = new M4Extension($packageName);
$ext->setExtensionName($matches[0]);
$ext->setSharedLibraryName($matches[0] . '.so');
if (isset($matches[6]) && strpos($matches[6], 'yes') !== false) {
$ext->setZend(true);
}
$ext->setSourceDirectory(dirname($m4Path));





if (
preg_match_all('/
                PHP_ARG_ENABLE\(
                    \s*([^,]*)
                    (?:
                        \s*,\s*
                        (
                            [^,\)]*
                        )
                        (?:
                            \s*,\s*
                            \[ 
                                \s* 
                                ([^\s]+)
                                \s+ 
                                ([^,\)]*)
                                \s* 
                            \]
                        )?
                    )?/x', $m4, $allMatches)
) {
for ($i = 0; $i < count($allMatches[0]); ++$i) {
$name = $allMatches[1][$i];
$desc = $allMatches[2][$i];
$option = $allMatches[3][$i];
$optionDesc = $allMatches[4][$i];
$ext->addConfigureOption(new ConfigureOption($option ?: '--enable-' . $name, $desc ?: $optionDesc));
}
}














if (
preg_match_all('/
                PHP_ARG_WITH\(
                    \s*

                    ([^,]*)

                    (?:
                        \s*,\s*
                        \[?
                            ([^,\)]*)
                        \]?

                        (?:
                            \s*,\s* 

                            \[ 
                                \s*

                                # simple match (\S+)

                                ([a-zA-Z0-9-]+)  # option
                                (?:
                                    =?

                                    \[?
                                        =?([^\s\]]*?) 
                                    \]?
                                )?                 # option value hint

                                \s+

                                ([^,\)]*)        # option description
                                \s*                 
                            \]

                            (?:
                                \s*,\s* 
                                ([^,\)]*)

                                (?:
                                    \s*,\s* 
                                    ([^,\)]*)
                                )?
                            )?
                        )?
                    )?/x', $m4, $allMatches)
) {




for ($i = 0; $i < count($allMatches[0]); ++$i) {
$name = $allMatches[1][$i];
$desc = $allMatches[2][$i];

$option = $allMatches[3][$i];
$optionValueHint = $allMatches[4][$i];
$optionDesc = $allMatches[5][$i];

$defaultValue = $allMatches[6][$i];

$opt = new ConfigureOption(
($option ?: '--with-' . $name),
($desc ?: $optionDesc),
$optionValueHint
);

if ($defaultValue) {
$opt->setDefaultValue($opt);
}
$ext->addConfigureOption($opt);
}
}

return $ext;
} else {
throw new Exception("Can not parse config.m4: $m4Path");
}
}

public static function createPeclExtension($packageName, $packageXmlPath)
{
$parser = new PackageXmlParser();
$package = $parser->parse($packageXmlPath);
$ext = new PeclExtension($packageName);
$ext->setPackage($package);






if ($m4path = $ext->findConfigM4FileFromPackageXml()) {
$sourceDirectory = dirname($packageXmlPath);
$m4dir = dirname($m4path);
if ($m4dir != '.') {
$sourceDirectory .= DIRECTORY_SEPARATOR . $m4dir;
}
$ext->setSourceDirectory($sourceDirectory);
} else {
$ext->setSourceDirectory(dirname($packageXmlPath));
}

return $ext;
}
}
<?php

namespace PhpBrew\PrefixFinder;

use PhpBrew\PrefixFinder;
use PhpBrew\Utils;




final class ExecutablePrefixFinder implements PrefixFinder
{



private $name;




public function __construct($name)
{
$this->name = $name;
}




public function findPrefix()
{
$bin = Utils::findBin($this->name);

if ($bin === null) {
return null;
}

return dirname($bin);
}
}
<?php

namespace PhpBrew\PrefixFinder;

use PhpBrew\PrefixFinder;
use PhpBrew\Utils;




final class IncludePrefixFinder implements PrefixFinder
{



private $path;




public function __construct($path)
{
$this->path = $path;
}




public function findPrefix()
{
return Utils::findIncludePrefix($this->path);
}
}
<?php

namespace PhpBrew\PrefixFinder;

use PhpBrew\PrefixFinder;
use PhpBrew\Utils;




final class BrewPrefixFinder implements PrefixFinder
{



private $formula;




public function __construct($formula)
{
$this->formula = $formula;
}




public function findPrefix()
{
$brew = Utils::findBin('brew');

if ($brew === null) {
return null;
}

$output = $this->execLine(
sprintf('%s --prefix %s', escapeshellcmd($brew), escapeshellarg($this->formula))
);

if ($output === null) {
printf('Homebrew formula "%s" not found.' . PHP_EOL, $this->formula);

return null;
}

if (!file_exists($output)) {
printf('Homebrew prefix "%s" does not exist.' . PHP_EOL, $output);

return null;
}

return $output;
}

private function execLine($command)
{
$output = array();
exec($command, $output, $retval);

if ($retval === 0) {
$output = array_filter($output);

return end($output);
}

return null;
}
}
<?php

namespace PhpBrew\PrefixFinder;

use PhpBrew\PrefixFinder;
use PhpBrew\Utils;




final class PkgConfigPrefixFinder implements PrefixFinder
{



private $package;




public function __construct($package)
{
$this->package = $package;
}




public function findPrefix()
{
return Utils::getPkgConfigPrefix($this->package);
}
}
<?php

namespace PhpBrew\PrefixFinder;

use PhpBrew\PrefixFinder;
use PhpBrew\Utils;




final class LibPrefixFinder implements PrefixFinder
{



private $path;




public function __construct($path)
{
$this->path = $path;
}




public function findPrefix()
{
return Utils::findLibPrefix($this->path);
}
}
<?php

namespace PhpBrew\PrefixFinder;

use PhpBrew\PrefixFinder;




final class UserProvidedPrefix implements PrefixFinder
{



private $prefix;




public function __construct($prefix)
{
$this->prefix = $prefix;
}




public function findPrefix()
{
return $this->prefix;
}
}
<?php

namespace PhpBrew;

use Exception;
use PhpBrew\Exception\OopsException;
use PhpBrew\PrefixFinder\BrewPrefixFinder;
use PhpBrew\PrefixFinder\ExecutablePrefixFinder;
use PhpBrew\PrefixFinder\IncludePrefixFinder;
use PhpBrew\PrefixFinder\LibPrefixFinder;
use PhpBrew\PrefixFinder\PkgConfigPrefixFinder;
use PhpBrew\PrefixFinder\UserProvidedPrefix;

function first_existing_executable($possiblePaths)
{
$existingPaths = array_filter(
array_filter(
array_filter($possiblePaths, 'file_exists'),
'is_file'
),
'is_executable'
);

if (!empty($existingPaths)) {
return realpath($existingPaths[0]);
}

return false;
}

function exec_line($command)
{
$output = array();
exec($command, $output, $retval);
if ($retval === 0) {
$output = array_filter($output);

return end($output);
}

return false;
}




class VariantBuilder
{





private $variants = array();

private $conflicts = array(

'apxs2' => array('fpm', 'cgi'),
'editline' => array('readline'),
'readline' => array('editline'),


'dtrace' => array('phpdbg'),
);






private $builtList = array();

public $virtualVariants = array(
'dbs' => array(
'sqlite',
'mysql',
'pgsql',
'pdo',
),

'mb' => array(
'mbstring',
'mbregex',
),


'neutral' => array(),

'small' => array(
'bz2',
'cli',
'dom',
'filter',
'ipc',
'json',
'mbregex',
'mbstring',
'pcre',
'phar',
'posix',
'readline',
'xml',
'curl',
'openssl',
),


'default' => array(
'bcmath',
'bz2',
'calendar',
'cli',
'ctype',
'dom',
'fileinfo',
'filter',
'ipc',
'json',
'mbregex',
'mbstring',
'mhash',
'pcntl',
'pcre',
'pdo',
'pear',
'phar',
'posix',
'readline',
'sockets',
'tokenizer',
'xml',
'curl',
'openssl',
'zip',
),
);

public function __construct()
{

$this->variants['all'] = '--enable-all';
$this->variants['dba'] = '--enable-dba';
$this->variants['ipv6'] = '--enable-ipv6';
$this->variants['dom'] = '--enable-dom';
$this->variants['calendar'] = '--enable-calendar';
$this->variants['wddx'] = '--enable-wddx';
$this->variants['static'] = '--enable-static';
$this->variants['inifile'] = '--enable-inifile';
$this->variants['inline'] = '--enable-inline-optimization';

$this->variants['cli'] = '--enable-cli';

$this->variants['ftp'] = '--enable-ftp';
$this->variants['filter'] = '--enable-filter';
$this->variants['gcov'] = '--enable-gcov';
$this->variants['zts'] = function (ConfigureParameters $params, Build $build) {
if ($build->compareVersion('8.0') < 0) {
return $params->withOption('--enable-maintainer-zts');
}

return $params->withOption('--enable-zts');
};

$this->variants['json'] = '--enable-json';
$this->variants['hash'] = '--enable-hash';
$this->variants['exif'] = '--enable-exif';

$this->variants['mbstring'] = function (ConfigureParameters $params, Build $build, $value) {
$params = $params->withOption('--enable-mbstring');

if ($build->compareVersion('7.4') >= 0 && !$build->isDisabledVariant('mbregex')) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('oniguruma.h'),
new BrewPrefixFinder('oniguruma'),
));

if ($prefix !== null) {
$params = $params->withPkgConfigPath($prefix . '/lib/pkgconfig');
}
}

return $params;
};

$this->variants['mbregex'] = '--enable-mbregex';
$this->variants['libgcc'] = '--enable-libgcc';

$this->variants['pdo'] = '--enable-pdo';
$this->variants['posix'] = '--enable-posix';
$this->variants['embed'] = '--enable-embed';
$this->variants['sockets'] = '--enable-sockets';
$this->variants['debug'] = '--enable-debug';
$this->variants['phpdbg'] = '--enable-phpdbg';

$this->variants['zip'] = function (ConfigureParameters $params, Build $build) {
if ($build->compareVersion('7.4') < 0) {
return $params->withOption('--enable-zip');
}

return $params->withOption('--with-zip');
};

$this->variants['bcmath'] = '--enable-bcmath';
$this->variants['fileinfo'] = '--enable-fileinfo';
$this->variants['ctype'] = '--enable-ctype';
$this->variants['cgi'] = '--enable-cgi';
$this->variants['soap'] = '--enable-soap';
$this->variants['gcov'] = '--enable-gcov';
$this->variants['pcntl'] = '--enable-pcntl';

$this->variants['phar'] = '--enable-phar';
$this->variants['session'] = '--enable-session';
$this->variants['tokenizer'] = '--enable-tokenizer';

$this->variants['opcache'] = '--enable-opcache';

$this->variants['imap'] = function (ConfigureParameters $params, Build $build, $value) {
$imapPrefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('imap-uw'),
));

$kerberosPrefix = Utils::findPrefix(array(
new BrewPrefixFinder('krb5'),
));

$opensslPrefix = Utils::findPrefix(array(
new BrewPrefixFinder('openssl'),
new PkgConfigPrefixFinder('openssl'),
new IncludePrefixFinder('openssl/opensslv.h'),
));

return $params->withOption('--with-imap', $imapPrefix)
->withOptionOrPkgConfigPath($build, '--with-kerberos', $kerberosPrefix)
->withOptionOrPkgConfigPath($build, '--with-imap-ssl', $opensslPrefix);
};

$this->variants['ldap'] = function (ConfigureParameters $params, Build $_, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('ldap.h'),
new BrewPrefixFinder('openldap'),
));

if ($prefix !== null) {
$params = $params->withOption('--with-ldap', $prefix);
}

return $params;
};

$this->variants['tidy'] = '--with-tidy';
$this->variants['kerberos'] = '--with-kerberos';
$this->variants['xmlrpc'] = '--with-xmlrpc';

$this->variants['fpm'] = function (ConfigureParameters $params) {
$params = $params->withOption('--enable-fpm');

if ($bin = Utils::findBin('systemctl') && Utils::findIncludePrefix('systemd/sd-daemon.h')) {
$params = $params->withOption('--with-fpm-systemd');
}

return $params;
};

$this->variants['dtrace'] = function (ConfigureParameters $params) {
return $params->withOption('--enable-dtrace');
};

$this->variants['pcre'] = function (ConfigureParameters $params, Build $build, $value) {
if ($build->compareVersion('7.4') >= 0) {
return $params;
}

$params = $params->withOption('--with-pcre-regex');

$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('pcre.h'),
new BrewPrefixFinder('pcre'),
));

if ($prefix !== null) {
$params = $params->withOption('--with-pcre-dir', $prefix);
}

return $params;
};

$this->variants['mhash'] = function (ConfigureParameters $params, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('mhash.h'),
new BrewPrefixFinder('mhash'),
));

return $params->withOption('--with-mhash', $prefix);
};

$this->variants['mcrypt'] = function (ConfigureParameters $params, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('mcrypt.h'),
new BrewPrefixFinder('mcrypt'),
));

return $params->withOption('--with-mcrypt', $prefix);
};

$this->variants['zlib'] = function (ConfigureParameters $params, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('zlib'),
new IncludePrefixFinder('zlib.h'),
));

return $params->withOptionOrPkgConfigPath($build, '--with-zlib', $prefix);
};

$this->variants['curl'] = function (ConfigureParameters $params, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('curl'),
new PkgConfigPrefixFinder('libcurl'),
new IncludePrefixFinder('curl/curl.h'),
));

return $params->withOptionOrPkgConfigPath($build, '--with-curl', $prefix);
};
















$this->variants['readline'] = function (ConfigureParameters $params, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('readline'),
new IncludePrefixFinder('readline/readline.h'),
));

return $params->withOption('--with-readline', $prefix);
};








$this->variants['editline'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('editline/readline.h'),
new BrewPrefixFinder('libedit'),
));

return $parameters->withOption('--with-libedit', $prefix);
};



















$this->variants['gd'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('gd.h'),
new BrewPrefixFinder('gd'),
));

if ($build->compareVersion('7.4') < 0) {
$option = '--with-gd';
} else {
$option = '--enable-gd';
}

$value = 'shared';

if ($prefix !== null) {
$value .= ',' . $prefix;
}

$parameters = $parameters->withOption($option, $value);

if ($build->compareVersion('5.5') < 0) {
$parameters = $parameters->withOption('--enable-gd-native-ttf');
}

if (
($prefix = Utils::findPrefix(array(
new IncludePrefixFinder('jpeglib.h'),
new BrewPrefixFinder('libjpeg'),
))) !== null
) {
if ($build->compareVersion('7.4') < 0) {
$option = '--with-jpeg-dir';
} else {
$option = '--with-jpeg';
}

$parameters = $parameters->withOption($option, $prefix);
}

if (
$build->compareVersion('7.4') < 0 && ($prefix = Utils::findPrefix(array(
new IncludePrefixFinder('png.h'),
new IncludePrefixFinder('libpng12/pngconf.h'),
new BrewPrefixFinder('libpng'),
))) !== null
) {
$parameters = $parameters->withOption('--with-png-dir', $prefix);
}






if (
($prefix = Utils::findPrefix(array(
new IncludePrefixFinder('freetype2/freetype.h'),
new IncludePrefixFinder('freetype2/freetype/freetype.h'),
new BrewPrefixFinder('freetype'),
))) !== null
) {
if ($build->compareVersion('7.4') < 0) {
$option = '--with-freetype-dir';
} else {
$option = '--with-freetype';
}

$parameters = $parameters->withOption($option, $prefix);
}

return $parameters;
};


















$this->variants['intl'] = function (ConfigureParameters $parameters, Build $build) {
$parameters = $parameters->withOption('--enable-intl');

$prefix = Utils::findPrefix(array(
new PkgConfigPrefixFinder('icu-i18n'),
new BrewPrefixFinder('icu4c'),
));

if ($build->compareVersion('7.4') < 0) {
if ($prefix !== null) {
$parameters = $parameters->withOption('--with-icu-dir', $prefix);
}
} else {
if ($prefix !== null) {
$parameters = $parameters->withPkgConfigPath($prefix . '/lib/pkgconfig');
}
}

return $parameters;
};

$this->variants['sodium'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('libsodium'),
new PkgConfigPrefixFinder('libsodium'),
new IncludePrefixFinder('sodium.h'),
new LibPrefixFinder('libsodium.a'),
));

return $parameters->withOption('--with-sodium', $prefix);
};









$this->variants['openssl'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('openssl'),
new PkgConfigPrefixFinder('openssl'),
new IncludePrefixFinder('openssl/opensslv.h'),
));

return $parameters->withOptionOrPkgConfigPath($build, '--with-openssl', $prefix);
};







































$this->variants['mysql'] = function (ConfigureParameters $parameters, Build $build, $value) {
if ($value === null) {
$value = 'mysqlnd';
}

if ($build->compareVersion('7.0') < 0) {
$parameters = $parameters->withOption('--with-mysql', $value);
}

$parameters = $parameters->withOption('--with-mysqli', $value);

if ($build->isEnabledVariant('pdo')) {
$parameters = $parameters->withOption('--with-pdo-mysql', $value);
}

$foundSock = false;
if ($bin = Utils::findBin('mysql_config')) {
if ($output = exec_line("$bin --socket")) {
$foundSock = true;
$parameters = $parameters->withOption('--with-mysql-sock', $output);
}
}

if (!$foundSock) {
$possiblePaths = array(

'/opt/local/var/run/mysql57/mysqld.sock',
'/opt/local/var/run/mysql56/mysqld.sock',
'/opt/local/var/run/mysql55/mysqld.sock',
'/opt/local/var/run/mysql54/mysqld.sock',

'/tmp/mysql.sock', 
'/var/run/mysqld/mysqld.sock', 
'/var/mysql/mysql.sock',
);

foreach ($possiblePaths as $path) {
if (file_exists($path)) {
$parameters = $parameters->withOption('--with-mysql-sock', $path);
break;
}
}
}

return $parameters;
};

$this->variants['sqlite'] = function (ConfigureParameters $parameters, Build $build, $value) {
$parameters = $parameters->withOption('--with-sqlite3', $value);

if ($build->isEnabledVariant('pdo')) {
$parameters = $parameters->withOption('--with-pdo-sqlite', $value);
}

return $parameters;
};




$this->variants['pgsql'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new ExecutablePrefixFinder('pg_config'),
new BrewPrefixFinder('libpq'),
));

$parameters = $parameters->withOption('--with-pgsql', $prefix);

if ($build->isEnabledVariant('pdo')) {
$parameters = $parameters->withOption('--with-pdo-pgsql', $prefix);
}

return $parameters;
};

$this->variants['xml'] = function (ConfigureParameters $parameters, Build $build, $value) {
$parameters = $parameters->withOption('--enable-dom');

$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('libxml2'),
new PkgConfigPrefixFinder('libxml'),
new IncludePrefixFinder('libxml2/libxml/globals.h'),
new LibPrefixFinder('libxml2.a'),
));

if ($build->compareVersion('7.4') < 0) {
$parameters = $parameters->withOption('--enable-libxml');

if ($prefix !== null) {
$parameters = $parameters->withOption('--with-libxml-dir', $prefix);
}
} else {
$parameters = $parameters->withOption('--with-libxml');

if ($prefix !== null) {
$parameters = $parameters->withPkgConfigPath($prefix . '/lib/pkgconfig');
}
}

return $parameters
->withOption('--enable-simplexml')
->withOption('--enable-xml')
->withOption('--enable-xmlreader')
->withOption('--enable-xmlwriter')
->withOption('--with-xsl');
};

$this->variants['apxs2'] = function (ConfigureParameters $parameters, Build $build, $value) {
if ($value) {
return $parameters->withOption('--with-apxs2', $value);
}

if ($bin = Utils::findBinByPrefix('apxs2')) {
return $parameters->withOption('--with-apxs2', $bin);
}

if ($bin = Utils::findBinByPrefix('apxs')) {
return $parameters->withOption('--with-apxs2', $bin);
}


$possiblePaths = array(

'/usr/local/opt/httpd24/bin/apxs',
'/usr/local/opt/httpd23/bin/apxs',
'/usr/local/opt/httpd22/bin/apxs',
'/usr/local/opt/httpd21/bin/apxs',

'/usr/local/sbin/apxs', 
'/usr/local/bin/apxs',
'/usr/sbin/apxs', 
'/usr/bin/apxs', 
);

$path = first_existing_executable($possiblePaths);

return $parameters->withOption('--with-apxs2', $path);
};

$this->variants['gettext'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('libintl.h'),
new BrewPrefixFinder('gettext'),
));

return $parameters->withOption('--with-gettext', $prefix);
};

$this->variants['iconv'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(


new UserProvidedPrefix($value),
new BrewPrefixFinder('libiconv'),
));

return $parameters->withOption('--with-iconv', $prefix);
};

$this->variants['bz2'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new BrewPrefixFinder('bzip2'),
new IncludePrefixFinder('bzlib.h'),
));

return $parameters->withOption('--with-bz2', $prefix);
};

$this->variants['ipc'] = function (ConfigureParameters $parameters, Build $build) {
return $parameters
->withOption('--enable-shmop')
->withOption('--enable-sysvsem')
->withOption('--enable-sysvshm')
->withOption('--enable-sysvmsg');
};

$this->variants['gmp'] = function (ConfigureParameters $parameters, Build $build, $value) {
$prefix = Utils::findPrefix(array(
new UserProvidedPrefix($value),
new IncludePrefixFinder('gmp.h'),
));

return $parameters->withOption('--with-gmp', $prefix);
};

$this->variants['pear'] = function (ConfigureParameters $parameters, Build $build, $value) {
if ($value === null) {
$value = $build->getInstallPrefix() . '/lib/php/pear';
}

return $parameters->withOption('--with-pear', $value);
};


$customVirtualVariants = Config::getConfigParam('variants');
$customVirtualVariantsToAdd = array();

if (!empty($customVirtualVariants)) {
foreach ($customVirtualVariants as $key => $extension) {

if (!empty($extension)) {
$customVirtualVariantsToAdd[$key] = array_keys($extension);
}
}
}

$this->virtualVariants = array_merge($customVirtualVariantsToAdd, $this->virtualVariants);


$this->virtualVariants['everything'] = array_diff(
array_keys($this->variants),
array('apxs2', 'all') 
);
}

private function getConflict(Build $build, $feature)
{
if (isset($this->conflicts[ $feature ])) {
$conflicts = array();

foreach ($this->conflicts[ $feature ] as $f) {
if ($build->isEnabledVariant($f)) {
$conflicts[] = $f;
}
}

return $conflicts;
}

return false;
}

private function checkConflicts(Build $build)
{
if ($build->isEnabledVariant('apxs2') && version_compare($build->getVersion(), '5.4.0') < 0) {
if ($conflicts = $this->getConflict($build, 'apxs2')) {
$msgs = array();
$msgs[] = 'PHP Version lower than 5.4.0 can only build one SAPI at the same time.';
$msgs[] = '+apxs2 is in conflict with ' . implode(',', $conflicts);

foreach ($conflicts as $c) {
$msgs[] = "Disabling $c";
$build->disableVariant($c);
}

echo implode(PHP_EOL, $msgs) . PHP_EOL;
}
}

return true;
}

public function getVariantNames()
{
return array_keys($this->variants);
}











private function buildEnabledVariant(Build $build, $variant, $value, ConfigureParameters $parameters)
{
if (!isset($this->variants[$variant])) {
throw new Exception(sprintf('Variant "%s" is not defined', $variant));
}


if (in_array($variant, $this->builtList)) {
return $parameters;
}


if (isset($this->disables[$variant])) {
return $parameters;
}

$this->builtList[] = $variant;

return $this->buildVariantFromDefinition($build, $this->variants[$variant], $value, $parameters);
}










private function buildDisabledVariant(Build $build, $variant, ConfigureParameters $parameters)
{
if (!isset($this->variants[$variant])) {
throw new Exception(sprintf('Variant "%s" is not defined', $variant));
}


if (in_array('-' . $variant, $this->builtList)) {
return $parameters;
}

$this->builtList[] = '-' . $variant;

$disabledParameters = $this->buildVariantFromDefinition(
$build,
$this->variants[$variant],
null,
new ConfigureParameters()
);

foreach ($disabledParameters->getOptions() as $option => $_) {

$option = preg_replace('/^--enable-/', '--disable-', $option);


$option = preg_replace('/^--with-/', '--without-', $option);

$parameters = $parameters->withOption($option);
}

return $parameters;
}











private function buildVariantFromDefinition(Build $build, $definition, $value, ConfigureParameters $parameters)
{
if (is_string($definition)) {
$parameters = $parameters->withOption($definition);
} elseif (is_array($definition)) {
foreach ($definition as $option => $value) {
$parameters = $parameters->withOption($option, $value);
}
} elseif (is_callable($definition)) {
$parameters = call_user_func_array($definition, array(
$parameters,
$build,
$value,
));
} else {
throw new OopsException();
}

return $parameters;
}










public function build(Build $build, ConfigureParameters $parameters = null)
{
$customVirtualVariants = Config::getConfigParam('variants');
foreach (array_keys($build->getEnabledVariants()) as $variantName) {
if (isset($customVirtualVariants[$variantName])) {
foreach ($customVirtualVariants[$variantName] as $lib => $params) {
if (is_array($params)) {
$this->variants[$lib] = $params;
}
}
}
}

if ($parameters === null) {
$parameters = new ConfigureParameters();
}


$this->builtList = array();


if (!$build->isEnabledVariant('all') && !$build->isEnabledVariant('neutral')) {

$parameters = $parameters
->withOption('--disable-all')
->withOption('--enable-phar')
->withOption('--enable-session')
->withOption('--enable-short-tags')
->withOption('--enable-tokenizer');

if ($build->compareVersion('7.4') < 0) {
$parameters = $parameters->withOption('--with-pcre-regex');
}

if ($value = Utils::findIncludePrefix('zlib.h')) {
$parameters = $parameters->withOption('--with-zlib', $value);
}
}

if ($value = Utils::findLibPrefix('x86_64-linux-gnu')) {
$parameters = $parameters->withOption('--with-libdir', 'lib/x86_64-linux-gnu');
} elseif ($value = Utils::findLibPrefix('i386-linux-gnu')) {
$parameters = $parameters->withOption('--with-libdir', 'lib/i386-linux-gnu');
}

if ($build->compareVersion('5.6') >= 0) {
$build->enableVariant('opcache');
}


foreach ($this->virtualVariants as $name => $variantNames) {
if ($build->isEnabledVariant($name)) {
foreach ($variantNames as $subVariantName) {


if (!$build->isEnabledVariant($subVariantName)) {
$build->enableVariant($subVariantName);
}
}



$build->removeVariant($name);
}
}


$build->resolveVariants();



$this->checkConflicts($build);

foreach ($build->getEnabledVariants() as $variant => $value) {
$parameters = $this->buildEnabledVariant($build, $variant, $value, $parameters);
}

foreach ($build->getDisabledVariants() as $variant => $_) {
$parameters = $this->buildDisabledVariant($build, $variant, $parameters);
}

foreach ($build->getExtraOptions() as $option) {
$parameters = $parameters->withOption($option);
}

return $parameters;
}
}
<?php

namespace PhpBrew;

use Exception;

class InvalidVariantSyntaxException extends Exception
{
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\BuildFinder;
use PhpBrew\CommandBuilder;
use PhpBrew\Config;

class CtagsCommand extends Command
{
public function brief()
{
return 'Run ctags at current php source dir for extension development.';
}

public function arguments($args)
{
$args->add('PHP build')
->validValues(function () {
return BuildFinder::findInstalledBuilds();
})
;
}

public function execute($versionName = null)
{
$args = func_get_args();
array_shift($args);

if ($versionName) {
$sourceDir = Config::getBuildDir() . DIRECTORY_SEPARATOR . $versionName;
} else {
if (!getenv('PHPBREW_PHP')) {
$this->logger->error(<<<EOF
Error: PHPBREW_PHP environment variable is not defined.
  This command requires you specify a PHP version from your build list.
  And it looks like you haven't switched to a version from the builds that were built with PHPBrew.
Suggestion: Please install at least one PHP with your preferred version and switch to it.
EOF
);

return;
}
$sourceDir = Config::getCurrentBuildDir();
}
if (!file_exists($sourceDir)) {
$this->logger->error("$sourceDir does not exist.");

return;
}
$this->logger->info('Scanning ' . $sourceDir);

$cmd = new CommandBuilder('ctags');
$cmd->arg('-R');
$cmd->arg('-a');
$cmd->arg('-h');
$cmd->arg('.c.h.cpp');

$cmd->arg($sourceDir . DIRECTORY_SEPARATOR . 'main');
$cmd->arg($sourceDir . DIRECTORY_SEPARATOR . 'ext');
$cmd->arg($sourceDir . DIRECTORY_SEPARATOR . 'Zend');

foreach ($args as $a) {
$cmd->arg($a);
}

$this->logger->debug($cmd->__toString());
$cmd->execute();

$this->logger->info('Done');
}
}
<?php

namespace PhpBrew\Command;




class OffCommand extends VirtualCommand
{
public function brief()
{
return 'Temporarily go back to the system php';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use GetOptionKit\OptionSpecCollection;
use PhpBrew\Config;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\ReleaseList;
use PhpBrew\Tasks\FetchReleaseListTask;

class KnownCommand extends Command
{
public function brief()
{
return 'List known PHP versions';
}




public function options($opts)
{
$opts->add('m|more', 'Show more older versions');
$opts->add('o|old', 'List old phps (less than 5.3)');
$opts->add('u|update', 'Update release list');

DownloadFactory::addOptionsForCommand($opts);
}

public function execute()
{
$releaseList = new ReleaseList();



if (!$releaseList->foundLocalReleaseList() || $this->options->update || $this->options->old) {
$fetchTask = new FetchReleaseListTask($this->logger, $this->options);
$releases = $fetchTask->fetch();
} else {
$this->logger->info(
sprintf(
'Read local release list (last update: %s UTC).',
gmdate(
'Y-m-d H:i:s',
filectime(Config::getPHPReleaseListPath())
)
)
);
$releases = $releaseList->loadLocalReleaseList();
$this->logger->info(
'You can run `phpbrew update` or `phpbrew known --update` to get a newer release list.'
);
}

foreach ($releases as $majorVersion => $versions) {
if (version_compare($majorVersion, '5.2', 'le') && !$this->options->old) {
continue;
}
$versionList = array_keys($versions);
if (!$this->options->more) {
array_splice($versionList, 8);
}
$this->logger->writeln(
$this->formatter->format("{$majorVersion}: ", 'yellow')
. wordwrap(implode(', ', $versionList), 80, PHP_EOL . str_repeat(' ', 5))
. (!$this->options->more ? ' ...' : '')
);
}

if ($this->options->old) {
$this->logger->warn(
'PHPBrew needs PHP 5.3 or above to run. build/switch to versions below 5.3 at your own risk.'
);
}
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use Exception;




class VirtualCommand extends Command
{



final public function execute()
{
throw new Exception(
"You should not see this. "
. "If you see this, it means you didn't load the ~/.phpbrew/bashrc script. "
. "Please check if bashrc is sourced in your shell."
);
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use CLIFramework\Command;
use GetOptionKit\OptionSpecCollection;
use PhpBrew\Config;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\Extension\ExtensionDownloader;
use PhpBrew\ExtensionList;

class KnownCommand extends Command
{
public function usage()
{
return 'phpbrew [-dv, -r] ext known extension_name';
}

public function brief()
{
return 'List known versions';
}




public function options($opts)
{
DownloadFactory::addOptionsForCommand($opts);
}

public function arguments($args)
{
$args->add('extensions')
->suggestions(function () {
$extdir = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';

return array_filter(
scandir($extdir),
function ($d) use ($extdir) {
return $d != '.' && $d != '..' && is_dir($extdir . DIRECTORY_SEPARATOR . $d);
}
);
});
}

public function execute($extensionName)
{
$extensionList = new ExtensionList($this->logger, $this->options);

$provider = $extensionList->exists($extensionName);

if ($provider) {
$extensionDownloader = new ExtensionDownloader($this->logger, $this->options);
$versionList = $extensionDownloader->knownReleases($provider);
$this->logger->info(PHP_EOL);
$this->logger->writeln(wordwrap(implode(', ', $versionList), 80, PHP_EOL));
} else {
$this->logger->info("Can not determine host or unsupported of $extensionName " . PHP_EOL);
}
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use Exception;
use PhpBrew\Config;
use PhpBrew\Extension\Extension;
use PhpBrew\Extension\ExtensionFactory;
use PhpBrew\Extension\PeclExtension;

class ShowCommand extends BaseCommand
{
public function usage()
{
return 'phpbrew [-dv, -r] ext show [extension name]';
}

public function brief()
{
return 'Show information of a PHP extension';
}

public function options($opts)
{
$opts->add('download', 'Download the extension source if extension not found.');
}

public function arguments($args)
{
$args->add('extension')
->suggestions(function () {
$extdir = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';

return array_filter(
scandir($extdir),
function ($d) use ($extdir) {
return $d != '.' && $d != '..' && is_dir($extdir . DIRECTORY_SEPARATOR . $d);
}
);
});
}

public function describeExtension(Extension $ext)
{
$info = array(
'Name' => $ext->getExtensionName(),
'Source Directory' => $ext->getSourceDirectory(),
'Config' => $ext->getConfigM4Path(),
'INI File' => $ext->getConfigFilePath(),
'Extension' => ($ext instanceof PeclExtension) ? 'Pecl' : 'Core',
'Zend' => $ext->isZend() ? 'yes' : 'no',
'Loaded' => (extension_loaded($ext->getExtensionName())
? $this->formatter->format('yes', 'green')
: $this->formatter->format('no', 'red')),
);

foreach ($info as $label => $val) {
$this->logger->writeln(sprintf('%20s: %s', $label, $val));
}

$options = $ext->getConfigureOptions();
if (!empty($options)) {
$this->logger->newline();
$this->logger->writeln(sprintf('%20s: ', 'Configure Options'));
$this->logger->newline();
foreach ($options as $option) {
$this->logger->writeln(sprintf(
'        %-32s %s',
$option->option . ($option->valueHint ? '[=' . $option->valueHint . ']' : ''),
$option->desc
));
$this->logger->newline();
}
}
}

public function execute($extensionName)
{
$ext = ExtensionFactory::lookup($extensionName);

if (!$ext) {
$ext = ExtensionFactory::lookupRecursive($extensionName);
}


if (!$ext && $this->options->{'download'}) {
$extensionList = new ExtensionList();

$extensionList->initLocalExtensionList($this->logger, $this->options);

$hosting = $extensionList->exists($extensionName);

$downloader = new ExtensionDownloader($this->logger, $this->options);
$extDir = $downloader->download($hosting, 'latest');

$ext = ExtensionFactory::lookupRecursive($extensionName, array($extDir));
}
if (!$ext) {
throw new Exception("$extensionName extension not found.");
}
$this->describeExtension($ext);
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use PhpBrew\Config;
use PhpBrew\Extension\ExtensionFactory;
use PhpBrew\Utils;

class ConfigCommand extends BaseCommand
{
public function usage()
{
return 'phpbrew ext config [--sapi] [extension name]';
}

public function brief()
{
return 'Edit extension-specific configuration file';
}

public function arguments($args)
{
$args->add('extensions')
->suggestions(function () {
return array_map(function ($path) {
return basename(basename($path, '.disabled'), '.ini');
}, glob(Config::getCurrentPhpDir() . '/var/db/*.{ini,disabled}', GLOB_BRACE));
});
}

public function options($opts)
{
$opts->add('s|sapi:=string', 'Edit extension for SAPI name.');
}

public function execute($extensionName)
{
$sapi = null;
if ($this->options->sapi) {
$sapi = $this->options->sapi;
}

$ext = ExtensionFactory::lookup($extensionName);
if (!$ext) {
return $this->error("Extension $extensionName not found.");
}
$file = $ext->getConfigFilePath($sapi);
$this->logger->info("Looking for {$file} file...");
if (!file_exists($file)) {
$file .= '.disabled'; 
$this->logger->info("Looking for {$file} file...");
if (!file_exists($file)) {
$this->logger->warn(
"Sorry, I can't find the ini file for the requested extension: \"{$extensionName}\"."
);

return false;
}
}

return Utils::editor($file) === 0;
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use PhpBrew\Config;
use PhpBrew\Extension\ExtensionFactory;
use PhpBrew\Extension\ExtensionManager;

class CleanCommand extends BaseCommand
{
public function brief()
{
return 'Clean up the compiled objects in the extension source directory.';
}

public function options($opts)
{
$opts->add('p|purge', 'Remove all the source files.');
}

public function arguments($args)
{
$args->add('extensions')
->suggestions(function () {
$extdir = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';

return array_filter(
scandir($extdir),
function ($d) use ($extdir) {
return $d != '.' && $d != '..' && is_dir($extdir . DIRECTORY_SEPARATOR . $d);
}
);
});
}

public function execute($extensionName)
{
if ($ext = ExtensionFactory::lookup($extensionName)) {
$this->logger->info("Cleaning $extensionName...");
$manager = new ExtensionManager($this->logger);

if ($this->options->purge) {
$manager->purgeExtension($ext);
} else {
$manager->cleanExtension($ext);
}
$this->logger->info('Done');
}
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use Exception;
use GetOptionKit\OptionSpecCollection;
use PhpBrew\Config;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\Extension\ExtensionDownloader;
use PhpBrew\Extension\ExtensionFactory;
use PhpBrew\Extension\ExtensionManager;
use PhpBrew\ExtensionList;
use PhpBrew\Utils;

class InstallCommand extends BaseCommand
{
public function usage()
{
return 'phpbrew [-dv, -r] ext install [extension name] [-- [options....]]';
}

public function brief()
{
return 'Install PHP extension';
}




public function options($opts)
{
$opts->add('pecl', 'Try to download from PECL even when ext source is bundled with php-src.');
$opts->add('redownload', 'Force to redownload extension source even if it is already available.');

DownloadFactory::addOptionsForCommand($opts);
}

public function arguments($args)
{
$args->add('extensions')
->suggestions(function () {
$extdir = Config::getBuildDir() . '/' . Config::getCurrentPhpName() . '/ext';

return array_filter(
scandir($extdir),
function ($d) use ($extdir) {
return $d != '.' && $d != '..' && is_dir($extdir . DIRECTORY_SEPARATOR . $d);
}
);
});
}

protected function getExtConfig($args)
{
$version = null;
$options = array();

if (count($args) > 0) {
$pos = array_search('--', $args);
if ($pos !== false) {
$options = array_slice($args, $pos + 1);
}

if ($pos === false || $pos == 1) {
$version = $args[0];
}
}

return (object) array(
'version' => $version,
'options' => $options,
);
}

public function prepare()
{
parent::prepare();

$buildDir = Config::getCurrentBuildDir();
$extDir = $buildDir . DIRECTORY_SEPARATOR . 'ext';
if (!is_dir($extDir)) {
$this->logger->error("Error: The ext directory '$extDir' does not exist.");
$this->logger->error(
"It looks like you don't have the PHP source in $buildDir or you didn't extract the tarball."
);
$this->logger->error(
'Suggestion: Please install at least one PHP with your prefered version and switch to it.'
);

return false;
}

return true;
}

public function execute($extName, $version = 'stable')
{
if (strtolower($extName) === 'apc' && version_compare(PHP_VERSION, '5.6.0') > 0) {
$this->logger->warn('apc is not compatible with php 5.6+ versions, install apcu instead.');
}


if (
(preg_match('#^git://#', $extName) || preg_match('#\.git$#', $extName))
&& !preg_match('#github|bitbucket#', $extName)
) {
$pathinfo = pathinfo($extName);
$repoUrl = $extName;
$extName = $pathinfo['filename'];
$extDir = Config::getBuildDir()
. DIRECTORY_SEPARATOR
. Config::getCurrentPhpName()
. DIRECTORY_SEPARATOR
. 'ext'
. DIRECTORY_SEPARATOR
. $extName;

if (!file_exists($extDir)) {
passthru("git clone $repoUrl $extDir", $ret);
if ($ret != 0) {
$this->logger->error('Clone failed.');

return;
}
}
}


$extensions = array();
if (substr($extName, 0, 1) === '+') {
$config = Config::getConfigParam('extensions');
$extName = ltrim($extName, '+');
if (isset($config[$extName])) {
foreach ($config[$extName] as $extensionName => $extOptions) {
$args = explode(' ', $extOptions);
$extensions[$extensionName] = $this->getExtConfig($args);
}
} else {
$this->logger->info('Extension set name not found. Have you configured it at the config.yaml file?');
}
} else {
$args = array_slice(func_get_args(), 1);
$extensions[$extName] = $this->getExtConfig($args);
}

$extensionList = new ExtensionList($this->logger, $this->options);

$manager = new ExtensionManager($this->logger);
foreach ($extensions as $extensionName => $extConfig) {
$provider = $extensionList->exists($extensionName);

if (!$provider) {
throw new Exception("Could not find provider for $extensionName.");
}

$extensionName = $provider->getPackageName();
$ext = ExtensionFactory::lookupRecursive($extensionName);

$always_redownload =
$this->options->{'pecl'} || $this->options->{'redownload'} || (!$provider->isBundled($extensionName));


if (!$ext || $always_redownload) {
if (empty($extConfig->version)) {
$extConfig->version = $provider->getDefaultVersion();
}

$extensionDownloader = new ExtensionDownloader($this->logger, $this->options);

$extensionDownloader->download($provider, $extConfig->version);


if ($provider->shouldLookupRecursive()) {
$ext = ExtensionFactory::lookupRecursive($extensionName);
} else {
$ext = ExtensionFactory::lookup($extensionName);
}

if ($ext) {
$extensionDownloader->renameSourceDirectory($ext);
}
}
if (!$ext) {
throw new Exception("$extensionName not found.");
}
$manager->installExtension($ext, $extConfig->options);
}
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use PhpBrew\Config;
use PhpBrew\Extension\ExtensionManager;

class DisableCommand extends BaseCommand
{
public function usage()
{
return 'phpbrew ext disable [extension name]';
}

public function brief()
{
return 'Disable PHP extension';
}

public function options($opts)
{
$opts->add('s|sapi:=string', 'Disable extension for SAPI name.');
}

public function arguments($args)
{
$args->add('extensions')
->suggestions(function () {
$extension = '.ini';

return array_map(function ($path) use ($extension) {
return basename($path, $extension);
}, glob(Config::getCurrentPhpDir() . "/var/db/*{$extension}"));
});
}

public function execute($extensionName)
{
$sapi = null;
if ($this->options->sapi) {
$sapi = $this->options->sapi;
}
$manager = new ExtensionManager($this->logger);
$manager->disable($extensionName, $sapi);
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use PhpBrew\Config;
use PhpBrew\Extension\ExtensionManager;

class EnableCommand extends BaseCommand
{
public function usage()
{
return 'phpbrew ext enable [extension name]';
}

public function brief()
{
return 'Enable PHP extension';
}

public function options($opts)
{
$opts->add('s|sapi:=string', 'Enable extension for SAPI name.');
}

public function arguments($args)
{
$args->add('extensions')
->suggestions(function () {
$extension = '.ini.disabled';

return array_map(function ($path) use ($extension) {
return basename($path, $extension);
}, glob(Config::getCurrentPhpDir() . "/var/db/*{$extension}"));
});
}

public function execute($extensionName)
{
$sapi = null;
if ($this->options->sapi) {
$sapi = $this->options->sapi;
}
$manager = new ExtensionManager($this->logger);
$manager->enable($extensionName, $sapi);
}
}
<?php

namespace PhpBrew\Command\ExtensionCommand;

use CLIFramework\Command;

abstract class BaseCommand extends Command
{
public function prepare()
{
parent::prepare();
if (!getenv('PHPBREW_PHP')) {
$this->logger->error(<<<EOF
Error: PHPBREW_PHP environment variable is not defined.
  This extension command requires you specify a PHP version from your build list.
  And it looks like you haven't switched to a version from the builds that were built with PHPBrew.
Suggestion: Please install at least one PHP with your preferred version and switch to it.
EOF
);

return false;
}

return true;
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;

class ListIniCommand extends Command
{
public function brief()
{
return 'List loaded ini config files.';
}

public function execute()
{
$this->logger->warn(
'The list-ini command is deprecated and will be removed in the future.' . PHP_EOL
. 'Please use `php --ini` instead.'
);

if ($filelist = php_ini_scanned_files()) {
echo "Loaded ini files:" . PHP_EOL;
if (strlen($filelist) > 0) {
$files = explode(',', $filelist);
foreach ($files as $file) {
echo ' - ' . trim($file) . PHP_EOL;
}
}
}
}
}
<?php

namespace PhpBrew\Command;

use PhpBrew\BuildFinder;




class UseCommand extends VirtualCommand
{
public function arguments($args)
{
$args->add('PHP version')
->validValues(function () {
return BuildFinder::findInstalledVersions();
})
;
}

public function brief()
{
return 'Use php, switch version temporarily';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\Config;
use PhpBrew\Utils;

class ConfigCommand extends Command
{
public function usage()
{
return 'phpbrew config [--sapi]';
}

public function brief()
{
return 'Edit your current php.ini in your favorite $EDITOR';
}

public function options($opts)
{
$opts->add('s|sapi:=string', 'Edit php.ini for SAPI name.');
}

public function execute()
{
$sapi = 'cli';
if ($this->options->sapi) {
$sapi = $this->options->sapi;
}

$file = Config::getVersionEtcPath(Config::getCurrentPhpName()) . '/' . $sapi . '/php.ini';

return Utils::editor($file) === 0;
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use Exception;
use PhpBrew\BuildFinder;
use PhpBrew\Config;




class PurgeCommand extends VirtualCommand
{
public function arguments($args)
{
$args->add('PHP build')
->validValues(function () {
return BuildFinder::findInstalledBuilds();
})
->multiple()
;
}

public function brief()
{
return 'Remove installed php version and config files.';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;




class MigratedCommand extends Command
{
public function brief()
{
return 'This command is migrated';
}

public function execute()
{
echo <<<HELP
- `phpbrew install-ext` command is now moved to `phpbrew ext install`
- `phpbrew enable` command is now moved to `phpbrew ext enable`
HELP;
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\Tasks\FetchReleaseListTask;

class UpdateCommand extends Command
{
public function brief()
{
return 'Update PHP release source file';
}

public function options($opts)
{
$opts->add('o|old', 'List versions older than PHP 7.0');

DownloadFactory::addOptionsForCommand($opts);
}

public function execute()
{
$fetchTask = new FetchReleaseListTask($this->logger, $this->options);
$releases = $fetchTask->fetch();

foreach ($releases as $majorVersion => $versions) {
if (version_compare($majorVersion, '5.2', '<=')) {
continue;
}
$versionList = array_keys($versions);
$this->logger->writeln($this->formatter->format("{$majorVersion}: ", 'yellow')
. count($versionList) . ' releases');
}
$this->logger->info('===> Done');
}
}
<?php

namespace PhpBrew\Command;




class SwitchOffCommand extends VirtualCommand
{
public function brief()
{
return 'Definitely go back to the system php';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;

class InfoCommand extends Command
{
public function brief()
{
return 'Show current PHP information';
}

public function usage()
{
return 'phpbrew info';
}

public function execute()
{
$this->logger->warn(
'The info command is deprecated and will be removed in the future.' . PHP_EOL
. 'Please use `php -ini` instead.'
);

echo <<<'EOF'
<?php

echo "Version" . PHP_EOL;
echo 'PHP-', phpversion(), PHP_EOL, PHP_EOL;

echo "Constants", PHP_EOL;
$constants = get_defined_constants();

if (defined('PHP_PREFIX')) {
    echo 'PHP Prefix: ', PHP_PREFIX, PHP_EOL;
}

if (defined('PHP_BINARY')) {
    echo 'PHP Binary: ', PHP_BINARY, PHP_EOL;
}

if (defined('DEFAULT_INCLUDE_PATH')) {
    echo 'PHP Default Include path: ', DEFAULT_INCLUDE_PATH, PHP_EOL;
}

echo 'PHP Include path: ', get_include_path(), PHP_EOL, PHP_EOL;

echo "General Info", PHP_EOL;
phpinfo(INFO_GENERAL);
echo PHP_EOL;

echo "Extensions", PHP_EOL;
$extensions = get_loaded_extensions();
echo implode(', ', $extensions), PHP_EOL;
echo PHP_EOL;

echo "Database Extensions", PHP_EOL;
foreach (
    array_filter(
        $extensions,
        function ($n) {
            return in_array(
                $n,
                array(
                'PDO',
                'pdo_mysql',
                'pdo_pgsql',
                'pdo_sqlite',
                'pgsql',
                'mysqli',
                'mysql',
                'oci8',
                'sqlite3',
                'mysqlnd',
                )
            );
        }
    ) as $extName
) {
    echo $extName, PHP_EOL;
}
EOF;
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command\HelpCommand as BaseHelpCommand;

class HelpCommand extends BaseHelpCommand
{
public function execute()
{
$args = func_get_args();

if (empty($args)) {
$headline = <<<EOS
  ______ _   _ ____________                   
  | ___ \ | | || ___ \ ___ \                  
  | |_/ / |_| || |_/ / |_/ /_ __ _____      __
  |  __/|  _  ||  __/| ___ \ '__/ _ \ \ /\ / /
  | |   | | | || |   | |_/ / | |  __/\ V  V / 
  \_|   \_| |_/\_|   \____/|_|  \___| \_/\_/  
                                            

EOS;
$this->logger->write($this->formatter->format($headline, 'strong_white'));
}


return call_user_func_array(array($this, 'parent::execute'), func_get_args());
}
}
<?php

namespace PhpBrew\Command;





class CdCommand extends VirtualCommand
{
public function brief()
{
return 'Change to directories';
}

public function arguments($args)
{
$args->add('directory')
->isa('string')
->validValues(explode('|', 'var|etc|build|dist'))
;
}

public function usage()
{
return 'phpbrew cd [var|etc|build|dist]';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\Build;
use PhpBrew\BuildFinder;
use PhpBrew\Config;
use PhpBrew\Tasks\MakeTask;
use PhpBrew\Utils;

class CleanCommand extends Command
{
public function brief()
{
return 'Clean up the source directory of a PHP distribution';
}

public function usage()
{
return 'phpbrew clean [-a|--all] [php-version]';
}

public function options($opts)
{
$opts->add('a|all', 'Remove all the files in the source directory of the PHP distribution.');
}

public function arguments($args)
{
$args->add('PHP build')
->validValues(function () {
return BuildFinder::findInstalledBuilds();
})
;
}

public function execute($version)
{
$buildDir = Config::getBuildDir() . DIRECTORY_SEPARATOR . $version;
if ($this->options->all) {
if (!file_exists($buildDir)) {
$this->logger->info('Source directory ' . $buildDir . ' does not exist.');
} else {
$this->logger->info('Source directory ' . $buildDir . ' found, deleting...');
Utils::recursive_unlink($buildDir, $this->logger);
}
} else {
$make = new MakeTask($this->logger);
$make->setQuiet();
$build = new Build($version);
$build->setSourceDirectory($buildDir);
if ($make->clean($build)) {
$this->logger->info('Distribution is cleaned up. Woof! ');
}
}
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command as BaseCommand;
use PhpBrew\BuildFinder;
use PhpBrew\Config;

class EnvCommand extends BaseCommand
{
public function brief()
{
return 'Export environment variables';
}

public function arguments($args)
{
$args->add('PHP build')
->optional()
->validValues(function () {
return BuildFinder::findInstalledBuilds();
})
;
}

public function execute($buildName = null)
{

if (!$buildName) {
$buildName = getenv('PHPBREW_PHP');
}

$this->export('PHPBREW_ROOT', Config::getRoot());
$this->export('PHPBREW_HOME', Config::getHome());

$this->replicate('PHPBREW_LOOKUP_PREFIX');

if ($buildName !== false) {
$targetPhpBinPath = Config::getVersionBinPath($buildName);


if (is_dir($targetPhpBinPath)) {
$this->export('PHPBREW_PHP', $buildName);
$this->export('PHPBREW_PATH', $targetPhpBinPath);
}
}

$this->replicate('PHPBREW_SYSTEM_PHP');

$this->logger->writeln('# Run this command to configure your shell:');
$this->logger->writeln('# eval "$(phpbrew env)"');
}

private function export($varName, $value)
{
$this->logger->writeln(sprintf('export %s=%s', $varName, $value));
}

private function replicate($varName)
{
$value = getenv($varName);

if ($value !== false && $value !== '') {
$this->export($varName, $value);
}
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use Phar;
use PhpBrew\Config;

class InitCommand extends Command
{
public function brief()
{
return 'Initialize phpbrew config file.';
}

public function options($opts)
{
$opts->add(
'c|config:',
'The YAML config file which should be copied into phpbrew home.' .
'The config file is used for creating custom virtual variants. ' .
'For more details, please see https://github.com/phpbrew/phpbrew/wiki/Setting-up-Configuration'
)->isa('file');

$opts->add(
'root:',
'Override the default PHPBREW_ROOT path setting.' .
'This option is usually used to load system-wide build pool. ' .
'e.g. phpbrew init --root=/opt/phpbrew '
)->isa('dir');
}

public function execute()
{

$root = $this->options->root ?: Config::getRoot();
$home = Config::getHome();
$buildDir = Config::getBuildDir();
$buildPrefix = Config::getInstallPrefix();



$this->logger->info("Using root: $root");
if (!file_exists($root)) {
mkdir($root, 0755, true);
}

$paths = array();
$paths[] = $home;
$paths[] = $root;
$paths[] = $buildDir;
$paths[] = $buildPrefix;
foreach ($paths as $p) {
$this->logger->debug("Checking directory $p");
if (!file_exists($p)) {
$this->logger->debug("Creating directory $p");
mkdir($p, 0755, true);
} else {
$this->logger->debug("Directory $p is already created.");
}
}

$this->logger->debug('Creating .metadata_never_index to prevent SpotLight indexing');
$indexFiles = array(
$root . DIRECTORY_SEPARATOR . '.metadata_never_index',
$home . DIRECTORY_SEPARATOR . '.metadata_never_index',
);
foreach ($indexFiles as $indexFile) {
if (!file_exists($indexFile)) {
touch($indexFile); 
}
}

if ($configFile = $this->options->{'config'}) {
if (!file_exists($configFile)) {
$this->logger->error("config file '$configFile' does not exist.");

return;
}
$this->logger->debug("Using yaml config from '$configFile'");
copy($configFile, $root . DIRECTORY_SEPARATOR . 'config.yaml');
}

$this->logger->writeln($this->formatter->format('Initialization successfully finished!', 'strong_green'));
$this->logger->writeln(
$this->formatter->format(
'<=====================================================>',
'strong_white'
)
);


file_put_contents($home . '/bashrc', $this->getBashScriptPath());

file_put_contents($home . '/phpbrew.fish', $this->getFishScriptPath());

if (strpos(getenv('SHELL'), 'fish') !== false) {
$initConfig = <<<EOS
Paste the following line(s) to the end of your ~/.config/fish/config.fish and start a
new shell, phpbrew should be up and fully functional from there:

    source $home/phpbrew.fish
EOS;
} else {
$initConfig = <<<EOS
Paste the following line(s) to the end of your ~/.bashrc and start a
new shell, phpbrew should be up and fully functional from there:

    source $home/bashrc

To enable PHP version info in your shell prompt, please set PHPBREW_SET_PROMPT=1
in your `~/.bashrc` before you source `~/.phpbrew/bashrc`

    export PHPBREW_SET_PROMPT=1

To enable .phpbrewrc file searching, please export the following variable:

    export PHPBREW_RC_ENABLE=1

EOS;
}

echo <<<EOS
Phpbrew environment is initialized, required directories are created under

    $home

$initConfig

For further instructions, simply run `phpbrew` to see the help message.

Enjoy phpbrew at \$HOME!!


EOS;

$this->logger->writeln(
$this->formatter->format(
'<=====================================================>',
'strong_white'
)
);
}

protected function getCurrentShellDirectory()
{
$path = Phar::running();
if ($path) {
$path = $path . DIRECTORY_SEPARATOR . 'shell';
} else {
$path = dirname(dirname(dirname(__DIR__))) . DIRECTORY_SEPARATOR . 'shell';
}

return $path;
}

protected function getBashScriptPath()
{
$path = $this->getCurrentShellDirectory();

return file_get_contents($path . DIRECTORY_SEPARATOR . 'bashrc');
}

protected function getFishScriptPath()
{
$path = $this->getCurrentShellDirectory();

return file_get_contents($path . DIRECTORY_SEPARATOR . 'phpbrew.fish');
}
}
<?php

namespace PhpBrew\Command\FpmCommand;

use PhpBrew\Command\VirtualCommand;

class RestartCommand extends VirtualCommand
{
public function brief()
{
return 'Restart FPM server';
}
}
<?php

namespace PhpBrew\Command\FpmCommand;

use CLIFramework\Command;
use Exception;
use PhpBrew\Config;

class SetupCommand extends Command
{
public function brief()
{
return 'Generate and setup FPM startup config';
}

public function usage()
{
return 'phpbrew fpm setup [--systemctl|--initd|--launchctl] [--stdout] [<build name>]';
}

public function options($opts)
{
$opts->add(
'systemctl',
"Generate systemd service entry. " .
"This option only works for systemd-based Linux. " .
"To use this option, be sure to compile PHP with --with-fpm-systemd option. " .
"Start from 1.22, phpbrew automatically add --with-fpm-systemd when systemd is detected."
);
$opts->add(
'initd',
'Generate init.d script. ' .
'The generated init.d script depends on lsb-base >= 4.0. ' .
'If initctl is based on upstart, the init.d script will not be executed. ' .
'To check, please run /sbin/initctl --version in the command-line.'
);
$opts->add('launchctl', 'Generate plist for launchctl (OS X)');
$opts->add('stdout', 'Print config to STDOUT instead of writing to the file.');
}

public function arguments($args)
{
$args->add('buildName')->optional();
}

public function execute($buildName = null)
{
if (!$buildName) {
$buildName = Config::getCurrentPhpName();
}
if (!$buildName) {
throw new Exception("PHPBREW_PHP is not set. You should provide the build name in the command.");
}

fprintf(
STDERR,
"*WARNING* php-fpm --pid option requires php >= 5.6. "
. "You need to update your php-fpm.conf for the pid file location." . PHP_EOL
);

$root = Config::getRoot();
$fpmBin = "$root/php/$buildName/sbin/php-fpm";

if (!file_exists($fpmBin)) {
throw new Exception("$fpmBin doesn't exist.");
}


if ($this->options->systemctl) {
$content = $this->generateSystemctlService($buildName, $fpmBin);

if ($this->options->stdout) {
echo $content;
return;
}

$file = '/lib/systemd/system/phpbrew-fpm.service';
if (!is_writable(dirname($file))) {
$this->logger->error("$file is not writable.");
return;
}

$this->logger->info("Writing systemctl service entry: $file");
file_put_contents($file, $content);

$this->logger->info("To reload systemctl service:");
$this->logger->info("    systemctl daemon-reload");

$this->logger->info("Ensure that $buildName was built with --fpm-systemd option");
} elseif ($this->options->initd) {
$content = $this->generateInitD($buildName, $fpmBin);

if ($this->options->stdout) {
echo $content;
return;
}

$file = '/etc/init.d/phpbrew-fpm';
if (!is_writable(dirname($file))) {
$this->logger->error("$file is not writable.");
return;
}

$this->logger->info("Writing init.d script: $file");
file_put_contents($file, $content);
chmod($file, 0755); 

$this->logger->info("To setup the startup item, remember to run update-rc.d to link the init script:");
$this->logger->info("    sudo update-rc.d phpbrew-fpm defaults");
} elseif ($this->options->launchctl) {
$content = $this->generateLaunchctlService($buildName, $fpmBin);

if ($this->options->stdout) {
echo $content;
return;
}

$file = '/Library/LaunchDaemons/org.phpbrew.fpm.plist';
if (!is_writable(dirname($file))) {
$this->logger->error("$file is not writable.");
return;
}

$this->logger->info("Writing launchctl plist file: $file");
file_put_contents($file, $content);

$this->logger->info("To load the service:");
$this->logger->info("    sudo launchctl load $file");
} else {
$this->logger->info(
'Please use one of the options [--systemctl, --initd, --launchctl] to setup system fpm service.'
);
}
}

protected function generateLaunchctlService($buildName, $fpmBin)
{
$root = Config::getRoot();
$phpdir = "$root/php/$buildName";
$config = <<<"EOS"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>org.phpbrew.fpm</string>
    <key>ProgramArguments</key>
    <array>
        <string>$fpmBin</string>
        <string>--nodaemonize</string>
        <string>--php-ini</string>
        <string>$phpdir/etc/php.ini</string>
        <string>--fpm-config</string>
        <string>$phpdir/etc/php-fpm.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>LaunchOnlyOnce</key>
    <true/>
  </dict>
</plist>
EOS;
return $config;
}


protected function generateSystemctlService($buildName, $fpmBin)
{
$root = Config::getRoot();
$phpdir = "$root/php/$buildName";
$pidFile = $phpdir . '/var/run/php-fpm.pid';
$config = <<<"EOS"
[Unit]
Description=The PHPBrew FastCGI Process Manager
After=network.target

[Service]
Type=notify
PIDFile=$pidFile
ExecStart=$fpmBin --nodaemonize --fpm-config $phpdir/etc/php-fpm.conf --pid $pidFile
ExecReload=/bin/kill -USR2 \$MAINPID

[Install]
WantedBy=multi-user.target
EOS;
return $config;
}


protected function generateInitD($buildName, $fpmBin)
{
$root = Config::getRoot();
$phpdir = "$root/php/$buildName";
$pidFile = $phpdir . '/var/run/php-fpm.pid';
$config = <<<"EOS"
#!/bin/sh
### BEGIN INIT INFO
# Provides:          phpbrew-fpm
# Required-Start:    \$remote_fs \$network
# Required-Stop:     \$remote_fs \$network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts phpbrew-fpm
# Description:       Starts The PHP FastCGI Process Manager Daemon
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="PHPBrew FastCGI Process Manager"
NAME=phpbrew-fpm
PHP_VERSION=$buildName
PHPBREW_ROOT=$root
CONFFILE=$phpdir/etc/php-fpm.conf
DAEMON=$fpmBin
DAEMON_ARGS="--daemonize --fpm-config \$CONFFILE --pid $pidFile"
PIDFILE=$pidFile
TIMEOUT=30
SCRIPTNAME=/etc/init.d/\$NAME

# Exit if the package is not installed
[ -x "\$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/\$NAME ] && . /etc/default/\$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function to check the correctness of the config file
#
do_check()
{
    # FIXME
    # /usr/lib/php/phpbrew-fpm-checkconf || return 1
    return 0
}

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
	start-stop-daemon --start --quiet --pidfile \$PIDFILE --exec \$DAEMON --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile \$PIDFILE --exec \$DAEMON -- \
		\$DAEMON_ARGS 2>/dev/null \
		|| return 2
	# Add code here, if necessary, that waits for the process to be ready
	# to handle requests from services started subsequently which depend
	# on this one.  As a last resort, sleep for some time.
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	start-stop-daemon --stop --quiet --retry=QUIT/\$TIMEOUT/TERM/5/KILL/5 --pidfile \$PIDFILE --name \$NAME
	RETVAL="\$?"
	[ "\$RETVAL" = 2 ] && return 2
	# Wait for children to finish too if this is a daemon that forks
	# and if the daemon is only ever run from this initscript.
	# If the above conditions are not satisfied then add some other code
	# that waits for the process to drop all resources that could be
	# needed by services started subsequently.  A last resort is to
	# sleep for some time.
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/TERM/5/KILL/5 --exec \$DAEMON
	[ "\$?" = 2 ] && return 2
	# Many daemons don't delete their pidfiles when they exit.
	rm -f \$PIDFILE
	return "\$RETVAL"
}

#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
	#
	# If the daemon can reload its configuration without
	# restarting (for example, when it is sent a SIGHUP),
	# then implement that here.
	#
	start-stop-daemon --stop --signal USR2 --quiet --pidfile \$PIDFILE --name \$NAME
	return 0
}

do_tmpfiles() {
    local type path mode user group

    [ "\$1" != no ] && V=-v

    TMPFILES=/usr/lib/tmpfiles.d/phpbrew-fpm.conf

    if [ -r "\$TMPFILES" ]; then
	while read type path mode user group age argument; do
	    if [ "\$type" = "d" ]; then
		mkdir \$V -p "\$path"
		chmod \$V "\$mode" "\$path"
		chown \$V "\$user:\$group" "\$path"
	    fi
	done < "\$TMPFILES"
    fi
}

case "\$1" in
    start)
	if init_is_upstart; then
	    exit 1
	fi
	[ "\$VERBOSE" != no ] && log_daemon_msg "Starting \$DESC" "\$NAME"
	do_tmpfiles \$VERBOSE
	do_check \$VERBOSE
	case "\$?" in
	    0)
		do_start
		case "\$?" in
		    0|1) [ "\$VERBOSE" != no ] && log_end_msg 0 ;;
		    2) [ "\$VERBOSE" != no ] && log_end_msg 1 ;;
		esac
		;;
	    1) [ "\$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
    stop)
	if init_is_upstart; then
	    exit 0
	fi
	[ "\$VERBOSE" != no ] && log_daemon_msg "Stopping \$DESC" "\$NAME"
	do_stop
	case "\$?" in
		0|1) [ "\$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "\$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
    status)
        status_of_proc "\$DAEMON" "\$NAME" && exit 0 || exit \$?
        ;;
    check)
        do_check yes
	;;
    reload|force-reload)
	if init_is_upstart; then
	    exit 1
	fi
    	log_daemon_msg "Reloading \$DESC" "\$NAME"
	do_reload
	log_end_msg \$?
	;;
    reopen-logs)
	log_daemon_msg "Reopening \$DESC logs" \$NAME
	if start-stop-daemon --stop --signal USR1 --oknodo --quiet \
	    --pidfile \$PIDFILE --exec \$DAEMON
	then
	    log_end_msg 0
	else
	    log_end_msg 1
	fi
	;;
    restart)
	if init_is_upstart; then
	    exit 1
	fi
	log_daemon_msg "Restarting \$DESC" "\$NAME"
	do_stop
	case "\$?" in
	  0|1)
		do_start
		case "\$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
	  	# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
    *)
	echo "Usage: \$SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2
	exit 1
    ;;
esac
:
EOS;
return $config;
}
}
<?php

namespace PhpBrew\Command\FpmCommand;

use PhpBrew\Command\VirtualCommand;

class StopCommand extends VirtualCommand
{
public function brief()
{
return 'Stop FPM server';
}
}
<?php

namespace PhpBrew\Command\FpmCommand;

use PhpBrew\Command\VirtualCommand;

class StartCommand extends VirtualCommand
{
public function brief()
{
return 'Start FPM server';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use CLIFramework\ValueCollection;
use Exception;
use GetOptionKit\OptionCollection;
use PhpBrew\Build;
use PhpBrew\Config;
use PhpBrew\ConfigureParameters;
use PhpBrew\Distribution\DistributionUrlPolicy;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\Exception\SystemCommandException;
use PhpBrew\ReleaseList;
use PhpBrew\Tasks\AfterConfigureTask;
use PhpBrew\Tasks\BeforeConfigureTask;
use PhpBrew\Tasks\BuildTask;
use PhpBrew\Tasks\ConfigureTask;
use PhpBrew\Tasks\DownloadTask;
use PhpBrew\Tasks\DSymTask;
use PhpBrew\Tasks\ExtractTask;
use PhpBrew\Tasks\InstallTask;
use PhpBrew\Tasks\MakeTask;
use PhpBrew\Tasks\PrepareDirectoryTask;
use PhpBrew\Tasks\TestTask;
use PhpBrew\VariantBuilder;
use PhpBrew\VariantParser;
use PhpBrew\VersionDslParser;
use SplFileInfo;

class InstallCommand extends Command
{
public function brief()
{
return 'Install php';
}

public function aliases()
{
return array('i', 'ins');
}

public function usage()
{
return 'phpbrew install [php-version] ([+variant...])';
}

public function arguments($args)
{
$args->add('version')->suggestions(function () {
$releaseList = ReleaseList::getReadyInstance();
$releases = $releaseList->getReleases();

$collection = new ValueCollection();
foreach ($releases as $major => $versions) {
$collection->group($major, "PHP $major", array_keys($versions));
}

$collection->group('pseudo', 'pseudo', array('latest', 'next'));

return $collection;
});
$args->add('variants')->multiple()->suggestions(function () {
$variants = new VariantBuilder();
$list = $variants->getVariantNames();
sort($list);

return array_map(function ($n) {
return '+' . $n;
}, $list);
});
}

public function parseSemanticOptions(array &$args)
{
$settings = array();

$definitions = array(
'as' => '*',
'like' => '*',
'using' => '*+',
);


foreach ($definitions as $k => $requirement) {
$idx = array_search($k, $args);

if ($idx !== false) {
if ($requirement == '*') {

list($key, $val) = array_splice($args, $idx, 2);
$settings[$key] = $val;
} elseif ($requirement == '*+') {
$values = array_splice($args, $idx, 2);
$key = array_shift($values);
$settings[$key] = $values;
}
}
}

return $settings;
}




public function options($opts)
{
$opts->add('test', 'Run tests after the installation.');

$opts->add(
'name:',
'The name of the installation. '
. 'By default the installed path is equal to the release version name (php-5.x.x), '
. 'however you can specify a custom name instead of the default `php-5.x.x`. For example, `myphp-5.3.2-dbg`'
)
->valueName('name');

$opts->add('post-clean', 'Run make clean after the installation.');

$opts->add(
'production',
'Use production configuration file. this installer will copy the php-production.ini into the etc directory.'
);

$opts->add('build-dir:', 'Specify the build directory. '
. 'the distribution tarball will be extracted to the directory you specified '
. 'instead of $PHPBREW_ROOT/build/{name}.')
->isa('dir')
;

$opts->add('root', 'Specify PHPBrew root instead of PHPBREW_ROOT');

$opts->add('home', 'Specify PHPBrew home instead of PHPBREW_HOME');

$opts->add('no-config-cache', 'Do not use config.cache for configure script.');

$opts->add('no-clean', 'Do not clean previously compiled objects before building PHP. '
. 'By default phpbrew will run `make clean` before running the configure script '
. 'to ensure everything is cleaned up.')
;

$opts->add('no-patch', 'Do not apply any patch');

$opts->add('no-configure', 'Do not run configure script');

$opts->add('no-install', 'Do not install, just run build the target');

$opts->add(
'n|nice:',
'Runs build processes at an altered scheduling priority. '
. 'The priority can be adjusted over a range of -20 (the highest) to 20 (the lowest).'
)
->valueName('priority');

$opts->add('patch+:', 'Apply patch before build.')
->isa('file');

$opts->add('old', 'Install phpbrew incompatible phps (< 5.3)');

$opts->add('user-config', 'Allow users create their own config file (php.ini or extension config init files)');

DownloadFactory::addOptionsForCommand($opts);

$opts->add('f|force', 'Force the installation (redownloads source).')
->defaultValue(false)
;

$opts->add('d|dryrun', 'Do not build, but run through all the tasks.');

$opts->add(
'like:',
'Inherit variants from an existing build. '
. 'This option would require an existing build directory from the {version}.'
)
->valueName('version');

$opts->add('j|jobs:', 'Specifies the number of jobs to run build simultaneously (make -jN).')
->valueName('concurrent job number')
;
$opts->add('stdout', 'Outputs install logs to stdout.');

$opts->add('sudo', 'sudo to run install command.');
}

public function execute($version)
{
if (extension_loaded('posix') && posix_getuid() === 0) {
$this->logger->warn(
"*WARNING* You're running phpbrew as root/sudo. Unless you're going to install "
. "system-wide phpbrew, this might cause problems."
);
sleep(3);
}
$distUrl = null;
$versionInfo = array();
$releaseList = ReleaseList::getReadyInstance($this->options);
$versionDslParser = new VersionDslParser();
$clean = new MakeTask($this->logger, $this->options);
$clean->setQuiet();

if ($root = $this->options->root) {
Config::setPhpbrewRoot($root);
}
if ($home = $this->options->home) {
Config::setPhpbrewHome($home);
}

if ('latest' === strtolower($version)) {
$version = $releaseList->getLatestVersion();
}


if ('next' === strtolower($version)) {
$version = 'github.com/php/php-src:master';
}

if ($info = $versionDslParser->parse($version)) {
$version = $info['version'];
$distUrl = $info['url'];



$this->options['force']->setValue(
empty($info['is_tag'])
);
} else {

$version = preg_replace('/^php-/', '', $version);
$versionInfo = $releaseList->getVersion($version);
if (!$versionInfo) {
throw new Exception("Version $version not found.");
}
$version = $versionInfo['version'];

$distUrlPolicy = new DistributionUrlPolicy();
$distUrl = $distUrlPolicy->buildUrl($version, $versionInfo['filename'], $versionInfo['museum']);
}



$args = func_get_args();
array_shift($args); 

$semanticOptions = $this->parseSemanticOptions($args);
$buildAs = isset($semanticOptions['as']) ? $semanticOptions['as'] : $this->options->name;
$buildLike = isset($semanticOptions['like']) ? $semanticOptions['like'] : $this->options->like;


if ($this->options->patch) {
$patchPaths = array();
foreach ($this->options->patch as $patch) {

$patchPath = realpath($patch);
if ($patchPath !== false) {
$patchPaths[(string) $patch] = $patchPath;
}
}

$this->options->keys['patch']->value = $patchPaths;
}


$build = new Build($version, $buildAs);

$installPrefix = Config::getInstallPrefix() . DIRECTORY_SEPARATOR . $build->getName();
if (!file_exists($installPrefix)) {
if (!mkdir($installPrefix, 0755, true) && !is_dir($installPrefix)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $installPrefix));
}
}
$build->setInstallPrefix($installPrefix);


if ($buildLike) {
if ($parentBuild = Build::findByName($buildLike)) {
$this->logger->info("===> Loading build settings from $buildLike");
$build->loadVariantInfo($parentBuild->settings->toArray());
}
}

$msg = "===> phpbrew will now build {$build->getVersion()}";
if ($buildLike) {
$msg .= ' using variants from ' . $buildLike;
}
if (isset($semanticOptions['using'])) {
$msg .= ' plus custom variants: ' . implode(', ', $semanticOptions['using']);
$args = array_merge($args, $semanticOptions['using']);
}
if ($buildAs) {
$msg .= ' as ' . $buildAs;
}
$this->logger->info($msg);

if (!empty($args)) {
$this->logger->debug("---> Parsing variants from command arguments '" . implode(' ', $args) . "'");
}




$variantInfo = VariantParser::parseCommandArguments($args);
$build->loadVariantInfo($variantInfo); 


if (!$variantInfo['enabled_variants']) {
$build->settings->enableVariant('default');
$this->logger->notice(
"You haven't enabled any variants. The default variant will be enabled: "
);
$builder = new VariantBuilder();
$this->logger->notice('[' . implode(', ', $builder->virtualVariants['default']) . ']');
$this->logger->notice("Please run 'phpbrew variants' for more information." . PHP_EOL);
}

if (preg_match('/5\.3\./', $version)) {
$this->logger->notice('PHP 5.3 requires +intl, enabled by default.');
$build->enableVariant('intl');
}



if (!in_array('--without-pear', $variantInfo['extra_options'])) {
$build->enableVariant('xml');
}

$this->logger->info('===> Loading and resolving variants...');
$build->loadVariantInfo($variantInfo);

$prepareTask = new PrepareDirectoryTask($this->logger, $this->options);
$prepareTask->run($build);


$buildDir = $this->options->{'build-dir'} ?: Config::getBuildDir();
if (!file_exists($buildDir)) {
if (!mkdir($buildDir, 0755, true) && !is_dir($buildDir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $buildDir));
}
}

$parameters = new ConfigureParameters();

if (!$this->options->{'no-config-cache'}) {
$parameters = $parameters->withOption('--cache-file', Config::getCacheDir() . '/config.cache');
}

$prefix = $build->getInstallPrefix();

$parameters = $parameters
->withOption('--prefix', $prefix);



if ($build->compareVersion('5.4') == -1) {

$parameters = $parameters
->withOption('--enable-sqlite-utf8')
->withOption('--enable-zend-multibyte');
} elseif ($build->compareVersion('5.6') == -1) {
$parameters = $parameters->withOption('--enable-zend-signals');
}

$variantBuilder = new VariantBuilder();
$parameters = $variantBuilder->build($build, $parameters);

$pkgConfigPaths = getenv('PKG_CONFIG_PATH');
if ($pkgConfigPaths !== '' && $pkgConfigPaths !== false) {
foreach (explode(PATH_SEPARATOR, $pkgConfigPaths) as $pkgConfigPath) {
$parameters = $parameters->withPkgConfigPath($pkgConfigPath);
}
}

$distFileDir = Config::getDistFileDir();

$downloadTask = new DownloadTask($this->logger, $this->options);
$algo = 'md5';
$hash = null;
if (isset($versionInfo['sha256'])) {
$algo = 'sha256';
$hash = $versionInfo['sha256'];
} elseif (isset($versionInfo['md5'])) {
$algo = 'md5';
$hash = $versionInfo['md5'];
}
$targetFilePath = $downloadTask->download($distUrl, $distFileDir, $algo, $hash);
if (!file_exists($targetFilePath)) {
throw new SystemCommandException("Download failed, $targetFilePath does not exist.", $build);
}
unset($downloadTask);

$extractTask = new ExtractTask($this->logger, $this->options);
$targetDir = $extractTask->extract($build, $targetFilePath, $buildDir);
if (!file_exists($targetDir)) {
throw new SystemCommandException("Extract failed, $targetDir does not exist.", $build);
}
unset($extractTask);


$this->logger->debug('Source Directory: ' . realpath($targetDir));
$build->setSourceDirectory($targetDir);

if (!$this->options->{'no-clean'} && file_exists($targetDir . DIRECTORY_SEPARATOR . 'Makefile')) {
if ($build->isEnabledVariant('apxs2') || $build->isEnabledVariant('fpm')) {
$this->logger->info('You want to build several variants. No clean is not available.');
} else {
$this->logger->info(
'Found existing Makefile, running make clean to ensure everything will be rebuilt.'
);
$this->logger->info(
"You can append --no-clean option after the install command if you don't want to rebuild."
);
$clean->clean($build);
}
}


chdir($targetDir);

$variantInfoFile = $build->getInstallPrefix() . DIRECTORY_SEPARATOR . 'phpbrew.variants';
$this->logger->debug("Writing variant info to $variantInfoFile");
if (false === $build->writeVariantInfoFile($variantInfoFile)) {
$this->logger->warn("Can't store variant info.");
}

$targetPaths = array();
if (!$this->options->{'no-configure'}) {
$options = $parameters->getOptions();

$sapis = array('cli' => array(
'enable' => array('--enable-cli'),
'disable' => array('--disable-cli')
));

if ($build->isEnabledVariant('apxs2')) {
$sapis['apache2'] = array(
'enable' => array('--with-apxs2'),
'disable' => array(),
);
}
if ($build->isEnabledVariant('fpm')) {
$sapis['fpm'] = array(
'enable' => array('--enable-fpm', '--with-fpm-systemd'),
'disable' => array(),
);
}

foreach ($sapis as $sapi => $enableDisable) {
$this->logger->info('Running make clean to ensure everything will be rebuilt.');
$clean->clean($build);

$addedOptions = $removedOptions = array();

foreach ($sapis as $sapiName => $sapiEnableDisable) {
list($addedOptions, $removedOptions) = $this->enableDisable(
$parameters,
$sapiEnableDisable,
$sapiName === $sapi,
$options
);
}

$parameters = $parameters
->withOption('--with-config-file-path', $prefix . '/etc/' . $sapi)
->withOption('--with-config-file-scan-dir', $prefix . '/var/db/' . $sapi);

$this->build($build, $parameters);

foreach ($addedOptions as $addedOption) {
$parameters = $parameters->withoutOption($addedOption);
}
foreach ($removedOptions as $removedOption) {
$parameters = $parameters->withOption(
$removedOption,
array_key_exists($removedOption, $options) ? $options[$removedOption] : null
);
}

{
$buildTask = new BuildTask($this->logger, $this->options);
$buildTask->run($build);
unset($buildTask); 
}

if ($this->options->{'test'}) {
$testTask = new TestTask($this->logger, $this->options);
$testTask->run($build);
unset($testTask); 
}

if (!$this->options->{'no-install'}) {
$installTask = new InstallTask($this->logger, $this->options);
$installTask->install($build);
unset($installTask); 
}

if ($this->options->{'post-clean'}) {
$clean->clean($build);
}


{
$dsym = new DSymTask($this->logger, $this->options);
$dsym->patch($build, $this->options);
}

$etcDirectory = $build->getEtcDirectory();

if ('fpm' === $sapi) {

$this->logger->info('---> Creating php-fpm.conf');
$fpmUnixSocket = $build->getInstallPrefix() . "/var/run/php-fpm.sock";
$this->installAs("$etcDirectory/php-fpm.conf.default", "$etcDirectory/php-fpm.conf");
$this->installAs("$etcDirectory/php-fpm.d/www.conf.default", "$etcDirectory/php-fpm.d/www.conf");

$patchingFiles = array("$etcDirectory/php-fpm.d/www.conf", "$etcDirectory/php-fpm.conf");
foreach ($patchingFiles as $patchingFile) {
if (file_exists($patchingFile)) {
$this->logger->info("---> Found $patchingFile");






$ini = file_get_contents($patchingFile);
$this->logger->info("---> Patching default fpm pool listen path to $fpmUnixSocket");
$ini = preg_replace('/^listen = .*$/m', "listen = $fpmUnixSocket" . PHP_EOL, $ini);
file_put_contents($patchingFile, $ini);
break;
}
}
}


$this->logger->info('---> Creating php.ini');
$phpConfigPath = $build->getSourceDirectory()
. DIRECTORY_SEPARATOR . ($this->options->production ? 'php.ini-production' : 'php.ini-development');
$this->logger->info("---> Copying $phpConfigPath ");

if (file_exists($phpConfigPath) && !$this->options->dryrun) {
$targetConfigPath = $this->makeIniFile($build, $etcDirectory, $phpConfigPath, $sapi);
$targetPaths[] = '    ' . $targetConfigPath;
}
}
}

if ($build->isEnabledVariant('pear')) {
$this->logger->info('Initializing pear config...');
$home = Config::getHome();

@mkdir("$home/tmp/pear/temp", 0755, true);
@mkdir("$home/tmp/pear/cache_dir", 0755, true);
@mkdir("$home/tmp/pear/download_dir", 0755, true);

system("pear config-set temp_dir $home/tmp/pear/temp");
system("pear config-set cache_dir $home/tmp/pear/cache_dir");
system("pear config-set download_dir $home/tmp/pear/download_dir");

$this->logger->info('Enabling pear auto-discover...');
system('pear config-set auto_discover 1');
}

$this->logger->debug('Source directory: ' . $targetDir);

$buildName = $build->getName();

$this->logger->info("Congratulations! Now you have PHP with $version as $buildName");

if ($build->isEnabledVariant('pdo') && $build->isEnabledVariant('mysql')) {
echo <<<EOT

* We found that you enabled 'mysql' variant, you might need to setup your
  'pdo_mysql.default_socket' or 'mysqli.default_socket' in your php.ini file.

EOT;
}

if (count($targetPaths)) {
$targetConfigPaths = implode(PHP_EOL, $targetPaths);

echo <<<EOT

* To configure your installed PHP further, you can edit the config file(s) at
$targetConfigPaths

EOT;
}



if (!file_exists(Config::getHome() . DIRECTORY_SEPARATOR . 'bashrc')) {
echo <<<EOT

* WARNING:
  You haven't run 'phpbrew init' yet! Be sure to setup your phpbrew to use your own php(s)
  Please run 'phpbrew init' to setup your phpbrew in place.

EOT;
}



if (!getenv('PHPBREW_HOME')) {
echo <<<EOT

* WARNING:
  You haven't setup your .bashrc file to load phpbrew shell script yet!
  Please run 'phpbrew init' to see the steps!

EOT;
}

echo <<<EOT

To use the newly built PHP, try the line(s) below:

    $ phpbrew use $buildName

Or you can use switch command to switch your default php to $buildName:

    $ phpbrew switch $buildName

Enjoy!

EOT;
}


protected function installAs($source, $target, $override = false)
{
if (file_exists($source)) {
if ($override || !file_exists($target)) {
return copy($source, $target);
} else {
$this->logger->notice("Found existing $target.");
return false;
}
}
}








private function makeIniFile(Build $build, $etcDirectory, $phpConfigPath, $sapi)
{
$sapiEtcDirectory = $etcDirectory . DIRECTORY_SEPARATOR . $sapi;
if (!is_dir($sapiEtcDirectory) && mkdir($sapiEtcDirectory) && !is_dir($sapiEtcDirectory)) {
$this->logger->error("Can't create config directory " . $sapiEtcDirectory);
}
$extensionsConfig = $etcDirectory . '/../var/db/' . $sapi;
if (!is_dir($extensionsConfig) && mkdir($extensionsConfig, 0777, true) && !is_dir($extensionsConfig)) {
$this->logger->error("Can't create config directory " . $sapiEtcDirectory);
}

$targetConfigPath = $sapiEtcDirectory . DIRECTORY_SEPARATOR . 'php.ini';

if (file_exists($targetConfigPath)) {
$this->logger->notice("Found existing $targetConfigPath.");
} else {


copy($phpConfigPath, $targetConfigPath);
}

if (!$this->options->{'no-patch'}) {
$config = parse_ini_file($targetConfigPath, true);
$configContent = file_get_contents($targetConfigPath);

if (!isset($config['date']['timezone'])) {
$this->logger->info('---> Found date.timezone is not set, patching...');


if ($timezone = ini_get('date.timezone')) {
$this->logger->info("---> Found date.timezone, patching config timezone with $timezone");
$configContent = preg_replace(
'/^;?date.timezone\s*=\s*.*/im',
"date.timezone = $timezone",
$configContent
);
}
}

if (!isset($config['phar']['readonly'])) {
$pharReadonly = ini_get('phar.readonly');

if (!$pharReadonly) {
$this->logger->info('---> Disabling phar.readonly option.');
$configContent = preg_replace(
'/^;?phar.readonly\s*=\s*.*/im',
'phar.readonly = 0',
$configContent
);
}
}


if ($build->compareVersion('5.4') < 0) {
$this->logger->info("---> Turn off detect_encoding for php 5.3.*");
$configContent = $configContent . PHP_EOL . "detect_unicode = Off" . PHP_EOL;
}

file_put_contents($targetConfigPath, $configContent);
}

return $targetConfigPath;
}

private function build(Build $build, ConfigureParameters $parameters)
{
$configureTask = new BeforeConfigureTask($this->logger, $this->options);
$configureTask->run($build, $parameters);
unset($configureTask); 

$configureTask = new ConfigureTask($this->logger, $this->options);
$configureTask->run($build, $parameters);
unset($configureTask); 

$configureTask = new AfterConfigureTask($this->logger, $this->options);
$configureTask->run($build);
unset($configureTask); 
}









private function enableDisable(&$parameters, $sapiSettings, $currentSapi, $defaults)
{
$addedOptions = $removedOptions = array();

$enableOptions = $currentSapi ? $sapiSettings['enable'] : $sapiSettings['disable'];
$disableOptions = $currentSapi ? $sapiSettings['disable'] : $sapiSettings['enable'];

foreach ($enableOptions as $configOption) {
$addedOptions[] = $configOption;
$parameters = $parameters->withOption(
$configOption,
array_key_exists($configOption, $defaults) ? $defaults[$configOption] : null
);
}

foreach ($disableOptions as $configOption) {
$removedOptions[] = $configOption;
$parameters = $parameters->withoutOption($configOption);
}

return array($addedOptions, $removedOptions);
}
}
<?php

namespace PhpBrew\Command;

use Exception;
use GetOptionKit\OptionCollection;
use PhpBrew\Command\ExtensionCommand\BaseCommand;
use PhpBrew\Config;
use PhpBrew\Extension\Extension;
use PhpBrew\Extension\ExtensionFactory;
use PhpBrew\Extension\M4Extension;

class ExtensionCommand extends BaseCommand
{
public function aliases()
{
return array('ext');
}

public function usage()
{
return 'phpbrew ext [install|enable|disable|config|known]';
}

public function brief()
{
return 'List extensions or execute extension subcommands';
}

public function init()
{
$this->command('enable');
$this->command('install');
$this->command('disable');
$this->command('config');
$this->command('clean');
$this->command('show');
$this->command('known');
}




public function options($opts)
{
$opts->add('so|show-options', 'Show extension configure options');
$opts->add('sp|show-path', 'Show extension config.m4 path');
}

public function describeExtension(Extension $ext)
{
$this->logger->write(sprintf(
' [%s] %-12s %-12s',
extension_loaded($ext->getExtensionName()) ? '*' : ' ',
$ext->getExtensionName(),
phpversion($ext->getExtensionName())
));

if ($this->options->{'show-path'}) {
$this->logger->write(sprintf(' from %s', $ext->getConfigM4Path()));
}
$this->logger->newline();



if ($this->options->{'show-options'}) {
$padding = '     ';
if ($ext instanceof M4Extension) {
$options = $ext->getConfigureOptions();
if (!empty($options)) {
$this->logger->info($padding . 'Configure options:');
foreach ($options as $option) {
$this->logger->info($padding . '  ' . sprintf(
'%-32s %s',
$option->option . ($option->valueHint ? '[=' . $option->valueHint . ']' : ''),
$option->desc
));
}
}
}
}
}

public function execute()
{
$buildDir = Config::getCurrentBuildDir();
$extDir = $buildDir . DIRECTORY_SEPARATOR . 'ext';


$extensions = array();
$extensionNames = array();


$lookupDirectories = array('', 'ext', 'extension');

if (file_exists($extDir) && is_dir($extDir)) {
$this->logger->debug("Scanning $extDir...");
foreach (scandir($extDir) as $extName) {
if ($extName == '.' || $extName == '..') {
continue;
}
$dir = $extDir . DIRECTORY_SEPARATOR . $extName;
foreach ($lookupDirectories as $lookupDirectory) {
$extensionDir = $dir . (empty($lookupDirectory) ? '' : DIRECTORY_SEPARATOR . $lookupDirectory);
if ($m4files = ExtensionFactory::configM4Exists($extensionDir)) {
$this->logger->debug("Loading extension information $extName from $extensionDir");

foreach ($m4files as $m4file) {
try {
$ext = ExtensionFactory::createM4Extension($extName, $m4file);

$extensions[$ext->getExtensionName()] = $ext;
$extensionNames[] = $extName;
break;
} catch (Exception $e) {
}
}

break;
}
}
}
}

$this->logger->info('Loaded extensions:');
foreach ($extensions as $extName => $ext) {
if (extension_loaded($extName)) {
$this->describeExtension($ext);
}
}

$this->logger->info('Available local extensions:');
foreach ($extensions as $extName => $ext) {
if (extension_loaded($extName)) {
continue;
}
$this->describeExtension($ext);
}
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\Config;

class PathCommand extends Command
{
public function brief()
{
return 'Show paths of the current PHP.';
}

public function usage()
{
return 'phpbrew path ['
. implode(', ', array(
'root',
'home',
'build',
'bin',
'include',
'etc',
'ext',
'ext-src',
'extension-src',
'extension-dir',
'config-scan',
'dist'
)) . ']';
}

public function arguments($args)
{
$args->add('type')
->validValues(array(
'root',
'home',
'build',
'bin',
'include',
'etc',
'ext',
'ext-src',
'extension-src',
'extension-dir',
'config-scan',
'dist',
));
}

public function execute($name)
{
switch ($name) {
case 'root':
echo Config::getRoot();
break;
case 'home':
echo Config::getHome();
break;
case 'config-scan':
echo Config::getCurrentPhpConfigScanPath();
break;
case 'dist':
echo Config::getDistFileDir();
break;
case 'build':
echo Config::getCurrentBuildDir();
break;
case 'bin':
echo Config::getCurrentPhpBin();
break;
case 'include':
echo Config::getVersionInstallPrefix(Config::getCurrentPhpName()) .
DIRECTORY_SEPARATOR . 'include';
break;
case 'extension-src':
case 'ext-src':
echo Config::getCurrentBuildDir() . DIRECTORY_SEPARATOR . 'ext';
break;
case 'extension-dir':
case 'ext-dir':
case 'ext':
echo ini_get('extension_dir');
break;
case 'etc':
echo Config::getVersionInstallPrefix(Config::getCurrentPhpName()) .
DIRECTORY_SEPARATOR . 'etc';
break;
}
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\VariantBuilder;

class VariantsCommand extends Command
{
public function brief()
{
return 'List php variants';
}

public function usage()
{
return 'phpbrew variants [php-version]';
}

public function wrapLine($line, $prefix = '  ', $indent = '  ')
{
$lineX = 0;
$newLine = $prefix;

for ($i = 0; $i < strlen($line); $i++ && $lineX++) {
$c = $line[$i];
$newLine .= $c;

if ($lineX > 68 && $c === ' ') {
$newLine .= PHP_EOL . $indent;
$lineX = 0;
}
}

return $newLine;
}

public function execute($version = null)
{
$variants = new VariantBuilder();
$list = $variants->getVariantNames();
sort($list);

echo "Variants: " . PHP_EOL;
echo $this->wrapLine(implode(', ', $list)) , PHP_EOL;
echo PHP_EOL, PHP_EOL;

echo "Virtual variants: ", PHP_EOL;

foreach ($variants->virtualVariants as $name => $subvars) {
echo $this->wrapLine("$name: " . implode(', ', $subvars)) , PHP_EOL;
}

echo PHP_EOL, PHP_EOL;

echo "Using variants to build PHP:", PHP_EOL;
echo PHP_EOL;
echo "  phpbrew install php-5.3.10 +default", PHP_EOL;
echo "  phpbrew install php-5.3.10 +mysql +pdo", PHP_EOL;
echo "  phpbrew install php-5.3.10 +mysql +pdo +apxs2", PHP_EOL;
echo "  phpbrew install php-5.3.10 +mysql +pdo +apxs2=/usr/bin/apxs2", PHP_EOL;
echo PHP_EOL, PHP_EOL;
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use CLIFramework\ValueCollection;
use Exception;
use GetOptionKit\OptionCollection;
use PhpBrew\Config;
use PhpBrew\Distribution\DistributionUrlPolicy;
use PhpBrew\Downloader\DownloadFactory;
use PhpBrew\ReleaseList;
use PhpBrew\Tasks\DownloadTask;
use PhpBrew\Tasks\PrepareDirectoryTask;

class DownloadCommand extends Command
{
public function brief()
{
return 'Download php';
}

public function usage()
{
return 'phpbrew download [php-version]';
}

public function arguments($args)
{
$args->add('version')->suggestions(function () {
$releaseList = ReleaseList::getReadyInstance();
$releases = $releaseList->getReleases();

$collection = new ValueCollection();
foreach ($releases as $major => $versions) {
$collection->group($major, "PHP $major", array_keys($versions));
}

$collection->group('pseudo', 'pseudo', array('latest', 'next'));

return $collection;
});
}




public function options($opts)
{
$opts->add('f|force', 'Force extraction');
$opts->add('old', 'enable old phps (less than 5.3)');

DownloadFactory::addOptionsForCommand($opts);
}

public function execute($version)
{
$version = preg_replace('/^php-/', '', $version);
$releaseList = ReleaseList::getReadyInstance($this->options);
$versionInfo = $releaseList->getVersion($version);
if (!$versionInfo) {
throw new Exception("Version $version not found.");
}
$version = $versionInfo['version'];
$distUrlPolicy = new DistributionUrlPolicy();
$distUrl = $distUrlPolicy->buildUrl($version, $versionInfo['filename'], $versionInfo['museum']);

$prepare = new PrepareDirectoryTask($this->logger, $this->options);
$prepare->run();

$distFileDir = Config::getDistFileDir();

$download = new DownloadTask($this->logger, $this->options);
$algo = 'md5';
$hash = null;
if (isset($versionInfo['sha256'])) {
$algo = 'sha256';
$hash = $versionInfo['sha256'];
} elseif (isset($versionInfo['md5'])) {
$algo = 'md5';
$hash = $versionInfo['md5'];
}
$targetDir = $download->download($distUrl, $distFileDir, $algo, $hash);

if (!file_exists($targetDir)) {
throw new Exception('Download failed.');
}
$this->logger->info("Done, please look at: $targetDir");
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\BuildFinder;

class SystemCommand extends Command
{
public function brief()
{
return 'Get or set the internally used PHP binary';
}

public function arguments($args)
{
$args->add('php version')
->suggestions(function () {
return BuildFinder::findInstalledBuilds();
});
}

final public function execute()
{
$path = getenv('PHPBREW_SYSTEM_PHP');

if ($path !== false && $path !== '') {
$this->logger->writeln($path);
}
}
}
<?php

namespace PhpBrew\Command;




class SystemOffCommand extends VirtualCommand
{
public function brief()
{
return 'Use the currently effective PHP binary internally';
}
}
<?php

namespace PhpBrew\Command;

class EachCommand extends VirtualCommand
{
public function brief()
{
return 'Iterate and run a given shell command over all php versions managed by PHPBrew.';
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use PhpBrew\BuildFinder;
use PhpBrew\Config;
use PhpBrew\VariantParser;

class ListCommand extends Command
{
public function brief()
{
return 'List installed PHPs';
}

public function options($opts)
{
$opts->add('d|dir', 'Show php directories.');
$opts->add('v|variants', 'Show used variants.');
}

public function execute()
{
$builds = BuildFinder::findInstalledBuilds();
$currentBuild = Config::getCurrentPhpName();

if (empty($builds)) {
return $this->logger->notice('Please install at least one PHP with your preferred version.');
}

if ($currentBuild === false or !in_array($currentBuild, $builds)) {
$this->logger->writeln('* (system)');
}

foreach ($builds as $build) {
$versionPrefix = Config::getVersionInstallPrefix($build);

if ($currentBuild === $build) {
$this->logger->writeln(
$this->formatter->format(sprintf('* %-15s', $build), 'bold')
);
} else {
$this->logger->writeln(
$this->formatter->format(sprintf('  %-15s', $build), 'bold')
);
}

if ($this->options->dir) {
$this->logger->writeln(sprintf('    Prefix:   %s', $versionPrefix));
}


if ($this->options->variants && file_exists($versionPrefix . DIRECTORY_SEPARATOR . 'phpbrew.variants')) {
$info = unserialize(file_get_contents($versionPrefix . DIRECTORY_SEPARATOR . 'phpbrew.variants'));
echo '    Variants: ';
echo wordwrap(VariantParser::revealCommandArguments($info), 75, " \\\n              ");
echo PHP_EOL;
}
}
}
}
<?php

namespace PhpBrew\Command;

use CLIFramework\Command;
use Exception;
use GetOptionKit\OptionCollection;
use PhpBrew\Downloader\DownloadFactory;
use RuntimeException;

class SelfUpdateCommand extends Command
{
public function usage()
{
return 'phpbrew self-update [branch-name]';
}

public function brief()
{
return 'Self-update, default to master version';
}




public function options($opts)
{
DownloadFactory::addOptionsForCommand($opts);
}

public function execute()
{
global $argv;
$script = realpath($argv[0]);

if (!is_writable($script)) {
throw new Exception("$script is not writable.");
}


$this->logger->info("Updating phpbrew $script...");
$url = 'https://github.com/phpbrew/phpbrew/releases/latest/download/phpbrew.phar';



$downloader = DownloadFactory::getInstance(
$this->logger,
$this->options,
array(DownloadFactory::METHOD_CURL, DownloadFactory::METHOD_WGET)
);
$tempFile = $downloader->download($url);

if ($tempFile === false) {
throw new RuntimeException('Update Failed', 1);
}
chmod($tempFile, 0755);


if (!$this->checkRequirements($tempFile)) {
unlink($tempFile);

throw new RuntimeException('Update failed');
}


if (!rename($tempFile, $script)) {
throw new RuntimeException('Update Failed', 3);
}

$this->logger->info('Version updated.');
system($script . ' init');
}










private function checkRequirements($binary)
{
system(escapeshellcmd($binary) . ' --version', $code);

return $code === 0;
}
}
<?php

namespace PhpBrew\Command;

use PhpBrew\BuildFinder;




class SwitchCommand extends VirtualCommand
{
public function arguments($args)
{
$args->add('PHP version')
->validValues(function () {
return BuildFinder::findInstalledVersions();
})
;
}

public function brief()
{
return 'Switch default php version.';
}
}
<?php

namespace PhpBrew\Command;




use CLIFramework\Command;
use CLIFramework\Prompter;
use Exception;
use PhpBrew\BuildFinder;
use PhpBrew\Config;
use PhpBrew\Utils;

class RemoveCommand extends Command
{
public function brief()
{
return 'Remove installed php build.';
}

public function arguments($args)
{
$args->add('installed php')
->validValues(function () {
return BuildFinder::findInstalledBuilds();
})
;
}

public function execute($buildName)
{
$prefix = Config::getVersionInstallPrefix($buildName);
if (!file_exists($prefix)) {
throw new Exception("$prefix does not exist.");
}
$prompter = new Prompter();
$answer = $prompter->ask("Are you sure to delete $buildName?", array('Y', 'n'), 'Y');
if (strtolower($answer) == 'y') {
Utils::recursive_unlink($prefix, $this->logger);
$this->logger->info("$buildName is removed.  I hope you're not surprised. :)");
} else {
$this->logger->info('Let me guess, you drunk tonight.');
}
}
}
<?php

namespace PhpBrew\Command;

class FpmCommand extends VirtualCommand
{
public function brief()
{
return 'fpm commands';
}

public function init()
{
parent::init();

$this->command('restart');
$this->command('setup');
$this->command('start');
$this->command('stop');
}
}
<?php

namespace PhpBrew\Downloader;

use RuntimeException;

class PhpStreamDownloader extends BaseDownloader
{
protected function process($url, $targetFilePath)
{
$this->logger->info("Downloading $url via php stream");

$opts = array();
if ($proxy = $this->options->{'http-proxy'}) {
$opts['http']['proxy'] = $proxy;
$opts['http']['request_fulluri'] = true;
$opts['http']['header'] = array();
if ($proxyAuth = $this->options->{'http-proxy-auth'}) {
$opts['http']['header'][] = "Proxy-Authorization: Basic $proxyAuth";
}
}
if ($timeout = $this->options->{'connect-timeout'}) {
$opts['http']['timeout'] = $timeout;
}

if ($this->options->{'continue'}) {
$this->logger->warn('--continue is not support by this download.');
}

if (empty($opts)) {
$binary = file_get_contents($url);
} else {
$context = stream_context_create($opts);
$binary = file_get_contents($url, null, $context);
}
if ($binary === false) {
throw new RuntimeException("Fail to request $url");
}

$res = file_put_contents($targetFilePath, $binary);
if ($res === false) {
throw new RuntimeException("Failed writing to $targetFilePath");
}

return true;
}

public function hasSupport($requireSsl)
{
if (!function_exists('file_get_contents')) {
return false;
}
$wrappers = stream_get_wrappers();
if ($requireSsl) {
return in_array('https', $wrappers);
}

return in_array('http', $wrappers);
}
}
<?php

namespace PhpBrew\Downloader;

use CLIFramework\Logger;
use GetOptionKit\OptionResult;
use RuntimeException;

abstract class BaseDownloader
{
protected $logger;

protected $options;

public function __construct(Logger $logger, OptionResult $options)
{
$this->logger = $logger;
$this->options = $options;
}









public function download($url, $targetFilePath = null)
{
if (empty($targetFilePath)) {
$targetFilePath = tempnam(sys_get_temp_dir(), 'phpbrew_');
if ($targetFilePath === false) {
throw new RuntimeException('Fail to create temp file');
}
} else {
if (!file_exists($targetFilePath)) {
touch($targetFilePath);
}
}
if (!is_writable($targetFilePath)) {
throw new RuntimeException("Target path ($targetFilePath) is not writable!");
}
if ($this->process($url, $targetFilePath)) {
$this->logger->debug("$url => $targetFilePath");

return $targetFilePath;
} else {
return false;
}
}










public function request($url)
{
$path = $this->download($url);

return $path === false ? false : file_get_contents($path);
}

abstract protected function process($url, $targetFilePath);







public function resolveDownloadFileName($url)
{

if (preg_match('/php-\d.+\.tar\.(bz2|gz|xz)/', $url, $parts)) {
return $parts[0];
}


$path = parse_url($url, PHP_URL_PATH);
if (false === $path || false === strpos($path, '.')) {
return;
}

return basename($path);
}

abstract public function hasSupport($requireSsl);
}
<?php

namespace PhpBrew\Downloader;

use CLIFramework\Logger;
use GetOptionKit\OptionCollection;
use GetOptionKit\OptionResult;

class DownloadFactory
{
const METHOD_PHP_CURL = 'php_curl';
const METHOD_PHP_STREAM = 'php_stream';
const METHOD_WGET = 'wget';
const METHOD_CURL = 'curl';

private static $availableDownloaders = array(
self::METHOD_PHP_CURL => 'PhpBrew\Downloader\PhpCurlDownloader',
self::METHOD_PHP_STREAM => 'PhpBrew\Downloader\PhpStreamDownloader',
self::METHOD_WGET => 'PhpBrew\Downloader\WgetCommandDownloader',
self::METHOD_CURL => 'PhpBrew\Downloader\CurlCommandDownloader',
);




private static $fallbackDownloaders = array('curl', 'wget');









protected static function create(Logger $logger, OptionResult $options, array $preferences, $requireSsl = true)
{
foreach ($preferences as $prefKey) {
if (isset(self::$availableDownloaders[$prefKey])) {
$downloader = self::$availableDownloaders[$prefKey];
$down = new $downloader($logger, $options);
if ($down->hasSupport($requireSsl)) {
return $down;
}
}
}

return;
}








public static function getInstance(Logger $logger, OptionResult $options, $downloader = null)
{
if (is_string($downloader)) {

if (class_exists($downloader) && is_subclass_of($downloader, 'PhpBrew\Downloader\BaseDownloader')) {
return new $downloader($logger, $options);
}
$downloader = array($downloader);
}
if (empty($downloader)) {
$downloader = array_keys(self::$availableDownloaders);
}



if ($options->has('downloader')) {
$logger->info("Found --downloader option, try to use {$options->downloader} as default downloader.");
$downloader = array_merge(array($options->downloader), $downloader);
}

$instance = self::create($logger, $options, $downloader);
if ($instance === null) {
$logger->debug('Downloader not found, falling back to command-based downloader.');

return self::create($logger, $options, self::$fallbackDownloaders);
} else {
return $instance;
}
}

public static function addOptionsForCommand(OptionCollection $opts)
{
$opts->add('downloader:', 'Use alternative downloader.');
$opts->add('continue', 'Continue getting a partially downloaded file.');
$opts->add('http-proxy:', 'HTTP proxy address')
->valueName('Proxy host[:port]');
$opts->add('http-proxy-auth:', 'HTTP proxy authentication')
->valueName('Proxy username:password');
$opts->add(
'connect-timeout:',
'Connection timeout'
)
->valueName('Timeout in seconds');

return $opts;
}
}
<?php

namespace PhpBrew\Downloader;

use PhpBrew\Utils;

class CurlCommandDownloader extends BaseDownloader
{
protected function process($url, $targetFilePath)
{
$this->logger->info('downloading via curl command');

$command = array('curl');

if ($proxy = $this->options->{'http-proxy'}) {
$this->logger->warn('http proxy is not support by this download.');
}
if ($proxyAuth = $this->options->{'http-proxy-auth'}) {
$this->logger->warn('http proxy is not support by this download.');
}

if ($this->options->{'continue'}) {
$command[] = '-C -';
}

$command[] = '-L';
if ($this->logger->isQuiet()) {
$command[] = '--silent';
}
$command[] = '-o';
$command[] = escapeshellarg($targetFilePath);
$command[] = escapeshellarg($url);
$cmd = implode(' ', $command);
$this->logger->debug($cmd);
Utils::system($cmd);

return true;
}

public function hasSupport($requireSsl)
{
return Utils::findbin('curl');
}
}
<?php

namespace PhpBrew\Downloader;

use PhpBrew\Utils;
use RuntimeException;

class WgetCommandDownloader extends BaseDownloader
{
protected $enableContinueAt = false;








protected function process($url, $targetFilePath)
{
$this->logger->info("Downloading $url via wget command");

$proxy = '';
if (!empty($this->options->{'http-proxy'})) {
if (!empty($this->options->{'http-proxy-auth'})) {
$proxy = sprintf(
'-e use_proxy=on -e http_proxy=%s@%s',
$this->options->{'http-proxy-auth'},
$this->options->{'http-proxy'}
);
} else {
$proxy = sprintf('-e use_proxy=on -e http_proxy=%s', $this->options->{'http-proxy'});
}
}

$quiet = $this->logger->isQuiet() ? '--quiet' : '';
$continue = $this->enableContinueAt || $this->options->{'continue'} ? '-c' : '';
Utils::system(sprintf(
'wget --no-check-certificate %s %s %s -N -O %s %s',
$continue,
$quiet,
$proxy,
escapeshellarg($targetFilePath),
escapeshellarg($url)
));

return true;
}

public function hasSupport($requireSsl)
{
return Utils::findbin('wget');
}
}
<?php

namespace PhpBrew\Downloader;

use CurlKit\CurlDownloader;
use CurlKit\Progress\ProgressBar;
use RuntimeException;

class PhpCurlDownloader extends BaseDownloader
{
protected function process($url, $targetFilePath)
{
$this->logger->info("Downloading $url via curl extension");

$downloader = new CurlDownloader();

$seconds = $this->options->{'connect-timeout'};
if ($seconds || $seconds = getenv('CONNECT_TIMEOUT')) {
$downloader->setConnectionTimeout($seconds);
}
if ($proxy = $this->options->{'http-proxy'}) {
$downloader->setProxy($proxy);
}
if ($proxyAuth = $this->options->{'http-proxy-auth'}) {
$downloader->setProxyAuth($proxyAuth);
}
if (!$this->options->{'no-progress'} && $this->logger->getLevel() > 2) {
$downloader->setProgressHandler(new ProgressBar());
}
if ($this->options->{'continue'}) {
$this->logger->warn('--continue is not support by this download.');
}
$binary = $downloader->request($url);
if (false === file_put_contents($targetFilePath, $binary)) {
throw new RuntimeException("Can't write file $targetFilePath");
}

return true;
}

public function hasSupport($requireSsl)
{
if (!extension_loaded('curl')) {
return false;
}
if ($requireSsl) {
$info = curl_version();

return in_array('https', $info['protocols']);
}

return true;
}
}
<?php

namespace PhpBrew;

use CLIFramework\Logger;
use GetOptionKit\OptionResult;
use PhpBrew\Extension\Provider\Provider;

class ExtensionList
{
private $logger;
private $options;

public function __construct(Logger $logger, OptionResult $options)
{
$this->logger = $logger;
$this->options = $options;
}






public function getProviders()
{
static $providers;
if ($providers) {
return $providers;
}
$providers = array(
new Extension\Provider\GithubProvider(),
new Extension\Provider\BitbucketProvider(),
new Extension\Provider\PeclProvider($this->logger, $this->options),
);

return $providers;
}







public function exists($extensionName)
{

$providers = $this->getProviders();
foreach ($providers as $provider) {
if ($provider->exists($extensionName)) {
return $provider;
}
}

return null;
}
}
<?php

namespace PhpBrew;

use Exception;

class VersionDslParser
{
protected static $schemes = array(
'git@github.com:',
'github.com:',
'github.com/',
'github:',
);

public function parse($dsl)
{
if (preg_match('/^(php-)?(\d+\.\d+\.\d+(alpha|beta|RC)\d+)$/', $dsl, $matches)) {
$version = 'php-' . $matches[2];

return array(
'version' => $version,
'url' => $this->buildGitHubUrl('php', $version),
'is_tag' => true,
);
}


$url = str_replace(self::$schemes, 'https://github.com/', $dsl);


if (
preg_match(
"#https?://(www\.)?github\.com/([0-9a-zA-Z-._]+)/php-src(@([0-9a-zA-Z-._]+))?#",
$url,
$matches
)
) {
$owner = $matches[2];
$branch = isset($matches[4]) ? $matches[4] : 'master';
$version = preg_replace('/^php-/', '', $branch);

if ($owner !== 'php') {
$version = $owner . '-' . $version;
}

return array(
'version' => 'php-' . $version,
'url' => $this->buildGitHubUrl($owner, $branch),
);
}


if (preg_match('#^https?://#', $url)) {
if (!preg_match('#(php-(\d.\d+.\d+(?:(?:RC|alpha|beta)\d+)?)\.tar\.(?:gz|bz2))#', $url, $matches)) {
throw new Exception("Can not find version name from the given URL: $url");
}

return array(
'version' => "php-{$matches[2]}",
'url' => $url,
);
}

return false;
}









private function buildGitHubUrl($owner, $ref)
{
return sprintf(
'https://github.com/%s/php-src/archive/%s.tar.gz',
rawurlencode($owner),
rawurlencode($ref)
);
}
}
<?php

namespace PhpBrew\Patches;

use CLIFramework\Logger;
use PhpBrew\Buildable;
use PhpBrew\PatchKit\Patch;
use PhpBrew\PatchKit\RegExpPatchRule;

class IntlWith64bitPatch extends Patch
{
public function desc()
{
return 'php5.3.x on 64bit machine when intl is enabled.';
}





































public function match(Buildable $build, Logger $logger)
{
return $build->isEnabledVariant('intl') && version_compare($build->getVersion(), '5.4', '<=');
}

public function rules()
{
$rules = array();
$rules[] = RegExpPatchRule::files('Makefile')
->allOf(array('/^BUILD_/'))
->replaces('/\$\(CC\)/', '$(CXX)');

$rules[] = RegExpPatchRule::files('Makefile')
->allOf(array('/^EXTRA_LIBS =/'))
->replaces('/^(.*)$/', '$1 -lstdc++');

return $rules;
}
}
<?php

namespace PhpBrew\Patches;

use CLIFramework\Logger;
use PhpBrew\Buildable;
use PhpBrew\PatchKit\DiffPatchRule;
use PhpBrew\PatchKit\Patch;






class FreeTypePatch extends Patch
{
public function desc()
{
return 'replace freetype-config with pkg-config on php older than 7.4';
}

public function match(Buildable $build, Logger $logger)
{
return $build->isEnabledVariant('gd') && version_compare($build->getVersion(), '7.4', '<=');
}






public function rules()
{
return array(
DiffPatchRule::fromPatch(
<<<'EOP'
diff -u -r php-7.2.5/ext/gd/config.m4 php-7.2.5-freetype/ext/gd/config.m4
--- php-7.2.5/ext/gd/config.m4	2018-04-24 17:09:54.000000000 +0200
+++ php-7.2.5-freetype/ext/gd/config.m4	2018-05-09 14:49:03.647108948 +0200
@@ -186,6 +186,9 @@
 AC_DEFUN([PHP_GD_FREETYPE2],[
   if test "$PHP_FREETYPE_DIR" != "no"; then
 
+    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+
+    AC_MSG_CHECKING([for freetype])
     for i in $PHP_FREETYPE_DIR /usr/local /usr; do
       if test -f "$i/bin/freetype-config"; then
         FREETYPE2_DIR=$i
@@ -194,13 +197,20 @@
       fi
     done
 
-    if test -z "$FREETYPE2_DIR"; then
+    if test -n "$FREETYPE2_CONFIG"; then
+      FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
+      FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
+      AC_MSG_RESULT([found in $FREETYPE2_DIR])
+    elif test "$PKG_CONFIG" != "no" && $PKG_CONFIG --exists freetype2; then
+      FREETYPE2_DIR=pkg-config
+      FREETYPE2_CFLAGS=`$PKG_CONFIG freetype2 --cflags`
+      FREETYPE2_LIBS=`$PKG_CONFIG freetype2 --libs`
+      AC_MSG_RESULT([found by pkg-config])
+    else
+      AC_MSG_RESULT([not found])
       AC_MSG_ERROR([freetype-config not found.])
     fi
 
-    FREETYPE2_CFLAGS=`$FREETYPE2_CONFIG --cflags`
-    FREETYPE2_LIBS=`$FREETYPE2_CONFIG --libs`
-
     PHP_EVAL_INCLINE($FREETYPE2_CFLAGS)
     PHP_EVAL_LIBLINE($FREETYPE2_LIBS, GD_SHARED_LIBADD)
     AC_DEFINE(HAVE_LIBFREETYPE,1,[ ])
EOP
)->strip(1)
);
}
}
<?php

namespace PhpBrew\Patches;

use CLIFramework\Logger;
use PhpBrew\Buildable;
use PhpBrew\PatchKit\Patch;
use PhpBrew\PatchKit\RegExpPatchRule;

class OpenSSLDSOPatch extends Patch
{
public function desc()
{
return 'openssl dso linking patch';
}

public function match(Buildable $build, Logger $logger)
{
return $build->osName === 'Darwin'
&& version_compare($build->osRelease, '15.0.0') > 0
&& $build->isEnabledVariant('openssl');
}

public function rules()
{









$dylibssl = null;
$dylibcrypto = null;

$paths = array('/opt/local/lib/libssl.dylib',
'/usr/local/opt/openssl/lib/libssl.dylib',
'/usr/local/lib/libssl.dylib', '/usr/lib/libssl.dylib', );
foreach ($paths as $path) {
if (file_exists($path)) {
$dylibssl = $path;
break;
}
}

$paths = array('/opt/local/lib/libcrypto.dylib',
'/usr/local/opt/openssl/lib/libcrypto.dylib',
'/usr/local/lib/libcrypto.dylib', '/usr/lib/libcrypto.dylib', );
foreach ($paths as $path) {
if (file_exists($path)) {
$dylibcrypto = $path;
break;
}
}

$rules = array();
if ($dylibssl) {
$rules[] = RegExpPatchRule::files('Makefile')
->allOf(array('/^EXTRA_LIBS =/'))
->replaces('/-lssl/', $dylibssl);
}
if ($dylibcrypto) {
$rules[] = RegExpPatchRule::files('Makefile')
->allOf(array('/^EXTRA_LIBS =/'))
->replaces('/-lcrypto/', $dylibcrypto);
}

return $rules;
}
}
<?php

namespace PhpBrew\Patches;

use CLIFramework\Logger;
use PhpBrew\Buildable;
use PhpBrew\PatchKit\Patch;
use PhpBrew\PatchKit\RegExpPatchRule;

class Apache2ModuleNamePatch extends Patch
{
private $targetPhpVersion;

public function __construct($targetPhpVersion)
{
$this->targetPhpVersion = $targetPhpVersion;
}

public function desc()
{
return 'replace apache php module name with custom version name';
}

public function match(Buildable $build, Logger $logger)
{
return $build->isEnabledVariant('apxs2');
}

public function rules()
{
$rules = array();














if (version_compare($this->targetPhpVersion, '8.0') < 0) {
$rules[] = RegExpPatchRule::files(array('configure'))
->always()
->replaces(
'#libphp\$PHP_MAJOR_VERSION\.#',
'libphp$PHP_VERSION.'
);


$rules[] = RegExpPatchRule::files(array('configure'))
->always()
->replaces(
'#libs/libphp[57].(so|la)#',
'libs/libphp\$PHP_VERSION.$1'
);
} else {
$rules[] = RegExpPatchRule::files(array('configure'))
->always()
->replaces(
'#libphp.(a|so|la|bundle)#',
'libphp$PHP_VERSION.$1'
);

$rules[] = RegExpPatchRule::files(array('configure'))
->always()
->replaces(
'#libs/libphp.(a|so|la|bundle)#',
'libs/libphp\$PHP_VERSION.$1'
);
$rules[] = RegExpPatchRule::files(array('configure'))
->always()
->replaces(
'#libs/libphp.\$SHLIB_DL_SUFFIX_NAME#',
'libs/libphp\$PHP_VERSION.$SHLIB_DL_SUFFIX_NAME'
);
}

$makefile = 'Makefile.global';

if (version_compare($this->targetPhpVersion, '8.0') >= 0) {
$makefile = 'build/Makefile.global';
$rules[] = RegExpPatchRule::files(array($makefile))
->always()
->replaces(
'#libphp.(a|so|la|bundle)#',
'libphp$(PHP_VERSION).$1'
);

$rules[] = RegExpPatchRule::files(array($makefile))
->always()
->replaces(
'#libphp.\$\(SHLIB_DL_SUFFIX_NAME\)#',
'libphp$(PHP_VERSION).$(SHLIB_DL_SUFFIX_NAME)'
);
}

if (version_compare($this->targetPhpVersion, '7.4') >= 0) {
$makefile = 'build/Makefile.global';
}

$rules[] = RegExpPatchRule::files(array($makefile))
->always()
->replaces(
'#libphp\$\(PHP_MAJOR_VERSION\)#',
'libphp$(PHP_VERSION)'
);

return $rules;
}
}
<?php

namespace PhpBrew\Patches;

use PhpBrew\Buildable;
use PhpBrew\PatchKit\Patch;
use PhpBrew\PatchKit\DiffPatchRule;
use CLIFramework\Logger;

class PHP56WithOpenSSL11Patch extends Patch
{
public function desc()
{
return 'php5.6 with openssl 1.1.x patch.';
}

public function match(Buildable $build, Logger $logger)
{
$buildVersion = $build->getVersion();

return substr($buildVersion, 0, 4) === '5.6.'
&& version_compare($buildVersion, '5.6.31') >= 0 
&& $build->isEnabledVariant('openssl');
}








public function rules()
{
return array(
DiffPatchRule::fromPatch(
<<<'EOP'
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index a78a8fb10f82..6c3ae3cde80a 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -42,6 +42,12 @@
 
 /* OpenSSL includes */
 #include <openssl/evp.h>
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#endif
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/crypto.h>
@@ -531,6 +537,131 @@ zend_module_entry openssl_module_entry = {
 ZEND_GET_MODULE(openssl)
 #endif
 
+/* {{{ OpenSSL compatibility functions and macros */
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
+#define EVP_PKEY_get0_RSA(_pkey) _pkey->pkey.rsa
+#define EVP_PKEY_get0_DH(_pkey) _pkey->pkey.dh
+#define EVP_PKEY_get0_DSA(_pkey) _pkey->pkey.dsa
+#define EVP_PKEY_get0_EC_KEY(_pkey) _pkey->pkey.ec
+
+static int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+	r->n = n;
+	r->e = e;
+	r->d = d;
+
+	return 1;
+}
+
+static int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+	r->p = p;
+	r->q = q;
+
+	return 1;
+}
+
+static int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+	r->dmp1 = dmp1;
+	r->dmq1 = dmq1;
+	r->iqmp = iqmp;
+
+	return 1;
+}
+
+static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+	*n = r->n;
+	*e = r->e;
+	*d = r->d;
+}
+
+static void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+	*p = r->p;
+	*q = r->q;
+}
+
+static void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
+{
+	*dmp1 = r->dmp1;
+	*dmq1 = r->dmq1;
+	*iqmp = r->iqmp;
+}
+
+static void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+	*p = dh->p;
+	*q = dh->q;
+	*g = dh->g;
+}
+
+static int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+	dh->p = p;
+	dh->q = q;
+	dh->g = g;
+
+	return 1;
+}
+
+static void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+	*pub_key = dh->pub_key;
+	*priv_key = dh->priv_key;
+}
+
+static int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+	dh->pub_key = pub_key;
+	dh->priv_key = priv_key;
+
+	return 1;
+}
+
+static void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+	*p = d->p;
+	*q = d->q;
+	*g = d->g;
+}
+
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+	d->p = p;
+	d->q = q;
+	d->g = g;
+
+	return 1;
+}
+
+static void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+	*pub_key = d->pub_key;
+	*priv_key = d->priv_key;
+}
+
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+	d->pub_key = pub_key;
+	d->priv_key = priv_key;
+
+	return 1;
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined (LIBRESSL_VERSION_NUMBER)
+
+static int X509_get_signature_nid(const X509 *x)
+{
+	return OBJ_obj2nid(x->sig_alg->algorithm);
+}
+
+#endif
+
+#endif
+/* }}} */
+
 static int le_key;
 static int le_x509;
 static int le_csr;
@@ -825,7 +956,7 @@ static int add_oid_section(struct php_x509_request * req TSRMLS_DC) /* {{{ */
 	}
 	for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
 		cnf = sk_CONF_VALUE_value(sktmp, i);
-		if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
+		if (OBJ_sn2nid(cnf->name) == NID_undef && OBJ_ln2nid(cnf->name) == NID_undef && OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "problem creating object %s=%s", cnf->name, cnf->value);
 			return FAILURE;
 		}
@@ -967,7 +1098,7 @@ static void php_openssl_dispose_config(struct php_x509_request * req TSRMLS_DC)
 }
 /* }}} */
 
-#ifdef PHP_WIN32
+#if defined(PHP_WIN32) || (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER))
 #define PHP_OPENSSL_RAND_ADD_TIME() ((void) 0)
 #else
 #define PHP_OPENSSL_RAND_ADD_TIME() php_openssl_rand_add_timeval()
@@ -1053,9 +1184,11 @@ static EVP_MD * php_openssl_get_evp_md_from_algo(long algo) { /* {{{ */
 			mdtype = (EVP_MD *) EVP_md2();
 			break;
 #endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
 		case OPENSSL_ALGO_DSS1:
 			mdtype = (EVP_MD *) EVP_dss1();
 			break;
+#endif
 #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
 		case OPENSSL_ALGO_SHA224:
 			mdtype = (EVP_MD *) EVP_sha224();
@@ -1146,6 +1279,12 @@ PHP_MINIT_FUNCTION(openssl)
 	OpenSSL_add_all_digests();
 	OpenSSL_add_all_algorithms();
 
+#if !defined(OPENSSL_NO_AES) && defined(EVP_CIPH_CCM_MODE) && OPENSSL_VERSION_NUMBER < 0x100020000
+	EVP_add_cipher(EVP_aes_128_ccm());
+	EVP_add_cipher(EVP_aes_192_ccm());
+	EVP_add_cipher(EVP_aes_256_ccm());
+#endif
+
 	SSL_load_error_strings();
 
 	/* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
@@ -1173,7 +1312,9 @@ PHP_MINIT_FUNCTION(openssl)
 #ifdef HAVE_OPENSSL_MD2_H
 	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD2", OPENSSL_ALGO_MD2, CONST_CS|CONST_PERSISTENT);
 #endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
 	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_DSS1", OPENSSL_ALGO_DSS1, CONST_CS|CONST_PERSISTENT);
+#endif
 #if OPENSSL_VERSION_NUMBER >= 0x0090708fL
 	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA224", OPENSSL_ALGO_SHA224, CONST_CS|CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA256", OPENSSL_ALGO_SHA256, CONST_CS|CONST_PERSISTENT);
@@ -1251,7 +1392,9 @@ PHP_MINIT_FUNCTION(openssl)
 	}
 
 	php_stream_xport_register("ssl", php_openssl_ssl_socket_factory TSRMLS_CC);
+#ifndef OPENSSL_NO_SSL3
 	php_stream_xport_register("sslv3", php_openssl_ssl_socket_factory TSRMLS_CC);
+#endif
 #ifndef OPENSSL_NO_SSL2
 	php_stream_xport_register("sslv2", php_openssl_ssl_socket_factory TSRMLS_CC);
 #endif
@@ -1308,7 +1451,9 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
 #ifndef OPENSSL_NO_SSL2
 	php_stream_xport_unregister("sslv2" TSRMLS_CC);
 #endif
+#ifndef OPENSSL_NO_SSL3
 	php_stream_xport_unregister("sslv3" TSRMLS_CC);
+#endif
 	php_stream_xport_unregister("tls" TSRMLS_CC);
 	php_stream_xport_unregister("tlsv1.0" TSRMLS_CC);
 #if OPENSSL_VERSION_NUMBER >= 0x10001001L
@@ -1893,6 +2038,7 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
 {
 	GENERAL_NAMES *names;
 	const X509V3_EXT_METHOD *method = NULL;
+	ASN1_OCTET_STRING *extension_data;
 	long i, length, num;
 	const unsigned char *p;
 
@@ -1901,8 +2047,9 @@ static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
 		return -1;
 	}
 
-	p = extension->value->data;
-	length = extension->value->length;
+	extension_data = X509_EXTENSION_get_data(extension);
+	p = extension_data->data;
+	length = extension_data->length;
 	if (method->it) {
 		names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
 						       ASN1_ITEM_ptr(method->it)));
@@ -1965,6 +2112,8 @@ PHP_FUNCTION(openssl_x509_parse)
 	char * tmpstr;
 	zval * subitem;
 	X509_EXTENSION *extension;
+	X509_NAME *subject_name;
+	char *cert_name;
 	char *extname;
 	BIO  *bio_out;
 	BUF_MEM *bio_buf;
@@ -1979,10 +2128,10 @@ PHP_FUNCTION(openssl_x509_parse)
 	}
 	array_init(return_value);
 
-	if (cert->name) {
-		add_assoc_string(return_value, "name", cert->name, 1);
-	}
-/*	add_assoc_bool(return_value, "valid", cert->valid); */
+	subject_name = X509_get_subject_name(cert);
+	cert_name = X509_NAME_oneline(subject_name, NULL, 0);
+	add_assoc_string(return_value, "name", cert_name, 1);
+	OPENSSL_free(cert_name);
 
 	add_assoc_name_entry(return_value, "subject", 		X509_get_subject_name(cert), useshortnames TSRMLS_CC);
 	/* hash as used in CA directories to lookup cert by subject name */
@@ -2008,7 +2157,7 @@ PHP_FUNCTION(openssl_x509_parse)
 		add_assoc_string(return_value, "alias", tmpstr, 1);
 	}
 
-	sig_nid = OBJ_obj2nid((cert)->sig_alg->algorithm);
+	sig_nid = X509_get_signature_nid(cert);
 	add_assoc_string(return_value, "signatureTypeSN", (char*)OBJ_nid2sn(sig_nid), 1);
 	add_assoc_string(return_value, "signatureTypeLN", (char*)OBJ_nid2ln(sig_nid), 1);
 	add_assoc_long(return_value, "signatureTypeNID", sig_nid);
@@ -3217,7 +3366,21 @@ PHP_FUNCTION(openssl_csr_get_public_key)
 		RETURN_FALSE;
 	}
 
-	tpubkey=X509_REQ_get_pubkey(csr);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+	/* Due to changes in OpenSSL 1.1 related to locking when decoding CSR,
+	 * the pub key is not changed after assigning. It means if we pass
+	 * a private key, it will be returned including the private part.
+	 * If we duplicate it, then we get just the public part which is
+	 * the same behavior as for OpenSSL 1.0 */
+	csr = X509_REQ_dup(csr);
+#endif
+	/* Retrieve the public key from the CSR */
+	tpubkey = X509_REQ_get_pubkey(csr);
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+	/* We need to free the CSR as it was duplicated */
+	X509_REQ_free(csr);
+#endif
 	RETVAL_RESOURCE(zend_list_insert(tpubkey, le_key TSRMLS_CC));
 	return;
 }
@@ -3482,13 +3645,20 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
 {
 	assert(pkey != NULL);
 
-	switch (pkey->type) {
+	switch (EVP_PKEY_id(pkey)) {
 #ifndef NO_RSA
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
-			assert(pkey->pkey.rsa != NULL);
-			if (pkey->pkey.rsa != NULL && (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q)) {
-				return 0;
+			{
+				RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+				if (rsa != NULL) {
+					const BIGNUM *p, *q;
+
+					RSA_get0_factors(rsa, &p, &q);
+					 if (p == NULL || q == NULL) {
+						return 0;
+					 }
+				}
 			}
 			break;
 #endif
@@ -3498,28 +3668,51 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
 		case EVP_PKEY_DSA2:
 		case EVP_PKEY_DSA3:
 		case EVP_PKEY_DSA4:
-			assert(pkey->pkey.dsa != NULL);
-
-			if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){ 
-				return 0;
+			{
+				DSA *dsa = EVP_PKEY_get0_DSA(pkey);
+				if (dsa != NULL) {
+					const BIGNUM *p, *q, *g, *pub_key, *priv_key;
+
+					DSA_get0_pqg(dsa, &p, &q, &g);
+					if (p == NULL || q == NULL) {
+						return 0;
+					}
+ 
+					DSA_get0_key(dsa, &pub_key, &priv_key);
+					if (priv_key == NULL) {
+						return 0;
+					}
+				}
 			}
 			break;
 #endif
 #ifndef NO_DH
 		case EVP_PKEY_DH:
-			assert(pkey->pkey.dh != NULL);
-
-			if (NULL == pkey->pkey.dh->p || NULL == pkey->pkey.dh->priv_key) {
-				return 0;
+			{
+				DH *dh = EVP_PKEY_get0_DH(pkey);
+				if (dh != NULL) {
+					const BIGNUM *p, *q, *g, *pub_key, *priv_key;
+
+					DH_get0_pqg(dh, &p, &q, &g);
+					if (p == NULL) {
+						return 0;
+					}
+ 
+					DH_get0_key(dh, &pub_key, &priv_key);
+					if (priv_key == NULL) {
+						return 0;
+					}
+				}
 			}
 			break;
 #endif
 #ifdef HAVE_EVP_PKEY_EC
 		case EVP_PKEY_EC:
-			assert(pkey->pkey.ec != NULL);
-
-			if ( NULL == EC_KEY_get0_private_key(pkey->pkey.ec)) {
-				return 0;
+			{
+				EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+				if (ec != NULL && NULL == EC_KEY_get0_private_key(ec)) {
+					return 0;
+				}
 			}
 			break;
 #endif
@@ -3531,34 +3724,80 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
 }
 /* }}} */
 
-#define OPENSSL_PKEY_GET_BN(_type, _name) do {							\
-		if (pkey->pkey._type->_name != NULL) {							\
-			int len = BN_num_bytes(pkey->pkey._type->_name);			\
-			char *str = emalloc(len + 1);								\
-			BN_bn2bin(pkey->pkey._type->_name, (unsigned char*)str);	\
-			str[len] = 0;                                           	\
-			add_assoc_stringl(_type, #_name, str, len, 0);				\
-		}																\
-	} while (0)
-
-#define OPENSSL_PKEY_SET_BN(_ht, _type, _name) do {						\
-		zval **bn;														\
-		if (zend_hash_find(_ht, #_name, sizeof(#_name),	(void**)&bn) == SUCCESS && \
-				Z_TYPE_PP(bn) == IS_STRING) {							\
-			_type->_name = BN_bin2bn(									\
-				(unsigned char*)Z_STRVAL_PP(bn),						\
-	 			Z_STRLEN_PP(bn), NULL);									\
-	    }                                                               \
+#define OPENSSL_GET_BN(_array, _bn, _name) do { \
+		if (_bn != NULL) { \
+			int len = BN_num_bytes(_bn); \
+			char *str = emalloc(len + 1); \
+			BN_bn2bin(_bn, (unsigned char*)str); \
+			str[len] = 0; \
+			add_assoc_stringl(_array, #_name, str, len, 0); \
+		} \
 	} while (0);
 
+#define OPENSSL_PKEY_GET_BN(_type, _name) OPENSSL_GET_BN(_type, _name, _name)
+
+#define OPENSSL_PKEY_SET_BN(_data, _name) do { \
+		zval **bn; \
+		if (zend_hash_find(Z_ARRVAL_P(_data), #_name, sizeof(#_name),(void**)&bn) == SUCCESS && \
+				Z_TYPE_PP(bn) == IS_STRING) { \
+			_name = BN_bin2bn( \
+				(unsigned char*)Z_STRVAL_PP(bn), \
+				Z_STRLEN_PP(bn), NULL); \
+		} else { \
+			_name = NULL; \
+		} \
+ 	} while (0);
+
+/* {{{ php_openssl_pkey_init_rsa */
+zend_bool php_openssl_pkey_init_and_assign_rsa(EVP_PKEY *pkey, RSA *rsa, zval *data)
+{
+	BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
+
+	OPENSSL_PKEY_SET_BN(data, n);
+	OPENSSL_PKEY_SET_BN(data, e);
+	OPENSSL_PKEY_SET_BN(data, d);
+	if (!n || !d || !RSA_set0_key(rsa, n, e, d)) {
+		return 0;
+	}
+
+	OPENSSL_PKEY_SET_BN(data, p);
+	OPENSSL_PKEY_SET_BN(data, q);
+	if ((p || q) && !RSA_set0_factors(rsa, p, q)) {
+		return 0;
+	}
+
+	OPENSSL_PKEY_SET_BN(data, dmp1);
+	OPENSSL_PKEY_SET_BN(data, dmq1);
+	OPENSSL_PKEY_SET_BN(data, iqmp);
+	if ((dmp1 || dmq1 || iqmp) && !RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp)) {
+		return 0;
+	}
+
+	if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
+		return 0;
+	}
+
+	return 1;
+}
+/* }}} */
+
 /* {{{ php_openssl_pkey_init_dsa */
-zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
+zend_bool php_openssl_pkey_init_dsa(DSA *dsa, zval *data)
 {
-	if (!dsa->p || !dsa->q || !dsa->g) {
+	BIGNUM *p, *q, *g, *priv_key, *pub_key;
+	const BIGNUM *priv_key_const, *pub_key_const;
+
+	OPENSSL_PKEY_SET_BN(data, p);
+	OPENSSL_PKEY_SET_BN(data, q);
+	OPENSSL_PKEY_SET_BN(data, g);
+	if (!p || !q || !g || !DSA_set0_pqg(dsa, p, q, g)) {
 		return 0;
 	}
-	if (dsa->priv_key || dsa->pub_key) {
-		return 1;
+
+	OPENSSL_PKEY_SET_BN(data, pub_key);
+	OPENSSL_PKEY_SET_BN(data, priv_key);
+	if (pub_key) {
+		return DSA_set0_key(dsa, pub_key, priv_key);
 	}
 	PHP_OPENSSL_RAND_ADD_TIME();
 	if (!DSA_generate_key(dsa)) {
@@ -3566,7 +3805,8 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
 	}
 	/* if BN_mod_exp return -1, then DSA_generate_key succeed for failed key
 	 * so we need to double check that public key is created */
-	if (!dsa->pub_key || BN_is_zero(dsa->pub_key)) {
+	DSA_get0_key(dsa, &pub_key_const, &priv_key_const);
+	if (!pub_key_const || BN_is_zero(pub_key_const)) {
 		return 0;
 	}
 	/* all good */
@@ -3574,14 +3814,66 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa)
 }
 /* }}} */
 
+/* {{{ php_openssl_dh_pub_from_priv */
+static BIGNUM *php_openssl_dh_pub_from_priv(BIGNUM *priv_key, BIGNUM *g, BIGNUM *p)
+{
+	BIGNUM *pub_key, *priv_key_const_time;
+	BN_CTX *ctx;
+
+	pub_key = BN_new();
+	if (pub_key == NULL) {
+		return NULL;
+	}
+
+	priv_key_const_time = BN_new();
+	if (priv_key_const_time == NULL) {
+		BN_free(pub_key);
+		return NULL;
+	}
+	ctx = BN_CTX_new();
+	if (ctx == NULL) {
+		BN_free(pub_key);
+		BN_free(priv_key_const_time);
+		return NULL;
+	}
+
+	BN_with_flags(priv_key_const_time, priv_key, BN_FLG_CONSTTIME);
+
+	if (!BN_mod_exp_mont(pub_key, g, priv_key_const_time, p, ctx, NULL)) {
+		BN_free(pub_key);
+		pub_key = NULL;
+	}
+
+	BN_free(priv_key_const_time);
+	BN_CTX_free(ctx);
+
+	return pub_key;
+}
+/* }}} */
+
 /* {{{ php_openssl_pkey_init_dh */
-zend_bool php_openssl_pkey_init_dh(DH *dh)
+zend_bool php_openssl_pkey_init_dh(DH *dh, zval *data)
 {
-	if (!dh->p || !dh->g) {
+	BIGNUM *p, *q, *g, *priv_key, *pub_key;
+
+	OPENSSL_PKEY_SET_BN(data, p);
+	OPENSSL_PKEY_SET_BN(data, q);
+	OPENSSL_PKEY_SET_BN(data, g);
+	if (!p || !g || !DH_set0_pqg(dh, p, q, g)) {
 		return 0;
 	}
-	if (dh->pub_key) {
-		return 1;
+
+	OPENSSL_PKEY_SET_BN(data, priv_key);
+	OPENSSL_PKEY_SET_BN(data, pub_key);
+	if (pub_key) {
+		return DH_set0_key(dh, pub_key, priv_key);
+	}
+	if (priv_key) {
+		pub_key = php_openssl_dh_pub_from_priv(priv_key, g, p);
+		if (pub_key == NULL) {
+			return 0;
+		}
+		return DH_set0_key(dh, pub_key, priv_key);
 	}
 	PHP_OPENSSL_RAND_ADD_TIME();
 	if (!DH_generate_key(dh)) {
@@ -3614,18 +3906,8 @@ PHP_FUNCTION(openssl_pkey_new)
 		    if (pkey) {
 				RSA *rsa = RSA_new();
 				if (rsa) {
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, n);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, e);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, d);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, p);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, q);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmp1);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, dmq1);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), rsa, iqmp);
-					if (rsa->n && rsa->d) {
-						if (EVP_PKEY_assign_RSA(pkey, rsa)) {
-							RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
-						}
+					if (php_openssl_pkey_init_and_assign_rsa(pkey, rsa, *data)) {
+						RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
 					}
 					RSA_free(rsa);
 				}
@@ -3638,12 +3920,7 @@ PHP_FUNCTION(openssl_pkey_new)
 		    if (pkey) {
 				DSA *dsa = DSA_new();
 				if (dsa) {
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, p);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, q);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, g);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, priv_key);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dsa, pub_key);
-					if (php_openssl_pkey_init_dsa(dsa)) {
+					if (php_openssl_pkey_init_dsa(dsa, *data)) {
 						if (EVP_PKEY_assign_DSA(pkey, dsa)) {
 							RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
 						}
@@ -3659,11 +3936,7 @@ PHP_FUNCTION(openssl_pkey_new)
 		    if (pkey) {
 				DH *dh = DH_new();
 				if (dh) {
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, p);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, g);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, priv_key);
-					OPENSSL_PKEY_SET_BN(Z_ARRVAL_PP(data), dh, pub_key);
-					if (php_openssl_pkey_init_dh(dh)) {
+					if (php_openssl_pkey_init_dh(dh, *data)) {
 						if (EVP_PKEY_assign_DH(pkey, dh)) {
 							RETURN_RESOURCE(zend_list_insert(pkey, le_key TSRMLS_CC));
 						}
@@ -3738,10 +4011,10 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
 			cipher = NULL;
 		}
 
-		switch (EVP_PKEY_type(key->type)) {
+		switch (EVP_PKEY_base_id(key)) {
 #ifdef HAVE_EVP_PKEY_EC
 			case EVP_PKEY_EC:
-				pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
+				pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get0_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
 				break;
 #endif
 			default:
@@ -3807,7 +4080,7 @@ PHP_FUNCTION(openssl_pkey_export)
 			cipher = NULL;
 		}
 
-		switch (EVP_PKEY_type(key->type)) {
+		switch (EVP_PKEY_base_id(key)) {
 #ifdef HAVE_EVP_PKEY_EC
 			case EVP_PKEY_EC:
 				pem_write = PEM_write_bio_ECPrivateKey(bio_out, EVP_PKEY_get1_EC_KEY(key), cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL);
@@ -3928,25 +4201,33 @@ PHP_FUNCTION(openssl_pkey_get_details)
 	/*TODO: Use the real values once the openssl constants are used 
 	 * See the enum at the top of this file
 	 */
-	switch (EVP_PKEY_type(pkey->type)) {
+	switch (EVP_PKEY_base_id(pkey)) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
-			ktype = OPENSSL_KEYTYPE_RSA;
-
-			if (pkey->pkey.rsa != NULL) {
-				zval *rsa;
-
-				ALLOC_INIT_ZVAL(rsa);
-				array_init(rsa);
-				OPENSSL_PKEY_GET_BN(rsa, n);
-				OPENSSL_PKEY_GET_BN(rsa, e);
-				OPENSSL_PKEY_GET_BN(rsa, d);
-				OPENSSL_PKEY_GET_BN(rsa, p);
-				OPENSSL_PKEY_GET_BN(rsa, q);
-				OPENSSL_PKEY_GET_BN(rsa, dmp1);
-				OPENSSL_PKEY_GET_BN(rsa, dmq1);
-				OPENSSL_PKEY_GET_BN(rsa, iqmp);
-				add_assoc_zval(return_value, "rsa", rsa);
+			{
+				RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+				ktype = OPENSSL_KEYTYPE_RSA;
+
+				if (rsa != NULL) {
+					zval *z_rsa;
+					const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
+
+					RSA_get0_key(rsa, &n, &e, &d);
+					RSA_get0_factors(rsa, &p, &q);
+					RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+
+					ALLOC_INIT_ZVAL(z_rsa);
+					array_init(z_rsa);
+					OPENSSL_PKEY_GET_BN(z_rsa, n);
+					OPENSSL_PKEY_GET_BN(z_rsa, e);
+					OPENSSL_PKEY_GET_BN(z_rsa, d);
+					OPENSSL_PKEY_GET_BN(z_rsa, p);
+					OPENSSL_PKEY_GET_BN(z_rsa, q);
+					OPENSSL_PKEY_GET_BN(z_rsa, dmp1);
+					OPENSSL_PKEY_GET_BN(z_rsa, dmq1);
+					OPENSSL_PKEY_GET_BN(z_rsa, iqmp);
+					add_assoc_zval(return_value, "rsa", z_rsa);
+				}
 			}
 
 			break;	
@@ -3954,42 +4235,55 @@ PHP_FUNCTION(openssl_pkey_get_details)
 		case EVP_PKEY_DSA2:
 		case EVP_PKEY_DSA3:
 		case EVP_PKEY_DSA4:
-			ktype = OPENSSL_KEYTYPE_DSA;
-
-			if (pkey->pkey.dsa != NULL) {
-				zval *dsa;
-
-				ALLOC_INIT_ZVAL(dsa);
-				array_init(dsa);
-				OPENSSL_PKEY_GET_BN(dsa, p);
-				OPENSSL_PKEY_GET_BN(dsa, q);
-				OPENSSL_PKEY_GET_BN(dsa, g);
-				OPENSSL_PKEY_GET_BN(dsa, priv_key);
-				OPENSSL_PKEY_GET_BN(dsa, pub_key);
-				add_assoc_zval(return_value, "dsa", dsa);
+			{
+				DSA *dsa = EVP_PKEY_get0_DSA(pkey);
+				ktype = OPENSSL_KEYTYPE_DSA;
+
+				if (dsa != NULL) {
+					zval *z_dsa;
+					const BIGNUM *p, *q, *g, *priv_key, *pub_key;
+
+					DSA_get0_pqg(dsa, &p, &q, &g);
+					DSA_get0_key(dsa, &pub_key, &priv_key);
+
+					ALLOC_INIT_ZVAL(z_dsa);
+					array_init(z_dsa);
+					OPENSSL_PKEY_GET_BN(z_dsa, p);
+					OPENSSL_PKEY_GET_BN(z_dsa, q);
+					OPENSSL_PKEY_GET_BN(z_dsa, g);
+					OPENSSL_PKEY_GET_BN(z_dsa, priv_key);
+					OPENSSL_PKEY_GET_BN(z_dsa, pub_key);
+					add_assoc_zval(return_value, "dsa", z_dsa);
+				}
 			}
 			break;
 		case EVP_PKEY_DH:
-			
-			ktype = OPENSSL_KEYTYPE_DH;
-
-			if (pkey->pkey.dh != NULL) {
-				zval *dh;
-
-				ALLOC_INIT_ZVAL(dh);
-				array_init(dh);
-				OPENSSL_PKEY_GET_BN(dh, p);
-				OPENSSL_PKEY_GET_BN(dh, g);
-				OPENSSL_PKEY_GET_BN(dh, priv_key);
-				OPENSSL_PKEY_GET_BN(dh, pub_key);
-				add_assoc_zval(return_value, "dh", dh);
+			{
+				DH *dh = EVP_PKEY_get0_DH(pkey);
+				ktype = OPENSSL_KEYTYPE_DH;
+
+				if (dh != NULL) {
+					zval *z_dh;
+					const BIGNUM *p, *q, *g, *priv_key, *pub_key;
+
+					DH_get0_pqg(dh, &p, &q, &g);
+					DH_get0_key(dh, &pub_key, &priv_key);
+
+					ALLOC_INIT_ZVAL(z_dh);
+					array_init(z_dh);
+					OPENSSL_PKEY_GET_BN(z_dh, p);
+					OPENSSL_PKEY_GET_BN(z_dh, g);
+					OPENSSL_PKEY_GET_BN(z_dh, priv_key);
+					OPENSSL_PKEY_GET_BN(z_dh, pub_key);
+					add_assoc_zval(return_value, "dh", z_dh);
+				}
 			}
 
 			break;
 #ifdef HAVE_EVP_PKEY_EC
 		case EVP_PKEY_EC:
 			ktype = OPENSSL_KEYTYPE_EC;
-			if (pkey->pkey.ec != NULL) {
+			if (EVP_PKEY_get0_EC_KEY(pkey) != NULL) {
 				zval *ec;
 				const EC_GROUP *ec_group;
 				int nid;
@@ -4546,13 +4840,13 @@ PHP_FUNCTION(openssl_private_encrypt)
 	cryptedlen = EVP_PKEY_size(pkey);
 	cryptedbuf = emalloc(cryptedlen + 1);
 
-	switch (pkey->type) {
+	switch (EVP_PKEY_id(pkey)) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
 			successful =  (RSA_private_encrypt(data_len, 
 						(unsigned char *)data, 
 						cryptedbuf, 
-						pkey->pkey.rsa, 
+						EVP_PKEY_get0_RSA(pkey), 
 						padding) == cryptedlen);
 			break;
 		default:
@@ -4604,13 +4898,13 @@ PHP_FUNCTION(openssl_private_decrypt)
 	cryptedlen = EVP_PKEY_size(pkey);
 	crypttemp = emalloc(cryptedlen + 1);
 
-	switch (pkey->type) {
+	switch (EVP_PKEY_id(pkey)) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
 			cryptedlen = RSA_private_decrypt(data_len, 
 					(unsigned char *)data, 
 					crypttemp, 
-					pkey->pkey.rsa, 
+					EVP_PKEY_get0_RSA(pkey), 
 					padding);
 			if (cryptedlen != -1) {
 				cryptedbuf = emalloc(cryptedlen + 1);
@@ -4669,13 +4963,13 @@ PHP_FUNCTION(openssl_public_encrypt)
 	cryptedlen = EVP_PKEY_size(pkey);
 	cryptedbuf = emalloc(cryptedlen + 1);
 
-	switch (pkey->type) {
+	switch (EVP_PKEY_id(pkey)) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
 			successful = (RSA_public_encrypt(data_len, 
 						(unsigned char *)data, 
 						cryptedbuf, 
-						pkey->pkey.rsa, 
+						EVP_PKEY_get0_RSA(pkey), 
 						padding) == cryptedlen);
 			break;
 		default:
@@ -4728,13 +5022,13 @@ PHP_FUNCTION(openssl_public_decrypt)
 	cryptedlen = EVP_PKEY_size(pkey);
 	crypttemp = emalloc(cryptedlen + 1);
 
-	switch (pkey->type) {
+	switch (EVP_PKEY_id(pkey)) {
 		case EVP_PKEY_RSA:
 		case EVP_PKEY_RSA2:
 			cryptedlen = RSA_public_decrypt(data_len, 
 					(unsigned char *)data, 
 					crypttemp, 
-					pkey->pkey.rsa, 
+					EVP_PKEY_get0_RSA(pkey), 
 					padding);
 			if (cryptedlen != -1) {
 				cryptedbuf = emalloc(cryptedlen + 1);
@@ -4798,7 +5092,7 @@ PHP_FUNCTION(openssl_sign)
 	long keyresource = -1;
 	char * data;
 	int data_len;
-	EVP_MD_CTX md_ctx;
+	EVP_MD_CTX *md_ctx;
 	zval *method = NULL;
 	long signature_algo = OPENSSL_ALGO_SHA1;
 	const EVP_MD *mdtype;
@@ -4831,9 +5125,10 @@ PHP_FUNCTION(openssl_sign)
 	siglen = EVP_PKEY_size(pkey);
 	sigbuf = emalloc(siglen + 1);
 
-	EVP_SignInit(&md_ctx, mdtype);
-	EVP_SignUpdate(&md_ctx, data, data_len);
-	if (EVP_SignFinal (&md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
+	md_ctx = EVP_MD_CTX_create();
+	EVP_SignInit(md_ctx, mdtype);
+	EVP_SignUpdate(md_ctx, data, data_len);
+	if (EVP_SignFinal (md_ctx, sigbuf,(unsigned int *)&siglen, pkey)) {
 		zval_dtor(signature);
 		sigbuf[siglen] = '\0';
 		ZVAL_STRINGL(signature, (char *)sigbuf, siglen, 0);
@@ -4842,7 +5137,7 @@ PHP_FUNCTION(openssl_sign)
 		efree(sigbuf);
 		RETVAL_FALSE;
 	}
-	EVP_MD_CTX_cleanup(&md_ctx);
+	EVP_MD_CTX_destroy(md_ctx);
 	if (keyresource == -1) {
 		EVP_PKEY_free(pkey);
 	}
@@ -4856,7 +5151,7 @@ PHP_FUNCTION(openssl_verify)
 	zval **key;
 	EVP_PKEY *pkey;
 	int err;
-	EVP_MD_CTX     md_ctx;
+	EVP_MD_CTX     *md_ctx;
 	const EVP_MD *mdtype;
 	long keyresource = -1;
 	char * data;	int data_len;
@@ -4890,10 +5185,11 @@ PHP_FUNCTION(openssl_verify)
 		RETURN_FALSE;
 	}
 
-	EVP_VerifyInit   (&md_ctx, mdtype);
-	EVP_VerifyUpdate (&md_ctx, data, data_len);
-	err = EVP_VerifyFinal (&md_ctx, (unsigned char *)signature, signature_len, pkey);
-	EVP_MD_CTX_cleanup(&md_ctx);
+	md_ctx = EVP_MD_CTX_create();
+	EVP_VerifyInit   (md_ctx, mdtype);
+	EVP_VerifyUpdate (md_ctx, data, data_len);
+	err = EVP_VerifyFinal (md_ctx, (unsigned char *)signature, signature_len, pkey);
+	EVP_MD_CTX_destroy(md_ctx);
 
 	if (keyresource == -1) {
 		EVP_PKEY_free(pkey);
@@ -4917,7 +5213,7 @@ PHP_FUNCTION(openssl_seal)
 	char *method =NULL;
 	int method_len = 0;
 	const EVP_CIPHER *cipher;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx;
 
 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
 		return;
@@ -4950,6 +5246,7 @@ PHP_FUNCTION(openssl_seal)
 	memset(eks, 0, sizeof(*eks) * nkeys);
 	key_resources = safe_emalloc(nkeys, sizeof(long), 0);
 	memset(key_resources, 0, sizeof(*key_resources) * nkeys);
+	memset(pkeys, 0, sizeof(*pkeys) * nkeys);
 
 	/* get the public keys we are using to seal this data */
 	zend_hash_internal_pointer_reset_ex(pubkeysht, &pos);
@@ -4967,27 +5264,28 @@ PHP_FUNCTION(openssl_seal)
 		i++;
 	}
 
-	if (!EVP_EncryptInit(&ctx,cipher,NULL,NULL)) {
+	ctx = EVP_CIPHER_CTX_new();
+	if (ctx == NULL || !EVP_EncryptInit(ctx,cipher,NULL,NULL)) {
 		RETVAL_FALSE;
-		EVP_CIPHER_CTX_cleanup(&ctx);
+		EVP_CIPHER_CTX_free(ctx);
 		goto clean_exit;
 	}
 
 #if 0
 	/* Need this if allow ciphers that require initialization vector */
-	ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
+	ivlen = EVP_CIPHER_CTX_iv_length(ctx);
 	iv = ivlen ? emalloc(ivlen + 1) : NULL;
 #endif
 	/* allocate one byte extra to make room for \0 */
-	buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(&ctx));
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	buf = emalloc(data_len + EVP_CIPHER_CTX_block_size(ctx));
+	EVP_CIPHER_CTX_cleanup(ctx);
 
-	if (EVP_SealInit(&ctx, cipher, eks, eksl, NULL, pkeys, nkeys) <= 0 ||
-			!EVP_SealUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len) ||
-			!EVP_SealFinal(&ctx, buf + len1, &len2)) {
+	if (EVP_SealInit(ctx, cipher, eks, eksl, NULL, pkeys, nkeys) <= 0 ||
+			!EVP_SealUpdate(ctx, buf, &len1, (unsigned char *)data, data_len) ||
+			!EVP_SealFinal(ctx, buf + len1, &len2)) {
 		RETVAL_FALSE;
 		efree(buf);
-		EVP_CIPHER_CTX_cleanup(&ctx);
+		EVP_CIPHER_CTX_free(ctx);
 		goto clean_exit;
 	}
 
@@ -5018,7 +5316,7 @@ PHP_FUNCTION(openssl_seal)
 		efree(buf);
 	}
 	RETVAL_LONG(len1 + len2);
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 
 clean_exit:
 	for (i=0; i<nkeys; i++) {
@@ -5045,7 +5343,7 @@ PHP_FUNCTION(openssl_open)
 	int len1, len2;
 	unsigned char *buf;
 	long keyresource = -1;
-	EVP_CIPHER_CTX ctx;
+	EVP_CIPHER_CTX *ctx;
 	char * data;	int data_len;
 	char * ekey;	int ekey_len;
 	char *method =NULL;
@@ -5074,8 +5372,9 @@ PHP_FUNCTION(openssl_open)
 	
 	buf = emalloc(data_len + 1);
 
-	if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
-		if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
+	ctx = EVP_CIPHER_CTX_new();
+	if (EVP_OpenInit(ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(ctx, buf, &len1, (unsigned char *)data, data_len)) {
+		if (!EVP_OpenFinal(ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
 			efree(buf);
 			RETVAL_FALSE;
 		} else {
@@ -5091,7 +5390,7 @@ PHP_FUNCTION(openssl_open)
 	if (keyresource == -1) {
 		EVP_PKEY_free(pkey);
 	}
-	EVP_CIPHER_CTX_cleanup(&ctx);
+	EVP_CIPHER_CTX_free(ctx);
 }
 /* }}} */
 
@@ -5151,7 +5450,7 @@ PHP_FUNCTION(openssl_digest)
 	char *data, *method;
 	int data_len, method_len;
 	const EVP_MD *mdtype;
-	EVP_MD_CTX md_ctx;
+	EVP_MD_CTX *md_ctx;
 	int siglen;
 	unsigned char *sigbuf;
 
@@ -5167,9 +5466,10 @@ PHP_FUNCTION(openssl_digest)
 	siglen = EVP_MD_size(mdtype);
 	sigbuf = emalloc(siglen + 1);
 
-	EVP_DigestInit(&md_ctx, mdtype);
-	EVP_DigestUpdate(&md_ctx, (unsigned char *)data, data_len);
-	if (EVP_DigestFinal (&md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
+	md_ctx = EVP_MD_CTX_create();
+	EVP_DigestInit(md_ctx, mdtype);
+	EVP_DigestUpdate(md_ctx, (unsigned char *)data, data_len);
+	if (EVP_DigestFinal (md_ctx, (unsigned char *)sigbuf, (unsigned int *)&siglen)) {
 		if (raw_output) {
 			sigbuf[siglen] = '\0';
 			RETVAL_STRINGL((char *)sigbuf, siglen, 0);
@@ -5185,6 +5485,8 @@ PHP_FUNCTION(openssl_digest)
 		efree(sigbuf);
 		RETVAL_FALSE;
 	}
+
+	EVP_MD_CTX_destroy(md_ctx);
 }
 /* }}} */
 
@@ -5230,7 +5532,7 @@ PHP_FUNCTION(openssl_encrypt)
 	char *data, *method, *password, *iv = "";
 	int data_len, method_len, password_len, iv_len = 0, max_iv_len;
 	const EVP_CIPHER *cipher_type;
-	EVP_CIPHER_CTX cipher_ctx;
+	EVP_CIPHER_CTX *cipher_ctx;
 	int i=0, outlen, keylen;
 	unsigned char *outbuf, *key;
 	zend_bool free_iv;
@@ -5262,19 +5564,24 @@ PHP_FUNCTION(openssl_encrypt)
 	outlen = data_len + EVP_CIPHER_block_size(cipher_type);
 	outbuf = safe_emalloc(outlen, 1, 1);
 
-	EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL);
+	cipher_ctx = EVP_CIPHER_CTX_new();
+	if (!cipher_ctx) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to create cipher context");
+		RETURN_FALSE;
+	}
+	EVP_EncryptInit(cipher_ctx, cipher_type, NULL, NULL);
 	if (password_len > keylen) {
-		EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
+		EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len);
 	}
-	EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
+	EVP_EncryptInit_ex(cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
 	if (options & OPENSSL_ZERO_PADDING) {
-		EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
+		EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
 	}
 	if (data_len > 0) {
-		EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
+		EVP_EncryptUpdate(cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
 	}
 	outlen = i;
-	if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+	if (EVP_EncryptFinal(cipher_ctx, (unsigned char *)outbuf + i, &i)) {
 		outlen += i;
 		if (options & OPENSSL_RAW_DATA) {
 			outbuf[outlen] = '\0';
@@ -5301,7 +5608,8 @@ PHP_FUNCTION(openssl_encrypt)
 	if (free_iv) {
 		efree(iv);
 	}
-	EVP_CIPHER_CTX_cleanup(&cipher_ctx);
+	EVP_CIPHER_CTX_cleanup(cipher_ctx);
+	EVP_CIPHER_CTX_free(cipher_ctx);
 }
 /* }}} */
 
@@ -5313,7 +5621,7 @@ PHP_FUNCTION(openssl_decrypt)
 	char *data, *method, *password, *iv = "";
 	int data_len, method_len, password_len, iv_len = 0;
 	const EVP_CIPHER *cipher_type;
-	EVP_CIPHER_CTX cipher_ctx;
+	EVP_CIPHER_CTX *cipher_ctx;
 	int i, outlen, keylen;
 	unsigned char *outbuf, *key;
 	int base64_str_len;
@@ -5359,17 +5667,23 @@ PHP_FUNCTION(openssl_decrypt)
 	outlen = data_len + EVP_CIPHER_block_size(cipher_type);
 	outbuf = emalloc(outlen + 1);
 
-	EVP_DecryptInit(&cipher_ctx, cipher_type, NULL, NULL);
+	cipher_ctx = EVP_CIPHER_CTX_new();
+	if (!cipher_ctx) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to create cipher context");
+		RETURN_FALSE;
+	}
+
+	EVP_DecryptInit(cipher_ctx, cipher_type, NULL, NULL);
 	if (password_len > keylen) {
-		EVP_CIPHER_CTX_set_key_length(&cipher_ctx, password_len);
+		EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len);
 	}
-	EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
+	EVP_DecryptInit_ex(cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
 	if (options & OPENSSL_ZERO_PADDING) {
-		EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
+		EVP_CIPHER_CTX_set_padding(cipher_ctx, 0);
 	}
-	EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
+	EVP_DecryptUpdate(cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
 	outlen = i;
-	if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
+	if (EVP_DecryptFinal(cipher_ctx, (unsigned char *)outbuf + i, &i)) {
 		outlen += i;
 		outbuf[outlen] = '\0';
 		RETVAL_STRINGL((char *)outbuf, outlen, 0);
@@ -5386,7 +5700,8 @@ PHP_FUNCTION(openssl_decrypt)
 	if (base64_str) {
 		efree(base64_str);
 	}
- 	EVP_CIPHER_CTX_cleanup(&cipher_ctx);
+ 	EVP_CIPHER_CTX_cleanup(cipher_ctx);
+ 	EVP_CIPHER_CTX_free(cipher_ctx);
 }
 /* }}} */
 
@@ -5424,6 +5739,7 @@ PHP_FUNCTION(openssl_dh_compute_key)
 	zval *key;
 	char *pub_str;
 	int pub_len;
+	DH *dh;
 	EVP_PKEY *pkey;
 	BIGNUM *pub;
 	char *data;
@@ -5433,14 +5749,21 @@ PHP_FUNCTION(openssl_dh_compute_key)
 		return;
 	}
 	ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key);
-	if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) {
+	if (pkey == NULL) {
+		RETURN_FALSE;
+	}
+	if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
+		RETURN_FALSE;
+	}
+	dh = EVP_PKEY_get0_DH(pkey);
+	if (dh == NULL) {
 		RETURN_FALSE;
 	}
 
 	pub = BN_bin2bn((unsigned char*)pub_str, pub_len, NULL);
 
-	data = emalloc(DH_size(pkey->pkey.dh) + 1);
-	len = DH_compute_key((unsigned char*)data, pub, pkey->pkey.dh);
+	data = emalloc(DH_size(dh) + 1);
+	len = DH_compute_key((unsigned char*)data, pub, dh);
 
 	if (len >= 0) {
 		data[len] = 0;
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index d5490331d634..c2d477c1db2b 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -935,7 +935,7 @@ static int set_local_cert(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{ */
 static const SSL_METHOD *php_select_crypto_method(long method_value, int is_client TSRMLS_DC) /* {{{ */
 {
 	if (method_value == STREAM_CRYPTO_METHOD_SSLv2) {
-#ifndef OPENSSL_NO_SSL2
+#if !defined(OPENSSL_NO_SSL2) && OPENSSL_VERSION_NUMBER < 0x10100000L
 		return is_client ? SSLv2_client_method() : SSLv2_server_method();
 #else
 		php_error_docref(NULL TSRMLS_CC, E_WARNING,
@@ -1588,12 +1588,26 @@ int php_openssl_setup_crypto(php_stream *stream,
 }
 /* }}} */
 
+#define PHP_SSL_MAX_VERSION_LEN 32
+
+static char *php_ssl_cipher_get_version(const SSL_CIPHER *c, char *buffer, size_t max_len) /* {{{ */
+{
+	const char *version = SSL_CIPHER_get_version(c);
+	strncpy(buffer, version, max_len);
+	if (max_len <= strlen(version)) {
+		buffer[max_len - 1] = 0;
+	}
+	return buffer;
+}
+/* }}} */
+
 static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
 {
 	zval *meta_arr;
 	char *proto_str;
 	long proto = SSL_version(ssl_handle);
 	const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_handle);
+	char version_str[PHP_SSL_MAX_VERSION_LEN];
 
 	switch (proto) {
 #if OPENSSL_VERSION_NUMBER >= 0x10001001L
@@ -1611,7 +1625,7 @@ static zval *capture_session_meta(SSL *ssl_handle) /* {{{ */
 	add_assoc_string(meta_arr, "protocol", proto_str, 1);
 	add_assoc_string(meta_arr, "cipher_name", (char *) SSL_CIPHER_get_name(cipher), 1);
 	add_assoc_long(meta_arr, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL));
-	add_assoc_string(meta_arr, "cipher_version", SSL_CIPHER_get_version(cipher), 1);
+	add_assoc_string(meta_arr, "cipher_version", php_ssl_cipher_get_version(cipher, version_str, PHP_SSL_MAX_VERSION_LEN), 1);
 
 	return meta_arr;
 }
diff --git a/ext/phar/util.c b/ext/phar/util.c
index 828be8f9a23f..06e4e55da7af 100644
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -1531,7 +1531,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 			BIO *in;
 			EVP_PKEY *key;
 			EVP_MD *mdtype = (EVP_MD *) EVP_sha1();
-			EVP_MD_CTX md_ctx;
+			EVP_MD_CTX *md_ctx;
 #else
 			int tempsig;
 #endif
@@ -1608,7 +1608,8 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 				return FAILURE;
 			}
 
-			EVP_VerifyInit(&md_ctx, mdtype);
+			md_ctx = EVP_MD_CTX_create();
+			EVP_VerifyInit(md_ctx, mdtype);
 			read_len = end_of_phar;
 
 			if (read_len > sizeof(buf)) {
@@ -1620,7 +1621,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 			php_stream_seek(fp, 0, SEEK_SET);
 
 			while (read_size && (len = php_stream_read(fp, (char*)buf, read_size)) > 0) {
-				EVP_VerifyUpdate (&md_ctx, buf, len);
+				EVP_VerifyUpdate (md_ctx, buf, len);
 				read_len -= (off_t)len;
 
 				if (read_len < read_size) {
@@ -1628,9 +1629,9 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 				}
 			}
 
-			if (EVP_VerifyFinal(&md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
+			if (EVP_VerifyFinal(md_ctx, (unsigned char *)sig, sig_len, key) != 1) {
 				/* 1: signature verified, 0: signature does not match, -1: failed signature operation */
-				EVP_MD_CTX_cleanup(&md_ctx);
+				EVP_MD_CTX_destroy(md_ctx);
 
 				if (error) {
 					spprintf(error, 0, "broken openssl signature");
@@ -1639,7 +1640,7 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
 				return FAILURE;
 			}
 
-			EVP_MD_CTX_cleanup(&md_ctx);
+			EVP_MD_CTX_destroy(md_ctx);
 #endif
 
 			*signature_len = phar_hex_str((const char*)sig, sig_len, signature TSRMLS_CC);
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 6c3ae3cde80a..b53114cdf34d 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -651,6 +651,8 @@ int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
 }
 
 #if OPENSSL_VERSION_NUMBER < 0x10002000L || defined (LIBRESSL_VERSION_NUMBER)
+#define EVP_PKEY_id(_pkey) _pkey->type
+#define EVP_PKEY_base_id(_key) EVP_PKEY_type(_key->type)
 
 static int X509_get_signature_nid(const X509 *x)
 {
EOP
)->strip(1)
);
}
}
<?php

namespace PhpBrew\Patches;

use CLIFramework\Logger;
use PhpBrew\Buildable;
use PhpBrew\PatchKit\DiffPatchRule;
use PhpBrew\PatchKit\Patch;




class ReadlinePatch extends Patch
{
public function desc()
{
return 'fix readline detection on PHP 5.3 to PHP 7.1';
}

public function match(Buildable $build, Logger $logger)
{
return version_compare($build->getVersion(), '5.4', '>=')
|| version_compare($build->getVersion(), '7.1', '<=');
}






public function rules()
{
return array(
DiffPatchRule::fromPatch(
<<<'EOP'
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@sury.org>
Date: Mon, 17 Dec 2018 09:56:06 +0000
Subject: Fix rl_completion_matches detection

Also fix a typo when checking for rl_on_new_line in readline library.
---
 ext/readline/config.m4 | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/ext/readline/config.m4 b/ext/readline/config.m4
index d63df8bef9..3995bd7587 100644
--- a/ext/readline/config.m4
+++ b/ext/readline/config.m4
@@ -60,13 +60,20 @@ if test "$PHP_READLINE" && test "$PHP_READLINE" != "no"; then
     -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS
   ])
 
-  PHP_CHECK_LIBRARY(edit, rl_on_new_line,
+  PHP_CHECK_LIBRARY(readline, rl_on_new_line,
   [
     AC_DEFINE(HAVE_RL_ON_NEW_LINE, 1, [ ])
   ],[],[
     -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS
   ])
 
+  PHP_CHECK_LIBRARY(readline, rl_completion_matches,
+  [
+    AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, [ ])
+  ],[],[
+    -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS
+  ])
+
   AC_DEFINE(HAVE_LIBREADLINE, 1, [ ])
 
 elif test "$PHP_LIBEDIT" != "no"; then
@@ -114,11 +121,17 @@ elif test "$PHP_LIBEDIT" != "no"; then
     -L$READLINE_DIR/$PHP_LIBDIR
   ])
 
+  PHP_CHECK_LIBRARY(edit, rl_completion_matches,
+  [
+    AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, [ ])
+  ],[],[
+    -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS
+  ])
+
   AC_DEFINE(HAVE_LIBEDIT, 1, [ ])
 fi
 
 if test "$PHP_READLINE" != "no" || test "$PHP_LIBEDIT" != "no"; then
-  AC_CHECK_FUNCS([rl_completion_matches])
   PHP_NEW_EXTENSION(readline, readline.c readline_cli.c, $ext_shared, cli)
   PHP_SUBST(READLINE_SHARED_LIBADD)
 fi
-- 
2.27.0

EOP
)->strip(1)
);
}
}
<?php

namespace PhpBrew;

class BuildFinder
{



public static function findInstalledBuilds()
{
$path = Config::getRoot() . DIRECTORY_SEPARATOR . 'php';

if (!file_exists($path)) {
return array();
}

$names = array_filter(scandir($path), function ($name) use ($path) {
return $name != '.'
&& $name != '..'
&& file_exists(
$path
. DIRECTORY_SEPARATOR . $name
. DIRECTORY_SEPARATOR . 'bin'
. DIRECTORY_SEPARATOR . 'php'
);
});

uasort($names, 'version_compare'); 


return array_reverse($names);
}




public static function findInstalledVersions()
{
return array_map(function ($name) {
return preg_replace('/^php-(?=(\d+\.\d+\.\d+(-dev|((alpha|beta|RC)\d+))?)$)/', '', $name);
}, self::findInstalledBuilds());
}
}
<?php

namespace PhpBrew\Testing;

use CLIFramework\Testing\CommandTestCase as BaseCommandTestCase;
use GetOptionKit\Option;
use PhpBrew\Console;

abstract class CommandTestCase extends BaseCommandTestCase
{
protected $debug = false;

private $previousPhpBrewRoot;

private $previousPhpBrewHome;

public $primaryVersion = '7.0.33';




public $usesVCR = false;

public function getPrimaryVersion()
{





return $this->primaryVersion;
}

public function setupApplication()
{
$console = Console::getInstance();
$console->getLogger()->setQuiet();
$console->getFormatter()->preferRawOutput();

return $console;
}

protected function setUp(): void
{
parent::setUp();
$this->previousPhpBrewRoot = getenv('PHPBREW_ROOT');
$this->previousPhpBrewHome = getenv('PHPBREW_HOME');








if ($options = Console::getInstance()->options) {
$option = new Option('no-progress');
$option->setValue(true);
$options->set('no-progress', $option);
}

if ($this->usesVCR) {
VCRAdapter::enableVCR($this);
}
}






protected function tearDown(): void
{
if ($this->previousPhpBrewRoot !== null) {

}
if ($this->previousPhpBrewHome !== null) {

}

if ($this->usesVCR) {
VCRAdapter::disableVCR();
}
}

public function assertCommandSuccess($args)
{
try {
if ($this->debug) {
fwrite(STDERR, $args . PHP_EOL);
}

ob_start();
$ret = parent::runCommand($args);
$output = ob_get_contents();
ob_end_clean();

$this->assertTrue($ret, $output);
} catch (\CurlKit\CurlException $e) {
$this->markTestIncomplete($e->getMessage());
}
}

public function runCommand($args)
{
ob_start();
$status = parent::runCommand($args);
ob_end_clean();

return $status;
}

public function runCommandWithStdout($args)
{
return parent::runCommand($args);
}
}
<?php

namespace PhpBrew\Testing;

use VCR\VCR;

class VCRAdapter
{
public static function enableVCR($testInstance)
{
VCR::turnOn();
VCR::insertCassette(self::getVCRCassetteName($testInstance));
}

public static function disableVCR()
{
VCR::eject();
VCR::turnOff();
}

protected static function getVCRCassetteName($testInstance)
{
$classname_parts = explode('\\', get_class($testInstance));

return join('/', array_slice($classname_parts, -2, 2));
}
}
<?php

namespace PhpBrew\Testing;

use PHPUnit_Framework_TestCase;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

abstract class PatchTestCase extends PHPUnit_Framework_TestCase
{
protected function setupBuildDirectory($version)
{
$sourceDirectory = getenv('PHPBREW_BUILD_PHP_DIR');
$sourceFixtureDirectory = getenv('PHPBREW_FIXTURES_PHP_DIR') . DIRECTORY_SEPARATOR . $version;

$source = $sourceFixtureDirectory;
$dest = $sourceDirectory;

if (!file_exists($dest)) {
mkdir($dest, 0755, true);
}
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
if ($item->isDir()) {
mkdir($dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(), 0755, true);
} else {
copy($item, $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
}
}
}

protected function cleanupBuildDirectory()
{
$sourceDirectory = getenv('PHPBREW_BUILD_PHP_DIR');
if (!is_dir($sourceDirectory)) {
return;
}

$directoryIterator = new RecursiveDirectoryIterator($sourceDirectory, RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($it as $file) {
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
if (is_dir($sourceDirectory)) {
rmdir($sourceDirectory);
} elseif (is_file($sourceDirectory)) {
unlink($sourceDirectory);
}
}

protected function setUp(): void
{
$sourceDirectory = getenv('PHPBREW_BUILD_PHP_DIR');
$this->cleanupBuildDirectory();
if (!file_exists($sourceDirectory)) {
mkdir($sourceDirectory, 0755, true);
}
}

protected function tearDown(): void
{

if ($this->hasFailed()) {
return;
}
$this->cleanupBuildDirectory();
}
}
<?php

namespace PhpBrew\Exception;

use PhpBrew\Buildable;
use RuntimeException;

class SystemCommandException extends RuntimeException
{
protected $logFile;

protected $build;

public function __construct($message, Buildable $build = null, $logFile = null)
{
parent::__construct($message);
$this->build = $build;
$this->logFile = $logFile;
}

public function getLogFile()
{
if ($this->logFile) {
return $this->logFile;
} elseif ($this->build) {
return $this->build->getBuildLogPath();
}
}
}
<?php

namespace PhpBrew\Exception;

use Exception;

class OopsException extends Exception
{
public function __construct()
{
parent::__construct('Oops, report this issue on GitHub? http://github.com/phpbrew/phpbrew ');
}
}
<?php

namespace PhpBrew;

class VariantParser
{







public static function parseCommandArguments(array $args)
{
$extra = array();
$enabledVariants = array();
$disabledVariants = array();

while (true) {
$arg = array_shift($args);

if ($arg === null) {
break;
}

if ($arg === '') {
throw new InvalidVariantSyntaxException('Variant cannot be empty');
}

if ($arg === '--') {
$extra = $args;
break;
}

$operator = substr($arg, 0, 1);

switch ($operator) {
case '+':
$target =& $enabledVariants;
break;
case '-':
$target =& $disabledVariants;
break;
default:
throw new InvalidVariantSyntaxException('Variant must start with a + or -');
}

$variant = substr($arg, 1);
list($name, $value) = array_pad(explode('=', $variant, 2), 2, null);

if ($name === '') {
throw new InvalidVariantSyntaxException('Variant name cannot be empty');
}

$target[$name] = $value;
}

return array(
'enabled_variants' => $enabledVariants,
'disabled_variants' => $disabledVariants,
'extra_options' => $extra,
);
}




public static function revealCommandArguments(array $info)
{
$args = array();

foreach ($info['enabled_variants'] as $k => $v) {
$arg = '+' . $k;

if (!is_bool($v)) {
$arg .= '=' . $v;
}

$args[] = $arg;
}

if (!empty($info['disabled_variants'])) {
foreach ($info['disabled_variants'] as $k => $_) {
$args[] = '-' . $k;
}
}

if (!empty($info['extra_options'])) {
$args = array_merge($args, array('--'), $info['extra_options']);
}

return implode(' ', $args);
}
}
<?php

namespace PhpBrew;

use BadMethodCallException;
use CLIFramework\Application;
use CLIFramework\Exception\CommandArgumentNotEnoughException;
use CLIFramework\Exception\CommandNotFoundException;
use CLIFramework\ExceptionPrinter\DevelopmentExceptionPrinter;
use CLIFramework\ExceptionPrinter\ProductionExceptionPrinter;
use Exception;
use PhpBrew\Exception\SystemCommandException;

class Console extends Application
{
const NAME = 'phpbrew';
const VERSION = '2.1.0';

public function options($opts)
{
parent::options($opts);
$opts->add('no-progress', 'Do not display progress bar.');
}

public function init()
{
parent::init();

$this->command('init');
$this->command('known');
$this->command('install');
$this->command('list');
$this->command('use');
$this->command('switch');
$this->command('each');

$this->command('config');
$this->command('info');
$this->command('env');
$this->command('extension');
$this->command('variants');
$this->command('path');
$this->command('cd');
$this->command('download');
$this->command('clean');
$this->command('update');
$this->command('ctags');
$this->command('help');

$this->command('fpm');

$this->command('list-ini', 'PhpBrew\Command\ListIniCommand');
$this->command('self-update', 'PhpBrew\Command\SelfUpdateCommand');

$this->command('remove');
$this->command('purge');

$this->command('off');
$this->command('switch-off', 'PhpBrew\Command\SwitchOffCommand');

$this->command('system');
$this->command('system-off');

$this->configure();


if (!extension_loaded('json')) {
$this->logger->warn('# WARNING: json extension is required for parsing release info.');
}
if (!extension_loaded('libxml')) {
$this->logger->warn('# WARNING: libxml extension is required for parsing pecl package file.');
}
if (!extension_loaded('ctype')) {
$this->logger->warn('# WARNING: ctype extension might be required for parsing yaml file.');
}
}

public function configure()
{

if (extension_loaded('libxml')) {
libxml_use_internal_errors(true);
}

set_time_limit(0);


date_default_timezone_set(Utils::readTimeZone() ?: 'America/Los_Angeles');


$this->getFormatter()->addStyle('bold', array('bold' => 1));

$this->logger->levelStyles['warn'] = 'yellow';
$this->logger->levelStyles['error'] = 'red';
}

public function brief()
{
return 'brew your latest php!';
}

public function runWithTry(array $argv)
{
try {
return $this->run($argv);
} catch (CommandArgumentNotEnoughException $e) {
$this->logger->error($e->getMessage());
$this->logger->writeln('Expected argument prototypes:');
foreach ($e->getCommand()->getAllCommandPrototype() as $p) {
$this->logger->writeln("\t" . $p);
}
$this->logger->newline();
} catch (CommandNotFoundException $e) {
$this->logger->error(
$e->getMessage()
. ' available commands are: '
. implode(', ', $e->getCommand()->getVisibleCommandList())
);
$this->logger->newline();

$this->logger->writeln('Please try the command below to see the details:');
$this->logger->newline();
$this->logger->writeln("\t" . $this->getProgramName() . ' help ');
$this->logger->newline();
} catch (SystemCommandException $e) {


$buildLog = $e->getLogFile();
$this->logger->error('Error: ' . trim($e->getMessage()));

if ($buildLog !== null && file_exists($buildLog)) {
$this->logger->error('The last 5 lines in the log file:');
$lines = array_slice(file($buildLog), -5);
foreach ($lines as $line) {
echo $line , PHP_EOL;
}
$this->logger->error('Please checkout the build log file for more details:');
$this->logger->error("\t tail $buildLog");
}
} catch (BadMethodCallException $e) {
$this->logger->error($e->getMessage());
$this->logger->error('Seems like an application logic error, please contact the developer.');
} catch (Exception $e) {
if ($this->options && $this->options->debug) {
$printer = new DevelopmentExceptionPrinter($this->getLogger());
$printer->dump($e);
} else {
$printer = new ProductionExceptionPrinter($this->getLogger());
$printer->dump($e);
}
}

return false;
}
}
<?php

namespace PhpBrew;

use CLIFramework\Logger;
use PhpBrew\Exception\SystemCommandException;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

class Utils
{
public static function readTimeZone()
{
if (is_readable($tz = '/etc/timezone')) {
$lines = array_filter(file($tz), function ($line) {
return !preg_match('/^#/', $line);
});
if (!empty($lines)) {
return trim($lines[0]);
}
}

return false;
}

public static function support64bit()
{
$int = '9223372036854775807';
$int = intval($int);
if ($int == 9223372036854775807) {


return true;
} elseif ($int == 2147483647) {


return false;
} else {
return false;
}
}








public static function findBinByPrefix($bin)
{
$prefixes = self::getLookupPrefixes();

foreach ($prefixes as $prefix) {
$binPath = $prefix . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . $bin;

if (file_exists($binPath)) {
return $binPath;
}

$binPath = $prefix . DIRECTORY_SEPARATOR . 'sbin' . DIRECTORY_SEPARATOR . $bin;

if (file_exists($binPath)) {
return $binPath;
}
}

return;
}

public static function detectArch($prefix)
{










$multiArchs = array(
'lib/lib64',
'lib/lib32',
'lib64', 
'lib', 
'lib/ia64-linux-gnu', 
'lib/x86_64-linux-gnu', 
'lib/x86_64-kfreebsd-gnu', 
'lib/i386-linux-gnu',
);

return array_filter($multiArchs, function ($archName) use ($prefix) {
return file_exists($prefix . '/' . $archName);
});
}

public static function getLookupPrefixes()
{
$prefixes = array(
'/usr',
'/usr/local',
'/usr/local/opt', 
'/opt',
'/opt/local',
);

if ($pathStr = getenv('PHPBREW_LOOKUP_PREFIX')) {
$paths = explode(':', $pathStr);
foreach ($paths as $path) {
$prefixes[] = $path;
}
}


foreach ($prefixes as $prefix) {
foreach (self::detectArch($prefix) as $arch) {
$prefixes[] = "$prefix/$arch";
}
}

return array_reverse($prefixes);
}

public static function findLibPrefix()
{
$files = func_get_args();
$prefixes = self::getLookupPrefixes();

foreach ($prefixes as $prefix) {
foreach ($files as $file) {
$p = $prefix . DIRECTORY_SEPARATOR . $file;
if (file_exists($p)) {
return $prefix;
}
}
}

return null;
}

public static function findIncludePrefix()
{
$files = func_get_args();
$prefixes = self::getLookupPrefixes();

foreach ($prefixes as $prefix) {
foreach ($files as $file) {
$path = $prefix . DIRECTORY_SEPARATOR . 'include' . DIRECTORY_SEPARATOR . $file;
if (file_exists($path)) {
return $prefix;
}
}
}

return;
}






public static function getPkgConfigPrefix($package)
{
if (!self::findBin('pkg-config')) {
return null;
}

$path = exec('pkg-config --variable=prefix ' . escapeshellarg($package) . ' 2>/dev/null', $_, $ret);

if ($ret !== 0) {
return null;
}

if (!file_exists($path)) {
return null;
}

return $path;
}

public static function system($command, $logger = null, $build = null)
{
if (is_array($command)) {
$command = implode(' ', $command);
}

if ($logger) {
$logger->debug('Running Command:' . $command);
}

$lastline = system($command, $returnValue);
if ($returnValue !== 0) {
throw new SystemCommandException("Command failed: $command returns: $lastline", $build);
}
return $returnValue;
}








public static function findBin($bin)
{
$path = getenv('PATH');
$paths = explode(PATH_SEPARATOR, $path);

foreach ($paths as $path) {
$f = $path . DIRECTORY_SEPARATOR . $bin;

$f = realpath($f);
if ($f !== false) {
return $f;
}
}

return null;
}







public static function findPrefix(array $prefixFinders)
{
foreach ($prefixFinders as $prefixFinder) {
$prefix = $prefixFinder->findPrefix();

if ($prefix !== null) {
return $prefix;
}
}

return null;
}

public static function recursive_unlink($path, Logger $logger)
{
$directoryIterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($it as $file) {
$logger->debug('Deleting ' . $file->getPathname());
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
if (is_dir($path)) {
rmdir($path);
} elseif (is_file($path)) {
unlink($path);
}
}

public static function editor($file)
{
$tty = exec('tty');
$editor = escapeshellarg(getenv('EDITOR') ?: 'nano');
exec("{$editor} {$file} > {$tty}", $_, $ret);

return $ret;
}
}
^@5 |wb+{   GBMB