#!/usr/bin/env php
<?php
Phar::mapPhar();
include 'phar://wp-cli.phar/php/boot-phar.php';
__HALT_COMPILER(); ?>
          wp-cli.phar    #   vendor/wp-cli/wp-cli/php/wp-cli.php_  -h_  y      )   vendor/wp-cli/wp-cli/php/class-wp-cli.php  -h  O u      /   vendor/wp-cli/wp-cli/php/fallback-functions.php\  -h\        '   vendor/wp-cli/wp-cli/php/dispatcher.phpX  -hX        F   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareFallbackFunctions.phpC  -hC  @*Bg      =   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadExecCommand.phpW  -hW  y~      >   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareMainClass.php  -h  Tj      G   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFallbackAutoloader.php  -h  |m      :   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php  -h  A^U      B   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadUtilityFunctions.php)  -h)  TYMݤ      ;   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/BootstrapStep.php  -h  A7/      G   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeRequestsAutoloader.php  -h  }3X      <   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RunnerInstance.php  -h  k      =   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/ConfigureRunner.php  -h  B)Q(      H   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DeclareAbstractBaseCommand.phpA  -hA  @<@      >   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeLogger.php*  -h*  \3      <   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadDispatcher.php5  -h5  U4      A   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LoadRequiredCommand.php  -h  Ӥ      G   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RegisterFrameworkCommands.phpg  -hg  >V      <   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/BootstrapState.php  -h  פ      @   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeContexts.php  -h  0Ca      <   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/AutoloaderStep.php&	  -h&	        D   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/InitializeColorization.phpL  -hL  '=      H   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludeFrameworkAutoloader.php$  -h$  z      7   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/CheckRoot.php  -h        F   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/RegisterDeferredCommands.php  -h  k	      F   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/IncludePackageAutoloader.php  -h  F      E   vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/DefineProtectedCommands.php  -h  8>2      0   vendor/wp-cli/wp-cli/php/WP_CLI/Configurator.php+  -h+  Αˤ      2   vendor/wp-cli/wp-cli/php/WP_CLI/SynopsisParser.php  -h  
      E   vendor/wp-cli/wp-cli/php/WP_CLI/Exception/NonExistentKeyException.php  -h  4      -   vendor/wp-cli/wp-cli/php/WP_CLI/Extractor.php>'  -h>'  m      9   vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php6  -h6  ھ      =   vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php"  -h"  n      ?   vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CompositeCommand.php   -h    ڤ      >   vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandAddition.php#  -h#  躛      :   vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/RootCommand.phpK  -hK  yդ      ?   vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandNamespace.php  -h  ,{      *   vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php  -h  Y#g      1   vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/User.php  -h  ==R
      3   vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Signup.phpt  -ht  lYQj      1   vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Base.php  -h  󯹤      4   vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Comment.php|  -h|  m      1   vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Site.php  -h  F)      1   vendor/wp-cli/wp-cli/php/WP_CLI/Fetchers/Post.php8  -h8  重      .   vendor/wp-cli/wp-cli/php/WP_CLI/ComposerIO.php  -h  мT      /   vendor/wp-cli/wp-cli/php/WP_CLI/Completions.php  -h  Τ      .   vendor/wp-cli/wp-cli/php/WP_CLI/ProcessRun.php(  -h(  c홤      1   vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Quiet.php	  -h	  -n      0   vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Base.php  -h  3T      3   vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Regular.php  -h  [Ф      5   vendor/wp-cli/wp-cli/php/WP_CLI/Loggers/Execution.phpa  -ha  tW      3   vendor/wp-cli/wp-cli/php/WP_CLI/RequestsLibrary.php  -h  Τ      -   vendor/wp-cli/wp-cli/php/WP_CLI/Inflector.phpE@  -hE@  #7      +   vendor/wp-cli/wp-cli/php/WP_CLI/Context.phpM  -hM  [NG      (   vendor/wp-cli/wp-cli/php/WP_CLI/NoOp.php   -h   !      -   vendor/wp-cli/wp-cli/php/WP_CLI/FileCache.phpC"  -hC"  0#/      2   vendor/wp-cli/wp-cli/php/WP_CLI/ContextManager.php  -h  ZϤ      7   vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Exception.phpg   -hg   
4      3   vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Query.php  -h  (      3   vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Table.phpd
  -hd
  p      7   vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/Transform.php  -h        1   vendor/wp-cli/wp-cli/php/WP_CLI/Iterators/CSV.phpY  -hY  2.o      1   vendor/wp-cli/wp-cli/php/WP_CLI/Context/Admin.php  -h  
dɤ      0   vendor/wp-cli/wp-cli/php/WP_CLI/Context/Auto.php  -h  2      /   vendor/wp-cli/wp-cli/php/WP_CLI/Context/Cli.php  -h  A      4   vendor/wp-cli/wp-cli/php/WP_CLI/Context/Frontend.php  -h  Br      .   vendor/wp-cli/wp-cli/php/WP_CLI/Autoloader.php-  -h-  	lѤ      ,   vendor/wp-cli/wp-cli/php/WP_CLI/WpOrgApi.php   -h         -   vendor/wp-cli/wp-cli/php/WP_CLI/DocParser.php  -h  JR"      0   vendor/wp-cli/wp-cli/php/WP_CLI/UpgraderSkin.phpr  -hr        A   vendor/wp-cli/wp-cli/php/WP_CLI/PackageManagerEventSubscriber.php  -h  !Җ      6   vendor/wp-cli/wp-cli/php/WP_CLI/WpHttpCacheManager.php  -h        +   vendor/wp-cli/wp-cli/php/WP_CLI/Process.php  -h  oK      -   vendor/wp-cli/wp-cli/php/WP_CLI/Formatter.php%  -h%  M       M   vendor/wp-cli/wp-cli/php/WP_CLI/Traverser/RecursiveDataStructureTraverser.php  -h  OK      5   vendor/wp-cli/wp-cli/php/WP_CLI/SynopsisValidator.php  -h        1   vendor/wp-cli/wp-cli/php/WP_CLI/ExitException.phpS   -hS   {uׄ      $   vendor/wp-cli/wp-cli/php/boot-fs.php  -h  de      &   vendor/wp-cli/wp-cli/php/bootstrap.php>	  -h>	  )>      (   vendor/wp-cli/wp-cli/php/config-spec.php  -h         %   vendor/wp-cli/wp-cli/php/utils-wp.phpA  -hA  EU      #   vendor/wp-cli/wp-cli/php/compat.php   -h         1   vendor/wp-cli/wp-cli/php/class-wp-cli-command.php   -h   2}ä      "   vendor/wp-cli/wp-cli/php/utils.phpB  -hB  2f      ,   vendor/wp-cli/wp-cli/php/wp-settings-cli.php]C  -h]C  qU      ;   vendor/wp-cli/wp-cli/php/commands/src/CLI_Alias_Command.php8  -h8  	      ;   vendor/wp-cli/wp-cli/php/commands/src/CLI_Cache_Command.php  -h  n?      5   vendor/wp-cli/wp-cli/php/commands/src/CLI_Command.php3b  -h3b  ڤS      6   vendor/wp-cli/wp-cli/php/commands/src/Help_Command.php1  -h1  wޠ      )   vendor/wp-cli/wp-cli/php/commands/cli.php  -h  jn      *   vendor/wp-cli/wp-cli/php/commands/help.php   -h   lD         php/boot-phar.phpG  -hG  uI/      .   vendor/wp-cli/mustache/bin/build_bootstrap.php6  -h6  w      -   vendor/wp-cli/mustache/src/Mustache/Cache.php  -h  W      1   vendor/wp-cli/mustache/src/Mustache/Exception.phpR  -hR  ]u      .   vendor/wp-cli/mustache/src/Mustache/Engine.php1f  -h1f  V      B   vendor/wp-cli/mustache/src/Mustache/Exception/RuntimeException.php  -h  1]Ӥ      H   vendor/wp-cli/mustache/src/Mustache/Exception/UnknownFilterException.php  -h  CwS      J   vendor/wp-cli/mustache/src/Mustache/Exception/InvalidArgumentException.php  -h  Q      H   vendor/wp-cli/mustache/src/Mustache/Exception/UnknownHelperException.php  -h  ҫg4      A   vendor/wp-cli/mustache/src/Mustache/Exception/SyntaxException.php  -h  {Ť      @   vendor/wp-cli/mustache/src/Mustache/Exception/LogicException.php  -h  }A      J   vendor/wp-cli/mustache/src/Mustache/Exception/UnknownTemplateException.php  -h  &]      .   vendor/wp-cli/mustache/src/Mustache/Parser.php4  -h4  TC      ?   vendor/wp-cli/mustache/src/Mustache/Loader/FilesystemLoader.php  -h  L$y      :   vendor/wp-cli/mustache/src/Mustache/Loader/ArrayLoader.php  -h  !      >   vendor/wp-cli/mustache/src/Mustache/Loader/CascadingLoader.php  -h        ;   vendor/wp-cli/mustache/src/Mustache/Loader/StringLoader.php  -h  <%      ;   vendor/wp-cli/mustache/src/Mustache/Loader/InlineLoader.php  -h  \	      I   vendor/wp-cli/mustache/src/Mustache/Loader/ProductionFilesystemLoader.phpf  -hf        <   vendor/wp-cli/mustache/src/Mustache/Loader/MutableLoader.php  -h  g      7   vendor/wp-cli/mustache/src/Mustache/Cache/NoopCache.phpA  -hA  ٤      =   vendor/wp-cli/mustache/src/Mustache/Cache/FilesystemCache.phph  -hh  (}4      ;   vendor/wp-cli/mustache/src/Mustache/Cache/AbstractCache.php  -h  Y`      8   vendor/wp-cli/mustache/src/Mustache/HelperCollection.php  -h  Ӥ      /   vendor/wp-cli/mustache/src/Mustache/Context.php!  -h!  >0      .   vendor/wp-cli/mustache/src/Mustache/Logger.php$  -h$  @Y9      0   vendor/wp-cli/mustache/src/Mustache/Template.php1  -h1  Mu      1   vendor/wp-cli/mustache/src/Mustache/Tokenizer.php
5  -h
5  ;Ĥ      =   vendor/wp-cli/mustache/src/Mustache/Logger/AbstractLogger.phpv  -hv  nY6      ;   vendor/wp-cli/mustache/src/Mustache/Logger/StreamLogger.php  -h  J      2   vendor/wp-cli/mustache/src/Mustache/Autoloader.php  -h  =c֤      .   vendor/wp-cli/mustache/src/Mustache/Source.php  -h  b׶m      0   vendor/wp-cli/mustache/src/Mustache/Compiler.php	a  -h	a  GФ      ?   vendor/wp-cli/mustache/src/Mustache/Source/FilesystemSource.php  -h  V      4   vendor/wp-cli/mustache/src/Mustache/LambdaHelper.php  -h  pդ      .   vendor/wp-cli/mustache/src/Mustache/Loader.phpB  -hB  Qy      )   vendor/wp-cli/process/Pipes/UnixPipes.php,  -h,  q      ,   vendor/wp-cli/process/Pipes/WindowsPipes.phpu  -hu  u      .   vendor/wp-cli/process/Pipes/PipesInterface.php  -h  +      -   vendor/wp-cli/process/Pipes/AbstractPipes.php  -h  <      6   vendor/wp-cli/process/Exception/ExceptionInterface.php  -h  <      4   vendor/wp-cli/process/Exception/RuntimeException.php  -h  >H      <   vendor/wp-cli/process/Exception/InvalidArgumentException.php  -h  ˅      <   vendor/wp-cli/process/Exception/ProcessTimedOutException.php{  -h{  4      2   vendor/wp-cli/process/Exception/LogicException.php  -h  W      :   vendor/wp-cli/process/Exception/ProcessFailedException.php  -h  P5      *   vendor/wp-cli/process/ExecutableFinder.phpO  -hO  tm      &   vendor/wp-cli/process/ProcessUtils.php  -h  aXa      (   vendor/wp-cli/process/ProcessBuilder.php
  -h
  j'Uh      !   vendor/wp-cli/process/Process.phpq  -hq  D>o      $   vendor/wp-cli/process/PhpProcess.php	  -h	        -   vendor/wp-cli/process/PhpExecutableFinder.phph
  -hh
        %   vendor/wp-cli/process/InputStream.php	  -h	  w'Ȥ      *   vendor/eftec/bladeone/lib/BladeOneLang.phpm  -hm  V      *   vendor/eftec/bladeone/lib/BladeOneHtml.phpL  -hL  N      0   vendor/eftec/bladeone/lib/BladeOneCacheRedis.php  -h  vq)      &   vendor/eftec/bladeone/lib/BladeOne.php -h $      ,   vendor/eftec/bladeone/lib/BladeOneCustom.php  -h  c|	      +   vendor/eftec/bladeone/lib/BladeOneCache.php+  -h+  z<      3   vendor/eftec/bladeone/lib/BladeOneHtmlBootstrap.php[(  -h[(  ![$      @   vendor/wp-cli/wp-cli/bundle/rmccue/requests/library/Requests.php  -h  .      B   vendor/wp-cli/wp-cli/bundle/rmccue/requests/library/Deprecated.php!  -h!  Z+s      G   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Transport/Fsockopen.php>  -h>  YP      B   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Transport/Curl.phpsL  -hsL  j;ۤ      <   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Response.php  -h  ח      <   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Autoload.phpw$  -hw$  r      =   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception.phpZ  -hZ  _      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Transport/Curl.phpu  -hu  *      G   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Transport.php   -h   iA      K   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/ArgumentCount.php  -h  q1      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status418.php,  -h,  4      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status402.php  -h  {̤      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status503.php  -h  w;      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status408.php  -h  kTϤ      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status404.php  -h  y棤      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status416.php  -h  孤      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status414.php  -h  2d      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status401.php  -h         P   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/StatusUnknown.php  -h  *      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status410.php  -h  η.p      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status431.phpe  -he  &X      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status415.php  -h  P      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status411.php  -h  [F      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status413.php  -h  hm      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status502.php  -h        L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status306.php  -h  h$a      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status304.php  -h        L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status409.php  -h        L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status505.php  -h  m      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status405.php  -h  wא      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status406.php  -h  Sbդ      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status403.php  -h        L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status400.php  -h  ǿH7      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status407.php  -h  ]      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status412.php  -h  `      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status305.php  -h        L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status511.phpe  -he  ˤ      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status417.php  -h  f+      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status429.phps  -hs  (ɤ      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status504.php  -h  kf      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status501.php  -h  mk      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status428.phpG  -hG  ^:      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http/Status500.php  -h         M   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/InvalidArgument.phpR  -hR  ˤ      B   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Exception/Http.php  -h  &      7   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Ssl.php1  -h1  w	׺      <   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Requests.phpф  -hф  ㋵      9   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Hooks.phpj  -hj  ]>      =   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Transport.php  -h  ,S      L   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Utility/FilteredIterator.phpm  -hm        U   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Utility/CaseInsensitiveDictionary.php	  -h	  5L      J   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Utility/InputValidator.php	  -h	  ^	      8   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Ipv6.php  -h  v'      8   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Port.php  -h  Ҥ      >   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Proxy/Http.phpy  -hy  g^      7   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Iri.phpq  -hq  h      8   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Auth.php\  -h\        >   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Auth/Basic.php	  -h	  Z      ;   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Session.php%#  -h%#  L      D   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Response/Headers.php  -h  ^ͤ      :   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Cookie.php<  -h<  JMؤ      ?   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/IdnaEncoder.php0  -h0  SϤ      >   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Cookie/Jar.php  -h  84      >   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Capability.php  -h  ޣ@      9   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/Proxy.phpc  -hc  Մe      ?   vendor/wp-cli/wp-cli/bundle/rmccue/requests/src/HookManager.php  -h  C         vendor/composer/installed.phph  -hh  ;e         vendor/composer/ClassLoader.php>  -h>  5Ky      2   vendor/composer/spdx-licenses/src/SpdxLicenses.phpw&  -hw&  e K      *   vendor/composer/composer/src/bootstrap.php  -h  u)      C   vendor/composer/composer/src/Composer/Console/GithubActionError.php$	  -h$	  TH      E   vendor/composer/composer/src/Composer/Console/HtmlOutputFormatter.php  -h  : B      =   vendor/composer/composer/src/Composer/Console/Application.phpNd  -hNd  B      /   vendor/composer/composer/src/Composer/Cache.php)  -h)  ,      2   vendor/composer/composer/src/Composer/Util/Git.phpV  -hV  {0      8   vendor/composer/composer/src/Composer/Util/Bitbucket.phpr$  -hr$  AZԤ      =   vendor/composer/composer/src/Composer/Util/ComposerMirror.php
  -h
  D      1   vendor/composer/composer/src/Composer/Util/Hg.phpU  -hU  j       3   vendor/composer/composer/src/Composer/Util/Loop.php  -h  =,ͤ      >   vendor/composer/composer/src/Composer/Util/ProcessExecutor.php<  -h<  I      9   vendor/composer/composer/src/Composer/Util/Filesystem.php|q  -h|q  4g      <   vendor/composer/composer/src/Composer/Util/PackageSorter.phpH  -hH  )      8   vendor/composer/composer/src/Composer/Util/TlsHelper.phpq  -hq  z w      7   vendor/composer/composer/src/Composer/Util/Perforce.phpQ  -hQ  <+0      7   vendor/composer/composer/src/Composer/Util/Silencer.php  -h  >      =   vendor/composer/composer/src/Composer/Util/NoProxyPattern.php,  -h,  g      B   vendor/composer/composer/src/Composer/Util/Http/CurlDownloader.phpl  -hl  m      <   vendor/composer/composer/src/Composer/Util/Http/Response.php  -h  ڦ      ?   vendor/composer/composer/src/Composer/Util/Http/ProxyHelper.php  -h  ;:h      @   vendor/composer/composer/src/Composer/Util/Http/RequestProxy.php  -h  ,:N      @   vendor/composer/composer/src/Composer/Util/Http/ProxyManager.php  -h  t¤      @   vendor/composer/composer/src/Composer/Util/Http/CurlResponse.php  -h  t      9   vendor/composer/composer/src/Composer/Util/SyncHelper.php	  -h	  ۊd      2   vendor/composer/composer/src/Composer/Util/Url.php  -h  ~[      2   vendor/composer/composer/src/Composer/Util/Svn.phpi(  -hi(  mޣ      =   vendor/composer/composer/src/Composer/Util/HttpDownloader.phpNH  -hNH  UM      2   vendor/composer/composer/src/Composer/Util/Tar.phpX  -hX  W	W      ;   vendor/composer/composer/src/Composer/Util/ErrorHandler.php  -h   R      9   vendor/composer/composer/src/Composer/Util/AuthHelper.php7  -h7  /      >   vendor/composer/composer/src/Composer/Util/ConfigValidator.php"  -h"  ^      2   vendor/composer/composer/src/Composer/Util/Zip.php  -h  fU:      5   vendor/composer/composer/src/Composer/Util/GitHub.phpw  -hw  <@      ?   vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php
  -h
  x      8   vendor/composer/composer/src/Composer/Util/IniHelper.phpc  -hc  ,      ?   vendor/composer/composer/src/Composer/Util/MetadataMinifier.phpq  -hq  tX      7   vendor/composer/composer/src/Composer/Util/Platform.php  -h  uZ      5   vendor/composer/composer/src/Composer/Util/GitLab.phps  -hs  .      C   vendor/composer/composer/src/Composer/Util/StreamContextFactory.phpF%  -hF%  {)Az      R   vendor/composer/composer/src/Composer/Exception/IrrecoverableDownloadException.php  -h  -      B   vendor/composer/composer/src/Composer/Exception/NoSslException.php  -h  8M5      0   vendor/composer/composer/src/Composer/Config.phpX  -hX  ]`I      >   vendor/composer/composer/src/Composer/Autoload/ClassLoader.php>  -h>  5Ky      A   vendor/composer/composer/src/Composer/Autoload/PhpFileCleaner.php
  -h
  63      D   vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php  -h  '      D   vendor/composer/composer/src/Composer/Autoload/ClassMapGenerator.php3  -h3  ID      C   vendor/composer/composer/src/Composer/Plugin/PreCommandRunEvent.phpM  -hM  Ò@	      F   vendor/composer/composer/src/Composer/Plugin/PostFileDownloadEvent.php  -h  Q      K   vendor/composer/composer/src/Composer/Plugin/Capability/CommandProvider.php_  -h_  μ      F   vendor/composer/composer/src/Composer/Plugin/Capability/Capability.php  -h  Y93      =   vendor/composer/composer/src/Composer/Plugin/PluginEvents.php'  -h'  =      C   vendor/composer/composer/src/Composer/Plugin/PrePoolCreateEvent.php  -h  r      =   vendor/composer/composer/src/Composer/Plugin/CommandEvent.php  -h  Y>      >   vendor/composer/composer/src/Composer/Plugin/PluginManager.php  -h        @   vendor/composer/composer/src/Composer/Plugin/PluginInterface.php  -h  L3]      E   vendor/composer/composer/src/Composer/Plugin/PreFileDownloadEvent.php  -h  R      G   vendor/composer/composer/src/Composer/Plugin/PluginBlockedException.php  -h  %:      8   vendor/composer/composer/src/Composer/Plugin/Capable.php  -h  '}      =   vendor/composer/composer/src/Composer/SelfUpdate/Versions.php  -h  U      9   vendor/composer/composer/src/Composer/SelfUpdate/Keys.php  -h  D      ;   vendor/composer/composer/src/Composer/InstalledVersions.php>  -h>  {`      =   vendor/composer/composer/src/Composer/Script/ScriptEvents.php'  -h'   Ƥ      6   vendor/composer/composer/src/Composer/Script/Event.php[  -h[  &mԤ      A   vendor/composer/composer/src/Composer/Config/JsonConfigSource.phpB)  -hB)  P      F   vendor/composer/composer/src/Composer/Config/ConfigSourceInterface.php	  -h	  o      M   vendor/composer/composer/src/Composer/Question/StrictConfirmationQuestion.php
  -h
  ;      F   vendor/composer/composer/src/Composer/Json/JsonValidationException.phpe  -he  y̤      >   vendor/composer/composer/src/Composer/Json/JsonManipulator.php+Q  -h+Q  @      7   vendor/composer/composer/src/Composer/Json/JsonFile.php+  -h+  Q٤      <   vendor/composer/composer/src/Composer/Json/JsonFormatter.php  -h  D|      B   vendor/composer/composer/src/Composer/Command/ProhibitsCommand.php  -h  DD      =   vendor/composer/composer/src/Composer/Command/ShowCommand.php  -h  :      >   vendor/composer/composer/src/Composer/Command/AboutCommand.php  -h  qy9      @   vendor/composer/composer/src/Composer/Command/ArchiveCommand.php  -h  %z      A   vendor/composer/composer/src/Composer/Command/SuggestsCommand.php  -h  Qc      =   vendor/composer/composer/src/Composer/Command/FundCommand.php$  -h$  2C      J   vendor/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.phpI  -hI  `KY      ?   vendor/composer/composer/src/Composer/Command/UpdateCommand.phpA  -hA  J~X      ?   vendor/composer/composer/src/Composer/Command/GlobalCommand.php  -h  z@~      A   vendor/composer/composer/src/Composer/Command/OutdatedCommand.php  -h  L      B   vendor/composer/composer/src/Composer/Command/RunScriptCommand.phpg  -hg  ⶤ      ?   vendor/composer/composer/src/Composer/Command/ConfigCommand.phpq  -hq  FB      @   vendor/composer/composer/src/Composer/Command/DependsCommand.php  -h  m      =   vendor/composer/composer/src/Composer/Command/BaseCommand.phps(  -hs(  s?\      =   vendor/composer/composer/src/Composer/Command/InitCommand.php  -h  23,      A   vendor/composer/composer/src/Composer/Command/DiagnoseCommand.phpp  -hp  k2      ?   vendor/composer/composer/src/Composer/Command/RemoveCommand.php-8  -h-8  YU      @   vendor/composer/composer/src/Composer/Command/InstallCommand.php5  -h5  ȯ      C   vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php  -h  X0<ˤ      @   vendor/composer/composer/src/Composer/Command/RequireCommand.phpOY  -hOY  #      =   vendor/composer/composer/src/Composer/Command/ExecCommand.php  -h  Β      A   vendor/composer/composer/src/Composer/Command/LicensesCommand.php  -h  zW      =   vendor/composer/composer/src/Composer/Command/HomeCommand.php  -h  oL      ?   vendor/composer/composer/src/Composer/Command/SearchCommand.php  -h  A      B   vendor/composer/composer/src/Composer/Command/ReinstallCommand.phph!  -hh!  n      D   vendor/composer/composer/src/Composer/Command/ScriptAliasCommand.php  -h  ^f̤      E   vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php  -h  (4      C   vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.phpf  -hf  u      F   vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php`  -h`  xb      G   vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php#  -h#  &      ?   vendor/composer/composer/src/Composer/Command/StatusCommand.php/!  -h/!        A   vendor/composer/composer/src/Composer/Command/ValidateCommand.php,-  -h,-        k   vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterFactory.php  -h  ~      q   vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreNothingPlatformRequirementFilter.php'  -h'  u8      m   vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterInterface.php   -h   V      m   vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreAllPlatformRequirementFilter.phpu  -hu  v      n   vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php	  -h	  TɅ      3   vendor/composer/composer/src/Composer/IO/BaseIO.phpt  -ht  x      5   vendor/composer/composer/src/Composer/IO/BufferIO.php  -h  IL[      3   vendor/composer/composer/src/Composer/IO/NullIO.php  -h  D      6   vendor/composer/composer/src/Composer/IO/ConsoleIO.php*  -h*  j&U      8   vendor/composer/composer/src/Composer/IO/IOInterface.php   -h   Z      :   vendor/composer/composer/src/Composer/Platform/Version.php@  -h@  .-k      :   vendor/composer/composer/src/Composer/Platform/Runtime.phpN	  -hN	  *`      ?   vendor/composer/composer/src/Composer/Platform/HhvmDetector.php  -h  c˲      2   vendor/composer/composer/src/Composer/Composer.php	  -h	  *      O   vendor/composer/composer/src/Composer/DependencyResolver/SolverBugException.php,  -h,  fo      b   vendor/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasInstalledOperation.php  -h  D
Ф      V   vendor/composer/composer/src/Composer/DependencyResolver/Operation/SolverOperation.php  -h  i`<      d   vendor/composer/composer/src/Composer/DependencyResolver/Operation/MarkAliasUninstalledOperation.php  -h  8 ˤ      Y   vendor/composer/composer/src/Composer/DependencyResolver/Operation/OperationInterface.php  -h  
Y/z      Y   vendor/composer/composer/src/Composer/DependencyResolver/Operation/UninstallOperation.php*  -h*  .n      W   vendor/composer/composer/src/Composer/DependencyResolver/Operation/InstallOperation.php@  -h@  $Z@      V   vendor/composer/composer/src/Composer/DependencyResolver/Operation/UpdateOperation.phpN  -hN  }      C   vendor/composer/composer/src/Composer/DependencyResolver/Solver.phph  -hh        J   vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php|
  -h|
        H   vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php  -h  P{      H   vendor/composer/composer/src/Composer/DependencyResolver/PoolBuilder.phpy  -hy  k|      J   vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.phpt  -ht  g      D   vendor/composer/composer/src/Composer/DependencyResolver/RuleSet.php  -h  ) y      H   vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php6  -h6        Q   vendor/composer/composer/src/Composer/DependencyResolver/LocalRepoTransaction.php  -h  ,4      K   vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchChain.php  -h  ջ      J   vendor/composer/composer/src/Composer/DependencyResolver/PoolOptimizer.phpM  -hM  b*      D   vendor/composer/composer/src/Composer/DependencyResolver/Problem.phpl  -hl  _Sl      A   vendor/composer/composer/src/Composer/DependencyResolver/Rule.phpO  -hO  dk      L   vendor/composer/composer/src/Composer/DependencyResolver/RuleSetIterator.phpp  -hp  k      N   vendor/composer/composer/src/Composer/DependencyResolver/MultiConflictRule.php7
  -h7
  lX      M   vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php4  -h4  ;      F   vendor/composer/composer/src/Composer/DependencyResolver/Decisions.php  -h  =Τ      J   vendor/composer/composer/src/Composer/DependencyResolver/DefaultPolicy.php  -h  ZŤ      A   vendor/composer/composer/src/Composer/DependencyResolver/Pool.php!  -h!  "gp      L   vendor/composer/composer/src/Composer/DependencyResolver/LockTransaction.php_  -h_  DX      T   vendor/composer/composer/src/Composer/DependencyResolver/SolverProblemsException.php  -h  %ݤ      K   vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchGraph.phpW  -hW  A\Ф      D   vendor/composer/composer/src/Composer/DependencyResolver/Request.php*   -h*   5&>w      L   vendor/composer/composer/src/Composer/DependencyResolver/PolicyInterface.php  -h  Pj      =   vendor/composer/composer/src/Composer/Package/RootPackage.php
  -h
  z      A   vendor/composer/composer/src/Composer/Package/CompletePackage.phpU  -hU  do֤      C   vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php7  -h7  J鱄      6   vendor/composer/composer/src/Composer/Package/Link.php  -h  OE      P   vendor/composer/composer/src/Composer/Package/Loader/InvalidPackageException.php&  -h&  I      H   vendor/composer/composer/src/Composer/Package/Loader/LoaderInterface.phpz  -hz  3H      D   vendor/composer/composer/src/Composer/Package/Loader/ArrayLoader.phpE  -hE        N   vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php^q  -h^q  ?t      C   vendor/composer/composer/src/Composer/Package/Loader/JsonLoader.php  -h  Y      J   vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php,  -h,  Y*ޤ      B   vendor/composer/composer/src/Composer/Package/PackageInterface.php-  -h-  _      H   vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.phpr@  -hr@  X      I   vendor/composer/composer/src/Composer/Package/Version/VersionSelector.php(  -h(  Zb]      I   vendor/composer/composer/src/Composer/Package/Version/StabilityFilter.php)  -h)  ?Zՠ      G   vendor/composer/composer/src/Composer/Package/Version/VersionParser.php  -h  3Mդ      =   vendor/composer/composer/src/Composer/Package/BasePackage.php  -h  $p      9   vendor/composer/composer/src/Composer/Package/Package.phpE  -hE  <2      D   vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php3  -h3  #      >   vendor/composer/composer/src/Composer/Package/AliasPackage.php%  -h%  +      I   vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php  -h  qۤ      L   vendor/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php  -h  /D       K   vendor/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php  -h  ̀դ      P   vendor/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFilter.php]  -h]  a      F   vendor/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php  -h  ).      P   vendor/composer/composer/src/Composer/Package/Archiver/ArchivableFilesFinder.phpj  -hj  _]      L   vendor/composer/composer/src/Composer/Package/Archiver/ArchiverInterface.phpj  -hj  ]aC      G   vendor/composer/composer/src/Composer/Package/Archiver/PharArchiver.php  -h  R}      P   vendor/composer/composer/src/Composer/Package/Archiver/ComposerExcludeFilter.phpZ  -hZ  k      B   vendor/composer/composer/src/Composer/Package/RootAliasPackage.php  -h  ;+      F   vendor/composer/composer/src/Composer/Package/CompleteAliasPackage.phpp  -hp  N\      8   vendor/composer/composer/src/Composer/Package/Locker.phpE  -hE  ;      F   vendor/composer/composer/src/Composer/Package/RootPackageInterface.php1  -h1  ;A      J   vendor/composer/composer/src/Composer/Package/CompletePackageInterface.php  -h  G      2   vendor/composer/composer/src/Composer/Compiler.phpm0  -hm0  0      1   vendor/composer/composer/src/Composer/Factory.php0x  -h0x  (      I   vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.phpD^  -hD^  7D      R   vendor/composer/composer/src/Composer/EventDispatcher/ScriptExecutionException.php  -h  \!'Ƥ      ?   vendor/composer/composer/src/Composer/EventDispatcher/Event.php  -h  JvU      R   vendor/composer/composer/src/Composer/EventDispatcher/EventSubscriberInterface.php\  -h\  *      3   vendor/composer/composer/src/Composer/Installer.php  -h        C   vendor/composer/composer/src/Composer/Installer/InstallerEvents.php{  -h{  3      B   vendor/composer/composer/src/Composer/Installer/InstallerEvent.php  -h  ~,      A   vendor/composer/composer/src/Composer/Installer/PackageEvents.php  -h  ZV      H   vendor/composer/composer/src/Composer/Installer/MetapackageInstaller.php  -h  {      C   vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php9  -h9  ˎj2      K   vendor/composer/composer/src/Composer/Installer/BinaryPresenceInterface.php  -h        G   vendor/composer/composer/src/Composer/Installer/InstallationManager.phpb  -hb  u#      M   vendor/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php!  -h!  K)S      A   vendor/composer/composer/src/Composer/Installer/NoopInstaller.php  -h        F   vendor/composer/composer/src/Composer/Installer/InstallerInterface.php  -h  Oh      D   vendor/composer/composer/src/Composer/Installer/ProjectInstaller.php  -h  3+      D   vendor/composer/composer/src/Composer/Installer/LibraryInstaller.phpA*  -hA*  t\Ƭ      C   vendor/composer/composer/src/Composer/Installer/PluginInstaller.php,  -h,        @   vendor/composer/composer/src/Composer/Installer/PackageEvent.phpM
  -hM
  ?y%      G   vendor/composer/composer/src/Composer/Repository/ComposerRepository.php9  -h9  T      G   vendor/composer/composer/src/Composer/Repository/PlatformRepository.php~  -h~  [      J   vendor/composer/composer/src/Composer/Repository/RootPackageRepository.php
  -h
  bS"      H   vendor/composer/composer/src/Composer/Repository/CompositeRepository.phpk  -hk  !`U      F   vendor/composer/composer/src/Composer/Repository/PackageRepository.php  -h  ~Ф      C   vendor/composer/composer/src/Composer/Repository/PathRepository.php  -h        H   vendor/composer/composer/src/Composer/Repository/InstalledRepository.php2  -h2  8h      G   vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php_  -h_  1      D   vendor/composer/composer/src/Composer/Repository/ArrayRepository.php)  -h)  bZ      E   vendor/composer/composer/src/Composer/Repository/FilterRepository.phpG  -hG  *      M   vendor/composer/composer/src/Composer/Repository/InstalledArrayRepository.php  -h  i      B   vendor/composer/composer/src/Composer/Repository/VcsRepository.phpQ  -hQ  ( u      R   vendor/composer/composer/src/Composer/Repository/InstalledFilesystemRepository.php  -h  ޡx      H   vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php  -h  9      J   vendor/composer/composer/src/Composer/Repository/VersionCacheInterface.php  -h  mY      P   vendor/composer/composer/src/Composer/Repository/WritableRepositoryInterface.php  -h  )놤      H   vendor/composer/composer/src/Composer/Repository/LockArrayRepository.phpm  -hm  !      L   vendor/composer/composer/src/Composer/Repository/WritableArrayRepository.php	  -h	  O      O   vendor/composer/composer/src/Composer/Repository/InvalidRepositoryException.php  -h  $      F   vendor/composer/composer/src/Composer/Repository/RepositoryFactory.php  -h  Wla?      T   vendor/composer/composer/src/Composer/Repository/ConfigurableRepositoryInterface.php  -h        F   vendor/composer/composer/src/Composer/Repository/RepositoryManager.php  -h   g}      P   vendor/composer/composer/src/Composer/Repository/RepositorySecurityException.php  -h  <9      C   vendor/composer/composer/src/Composer/Repository/PearRepository.php2  -h2  '      I   vendor/composer/composer/src/Composer/Repository/FilesystemRepository.php\7  -h\7  t{      B   vendor/composer/composer/src/Composer/Repository/RepositorySet.php2  -h2        B   vendor/composer/composer/src/Composer/Repository/Vcs/VcsDriver.php  -h  7Rm      K   vendor/composer/composer/src/Composer/Repository/Vcs/GitBitbucketDriver.php@  -h@  Zkn      B   vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php0  -h0  ;      B   vendor/composer/composer/src/Composer/Repository/Vcs/GitDriver.php  -h  
RԤ      E   vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.phpS  -hS  yj      K   vendor/composer/composer/src/Composer/Repository/Vcs/VcsDriverInterface.php%  -h%  %      E   vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php3O  -h3O  .\      E   vendor/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php  -h  dr      A   vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php,  -h,  *Yɤ      G   vendor/composer/composer/src/Composer/Repository/Vcs/PerforceDriver.php  -h  hc      Q   vendor/composer/composer/src/Composer/Repository/InstalledRepositoryInterface.phpd  -hd  Y8O      H   vendor/composer/composer/src/Composer/Downloader/FilesystemException.php#  -h#  Q{(      Q   vendor/composer/composer/src/Composer/Downloader/MaxFileSizeExceededException.phpo  -ho  :      L   vendor/composer/composer/src/Composer/Downloader/DvcsDownloaderInterface.php  -h  v(      B   vendor/composer/composer/src/Composer/Downloader/TarDownloader.php$  -h$  3      G   vendor/composer/composer/src/Composer/Downloader/TransportException.php)  -h)  4 N      G   vendor/composer/composer/src/Composer/Downloader/PerforceDownloader.php/  -h/   :      E   vendor/composer/composer/src/Composer/Downloader/FossilDownloader.php  -h        B   vendor/composer/composer/src/Composer/Downloader/RarDownloader.php	  -h	  K      A   vendor/composer/composer/src/Composer/Downloader/HgDownloader.php  -h  |p      B   vendor/composer/composer/src/Composer/Downloader/GitDownloader.phpc  -hc  ۤ      H   vendor/composer/composer/src/Composer/Downloader/DownloaderInterface.php  -h  xD      C   vendor/composer/composer/src/Composer/Downloader/FileDownloader.phpwL  -hwL        F   vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php!  -h!  M      R   vendor/composer/composer/src/Composer/Downloader/VcsCapableDownloaderInterface.php  -h        B   vendor/composer/composer/src/Composer/Downloader/VcsDownloader.phpJ2  -hJ2  {      C   vendor/composer/composer/src/Composer/Downloader/GzipDownloader.phpx  -hx  ˕      C   vendor/composer/composer/src/Composer/Downloader/PathDownloader.php-2  -h-2  d      J   vendor/composer/composer/src/Composer/Downloader/ChangeReportInterface.php  -h  )Ÿ      C   vendor/composer/composer/src/Composer/Downloader/PharDownloader.php  -h  `      B   vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php0  -h0  {HѤ      D   vendor/composer/composer/src/Composer/Downloader/DownloadManager.phpa>  -ha>        B   vendor/composer/composer/src/Composer/Downloader/SvnDownloader.php"  -h"  8+      A   vendor/composer/composer/src/Composer/Downloader/XzDownloader.php  -h  ʤ      '   vendor/composer/semver/src/Interval.php~  -h~  E|V      =   vendor/composer/semver/src/Constraint/MatchNoneConstraint.php  -h  ?T>      4   vendor/composer/semver/src/Constraint/Constraint.php1  -h1  .      <   vendor/composer/semver/src/Constraint/MatchAllConstraint.php  -h  D      /   vendor/composer/semver/src/Constraint/Bound.phpe
  -he
  M      9   vendor/composer/semver/src/Constraint/MultiConstraint.phpA%  -hA%  w      =   vendor/composer/semver/src/Constraint/ConstraintInterface.php  -h  vx      /   vendor/composer/semver/src/CompilingMatcher.php   -h   }~@      )   vendor/composer/semver/src/Comparator.phpD
  -hD
  Ș܁      %   vendor/composer/semver/src/Semver.php?  -h?  =      (   vendor/composer/semver/src/Intervals.phpO  -hO  3      ,   vendor/composer/semver/src/VersionParser.phpAV  -hAV  n!Z      *   vendor/composer/ca-bundle/src/CaBundle.phpE  -hE  Ć¤      !   vendor/composer/autoload_psr4.phpd
  -hd
        %   vendor/composer/InstalledVersions.php>  -h>  {`      "   vendor/composer/platform_check.php  -h  Tt      :   vendor/composer/metadata-minifier/src/MetadataMinifier.php
  -h
  l3      '   vendor/composer/autoload_namespaces.php  -h  ?v]g      "   vendor/composer/autoload_files.php  -h  g~e      %   vendor/composer/autoload_classmap.php9  -h9  F      !   vendor/composer/autoload_real.phpE
  -hE
  y򡗤      -   vendor/composer/xdebug-handler/src/Status.php+  -h+  &e      4   vendor/composer/xdebug-handler/src/XdebugHandler.phpU  -hU  _Q      0   vendor/composer/xdebug-handler/src/PhpConfig.php  -h  Q=D      .   vendor/composer/xdebug-handler/src/Process.phpw  -hw  ð      3   vendor/composer/pcre/src/MatchWithOffsetsResult.php  -h  pa8w      *   vendor/composer/pcre/src/ReplaceResult.php  -h  K2      !   vendor/composer/pcre/src/Preg.php>*  -h>*  6%Ƥ      (   vendor/composer/pcre/src/MatchResult.php  -h        +   vendor/composer/pcre/src/MatchAllResult.phpv  -hv  *:      "   vendor/composer/pcre/src/Regex.phpa  -ha  X~      6   vendor/composer/pcre/src/MatchAllWithOffsetsResult.php  -h  -      *   vendor/composer/pcre/src/PcreException.php  -h  e,      #   vendor/composer/autoload_static.phpo  -ho  A7      .   vendor/symfony/polyfill-mbstring/bootstrap.php  -h  m|D      -   vendor/symfony/polyfill-mbstring/Mbstring.phpn  -hn  p^C      F   vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php9  -h9  >|zK      @   vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php`  -h`  S      @   vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php_  -h_  Z      D   vendor/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8?  -h?        6   vendor/symfony/finder/Exception/ExceptionInterface.php"  -h"  ڀfW      9   vendor/symfony/finder/Exception/AccessDeniedException.php  -h  cWޤ          vendor/symfony/finder/Finder.php{N  -h{N  I      9   vendor/symfony/finder/Iterator/FilenameFilterIterator.php  -h  p      <   vendor/symfony/finder/Iterator/FilecontentFilterIterator.php  -h  r~      =   vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php.  -h.  sӤ      9   vendor/symfony/finder/Iterator/FileTypeFilterIterator.php>  -h>  pY      A   vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php	  -h	  t褤      7   vendor/symfony/finder/Iterator/CustomFilterIterator.php  -h         5   vendor/symfony/finder/Iterator/PathFilterIterator.php  -h  }      =   vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.phpz  -hz  6즤      1   vendor/symfony/finder/Iterator/FilterIterator.php  -h  VASs      3   vendor/symfony/finder/Iterator/SortableIterator.php@
  -h@
  [       :   vendor/symfony/finder/Iterator/DateRangeFilterIterator.php  -h  $99      ;   vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php  -h  *      :   vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php  -h  8K         vendor/symfony/finder/Glob.php  -h  {      5   vendor/symfony/finder/Comparator/NumberComparator.php
  -h
        /   vendor/symfony/finder/Comparator/Comparator.php  -h  ~4ؤ      3   vendor/symfony/finder/Comparator/DateComparator.php  -h  Gä      %   vendor/symfony/finder/SplFileInfo.phpW  -hW  !tVb      9   vendor/symfony/console/Formatter/OutputFormatterStyle.php2  -h2  S      B   vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php<  -h<  Z      4   vendor/symfony/console/Formatter/OutputFormatter.php  -h  Nx      >   vendor/symfony/console/Formatter/OutputFormatterStyleStack.php	  -h	  Ҥ      =   vendor/symfony/console/Formatter/OutputFormatterInterface.php  -h  #7u      /   vendor/symfony/console/Output/ConsoleOutput.php  -h  JDb      (   vendor/symfony/console/Output/Output.php{  -h{  7      ,   vendor/symfony/console/Output/NullOutput.phpn  -hn  tD      0   vendor/symfony/console/Output/BufferedOutput.phpI  -hI  \      8   vendor/symfony/console/Output/ConsoleOutputInterface.php  -h        .   vendor/symfony/console/Output/StreamOutput.phpo  -ho  ~      1   vendor/symfony/console/Output/OutputInterface.php  -h  &      9   vendor/symfony/console/Descriptor/DescriptorInterface.php  -h  PZ      3   vendor/symfony/console/Descriptor/XmlDescriptor.php#  -h#  dK      <   vendor/symfony/console/Descriptor/ApplicationDescription.php  -h        8   vendor/symfony/console/Descriptor/MarkdownDescriptor.php  -h  f 0>      4   vendor/symfony/console/Descriptor/TextDescriptor.phpf0  -hf0  W      0   vendor/symfony/console/Descriptor/Descriptor.phpd  -hd  T      4   vendor/symfony/console/Descriptor/JsonDescriptor.php  -h  n      7   vendor/symfony/console/Exception/ExceptionInterface.php  -h  U      5   vendor/symfony/console/Exception/RuntimeException.php  -h  *b      =   vendor/symfony/console/Exception/InvalidArgumentException.php  -h  u i      =   vendor/symfony/console/Exception/CommandNotFoundException.php  -h  .o      ;   vendor/symfony/console/Exception/InvalidOptionException.php  -h  ;      3   vendor/symfony/console/Exception/LogicException.php  -h  SML      D   vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php  -h  A|\      (   vendor/symfony/console/ConsoleEvents.php!  -h!  Ω      6   vendor/symfony/console/EventListener/ErrorListener.php
  -h
  e?ߤ      0   vendor/symfony/console/Helper/TableSeparator.php  -h  &      +   vendor/symfony/console/Helper/HelperSet.php	  -h	  3C      (   vendor/symfony/console/Helper/Helper.php  -h  }Ku      0   vendor/symfony/console/Helper/QuestionHelper.php B  -h B  ݗ^      +   vendor/symfony/console/Helper/TableCell.phpR  -hR  J{      6   vendor/symfony/console/Helper/DebugFormatterHelper.phpH  -hH  ]R`A      2   vendor/symfony/console/Helper/DescriptorHelper.php	  -h	        7   vendor/symfony/console/Helper/SymfonyQuestionHelper.php  -h  9      1   vendor/symfony/console/Helper/HelperInterface.phpp  -hp  n      /   vendor/symfony/console/Helper/ProcessHelper.php  -h  t      3   vendor/symfony/console/Helper/ProgressIndicator.php  -h  ДP      ,   vendor/symfony/console/Helper/TableStyle.php{  -h{  pn      1   vendor/symfony/console/Helper/FormatterHelper.php
  -h
  U      2   vendor/symfony/console/Helper/InputAwareHelper.php  -h        -   vendor/symfony/console/Helper/ProgressBar.php?C  -h?C  8      '   vendor/symfony/console/Helper/Table.phpM  -hM  !<      ,   vendor/symfony/console/Question/Question.php  -h  Ί      2   vendor/symfony/console/Question/ChoiceQuestion.php]  -h]  5'      8   vendor/symfony/console/Question/ConfirmationQuestion.php#  -h#  ρ      =   vendor/symfony/console/CommandLoader/FactoryCommandLoader.php7  -h7  m_      ?   vendor/symfony/console/CommandLoader/ContainerCommandLoader.php>  -h>  #*      ?   vendor/symfony/console/CommandLoader/CommandLoaderInterface.php  -h        #   vendor/symfony/console/Terminal.php  -h  u      /   vendor/symfony/console/Logger/ConsoleLogger.php  -h  U      .   vendor/symfony/console/Command/HelpCommand.php?	  -h?	  '      0   vendor/symfony/console/Command/LockableTrait.php  -h  O      *   vendor/symfony/console/Command/Command.phpL  -hL  F      .   vendor/symfony/console/Command/ListCommand.php	  -h	  #      -   vendor/symfony/console/Style/SymfonyStyle.phpO/  -hO/  Az      /   vendor/symfony/console/Style/StyleInterface.php(  -h(  5       ,   vendor/symfony/console/Style/OutputStyle.php  -h  ~      /   vendor/symfony/console/Tester/CommandTester.php  -h  Dd      3   vendor/symfony/console/Tester/ApplicationTester.php
  -h
  Z      4   vendor/symfony/console/Event/ConsoleCommandEvent.php%  -h%  {˾      6   vendor/symfony/console/Event/ConsoleTerminateEvent.php  -h  {e      2   vendor/symfony/console/Event/ConsoleErrorEvent.php  -h  l      6   vendor/symfony/console/Event/ConsoleExceptionEvent.phpT  -hT        -   vendor/symfony/console/Event/ConsoleEvent.php  -h  xS*      ,   vendor/symfony/console/Input/StringInput.phpF	  -hF	  c:      &   vendor/symfony/console/Input/Input.phpr  -hr  Ujx      4   vendor/symfony/console/Input/InputAwareInterface.php:  -h:   '      /   vendor/symfony/console/Input/InputInterface.php  -h  Έڤ      +   vendor/symfony/console/Input/ArrayInput.php0  -h0  mQj      *   vendor/symfony/console/Input/ArgvInput.php&/  -h&/        .   vendor/symfony/console/Input/InputArgument.phpO  -hO  (      0   vendor/symfony/console/Input/InputDefinition.php+  -h+  |      9   vendor/symfony/console/Input/StreamableInputInterface.phpi  -hi        ,   vendor/symfony/console/Input/InputOption.php  -h  6]      &   vendor/symfony/console/Application.php6  -h6  Ac      +   vendor/symfony/polyfill-ctype/bootstrap.php  -h  01      '   vendor/symfony/polyfill-ctype/Ctype.php}  -h}  \谤      :   vendor/symfony/filesystem/Exception/ExceptionInterface.php  -h  h      =   vendor/symfony/filesystem/Exception/FileNotFoundException.php  -h  0z¤      3   vendor/symfony/filesystem/Exception/IOException.php  -h  ёA      <   vendor/symfony/filesystem/Exception/IOExceptionInterface.php  -h  i      (   vendor/symfony/filesystem/Filesystem.phpGt  -hGt  .WX      )   vendor/symfony/filesystem/LockHandler.php>  -h>  8 H      8   vendor/react/promise/src/UnhandledRejectionException.phpe  -he  g4ߤ      &   vendor/react/promise/src/functions.php7  -h7  x=      6   vendor/react/promise/src/Exception/LengthException.php^   -h^   ?q      .   vendor/react/promise/src/PromisorInterface.php   -h   w;      -   vendor/react/promise/src/FulfilledPromise.php^  -h^  v      $   vendor/react/promise/src/Promise.php"  -h"  m      8   vendor/react/promise/src/CancellablePromiseInterface.php  -h  \lb      -   vendor/react/promise/src/PromiseInterface.php  -h  ^Ǥ      ,   vendor/react/promise/src/RejectedPromise.php  -h  M0      %   vendor/react/promise/src/Deferred.php  -h  
̤      5   vendor/react/promise/src/ExtendedPromiseInterface.phpv  -hv  I      .   vendor/react/promise/src/functions_include.phpa   -ha   |      (   vendor/react/promise/src/LazyPromise.php  -h  MJ      .   vendor/react/promise/src/CancellationQueue.phpu  -hu  n      5   vendor/wp-cli/cache-command/src/Transient_Command.phpU  -hU  T      1   vendor/wp-cli/cache-command/src/Cache_Command.php6  -h6   3T      -   vendor/wp-cli/cache-command/cache-command.php7  -h7  z      /   vendor/wp-cli/import-command/import-command.php  -h  &      3   vendor/wp-cli/import-command/src/Import_Command.php9  -h9  m x      /   vendor/wp-cli/entity-command/entity-command.php  -h  jl      9   vendor/wp-cli/entity-command/src/Comment_Meta_Command.php  -h  Cq      6   vendor/wp-cli/entity-command/src/Network_Namespace.php*  -h*  {d      :   vendor/wp-cli/entity-command/src/Menu_Location_Command.php  -h  :E      6   vendor/wp-cli/entity-command/src/Site_Meta_Command.php  -h  R      9   vendor/wp-cli/entity-command/src/Network_Meta_Command.php]  -h]  kN      9   vendor/wp-cli/entity-command/src/User_Session_Command.php  -h        1   vendor/wp-cli/entity-command/src/Term_Command.phpM  -hM  N      ;   vendor/wp-cli/entity-command/src/WP_CLI/CommandWithMeta.php9  -h9  {      <   vendor/wp-cli/entity-command/src/WP_CLI/CommandWithTerms.php  -h  3֤      ?   vendor/wp-cli/entity-command/src/WP_CLI/CommandWithDBObject.php  -h  #      1   vendor/wp-cli/entity-command/src/Post_Command.php {  -h {  6u      5   vendor/wp-cli/entity-command/src/Taxonomy_Command.php  -h  X      1   vendor/wp-cli/entity-command/src/User_Command.php  -h  :T      8   vendor/wp-cli/entity-command/src/Site_Option_Command.php='  -h='  (      3   vendor/wp-cli/entity-command/src/Signup_Command.php!  -h!  hs(      1   vendor/wp-cli/entity-command/src/Menu_Command.php2  -h2  -      6   vendor/wp-cli/entity-command/src/Menu_Item_Command.php9  -h9  '      6   vendor/wp-cli/entity-command/src/User_Meta_Command.php?%  -h?%  [7m      6   vendor/wp-cli/entity-command/src/Post_Term_Command.php  -h        6   vendor/wp-cli/entity-command/src/Post_Meta_Command.php#  -h#  ~$      6   vendor/wp-cli/entity-command/src/User_Term_Command.php&  -h&  {b      3   vendor/wp-cli/entity-command/src/Option_Command.phpO  -hO  jd!      F   vendor/wp-cli/entity-command/src/User_Application_Password_Command.phpC  -hC  ]B      1   vendor/wp-cli/entity-command/src/Site_Command.php  -h  'i      6   vendor/wp-cli/entity-command/src/Term_Meta_Command.php  -h  Bs      6   vendor/wp-cli/entity-command/src/Post_Type_Command.php  -h  ֤      4   vendor/wp-cli/entity-command/src/Comment_Command.phpH  -hH  N]1"      4   vendor/wp-cli/widget-command/src/Sidebar_Command.php  -h  =      3   vendor/wp-cli/widget-command/src/Widget_Command.phpcG  -hcG        /   vendor/wp-cli/widget-command/widget-command.php8  -h8  q?e      B   vendor/wp-cli/search-replace-command/src/WP_CLI/SearchReplacer.phpB  -hB        C   vendor/wp-cli/search-replace-command/src/Search_Replace_Command.phpZ  -hZ  B      ?   vendor/wp-cli/search-replace-command/search-replace-command.php+  -h+  DKI      3   vendor/wp-cli/language-command/language-command.php&  -h&        =   vendor/wp-cli/language-command/src/Theme_Language_Command.phpLC  -hLC  ӛѤ      B   vendor/wp-cli/language-command/src/WP_CLI/LanguagePackUpgrader.php  -h  n      D   vendor/wp-cli/language-command/src/WP_CLI/CommandWithTranslation.phpb!  -hb!  ȅ0      C   vendor/wp-cli/language-command/src/Site_Switch_Language_Command.php  -h  1      <   vendor/wp-cli/language-command/src/Core_Language_Command.php*  -h*  C      9   vendor/wp-cli/language-command/src/Language_Namespace.php  -h  -      >   vendor/wp-cli/language-command/src/Plugin_Language_Command.phpD  -hD  &      3   vendor/wp-cli/i18n-command/src/PhpCodeExtractor.php  -h  Ϥ      8   vendor/wp-cli/i18n-command/src/IterableCodeExtractor.php,  -h,  =      6   vendor/wp-cli/i18n-command/src/PhpFunctionsScanner.php
  -h
  񫌘      1   vendor/wp-cli/i18n-command/src/MakePotCommand.php4  -h4  XzC      2   vendor/wp-cli/i18n-command/src/MakeJsonCommand.php{2  -h{2  1O      3   vendor/wp-cli/i18n-command/src/MapCodeExtractor.phpw  -hw  "֤      1   vendor/wp-cli/i18n-command/src/MakePhpCommand.phpP	  -hP	  UN      1   vendor/wp-cli/i18n-command/src/BlockExtractor.php  -h        5   vendor/wp-cli/i18n-command/src/BladeCodeExtractor.php  -h  $i      5   vendor/wp-cli/i18n-command/src/JsFunctionsScanner.php%/  -h%/  qŐ      4   vendor/wp-cli/i18n-command/src/PhpArrayGenerator.phpj  -hj  Q3      /   vendor/wp-cli/i18n-command/src/JedGenerator.phpm  -hm  ʓ      6   vendor/wp-cli/i18n-command/src/JsonSchemaExtractor.php  -h  5Ⴄ      2   vendor/wp-cli/i18n-command/src/JsCodeExtractor.php  -h  F9<      4   vendor/wp-cli/i18n-command/src/FileDataExtractor.php  -h  -&      8   vendor/wp-cli/i18n-command/src/BladeGettextExtractor.php  -h        2   vendor/wp-cli/i18n-command/src/UpdatePoCommand.php
  -h
  Ĥ      0   vendor/wp-cli/i18n-command/src/MakeMoCommand.php  -h  +3      3   vendor/wp-cli/i18n-command/src/CommandNamespace.php  -h  lh      /   vendor/wp-cli/i18n-command/src/PotGenerator.php  -h        +   vendor/wp-cli/i18n-command/i18n-command.php  -h  D      5   vendor/wp-cli/rewrite-command/src/Rewrite_Command.php1  -h1        1   vendor/wp-cli/rewrite-command/rewrite-command.php  -h  9'Rr      #   vendor/wp-cli/wp-cli/utils/find-php\  -h\  \)      @   vendor/wp-cli/wp-cli/utils/get-package-require-from-composer.php  -h        +   vendor/wp-cli/role-command/role-command.php/  -h/  x      /   vendor/wp-cli/role-command/src/Role_Command.php7,  -h7,  }      7   vendor/wp-cli/role-command/src/Capabilities_Command.phpy  -hy  u?      *   vendor/wp-cli/export-command/functions.phpp  -hp        :   vendor/wp-cli/export-command/src/WP_Iterator_Exception.php9   -h9   w      <   vendor/wp-cli/export-command/src/WP_Export_WXR_Formatter.php&  -h&  Ѣ      :   vendor/wp-cli/export-command/src/WP_Export_Base_Writer.php  -h  Ǵb      4   vendor/wp-cli/export-command/src/WP_Map_Iterator.phpZ  -hZ  Dꫤ      9   vendor/wp-cli/export-command/src/WP_Post_IDs_Iterator.phpI  -hI  d,֤      8   vendor/wp-cli/export-command/src/WP_Export_Exception.php>   -h>   M       A   vendor/wp-cli/export-command/src/WP_Export_Split_Files_Writer.php   -h   Ls      3   vendor/wp-cli/export-command/src/Export_Command.phpJ9  -hJ9  x1      7   vendor/wp-cli/export-command/src/WP_Export_Returner.phpB  -hB  M      <   vendor/wp-cli/export-command/src/WP_Export_XML_Over_HTTP.phpa  -ha  ]      =   vendor/wp-cli/export-command/src/WP_Export_Term_Exception.phpC   -hC   Ǥ      :   vendor/wp-cli/export-command/src/WP_Export_File_Writer.php>  -h>  R}T      4   vendor/wp-cli/export-command/src/WP_Export_Query.php8  -h8  D/      5   vendor/wp-cli/export-command/src/WP_Export_Oxymel.php  -h  ֦嵤      /   vendor/wp-cli/export-command/export-command.php  -h   ͤ      +   vendor/wp-cli/cron-command/cron-command.phpu  -hu  5R      8   vendor/wp-cli/cron-command/src/Cron_Schedule_Command.phpg  -hg        5   vendor/wp-cli/cron-command/src/Cron_Event_Command.phpA  -hA  @դ      /   vendor/wp-cli/cron-command/src/Cron_Command.php  -h  #,/      C   vendor/wp-cli/maintenance-mode-command/maintenance-mode-command.phpL  -hL  9v4      E   vendor/wp-cli/maintenance-mode-command/src/MaintenanceModeCommand.php  -h  ,t      ?   vendor/wp-cli/wp-config-transformer/src/WPConfigTransformer.php+  -h+  Ņ      5   vendor/wp-cli/extension-command/extension-command.php  -h  sv      A   vendor/wp-cli/extension-command/src/Theme_AutoUpdates_Command.phpw  -hw  zpL      C   vendor/wp-cli/extension-command/src/WP_CLI/ParsePluginNameInput.php  -h  1'TJ      B   vendor/wp-cli/extension-command/src/WP_CLI/ParseThemeNameInput.php@  -h@  7-      =   vendor/wp-cli/extension-command/src/WP_CLI/Fetchers/Theme.php  -h  i      >   vendor/wp-cli/extension-command/src/WP_CLI/Fetchers/Plugin.php!  -h!  Yȩ      G   vendor/wp-cli/extension-command/src/WP_CLI/DestructiveThemeUpgrader.php  -h  e      H   vendor/wp-cli/extension-command/src/WP_CLI/DestructivePluginUpgrader.php  -h  _      A   vendor/wp-cli/extension-command/src/WP_CLI/CommandWithUpgrade.php7x  -h7x        B   vendor/wp-cli/extension-command/src/Plugin_AutoUpdates_Command.php&  -h&  SO      9   vendor/wp-cli/extension-command/src/Theme_Mod_Command.php  -h  9n      5   vendor/wp-cli/extension-command/src/Theme_Command.phpg  -hg  :      6   vendor/wp-cli/extension-command/src/Plugin_Command.php>  -h>  Yic      =   vendor/wp-cli/checksum-command/src/Core_Command_Namespace.php   -h   {      G   vendor/wp-cli/checksum-command/src/WP_CLI/Fetchers/UnfilteredPlugin.php9  -h9  Ф      <   vendor/wp-cli/checksum-command/src/Checksum_Core_Command.php  -h  {      ?   vendor/wp-cli/checksum-command/src/Plugin_Command_Namespace.php   -h   :f      >   vendor/wp-cli/checksum-command/src/Checksum_Plugin_Command.php%  -h%  2m      <   vendor/wp-cli/checksum-command/src/Checksum_Base_Command.php  -h  XD#      3   vendor/wp-cli/checksum-command/checksum-command.php  -h  K0Ǥ      ;   vendor/wp-cli/core-command/src/WP_CLI/Core/CoreUpgrader.php  -h  )Z      I   vendor/wp-cli/core-command/src/WP_CLI/Core/NonDestructiveCoreUpgrader.php  -h  !]7Ĥ      /   vendor/wp-cli/core-command/src/Core_Command.php  -h  +P4      +   vendor/wp-cli/core-command/core-command.php   -h   	|      <   vendor/wp-cli/package-command/src/WP_CLI/JsonManipulator.phpS  -hS  Ϣ      ?   vendor/wp-cli/package-command/src/WP_CLI/Package/ComposerIO.php  -h  R𻭤      N   vendor/wp-cli/package-command/src/WP_CLI/Package/Compat/NullIOMethodsTrait.php  -h        _   vendor/wp-cli/package-command/src/WP_CLI/Package/Compat/Min_Composer_2_3/NullIOMethodsTrait.phpL  -hL  YϤ      `   vendor/wp-cli/package-command/src/WP_CLI/Package/Compat/Min_Composer_1_10/NullIOMethodsTrait.php)  -h)  ;JY      5   vendor/wp-cli/package-command/src/Package_Command.php  -h  v      1   vendor/wp-cli/package-command/package-command.php.  -h.  S      0   vendor/wp-cli/php-cli-tools/lib/cli/Progress.php  -h  a      /   vendor/wp-cli/php-cli-tools/lib/cli/Streams.php#  -h#  y_W      ,   vendor/wp-cli/php-cli-tools/lib/cli/Tree.php  -h  @      .   vendor/wp-cli/php-cli-tools/lib/cli/Colors.php!  -h!  _t      4   vendor/wp-cli/php-cli-tools/lib/cli/progress/Bar.php	  -h	  n(O      6   vendor/wp-cli/php-cli-tools/lib/cli/table/Renderer.phpG  -hG  Yߒ      5   vendor/wp-cli/php-cli-tools/lib/cli/table/Tabular.phpE  -hE  ^      3   vendor/wp-cli/php-cli-tools/lib/cli/table/Ascii.php  -h  :tt      5   vendor/wp-cli/php-cli-tools/lib/cli/unicode/regex.phpb  -hb  ɶ9ͤ      5   vendor/wp-cli/php-cli-tools/lib/cli/tree/Renderer.phpO  -hO  c"Ӥ      5   vendor/wp-cli/php-cli-tools/lib/cli/tree/Markdown.php  -h  T魤      2   vendor/wp-cli/php-cli-tools/lib/cli/tree/Ascii.phpx  -hx  9      -   vendor/wp-cli/php-cli-tools/lib/cli/Shell.phpF  -hF  6}^      +   vendor/wp-cli/php-cli-tools/lib/cli/cli.php@  -h@  "1      1   vendor/wp-cli/php-cli-tools/lib/cli/Arguments.phpn/  -hn/  M      6   vendor/wp-cli/php-cli-tools/lib/cli/notify/Spinner.php  -h  8u      3   vendor/wp-cli/php-cli-tools/lib/cli/notify/Dots.phpd  -hd  wz      .   vendor/wp-cli/php-cli-tools/lib/cli/Notify.php  -h  }/ˤ      /   vendor/wp-cli/php-cli-tools/lib/cli/Memoize.php  -h        -   vendor/wp-cli/php-cli-tools/lib/cli/Table.php  -h        :   vendor/wp-cli/php-cli-tools/lib/cli/arguments/Argument.php0  -h0  C      7   vendor/wp-cli/php-cli-tools/lib/cli/arguments/Lexer.php	  -h	  NYޤ      B   vendor/wp-cli/php-cli-tools/lib/cli/arguments/InvalidArguments.php  -h  #      <   vendor/wp-cli/php-cli-tools/lib/cli/arguments/HelpScreen.php
  -h
  m      ,   vendor/wp-cli/php-cli-tools/http-console.php  -h  >      $   vendor/wp-cli/php-cli-tools/test.phpi  -hi  3M      '   vendor/wp-cli/db-command/db-command.php   -h   5      +   vendor/wp-cli/db-command/src/DB_Command.php -h T      3   vendor/wp-cli/eval-command/src/EvalFile_Command.php	  -h	  Yy      /   vendor/wp-cli/eval-command/src/Eval_Command.php]  -h]  '      +   vendor/wp-cli/eval-command/eval-command.php1  -h1  /"2      4   vendor/wp-cli/embed-command/src/Provider_Command.php  -h  WV      *   vendor/wp-cli/embed-command/src/oEmbed.php  -h  p>      3   vendor/wp-cli/embed-command/src/Handler_Command.php	  -h	  !!      4   vendor/wp-cli/embed-command/src/Embeds_Namespace.php.  -h.  `H>ؤ      1   vendor/wp-cli/embed-command/src/Cache_Command.php,  -h,  q      1   vendor/wp-cli/embed-command/src/Fetch_Command.php%  -h%  
nW      -   vendor/wp-cli/embed-command/embed-command.phpx  -hx  #Τ      1   vendor/wp-cli/shell-command/src/Shell_Command.phpU  -hU  n*      5   vendor/wp-cli/shell-command/src/WP_CLI/Shell/REPL.php  -h  Vo      -   vendor/wp-cli/shell-command/shell-command.php   -h   '      )   vendor/wp-cli/mustangostang-spyc/Spyc.php  -h  x      .   vendor/wp-cli/mustangostang-spyc/php4/5to4.php  -h  uS])      /   vendor/wp-cli/mustangostang-spyc/php4/test.php4  -h   f3P      /   vendor/wp-cli/mustangostang-spyc/php4/spyc.php4Iu  -hIu  -.      -   vendor/wp-cli/mustangostang-spyc/src/Spyc.php˅  -h˅   ~      7   vendor/wp-cli/mustangostang-spyc/includes/functions.php  -h  :      7   vendor/wp-cli/scaffold-command/src/Scaffold_Command.php  -h        ;   vendor/wp-cli/scaffold-command/templates/block-php.mustache.  -h.  F^      3   vendor/wp-cli/scaffold-command/scaffold-command.php  -h  9      3   vendor/wp-cli/config-command/src/Config_Command.php/  -h/        /   vendor/wp-cli/config-command/config-command.php  -h  }      =   vendor/wp-cli/super-admin-command/src/Super_Admin_Command.php  -h  t~      9   vendor/wp-cli/super-admin-command/super-admin-command.php  -h  ¤      /   vendor/wp-cli/server-command/server-command.php  -h        3   vendor/wp-cli/server-command/src/Server_Command.php,  -h,  6\      '   vendor/wp-cli/server-command/router.phpN  -hN        -   vendor/wp-cli/media-command/media-command.php  -h  NZ两      1   vendor/wp-cli/media-command/src/Media_Command.php  -h  ?NQ      6   vendor/wp-cli/wp-cli-tests/utils/generate-coverage.php  -h  ɐ      .   vendor/wp-cli/wp-cli-tests/utils/polyfills.php
  -h
  y      ,   vendor/wp-cli/wp-cli-tests/utils/no-mail.php  -h  "5      1   vendor/wp-cli/wp-cli-tests/bin/run-phpcbf-cleanup   -h   %      1   vendor/wp-cli/wp-cli-tests/bin/run-php-unit-tests  -h  z      .   vendor/wp-cli/wp-cli-tests/bin/run-phpcs-tests   -h   .&      >   vendor/wp-cli/wp-cli-tests/src/Context/WhenStepDefinitions.php  -h  3-      >   vendor/wp-cli/wp-cli-tests/src/Context/ThenStepDefinitions.php8  -h8  ~(~E      ?   vendor/wp-cli/wp-cli-tests/src/Context/GivenStepDefinitions.phpI  -hI  t      2   vendor/wp-cli/wp-cli-tests/src/Context/Support.php<  -h<  [Ƥ      9   vendor/wp-cli/wp-cli-tests/src/Context/FeatureContext.php  -h  +׍/         vendor/nb/oxymel/Oxymel.php)  -h)  (rդ         vendor/nb/oxymel/OxymelTest.php  -h  BLV      %   vendor/psr/log/Psr/Log/NullLogger.php  -h  I      *   vendor/psr/log/Psr/Log/LoggerInterface.php*  -h*  1b!q      #   vendor/psr/log/Psr/Log/LogLevel.phpP  -hP        3   vendor/psr/log/Psr/Log/InvalidArgumentException.php`   -h`    X1      &   vendor/psr/log/Psr/Log/LoggerTrait.phpW  -hW  Wj      )   vendor/psr/log/Psr/Log/AbstractLogger.php   -h   G      /   vendor/psr/log/Psr/Log/LoggerAwareInterface.php)  -h)  j      +   vendor/psr/log/Psr/Log/LoggerAwareTrait.php  -h  Q'      7   vendor/psr/container/src/NotFoundExceptionInterface.php   -h   -      8   vendor/psr/container/src/ContainerExceptionInterface.php   -h   N>K      /   vendor/psr/container/src/ContainerInterface.phpJ  -hJ  "x      ;   vendor/seld/jsonlint/src/Seld/JsonLint/ParsingException.php  -h  #      4   vendor/seld/jsonlint/src/Seld/JsonLint/Undefined.php  -h  g      0   vendor/seld/jsonlint/src/Seld/JsonLint/Lexer.php"  -h"  H*      5   vendor/seld/jsonlint/src/Seld/JsonLint/JsonParser.phpt`  -ht`  S`=      @   vendor/seld/jsonlint/src/Seld/JsonLint/DuplicateKeyException.php  -h  >f	      )   vendor/seld/phar-utils/src/Timestamps.php  -h  (6      %   vendor/seld/phar-utils/src/Linter.php  -h  '4#      ;   vendor/justinrainbow/json-schema/src/JsonSchema/Rfc3339.phpv  -hv  x$      Q   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ValidationException.php  -h  EB*      P   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ExceptionInterface.phpI   -hI   %|      N   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/RuntimeException.phpa  -ha  `      T   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaException.phpN  -hN  ݠ      W   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSourceUriException.php\  -h\  iR      V   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidArgumentException.phpy  -hy  WΖ      S   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/JsonDecodingException.php  -h  ٣      W   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/ResourceNotFoundException.phpT  -hT  :      ^   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UnresolvableJsonPointerException.php  -h  .mi      ]   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidSchemaMediaTypeException.phpW  -hW  %*)֤      T   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/InvalidConfigException.phpQ  -hQ   J      R   vendor/justinrainbow/json-schema/src/JsonSchema/Exception/UriResolverException.phpJ  -hJ  -      K   vendor/justinrainbow/json-schema/src/JsonSchema/Iterator/ObjectIterator.php
  -h
  H      N   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeConstraint.php1  -h1  Je[      N   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/EnumConstraint.phpq  -hq  `       Y   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php+  -h+  Qܤ      X   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/LooseTypeCheck.php  -h  
      \   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/TypeCheck/TypeCheckInterface.php  -h  c>Ϥ      P   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/SchemaConstraint.php  -h  fK      P   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/NumberConstraint.php  -h  9|      J   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Constraint.php  -h  ד      P   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/StringConstraint.php  -h  ~G      T   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/CollectionConstraint.php  -h  N      S   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/UndefinedConstraint.php>  -h>  ST      N   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/BaseConstraint.php%  -h%  2      P   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ObjectConstraint.php  -h  Fgc      P   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/FormatConstraint.php"  -h"  ͥ#K      G   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/Factory.phpF  -hF  :0/      S   vendor/justinrainbow/json-schema/src/JsonSchema/Constraints/ConstraintInterface.php  -h  te      =   vendor/justinrainbow/json-schema/src/JsonSchema/Validator.php
  -h
  8      I   vendor/justinrainbow/json-schema/src/JsonSchema/UriRetrieverInterface.php  -h  5|[      F   vendor/justinrainbow/json-schema/src/JsonSchema/Entity/JsonPointer.php>  -h>  W      H   vendor/justinrainbow/json-schema/src/JsonSchema/UriResolverInterface.php  -h  IѤ      C   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriResolver.php;  -h;        D   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/UriRetriever.php$  -h$  Xh      R   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/PredefinedArray.php  -h  0      R   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/FileGetContents.phpj
  -hj
  [}x#      T   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/AbstractRetriever.phpr  -hr  M      G   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/Curl.phpo  -ho  n      X   vendor/justinrainbow/json-schema/src/JsonSchema/Uri/Retrievers/UriRetrieverInterface.php  -h  ?r@      A   vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorage.php+  -h+  _      J   vendor/justinrainbow/json-schema/src/JsonSchema/SchemaStorageInterface.php"  -h"  x&7      )   vendor/gettext/languages/src/CldrData.php5  -h5  Fؤ      )   vendor/gettext/languages/src/Language.php>  -h>  z:      .   vendor/gettext/languages/src/Exporter/Ruby.php  -h  <Av      ,   vendor/gettext/languages/src/Exporter/Po.php  -h  ҔX      .   vendor/gettext/languages/src/Exporter/Json.php
  -h
  *      -   vendor/gettext/languages/src/Exporter/Php.php@  -h@  Pڤ      4   vendor/gettext/languages/src/Exporter/Prettyjson.phpD  -hD  V&
      -   vendor/gettext/languages/src/Exporter/Xml.php	  -h	  9      .   vendor/gettext/languages/src/Exporter/Html.php;  -h;  V      2   vendor/gettext/languages/src/Exporter/Exporter.php  -h  k      )   vendor/gettext/languages/src/Category.php  -h  j      1   vendor/gettext/languages/src/FormulaConverter.php  -h  h      +   vendor/gettext/languages/src/autoloader.phpZ  -hZ  .r      3   vendor/gettext/gettext/src/translator_functions.php0  -h0  Ȥ      ,   vendor/gettext/gettext/src/Generators/Po.php
  -h
  (S      ,   vendor/gettext/gettext/src/Generators/Mo.php  -h  0Ф      -   vendor/gettext/gettext/src/Generators/Jed.phpp  -hp  ,k.      .   vendor/gettext/gettext/src/Generators/Json.phpO  -hO  f'N      -   vendor/gettext/gettext/src/Generators/Csv.php  -h  {      .   vendor/gettext/gettext/src/Generators/Yaml.php  -h        /   vendor/gettext/gettext/src/Generators/Xliff.php6  -h6  þQ      2   vendor/gettext/gettext/src/Generators/PhpArray.php  -h  H;      7   vendor/gettext/gettext/src/Generators/CsvDictionary.php  -h  CT       8   vendor/gettext/gettext/src/Generators/YamlDictionary.php  -h  L5      3   vendor/gettext/gettext/src/Generators/Generator.php  -h  3      <   vendor/gettext/gettext/src/Generators/GeneratorInterface.php  -h  g      8   vendor/gettext/gettext/src/Generators/JsonDictionary.php=  -h=  {      0   vendor/gettext/gettext/src/GettextTranslator.php  -h  ޼|      )   vendor/gettext/gettext/src/Translator.php  -h  J>      $   vendor/gettext/gettext/src/Merge.phpD  -hD  m6P      -   vendor/gettext/gettext/src/BaseTranslator.php  -h  3vĤ      *   vendor/gettext/gettext/src/Translation.php+  -h+  9      5   vendor/gettext/gettext/src/Utils/FunctionsScanner.phpI  -hI  ahk$      8   vendor/gettext/gettext/src/Utils/PhpFunctionsScanner.php  -h  jG"      -   vendor/gettext/gettext/src/Utils/CsvTrait.php  -h  S*      :   vendor/gettext/gettext/src/Utils/HeadersExtractorTrait.php~  -h~  Ф      3   vendor/gettext/gettext/src/Utils/ParsedFunction.php  -h  b      2   vendor/gettext/gettext/src/Utils/ParsedComment.php\  -h\  ܺC      4   vendor/gettext/gettext/src/Utils/DictionaryTrait.php  -h  '      :   vendor/gettext/gettext/src/Utils/HeadersGeneratorTrait.php7  -h7  6ÉG      7   vendor/gettext/gettext/src/Utils/JsFunctionsScanner.php$  -h$  (d      1   vendor/gettext/gettext/src/Utils/StringReader.php  -h  P8Z      ?   vendor/gettext/gettext/src/Utils/MultidimensionalArrayTrait.php  -h  i$a      +   vendor/gettext/gettext/src/Translations.phpA  -hA  O4#N      2   vendor/gettext/gettext/src/TranslatorInterface.php%
  -h%
        )   vendor/gettext/gettext/src/autoloader.php  -h  Ap      ,   vendor/gettext/gettext/src/Extractors/Po.php  -h  !      ,   vendor/gettext/gettext/src/Extractors/Mo.phpm  -hm  ep      -   vendor/gettext/gettext/src/Extractors/Jed.php  -h  {c      .   vendor/gettext/gettext/src/Extractors/Json.php.  -h.  w=u      3   vendor/gettext/gettext/src/Extractors/Extractor.php  -h  {n      <   vendor/gettext/gettext/src/Extractors/ExtractorInterface.php  -h  p}YФ      .   vendor/gettext/gettext/src/Extractors/Twig.php<  -h<  K      1   vendor/gettext/gettext/src/Extractors/PhpCode.php?  -h?  '      /   vendor/gettext/gettext/src/Extractors/Blade.php  -h  5x      -   vendor/gettext/gettext/src/Extractors/Csv.php  -h  m8¤      /   vendor/gettext/gettext/src/Extractors/VueJs.phpn6  -hn6  >      .   vendor/gettext/gettext/src/Extractors/Yaml.php]  -h]  jя"      /   vendor/gettext/gettext/src/Extractors/Xliff.php  -h  W}      A   vendor/gettext/gettext/src/Extractors/ExtractorMultiInterface.php  -h  ]      2   vendor/gettext/gettext/src/Extractors/PhpArray.phpG  -hG  /DѤ      7   vendor/gettext/gettext/src/Extractors/CsvDictionary.phpR  -hR  WG      8   vendor/gettext/gettext/src/Extractors/YamlDictionary.phpQ  -hQ  ts      0   vendor/gettext/gettext/src/Extractors/JsCode.php(  -h(  8vU      8   vendor/gettext/gettext/src/Extractors/JsonDictionary.php(  -h(  -*      2   vendor/mck89/peast/lib/Peast/Formatter/Compact.phpG  -hG  o      6   vendor/mck89/peast/lib/Peast/Formatter/PrettyPrint.phpr  -hr  jϤ      3   vendor/mck89/peast/lib/Peast/Formatter/Expanded.php  -h  x      /   vendor/mck89/peast/lib/Peast/Formatter/Base.phpl  -hl  =ڤ      )   vendor/mck89/peast/lib/Peast/Renderer.phpZ  -hZ  s
      3   vendor/mck89/peast/lib/Peast/Selector/Exception.php  -h  BQ:      0   vendor/mck89/peast/lib/Peast/Selector/Parser.phpB  -hB  G	d      1   vendor/mck89/peast/lib/Peast/Selector/Matches.php  -h  >z      7   vendor/mck89/peast/lib/Peast/Selector/Node/Selector.php  -h  :rդ      9   vendor/mck89/peast/lib/Peast/Selector/Node/Combinator.phpS  -hS        4   vendor/mck89/peast/lib/Peast/Selector/Node/Group.php  -h  H;      8   vendor/mck89/peast/lib/Peast/Selector/Node/Part/Type.php  -h  wۤ      B   vendor/mck89/peast/lib/Peast/Selector/Node/Part/PseudoSelector.phpZ  -hZ  8,n      8   vendor/mck89/peast/lib/Peast/Selector/Node/Part/Part.phpm  -hm  ^Ƥ      ?   vendor/mck89/peast/lib/Peast/Selector/Node/Part/PseudoIndex.php(	  -h(	  z\F      @   vendor/mck89/peast/lib/Peast/Selector/Node/Part/PseudoSimple.phpf  -hf  /o      =   vendor/mck89/peast/lib/Peast/Selector/Node/Part/Attribute.php  -h  ŋ      :   vendor/mck89/peast/lib/Peast/Selector/Node/Part/Pseudo.php  -h  @-핤      *   vendor/mck89/peast/lib/Peast/Traverser.php  -h  8+      &   vendor/mck89/peast/lib/Peast/Query.php@  -h@  ޖؤ      1   vendor/mck89/peast/lib/Peast/Syntax/Exception.php  -h  7]i      7   vendor/mck89/peast/lib/Peast/Syntax/ES2019/Features.php  -h  0^      .   vendor/mck89/peast/lib/Peast/Syntax/Parser.php= -h= +N      7   vendor/mck89/peast/lib/Peast/Syntax/ES2023/Features.php  -h  l3      0   vendor/mck89/peast/lib/Peast/Syntax/Features.php  -h  Uv      6   vendor/mck89/peast/lib/Peast/Syntax/ParserAbstract.php^$  -h^$  4      9   vendor/mck89/peast/lib/Peast/Syntax/EncodingException.php  -h  Lp      2   vendor/mck89/peast/lib/Peast/Syntax/JSX/Parser.php6  -h6  դ      3   vendor/mck89/peast/lib/Peast/Syntax/JSX/Scanner.phps  -hs  ֙Ԥ      0   vendor/mck89/peast/lib/Peast/Syntax/Position.php  -h  kwG      8   vendor/mck89/peast/lib/Peast/Syntax/CommentsRegistry.php(  -h(  2)>      7   vendor/mck89/peast/lib/Peast/Syntax/ES2021/Features.php  -h  KYA      7   vendor/mck89/peast/lib/Peast/Syntax/ES2018/Features.php(  -h(  pf      7   vendor/mck89/peast/lib/Peast/Syntax/ES2015/Features.php  -h  @      7   vendor/mck89/peast/lib/Peast/Syntax/ES2020/Features.php  -h  O      -   vendor/mck89/peast/lib/Peast/Syntax/Token.php  -h  B      5   vendor/mck89/peast/lib/Peast/Syntax/EventsEmitter.php  -h  {u      /   vendor/mck89/peast/lib/Peast/Syntax/Scanner.php  -h  BAפ      -   vendor/mck89/peast/lib/Peast/Syntax/Utils.php&  -h&  Ls      7   vendor/mck89/peast/lib/Peast/Syntax/ES2025/Features.php  -h  cT      7   vendor/mck89/peast/lib/Peast/Syntax/ES2024/Features.php  -h  U      7   vendor/mck89/peast/lib/Peast/Syntax/ES2017/Features.php  -h  H@      +   vendor/mck89/peast/lib/Peast/Syntax/LSM.php  -h  /      6   vendor/mck89/peast/lib/Peast/Syntax/SourceLocation.php  -h  <      7   vendor/mck89/peast/lib/Peast/Syntax/ES2022/Features.phpC  -hC        7   vendor/mck89/peast/lib/Peast/Syntax/ES2016/Features.php  -h  t~      ?   vendor/mck89/peast/lib/Peast/Syntax/Node/VariableDeclarator.php  -h  b٤      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ImportSpecifier.php  -h  !I      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/ThisExpression.php  -h  %a      9   vendor/mck89/peast/lib/Peast/Syntax/Node/ArrayPattern.php  -h  ʑ(      7   vendor/mck89/peast/lib/Peast/Syntax/Node/SwitchCase.phpX  -hX  E      6   vendor/mck89/peast/lib/Peast/Syntax/Node/Statement.php  -h        =   vendor/mck89/peast/lib/Peast/Syntax/Node/ObjectExpression.php  -h  '!E      =   vendor/mck89/peast/lib/Peast/Syntax/Node/UpdateExpression.php;	  -h;	        <   vendor/mck89/peast/lib/Peast/Syntax/Node/AwaitExpression.phpU  -hU        >   vendor/mck89/peast/lib/Peast/Syntax/Node/LogicalExpression.phpZ  -hZ  S      =   vendor/mck89/peast/lib/Peast/Syntax/Node/BinaryExpression.php  -h  vX$      7   vendor/mck89/peast/lib/Peast/Syntax/Node/Identifier.php  -h  O      E   vendor/mck89/peast/lib/Peast/Syntax/Node/ExportDefaultDeclaration.php"  -h"  S(6      =   vendor/mck89/peast/lib/Peast/Syntax/Node/MethodDefinition.php  -h  w\      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/BreakStatement.phpy  -hy  2      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/EmptyStatement.php  -h  n      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ClassExpression.php  -h  p~ä      B   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXOpeningElement.php  -h  D&      =   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXAttribute.php}  -h}        B   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXClosingElement.php  -h  f      <   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXFragment.php
  -h
  ̌Է      G   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXExpressionContainer.php  -h  ]{W      8   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXText.php  -h  Ƒ      ?   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXSpreadChild.php  -h  iMb      C   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXSpreadAttribute.php  -h  K&Q      C   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXBoundaryElement.php  -h        ;   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXElement.php
  -h
  .*kB      C   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXOpeningFragment.php  -h        B   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXNamespacedName.phpz  -hz  Ԅ=      D   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXMemberExpression.phpf  -hf  h      C   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXClosingFragment.php  -h  N\      >   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXIdentifier.php  -h  L      C   vendor/mck89/peast/lib/Peast/Syntax/Node/JSX/JSXEmptyExpression.php  -h  :8      8   vendor/mck89/peast/lib/Peast/Syntax/Node/CatchClause.php  -h        <   vendor/mck89/peast/lib/Peast/Syntax/Node/ModuleSpecifier.php  -h  GjC      8   vendor/mck89/peast/lib/Peast/Syntax/Node/StaticBlock.php  -h  X~V      =   vendor/mck89/peast/lib/Peast/Syntax/Node/LabeledStatement.php  -h  (      <   vendor/mck89/peast/lib/Peast/Syntax/Node/TemplateLiteral.phpk  -hk  ;`      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/NumericLiteral.php  -h        B   vendor/mck89/peast/lib/Peast/Syntax/Node/ConditionalExpression.php	  -h	        9   vendor/mck89/peast/lib/Peast/Syntax/Node/ForStatement.phpC  -hC  1      :   vendor/mck89/peast/lib/Peast/Syntax/Node/NewExpression.php  -h  >      6   vendor/mck89/peast/lib/Peast/Syntax/Node/ClassBody.php,  -h,  7      <   vendor/mck89/peast/lib/Peast/Syntax/Node/SwitchStatement.php  -h        :   vendor/mck89/peast/lib/Peast/Syntax/Node/WithStatement.phpi  -hi  $      :   vendor/mck89/peast/lib/Peast/Syntax/Node/RegExpLiteral.phpJ
  -hJ
  tq      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ChainExpression.php  -h  e      8   vendor/mck89/peast/lib/Peast/Syntax/Node/RestElement.php  -h  7^g      <   vendor/mck89/peast/lib/Peast/Syntax/Node/TemplateElement.php	  -h	  7Ѥ      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/ForInStatement.php	  -h	  P㛤      :   vendor/mck89/peast/lib/Peast/Syntax/Node/StringLiteral.php	  -h	  5v      :   vendor/mck89/peast/lib/Peast/Syntax/Node/SpreadElement.php  -h  $Ug      :   vendor/mck89/peast/lib/Peast/Syntax/Node/BigIntLiteral.php  -h  Aͤ      >   vendor/mck89/peast/lib/Peast/Syntax/Node/ContinueStatement.php  -h  ZY      9   vendor/mck89/peast/lib/Peast/Syntax/Node/MetaProperty.php  -h  :      A   vendor/mck89/peast/lib/Peast/Syntax/Node/AssignmentExpression.php2	  -h2	  T      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/BlockStatement.php  -h         4   vendor/mck89/peast/lib/Peast/Syntax/Node/Comment.phpW  -hW  C>,      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ExportSpecifier.php  -h  (      8   vendor/mck89/peast/lib/Peast/Syntax/Node/NullLiteral.php  -h  K      1   vendor/mck89/peast/lib/Peast/Syntax/Node/Node.php   -h   \      8   vendor/mck89/peast/lib/Peast/Syntax/Node/IfStatement.php
  -h
  %      >   vendor/mck89/peast/lib/Peast/Syntax/Node/PrivateIdentifier.php  -h  o       ;   vendor/mck89/peast/lib/Peast/Syntax/Node/BooleanLiteral.phpI  -hI  m|      7   vendor/mck89/peast/lib/Peast/Syntax/Node/Expression.php  -h  zw!      =   vendor/mck89/peast/lib/Peast/Syntax/Node/ImportExpression.php  -h  4      @   vendor/mck89/peast/lib/Peast/Syntax/Node/VariableDeclaration.phpc  -hc  I      6   vendor/mck89/peast/lib/Peast/Syntax/Node/Function_.php  -h  wv      ?   vendor/mck89/peast/lib/Peast/Syntax/Node/PropertyDefinition.php  -h  H      <   vendor/mck89/peast/lib/Peast/Syntax/Node/YieldExpression.php0  -h0  )      4   vendor/mck89/peast/lib/Peast/Syntax/Node/Pattern.php  -h         9   vendor/mck89/peast/lib/Peast/Syntax/Node/TryStatement.php	  -h	  8"      <   vendor/mck89/peast/lib/Peast/Syntax/Node/UnaryExpression.phpR	  -hR	  +%6      8   vendor/mck89/peast/lib/Peast/Syntax/Node/Declaration.php  -h  84      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ImportAttribute.php  -h  r!z      4   vendor/mck89/peast/lib/Peast/Syntax/Node/Program.php	  -h	  Ԁv      D   vendor/mck89/peast/lib/Peast/Syntax/Node/ArrowFunctionExpression.php  -h  х      @   vendor/mck89/peast/lib/Peast/Syntax/Node/FunctionDeclaration.php  -h  7      2   vendor/mck89/peast/lib/Peast/Syntax/Node/Super.php  -h  RC(      :   vendor/mck89/peast/lib/Peast/Syntax/Node/ObjectPattern.php  -h  ܤ      9   vendor/mck89/peast/lib/Peast/Syntax/Node/ChainElement.php  -h  "+      3   vendor/mck89/peast/lib/Peast/Syntax/Node/Class_.phpy  -hy  n      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/ForOfStatement.php  -h  ,      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ReturnStatement.php  -h  :C      E   vendor/mck89/peast/lib/Peast/Syntax/Node/TaggedTemplateExpression.php\  -h\  -      >   vendor/mck89/peast/lib/Peast/Syntax/Node/ModuleDeclaration.php  -h  nt      E   vendor/mck89/peast/lib/Peast/Syntax/Node/ImportNamespaceSpecifier.php  -h  Mc      @   vendor/mck89/peast/lib/Peast/Syntax/Node/ExpressionStatement.php  -h  [m      C   vendor/mck89/peast/lib/Peast/Syntax/Node/ExportNamedDeclaration.phpG  -hG  %      ?   vendor/mck89/peast/lib/Peast/Syntax/Node/AssignmentProperty.php  -h  Aۤ      ?   vendor/mck89/peast/lib/Peast/Syntax/Node/SequenceExpression.php  -h        5   vendor/mck89/peast/lib/Peast/Syntax/Node/Property.php  -h  r      D   vendor/mck89/peast/lib/Peast/Syntax/Node/ParenthesizedExpression.php  -h  (Ӥ      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/CallExpression.phpW  -hW        =   vendor/mck89/peast/lib/Peast/Syntax/Node/ClassDeclaration.php  -h  %^j      >   vendor/mck89/peast/lib/Peast/Syntax/Node/ImportDeclaration.php	  -h	  2       4   vendor/mck89/peast/lib/Peast/Syntax/Node/Literal.php  -h  5ʤ      ?   vendor/mck89/peast/lib/Peast/Syntax/Node/FunctionExpression.php  -h  U      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/WhileStatement.php*  -h*  ꮓ      >   vendor/mck89/peast/lib/Peast/Syntax/Node/AssignmentPattern.php  -h  RY      <   vendor/mck89/peast/lib/Peast/Syntax/Node/ArrayExpression.php  -h  t8      =   vendor/mck89/peast/lib/Peast/Syntax/Node/DoWhileStatement.php2  -h2        >   vendor/mck89/peast/lib/Peast/Syntax/Node/DebuggerStatement.php  -h  di      =   vendor/mck89/peast/lib/Peast/Syntax/Node/MemberExpression.php`
  -h`
  G      ;   vendor/mck89/peast/lib/Peast/Syntax/Node/ThrowStatement.phpl  -hl        C   vendor/mck89/peast/lib/Peast/Syntax/Node/ImportDefaultSpecifier.php  -h  J      A   vendor/mck89/peast/lib/Peast/Syntax/Node/ExportAllDeclaration.phpV	  -hV	  TH      &   vendor/mck89/peast/lib/Peast/Peast.php   -h   9@y      2   vendor/wp-cli/wp-cli/templates/man-params.mustache?  -h?  n      +   vendor/wp-cli/wp-cli/templates/man.mustache   -h   I<      9   vendor/wp-cli/config-command/templates/wp-config.mustacheZ  -hZ  SԤ      6   vendor/wp-cli/core-command/templates/versions.mustache   -h   SU"      ?   vendor/wp-cli/extension-command/templates/theme-status.mustachex   -hx   ǁgѤ      @   vendor/wp-cli/extension-command/templates/plugin-status.mustache   -h   o[5      C   vendor/wp-cli/scaffold-command/templates/plugin-distignore.mustacheL  -hL  ڋ=      ?   vendor/wp-cli/scaffold-command/templates/plugin-gitlab.mustache  -h  Ӥ      8   vendor/wp-cli/scaffold-command/templates/plugin.mustacheq  -hq  GqҤ      D   vendor/wp-cli/scaffold-command/templates/plugin-test-sample.mustache'  -h'  \~      A   vendor/wp-cli/scaffold-command/templates/block-style-css.mustache  -h  ؤ      C   vendor/wp-cli/scaffold-command/templates/taxonomy_extended.mustache
  -h
  >^u      B   vendor/wp-cli/scaffold-command/templates/block-editor-css.mustache   -h   ,V]      >   vendor/wp-cli/scaffold-command/templates/theme-status.mustachex   -hx   ǁgѤ      =   vendor/wp-cli/scaffold-command/templates/child_theme.mustache   -h         ?   vendor/wp-cli/scaffold-command/templates/plugin-github.mustache*  -h*  ג      ;   vendor/wp-cli/scaffold-command/templates/post_type.mustache
  -h
  ?4      ?   vendor/wp-cli/scaffold-command/templates/plugin-circle.mustache<  -h<  y5      6   vendor/wp-cli/scaffold-command/templates/.editorconfig  -h  hѤ      A   vendor/wp-cli/scaffold-command/templates/plugin-composer.mustaches   -hs   Oqb      <   vendor/wp-cli/scaffold-command/templates/install-wp-tests.sh  -h  )5۔      @   vendor/wp-cli/scaffold-command/templates/block-index-js.mustache
  -h
  "0      G   vendor/wp-cli/scaffold-command/templates/child_theme_functions.mustacheT  -hT  ?8      8   vendor/wp-cli/scaffold-command/templates/.phpcs.xml.dist=  -h=  [-      B   vendor/wp-cli/scaffold-command/templates/plugin-bitbucket.mustache  -h  倧E      A   vendor/wp-cli/scaffold-command/templates/theme-bootstrap.mustache  -h  r      B   vendor/wp-cli/scaffold-command/templates/plugin-gitignore.mustachef   -hf         C   vendor/wp-cli/scaffold-command/templates/theme-test-sample.mustache&  -h&        9   vendor/wp-cli/scaffold-command/templates/phpunit.xml.dist  -h  +      ?   vendor/wp-cli/scaffold-command/templates/plugin-readme.mustache  -h  b      B   vendor/wp-cli/scaffold-command/templates/plugin-bootstrap.mustache  -h  I      :   vendor/wp-cli/scaffold-command/templates/taxonomy.mustache
  -h
  s      D   vendor/wp-cli/scaffold-command/templates/post_type_extended.mustache  -h  L}         vendor/autoload.php   -h   #y          vendor/composer/composer/LICENSE,  -h,  Vg      1   vendor/composer/composer/res/composer-schema.jsonh  -hh  ^      C   vendor/wp-cli/wp-cli/bundle/rmccue/requests/certificates/cacert.pem} -h} ۤ      &   vendor/wp-cli/wp-cli/COMPOSER_VERSIONS  -h  o         vendor/wp-cli/wp-cli/VERSION   -h   'Ĥ      <?php

// Can be used by plugins/themes to check if WP-CLI is running or not.
define( 'WP_CLI', true );
define( 'WP_CLI_VERSION', trim( file_get_contents( WP_CLI_ROOT . '/VERSION' ) ) );
define( 'WP_CLI_START_MICROTIME', microtime( true ) );

if ( file_exists( WP_CLI_ROOT . '/vendor/autoload.php' ) ) {
	define( 'WP_CLI_VENDOR_DIR', WP_CLI_ROOT . '/vendor' );
} elseif ( file_exists( dirname( dirname( WP_CLI_ROOT ) ) . '/autoload.php' ) ) {
	define( 'WP_CLI_VENDOR_DIR', dirname( dirname( WP_CLI_ROOT ) ) );
} elseif ( file_exists( dirname( WP_CLI_ROOT ) . '/vendor/autoload.php' ) ) {
	define( 'WP_CLI_VENDOR_DIR', dirname( WP_CLI_ROOT ) . '/vendor' );
} else {
	define( 'WP_CLI_VENDOR_DIR', WP_CLI_ROOT . '/vendor' );
}

require_once WP_CLI_ROOT . '/php/compat.php';

// Set common headers, to prevent warnings from plugins.
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.0';
$_SERVER['HTTP_USER_AGENT'] = ( ! empty( getenv( 'WP_CLI_USER_AGENT' ) ) ? getenv( 'WP_CLI_USER_AGENT' ) : 'WP CLI ' . WP_CLI_VERSION );
$_SERVER['REQUEST_METHOD']  = 'GET';
$_SERVER['REMOTE_ADDR']     = '127.0.0.1';

require_once WP_CLI_ROOT . '/php/bootstrap.php';

if ( getenv( 'WP_CLI_EARLY_REQUIRE' ) ) {
	foreach ( explode( ',', getenv( 'WP_CLI_EARLY_REQUIRE' ) ) as $wp_cli_early_require ) {
		require_once trim( $wp_cli_early_require );
	}
	unset( $wp_cli_early_require );
}

WP_CLI\bootstrap();
<?php

use cli\Colors;
use Mustangostang\Spyc;
use WP_CLI\Configurator;
use WP_CLI\Dispatcher;
use WP_CLI\Dispatcher\CommandAddition;
use WP_CLI\Dispatcher\CommandFactory;
use WP_CLI\Dispatcher\CommandNamespace;
use WP_CLI\Dispatcher\CompositeCommand;
use WP_CLI\Dispatcher\RootCommand;
use WP_CLI\DocParser;
use WP_CLI\ExitException;
use WP_CLI\FileCache;
use WP_CLI\Loggers\Execution;
use WP_CLI\Process;
use WP_CLI\ProcessRun;
use WP_CLI\Runner;
use WP_CLI\SynopsisParser;
use WP_CLI\Utils;
use WP_CLI\WpHttpCacheManager;

/**
 * Various utilities for WP-CLI commands.
 */
class WP_CLI {

	private static $logger;

	private static $hooks = [];

	private static $hooks_passed = [];

	private static $capture_exit = false;

	private static $deferred_additions = [];

	/**
	 * Set the logger instance.
	 *
	 * @param object $logger Logger instance to set.
	 */
	public static function set_logger( $logger ) {
		self::$logger = $logger;
	}

	/**
	 * Get the logger instance.
	 *
	 * @return object $logger Logger instance.
	 */
	public static function get_logger() {
		return self::$logger;
	}

	/**
	 * Get the Configurator instance
	 *
	 * @return Configurator
	 */
	public static function get_configurator() {
		static $configurator;

		if ( ! $configurator ) {
			$configurator = new Configurator( WP_CLI_ROOT . '/php/config-spec.php' );
		}

		return $configurator;
	}

	public static function get_root_command() {
		static $root;

		if ( ! $root ) {
			$root = new RootCommand();
		}

		return $root;
	}

	public static function get_runner() {
		static $runner;

		if ( ! $runner ) {
			$runner = new Runner();
		}

		return $runner;
	}

	/**
	 * @return FileCache
	 */
	public static function get_cache() {
		static $cache;

		if ( ! $cache ) {
			$dir      = Utils\get_cache_dir();
			$ttl      = getenv( 'WP_CLI_CACHE_EXPIRY' ) ? : 15552000;
			$max_size = getenv( 'WP_CLI_CACHE_MAX_SIZE' ) ? : 314572800;
			// 6 months, 300mb
			$cache = new FileCache( $dir, $ttl, $max_size );

			// Clean older files on shutdown with 1/50 probability.
			// phpcs:ignore WordPress.WP.AlternativeFunctions.rand_mt_rand -- no crypto and WP not loaded.
			if ( 0 === mt_rand( 0, 50 ) ) {
				register_shutdown_function(
					function () use ( $cache ) {
						$cache->clean();
					}
				);
			}
		}

		return $cache;
	}

	/**
	 * Set the context in which WP-CLI should be run
	 */
	public static function set_url( $url ) {
		self::debug( 'Set URL: ' . $url, 'bootstrap' );
		$url_parts = Utils\parse_url( $url );
		self::set_url_params( $url_parts );
	}

	private static function set_url_params( $url_parts ) {
		$f = function ( $key ) use ( $url_parts ) {
			return Utils\get_flag_value( $url_parts, $key, '' );
		};

		if ( isset( $url_parts['host'] ) ) {
			if ( isset( $url_parts['scheme'] ) && 'https' === strtolower( $url_parts['scheme'] ) ) {
				$_SERVER['HTTPS'] = 'on';
			}

			$_SERVER['HTTP_HOST'] = $url_parts['host'];
			if ( isset( $url_parts['port'] ) ) {
				$_SERVER['HTTP_HOST'] .= ':' . $url_parts['port'];
			}

			$_SERVER['SERVER_NAME'] = $url_parts['host'];
		}

		$_SERVER['REQUEST_URI']  = $f( 'path' ) . ( isset( $url_parts['query'] ) ? '?' . $url_parts['query'] : '' );
		$_SERVER['SERVER_PORT']  = Utils\get_flag_value( $url_parts, 'port', '80' );
		$_SERVER['QUERY_STRING'] = $f( 'query' );
	}

	/**
	 * @return WpHttpCacheManager
	 */
	public static function get_http_cache_manager() {
		static $http_cacher;

		if ( ! $http_cacher ) {
			$http_cacher = new WpHttpCacheManager( self::get_cache() );
		}

		return $http_cacher;
	}

	/**
	 * Colorize a string for output.
	 *
	 * Yes, you can change the color of command line text too. For instance,
	 * here's how `WP_CLI::success()` colorizes "Success: "
	 *
	 * ```
	 * WP_CLI::colorize( "%GSuccess:%n " )
	 * ```
	 *
	 * Uses `\cli\Colors::colorize()` to transform color tokens to display
	 * settings. Choose from the following tokens (and note 'reset'):
	 *
	 * * %y => ['color' => 'yellow'],
	 * * %g => ['color' => 'green'],
	 * * %b => ['color' => 'blue'],
	 * * %r => ['color' => 'red'],
	 * * %p => ['color' => 'magenta'],
	 * * %m => ['color' => 'magenta'],
	 * * %c => ['color' => 'cyan'],
	 * * %w => ['color' => 'grey'],
	 * * %k => ['color' => 'black'],
	 * * %n => ['color' => 'reset'],
	 * * %Y => ['color' => 'yellow', 'style' => 'bright'],
	 * * %G => ['color' => 'green', 'style' => 'bright'],
	 * * %B => ['color' => 'blue', 'style' => 'bright'],
	 * * %R => ['color' => 'red', 'style' => 'bright'],
	 * * %P => ['color' => 'magenta', 'style' => 'bright'],
	 * * %M => ['color' => 'magenta', 'style' => 'bright'],
	 * * %C => ['color' => 'cyan', 'style' => 'bright'],
	 * * %W => ['color' => 'grey', 'style' => 'bright'],
	 * * %K => ['color' => 'black', 'style' => 'bright'],
	 * * %N => ['color' => 'reset', 'style' => 'bright'],
	 * * %3 => ['background' => 'yellow'],
	 * * %2 => ['background' => 'green'],
	 * * %4 => ['background' => 'blue'],
	 * * %1 => ['background' => 'red'],
	 * * %5 => ['background' => 'magenta'],
	 * * %6 => ['background' => 'cyan'],
	 * * %7 => ['background' => 'grey'],
	 * * %0 => ['background' => 'black'],
	 * * %F => ['style' => 'blink'],
	 * * %U => ['style' => 'underline'],
	 * * %8 => ['style' => 'inverse'],
	 * * %9 => ['style' => 'bright'],
	 * * %_ => ['style' => 'bright']
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string $string String to colorize for output, with color tokens.
	 * @return string Colorized string.
	 */
	public static function colorize( $string ) {
		return Colors::colorize( $string, self::get_runner()->in_color() );
	}

	/**
	 * Schedule a callback to be executed at a certain point.
	 *
	 * Hooks conceptually are very similar to WordPress actions. WP-CLI hooks
	 * are typically called before WordPress is loaded.
	 *
	 * WP-CLI hooks include:
	 *
	 * * `before_add_command:<command>` - Before the command is added.
	 * * `after_add_command:<command>` - After the command was added.
	 * * `before_invoke:<command>` (1) - Just before a command is invoked.
	 * * `after_invoke:<command>` (1) - Just after a command is invoked.
	 * * `find_command_to_run_pre` - Just before WP-CLI finds the command to run.
	 * * `before_registering_contexts` (1) - Before the contexts are registered.
	 * * `before_wp_load` - Just before the WP load process begins.
	 * * `before_wp_config_load` - After wp-config.php has been located.
	 * * `after_wp_config_load` - After wp-config.php has been loaded into scope.
	 * * `after_wp_load` - Just after the WP load process has completed.
	 * * `before_run_command` (3) - Just before the command is executed.
	 *
	 * The parentheses behind the hook name denote the number of arguments
	 * being passed into the hook. For such hooks, the callback should return
	 * the first argument again, making them work like a WP filter.
	 *
	 * WP-CLI commands can create their own hooks with `WP_CLI::do_hook()`.
	 *
	 * If additional arguments are passed through the `WP_CLI::do_hook()` call,
	 * these will be passed on to the callback provided by `WP_CLI::add_hook()`.
	 *
	 * ```
	 * # `wp network meta` confirms command is executing in multisite context.
	 * WP_CLI::add_command( 'network meta', 'Network_Meta_Command', array(
	 *    'before_invoke' => function ( $name ) {
	 *        if ( !is_multisite() ) {
	 *            WP_CLI::error( 'This is not a multisite installation.' );
	 *        }
	 *    }
	 * ) );
	 * ```
	 *
	 * @access public
	 * @category Registration
	 *
	 * @param string $when Identifier for the hook.
	 * @param mixed $callback Callback to execute when hook is called.
	 * @return void
	 */
	public static function add_hook( $when, $callback ) {
		if ( array_key_exists( $when, self::$hooks_passed ) ) {
			self::debug(
				sprintf(
					'Immediately invoking on passed hook "%s": %s',
					$when,
					Utils\describe_callable( $callback )
				),
				'hooks'
			);
			call_user_func_array( $callback, (array) self::$hooks_passed[ $when ] );
		}

		self::$hooks[ $when ][] = $callback;
	}

	/**
	 * Execute callbacks registered to a given hook.
	 *
	 * See `WP_CLI::add_hook()` for details on WP-CLI's internal hook system.
	 * Commands can provide and call their own hooks.
	 *
	 * @access public
	 * @category Registration
	 *
	 * @param string $when    Identifier for the hook.
	 * @param mixed  ...$args Optional. Arguments that will be passed onto the
	 *                        callback provided by `WP_CLI::add_hook()`.
	 * @return null|mixed Returns the first optional argument if optional
	 *                    arguments were passed, otherwise returns null.
	 */
	public static function do_hook( $when, ...$args ) {
		self::$hooks_passed[ $when ] = $args;

		$has_args = count( $args ) > 0;

		if ( ! isset( self::$hooks[ $when ] ) ) {
			if ( $has_args ) {
				return $args[0];
			}

			return null;
		}

		self::debug(
			sprintf(
				'Processing hook "%s" with %d callbacks',
				$when,
				count( self::$hooks[ $when ] )
			),
			'hooks'
		);

		foreach ( self::$hooks[ $when ] as $callback ) {
			self::debug(
				sprintf(
					'On hook "%s": %s',
					$when,
					Utils\describe_callable( $callback )
				),
				'hooks'
			);

			if ( $has_args ) {
				$return_value = $callback( ...$args );
				if ( isset( $return_value ) ) {
					$args[0] = $return_value;
				}
			} else {
				$callback();
			}
		}

		if ( $has_args ) {
			return $args[0];
		}

		return null;
	}

	/**
	 * Add a callback to a WordPress action or filter.
	 *
	 * `add_action()` without needing access to `add_action()`. If WordPress is
	 * already loaded though, you should use `add_action()` (and `add_filter()`)
	 * instead.
	 *
	 * @access public
	 * @category Registration
	 *
	 * @param string $tag Named WordPress action or filter.
	 * @param mixed $function_to_add Callable to execute when the action or filter is evaluated.
	 * @param integer $priority Priority to add the callback as.
	 * @param integer $accepted_args Number of arguments to pass to callback.
	 * @return true
	 */
	public static function add_wp_hook( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
		global $wp_filter, $merged_filters;

		if ( function_exists( 'add_filter' ) ) {
			add_filter( $tag, $function_to_add, $priority, $accepted_args );
		} else {
			$idx = self::wp_hook_build_unique_id( $tag, $function_to_add, $priority );

			// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- This is intentional & the purpose of this function.
			$wp_filter[ $tag ][ $priority ][ $idx ] = [
				'function'      => $function_to_add,
				'accepted_args' => $accepted_args,
			];
			unset( $merged_filters[ $tag ] );
		}

		return true;
	}

	/**
	 * Build Unique ID for storage and retrieval.
	 *
	 * Essentially _wp_filter_build_unique_id() without needing access to _wp_filter_build_unique_id()
	 */
	private static function wp_hook_build_unique_id( $tag, $function, $priority ) {
		global $wp_filter;
		static $filter_id_count = 0;

		if ( is_string( $function ) ) {
			return $function;
		}

		if ( is_object( $function ) ) {
			// Closures are currently implemented as objects.
			$function = [ $function, '' ];
		} else {
			$function = (array) $function;
		}

		if ( is_object( $function[0] ) ) {
			// Object Class Calling.
			if ( function_exists( 'spl_object_hash' ) ) {
				return spl_object_hash( $function[0] ) . $function[1];
			}

			$obj_idx = get_class( $function[0] ) . $function[1];
			if ( ! isset( $function[0]->wp_filter_id ) ) {
				if ( false === $priority ) {
					return false;
				}
				$obj_idx                  .= isset( $wp_filter[ $tag ][ $priority ] ) ? count( (array) $wp_filter[ $tag ][ $priority ] ) : $filter_id_count;
				$function[0]->wp_filter_id = $filter_id_count;
				++$filter_id_count;
			} else {
				$obj_idx .= $function[0]->wp_filter_id;
			}

			return $obj_idx;
		}

		if ( is_string( $function[0] ) ) {
			// Static Calling.
			return $function[0] . '::' . $function[1];
		}
	}

	/**
	 * Register a command to WP-CLI.
	 *
	 * WP-CLI supports using any callable class, function, or closure as a
	 * command. `WP_CLI::add_command()` is used for both internal and
	 * third-party command registration.
	 *
	 * Command arguments are parsed from PHPDoc by default, but also can be
	 * supplied as an optional third argument during registration.
	 *
	 * ```
	 * # Register a custom 'foo' command to output a supplied positional param.
	 * #
	 * # $ wp foo bar --append=qux
	 * # Success: bar qux
	 *
	 * /**
	 *  * My awesome closure command
	 *  *
	 *  * <message>
	 *  * : An awesome message to display
	 *  *
	 *  * --append=<message>
	 *  * : An awesome message to append to the original message.
	 *  *
	 *  * @when before_wp_load
	 *  *\/
	 * $foo = function( $args, $assoc_args ) {
	 *     WP_CLI::success( $args[0] . ' ' . $assoc_args['append'] );
	 * };
	 * WP_CLI::add_command( 'foo', $foo );
	 * ```
	 *
	 * @access public
	 * @category Registration
	 *
	 * @param string   $name Name for the command (e.g. "post list" or "site empty").
	 * @param callable|object|string $callable Command implementation as a class, function or closure.
	 * @param array    $args {
	 *    Optional. An associative array with additional registration parameters.
	 *
	 *    @type callable $before_invoke Callback to execute before invoking the command.
	 *    @type callable $after_invoke  Callback to execute after invoking the command.
	 *    @type string   $shortdesc     Short description (80 char or less) for the command.
	 *    @type string   $longdesc      Description of arbitrary length for examples, etc.
	 *    @type string   $synopsis      The synopsis for the command (string or array).
	 *    @type string   $when          Execute callback on a named WP-CLI hook (e.g. before_wp_load).
	 *    @type bool     $is_deferred   Whether the command addition had already been deferred.
	 * }
	 * @return bool True on success, false if deferred, hard error if registration failed.
	 */
	public static function add_command( $name, $callable, $args = [] ) {
		// Bail immediately if the WP-CLI executable has not been run.
		if ( ! defined( 'WP_CLI' ) ) {
			return false;
		}

		$valid = false;
		if ( is_callable( $callable ) ) {
			$valid = true;
		} elseif ( is_string( $callable ) && class_exists( (string) $callable ) ) {
			$valid = true;
		} elseif ( is_object( $callable ) ) {
			$valid = true;
		} elseif ( Utils\is_valid_class_and_method_pair( $callable ) ) {
			$valid = true;
		}
		if ( ! $valid ) {
			if ( is_array( $callable ) ) {
				$callable[0] = is_object( $callable[0] ) ? get_class( $callable[0] ) : $callable[0];
				$callable    = [ $callable[0], $callable[1] ];
			}
			self::error( sprintf( 'Callable %s does not exist, and cannot be registered as `wp %s`.', json_encode( $callable ), $name ) );
		}

		$addition = new CommandAddition();
		self::do_hook( "before_add_command:{$name}", $addition );

		if ( $addition->was_aborted() ) {
			self::warning( "Aborting the addition of the command '{$name}' with reason: {$addition->get_reason()}." );
			return false;
		}

		foreach ( [ 'before_invoke', 'after_invoke' ] as $when ) {
			if ( isset( $args[ $when ] ) ) {
				self::add_hook( "{$when}:{$name}", $args[ $when ] );
			}
		}

		$path = preg_split( '/\s+/', $name );

		$leaf_name = array_pop( $path );

		$command = self::get_root_command();

		while ( ! empty( $path ) ) {
			$subcommand_name = $path[0];
			$parent          = implode( ' ', $path );
			$subcommand      = $command->find_subcommand( $path );

			// Parent not found. Defer addition or create an empty container as
			// needed.
			if ( ! $subcommand ) {
				if ( isset( $args['is_deferred'] ) && $args['is_deferred'] ) {
					$subcommand = new CompositeCommand(
						$command,
						$subcommand_name,
						new DocParser( '' )
					);

					self::debug(
						"Adding empty container for deferred command: {$name}",
						'commands'
					);

					$command->add_subcommand( $subcommand_name, $subcommand );
				} else {
					self::debug( "Deferring command: {$name}", 'commands' );

					self::defer_command_addition(
						$name,
						$parent,
						$callable,
						$args
					);

					return false;
				}
			}

			$command = $subcommand;
		}

		$leaf_command = CommandFactory::create( $leaf_name, $callable, $command );

		// Only add a command namespace if the command itself does not exist yet.
		if ( $leaf_command instanceof CommandNamespace
			&& array_key_exists( $leaf_name, $command->get_subcommands() ) ) {
			return false;
		}

		// Reattach commands attached to namespace to real command.
		$subcommand_name  = (array) $leaf_name;
		$existing_command = $command->find_subcommand( $subcommand_name );
		if ( $existing_command instanceof CompositeCommand && $existing_command->can_have_subcommands() ) {
			if ( $leaf_command instanceof CommandNamespace || ! $leaf_command->can_have_subcommands() ) {
				$command_to_keep = $existing_command;
			} else {
				$command_to_keep = $leaf_command;
			}

			self::merge_sub_commands( $command_to_keep, $existing_command, $leaf_command );
		}

		/** @var Dispatcher\Subcommand|Dispatcher\CompositeCommand|Dispatcher\CommandNamespace $leaf_command */

		if ( ! $command->can_have_subcommands() ) {
			throw new Exception(
				sprintf(
					"'%s' can't have subcommands.",
					implode( ' ', Dispatcher\get_path( $command ) )
				)
			);
		}

		/** @var Dispatcher\Subcommand $leaf_command */

		if ( isset( $args['shortdesc'] ) ) {
			$leaf_command->set_shortdesc( $args['shortdesc'] );
		}

		if ( isset( $args['longdesc'] ) ) {
			$leaf_command->set_longdesc( $args['longdesc'] );
		}

		if ( isset( $args['synopsis'] ) ) {
			if ( is_string( $args['synopsis'] ) ) {
				$leaf_command->set_synopsis( $args['synopsis'] );
			} elseif ( is_array( $args['synopsis'] ) ) {
				$synopsis = SynopsisParser::render( $args['synopsis'] );
				$leaf_command->set_synopsis( $synopsis );
				$long_desc = '';
				$bits      = explode( ' ', $synopsis );
				foreach ( $args['synopsis'] as $key => $arg ) {
					$long_desc .= $bits[ $key ] . "\n";
					if ( ! empty( $arg['description'] ) ) {
						$long_desc .= ': ' . $arg['description'] . "\n";
					}
					$yamlify = [];
					foreach ( [ 'default', 'options' ] as $key ) {
						if ( isset( $arg[ $key ] ) ) {
							$yamlify[ $key ] = $arg[ $key ];
						}
					}
					if ( ! empty( $yamlify ) ) {
						$long_desc .= Spyc::YAMLDump( $yamlify );
						$long_desc .= '---' . "\n";
					}
					$long_desc .= "\n";
				}
				if ( ! empty( $long_desc ) ) {
					$long_desc = rtrim( $long_desc, "\r\n" );
					$long_desc = '## OPTIONS' . "\n\n" . $long_desc;
					if ( ! empty( $args['longdesc'] ) ) {
						$long_desc .= "\n\n" . ltrim( $args['longdesc'], "\r\n" );
					}
					$leaf_command->set_longdesc( $long_desc );
				}
			}
		}

		if ( isset( $args['when'] ) ) {
			self::get_runner()->register_early_invoke( $args['when'], $leaf_command );
		}

		if ( ! empty( $parent ) ) {
			$sub_command = trim( str_replace( $parent, '', $name ) );
			self::debug( "Adding command: {$sub_command} in {$parent} Namespace", 'commands' );
		} else {
			self::debug( "Adding command: {$name}", 'commands' );
		}

		$command->add_subcommand( $leaf_name, $leaf_command );

		self::do_hook( "after_add_command:{$name}" );
		return true;
	}

	/**
	 * Merge the sub-commands of two commands into a single command to keep.
	 *
	 * @param CompositeCommand $command_to_keep Command to merge the sub commands into. This is typically one of the
	 *                                          two others.
	 * @param CompositeCommand $old_command     Command that was already registered.
	 * @param CompositeCommand $new_command     New command that is being added.
	 */
	private static function merge_sub_commands(
		CompositeCommand $command_to_keep,
		CompositeCommand $old_command,
		CompositeCommand $new_command
	) {
		foreach ( $old_command->get_subcommands() as $subname => $subcommand ) {
			$command_to_keep->add_subcommand( $subname, $subcommand, false );
		}

		foreach ( $new_command->get_subcommands() as $subname => $subcommand ) {
			$command_to_keep->add_subcommand( $subname, $subcommand, true );
		}
	}

	/**
	 * Defer command addition for a sub-command if the parent command is not yet
	 * registered.
	 *
	 * @param string $name     Name for the sub-command.
	 * @param string $parent   Name for the parent command.
	 * @param string $callable Command implementation as a class, function or closure.
	 * @param array  $args     Optional. See `WP_CLI::add_command()` for details.
	 */
	private static function defer_command_addition( $name, $parent, $callable, $args = [] ) {
		$args['is_deferred']               = true;
		self::$deferred_additions[ $name ] = [
			'parent'   => $parent,
			'callable' => $callable,
			'args'     => $args,
		];
		self::add_hook(
			"after_add_command:$parent",
			function () use ( $name ) {
				$deferred_additions = WP_CLI::get_deferred_additions();

				if ( ! array_key_exists( $name, $deferred_additions ) ) {
					return;
				}

				$callable = $deferred_additions[ $name ]['callable'];
				$args     = $deferred_additions[ $name ]['args'];
				WP_CLI::remove_deferred_addition( $name );

				WP_CLI::add_command( $name, $callable, $args );
			}
		);
	}

	/**
	 * Get the list of outstanding deferred command additions.
	 *
	 * @return array Array of outstanding command additions.
	 */
	public static function get_deferred_additions() {
		return self::$deferred_additions;
	}

	/**
	 * Remove a command addition from the list of outstanding deferred additions.
	 */
	public static function remove_deferred_addition( $name ) {
		if ( ! array_key_exists( $name, self::$deferred_additions ) ) {
			self::warning( "Trying to remove a non-existent command addition '{$name}'." );
		}

		unset( self::$deferred_additions[ $name ] );
	}

	/**
	 * Display informational message without prefix, and ignore `--quiet`.
	 *
	 * Message is written to STDOUT. `WP_CLI::log()` is typically recommended;
	 * `WP_CLI::line()` is included for historical compat.
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string $message Message to display to the end user.
	 * @return void
	 */
	public static function line( $message = '' ) {
		echo $message . "\n";
	}

	/**
	 * Display informational message without prefix.
	 *
	 * Message is written to STDOUT, or discarded when `--quiet` flag is supplied.
	 *
	 * ```
	 * # `wp cli update` lets user know of each step in the update process.
	 * WP_CLI::log( sprintf( 'Downloading from %s...', $download_url ) );
	 * ```
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string $message Message to write to STDOUT.
	 */
	public static function log( $message ) {
		if ( null === self::$logger ) {
			return;
		}

		self::$logger->info( $message );
	}

	/**
	 * Display success message prefixed with "Success: ".
	 *
	 * Success message is written to STDOUT, or discarded when `--quiet` flag is supplied.
	 *
	 * Typically recommended to inform user of successful script conclusion.
	 *
	 * ```
	 * # wp rewrite flush expects 'rewrite_rules' option to be set after flush.
	 * flush_rewrite_rules( \WP_CLI\Utils\get_flag_value( $assoc_args, 'hard' ) );
	 * if ( ! get_option( 'rewrite_rules' ) ) {
	 *     WP_CLI::warning( "Rewrite rules are empty." );
	 * } else {
	 *     WP_CLI::success( 'Rewrite rules flushed.' );
	 * }
	 * ```
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string $message Message to write to STDOUT.
	 * @return void
	 */
	public static function success( $message ) {
		if ( null === self::$logger ) {
			return;
		}

		self::$logger->success( $message );
	}

	/**
	 * Display debug message prefixed with "Debug: " when `--debug` is used.
	 *
	 * Debug message is written to STDERR, and includes script execution time.
	 *
	 * Helpful for optionally showing greater detail when needed. Used throughout
	 * WP-CLI bootstrap process for easier debugging and profiling.
	 *
	 * ```
	 * # Called in `WP_CLI\Runner::set_wp_root()`.
	 * private static function set_wp_root( $path ) {
	 *     define( 'ABSPATH', Utils\trailingslashit( $path ) );
	 *     WP_CLI::debug( 'ABSPATH defined: ' . ABSPATH );
	 *     $_SERVER['DOCUMENT_ROOT'] = realpath( $path );
	 * }
	 *
	 * # Debug details only appear when `--debug` is used.
	 * # $ wp --debug
	 * # [...]
	 * # Debug: ABSPATH defined: /srv/www/wordpress-develop.dev/src/ (0.225s)
	 * ```
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string|WP_Error|Exception|Throwable $message Message to write to STDERR.
	 * @param string|bool $group Organize debug message to a specific group.
	 * Use `false` to not group the message.
	 * @return void
	 */
	public static function debug( $message, $group = false ) {
		static $storage = [];

		if ( ! self::$logger ) {
			$storage[] = [ $message, $group ];
			return;
		}

		if ( ! empty( $storage ) ) {
			foreach ( $storage as $entry ) {
				list( $stored_message, $stored_group ) = $entry;
				self::$logger->debug( self::error_to_string( $stored_message ), $stored_group );
			}
			$storage = [];
		}

		self::$logger->debug( self::error_to_string( $message ), $group );
	}

	/**
	 * Display warning message prefixed with "Warning: ".
	 *
	 * Warning message is written to STDERR, or discarded when `--quiet` flag is supplied.
	 *
	 * Use instead of `WP_CLI::debug()` when script execution should be permitted
	 * to continue.
	 *
	 * ```
	 * # `wp plugin activate` skips activation when plugin is network active.
	 * $status = $this->get_status( $plugin->file );
	 * // Network-active is the highest level of activation status
	 * if ( 'active-network' === $status ) {
	 *   WP_CLI::warning( "Plugin '{$plugin->name}' is already network active." );
	 *   continue;
	 * }
	 * ```
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string|WP_Error|Exception|Throwable $message Message to write to STDERR.
	 * @return void
	 */
	public static function warning( $message ) {
		if ( null === self::$logger ) {
			return;
		}

		self::$logger->warning( self::error_to_string( $message ) );
	}

	/**
	 * Display error message prefixed with "Error: " and exit script.
	 *
	 * Error message is written to STDERR. Defaults to halting script execution
	 * with return code 1.
	 *
	 * Use `WP_CLI::warning()` instead when script execution should be permitted
	 * to continue.
	 *
	 * ```
	 * # `wp cache flush` considers flush failure to be a fatal error.
	 * if ( false === wp_cache_flush() ) {
	 *     WP_CLI::error( 'The object cache could not be flushed.' );
	 * }
	 * ```
	 *
	 * @access public
	 * @category Output
	 *
	 * @param string|WP_Error|Exception|Throwable $message Message to write to STDERR.
	 * @param boolean|integer            $exit    True defaults to exit(1).
	 * @return null
	 */
	public static function error( $message, $exit = true ) {
		if ( null !== self::$logger && ! isset( self::get_runner()->assoc_args['completions'] ) ) {
			self::$logger->error( self::error_to_string( $message ) );
		}

		$return_code = false;
		if ( true === $exit ) {
			$return_code = 1;
		} elseif ( is_int( $exit ) && $exit >= 1 ) {
			$return_code = $exit;
		}

		if ( $return_code ) {
			if ( self::$capture_exit ) {
				throw new ExitException( '', $return_code );
			}
			exit( $return_code );
		}
	}

	/**
	 * Halt script execution with a specific return code.
	 *
	 * Permits script execution to be overloaded by `WP_CLI::runcommand()`
	 *
	 * @access public
	 * @category Output
	 *
	 * @param integer $return_code
	 * @return never
	 */
	public static function halt( $return_code ) {
		if ( self::$capture_exit ) {
			throw new ExitException( '', $return_code );
		}
		exit( $return_code );
	}

	/**
	 * Display a multi-line error message in a red box. Doesn't exit script.
	 *
	 * Error message is written to STDERR.
	 *
	 * @access public
	 * @category Output
	 *
	 * @param array $message_lines Multi-line error message to be displayed.
	 */
	public static function error_multi_line( $message_lines ) {
		if ( null === self::$logger ) {
			return;
		}

		if ( ! isset( self::get_runner()->assoc_args['completions'] ) && is_array( $message_lines ) ) {
			self::$logger->error_multi_line( array_map( [ __CLASS__, 'error_to_string' ], $message_lines ) );
		}
	}

	/**
	 * Ask for confirmation before running a destructive operation.
	 *
	 * If 'y' is provided to the question, the script execution continues. If
	 * 'n' or any other response is provided to the question, script exits.
	 *
	 * ```
	 * # `wp db drop` asks for confirmation before dropping the database.
	 *
	 * WP_CLI::confirm( "Are you sure you want to drop the database?", $assoc_args );
	 * ```
	 *
	 * @access public
	 * @category Input
	 *
	 * @param string $question Question to display before the prompt.
	 * @param array $assoc_args Skips prompt if 'yes' is provided.
	 */
	public static function confirm( $question, $assoc_args = [] ) {
		if ( ! Utils\get_flag_value( $assoc_args, 'yes' ) ) {
			fwrite( STDOUT, $question . ' [y/n] ' );

			$answer = strtolower( trim( fgets( STDIN ) ) );

			if ( 'y' !== $answer ) {
				exit;
			}
		}
	}

	/**
	 * Read value from a positional argument or from STDIN.
	 *
	 * @param array $args The list of positional arguments.
	 * @param int $index At which position to check for the value.
	 *
	 * @return string
	 */
	public static function get_value_from_arg_or_stdin( $args, $index ) {
		if ( isset( $args[ $index ] ) ) {
			$raw_value = $args[ $index ];
		} else {
			// We don't use file_get_contents() here because it doesn't handle
			// Ctrl-D properly, when typing in the value interactively.
			$raw_value = '';
			$line      = fgets( STDIN );

			while ( false !== $line ) {
				$raw_value .= $line;
				$line       = fgets( STDIN );
			}
		}

		return $raw_value;
	}

	/**
	 * Read a value, from various formats.
	 *
	 * @access public
	 * @category Input
	 *
	 * @param mixed $raw_value
	 * @param array $assoc_args
	 */
	public static function read_value( $raw_value, $assoc_args = [] ) {
		if ( Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) {
			$value = json_decode( $raw_value, true );
			if ( null === $value ) {
				self::error( sprintf( 'Invalid JSON: %s', $raw_value ) );
			}
		} else {
			$value = $raw_value;
		}

		return $value;
	}

	/**
	 * Display a value, in various formats
	 *
	 * @param mixed $value Value to display.
	 * @param array $assoc_args Arguments passed to the command, determining format.
	 */
	public static function print_value( $value, $assoc_args = [] ) {
		if ( Utils\get_flag_value( $assoc_args, 'format' ) === 'json' ) {
			$value = json_encode( $value );
		} elseif ( Utils\get_flag_value( $assoc_args, 'format' ) === 'yaml' ) {
			$value = Spyc::YAMLDump( $value, 2, 0 );
		} elseif ( is_array( $value ) || is_object( $value ) ) {
			$value = var_export( $value, true );
		}

		echo $value . "\n";
	}

	/**
	 * Convert a WP_Error or Exception into a string
	 *
	 * @param string|WP_Error|Exception|Throwable $errors
	 * @throws InvalidArgumentException
	 *
	 * @return string
	 */
	public static function error_to_string( $errors ) {
		if ( is_string( $errors ) ) {
			return $errors;
		}

		// Only json_encode() the data when it needs it.
		$render_data = function ( $data ) {
			if ( is_array( $data ) || is_object( $data ) ) {
				return json_encode( $data );
			}

			return '"' . $data . '"';
		};

		if ( $errors instanceof WP_Error ) {
			foreach ( $errors->get_error_messages() as $message ) {
				if ( $errors->get_error_data() ) {
					return $message . ' ' . $render_data( $errors->get_error_data() );
				}

				return $message;
			}
		}

		// PHP 7+: internal and user exceptions must implement Throwable interface.
		// PHP 5: internal and user exceptions must extend Exception class.
		if ( ( interface_exists( 'Throwable' ) && ( $errors instanceof Throwable ) ) || ( $errors instanceof Exception ) ) {
			return get_class( $errors ) . ': ' . $errors->getMessage();
		}

		throw new InvalidArgumentException(
			sprintf(
				"Unsupported argument type passed to WP_CLI::error_to_string(): '%s'",
				gettype( $errors )
			)
		);
	}

	/**
	 * Launch an arbitrary external process that takes over I/O.
	 *
	 * ```
	 * # `wp core download` falls back to the `tar` binary when PharData isn't available
	 * if ( ! class_exists( 'PharData' ) ) {
	 *     $cmd = "tar xz --strip-components=1 --directory=%s -f $tarball";
	 *     WP_CLI::launch( Utils\esc_cmd( $cmd, $dest ) );
	 *     return;
	 * }
	 * ```
	 *
	 * @access public
	 * @category Execution
	 *
	 * @param string $command External process to launch.
	 * @param boolean $exit_on_error Whether to exit if the command returns an elevated return code.
	 * @param boolean $return_detailed Whether to return an exit status (default) or detailed execution results.
	 * @return int|ProcessRun The command exit status, or a ProcessRun object for full details.
	 */
	public static function launch( $command, $exit_on_error = true, $return_detailed = false ) {
		Utils\check_proc_available( 'launch' );

		$proc    = Process::create( $command );
		$results = $proc->run();

		if ( -1 === $results->return_code ) {
			self::warning( "Spawned process returned exit code {$results->return_code}, which could be caused by a custom compiled version of PHP that uses the --enable-sigchild option." );
		}

		if ( $results->return_code && $exit_on_error ) {
			exit( $results->return_code );
		}

		if ( $return_detailed ) {
			return $results;
		}

		return $results->return_code;
	}

	/**
	 * Run a WP-CLI command in a new process reusing the current runtime arguments.
	 *
	 * Use `WP_CLI::runcommand()` instead, which is easier to use and works better.
	 *
	 * Note: While this command does persist a limited set of runtime arguments,
	 * it *does not* persist environment variables. Practically speaking, WP-CLI
	 * packages won't be loaded when using WP_CLI::launch_self() because the
	 * launched process doesn't have access to the current process $HOME.
	 *
	 * @access public
	 * @category Execution
	 *
	 * @param string $command WP-CLI command to call.
	 * @param array $args Positional arguments to include when calling the command.
	 * @param array $assoc_args Associative arguments to include when calling the command.
	 * @param bool $exit_on_error Whether to exit if the command returns an elevated return code.
	 * @param bool $return_detailed Whether to return an exit status (default) or detailed execution results.
	 * @param array $runtime_args Override one or more global args (path,url,user,allow-root)
	 * @return int|ProcessRun The command exit status, or a ProcessRun instance
	 */
	public static function launch_self( $command, $args = [], $assoc_args = [], $exit_on_error = true, $return_detailed = false, $runtime_args = [] ) {
		$reused_runtime_args = [
			'path',
			'url',
			'user',
			'allow-root',
		];

		foreach ( $reused_runtime_args as $key ) {
			if ( isset( $runtime_args[ $key ] ) ) {
				$assoc_args[ $key ] = $runtime_args[ $key ];
				continue;
			}

			$value = self::get_runner()->config[ $key ];
			if ( $value ) {
				$assoc_args[ $key ] = $value;
			}
		}

		$php_bin = escapeshellarg( Utils\get_php_binary() );

		$script_path = $GLOBALS['argv'][0];

		if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) {
			$config_path = getenv( 'WP_CLI_CONFIG_PATH' );
		} else {
			$config_path = Utils\get_home_dir() . '/.wp-cli/config.yml';
		}
		$config_path = escapeshellarg( $config_path );

		$args       = implode( ' ', array_map( 'escapeshellarg', $args ) );
		$assoc_args = Utils\assoc_args_to_str( $assoc_args );

		$full_command = "WP_CLI_CONFIG_PATH={$config_path} {$php_bin} {$script_path} {$command} {$args} {$assoc_args}";

		return self::launch( $full_command, $exit_on_error, $return_detailed );
	}

	/**
	 * Get the path to the PHP binary used when executing WP-CLI.
	 *
	 * Environment values permit specific binaries to be indicated.
	 *
	 * Note: moved to Utils, left for BC.
	 *
	 * @access public
	 * @category System
	 *
	 * @return string
	 */
	public static function get_php_binary() {
		return Utils\get_php_binary();
	}

	/**
	 * Confirm that a global configuration parameter does exist.
	 *
	 * @access public
	 * @category Input
	 *
	 * @param string $key Config parameter key to check.
	 *
	 * @return bool
	 */
	public static function has_config( $key ) {
		return array_key_exists( $key, self::get_runner()->config );
	}

	/**
	 * Get values of global configuration parameters.
	 *
	 * Provides access to `--path=<path>`, `--url=<url>`, and other values of
	 * the [global configuration parameters](https://make.wordpress.org/cli/handbook/references/config/).
	 *
	 * ```
	 * WP_CLI::log( 'The --url=<url> value is: ' . WP_CLI::get_config( 'url' ) );
	 * ```
	 *
	 * @access public
	 * @category Input
	 *
	 * @param string $key Get value for a specific global configuration parameter.
	 * @return mixed
	 */
	public static function get_config( $key = null ) {
		if ( null === $key ) {
			return self::get_runner()->config;
		}

		if ( ! self::has_config( $key ) ) {
			self::warning( "Unknown config option '$key'." );
			return null;
		}

		return self::get_runner()->config[ $key ];
	}

	/**
	 * Run a WP-CLI command.
	 *
	 * Launches a new child process to run a specified WP-CLI command.
	 * Optionally:
	 *
	 * * Run the command in an existing process.
	 * * Prevent halting script execution on error.
	 * * Capture and return STDOUT, or full details about command execution.
	 * * Parse JSON output if the command rendered it.
	 * * Include additional arguments that are passed to the command.
	 *
	 * ```
	 * $options = array(
	 *   'return'       => true,                // Return 'STDOUT'; use 'all' for full object.
	 *   'parse'        => 'json',              // Parse captured STDOUT to JSON array.
	 *   'launch'       => false,               // Reuse the current process.
	 *   'exit_error'   => true,                // Halt script execution on error.
	 *   'command_args' => [ '--skip-themes' ], // Additional arguments to be passed to the $command.
	 * );
	 * $plugins = WP_CLI::runcommand( 'plugin list --format=json', $options );
	 * ```
	 *
	 * @access public
	 * @category Execution
	 *
	 * @param string $command WP-CLI command to run, including arguments.
	 * @param array  $options {
	 *     Configuration options for command execution.
	 *
	 *     @type bool        $launch     Launches a new process (true) or reuses the existing process (false). Default: true.
	 *     @type bool        $exit_error Halts the script on error. Default: true.
	 *     @type bool|string $return     Returns output as an object when set to 'all' (string), return just the 'stdout', 'stderr', or 'return_code' (string) of command, or print directly to stdout/stderr (false). Default: false.
	 *     @type bool|string $parse      Parse returned output as 'json' (string); otherwise, output is unchanged (false). Default: false.
	 * @param array $command_args Contains additional command line arguments for the command. Each element represents a single argument. Default: empty array.
	 * }
	 * @return mixed
	 */
	public static function runcommand( $command, $options = [] ) {
		$defaults     = [
			'launch'       => true,  // Launch a new process, or reuse the existing.
			'exit_error'   => true,  // Exit on error by default.
			'return'       => false, // Capture and return output, or render in realtime.
			'parse'        => false, // Parse returned output as a particular format.
			'command_args' => [],    // Include optional command arguments.
		];
		$options      = array_merge( $defaults, $options );
		$launch       = $options['launch'];
		$exit_error   = $options['exit_error'];
		$return       = $options['return'];
		$parse        = $options['parse'];
		$command_args = $options['command_args'];

		if ( ! empty( $command_args ) ) {
			$command .= ' ' . implode( ' ', $command_args );
		}

		$retval = null;
		if ( $launch ) {
			Utils\check_proc_available( 'launch option' );

			$descriptors = [
				0 => STDIN,
				1 => STDOUT,
				2 => STDERR,
			];

			if ( $return ) {
				$descriptors = [
					0 => STDIN,
					1 => [ 'pipe', 'w' ],
					2 => [ 'pipe', 'w' ],
				];
			}

			$php_bin     = escapeshellarg( Utils\get_php_binary() );
			$script_path = $GLOBALS['argv'][0];

			// Persist runtime arguments unless they've been specified otherwise.
			$configurator = self::get_configurator();
			$argv         = array_slice( $GLOBALS['argv'], 1 );

			list( $ignore1, $ignore2, $runtime_config ) = $configurator->parse_args( $argv );
			foreach ( $runtime_config as $k => $v ) {
				if ( preg_match( "|^--{$k}=?$|", $command ) ) {
					unset( $runtime_config[ $k ] );
				}
			}
			$runtime_config = Utils\assoc_args_to_str( $runtime_config );

			$runcommand = "{$php_bin} {$script_path} {$runtime_config} {$command}";

			$pipes = [];
			$proc  = Utils\proc_open_compat( $runcommand, $descriptors, $pipes, getcwd() );

			$stdout = '';
			$stderr = '';

			if ( $return ) {
				$stdout = stream_get_contents( $pipes[1] );
				fclose( $pipes[1] );
				$stderr = stream_get_contents( $pipes[2] );
				fclose( $pipes[2] );
			}
			$return_code = proc_close( $proc );
			if ( -1 === $return_code ) {
				self::warning( 'Spawned process returned exit code -1, which could be caused by a custom compiled version of PHP that uses the --enable-sigchild option.' );
			} elseif ( $return_code && $exit_error ) {
				exit( $return_code );
			}
			if ( true === $return || 'stdout' === $return ) {
				$retval = trim( $stdout );
			} elseif ( 'stderr' === $return ) {
				$retval = trim( $stderr );
			} elseif ( 'return_code' === $return ) {
				$retval = $return_code;
			} elseif ( 'all' === $return ) {
				$retval = (object) [
					'stdout'      => trim( $stdout ),
					'stderr'      => trim( $stderr ),
					'return_code' => $return_code,
				];
			}
		} else {
			$configurator                               = self::get_configurator();
			$argv                                       = Utils\parse_str_to_argv( $command );
			list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( $argv );
			if ( $return ) {
				$existing_logger = self::$logger;
				self::$logger    = new Execution();
				self::$logger->ob_start();
			}
			if ( ! $exit_error ) {
				self::$capture_exit = true;
			}
			try {
				self::get_runner()->run_command(
					$args,
					$assoc_args,
					[
						'back_compat_conversions' => true,
					]
				);
				$return_code = 0;
			} catch ( ExitException $e ) {
				$return_code = $e->getCode();
			}
			if ( $return ) {
				$execution_logger = self::$logger;
				$execution_logger->ob_end();
				self::$logger = $existing_logger;
				$stdout       = $execution_logger->stdout;
				$stderr       = $execution_logger->stderr;
				if ( true === $return || 'stdout' === $return ) {
					$retval = trim( $stdout );
				} elseif ( 'stderr' === $return ) {
					$retval = trim( $stderr );
				} elseif ( 'return_code' === $return ) {
					$retval = $return_code;
				} elseif ( 'all' === $return ) {
					$retval = (object) [
						'stdout'      => trim( $stdout ),
						'stderr'      => trim( $stderr ),
						'return_code' => $return_code,
					];
				}
			}
			if ( ! $exit_error ) {
				self::$capture_exit = false;
			}
		}
		if ( ( true === $return || 'stdout' === $return )
			&& 'json' === $parse ) {
			$retval = json_decode( $retval, true );
		}
		return $retval;
	}

	/**
	 * Run a given command within the current process using the same global
	 * parameters.
	 *
	 * Use `WP_CLI::runcommand()` instead, which is easier to use and works better.
	 *
	 * To run a command using a new process with the same global parameters,
	 * use WP_CLI::launch_self(). To run a command using a new process with
	 * different global parameters, use WP_CLI::launch().
	 *
	 * ```
	 * ob_start();
	 * WP_CLI::run_command( array( 'cli', 'cmd-dump' ) );
	 * $ret = ob_get_clean();
	 * ```
	 *
	 * @access public
	 * @category Execution
	 *
	 * @param array $args Positional arguments including command name.
	 * @param array $assoc_args
	 */
	public static function run_command( $args, $assoc_args = [] ) {
		self::get_runner()->run_command( $args, $assoc_args );
	}



	// DEPRECATED STUFF.

	public static function add_man_dir() {
		trigger_error( 'WP_CLI::add_man_dir() is deprecated. Add docs inline.', E_USER_WARNING );
	}

	// back-compat.
	public static function out( $str ) {
		fwrite( STDOUT, $str );
	}

	// back-compat.
	// phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid -- Deprecated method.
	public static function addCommand( $name, $class ) {
		trigger_error(
			sprintf(
				'wp %s: %s is deprecated. use WP_CLI::add_command() instead.',
				$name,
				__FUNCTION__
			),
			E_USER_WARNING
		);
		self::add_command( $name, $class );
	}
}
<?php

/**
 * This file contains fallback functions that might have been disabled but are required nevertheless.
 */

if ( PHP_MAJOR_VERSION >= 8 && ! function_exists( 'ini_set' ) ) {
	function ini_set( $option, $value ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- This is a stub only.
		return false;
	}
}
<?php

namespace WP_CLI\Dispatcher;

/**
 * Get the path to a command, e.g. "core download"
 *
 * @param Subcommand|CompositeCommand $command
 * @return string[]
 */
function get_path( $command ) {
	$path = [];

	do {
		array_unshift( $path, $command->get_name() );
		$command = $command->get_parent();
	} while ( $command );

	return $path;
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class DeclareFallbackFunctions.
 *
 * Declares functions that might have been disabled but are required.
 *
 * @package WP_CLI\Bootstrap
 */
final class DeclareFallbackFunctions implements BootstrapStep {
	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		include __DIR__ . '/../../fallback-functions.php';

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;

/**
 * Class LoadExtraCommand.
 *
 * Loads a command that was passed through the `--exec=<php-code>` option.
 *
 * @package WP_CLI\Bootstrap
 */
final class LoadExecCommand implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		if ( $state->getValue( BootstrapState::IS_PROTECTED_COMMAND, false ) ) {
			return $state;
		}

		$runner = new RunnerInstance();
		if ( ! isset( $runner()->config['exec'] ) ) {
			return $state;
		}

		foreach ( $runner()->config['exec'] as $php_code ) {
			eval( $php_code ); // phpcs:ignore Squiz.PHP.Eval.Discouraged
		}

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class DeclareMainClass.
 *
 * Declares the main `WP_CLI` class.
 *
 * @package WP_CLI\Bootstrap
 */
final class DeclareMainClass implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		require_once WP_CLI_ROOT . '/php/class-wp-cli.php';

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;

/**
 * Class IncludeFallbackAutoloader.
 *
 * Loads the fallback autoloader that is provided through the `composer.json`
 * file.
 *
 * @package WP_CLI\Bootstrap
 */
final class IncludeFallbackAutoloader extends AutoloaderStep {

	/**
	 * Get the autoloader paths to scan for an autoloader.
	 *
	 * @return string[] Array of autoloader paths, or an empty array if none are found.
	 */
	protected function get_autoloader_paths() {
		$autoloader_paths = [
			WP_CLI_VENDOR_DIR . '/autoload.php',
		];

		$custom_vendor = $this->get_custom_vendor_folder();
		if ( false !== $custom_vendor ) {
			array_unshift(
				$autoloader_paths,
				WP_CLI_ROOT . '/../../../' . $custom_vendor . '/autoload.php'
			);
		}

		WP_CLI::debug(
			sprintf(
				'Fallback autoloader paths: %s',
				implode( ', ', $autoloader_paths )
			),
			'bootstrap'
		);

		return $autoloader_paths;
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class LaunchRunner.
 *
 * Kick off the Runner object that starts the actual commands.
 *
 * @package WP_CLI\Bootstrap
 */
final class LaunchRunner implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$runner = new RunnerInstance();

		$runner()->register_context_manager(
			$state->getValue( 'context_manager' )
		);

		$runner()->start();

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class LoadUtilityFunctions.
 *
 * Loads the functions available through `WP_CLI\Utils`.
 *
 * @package WP_CLI\Bootstrap
 */
final class LoadUtilityFunctions implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		require_once WP_CLI_ROOT . '/php/utils.php';

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Interface BootstrapStep.
 *
 * Represents a single bootstrapping step that can be processed.
 *
 * @package WP_CLI\Bootstrap
 */
interface BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state );
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI\Autoloader;
use WP_CLI\RequestsLibrary;
use WP_CLI\Utils;

/**
 * Class IncludeRequestsAutoloader.
 *
 * Loads the Requests autoloader that best fits the current environment.
 *
 * If a WordPress installation is found, it autoloads that version of Requests.
 * Otherwise, it loads the version of Requests bundled with WP-CLI.
 *
 * This is done in order to avoid conflicts between Requests versions.
 *
 * @package WP_CLI\Bootstrap
 */
final class IncludeRequestsAutoloader implements BootstrapStep {

	/**
	 * Requests is being used from the WordPress installation.
	 *
	 * @var string
	 */
	const FROM_WP_CORE = 'wp-core';

	/**
	 * Requests is being used from the WP-CLI dependencies.
	 *
	 * @var string
	 */
	const FROM_WP_CLI = 'wp-cli';

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		// If Requests is already loaded, don't do anything.
		if ( class_exists( RequestsLibrary::CLASS_NAME_V2, false ) || class_exists( RequestsLibrary::CLASS_NAME_V1, false ) ) {
			return $state;
		}

		$runner = new RunnerInstance();

		// Use `--path` from the alias if one is matching.
		$alias_path = null;
		if ( $runner()->alias
			&& isset( $runner()->aliases[ $runner()->alias ]['path'] ) ) {
			$alias_path = $runner()->aliases[ $runner()->alias ]['path'];
			// Make sure it isn't an invalid value.
			if ( is_bool( $alias_path ) || empty( $alias_path ) ) {
				return $state;
			}
			if ( ! Utils\is_path_absolute( $alias_path ) ) {
				$alias_path = getcwd() . '/' . $alias_path;
			}
			$wp_root = rtrim( $alias_path, '/' );
		} else {
			// Make sure we don't deal with an invalid `--path` value.
			$config = $runner()->config;
			if ( isset( $config['path'] ) &&
				( is_bool( $config['path'] ) || empty( $config['path'] ) )
			) {
				return $state;
			}
			$wp_root = rtrim( $runner()->find_wp_root(), '/' );
		}

		// First try to detect a newer Requests version bundled with WordPress.
		if ( file_exists( $wp_root . '/wp-includes/Requests/src/Autoload.php' ) ) {
			if ( ! class_exists( '\\WpOrg\\Requests\\Autoload', false ) ) {
				require_once $wp_root . '/wp-includes/Requests/src/Autoload.php';
			}

			if ( class_exists( '\\WpOrg\\Requests\\Autoload' ) ) {
				\WpOrg\Requests\Autoload::register();
				$this->store_requests_meta( RequestsLibrary::CLASS_NAME_V2, self::FROM_WP_CORE );
				return $state;
			}
		}

		// Then see if we can detect the older version bundled with WordPress.
		if ( file_exists( $wp_root . '/wp-includes/class-requests.php' ) ) {
			if ( ! class_exists( '\\Requests', false ) ) {
				require_once $wp_root . '/wp-includes/class-requests.php';
			}

			if ( class_exists( '\\Requests' ) ) {
				\Requests::register_autoloader();
				$this->store_requests_meta( RequestsLibrary::CLASS_NAME_V1, self::FROM_WP_CORE );
				return $state;
			}
		}

		// Finally, fall back to the Requests version bundled with WP-CLI.
		$autoloader = new Autoloader();
		$autoloader->add_namespace(
			'WpOrg\Requests',
			WP_CLI_ROOT . '/bundle/rmccue/requests/src'
		);

		$autoloader->register();

		\WpOrg\Requests\Autoload::register();

		$this->store_requests_meta( RequestsLibrary::CLASS_NAME_V2, self::FROM_WP_CLI );

		return $state;
	}

	/**
	 * Store meta information about the used Requests integration.
	 *
	 * This can be used for all the conditional code that needs to work
	 * across multiple Requests versions.
	 *
	 * @param string $class_name The class name of the Requests integration.
	 * @param string $source     The source of the Requests integration.
	 */
	private function store_requests_meta( $class_name, $source ) {
		RequestsLibrary::set_version(
			RequestsLibrary::CLASS_NAME_V2 === $class_name
				? RequestsLibrary::VERSION_V2
				: RequestsLibrary::VERSION_V1
		);
		RequestsLibrary::set_source( $source );
		RequestsLibrary::set_class_name( $class_name );
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;
use WP_CLI\Runner;

/**
 * Class RunnerInstance.
 *
 * Convenience class for steps that make use of the `WP_CLI\Runner` object.
 *
 * @package WP_CLI\Bootstrap
 */
final class RunnerInstance {

	/**
	 * Return an instance of the `WP_CLI\Runner` object.
	 *
	 * Includes necessary class files first as needed.
	 *
	 * @return Runner
	 */
	public function __invoke() {
		if ( ! class_exists( 'WP_CLI\Runner' ) ) {
			require_once WP_CLI_ROOT . '/php/WP_CLI/Runner.php';
		}

		if ( ! class_exists( 'WP_CLI\Configurator' ) ) {
			require_once WP_CLI_ROOT . '/php/WP_CLI/Configurator.php';
		}

		return WP_CLI::get_runner();
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class ConfigureRunner.
 *
 * Initialize the configuration for the `WP_CLI\Runner` object.
 *
 * @package WP_CLI\Bootstrap
 */
final class ConfigureRunner implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$runner = new RunnerInstance();
		$runner()->init_config();

		$state->setValue( 'config', $runner()->config );
		$state->setValue( 'arguments', $runner()->arguments );
		$state->setValue( 'assoc_args', $runner()->assoc_args );

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class DeclareAbstractBaseCommand.
 *
 * Declares the abstract `WP_CLI_Command` base class.
 *
 * @package WP_CLI\Bootstrap
 */
final class DeclareAbstractBaseCommand implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		require_once WP_CLI_ROOT . '/php/class-wp-cli-command.php';

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use DirectoryIterator;

/**
 * Class InitializeLogger.
 *
 * Initialize the logger through the `WP_CLI\Runner` object.
 *
 * @package WP_CLI\Bootstrap
 */
final class InitializeLogger implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$this->declare_loggers();
		$runner = new RunnerInstance();
		$runner()->init_logger();

		return $state;
	}

	/**
	 * Load the class declarations for the loggers.
	 */
	private function declare_loggers() {
		$logger_dir = WP_CLI_ROOT . '/php/WP_CLI/Loggers';
		$iterator   = new DirectoryIterator( $logger_dir );

		// Make sure the base class is declared first.
		include_once "$logger_dir/Base.php";

		foreach ( $iterator as $filename ) {
			if ( '.php' !== substr( $filename, - 4 ) ) {
				continue;
			}

			include_once "$logger_dir/$filename";
		}
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class LoadDispatcher.
 *
 * Loads the dispatcher that will dispatch command names to file locations.
 *
 * @package WP_CLI\Bootstrap
 */
final class LoadDispatcher implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		require_once WP_CLI_ROOT . '/php/dispatcher.php';

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;
use WP_CLI\Utils;

/**
 * Class LoadRequiredCommand.
 *
 * Loads a command that was passed through the `--require=<command>` option.
 *
 * @package WP_CLI\Bootstrap
 */
final class LoadRequiredCommand implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		if ( $state->getValue( BootstrapState::IS_PROTECTED_COMMAND, false ) ) {
			return $state;
		}

		$runner = new RunnerInstance();
		if ( ! isset( $runner()->config['require'] ) ) {
			return $state;
		}

		foreach ( $runner()->config['require'] as $path ) {
			if ( ! file_exists( $path ) ) {
				$context        = '';
				$required_files = $runner()->get_required_files();
				foreach ( [ 'global', 'project', 'runtime' ] as $scope ) {
					if ( in_array( $path, $required_files[ $scope ], true ) ) {
						switch ( $scope ) {
							case 'global':
								$context = ' (from global ' . Utils\basename( $runner()->get_global_config_path() ) . ')';
								break;
							case 'project':
								$context = ' (from project\'s ' . Utils\basename( $runner()->get_project_config_path() ) . ')';
								break;
							case 'runtime':
								$context = ' (from runtime argument)';
								break;
						}
						break;
					}
				}
				WP_CLI::error( sprintf( "Required file '%s' doesn't exist%s.", Utils\basename( $path ), $context ) );
			}
			Utils\load_file( $path );
			WP_CLI::debug( 'Required file from config: ' . $path, 'bootstrap' );
		}

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use DirectoryIterator;
use Exception;
use WP_CLI;

/**
 * Class RegisterFrameworkCommands.
 *
 * Register the commands that are directly included with the framework.
 *
 * @package WP_CLI\Bootstrap
 */
final class RegisterFrameworkCommands implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$cmd_dir = WP_CLI_ROOT . '/php/commands';

		$iterator = new DirectoryIterator( $cmd_dir );

		foreach ( $iterator as $filename ) {
			if ( '.php' !== substr( $filename, - 4 ) ) {
				continue;
			}

			try {
				WP_CLI::debug(
					sprintf(
						'Adding framework command: %s',
						"$cmd_dir/$filename"
					),
					'bootstrap'
				);

				include_once "$cmd_dir/$filename";
			} catch ( Exception $exception ) {
				WP_CLI::warning(
					"Could not add command {$cmd_dir}/{$filename}. Reason: " . $exception->getMessage()
				);
			}
		}

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class BootstrapState.
 *
 * Represents the state that is passed from one bootstrap step to the next.
 *
 * @package WP_CLI\Bootstrap
 *
 * Maintain BC: Changing the method names in this class breaks autoload interactions between Phar
 * & framework/commands you use outside of Phar (like when running the Phar WP inside of a command folder).
 * @phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
 */
class BootstrapState {

	/**
	 * Whether the command currently being run is "protected".
	 *
	 * This means that the command should not be allowed to break due to
	 * extension code.
	 */
	const IS_PROTECTED_COMMAND = 'is_protected_command';

	/**
	 * Internal storage of the state values.
	 *
	 * @var array
	 */
	private $state = [];

	/**
	 * Get the state value for a given key.
	 *
	 * @param string $key      Key to get the state from.
	 * @param mixed  $fallback Fallback value to use if the key is not defined.
	 *
	 * @return mixed
	 */
	public function getValue( $key, $fallback = null ) {
		return array_key_exists( $key, $this->state )
			? $this->state[ $key ]
			: $fallback;
	}

	/**
	 * Set the state value for a given key.
	 *
	 * @param string $key   Key to set the state for.
	 * @param mixed  $value Value to set the state for the given key to.
	 *
	 * @return void
	 */
	public function setValue( $key, $value ) {
		$this->state[ $key ] = $value;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;
use WP_CLI\Context;
use WP_CLI\ContextManager;

/**
 * Class InitializeContexts.
 *
 * @package WP_CLI\Bootstrap
 */
final class InitializeContexts implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$context_manager = new ContextManager();

		$contexts = [
			Context::CLI      => new Context\Cli(),
			Context::ADMIN    => new Context\Admin(),
			Context::FRONTEND => new Context\Frontend(),
			Context::AUTO     => new Context\Auto( $context_manager ),
		];

		$contexts = WP_CLI::do_hook( 'before_registering_contexts', $contexts );

		foreach ( $contexts as $name => $implementation ) {
			$context_manager->register_context( $name, $implementation );
		}

		$state->setValue( 'context_manager', $context_manager );

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use Exception;
use WP_CLI;

/**
 * Abstract class AutoloaderStep.
 *
 * Abstract base class for steps that include an autoloader.
 *
 * @package WP_CLI\Bootstrap
 */
abstract class AutoloaderStep implements BootstrapStep {

	/**
	 * Store state for subclasses to have access.
	 *
	 * @var BootstrapState
	 */
	protected $state;

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$this->state = $state;

		$found_autoloader = false;
		$autoloader_paths = $this->get_autoloader_paths();

		if ( false === $autoloader_paths ) {
			// Skip this autoload step.
			return $state;
		}

		foreach ( $autoloader_paths as $autoloader_path ) {
			if ( is_readable( $autoloader_path ) ) {
				try {
					WP_CLI::debug(
						sprintf(
							'Loading detected autoloader: %s',
							$autoloader_path
						),
						'bootstrap'
					);
					require $autoloader_path;
					$found_autoloader = true;
				} catch ( Exception $exception ) {
					WP_CLI::warning(
						"Failed to load autoloader '{$autoloader_path}'. Reason: "
						. $exception->getMessage()
					);
				}
			}
		}

		if ( ! $found_autoloader ) {
			$this->handle_failure();
		}

		return $this->state;
	}

	/**
	 * Get the name of the custom vendor folder as set in `composer.json`.
	 *
	 * @return string|false Name of the custom vendor folder or false if none.
	 */
	protected function get_custom_vendor_folder() {
		$maybe_composer_json = WP_CLI_ROOT . '/../../../composer.json';
		if ( ! is_readable( $maybe_composer_json ) ) {
			return false;
		}

		$composer = json_decode( file_get_contents( $maybe_composer_json ) );

		if ( ! empty( $composer->config )
			&& ! empty( $composer->config->{'vendor-dir'} )
		) {
			return $composer->config->{'vendor-dir'};
		}

		return false;
	}

	/**
	 * Handle the failure to find an autoloader.
	 *
	 * @return void
	 */
	protected function handle_failure() { }

	/**
	 * Get the autoloader paths to scan for an autoloader.
	 *
	 * @return string[]|false Array of strings with autoloader paths, or false
	 *                        to skip.
	 */
	abstract protected function get_autoloader_paths();
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class InitializeColorization.
 *
 * Initialize the colorization through the `WP_CLI\Runner` object.
 *
 * @package WP_CLI\Bootstrap
 */
final class InitializeColorization implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$runner = new RunnerInstance();
		$runner()->init_colorization();

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI\Autoloader;

/**
 * Class IncludeFrameworkAutoloader.
 *
 * Loads the framework autoloader through an autoloader separate from the
 * Composer one, to avoid coupling the loading of the framework with bundled
 * commands.
 *
 * This only contains classes for the framework.
 *
 * @package WP_CLI\Bootstrap
 */
final class IncludeFrameworkAutoloader implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		if ( ! class_exists( 'WP_CLI\Autoloader' ) ) {
			require_once WP_CLI_ROOT . '/php/WP_CLI/Autoloader.php';
		}

		$autoloader = new Autoloader();

		$mappings = [
			'WP_CLI'                   => WP_CLI_ROOT . '/php/WP_CLI',
			'cli'                      => WP_CLI_VENDOR_DIR . '/wp-cli/php-cli-tools/lib/cli',
			'Symfony\Component\Finder' => WP_CLI_VENDOR_DIR . '/symfony/finder/',
		];

		foreach ( $mappings as $namespace => $folder ) {
			$autoloader->add_namespace(
				$namespace,
				$folder
			);
		}

		include_once WP_CLI_VENDOR_DIR . '/wp-cli/mustangostang-spyc/Spyc.php';

		$autoloader->register();

		return $state;
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;
use WP_CLI\Utils;

/**
 * Class CheckRoot.
 *
 * Check if the user is running as root and aborts with a warning if they are.
 *
 * @package WP_CLI\Bootstrap
 */
class CheckRoot implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$config = $state->getValue( 'config', [] );
		if ( array_key_exists( 'allow-root', $config ) && true === $config['allow-root'] ) {
			// They're aware of the risks and set a flag to allow root.
			return $state;
		}

		if ( getenv( 'WP_CLI_ALLOW_ROOT' ) ) {
			// They're aware of the risks and set an environment variable to allow root.
			return $state;
		}

		$args = $state->getValue( 'arguments', [] );
		if ( count( $args ) >= 2 && 'cli' === $args[0] && in_array( $args[1], [ 'update', 'info' ], true ) ) {
			// Make it easier to update root-owned copies.
			return $state;
		}

		if ( ! function_exists( 'posix_geteuid' ) ) {
			// POSIX functions not available.
			return $state;
		}

		if ( posix_geteuid() !== 0 ) {
			// Not root.
			return $state;
		}

		WP_CLI::error(
			"YIKES! It looks like you're running this as root. You probably meant to " .
			"run this as the user that your WordPress installation exists under.\n" .
			"\n" .
			"If you REALLY mean to run this as root, we won't stop you, but just " .
			'bear in mind that any code on this site will then have full control of ' .
			"your server, making it quite DANGEROUS.\n" .
			"\n" .
			"If you'd like to continue as root, please run this again, adding this " .
			"flag:  --allow-root\n" .
			"\n" .
			"If you'd like to run it as the user that this site is under, you can " .
			"run the following to become the respective user:\n" .
			"\n" .
			"    sudo -u USER -i -- wp <command>\n" .
			"\n"
		);
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;
use WP_CLI\Utils;

/**
 * Class RegisterDeferredCommands.
 *
 * Registers the deferred commands that for which no parent was registered yet.
 * This is necessary, because we can have sub-commands that have no direct
 * parent, like `wp network meta`.
 *
 * @package WP_CLI\Bootstrap
 */
final class RegisterDeferredCommands implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {

		// Process deferred command additions for external packages.
		$this->add_deferred_commands();

		// Process deferred command additions for commands added through
		// plugins.
		WP_CLI::add_hook(
			'before_run_command',
			[ $this, 'add_deferred_commands' ]
		);

		return $state;
	}

	/**
	 * Add deferred commands that are still waiting to be processed.
	 */
	public function add_deferred_commands() {
		$deferred_additions = WP_CLI::get_deferred_additions();

		foreach ( $deferred_additions as $name => $addition ) {
			$addition_data = [];
			foreach ( $addition as $addition_key => $addition_value ) {
				// Describe the callable as a string instead of directly printing it
				// for better debug info.
				if ( 'callable' === $addition_key ) {
					$addition_value = Utils\describe_callable( $addition_value );

				} elseif ( is_array( $addition_value ) ) {
					$addition_value = json_encode( $addition_value );
				}

				$addition_data[] = sprintf(
					'%s: %s',
					$addition_key,
					$addition_value
				);
			}

			WP_CLI::debug(
				sprintf(
					'Adding deferred command: %s (%s)',
					$name,
					implode( ', ', $addition_data )
				),
				'bootstrap'
			);

			WP_CLI::add_command(
				$name,
				$addition['callable'],
				$addition['args']
			);
		}
	}
}
<?php

namespace WP_CLI\Bootstrap;

use WP_CLI;

/**
 * Class IncludePackageAutoloader.
 *
 * Loads the package autoloader that includes all the external packages.
 *
 * @package WP_CLI\Bootstrap
 */
final class IncludePackageAutoloader extends AutoloaderStep {

	/**
	 * Get the autoloader paths to scan for an autoloader.
	 *
	 * @return string[]|false Array of strings with autoloader paths, or false
	 *                        to skip.
	 */
	protected function get_autoloader_paths() {
		if ( $this->state->getValue( BootstrapState::IS_PROTECTED_COMMAND, false ) ) {
			return false;
		}

		$runner        = new RunnerInstance();
		$skip_packages = $runner()->config['skip-packages'];
		if ( true === $skip_packages ) {
			WP_CLI::debug( 'Skipped loading packages.', 'bootstrap' );

			return false;
		}

		$autoloader_path = $runner()->get_packages_dir_path() . 'vendor/autoload.php';

		if ( is_readable( $autoloader_path ) ) {
			WP_CLI::debug(
				'Loading packages from: ' . $autoloader_path,
				'bootstrap'
			);

			return [
				$autoloader_path,
			];
		}

		return false;
	}

	/**
	 * Handle the failure to find an autoloader.
	 *
	 * @return void
	 */
	protected function handle_failure() {
		WP_CLI::debug( 'No package autoload found to load.', 'bootstrap' );
	}
}
<?php

namespace WP_CLI\Bootstrap;

/**
 * Class DefineProtectedCommands.
 *
 * Define the commands that are "protected", meaning that they shouldn't be able
 * to break due to extension code.
 *
 * @package WP_CLI\Bootstrap
 */
final class DefineProtectedCommands implements BootstrapStep {

	/**
	 * Process this single bootstrapping step.
	 *
	 * @param BootstrapState $state Contextual state to pass into the step.
	 *
	 * @return BootstrapState Modified state to pass to the next step.
	 */
	public function process( BootstrapState $state ) {
		$commands        = $this->get_protected_commands();
		$current_command = $this->get_current_command();

		foreach ( $commands as $command ) {
			if ( 0 === strpos( $current_command, $command ) ) {
				$state->setValue( BootstrapState::IS_PROTECTED_COMMAND, true );
			}
		}

		return $state;
	}

	/**
	 * Get the list of protected commands.
	 *
	 * @return array
	 */
	private function get_protected_commands() {
		return [
			'cli info',
			'package',
		];
	}

	/**
	 * Get the current command as a string.
	 *
	 * @return string Current command to be executed.
	 */
	private function get_current_command() {
		$runner = new RunnerInstance();

		return implode( ' ', (array) $runner()->arguments );
	}
}
<?php

namespace WP_CLI;

use Mustangostang\Spyc;
use SplFileInfo;

use function WP_CLI\Utils\is_path_absolute;
use function WP_CLI\Utils\normalize_path;

/**
 * Handles file- and runtime-based configuration values.
 *
 * @package WP_CLI
 */
class Configurator {

	/**
	 * Configurator argument specification.
	 *
	 * @var array
	 */
	private $spec;

	/**
	 * Values for keys defined in Configurator spec.
	 *
	 * @var array
	 */
	private $config = [];

	/**
	 * Extra config values not specified in spec.
	 *
	 * @var array
	 */
	private $extra_config = [];

	/**
	 * Any aliases defined in config files.
	 *
	 * @var array
	 */
	private $aliases = [];

	/**
	 * Regex pattern used to define an alias.
	 *
	 * @var string
	 */
	const ALIAS_REGEX = '^@[A-Za-z0-9-_\.\-]+$';

	/**
	 * Arguments that can be used in an alias.
	 *
	 * @var array
	 */
	private static $alias_spec = [
		'user',
		'url',
		'path',
		'ssh',
		'http',
		'proxyjump',
		'key',
	];

	/**
	 * @param string $path Path to config spec file.
	 */
	public function __construct( $path ) {
		$this->load_config_spec( $path );

		$defaults = [
			'runtime'  => false,
			'file'     => false,
			'synopsis' => '',
			'default'  => null,
			'multiple' => false,
		];

		foreach ( $this->spec as $key => &$details ) {
			$details = array_merge( $defaults, $details );

			$this->config[ $key ] = $details['default'];
		}

		$env_files = getenv( 'WP_CLI_REQUIRE' )
		? array_filter( array_map( 'trim', explode( ',', getenv( 'WP_CLI_REQUIRE' ) ) ) )
		: [];

		if ( ! empty( $env_files ) ) {
			if ( ! isset( $this->config['require'] ) ) {
				$this->config['require'] = [];
			}
			$this->config['require'] = array_unique( array_merge( $env_files, $this->config['require'] ) );
		}
	}

	/**
	 * Loads the config spec file.
	 *
	 * @param string $path Path to the config spec file.
	 */
	private function load_config_spec( $path ) {
		$config_spec = include $path;
		// A way for platforms to modify $config_spec.
		// Use with caution!
		$config_spec_filter_callback = defined( 'WP_CLI_CONFIG_SPEC_FILTER_CALLBACK' ) ? constant( 'WP_CLI_CONFIG_SPEC_FILTER_CALLBACK' ) : false;
		if ( $config_spec_filter_callback && is_callable( $config_spec_filter_callback ) ) {
			$config_spec = $config_spec_filter_callback( $config_spec );
		}
		$this->spec = $config_spec;
	}

	/**
	 * Get declared configuration values as an array.
	 *
	 * @return array
	 */
	public function to_array() {
		return [ $this->config, $this->extra_config ];
	}

	/**
	 * Get configuration specification, i.e. list of accepted keys.
	 *
	 * @return array
	 */
	public function get_spec() {
		return $this->spec;
	}

	/**
	 * Get any aliases defined in config files.
	 *
	 * @return array
	 */
	public function get_aliases() {
		$runtime_alias = getenv( 'WP_CLI_RUNTIME_ALIAS' );
		if ( false !== $runtime_alias ) {
			$returned_aliases = [];
			foreach ( json_decode( $runtime_alias, true ) as $key => $value ) {
				if ( preg_match( '#' . self::ALIAS_REGEX . '#', $key ) ) {
					$returned_aliases[ $key ] = [];
					foreach ( self::$alias_spec as $i ) {
						if ( isset( $value[ $i ] ) ) {
							$returned_aliases[ $key ][ $i ] = $value[ $i ];
						}
					}
				}
			}
			return $returned_aliases;
		}

		return $this->aliases;
	}

	/**
	 * Splits a list of arguments into positional, associative and config.
	 *
	 * @param array<string> $arguments
	 * @return array<array<string>>
	 */
	public function parse_args( $arguments ) {
		list( $positional_args, $mixed_args, $global_assoc, $local_assoc ) = self::extract_assoc( $arguments );
		list( $assoc_args, $runtime_config )                               = $this->unmix_assoc_args( $mixed_args, $global_assoc, $local_assoc );
		return [ $positional_args, $assoc_args, $runtime_config ];
	}

	/**
	 * Splits positional args from associative args.
	 *
	 * @param array<string> $arguments
	 * @return array{0: array<string>, 1: array<array{0: string, 1: string|bool}>, 2: array<array{0: string, 1: string|bool}>, 3: array<array{0: string, 1: string|bool}>}
	 */
	public static function extract_assoc( $arguments ) {
		$positional_args = [];
		$assoc_args      = [];
		$global_assoc    = [];
		$local_assoc     = [];

		foreach ( $arguments as $arg ) {
			$positional = null;
			$assoc_arg  = null;

			if ( preg_match( '|^--no-([^=]+)$|', $arg, $matches ) ) {
				$assoc_arg = [ $matches[1], false ];
			} elseif ( preg_match( '|^--([^=]+)$|', $arg, $matches ) ) {
				$assoc_arg = [ $matches[1], true ];
			} elseif ( preg_match( '|^--([^=]+)=(.*)|s', $arg, $matches ) ) {
				$assoc_arg = [ $matches[1], $matches[2] ];
			} else {
				$positional = $arg;
			}

			if ( ! is_null( $assoc_arg ) ) {
				$assoc_args[] = $assoc_arg;
				if ( count( $positional_args ) ) {
					$local_assoc[] = $assoc_arg;
				} else {
					$global_assoc[] = $assoc_arg;
				}
			} elseif ( ! is_null( $positional ) ) {
				$positional_args[] = $positional;
			}
		}

		return [ $positional_args, $assoc_args, $global_assoc, $local_assoc ];
	}

	/**
	 * Separate runtime parameters from command-specific parameters.
	 *
	 * @param array $mixed_args
	 * @return array
	 */
	private function unmix_assoc_args( $mixed_args, $global_assoc = [], $local_assoc = [] ) {
		$assoc_args     = [];
		$runtime_config = [];

		if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) {
			foreach ( $global_assoc as $tmp ) {
				list( $key, $value ) = $tmp;
				if ( isset( $this->spec[ $key ] ) && false !== $this->spec[ $key ]['runtime'] ) {
					$this->assoc_arg_to_runtime_config( $key, $value, $runtime_config );
				}
			}
			foreach ( $local_assoc as $tmp ) {
				$assoc_args[ $tmp[0] ] = $tmp[1];
			}
		} else {
			foreach ( $mixed_args as $tmp ) {
				list( $key, $value ) = $tmp;

				if ( isset( $this->spec[ $key ] ) && false !== $this->spec[ $key ]['runtime'] ) {
					$this->assoc_arg_to_runtime_config( $key, $value, $runtime_config );
				} else {
					$assoc_args[ $key ] = $value;
				}
			}
		}

		return [ $assoc_args, $runtime_config ];
	}

	/**
	 * Handle turning an $assoc_arg into a runtime arg.
	 */
	private function assoc_arg_to_runtime_config( $key, $value, &$runtime_config ) {
		$details = $this->spec[ $key ];
		if ( isset( $details['deprecated'] ) ) {
			fwrite( STDERR, "WP-CLI: The --{$key} global parameter is deprecated. {$details['deprecated']}\n" );
		}

		if ( $details['multiple'] ) {
			$runtime_config[ $key ][] = $value;
		} else {
			$runtime_config[ $key ] = $value;
		}
	}

	/**
	 * Load a YAML file of parameters into scope.
	 *
	 * @param string $path Path to YAML file.
	 */
	public function merge_yml( $path, $current_alias = null ) {
		$yaml = self::load_yml( $path );
		if ( ! empty( $yaml['_']['inherit'] ) ) {
			// Refactor with the WP-CLI `Path` class, once it's available.
			// See: https://github.com/wp-cli/wp-cli/issues/5007
			$inherit_path = is_path_absolute( $yaml['_']['inherit'] )
				? $yaml['_']['inherit']
				: ( new SplFileInfo( normalize_path( dirname( $path ) . '/' . $yaml['_']['inherit'] ) ) )->getRealPath();

			$this->merge_yml( $inherit_path, $current_alias );
		}
		// Prepare the base path for absolutized alias paths.
		$yml_file_dir = $path ? dirname( $path ) : false;
		foreach ( $yaml as $key => $value ) {
			if ( preg_match( '#' . self::ALIAS_REGEX . '#', $key ) ) {
				$this->aliases[ $key ] = [];
				$is_alias              = false;
				foreach ( self::$alias_spec as $i ) {
					if ( isset( $value[ $i ] ) ) {
						if ( 'path' === $i && ! isset( $value['ssh'] ) ) {
							self::absolutize( $value[ $i ], $yml_file_dir );
						}
						$this->aliases[ $key ][ $i ] = $value[ $i ];
						$is_alias                    = true;
					}
				}
				// If it's not an alias, it might be a group of aliases.
				if ( ! $is_alias && is_array( $value ) ) {
					$alias_group = [];
					foreach ( $value as $k ) {
						if ( preg_match( '#' . self::ALIAS_REGEX . '#', $k ) ) {
							$alias_group[] = $k;
						}
					}
					$this->aliases[ $key ] = $alias_group;
				}
			} elseif ( ! isset( $this->spec[ $key ] ) || false === $this->spec[ $key ]['file'] ) {
				if ( isset( $this->extra_config[ $key ] )
					&& ! empty( $yaml['_']['merge'] )
					&& is_array( $this->extra_config[ $key ] )
					&& is_array( $value ) ) {
					$this->extra_config[ $key ] = array_merge( $this->extra_config[ $key ], $value );
				} else {
					$this->extra_config[ $key ] = $value;
				}
			} elseif ( $this->spec[ $key ]['multiple'] ) {
				self::arrayify( $value );
				$this->config[ $key ] = array_merge( $this->config[ $key ], $value );
			} else {
				if ( $current_alias && in_array( $key, self::$alias_spec, true ) ) {
					continue;
				}
				$this->config[ $key ] = $value;
			}
		}
	}

	/**
	 * Merge an array of values into the configurator config.
	 *
	 * @param array $config
	 */
	public function merge_array( $config ) {
		foreach ( $this->spec as $key => $details ) {
			if ( false !== $details['runtime'] && isset( $config[ $key ] ) ) {
				$value = $config[ $key ];

				if ( 'require' === $key ) {
					$value = Utils\expand_globs( $value );
				}

				if ( $details['multiple'] ) {
					self::arrayify( $value );
					$this->config[ $key ] = array_merge( $this->config[ $key ], $value );
				} else {
					$this->config[ $key ] = $value;
				}
			}
		}
	}

	/**
	 * Load values from a YAML file.
	 *
	 * @param string $yml_file Path to the YAML file
	 * @return array Declared configuration values
	 */
	private static function load_yml( $yml_file ) {
		if ( ! $yml_file ) {
			return [];
		}

		$config = Spyc::YAMLLoad( $yml_file );

		// Make sure config-file-relative paths are made absolute.
		$yml_file_dir = dirname( $yml_file );

		if ( isset( $config['path'] ) ) {
			self::absolutize( $config['path'], $yml_file_dir );
		}

		if ( isset( $config['require'] ) ) {
			self::arrayify( $config['require'] );
			$config['require'] = Utils\expand_globs( $config['require'] );
			foreach ( $config['require'] as &$path ) {
				self::absolutize( $path, $yml_file_dir );
			}
		}

		// Backwards compat
		// Command 'core config' was moved to 'config create'.
		if ( isset( $config['core config'] ) ) {
			$config['config create'] = $config['core config'];
			unset( $config['core config'] );
		}
		// Command 'checksum core' was moved to 'core verify-checksums'.
		if ( isset( $config['checksum core'] ) ) {
			$config['core verify-checksums'] = $config['checksum core'];
			unset( $config['checksum core'] );
		}
		// Command 'checksum plugin' was moved to 'plugin verify-checksums'.
		if ( isset( $config['checksum plugin'] ) ) {
			$config['plugin verify-checksums'] = $config['checksum plugin'];
			unset( $config['checksum plugin'] );
		}

		return $config;
	}

	/**
	 * Conform a variable to an array.
	 *
	 * @param mixed $val A string or an array
	 */
	private static function arrayify( &$val ) {
		$val = (array) $val;
	}

	/**
	 * Make a path absolute.
	 *
	 * @param string $path Path to file.
	 * @param string $base Base path to prepend.
	 */
	private static function absolutize( &$path, $base ) {
		if ( ! empty( $path ) && ! Utils\is_path_absolute( $path ) ) {
			$path = $base . DIRECTORY_SEPARATOR . $path;
		}
	}
}
<?php

namespace WP_CLI;

/**
 * Generate a synopsis from a command's PHPdoc arguments.
 * Turns something like "<object-id>..."
 * into [ optional=>false, type=>positional, repeating=>true, name=>object-id ]
 */
class SynopsisParser {

	/**
	 * @param string $synopsis A synopsis
	 * @return array List of parameters
	 */
	public static function parse( $synopsis ) {
		$tokens = array_filter( preg_split( '/[\s\t]+/', $synopsis ) );

		$params = [];
		foreach ( $tokens as $token ) {
			$param = self::classify_token( $token );

			// Some types of parameters shouldn't be mandatory
			if ( isset( $param['optional'] ) && ! $param['optional'] ) {
				if ( 'flag' === $param['type'] || ( 'assoc' === $param['type'] && $param['value']['optional'] ) ) {
					$param['type'] = 'unknown';
				}
			}

			$param['token'] = $token;
			$params[]       = $param;
		}

		return $params;
	}

	/**
	 * Render the Synopsis into a format string.
	 *
	 * @param array $synopsis A structured synopsis. This might get reordered
	 *                        to match the parsed output.
	 * @return string Rendered synopsis.
	 */
	public static function render( &$synopsis ) {
		if ( ! is_array( $synopsis ) ) {
			return '';
		}
		$bits               = [
			'positional' => '',
			'assoc'      => '',
			'generic'    => '',
			'flag'       => '',
		];
		$reordered_synopsis = [
			'positional' => [],
			'assoc'      => [],
			'generic'    => [],
			'flag'       => [],
		];
		foreach ( $bits as $key => &$value ) {
			foreach ( $synopsis as $arg ) {
				if ( empty( $arg['type'] )
					|| $key !== $arg['type'] ) {
					continue;
				}

				if ( empty( $arg['name'] ) && 'generic' !== $arg['type'] ) {
					continue;
				}

				if ( 'positional' === $key ) {
					$rendered_arg = "<{$arg['name']}>";

					$reordered_synopsis['positional'] [] = $arg;
				} elseif ( 'assoc' === $key ) {
					$arg_value = isset( $arg['value']['name'] ) ? $arg['value']['name'] : $arg['name'];
					$arg_value = "=<{$arg_value}>";

					if ( ! empty( $arg['value']['optional'] ) ) {
						$arg_value = "[{$arg_value}]";
					}

					$rendered_arg = "--{$arg['name']}{$arg_value}";

					$reordered_synopsis['assoc'] [] = $arg;
				} elseif ( 'generic' === $key ) {
					$rendered_arg = '--<field>=<value>';

					$reordered_synopsis['generic'] [] = $arg;
				} elseif ( 'flag' === $key ) {
					$rendered_arg = "--{$arg['name']}";

					$reordered_synopsis['flag'] [] = $arg;
				}
				if ( ! empty( $arg['repeating'] ) ) {
					$rendered_arg = "{$rendered_arg}...";
				}
				if ( ! empty( $arg['optional'] ) ) {
					$rendered_arg = "[{$rendered_arg}]";
				}
				$value .= "{$rendered_arg} ";
			}
		}
		$rendered = implode( '', $bits );

		$synopsis = array_merge(
			$reordered_synopsis['positional'],
			$reordered_synopsis['assoc'],
			$reordered_synopsis['generic'],
			$reordered_synopsis['flag']
		);

		return rtrim( $rendered, ' ' );
	}

	/**
	 * Classify argument attributes based on its syntax.
	 *
	 * @param string $token
	 * @return array
	 */
	private static function classify_token( $token ) {
		$param = [];

		list( $param['optional'], $token )  = self::is_optional( $token );
		list( $param['repeating'], $token ) = self::is_repeating( $token );

		$p_name  = '([a-z-_0-9]+)';
		$p_value = '([a-zA-Z-_|,0-9]+)';

		if ( '--<field>=<value>' === $token ) {
			$param['type'] = 'generic';
		} elseif ( preg_match( "/^<($p_value)>$/", $token, $matches ) ) {
			$param['type'] = 'positional';
			$param['name'] = $matches[1];
		} elseif ( preg_match( "/^--(?:\\[no-\\])?$p_name/", $token, $matches ) ) {
			$param['name'] = $matches[1];

			$value = substr( $token, strlen( $matches[0] ) );

			// substr returns false <= PHP 5.6, and '' PHP 7+
			if ( false === $value || '' === $value ) {
				$param['type'] = 'flag';
			} else {
				$param['type'] = 'assoc';

				list( $param['value']['optional'], $value ) = self::is_optional( $value );

				if ( preg_match( "/^=<$p_value>$/", $value, $matches ) ) {
					$param['value']['name'] = $matches[1];
				} else {
					$param = [
						'type' => 'unknown',
					];
				}
			}
		} else {
			$param['type'] = 'unknown';
		}

		return $param;
	}

	/**
	 * An optional parameter is surrounded by square brackets.
	 *
	 * @param string $token
	 * @return array
	 */
	private static function is_optional( $token ) {
		if ( '[' === substr( $token, 0, 1 ) && ']' === substr( $token, -1 ) ) {
			return [ true, substr( $token, 1, -1 ) ];
		}

		return [ false, $token ];
	}

	/**
	 * A repeating parameter is followed by an ellipsis.
	 *
	 * @param string $token
	 * @return array
	 */
	private static function is_repeating( $token ) {
		if ( '...' === substr( $token, -3 ) ) {
			return [ true, substr( $token, 0, -3 ) ];
		}

		return [ false, $token ];
	}
}
<?php

namespace WP_CLI\Exception;

use OutOfBoundsException;
use WP_CLI\Traverser\RecursiveDataStructureTraverser;

class NonExistentKeyException extends OutOfBoundsException {
	/** @var RecursiveDataStructureTraverser */
	protected $traverser;

	/**
	 * @param RecursiveDataStructureTraverser $traverser
	 */
	public function set_traverser( $traverser ) {
		$this->traverser = $traverser;
	}

	/**
	 * @return RecursiveDataStructureTraverser
	 */
	public function get_traverser() {
		return $this->traverser;
	}
}
<?php

namespace WP_CLI;

use DirectoryIterator;
use Exception;
use PharData;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use WP_CLI;
use ZipArchive;

/**
 * Extract a provided archive file.
 */
class Extractor {

	/**
	 * Extract the archive file to a specific destination.
	 *
	 * @param string $dest
	 */
	public static function extract( $tarball_or_zip, $dest ) {
		if ( preg_match( '/\.zip$/', $tarball_or_zip ) ) {
			return self::extract_zip( $tarball_or_zip, $dest );
		}

		if ( preg_match( '/\.tar\.gz$/', $tarball_or_zip ) ) {
			return self::extract_tarball( $tarball_or_zip, $dest );
		}

		throw new Exception( "Extraction only supported for '.zip' and '.tar.gz' file types." );
	}

	/**
	 * Extract a ZIP file to a specific destination.
	 *
	 * @param string $zipfile
	 * @param string $dest
	 */
	private static function extract_zip( $zipfile, $dest ) {
		if ( ! class_exists( 'ZipArchive' ) ) {
			throw new Exception( 'Extracting a zip file requires ZipArchive.' );
		}

		// Ensure the destination folder exists or can be created.
		if ( ! self::ensure_dir_exists( $dest ) ) {
			throw new Exception( "Could not create folder '{$dest}'." );
		}

		if ( ! file_exists( $zipfile )
			|| ! is_readable( $zipfile )
			|| filesize( $zipfile ) <= 0 ) {
			throw new Exception( "Invalid zip file '{$zipfile}'." );
		}

		$zip = new ZipArchive();
		$res = $zip->open( $zipfile );

		if ( true === $res ) {
			$name    = Utils\basename( $zipfile );
			$tempdir = Utils\get_temp_dir()
						. uniqid( 'wp-cli-extract-zipfile-', true )
						. "-{$name}";

			$zip->extractTo( $tempdir );
			$zip->close();

			self::copy_overwrite_files(
				self::get_first_subfolder( $tempdir ),
				$dest
			);

			self::rmdir( $tempdir );
		} else {
			throw new Exception(
				sprintf(
					"ZipArchive failed to unzip '%s': %s.",
					$zipfile,
					self::zip_error_msg( $res )
				)
			);
		}
	}

	/**
	 * Extract a tarball to a specific destination.
	 *
	 * @param string $tarball
	 * @param string $dest
	 */
	private static function extract_tarball( $tarball, $dest ) {
		// Ensure the destination folder exists or can be created.
		if ( ! self::ensure_dir_exists( $dest ) ) {
			throw new Exception( "Could not create folder '{$dest}'." );
		}

		if ( class_exists( 'PharData' ) ) {
			try {
				$phar    = new PharData( $tarball );
				$name    = Utils\basename( $tarball );
				$tempdir = Utils\get_temp_dir()
							. uniqid( 'wp-cli-extract-tarball-', true )
							. "-{$name}";

				$phar->extractTo( $tempdir );

				self::copy_overwrite_files(
					self::get_first_subfolder( $tempdir ),
					$dest
				);

				self::rmdir( $tempdir );
				return;
			} catch ( Exception $e ) {
				WP_CLI::warning(
					"PharData failed, falling back to 'tar xz' ("
					. $e->getMessage() . ')'
				);
				// Fall through to trying `tar xz` below.
			}
		}

		// Ensure relative paths cannot be misinterpreted as hostnames.
		// Prepending `./` will force tar to interpret it as a filesystem path.
		if ( self::path_is_relative( $tarball ) ) {
			$tarball = "./{$tarball}";
		}

		if ( ! file_exists( $tarball )
			|| ! is_readable( $tarball )
			|| filesize( $tarball ) <= 0 ) {
			throw new Exception( "Invalid zip file '{$tarball}'." );
		}

		// Note: directory must exist for tar --directory to work.
		$cmd = Utils\esc_cmd(
			'tar xz --strip-components=1 --directory=%s -f %s',
			$dest,
			$tarball
		);

		$process_run = WP_CLI::launch(
			$cmd,
			false, /*exit_on_error*/
			true /*return_detailed*/
		);

		if ( 0 !== $process_run->return_code ) {
			throw new Exception(
				sprintf(
					'Failed to execute `%s`: %s.',
					$cmd,
					self::tar_error_msg( $process_run )
				)
			);
		}
	}

	/**
	 * Copy files from source directory to destination directory. Source
	 * directory must exist.
	 *
	 * @param string $source
	 * @param string $dest
	 */
	public static function copy_overwrite_files( $source, $dest ) {
		$iterator = new RecursiveIteratorIterator(
			new RecursiveDirectoryIterator(
				$source,
				RecursiveDirectoryIterator::SKIP_DOTS
			),
			RecursiveIteratorIterator::SELF_FIRST
		);

		$error = 0;

		if ( ! is_dir( $dest ) ) {
			mkdir( $dest, 0777, true );
		}

		foreach ( $iterator as $item ) {

			$dest_path = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName();

			if ( $item->isDir() ) {
				if ( ! is_dir( $dest_path ) ) {
					mkdir( $dest_path );
				}
			} elseif ( file_exists( $dest_path ) && is_writable( $dest_path ) ) {
					copy( $item, $dest_path );
			} elseif ( ! file_exists( $dest_path ) ) {
				copy( $item, $dest_path );
			} else {
				$error = 1;
				WP_CLI::warning( "Unable to copy '" . $iterator->getSubPathName() . "' to current directory." );
			}
		}

		if ( $error ) {
			throw new Exception( 'There was an error overwriting existing files.' );
		}
	}

	/**
	 * Delete all files and directories recursively from directory. Directory
	 * must exist.
	 *
	 * @param string $dir
	 */
	public static function rmdir( $dir ) {
		$files = new RecursiveIteratorIterator(
			new RecursiveDirectoryIterator(
				$dir,
				RecursiveDirectoryIterator::SKIP_DOTS
			),
			RecursiveIteratorIterator::CHILD_FIRST
		);

		foreach ( $files as $fileinfo ) {
			$todo = $fileinfo->isDir() ? 'rmdir' : 'unlink';
			$path = $fileinfo->getRealPath();
			if ( 0 !== strpos( $path, $fileinfo->getRealPath() ) ) {
				WP_CLI::warning(
					"Temporary file or folder to be removed was found outside of temporary folder, aborting removal: '{$path}'"
				);
			}
			$todo( $path );
		}
		rmdir( $dir );
	}

	/**
	 * Return formatted ZipArchive error message from error code.
	 *
	 * @param int $error_code
	 * @return string|int The error message corresponding to the specified
	 *                    code, if found; Other wise the same error code,
	 *                    unmodified.
	 */
	public static function zip_error_msg( $error_code ) {
		// From https://github.com/php/php-src/blob/php-5.3.0/ext/zip/php_zip.c#L2623-L2646.
		static $zip_err_msgs = [
			ZipArchive::ER_OK          => 'No error',
			ZipArchive::ER_MULTIDISK   => 'Multi-disk zip archives not supported',
			ZipArchive::ER_RENAME      => 'Renaming temporary file failed',
			ZipArchive::ER_CLOSE       => 'Closing zip archive failed',
			ZipArchive::ER_SEEK        => 'Seek error',
			ZipArchive::ER_READ        => 'Read error',
			ZipArchive::ER_WRITE       => 'Write error',
			ZipArchive::ER_CRC         => 'CRC error',
			ZipArchive::ER_ZIPCLOSED   => 'Containing zip archive was closed',
			ZipArchive::ER_NOENT       => 'No such file',
			ZipArchive::ER_EXISTS      => 'File already exists',
			ZipArchive::ER_OPEN        => 'Can\'t open file',
			ZipArchive::ER_TMPOPEN     => 'Failure to create temporary file',
			ZipArchive::ER_ZLIB        => 'Zlib error',
			ZipArchive::ER_MEMORY      => 'Malloc failure',
			ZipArchive::ER_CHANGED     => 'Entry has been changed',
			ZipArchive::ER_COMPNOTSUPP => 'Compression method not supported',
			ZipArchive::ER_EOF         => 'Premature EOF',
			ZipArchive::ER_INVAL       => 'Invalid argument',
			ZipArchive::ER_NOZIP       => 'Not a zip archive',
			ZipArchive::ER_INTERNAL    => 'Internal error',
			ZipArchive::ER_INCONS      => 'Zip archive inconsistent',
			ZipArchive::ER_REMOVE      => 'Can\'t remove file',
			ZipArchive::ER_DELETED     => 'Entry has been deleted',
		];

		if ( isset( $zip_err_msgs[ $error_code ] ) ) {
			return sprintf(
				'%s (%d)',
				$zip_err_msgs[ $error_code ],
				$error_code
			);
		}
		return $error_code;
	}

	/**
	 * Return formatted error message from ProcessRun of tar command.
	 *
	 * @param ProcessRun $process_run
	 * @return string|int The error message of the process, if available;
	 *                    otherwise the return code.
	 */
	public static function tar_error_msg( $process_run ) {
		$stderr = trim( $process_run->stderr );
		$nl_pos = strpos( $stderr, "\n" );
		if ( false !== $nl_pos ) {
			$stderr = trim( substr( $stderr, 0, $nl_pos ) );
		}
		if ( $stderr ) {
			return sprintf( '%s (%d)', $stderr, $process_run->return_code );
		}
		return $process_run->return_code;
	}

	/**
	 * Return the first subfolder within a given path.
	 *
	 * Falls back to the provided path if no subfolder was detected.
	 *
	 * @param string $path Path to find the first subfolder in.
	 * @return string First subfolder, or same as $path if none found.
	 */
	private static function get_first_subfolder( $path ) {
		$iterator = new DirectoryIterator( $path );

		foreach ( $iterator as $fileinfo ) {
			if ( $fileinfo->isDir() && ! $fileinfo->isDot() ) {
				return "{$path}/{$fileinfo->getFilename()}";
			}
		}

		return $path;
	}

	/**
	 * Ensure directory exists.
	 *
	 * @param string $dir Directory to ensure the existence of.
	 * @return bool Whether the existence could be asserted.
	 */
	private static function ensure_dir_exists( $dir ) {
		if ( ! is_dir( $dir ) ) {
			if ( ! @mkdir( $dir, 0777, true ) ) {
				$error = error_get_last();
				WP_CLI::warning(
					sprintf(
						"Failed to create directory '%s': %s.",
						$dir,
						$error['message']
					)
				);
				return false;
			}
		}

		return true;
	}

	/**
	 * Check whether a path is relative-
	 *
	 * @param string $path Path to check.
	 * @return bool Whether the path is relative.
	 */
	private static function path_is_relative( $path ) {
		if ( '' === $path ) {
			return true;
		}

		// Strip scheme.
		$scheme_position = strpos( $path, '://' );
		if ( false !== $scheme_position ) {
			$path = substr( $path, $scheme_position + 3 );
		}

		// UNIX root "/" or "\" (Windows style).
		if ( '/' === $path[0] || '\\' === $path[0] ) {
			return false;
		}

		// Windows root.
		if ( strlen( $path ) > 1 && ctype_alpha( $path[0] ) && ':' === $path[1] ) {

			// Special case: only drive letter, like "C:".
			if ( 2 === strlen( $path ) ) {
				return false;
			}

			// Regular Windows path starting with drive letter, like "C:/ or "C:\".
			if ( '/' === $path[2] || '\\' === $path[2] ) {
				return false;
			}
		}

		return true;
	}
}
<?php

namespace WP_CLI\Dispatcher;

use WP_CLI;
use WP_CLI\DocParser;
use WP_CLI\SynopsisParser;
use WP_CLI\SynopsisValidator;
use WP_CLI\Utils;

/**
 * A leaf node in the command tree.
 *
 * @package WP_CLI
 */
class Subcommand extends CompositeCommand {

	private $alias;

	private $when_invoked;

	public function __construct( $parent, $name, $docparser, $when_invoked ) {
		$this->alias = $docparser->get_tag( 'alias' );

		parent::__construct( $parent, $name, $docparser );

		$this->when_invoked = $when_invoked;

		$this->synopsis = $docparser->get_synopsis();
		if ( ! $this->synopsis && $this->longdesc ) {
			$this->synopsis = self::extract_synopsis( $this->longdesc );
		}
	}

	/**
	 * Extract the synopsis from PHPdoc string.
	 *
	 * @param string $longdesc Command docs via PHPdoc
	 * @return string
	 */
	private static function extract_synopsis( $longdesc ) {
		preg_match_all( '/(.+?)[\r\n]+:/', $longdesc, $matches );
		return implode( ' ', $matches[1] );
	}

	/**
	 * Subcommands can't have subcommands because they
	 * represent code to be executed.
	 *
	 * @return bool
	 */
	public function can_have_subcommands() {
		return false;
	}

	/**
	 * Get the synopsis string for this subcommand.
	 * A synopsis defines what runtime arguments are
	 * expected, useful to humans and argument validation.
	 *
	 * @return string
	 */
	public function get_synopsis() {
		return $this->synopsis;
	}

	/**
	 * Set the synopsis string for this subcommand.
	 *
	 * @param string $synopsis
	 */
	public function set_synopsis( $synopsis ) {
		$this->synopsis = $synopsis;
	}

	/**
	 * If an alias is set, grant access to it.
	 * Aliases permit subcommands to be instantiated
	 * with a secondary identity.
	 *
	 * @return string
	 */
	public function get_alias() {
		return $this->alias;
	}

	/**
	 * Print the usage details to the end user.
	 *
	 * @param string $prefix
	 */
	public function show_usage( $prefix = 'usage: ' ) {
		\WP_CLI::line( $this->get_usage( $prefix ) );
	}

	/**
	 * Get the usage of the subcommand as a formatted string.
	 *
	 * @param string $prefix
	 * @return string
	 */
	public function get_usage( $prefix ) {
		return sprintf(
			'%s%s %s',
			$prefix,
			implode( ' ', get_path( $this ) ),
			$this->get_synopsis()
		);
	}

	/**
	 * Wrapper for CLI Tools' prompt() method.
	 *
	 * @param string $question
	 * @param string $default
	 * @return string|false
	 */
	private function prompt( $question, $default ) {

		$question .= ': ';
		if ( function_exists( 'readline' ) ) {
			return readline( $question );
		}

		echo $question;

		$ret = stream_get_line( STDIN, 1024, "\n" );
		if ( Utils\is_windows() && "\r" === substr( $ret, -1 ) ) {
			$ret = substr( $ret, 0, -1 );
		}
		return $ret;
	}

	/**
	 * Interactively prompt the user for input
	 * based on defined synopsis and passed arguments.
	 *
	 * @param array $args
	 * @param array $assoc_args
	 * @return array
	 */
	private function prompt_args( $args, $assoc_args ) {

		$synopsis = $this->get_synopsis();

		if ( ! $synopsis ) {
			return [ $args, $assoc_args ];
		}

		// To skip the already provided positional arguments, we need to count
		// how many we had already received.
		$arg_index = 0;

		$spec = array_filter(
			SynopsisParser::parse( $synopsis ),
			function ( $spec_arg ) use ( $args, $assoc_args, &$arg_index ) {
				switch ( $spec_arg['type'] ) {
					case 'positional':
						// Only prompt for the positional arguments that are not
						// yet provided, based purely on number.
						return $arg_index++ >= count( $args );
					case 'generic':
						// Always prompt for generic arguments.
						return true;
					case 'assoc':
					case 'flag':
					default:
						// Prompt for the specific flags that were not provided
						// yet, based on name.
						return ! isset( $assoc_args[ $spec_arg['name'] ] );
				}
			}
		);

		$spec = array_values( $spec );

		$prompt_args = WP_CLI::get_config( 'prompt' );
		if ( true !== $prompt_args ) {
			$prompt_args = explode( ',', $prompt_args );
		}

		// 'positional' arguments are positional (aka zero-indexed)
		// so $args needs to be reset before prompting for new arguments
		$args = [];

		foreach ( $spec as $key => $spec_arg ) {

			// When prompting for specific arguments (e.g. --prompt=user_pass),
			// ignore all arguments that don't match.
			if ( is_array( $prompt_args ) ) {
				if ( 'assoc' !== $spec_arg['type'] ) {
					continue;
				}
				if ( ! in_array( $spec_arg['name'], $prompt_args, true ) ) {
					continue;
				}
			}

			$current_prompt = ( $key + 1 ) . '/' . count( $spec ) . ' ';
			$default        = $spec_arg['optional'] ? '' : false;

			// 'generic' permits arbitrary key=value (e.g. [--<field>=<value>] )
			if ( 'generic' === $spec_arg['type'] ) {

				list( $key_token, $value_token ) = explode( '=', $spec_arg['token'] );

				$repeat = false;
				do {
					if ( ! $repeat ) {
						$key_prompt = $current_prompt . $key_token;
					} else {
						$key_prompt = str_repeat( ' ', strlen( $current_prompt ) ) . $key_token;
					}

					$key = $this->prompt( $key_prompt, $default );
					if ( false === $key ) {
						return [ $args, $assoc_args ];
					}

					if ( $key ) {
						$key_prompt_count = strlen( $key_prompt ) - strlen( $value_token ) - 1;
						$value_prompt     = str_repeat( ' ', $key_prompt_count ) . '=' . $value_token;

						$value = $this->prompt( $value_prompt, $default );
						if ( false === $value ) {
							return [ $args, $assoc_args ];
						}

						$assoc_args[ $key ] = $value;

						$repeat = true;
					} else {
						$repeat = false;
					}
				} while ( $repeat );

			} else {
				$prompt = $current_prompt . $spec_arg['token'];
				if ( 'flag' === $spec_arg['type'] ) {
					$prompt .= ' (Y/n)';
				}

				$response = $this->prompt( $prompt, $default );
				if ( false === $response ) {
					return [ $args, $assoc_args ];
				}

				if ( $response ) {
					switch ( $spec_arg['type'] ) {
						case 'positional':
							if ( $spec_arg['repeating'] ) {
								$response = explode( ' ', $response );
							} else {
								$response = [ $response ];
							}
							$args = array_merge( $args, $response );
							break;
						case 'assoc':
							$assoc_args[ $spec_arg['name'] ] = $response;
							break;
						case 'flag':
							if ( 'Y' === strtoupper( $response ) ) {
								$assoc_args[ $spec_arg['name'] ] = true;
							}
							break;
					}
				}
			}
		}

		return [ $args, $assoc_args ];
	}

	/**
	 * Validate the supplied arguments to the command.
	 * Throws warnings or errors if arguments are missing
	 * or invalid.
	 *
	 * @param array $args
	 * @param array $assoc_args
	 * @param array $extra_args
	 * @return array list of invalid $assoc_args keys to unset
	 */
	private function validate_args( $args, $assoc_args, $extra_args ) {
		$synopsis = $this->get_synopsis();
		if ( ! $synopsis ) {
			return [ [], $args, $assoc_args, $extra_args ];
		}

		$validator = new SynopsisValidator( $synopsis );

		$cmd_path = implode( ' ', get_path( $this ) );
		foreach ( $validator->get_unknown() as $token ) {
			\WP_CLI::warning(
				sprintf(
					'The `%s` command has an invalid synopsis part: %s',
					$cmd_path,
					$token
				)
			);
		}

		if ( ! $validator->enough_positionals( $args ) ) {
			$this->show_usage();
			exit( 1 );
		}

		$unknown_positionals = $validator->unknown_positionals( $args );
		if ( ! empty( $unknown_positionals ) ) {
			\WP_CLI::error(
				'Too many positional arguments: ' .
				implode( ' ', $unknown_positionals )
			);
		}

		$synopsis_spec = SynopsisParser::parse( $synopsis );
		$i             = 0;
		$errors        = [
			'fatal'   => [],
			'warning' => [],
		];
		$mock_doc      = [ $this->get_shortdesc(), '' ];
		$mock_doc      = array_merge( $mock_doc, explode( "\n", $this->get_longdesc() ) );
		$mock_doc      = '/**' . PHP_EOL . '* ' . implode( PHP_EOL . '* ', $mock_doc ) . PHP_EOL . '*/';
		$docparser     = new DocParser( $mock_doc );
		foreach ( $synopsis_spec as $spec ) {
			if ( 'positional' === $spec['type'] ) {
				$spec_args = $docparser->get_arg_args( $spec['name'] );
				if ( ! isset( $args[ $i ] ) ) {
					if ( isset( $spec_args['default'] ) ) {
						$args[ $i ] = $spec_args['default'];
					}
				}
				if ( isset( $spec_args['options'] ) ) {
					if ( ! empty( $spec['repeating'] ) ) {
						do {
							// phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict -- This is a loose comparison by design.
							if ( isset( $args[ $i ] ) && ! in_array( $args[ $i ], $spec_args['options'] ) ) {
								\WP_CLI::error( 'Invalid value specified for positional arg.' );
							}
							++$i;
						} while ( isset( $args[ $i ] ) );
					} elseif ( isset( $args[ $i ] ) && ! in_array( $args[ $i ], $spec_args['options'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict -- This is a loose comparison by design.
						\WP_CLI::error( 'Invalid value specified for positional arg.' );
					}
				}
				++$i;
			} elseif ( 'assoc' === $spec['type'] ) {
				$spec_args = $docparser->get_param_args( $spec['name'] );
				if ( ! isset( $assoc_args[ $spec['name'] ] ) && ! isset( $extra_args[ $spec['name'] ] ) ) {
					if ( isset( $spec_args['default'] ) ) {
						$assoc_args[ $spec['name'] ] = $spec_args['default'];
					}
				}
				if ( isset( $assoc_args[ $spec['name'] ] ) && isset( $spec_args['options'] ) ) {
					$value   = $assoc_args[ $spec['name'] ];
					$options = $spec_args['options'];
					// phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict -- This is a loose comparison by design.
					if ( ! in_array( $value, $options ) ) {
						// Try whether it might be a comma-separated list of multiple values.
						$values = array_map( 'trim', explode( ',', $value ) );
						$count  = count( $values );
						if (
							$count > 1
							&&
							count(
								array_filter(
									$values,
									static function ( $value ) use ( $options ) {
										return in_array( $value, $options, true );
									}
								)
							) === $count
						) {
							continue;
						}
						$errors['fatal'][ $spec['name'] ] = "Invalid value specified for '{$spec['name']}'";
					}
				}
			}
		}

		list( $returned_errors, $to_unset ) = $validator->validate_assoc(
			array_merge( \WP_CLI::get_config(), $extra_args, $assoc_args )
		);
		foreach ( [ 'fatal', 'warning' ] as $error_type ) {
			$errors[ $error_type ] = array_merge( $errors[ $error_type ], $returned_errors[ $error_type ] );
		}

		if ( 'help' !== $this->name ) {
			foreach ( $validator->unknown_assoc( $assoc_args ) as $key ) {
				$suggestion    = Utils\get_suggestion(
					$key,
					$this->get_parameters( $synopsis_spec ),
					$threshold = 2
				);

				$errors['fatal'][] = sprintf(
					'unknown --%s parameter%s',
					$key,
					! empty( $suggestion ) ? PHP_EOL . "Did you mean '--{$suggestion}'?" : ''
				);
			}
		}

		if ( ! empty( $errors['fatal'] ) ) {
			$out = 'Parameter errors:';
			foreach ( $errors['fatal'] as $key => $error ) {
				$out .= "\n {$error}";
				$desc = $docparser->get_param_desc( $key );
				if ( '' !== $desc ) {
					$out .= " ({$desc})";
				}
			}

			\WP_CLI::error( $out );
		}

		array_map( '\\WP_CLI::warning', $errors['warning'] );

		return [ $to_unset, $args, $assoc_args, $extra_args ];
	}

	/**
	 * Invoke the subcommand with the supplied arguments.
	 * Given a --prompt argument, interactively request input
	 * from the end user.
	 *
	 * @param array $args
	 * @param array $assoc_args
	 */
	public function invoke( $args, $assoc_args, $extra_args ) {
		static $prompted_once = false;

		if ( 'help' !== $this->name ) {
			if ( \WP_CLI::get_config( 'prompt' ) && ! $prompted_once ) {
				list( $_args, $assoc_args ) = $this->prompt_args( $args, $assoc_args );
				$args                       = array_merge( $args, $_args );
				$prompted_once              = true;
			}
		}

		$extra_positionals = [];
		foreach ( $extra_args as $k => $v ) {
			if ( is_numeric( $k ) ) {
				if ( ! isset( $args[ $k ] ) ) {
					$extra_positionals[ $k ] = $v;
				}
				unset( $extra_args[ $k ] );
			}
		}
		$args += $extra_positionals;

		list( $to_unset, $args, $assoc_args, $extra_args ) = $this->validate_args( $args, $assoc_args, $extra_args );

		foreach ( $to_unset as $key ) {
			unset( $assoc_args[ $key ] );
		}

		$path   = get_path( $this->get_parent() );
		$parent = implode( ' ', array_slice( $path, 1 ) );
		$cmd    = $this->name;
		if ( $parent ) {
			WP_CLI::do_hook( "before_invoke:{$parent}", $parent );
			$cmd = $parent . ' ' . $cmd;
		}
		WP_CLI::do_hook( "before_invoke:{$cmd}", $cmd );

		// Check if `--prompt` arg passed or not.
		if ( $prompted_once ) {
			// Unset empty args.
			$actual_args = $assoc_args;
			foreach ( $actual_args as $key ) {
				if ( empty( $actual_args[ $key ] ) ) {
					unset( $actual_args[ $key ] );
				}
			}

			WP_CLI::log(
				sprintf(
					'wp %s %s',
					$cmd,
					ltrim(
						implode(
							' ',
							[
								ltrim( Utils\args_to_str( $args ), ' ' ),
								ltrim( Utils\assoc_args_to_str( $actual_args ), ' ' ),
							]
						),
						' '
					)
				)
			);
		}

		call_user_func( $this->when_invoked, $args, array_merge( $extra_args, $assoc_args ) );

		if ( $parent ) {
			WP_CLI::do_hook( "after_invoke:{$parent}", $parent );
		}
		WP_CLI::do_hook( "after_invoke:{$cmd}", $cmd );
	}

	/**
	 * Get an array of parameter names, by merging the command-specific and the
	 * global parameters.
	 *
	 * @param array $spec Optional. Specification of the current command.
	 *
	 * @return array Array of parameter names
	 */
	private function get_parameters( $spec = [] ) {
		$local_parameters  = array_column( $spec, 'name' );
		$global_parameters = array_column(
			SynopsisParser::parse( $this->get_global_params() ),
			'name'
		);

		return array_unique( array_merge( $local_parameters, $global_parameters ) );
	}
}
<?php

namespace WP_CLI\Dispatcher;

use Closure;
use ReflectionClass;
use ReflectionFunction;
use ReflectionMethod;
use WP_CLI;
use WP_CLI\DocParser;
use WP_CLI\Utils;

/**
 * Creates CompositeCommand or Subcommand instances.
 *
 * @package WP_CLI
 */
class CommandFactory {

	// Cache of file contents, indexed by filename. Only used if opcache.save_comments is disabled.
	private static $file_contents = [];

	/**
	 * Create a new CompositeCommand (or Subcommand if class has __invoke())
	 *
	 * @param string                                $name     Represents how the command should be invoked
	 * @param string|callable-string|callable|array $callable A subclass of WP_CLI_Command, a function, or a closure
	 * @param mixed $parent The new command's parent Composite (or Root) command
	 */
	public static function create( $name, $callable, $parent ) {

		if ( ( is_object( $callable ) && ( $callable instanceof Closure ) )
			|| ( is_string( $callable ) && function_exists( $callable ) ) ) {
			$reflection = new ReflectionFunction( $callable );
			$command    = self::create_subcommand( $parent, $name, $callable, $reflection );
		} elseif ( is_array( $callable ) && ( is_callable( $callable ) || Utils\is_valid_class_and_method_pair( $callable ) ) ) {
			$reflection = new ReflectionClass( $callable[0] );
			$command    = self::create_subcommand(
				$parent,
				$name,
				[ $callable[0], $callable[1] ],
				$reflection->getMethod( $callable[1] )
			);
		} else {
			$reflection = new ReflectionClass( $callable );
			if ( $reflection->isSubclassOf( '\WP_CLI\Dispatcher\CommandNamespace' ) ) {
				$command = self::create_namespace( $parent, $name, $callable );
			} elseif ( $reflection->hasMethod( '__invoke' ) ) {
				$class   = is_object( $callable ) ? $callable : $reflection->name;
				$command = self::create_subcommand(
					$parent,
					$name,
					[ $class, '__invoke' ],
					$reflection->getMethod( '__invoke' )
				);
			} else {
				$command = self::create_composite_command( $parent, $name, $callable );
			}
		}

		return $command;
	}

	/**
	 * Clear the file contents cache.
	 */
	public static function clear_file_contents_cache() {
		self::$file_contents = [];
	}

	/**
	 * Create a new Subcommand instance.
	 *
	 * @param mixed $parent The new command's parent Composite command
	 * @param string|bool $name Represents how the command should be invoked.
	 * If false, will be determined from the documented subject, represented by `$reflection`.
	 * @param mixed $callable A callable function or closure, or class name and method
	 * @param object $reflection Reflection instance, for doc parsing
	 */
	private static function create_subcommand( $parent, $name, $callable, $reflection ) {
		$doc_comment = self::get_doc_comment( $reflection );
		$docparser   = new DocParser( $doc_comment );

		if ( is_array( $callable ) ) {
			if ( ! $name ) {
				$name = $docparser->get_tag( 'subcommand' );
			}

			if ( ! $name ) {
				$name = $reflection->name;
			}
		}
		if ( ! $doc_comment ) {
			WP_CLI::debug( null === $doc_comment ? "Failed to get doc comment for {$name}." : "No doc comment for {$name}.", 'commandfactory' );
		}

		$when_invoked = function ( $args, $assoc_args ) use ( $callable ) {
			if ( is_array( $callable ) ) {
				$callable[0] = is_object( $callable[0] ) ? $callable[0] : new $callable[0]();
				call_user_func( [ $callable[0], $callable[1] ], $args, $assoc_args );
			} else {
				call_user_func( $callable, $args, $assoc_args );
			}
		};

		return new Subcommand( $parent, $name, $docparser, $when_invoked );
	}

	/**
	 * Create a new Composite command instance.
	 *
	 * @param mixed $parent The new command's parent Root or Composite command
	 * @param string $name Represents how the command should be invoked
	 * @param mixed $callable
	 */
	private static function create_composite_command( $parent, $name, $callable ) {
		$reflection  = new ReflectionClass( $callable );
		$doc_comment = self::get_doc_comment( $reflection );
		if ( ! $doc_comment ) {
			WP_CLI::debug( null === $doc_comment ? "Failed to get doc comment for {$name}." : "No doc comment for {$name}.", 'commandfactory' );
		}
		$docparser = new DocParser( $doc_comment );

		$container = new CompositeCommand( $parent, $name, $docparser );

		foreach ( $reflection->getMethods() as $method ) {
			if ( ! self::is_good_method( $method ) ) {
				continue;
			}

			$class      = is_object( $callable ) ? $callable : $reflection->name;
			$subcommand = self::create_subcommand( $container, false, [ $class, $method->name ], $method );

			$subcommand_name = $subcommand->get_name();

			$container->add_subcommand( $subcommand_name, $subcommand );
		}

		return $container;
	}

	/**
	 * Create a new command namespace instance.
	 *
	 * @param mixed $parent The new namespace's parent Root or Composite command.
	 * @param string $name Represents how the command should be invoked
	 * @param mixed $callable
	 */
	private static function create_namespace( $parent, $name, $callable ) {
		$reflection  = new ReflectionClass( $callable );
		$doc_comment = self::get_doc_comment( $reflection );
		if ( ! $doc_comment ) {
			WP_CLI::debug( null === $doc_comment ? "Failed to get doc comment for {$name}." : "No doc comment for {$name}.", 'commandfactory' );
		}
		$docparser = new DocParser( $doc_comment );

		return new CommandNamespace( $parent, $name, $docparser );
	}

	/**
	 * Check whether a method is actually callable.
	 *
	 * @param ReflectionMethod $method
	 * @return bool
	 */
	private static function is_good_method( $method ) {
		return $method->isPublic() && ! $method->isStatic() && 0 !== strpos( $method->getName(), '__' );
	}

	/**
	 * Gets the document comment. Caters for PHP directive `opcache.save comments` being disabled.
	 *
	 * @param ReflectionMethod|ReflectionClass|ReflectionFunction $reflection Reflection instance.
	 * @return string|false|null Doc comment string if any, false if none (same as `Reflection*::getDocComment()`), null if error.
	 */
	private static function get_doc_comment( $reflection ) {
		$contents    = null;
		$doc_comment = $reflection->getDocComment();

		if ( false !== $doc_comment || ! ( ini_get( 'opcache.enable_cli' ) && ! ini_get( 'opcache.save_comments' ) ) ) { // phpcs:ignore PHPCompatibility.IniDirectives.NewIniDirectives
			// Either have doc comment, or no doc comment and save comments enabled - standard situation.
			if ( ! getenv( 'WP_CLI_TEST_GET_DOC_COMMENT' ) ) {
				return $doc_comment;
			}
		}

		$filename = $reflection->getFileName();

		if ( isset( self::$file_contents[ $filename ] ) ) {
			$contents = self::$file_contents[ $filename ];
		} elseif ( is_readable( $filename ) ) {
			$contents = file_get_contents( $filename );
			if ( is_string( $contents ) && '' !== $contents ) {
				$contents                         = explode( "\n", $contents );
				self::$file_contents[ $filename ] = $contents;
			}
		}

		if ( ! empty( $contents ) ) {
			return self::extract_last_doc_comment( implode( "\n", array_slice( $contents, 0, $reflection->getStartLine() ) ) );
		}

		WP_CLI::debug( "Could not read contents for filename '{$filename}'.", 'commandfactory' );
		return null;
	}

	/**
	 * Returns the last doc comment if any in `$content`.
	 *
	 * @param string $content The content, which should end at the class or function declaration.
	 * @return string|bool The last doc comment if any, or false if none.
	 */
	private static function extract_last_doc_comment( $content ) {
		$content         = trim( $content );
		$comment_end_pos = strrpos( $content, '*/' );

		if ( false === $comment_end_pos ) {
			return false;
		}

		// Make sure comment end belongs to this class/function.
		if ( preg_match_all( '/(?:^|[\s;}])(?:class|function)\s+/', substr( $content, $comment_end_pos + 2 ), $dummy /*needed for PHP 5.3*/ ) > 1 ) {
			return false;
		}

		$content           = substr( $content, 0, $comment_end_pos + 2 );
		$comment_start_pos = strrpos( $content, '/**' );

		if ( false === $comment_start_pos || ( $comment_start_pos + 2 ) === $comment_end_pos ) {
			return false;
		}

		// Make sure comment start belongs to this comment end.
		$comment_end2_pos = strpos( substr( $content, $comment_start_pos ), '*/' );

		if ( false !== $comment_end2_pos && ( $comment_start_pos + $comment_end2_pos ) < $comment_end_pos ) {
			return false;
		}

		// Allow for '/**' within doc comment.
		$subcontent         = substr( $content, 0, $comment_start_pos );
		$comment_start2_pos = strrpos( $subcontent, '/**' );

		while ( false !== $comment_start2_pos && false === strpos( $subcontent, '*/', $comment_start2_pos ) ) {
			$comment_start_pos  = $comment_start2_pos;
			$subcontent         = substr( $subcontent, 0, $comment_start_pos );
			$comment_start2_pos = strrpos( $subcontent, '/**' );
		}

		return substr( $content, $comment_start_pos, $comment_end_pos + 2 );
	}
}
<?php

namespace WP_CLI\Dispatcher;

use WP_CLI;
use WP_CLI\DocParser;
use WP_CLI\Utils;

/**
 * A non-leaf node in the command tree.
 * Contains one or more Subcommands.
 *
 * @package WP_CLI
 */
class CompositeCommand {

	protected $name;
	protected $shortdesc;
	protected $longdesc;
	protected $synopsis;
	protected $hook;
	protected $docparser;

	protected $parent;
	protected $subcommands = [];

	/**
	 * Instantiate a new CompositeCommand
	 *
	 * @param mixed $parent Parent command (either Root or Composite)
	 * @param string $name Represents how command should be invoked
	 * @param DocParser $docparser
	 */
	public function __construct( $parent, $name, $docparser ) {
		$this->parent = $parent;

		$this->name = $name;

		$this->shortdesc = $docparser->get_shortdesc();
		$this->longdesc  = $docparser->get_longdesc();
		$this->docparser = $docparser;
		$this->hook      = $parent->get_hook();

		$when_to_invoke = $docparser->get_tag( 'when' );
		if ( $when_to_invoke ) {
			$this->hook = $when_to_invoke;
			WP_CLI::get_runner()->register_early_invoke( $when_to_invoke, $this );
		}
	}

	/**
	 * Get the parent composite (or root) command
	 *
	 * @return mixed
	 */
	public function get_parent() {
		return $this->parent;
	}

	/**
	 * Add a named subcommand to this composite command's
	 * set of contained subcommands.
	 *
	 * @param string                      $name     Represents how subcommand should be invoked
	 * @param Subcommand|CompositeCommand $command  Cub-command to add.
	 * @param bool                        $override Optional. Whether to override an existing subcommand of the same
	 *                                              name.
	 */
	public function add_subcommand( $name, $command, $override = true ) {
		if ( $override || ! array_key_exists( $name, $this->subcommands ) ) {
			$this->subcommands[ $name ] = $command;
		}
	}

	/**
	 * Remove a named subcommand from this composite command's set of contained
	 * subcommands
	 *
	 * @param string $name Represents how subcommand should be invoked
	 */
	public function remove_subcommand( $name ) {
		if ( isset( $this->subcommands[ $name ] ) ) {
			unset( $this->subcommands[ $name ] );
		}
	}


	/**
	 * Composite commands always contain subcommands.
	 *
	 * @return true
	 */
	public function can_have_subcommands() {
		return true;
	}

	/**
	 * Get the subcommands contained by this composite
	 * command.
	 *
	 * @return array
	 */
	public function get_subcommands() {
		ksort( $this->subcommands );

		return $this->subcommands;
	}

	/**
	 * Get the name of this composite command.
	 *
	 * @return string
	 */
	public function get_name() {
		return $this->name;
	}

	/**
	 * Get the short description for this composite
	 * command.
	 *
	 * @return string
	 */
	public function get_shortdesc() {
		return $this->shortdesc;
	}

	/**
	 * Get the hook name for this composite
	 * command.
	 *
	 * @return string
	 */
	public function get_hook() {
		return $this->hook;
	}

	/**
	 * Set the short description for this composite command.
	 *
	 * @param string $shortdesc
	 */
	public function set_shortdesc( $shortdesc ) {
		$this->shortdesc = Utils\normalize_eols( $shortdesc );
	}

	/**
	 * Get the long description for this composite
	 * command.
	 *
	 * @return string
	 */
	public function get_longdesc() {
		return $this->longdesc . $this->get_global_params();
	}

	/**
	 * Set the long description for this composite command
	 *
	 * @param string $longdesc
	 */
	public function set_longdesc( $longdesc ) {
		$this->longdesc = Utils\normalize_eols( $longdesc );
	}

	/**
	 * Get the synopsis for this composite command.
	 * As a collection of subcommands, the composite
	 * command is only intended to invoke those
	 * subcommands.
	 *
	 * @return string
	 */
	public function get_synopsis() {
		return '<command>';
	}

	/**
	 * Get the usage for this composite command.
	 *
	 * @return string
	 */
	public function get_usage( $prefix ) {
		return sprintf(
			'%s%s %s',
			$prefix,
			implode( ' ', get_path( $this ) ),
			$this->get_synopsis()
		);
	}

	/**
	 * Show the usage for all subcommands contained
	 * by the composite command.
	 */
	public function show_usage() {
		$methods = $this->get_subcommands();

		$i = 0;

		foreach ( $methods as $subcommand ) {
			$prefix = ( 0 === $i ) ? 'usage: ' : '   or: ';
			++$i;

			if ( WP_CLI::get_runner()->is_command_disabled( $subcommand ) ) {
				continue;
			}

			WP_CLI::line( $subcommand->get_usage( $prefix ) );
		}

		$cmd_name = implode( ' ', array_slice( get_path( $this ), 1 ) );

		WP_CLI::line();
		WP_CLI::line( "See 'wp help $cmd_name <command>' for more information on a specific command." );
	}

	/**
	 * When a composite command is invoked, it shows usage
	 * docs for its subcommands.
	 *
	 * @param array $args
	 * @param array $assoc_args
	 * @param array $extra_args
	 */
	public function invoke( $args, $assoc_args, $extra_args ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- arguments not used, as only help displayed.
		$this->show_usage();
	}

	/**
	 * Given supplied arguments, find a contained
	 * subcommand
	 *
	 * @param array $args
	 * @return Subcommand|false
	 */
	public function find_subcommand( &$args ) {
		$name = array_shift( $args );

		$subcommands = $this->get_subcommands();

		if ( ! isset( $subcommands[ $name ] ) ) {
			$aliases = self::get_aliases( $subcommands );

			if ( isset( $aliases[ $name ] ) ) {
				$name = $aliases[ $name ];
			}
		}

		if ( ! isset( $subcommands[ $name ] ) ) {
			return false;
		}

		return $subcommands[ $name ];
	}

	/**
	 * Get any registered aliases for this composite command's
	 * subcommands.
	 *
	 * @param array $subcommands
	 * @return array
	 */
	private static function get_aliases( $subcommands ) {
		$aliases = [];

		foreach ( $subcommands as $name => $subcommand ) {
			$alias = $subcommand->get_alias();
			if ( $alias ) {
				$aliases[ $alias ] = $name;
			}
		}

		return $aliases;
	}

	/**
	 * Composite commands can only be known by one name.
	 *
	 * @return string|false
	 */
	public function get_alias() {
		return false;
	}

	/***
	 * Get the list of global parameters
	 *
	 * @param string $root_command whether to include or not root command specific description
	 * @return string
	 */
	protected function get_global_params( $root_command = false ) {
		$binding                 = [];
		$binding['root_command'] = $root_command;

		if ( ! $this->can_have_subcommands() || ( is_object( $this->parent ) && get_class( $this->parent ) === 'WP_CLI\Dispatcher\CompositeCommand' ) ) {
			$binding['is_subcommand'] = true;
		}

		foreach ( WP_CLI::get_configurator()->get_spec() as $key => $details ) {
			if ( false === $details['runtime'] ) {
				continue;
			}

			if ( isset( $details['deprecated'] ) ) {
				continue;
			}

			if ( isset( $details['hidden'] ) ) {
				continue;
			}

			if ( true === $details['runtime'] ) {
				$synopsis = "--[no-]$key";
			} else {
				$synopsis = "--$key" . $details['runtime'];
			}

			// Check if global parameters synopsis should be displayed or not.
			if ( 'true' !== getenv( 'WP_CLI_SUPPRESS_GLOBAL_PARAMS' ) ) {
				$binding['parameters'][]   = [
					'synopsis' => $synopsis,
					'desc'     => $details['desc'],
				];
				$binding['has_parameters'] = true;
			}
		}

		if ( $this->get_subcommands() ) {
			$binding['has_subcommands'] = true;
		}

		return Utils\mustache_render( 'man-params.mustache', $binding );
	}
}
<?php

namespace WP_CLI\Dispatcher;

use WP_CLI;

/**
 * Controls whether adding of a command should be completed or not.
 *
 * This is needed because we can't reliably pass scalar values by reference
 * through the hooks mechanism. An object is always passed by reference.
 *
 * @package WP_CLI
 */
final class CommandAddition {

	/**
	 * Whether the command addition was aborted or not.
	 *
	 * @var bool
	 */
	private $abort = false;

	/**
	 * Reason for which the addition was aborted.
	 *
	 * @var string
	 */
	private $reason = '';

	/**
	 * Abort the current command addition.
	 *
	 * @param string $reason Reason as to why the addition was aborted.
	 */
	public function abort( $reason = '' ) {
		$this->abort  = true;
		$this->reason = (string) $reason;
	}

	/**
	 * Check whether the command addition was aborted.
	 *
	 * @return bool
	 */
	public function was_aborted() {
		return $this->abort;
	}

	/**
	 * Get the reason as to why the addition was aborted.
	 *
	 * @return string
	 */
	public function get_reason() {
		return $this->reason;
	}
}
<?php

namespace WP_CLI\Dispatcher;

use WP_CLI\Utils;

/**
 * The root node in the command tree.
 *
 * @package WP_CLI
 */
class RootCommand extends CompositeCommand {

	public function __construct() {
		$this->parent = false;

		$this->name = 'wp';

		$this->shortdesc = 'Manage WordPress through the command-line.';
	}

	/**
	 * Get the human-readable long description.
	 *
	 * @return string
	 */
	public function get_longdesc() {
		return $this->get_global_params( true );
	}

	/**
	 * Find a subcommand registered on the root
	 * command.
	 *
	 * @param array $args
	 * @return Subcommand|false
	 */
	public function find_subcommand( &$args ) {
		$command = array_shift( $args );

		Utils\load_command( $command );

		if ( ! isset( $this->subcommands[ $command ] ) ) {
			return false;
		}

		return $this->subcommands[ $command ];
	}
}
<?php

namespace WP_CLI\Dispatcher;

use WP_CLI;

/**
 * Adds a command namespace without actual functionality.
 *
 * This is meant to provide the means to attach meta information to a namespace
 * when there's no actual command needed.
 *
 * In case a real command gets registered for the same name, it replaces the
 * command namespace.
 *
 * @package WP_CLI
 */
class CommandNamespace extends CompositeCommand {

	/**
	 * Show the usage for all subcommands contained
	 * by the composite command.
	 */
	public function show_usage() {
		$methods = $this->get_subcommands();

		$i     = 0;
		$count = 0;

		foreach ( $methods as $subcommand ) {
			$prefix = ( 0 === $i ) ? 'usage: ' : '   or: ';
			++$i;

			if ( \WP_CLI::get_runner()->is_command_disabled( $subcommand ) ) {
				continue;
			}

			\WP_CLI::line( $subcommand->get_usage( $prefix ) );
			++$count;
		}

		$cmd_name = implode( ' ', array_slice( get_path( $this ), 1 ) );
		$message  = $count > 0
			? "See 'wp help $cmd_name <command>' for more information on a specific command."
			: "The namespace $cmd_name does not contain any usable commands in the current context.";

		\WP_CLI::line();
		\WP_CLI::line( $message );
	}
}
<?php

namespace WP_CLI;

use WP_CLI;
use WP_CLI\Dispatcher;
use WP_CLI\Dispatcher\CompositeCommand;
use WP_CLI\Dispatcher\Subcommand;
use WP_CLI\Fetchers;
use WP_CLI\Iterators\Exception;
use WP_CLI\Loggers;
use WP_CLI\Utils;
use WP_Error;

/**
 * Performs the execution of a command.
 *
 * @property-read string         $global_config_path
 * @property-read string         $project_config_path
 * @property-read array          $config
 * @property-read array          $extra_config
 * @property-read ContextManager $context_manager
 * @property-read string         $alias
 * @property-read array          $aliases
 * @property-read array          $arguments
 * @property-read array          $assoc_args
 * @property-read array          $runtime_config
 * @property-read bool           $colorize
 * @property-read array          $early_invoke
 * @property-read string         $global_config_path_debug
 * @property-read string         $project_config_path_debug
 * @property-read array          $required_files
 *
 * @package WP_CLI
 */
class Runner {

	/**
	 * List of byte-order marks (BOMs) to detect.
	 *
	 * @var array<string, string>
	 */
	const BYTE_ORDER_MARKS = [
		'UTF-8'       => "\xEF\xBB\xBF",
		'UTF-16 (BE)' => "\xFE\xFF",
		'UTF-16 (LE)' => "\xFF\xFE",
	];

	private $global_config_path;
	private $project_config_path;

	private $config;
	private $extra_config;

	private $context_manager;

	private $alias;

	private $aliases;

	private $arguments;
	private $assoc_args;
	private $runtime_config;

	private $colorize = false;

	private $early_invoke = [];

	private $global_config_path_debug;

	private $project_config_path_debug;

	private $required_files;

	public function __get( $key ) {
		if ( '_' === $key[0] ) {
			return null;
		}

		return $this->$key;
	}

	public function register_context_manager( ContextManager $context_manager ) {
		$this->context_manager = $context_manager;
	}

	/**
	 * Register a command for early invocation, generally before WordPress loads.
	 *
	 * @param string $when Named execution hook
	 * @param Subcommand $command
	 */
	public function register_early_invoke( $when, $command ) {
		$cmd_path     = array_slice( Dispatcher\get_path( $command ), 1 );
		$command_name = implode( ' ', $cmd_path );
		WP_CLI::debug( "Attaching command '{$command_name}' to hook {$when}", 'bootstrap' );
		$this->early_invoke[ $when ][] = $cmd_path;
		if ( $command->get_alias() ) {
			array_pop( $cmd_path );
			$cmd_path[] = $command->get_alias();
			$alias_name = implode( ' ', $cmd_path );
			WP_CLI::debug( "Attaching command alias '{$alias_name}' to hook {$when}", 'bootstrap' );
			$this->early_invoke[ $when ][] = $cmd_path;
		}
	}

	/**
	 * Perform the early invocation of a command.
	 *
	 * @param string $when Named execution hook
	 */
	private function do_early_invoke( $when ) {
		WP_CLI::debug( "Executing hook: {$when}", 'hooks' );
		if ( ! isset( $this->early_invoke[ $when ] ) ) {
			return;
		}

		// Search the value of @when from the command method.
		$real_when = '';
		$r         = $this->find_command_to_run( $this->arguments );
		if ( is_array( $r ) ) {
			list( $command, $final_args, $cmd_path ) = $r;

			foreach ( $this->early_invoke as $_when => $_path ) {
				foreach ( $_path as $cmd ) {
					if ( $cmd === $cmd_path ) {
						$real_when = $_when;
					}
				}
			}
		}

		foreach ( $this->early_invoke[ $when ] as $path ) {
			if ( $this->cmd_starts_with( $path ) ) {
				if ( empty( $real_when ) || ( $real_when && $real_when === $when ) ) {
					$this->run_command_and_exit();
				}
			}
		}
	}

	/**
	 * Get the path to the global configuration YAML file.
	 *
	 * @param bool $create_config_file Optional. If a config file doesn't exist,
	 *                                 should it be created? Defaults to false.
	 *
	 * @return string|false
	 */
	public function get_global_config_path( $create_config_file = false ) {

		if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) {
			$config_path                    = getenv( 'WP_CLI_CONFIG_PATH' );
			$this->global_config_path_debug = 'Using global config from WP_CLI_CONFIG_PATH env var: ' . $config_path;
		} else {
			$config_path                    = Utils\get_home_dir() . '/.wp-cli/config.yml';
			$this->global_config_path_debug = 'Using default global config: ' . $config_path;
		}

		// If global config doesn't exist create one.
		if ( true === $create_config_file && ! file_exists( $config_path ) ) {
			$this->global_config_path_debug = "Default global config doesn't exist, creating one in {$config_path}";

			$dir = dirname( $config_path );

			if ( ! is_dir( $dir ) ) {
				mkdir( $dir, 0755, true );
			}

			touch( $config_path );

			if ( file_exists( $config_path ) ) {
				WP_CLI::debug( "Default global config does not exist, creating one in $config_path" );
			}
		}

		if ( is_readable( $config_path ) ) {
			return $config_path;
		}

		$this->global_config_path_debug = 'No readable global config found';

		return false;
	}

	/**
	 * Get the path to the project-specific configuration
	 * YAML file.
	 * wp-cli.local.yml takes priority over wp-cli.yml.
	 *
	 * @return string|false
	 */
	public function get_project_config_path() {
		$config_files = [
			'wp-cli.local.yml',
			'wp-cli.yml',
		];

		// Stop looking upward when we find we have emerged from a subdirectory
		// installation into a parent installation
		$project_config_path = Utils\find_file_upward(
			$config_files,
			getcwd(),
			static function ( $dir ) {
				static $wp_load_count = 0;
				$wp_load_path         = $dir . DIRECTORY_SEPARATOR . 'wp-load.php';
				if ( file_exists( $wp_load_path ) ) {
					++$wp_load_count;
				}
				return $wp_load_count > 1;
			}
		);

		if ( null === $project_config_path ) {
			$this->project_config_path_debug = 'No project config found';
			return false;
		}

		$this->project_config_path_debug = 'Using project config: ' . $project_config_path;
		return $project_config_path;
	}

	/**
	 * Get the path to the packages directory
	 *
	 * @return string
	 */
	public function get_packages_dir_path() {
		if ( getenv( 'WP_CLI_PACKAGES_DIR' ) ) {
			$packages_dir = Utils\trailingslashit( getenv( 'WP_CLI_PACKAGES_DIR' ) );
		} else {
			$packages_dir = Utils\get_home_dir() . '/.wp-cli/packages/';
		}
		return $packages_dir;
	}

	/**
	 * Attempts to find the path to the WP installation inside index.php
	 *
	 * @param string $index_path
	 * @return string|false
	 */
	private static function extract_subdir_path( $index_path ) {
		$index_code = file_get_contents( $index_path );

		if ( ! preg_match( '|^\s*require\s*\(?\s*(.+?)/wp-blog-header\.php([\'"])|m', $index_code, $matches ) ) {
			return false;
		}

		$wp_path_src = $matches[1] . $matches[2];
		$wp_path_src = Utils\replace_path_consts( $wp_path_src, $index_path );

		$wp_path = eval( "return $wp_path_src;" ); // phpcs:ignore Squiz.PHP.Eval.Discouraged

		if ( ! Utils\is_path_absolute( $wp_path ) ) {
			$wp_path = dirname( $index_path ) . "/$wp_path";
		}

		return $wp_path;
	}

	/**
	 * Find the directory that contains the WordPress files.
	 * Defaults to the current working dir.
	 *
	 * @return string An absolute path.
	 */
	public function find_wp_root() {
		if ( isset( $this->config['path'] ) &&
			( is_bool( $this->config['path'] ) || empty( $this->config['path'] ) )
		) {
			WP_CLI::error( 'The --path parameter cannot be empty when provided.' );
		}

		if ( ! empty( $this->config['path'] ) ) {
			$path = $this->config['path'];
			if ( ! Utils\is_path_absolute( $path ) ) {
				$path = getcwd() . '/' . $path;
			}

			return $path;
		}

		if ( $this->cmd_starts_with( [ 'core', 'download' ] ) ) {
			return getcwd();
		}

		$dir = getcwd();

		while ( is_readable( $dir ) ) {
			if ( file_exists( "$dir/wp-load.php" ) ) {
				return $dir;
			}

			if ( file_exists( "$dir/index.php" ) ) {
				$path = self::extract_subdir_path( "$dir/index.php" );
				if ( ! empty( $path ) ) {
					return $path;
				}
			}

			$parent_dir = dirname( $dir );
			if ( empty( $parent_dir ) || $parent_dir === $dir ) {
				break;
			}
			$dir = $parent_dir;
		}

		return getcwd();
	}

	/**
	 * Set WordPress root as a given path.
	 *
	 * @param string $path
	 */
	private static function set_wp_root( $path ) {
		if ( ! defined( 'ABSPATH' ) ) {
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Declaring a WP native constant.
			define( 'ABSPATH', Utils\normalize_path( Utils\trailingslashit( $path ) ) );
		} elseif ( ! is_null( $path ) ) {
			WP_CLI::error_multi_line(
				[
					'The --path parameter cannot be used when ABSPATH is already defined elsewhere',
					'ABSPATH is defined as: "' . ABSPATH . '"',
				]
			);
		}
		WP_CLI::debug( 'ABSPATH defined: ' . ABSPATH, 'bootstrap' );

		$_SERVER['DOCUMENT_ROOT'] = realpath( $path );
	}

	/**
	 * Guess which URL context WP-CLI has been invoked under.
	 *
	 * @param array $assoc_args
	 * @return string|false
	 */
	private static function guess_url( $assoc_args ) {
		if ( isset( $assoc_args['blog'] ) ) {
			$assoc_args['url'] = $assoc_args['blog'];
		}

		if ( isset( $assoc_args['url'] ) ) {
			$url = $assoc_args['url'];

			if ( true === $url ) {
				WP_CLI::warning( 'The --url parameter expects a value.' );
			}

			return $url;
		}

		return false;
	}

	/**
	 * Checks if the arguments passed to the WP-CLI binary start with the specified prefix.
	 *
	 * @param array $prefix An array of strings specifying the expected start of the arguments passed to the WP-CLI binary.
	 *                      For example, `['user', 'list']` checks if the arguments passed to the WP-CLI binary start with `user list`.
	 *
	 * @return bool `true` if the arguments passed to the WP-CLI binary start with the specified prefix, `false` otherwise.
	 */
	private function cmd_starts_with( $prefix ) {
		return array_slice( $this->arguments, 0, count( $prefix ) ) === $prefix;
	}

	/**
	 * Given positional arguments, find the command to execute.
	 *
	 * @param array $args
	 * @return array|string Command, args, and path on success; error message on failure
	 */
	public function find_command_to_run( $args ) {
		$command = WP_CLI::get_root_command();

		WP_CLI::do_hook( 'find_command_to_run_pre' );

		$cmd_path = [];

		while ( ! empty( $args ) && $command->can_have_subcommands() ) {
			$cmd_path[] = $args[0];
			$full_name  = implode( ' ', $cmd_path );

			$subcommand = $command->find_subcommand( $args );

			if ( ! $subcommand ) {
				if ( count( $cmd_path ) > 1 ) {
					$child       = array_pop( $cmd_path );
					$parent_name = implode( ' ', $cmd_path );
					$suggestion  = $this->get_subcommand_suggestion( $child, $command );

					if ( 'network' === $parent_name && 'option' === $child ) {
						$suggestion = 'meta';
					}

					return sprintf(
						"'%s' is not a registered subcommand of '%s'. See 'wp help %s' for available subcommands.%s",
						$child,
						$parent_name,
						$parent_name,
						! empty( $suggestion ) ? PHP_EOL . "Did you mean '{$suggestion}'?" : ''
					);
				}

				$suggestion = $this->get_subcommand_suggestion( $full_name, $command );

				// If the functions are available, it means WordPress is available
				// and has already been loaded.
				if ( function_exists( '\taxonomy_exists' ) ) {
					if ( \taxonomy_exists( $cmd_path[0] ) ) {
						$suggestion = 'wp term <command>';
					} elseif ( \post_type_exists( $cmd_path[0] ) ) {
						$suggestion = "wp post --post_type={$cmd_path[0]} <command>";
					}
				}

				return sprintf(
					"'%s' is not a registered wp command. See 'wp help' for available commands.%s",
					$full_name,
					! empty( $suggestion ) ? PHP_EOL . "Did you mean '{$suggestion}'?" : ''
				);
			}

			if ( $this->is_command_disabled( $subcommand ) ) {
				return sprintf(
					"The '%s' command has been disabled from the config file.",
					$full_name
				);
			}

			$command = $subcommand;
		}

		return [ $command, $args, $cmd_path ];
	}

	/**
	 * Find the WP-CLI command to run given arguments, and invoke it.
	 *
	 * @param array $args        Positional arguments including command name
	 * @param array $assoc_args  Associative arguments for the command.
	 * @param array $options     Configuration options for the function.
	 */
	public function run_command( $args, $assoc_args = [], $options = [] ) {
		WP_CLI::do_hook( 'before_run_command', $args, $assoc_args, $options );

		if ( ! empty( $options['back_compat_conversions'] ) ) {
			list( $args, $assoc_args ) = self::back_compat_conversions( $args, $assoc_args );
		}
		$r = $this->find_command_to_run( $args );
		if ( is_string( $r ) ) {
			WP_CLI::error( $r );
		}

		list( $command, $final_args, $cmd_path ) = $r;

		$name = implode( ' ', $cmd_path );

		$extra_args = [];

		if ( isset( $this->extra_config[ $name ] ) ) {
			$extra_args = $this->extra_config[ $name ];
		}

		WP_CLI::debug( 'Running command: ' . $name, 'bootstrap' );
		try {
			$command->invoke( $final_args, $assoc_args, $extra_args );
		} catch ( Exception $e ) {
			WP_CLI::error( $e->getMessage() );
		}
	}

	/**
	 * Show synopsis if the called command is a composite command
	 */
	public function show_synopsis_if_composite_command() {
		$r = $this->find_command_to_run( $this->arguments );
		if ( is_array( $r ) ) {
			list( $command ) = $r;

			if ( $command->can_have_subcommands() ) {
				$command->show_usage();
				exit;
			}
		}
	}

	private function run_command_and_exit( $help_exit_warning = '' ) {
		$this->show_synopsis_if_composite_command();
		$this->run_command( $this->arguments, $this->assoc_args );
		if ( $this->cmd_starts_with( [ 'help' ] ) ) {
			// Help couldn't find the command so exit with suggestion.
			$suggestion_or_disabled = $this->find_command_to_run( array_slice( $this->arguments, 1 ) );
			if ( is_string( $suggestion_or_disabled ) ) {
				if ( $help_exit_warning ) {
					WP_CLI::warning( $help_exit_warning );
				}
				WP_CLI::error( $suggestion_or_disabled );
			}
			// Should never get here.
		}
		exit;
	}

	/**
	 * Perform a command against a remote server over SSH (or a container using
	 * scheme of "docker", "docker-compose", or "docker-compose-run").
	 *
	 * @param string $connection_string Passed connection string.
	 * @return void
	 */
	private function run_ssh_command( $connection_string ) {

		WP_CLI::do_hook( 'before_ssh' );

		$bits = Utils\parse_ssh_url( $connection_string );

		$pre_cmd = getenv( 'WP_CLI_SSH_PRE_CMD' );
		if ( $pre_cmd ) {
			WP_CLI::warning( "WP_CLI_SSH_PRE_CMD found, executing the following command(s) on the remote machine:\n $pre_cmd" );

			$pre_cmd = rtrim( $pre_cmd, ';' ) . '; ';
		}

		$env_vars = '';
		if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) {
			$env_vars .= 'WP_CLI_STRICT_ARGS_MODE=1 ';
		}

		$wp_binary = getenv( 'WP_CLI_SSH_BINARY' ) ?: 'wp';
		$wp_args   = array_slice( $GLOBALS['argv'], 1 );

		if ( $this->alias && ! empty( $wp_args[0] ) && $this->alias === $wp_args[0] ) {
			array_shift( $wp_args );
			$runtime_alias = [];
			foreach ( $this->aliases[ $this->alias ] as $key => $value ) {
				if ( 'ssh' === $key ) {
					continue;
				}
				$runtime_alias[ $key ] = $value;
			}
			if ( ! empty( $runtime_alias ) ) {
				$encoded_alias = json_encode(
					[
						$this->alias => $runtime_alias,
					]
				);
				$wp_binary     = "WP_CLI_RUNTIME_ALIAS='{$encoded_alias}' {$wp_binary} {$this->alias}";
			}
		}

		foreach ( $wp_args as $k => $v ) {
			if ( preg_match( '#--ssh=#', $v ) ) {
				unset( $wp_args[ $k ] );
			}
		}

		$wp_command = $pre_cmd . $env_vars . $wp_binary . ' ' . implode( ' ', array_map( 'escapeshellarg', $wp_args ) );

		if ( isset( $bits['scheme'] ) && 'docker-compose-run' === $bits['scheme'] ) {
			$wp_command = implode( ' ', $wp_args );
		}

		$escaped_command = $this->generate_ssh_command( $bits, $wp_command );

		passthru( $escaped_command, $exit_code );
		if ( 255 === $exit_code ) {
			WP_CLI::error( 'Cannot connect over SSH using provided configuration.', 255 );
		} else {
			exit( $exit_code );
		}
	}

	/**
	 * Generate a shell command from the parsed connection string.
	 *
	 * @param array  $bits       Parsed connection string.
	 * @param string $wp_command WP-CLI command to run.
	 * @return string
	 */
	private function generate_ssh_command( $bits, $wp_command ) {
		$escaped_command = '';

		// Set default values.
		foreach ( [ 'scheme', 'user', 'host', 'port', 'path', 'key', 'proxyjump' ] as $bit ) {
			if ( ! isset( $bits[ $bit ] ) ) {
				$bits[ $bit ] = null;
			}

			WP_CLI::debug( 'SSH ' . $bit . ': ' . $bits[ $bit ], 'bootstrap' );
		}

		/*
		 * posix_isatty(STDIN) is generally true unless something was passed on stdin
		 * If autodetection leads to false (fd on stdin), then `-i` is passed to `docker` cmd
		 * (unless WP_CLI_DOCKER_NO_INTERACTIVE is set)
		 */
		$is_stdout_tty = function_exists( 'posix_isatty' ) && posix_isatty( STDOUT );
		$is_stdin_tty  = function_exists( 'posix_isatty' ) ? posix_isatty( STDIN ) : true;

		if ( in_array( $bits['scheme'], [ 'docker', 'docker-compose', 'docker-compose-run' ], true ) ) {
				$docker_compose_v2_version_cmd = Utils\esc_cmd( Utils\force_env_on_nix_systems( 'docker' ) . ' compose %s', 'version' );
				$docker_compose_cmd            = ! empty( Process::create( $docker_compose_v2_version_cmd )->run()->stdout )
						? 'docker compose'
						: 'docker-compose';
		}

		if ( 'docker' === $bits['scheme'] ) {
			$command = 'docker exec %s%s%s%s%s sh -c %s';

			$escaped_command = sprintf(
				$command,
				$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
				$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
				$is_stdout_tty && ! getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '-t  ' : '',
				$is_stdin_tty || getenv( 'WP_CLI_DOCKER_NO_INTERACTIVE' ) ? '' : '-i ',
				escapeshellarg( $bits['host'] ),
				escapeshellarg( $wp_command )
			);
		}

		if ( 'docker-compose' === $bits['scheme'] ) {
			$command = '%s exec %s%s%s%s sh -c %s';

			$escaped_command = sprintf(
				$command,
				$docker_compose_cmd,
				$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
				$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
				$is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ',
				escapeshellarg( $bits['host'] ),
				escapeshellarg( $wp_command )
			);
		}

		if ( 'docker-compose-run' === $bits['scheme'] ) {
			$command = '%s run %s%s%s%s%s %s';

			$escaped_command = sprintf(
				$command,
				$docker_compose_cmd,
				$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
				$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
				$is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ',
				$is_stdin_tty || getenv( 'WP_CLI_DOCKER_NO_INTERACTIVE' ) ? '' : '-i ',
				escapeshellarg( $bits['host'] ),
				$wp_command
			);
		}

		// For "vagrant" & "ssh" schemes which don't provide a working-directory option, use `cd`
		if ( $bits['path'] ) {
			$wp_command = 'cd ' . escapeshellarg( $bits['path'] ) . '; ' . $wp_command;
		}

		// Vagrant ssh-config.
		if ( 'vagrant' === $bits['scheme'] ) {
			$cache     = WP_CLI::get_cache();
			$cache_key = 'vagrant:' . $this->project_config_path;
			if ( $cache->has( $cache_key ) ) {
				$cached = $cache->read( $cache_key );
				$values = json_decode( $cached, true );
			} else {
				$ssh_config = shell_exec( 'vagrant ssh-config 2>/dev/null' );
				if ( preg_match_all( '#\s*(?<NAME>[a-zA-Z]+)\s(?<VALUE>.+)\s*#', $ssh_config, $matches ) ) {
					$values = array_combine( $matches['NAME'], $matches['VALUE'] );
					$cache->write( $cache_key, json_encode( $values ) );
				}
			}

			if ( empty( $bits['host'] ) || ( isset( $values['Host'] ) && $bits['host'] === $values['Host'] ) ) {
				$bits['scheme'] = 'ssh';
				$bits['host']   = isset( $values['HostName'] ) ? $values['HostName'] : '';
				$bits['port']   = isset( $values['Port'] ) ? $values['Port'] : '';
				$bits['user']   = isset( $values['User'] ) ? $values['User'] : '';
				$bits['key']    = isset( $values['IdentityFile'] ) ? $values['IdentityFile'] : '';
			}

			// If we could not resolve the bits still, fallback to just `vagrant ssh`
			if ( 'vagrant' === $bits['scheme'] ) {
				$command = 'vagrant ssh -c %s %s';

				$escaped_command = sprintf(
					$command,
					escapeshellarg( $wp_command ),
					escapeshellarg( $bits['host'] )
				);
			}
		}

		// Default scheme is SSH.
		if ( 'ssh' === $bits['scheme'] || null === $bits['scheme'] ) {
			$command = 'ssh %s %s %s';

			if ( $bits['user'] ) {
				$bits['host'] = $bits['user'] . '@' . $bits['host'];
			}

			if ( ! empty( $this->alias ) ) {
				$alias_config = isset( $this->aliases[ $this->alias ] ) ? $this->aliases[ $this->alias ] : false;

				if ( is_array( $alias_config ) ) {
					$bits['proxyjump'] = isset( $alias_config['proxyjump'] ) ? $alias_config['proxyjump'] : '';
					$bits['key']       = isset( $alias_config['key'] ) ? $alias_config['key'] : '';
				}
			}

			$command_args = [
				$bits['proxyjump'] ? sprintf( '-J %s', escapeshellarg( $bits['proxyjump'] ) ) : '',
				$bits['port'] ? sprintf( '-p %d', (int) $bits['port'] ) : '',
				$bits['key'] ? sprintf( '-i %s', escapeshellarg( $bits['key'] ) ) : '',
				$is_stdout_tty ? '-t' : '-T',
				WP_CLI::get_config( 'debug' ) ? '-vvv' : '-q',
			];

			$escaped_command = sprintf(
				$command,
				implode( ' ', array_filter( $command_args ) ),
				escapeshellarg( $bits['host'] ),
				escapeshellarg( $wp_command )
			);
		}

		WP_CLI::debug( 'Running SSH command: ' . $escaped_command, 'bootstrap' );

		return $escaped_command;
	}

	/**
	 * Check whether a given command is disabled by the config.
	 *
	 * @return bool
	 */
	public function is_command_disabled( $command ) {
		$path = implode( ' ', array_slice( Dispatcher\get_path( $command ), 1 ) );
		return in_array( $path, $this->config['disabled_commands'], true );
	}

	/**
	 * Returns wp-config.php code, skipping the loading of wp-settings.php.
	 *
	 * @param string $wp_config_path Optional. Config file path. If left empty, it tries to
	 *                               locate the wp-config.php file automatically.
	 *
	 * @return string
	 */
	public function get_wp_config_code( $wp_config_path = '' ) {
		if ( empty( $wp_config_path ) ) {
			$wp_config_path = Utils\locate_wp_config();
		}

		$wp_config_code = file_get_contents( $wp_config_path );

		// Detect and strip byte-order marks (BOMs).
		// This code assumes they can only be found on the first line.
		foreach ( self::BYTE_ORDER_MARKS as $bom_name => $bom_sequence ) {
			WP_CLI::debug( "Looking for {$bom_name} BOM", 'bootstrap' );

			$length = strlen( $bom_sequence );

			while ( substr( $wp_config_code, 0, $length ) === $bom_sequence ) {
				WP_CLI::warning(
					"{$bom_name} byte-order mark (BOM) detected in wp-config.php file, stripping it for parsing."
				);

				$wp_config_code = substr( $wp_config_code, $length );
			}
		}

		$count = 0;

		$wp_config_code = preg_replace( '/\s*require(?:_once)?\s*.*wp-settings\.php.*\s*;/', '', $wp_config_code, -1, $count );

		if ( 0 === $count ) {
			WP_CLI::error( 'Strange wp-config.php file: wp-settings.php is not loaded directly.' );
		}

		$source = Utils\replace_path_consts( $wp_config_code, $wp_config_path );
		return preg_replace( '|^\s*\<\?php\s*|', '', $source );
	}

	/**
	 * Transparently convert deprecated syntaxes
	 *
	 * @param array $args
	 * @param array $assoc_args
	 * @return array
	 */
	private static function back_compat_conversions( $args, $assoc_args ) {
		$top_level_aliases = [
			'sql'  => 'db',
			'blog' => 'site',
		];
		if ( count( $args ) > 0 ) {
			foreach ( $top_level_aliases as $old => $new ) {
				if ( $old === $args[0] ) {
					$args[0] = $new;
					break;
				}
			}
		}

		// *-meta  ->  * meta
		if ( ! empty( $args ) && preg_match( '/(post|comment|user|network)-meta/', $args[0], $matches ) ) {
			array_shift( $args );
			array_unshift( $args, 'meta' );
			array_unshift( $args, $matches[1] );
		}

		// cli aliases  ->  cli alias list
		if ( [ 'cli', 'aliases' ] === array_slice( $args, 0, 2 ) ) {
			list( $args[0], $args[1], $args[2] ) = [ 'cli', 'alias', 'list' ];
		}

		// core (multsite-)install --admin_name=  ->  --admin_user=
		if ( count( $args ) > 0 && 'core' === $args[0] && isset( $assoc_args['admin_name'] ) ) {
			$assoc_args['admin_user'] = $assoc_args['admin_name'];
			unset( $assoc_args['admin_name'] );
		}

		// core config  ->  config create
		if ( [ 'core', 'config' ] === array_slice( $args, 0, 2 ) ) {
			list( $args[0], $args[1] ) = [ 'config', 'create' ];
		}
		// core language  ->  language core
		if ( [ 'core', 'language' ] === array_slice( $args, 0, 2 ) ) {
			list( $args[0], $args[1] ) = [ 'language', 'core' ];
		}

		// checksum core  ->  core verify-checksums
		if ( [ 'checksum', 'core' ] === array_slice( $args, 0, 2 ) ) {
			list( $args[0], $args[1] ) = [ 'core', 'verify-checksums' ];
		}

		// checksum plugin  ->  plugin verify-checksums
		if ( [ 'checksum', 'plugin' ] === array_slice( $args, 0, 2 ) ) {
			list( $args[0], $args[1] ) = [ 'plugin', 'verify-checksums' ];
		}

		// site create --site_id=  ->  site create --network_id=
		if ( count( $args ) >= 2 && 'site' === $args[0] && 'create' === $args[1] && isset( $assoc_args['site_id'] ) ) {
			$assoc_args['network_id'] = $assoc_args['site_id'];
			unset( $assoc_args['site_id'] );
		}

		// {plugin|theme} update-all  ->  {plugin|theme} update --all
		if ( count( $args ) > 1 && in_array( $args[0], [ 'plugin', 'theme' ], true )
			&& 'update-all' === $args[1]
		) {
			$args[1]           = 'update';
			$assoc_args['all'] = true;
		}

		// transient delete-expired  ->  transient delete --expired
		if ( count( $args ) > 1 && 'transient' === $args[0] && 'delete-expired' === $args[1] ) {
			$args[1]               = 'delete';
			$assoc_args['expired'] = true;
		}

		// transient delete-all  ->  transient delete --all
		if ( count( $args ) > 1 && 'transient' === $args[0] && 'delete-all' === $args[1] ) {
			$args[1]           = 'delete';
			$assoc_args['all'] = true;
		}

		// plugin scaffold  ->  scaffold plugin
		if ( [ 'plugin', 'scaffold' ] === array_slice( $args, 0, 2 ) ) {
			list( $args[0], $args[1] ) = [ $args[1], $args[0] ];
		}

		// foo --help  ->  help foo
		if ( isset( $assoc_args['help'] ) ) {
			array_unshift( $args, 'help' );
			unset( $assoc_args['help'] );
		}

		// {post|user} list --ids  ->  {post|user} list --format=ids
		if ( count( $args ) > 1 && in_array( $args[0], [ 'post', 'user' ], true )
			&& 'list' === $args[1]
			&& isset( $assoc_args['ids'] )
		) {
			$assoc_args['format'] = 'ids';
			unset( $assoc_args['ids'] );
		}

		// --json  ->  --format=json
		if ( isset( $assoc_args['json'] ) ) {
			$assoc_args['format'] = 'json';
			unset( $assoc_args['json'] );
		}

		// --{version|info}  ->  cli {version|info}
		if ( empty( $args ) ) {
			$special_flags = [ 'version', 'info' ];
			foreach ( $special_flags as $key ) {
				if ( isset( $assoc_args[ $key ] ) ) {
					$args = [ 'cli', $key ];
					unset( $assoc_args[ $key ] );
					break;
				}
			}
		}

		// (post|comment|site|term) url  --> (post|comment|site|term) list --*__in --field=url
		if ( count( $args ) >= 2 && in_array( $args[0], [ 'post', 'comment', 'site', 'term' ], true ) && 'url' === $args[1] ) {
			switch ( $args[0] ) {
				case 'post':
					$post_ids                = array_slice( $args, 2 );
					$args                    = [ 'post', 'list' ];
					$assoc_args['post__in']  = implode( ',', $post_ids );
					$assoc_args['post_type'] = 'any';
					$assoc_args['orderby']   = 'post__in';
					$assoc_args['field']     = 'url';
					break;
				case 'comment':
					$comment_ids               = array_slice( $args, 2 );
					$args                      = [ 'comment', 'list' ];
					$assoc_args['comment__in'] = implode( ',', $comment_ids );
					$assoc_args['orderby']     = 'comment__in';
					$assoc_args['field']       = 'url';
					break;
				case 'site':
					$site_ids               = array_slice( $args, 2 );
					$args                   = [ 'site', 'list' ];
					$assoc_args['site__in'] = implode( ',', $site_ids );
					$assoc_args['field']    = 'url';
					break;
				case 'term':
					$taxonomy = '';
					if ( isset( $args[2] ) ) {
						$taxonomy = $args[2];
					}
					$term_ids              = array_slice( $args, 3 );
					$args                  = [ 'term', 'list', $taxonomy ];
					$assoc_args['include'] = implode( ',', $term_ids );
					$assoc_args['orderby'] = 'include';
					$assoc_args['field']   = 'url';
					break;
			}
		}

		// config get --[global|constant]=<global|constant> --> config get <name> --type=constant|variable
		// config get --> config list
		if ( count( $args ) === 2
			&& 'config' === $args[0]
			&& 'get' === $args[1] ) {
			if ( isset( $assoc_args['global'] ) ) {
				$name = $assoc_args['global'];
				$type = 'variable';
				unset( $assoc_args['global'] );
			} elseif ( isset( $assoc_args['constant'] ) ) {
				$name = $assoc_args['constant'];
				$type = 'constant';
				unset( $assoc_args['constant'] );
			}
			if ( ! empty( $name ) && ! empty( $type ) ) {
				$args[]             = $name;
				$assoc_args['type'] = $type;
			} else {
				// We had a 'config get' without a '<name>', so assume 'list' was wanted.
				$args[1] = 'list';
			}
		}

		return [ $args, $assoc_args ];
	}

	/**
	 * Whether or not the output should be rendered in color
	 *
	 * @return bool
	 */
	public function in_color() {
		return $this->colorize;
	}

	public function init_colorization() {
		if ( 'auto' === $this->config['color'] ) {
			$this->colorize = ( ! Utils\isPiped() && ! Utils\is_windows() );
		} else {
			$this->colorize = $this->config['color'];
		}
	}

	public function init_logger() {
		if ( $this->config['quiet'] ) {
			$logger = new Loggers\Quiet( $this->in_color() );
		} else {
			$logger = new Loggers\Regular( $this->in_color() );
		}

		WP_CLI::set_logger( $logger );
	}

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

	/**
	 * Do WordPress core files exist?
	 *
	 * @return bool
	 */
	private function wp_exists() {
		return file_exists( ABSPATH . 'wp-includes/version.php' );
	}

	/**
	 * Are WordPress core files readable?
	 *
	 * @return bool
	 */
	private function wp_is_readable() {
		return is_readable( ABSPATH . 'wp-includes/version.php' );
	}

	private function check_wp_version() {
		$wp_exists      = $this->wp_exists();
		$wp_is_readable = $this->wp_is_readable();
		if ( ! $wp_exists || ! $wp_is_readable ) {
			$this->show_synopsis_if_composite_command();
			// If the command doesn't exist use as error.
			$args                   = $this->cmd_starts_with( [ 'help' ] ) ? array_slice( $this->arguments, 1 ) : $this->arguments;
			$suggestion_or_disabled = $this->find_command_to_run( $args );
			if ( is_string( $suggestion_or_disabled ) ) {
				if ( ! preg_match( '/disabled from the config file.$/', $suggestion_or_disabled ) ) {
					WP_CLI::warning( "No WordPress installation found. If the command '" . implode( ' ', $args ) . "' is in a plugin or theme, pass --path=`path/to/wordpress`." );
				}
				WP_CLI::error( $suggestion_or_disabled );
			}

			if ( $wp_exists && ! $wp_is_readable ) {
				WP_CLI::error(
					'It seems, the WordPress core files do not have the proper file permissions.'
				);
			}
			WP_CLI::error(
				"This does not seem to be a WordPress installation.\n" .
				'The used path is: ' . ABSPATH . "\n" .
				'Pass --path=`path/to/wordpress` or run `wp core download`.'
			);
		}

		global $wp_version;
		include ABSPATH . 'wp-includes/version.php';

		$minimum_version = '3.7';

		if ( version_compare( $wp_version, $minimum_version, '<' ) ) {
			WP_CLI::error(
				"WP-CLI needs WordPress $minimum_version or later to work properly. " .
				"The version currently installed is $wp_version.\n" .
				'Try running `wp core download --force`.'
			);
		}
	}

	public function init_config() {
		$configurator = WP_CLI::get_configurator();

		$argv = array_slice( $GLOBALS['argv'], 1 );

		$this->alias = null;
		if ( ! empty( $argv[0] ) && preg_match( '#' . Configurator::ALIAS_REGEX . '#', $argv[0], $matches ) ) {
			$this->alias = array_shift( $argv );
		}

		// File config
		{
			$this->global_config_path  = $this->get_global_config_path();
			$this->project_config_path = $this->get_project_config_path();

			$configurator->merge_yml( $this->global_config_path, $this->alias );
			$config                         = $configurator->to_array();
			$this->required_files['global'] = $config[0]['require'];
			$configurator->merge_yml( $this->project_config_path, $this->alias );
			$config                          = $configurator->to_array();
			$this->required_files['project'] = $config[0]['require'];
		}

		// Runtime config and args
		{
			list( $args, $assoc_args, $this->runtime_config ) = $configurator->parse_args( $argv );

			list( $this->arguments, $this->assoc_args ) = self::back_compat_conversions(
				$args,
				$assoc_args
			);

			$configurator->merge_array( $this->runtime_config );
		}

		list( $this->config, $this->extra_config ) = $configurator->to_array();
		$this->aliases                             = $configurator->get_aliases();
		if ( count( $this->aliases ) && ! isset( $this->aliases['@all'] ) ) {
			$this->aliases         = array_reverse( $this->aliases );
			$this->aliases['@all'] = 'Run command against every registered alias.';
			$this->aliases         = array_reverse( $this->aliases );
		}
		$this->required_files['runtime'] = $this->config['require'];
	}

	private function run_alias_group( $aliases ) {
		Utils\check_proc_available( 'group alias' );

		$php_bin = escapeshellarg( Utils\get_php_binary() );

		$script_path = $GLOBALS['argv'][0];

		if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) {
			$config_path = getenv( 'WP_CLI_CONFIG_PATH' );
		} else {
			$config_path = Utils\get_home_dir() . '/.wp-cli/config.yml';
		}
		$config_path = escapeshellarg( $config_path );

		foreach ( $aliases as $alias ) {
			WP_CLI::log( $alias );
			$args           = implode( ' ', array_map( 'escapeshellarg', $this->arguments ) );
			$assoc_args     = Utils\assoc_args_to_str( $this->assoc_args );
			$runtime_config = Utils\assoc_args_to_str( $this->runtime_config );
			$full_command   = "WP_CLI_CONFIG_PATH={$config_path} {$php_bin} {$script_path} {$alias} {$args}{$assoc_args}{$runtime_config}";
			$pipes          = [];
			$proc           = Utils\proc_open_compat( $full_command, [ STDIN, STDOUT, STDERR ], $pipes );
			proc_close( $proc );
		}
	}

	private function set_alias( $alias ) {
		$orig_config  = $this->config;
		$alias_config = $this->aliases[ $alias ];
		$this->config = array_merge( $orig_config, $alias_config );
		foreach ( $alias_config as $key => $_ ) {
			if ( isset( $orig_config[ $key ] ) && ! is_null( $orig_config[ $key ] ) ) {
				$this->assoc_args[ $key ] = $orig_config[ $key ];
			}
		}
	}

	public function start() {
		// Enable PHP error reporting to stderr if testing. Will need to be re-enabled after WP loads.
		if ( getenv( 'BEHAT_RUN' ) ) {
			$this->enable_error_reporting();
		}

		WP_CLI::debug( $this->global_config_path_debug, 'bootstrap' );
		WP_CLI::debug( $this->project_config_path_debug, 'bootstrap' );
		WP_CLI::debug( 'argv: ' . implode( ' ', $GLOBALS['argv'] ), 'bootstrap' );

		if ( $this->alias ) {
			if ( '@all' === $this->alias && ! isset( $this->aliases['@all'] ) ) {
				WP_CLI::error( "Cannot use '@all' when no aliases are registered." );
			}

			if ( '@all' === $this->alias && is_string( $this->aliases['@all'] ) ) {
				$aliases = array_keys( $this->aliases );
				$k       = array_search( '@all', $aliases, true );
				unset( $aliases[ $k ] );
				$this->run_alias_group( $aliases );
				exit;
			}

			if ( ! array_key_exists( $this->alias, $this->aliases ) ) {
				$error_msg  = "Alias '{$this->alias}' not found.";
				$suggestion = Utils\get_suggestion( $this->alias, array_keys( $this->aliases ), $threshold = 2 );
				if ( $suggestion ) {
					$error_msg .= PHP_EOL . "Did you mean '{$suggestion}'?";
				}
				WP_CLI::error( $error_msg );
			}
			// Numerically indexed means a group of aliases
			if ( isset( $this->aliases[ $this->alias ][0] ) ) {
				$group_aliases = $this->aliases[ $this->alias ];
				$all_aliases   = array_keys( $this->aliases );
				$diff          = array_diff( $group_aliases, $all_aliases );
				if ( ! empty( $diff ) ) {
					WP_CLI::error( "Group '{$this->alias}' contains one or more invalid aliases: " . implode( ', ', $diff ) );
				}
				$this->run_alias_group( $group_aliases );
				exit;
			}

			$this->set_alias( $this->alias );
		}

		if ( empty( $this->arguments ) ) {
			$this->arguments[] = 'help';
		}

		// Protect 'cli info' from most of the runtime,
		// except when the command will be run over SSH
		if ( 'cli' === $this->arguments[0] && ! empty( $this->arguments[1] ) && 'info' === $this->arguments[1] && ! $this->config['ssh'] ) {
			$this->run_command_and_exit();
		}

		if ( isset( $this->config['http'] ) && ! class_exists( '\WP_REST_CLI\Runner' ) ) {
			WP_CLI::error( "RESTful WP-CLI needs to be installed. Try 'wp package install wp-cli/restful'." );
		}

		if ( $this->config['ssh'] ) {
			$this->run_ssh_command( $this->config['ssh'] );
			return;
		}

		// Handle --path parameter
		self::set_wp_root( $this->find_wp_root() );

		// First try at showing man page - if help command and either haven't found 'version.php' or 'wp-config.php' (so won't be loading WP & adding commands) or help on subcommand.
		if ( $this->cmd_starts_with( [ 'help' ] )
			&& ( ! $this->wp_exists()
				|| ! Utils\locate_wp_config()
				|| count( $this->arguments ) > 2
			) ) {
			$this->auto_check_update();
			$this->run_command( $this->arguments, $this->assoc_args );
			// Help didn't exit so failed to find the command at this stage.
		}

		// Handle --url parameter
		$url = self::guess_url( $this->config );
		if ( $url ) {
			WP_CLI::set_url( $url );
		}

		$this->do_early_invoke( 'before_wp_load' );

		$this->check_wp_version();

		if ( $this->cmd_starts_with( [ 'config', 'create' ] ) ) {
			$this->run_command_and_exit();
		}

		if ( ! Utils\locate_wp_config() ) {
			WP_CLI::error(
				"'wp-config.php' not found.\n" .
				'Either create one manually or use `wp config create`.'
			);
		}

		/*
		 * Set the MySQLi error reporting off because WordPress handles its own.
		 * This is due to the default value change from `MYSQLI_REPORT_OFF`
		 * to `MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT` in PHP 8.1.
		 */
		if ( function_exists( 'mysqli_report' ) ) {
			mysqli_report( 0 ); // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_report
		}

		// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Declaring WP native constants.

		if ( $this->cmd_starts_with( [ 'core', 'is-installed' ] )
			|| $this->cmd_starts_with( [ 'core', 'update-db' ] ) ) {
			define( 'WP_INSTALLING', true );
		}

		if (
			count( $this->arguments ) >= 2 &&
			'core' === $this->arguments[0] &&
			in_array( $this->arguments[1], [ 'install', 'multisite-install' ], true )
		) {
			define( 'WP_INSTALLING', true );

			// We really need a URL here
			if ( ! isset( $_SERVER['HTTP_HOST'] ) ) {
				$url = 'https://example.com';
				WP_CLI::set_url( $url );
			}

			if ( 'multisite-install' === $this->arguments[1] ) {
				// need to fake some globals to skip the checks in wp-includes/ms-settings.php
				$url_parts = Utils\parse_url( $url );
				self::fake_current_site_blog( $url_parts );

				if ( ! defined( 'COOKIEHASH' ) ) {
					define( 'COOKIEHASH', md5( $url_parts['host'] ) );
				}
			}
		}

		if ( $this->cmd_starts_with( [ 'import' ] ) ) {
			define( 'WP_LOAD_IMPORTERS', true );
			define( 'WP_IMPORTING', true );
		}

		if ( $this->cmd_starts_with( [ 'cron', 'event', 'run' ] ) ) {
			define( 'DOING_CRON', true );
		}
		// phpcs:enable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound

		$this->load_wordpress();

		$this->run_command_and_exit();
	}

	/**
	 * Load WordPress, if it hasn't already been loaded
	 */
	public function load_wordpress() {
		static $wp_cli_is_loaded;
		// Globals not explicitly globalized in WordPress
		global $site_id, $wpdb, $public, $current_site, $current_blog, $path, $shortcode_tags;

		if ( ! empty( $wp_cli_is_loaded ) ) {
			return;
		}

		$wp_cli_is_loaded = true;

		// Handle --context flag.
		$this->context_manager->switch_context( $this->config );

		WP_CLI::debug( 'Begin WordPress load', 'bootstrap' );
		WP_CLI::do_hook( 'before_wp_load' );

		$this->check_wp_version();

		$wp_config_path = Utils\locate_wp_config();
		if ( ! $wp_config_path ) {
			WP_CLI::error(
				"'wp-config.php' not found.\n" .
				'Either create one manually or use `wp config create`.'
			);
		}

		WP_CLI::debug( 'wp-config.php path: ' . $wp_config_path, 'bootstrap' );
		WP_CLI::do_hook( 'before_wp_config_load' );

		// Load wp-config.php code, in the global scope
		$wp_cli_original_defined_vars = get_defined_vars();

		eval( $this->get_wp_config_code() ); // phpcs:ignore Squiz.PHP.Eval.Discouraged

		foreach ( get_defined_vars() as $key => $var ) {
			if ( array_key_exists( $key, $wp_cli_original_defined_vars ) || 'wp_cli_original_defined_vars' === $key ) {
				continue;
			}

			// phpcs:ignore PHPCompatibility.Variables.ForbiddenGlobalVariableVariable.NonBareVariableFound
			global ${$key};
			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
			${$key} = $var;
		}

		$this->maybe_update_url_from_domain_constant();
		WP_CLI::do_hook( 'after_wp_config_load' );
		$this->do_early_invoke( 'after_wp_config_load' );

		// Prevent error notice from wp_guess_url() when core isn't installed
		if ( $this->cmd_starts_with( [ 'core', 'is-installed' ] )
			&& ! defined( 'COOKIEHASH' ) ) {
			define( 'COOKIEHASH', md5( 'wp-cli' ) );
		}

		// Load WP-CLI utilities
		require WP_CLI_ROOT . '/php/utils-wp.php';

		// Set up WordPress bootstrap actions and filters
		$this->setup_bootstrap_hooks();

		// Load Core, mu-plugins, plugins, themes etc.
		if ( Utils\wp_version_compare( '4.6-alpha-37575', '>=' ) ) {
			if ( $this->cmd_starts_with( [ 'help' ] ) ) {
				// Hack: define `WP_DEBUG` and `WP_DEBUG_DISPLAY` to get `wpdb::bail()` to `wp_die()`.
				if ( ! defined( 'WP_DEBUG' ) ) {
					define( 'WP_DEBUG', true );
				}
				if ( ! defined( 'WP_DEBUG_DISPLAY' ) ) {
					define( 'WP_DEBUG_DISPLAY', true );
				}
			}
			require ABSPATH . 'wp-settings.php';
		} else {
			require WP_CLI_ROOT . '/php/wp-settings-cli.php';
		}

		// Fix memory limit. See https://core.trac.wordpress.org/ticket/14889
		// phpcs:ignore WordPress.PHP.IniSet.memory_limit_Disallowed -- This is perfectly fine for CLI usage.
		ini_set( 'memory_limit', -1 );

		// Load all the admin APIs, for convenience
		require ABSPATH . 'wp-admin/includes/admin.php';

		add_filter(
			'filesystem_method',
			static function () {
				return 'direct';
			},
			99
		);

		// Re-enable PHP error reporting to stderr if testing.
		if ( getenv( 'BEHAT_RUN' ) ) {
			$this->enable_error_reporting();
		}

		WP_CLI::debug( 'Loaded WordPress', 'bootstrap' );
		WP_CLI::do_hook( 'after_wp_load' );
	}

	private static function fake_current_site_blog( $url_parts ) {
		global $current_site, $current_blog;

		if ( ! isset( $url_parts['path'] ) ) {
			$url_parts['path'] = '/';
		}

		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Intentional override.
		$current_site = (object) [
			'id'            => 1,
			'blog_id'       => 1,
			'domain'        => $url_parts['host'],
			'path'          => $url_parts['path'],
			'cookie_domain' => $url_parts['host'],
			'site_name'     => 'WordPress',
		];

		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Intentional override.
		$current_blog = (object) [
			'blog_id'  => 1,
			'site_id'  => 1,
			'domain'   => $url_parts['host'],
			'path'     => $url_parts['path'],
			'public'   => '1',
			'archived' => '0',
			'mature'   => '0',
			'spam'     => '0',
			'deleted'  => '0',
			'lang_id'  => '0',
		];
	}

	/**
	 * Called after wp-config.php is eval'd, to potentially reset `--url`
	 */
	private function maybe_update_url_from_domain_constant() {
		if ( ! empty( $this->config['url'] ) || ! empty( $this->config['blog'] ) ) {
			return;
		}

		if ( defined( 'DOMAIN_CURRENT_SITE' ) ) {
			$url = DOMAIN_CURRENT_SITE;
			if ( defined( 'PATH_CURRENT_SITE' ) ) {
				$url .= PATH_CURRENT_SITE;
			}
			WP_CLI::set_url( $url );
		}
	}

	/**
	 * Set up hooks meant to run during the WordPress bootstrap process
	 */
	private function setup_bootstrap_hooks() {

		if ( $this->config['skip-plugins'] ) {
			$this->setup_skip_plugins_filters();
		}

		if ( $this->config['skip-themes'] ) {
			WP_CLI::add_wp_hook( 'setup_theme', [ $this, 'action_setup_theme_wp_cli_skip_themes' ], 999 );
		}

		if ( $this->cmd_starts_with( [ 'help' ] ) ) {
			// Try to trap errors on help.
			$help_handler = [ $this, 'help_wp_die_handler' ]; // Avoid any cross PHP version issues by not using $this in anon function.
			WP_CLI::add_wp_hook(
				'wp_die_handler',
				function () use ( $help_handler ) {
					return $help_handler;
				}
			);
		} else {
			WP_CLI::add_wp_hook(
				'wp_die_handler',
				static function () {
					return '\WP_CLI\Utils\wp_die_handler';
				}
			);
		}

		// Prevent code from performing a redirect
		WP_CLI::add_wp_hook( 'wp_redirect', 'WP_CLI\\Utils\\wp_redirect_handler' );

		WP_CLI::add_wp_hook(
			'nocache_headers',
			static function ( $headers ) {
				// WordPress might be calling nocache_headers() because of a dead db
				global $wpdb;
				if ( ! empty( $wpdb->error ) ) {
					Utils\wp_die_handler( $wpdb->error );
				}
				// Otherwise, WP might be calling nocache_headers() because WP isn't installed
				Utils\wp_not_installed();
				return $headers;
			}
		);

		WP_CLI::add_wp_hook(
			'setup_theme',
			static function () {
				// Polyfill is_customize_preview(), as it is needed by TwentyTwenty to
				// check for starter content.
				if ( ! function_exists( 'is_customize_preview' ) ) {
					function is_customize_preview() {
						return false;
					}
				}
			},
			0
		);

		// ALTERNATE_WP_CRON might trigger a redirect, which we can't handle
		if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
			WP_CLI::add_wp_hook(
				'muplugins_loaded',
				static function () {
					remove_action( 'init', 'wp_cron' );
				}
			);
		}

		// Get rid of warnings when converting single site to multisite
		if ( defined( 'WP_INSTALLING' ) && $this->is_multisite() ) {
			$values = [
				'ms_files_rewriting'             => null,
				'active_sitewide_plugins'        => [],
				'_site_transient_update_core'    => null,
				'_site_transient_update_themes'  => null,
				'_site_transient_update_plugins' => null,
				'WPLANG'                         => '',
			];
			foreach ( $values as $key => $value ) {
				WP_CLI::add_wp_hook(
					"pre_site_option_$key",
					static function () use ( $values, $key ) {
						return $values[ $key ];
					}
				);
			}
		}

		// Always permit operations against sites, regardless of status
		WP_CLI::add_wp_hook( 'ms_site_check', '__return_true' );

		// Always permit operations against WordPress, regardless of maintenance mode
		WP_CLI::add_wp_hook(
			'enable_maintenance_mode',
			static function () {
				return false;
			}
		);

		// Use our own debug mode handling instead of WP core
		WP_CLI::add_wp_hook(
			'enable_wp_debug_mode_checks',
			static function ( $ret ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- WP core hook.
				Utils\wp_debug_mode();
				return false;
			}
		);

		// Never load advanced-cache.php drop-in when WP-CLI is operating
		WP_CLI::add_wp_hook(
			'enable_loading_advanced_cache_dropin',
			static function () {
				return false;
			}
		);

		// In a multisite installation, die if unable to find site given in --url parameter
		if ( $this->is_multisite() ) {
			$run_on_site_not_found = false;
			if ( $this->cmd_starts_with( [ 'cache', 'flush' ] ) ) {
				$run_on_site_not_found = 'cache flush';
			}
			if ( $this->cmd_starts_with( [ 'search-replace' ] ) ) {
				// Table-specified
				// Bits: search-replace <search> <replace> [<table>...]
				// Or not against a specific blog
				if ( count( $this->arguments ) > 3
					|| ! empty( $this->assoc_args['network'] )
					|| ! empty( $this->assoc_args['all-tables'] )
					|| ! empty( $this->assoc_args['all-tables-with-prefix'] ) ) {
					$run_on_site_not_found = 'search-replace';
				}
			}
			if ( $run_on_site_not_found
				&& Utils\wp_version_compare( '4.0', '>=' ) ) {
				WP_CLI::add_wp_hook(
					'ms_site_not_found',
					static function () use ( $run_on_site_not_found ) {
						// esc_sql() isn't yet loaded, but needed.
						if ( 'search-replace' === $run_on_site_not_found ) {
							require_once ABSPATH . WPINC . '/formatting.php';
						}
						// PHP 5.3 compatible implementation of run_command_and_exit().
						$runner = WP_CLI::get_runner();
						$runner->run_command( $runner->arguments, $runner->assoc_args );
						exit;
					},
					1
				);
			}
			WP_CLI::add_wp_hook(
				'ms_site_not_found',
				static function ( $current_site, $domain, $path ) {
					$url         = $domain . $path;
					$message     = $url ? "Site '{$url}' not found." : 'Site not found.';
					$has_param   = isset( WP_CLI::get_runner()->config['url'] );
					$has_const   = defined( 'DOMAIN_CURRENT_SITE' );
					$explanation = '';
					if ( $has_param ) {
						$explanation = 'Verify `--url=<url>` matches an existing site.';
					} else {
						$explanation = "Define DOMAIN_CURRENT_SITE in 'wp-config.php' or use `--url=<url>` to override.";

						if ( $has_const ) {
							$explanation = 'Verify DOMAIN_CURRENT_SITE matches an existing site or use `--url=<url>` to override.';
						}
					}
					$message .= ' ' . $explanation;
					WP_CLI::error( $message );
				},
				10,
				3
			);
		}

		// The APC cache is not available on the command-line, so bail, to prevent cache poisoning
		WP_CLI::add_wp_hook(
			'muplugins_loaded',
			static function () {
				if ( $GLOBALS['_wp_using_ext_object_cache'] && class_exists( 'APC_Object_Cache' ) ) {
					WP_CLI::warning( 'Running WP-CLI while the APC object cache is activated can result in cache corruption.' );
					WP_CLI::confirm( 'Given the consequences, do you wish to continue?' );
				}
			},
			0
		);

		// Handle --user parameter
		if ( ! defined( 'WP_INSTALLING' ) ) {
			$config = $this->config;
			WP_CLI::add_wp_hook(
				'init',
				static function () use ( $config ) {
					if ( isset( $config['user'] ) ) {
						$fetcher = new Fetchers\User();
						$user    = $fetcher->get_check( $config['user'] );
						wp_set_current_user( $user->ID );
					} else {
						add_action( 'init', 'kses_remove_filters', 11 );
					}
				},
				0
			);
		}

		// Avoid uncaught exception when using wp_mail() without defined $_SERVER['SERVER_NAME']
		WP_CLI::add_wp_hook(
			'wp_mail_from',
			static function ( $from_email ) {
				if ( 'wordpress@' === $from_email ) {
					$sitename = strtolower( Utils\parse_url( site_url(), PHP_URL_HOST ) );
					if ( substr( $sitename, 0, 4 ) === 'www.' ) {
						$sitename = substr( $sitename, 4 );
					}
					$from_email = 'wordpress@' . $sitename;
				}
				return $from_email;
			}
		);

		// Don't apply set_url_scheme in get_home_url() or get_site_url().
		WP_CLI::add_wp_hook(
			'home_url',
			static function ( $url, $path, $scheme, $blog_id ) {
				if ( empty( $blog_id ) || ! is_multisite() ) {
					$url = get_option( 'home' );
				} else {
					switch_to_blog( $blog_id );
					$url = get_option( 'home' );
					restore_current_blog();
				}

				if ( $path && is_string( $path ) ) {
					$url .= '/' . ltrim( $path, '/' );
				}

				return $url;
			},
			0,
			4
		);
		WP_CLI::add_wp_hook(
			'site_url',
			static function ( $url, $path, $scheme, $blog_id ) {
				if ( empty( $blog_id ) || ! is_multisite() ) {
					$url = get_option( 'siteurl' );
				} else {
					switch_to_blog( $blog_id );
					$url = get_option( 'siteurl' );
					restore_current_blog();
				}

				if ( $path && is_string( $path ) ) {
					$url .= '/' . ltrim( $path, '/' );
				}

				return $url;
			},
			0,
			4
		);

		// Set up hook for plugins and themes to conditionally add WP-CLI commands.
		WP_CLI::add_wp_hook(
			'init',
			static function () {
				do_action( 'cli_init' );
			}
		);
	}

	/**
	 * Set up the filters to skip the loaded plugins
	 */
	private function setup_skip_plugins_filters() {
		$wp_cli_filter_active_plugins = static function ( $plugins ) {
			$skipped_plugins = WP_CLI::get_runner()->config['skip-plugins'];
			if ( true === $skipped_plugins ) {
				return [];
			}
			if ( ! is_array( $plugins ) ) {
				return $plugins;
			}
			foreach ( $plugins as $a => $b ) {
				// active_sitewide_plugins stores plugin name as the key.
				if ( false !== strpos( current_filter(), 'active_sitewide_plugins' ) && Utils\is_plugin_skipped( $a ) ) {
					unset( $plugins[ $a ] );
					// active_plugins stores plugin name as the value.
				} elseif ( false !== strpos( current_filter(), 'active_plugins' ) && Utils\is_plugin_skipped( $b ) ) {
					unset( $plugins[ $a ] );
				}
			}
			// Reindex because active_plugins expects a numeric index.
			if ( false !== strpos( current_filter(), 'active_plugins' ) ) {
				$plugins = array_values( $plugins );
			}
			return $plugins;
		};

		$hooks = [
			'pre_site_option_active_sitewide_plugins',
			'site_option_active_sitewide_plugins',
			'pre_option_active_plugins',
			'option_active_plugins',
		];
		foreach ( $hooks as $hook ) {
			WP_CLI::add_wp_hook( $hook, $wp_cli_filter_active_plugins, 999 );
		}
		WP_CLI::add_wp_hook(
			'plugins_loaded',
			static function () use ( $hooks, $wp_cli_filter_active_plugins ) {
				foreach ( $hooks as $hook ) {
					remove_filter( $hook, $wp_cli_filter_active_plugins, 999 );
				}
			},
			0
		);
	}

	/**
	 * Set up the filters to skip the loaded theme
	 */
	public function action_setup_theme_wp_cli_skip_themes() {
		$wp_cli_filter_active_theme = static function ( $value ) {
			$skipped_themes = WP_CLI::get_runner()->config['skip-themes'];
			if ( true === $skipped_themes ) {
				return '';
			}
			if ( ! is_array( $skipped_themes ) ) {
				$skipped_themes = explode( ',', $skipped_themes );
			}

			$checked_value = $value;
			// Always check against the stylesheet value
			// This ensures a child theme can be skipped when template differs
			if ( false !== stripos( current_filter(), 'option_template' ) ) {
				$checked_value = get_option( 'stylesheet' );
			}

			if ( '' === $checked_value || in_array( $checked_value, $skipped_themes, true ) ) {
				return '';
			}
			return $value;
		};
		$hooks                      = [
			'pre_option_template',
			'option_template',
			'pre_option_stylesheet',
			'option_stylesheet',
		];
		foreach ( $hooks as $hook ) {
			add_filter( $hook, $wp_cli_filter_active_theme, 999 );
		}

		// Noop memoization added in WP 6.4.
		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- WordPress core global.
		$GLOBALS['wp_stylesheet_path'] = null;
		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- WordPress core global.
		$GLOBALS['wp_template_path'] = null;

		// Remove theme-related actions not directly tied into the theme lifecycle.
		if ( WP_CLI::get_runner()->config['skip-themes'] ) {
			$theme_related_actions = [
				[ 'init', '_register_theme_block_patterns' ],          // Block patterns registration in WP Core.
				[ 'init', 'gutenberg_register_theme_block_patterns' ], // Block patterns registration in the GB plugin.
			];
			foreach ( $theme_related_actions as $action ) {
				list( $hook, $callback ) = $action;
				remove_action( $hook, $callback );
			}
		}

		// Clean up after the TEMPLATEPATH and STYLESHEETPATH constants are defined
		WP_CLI::add_wp_hook(
			'after_setup_theme',
			static function () use ( $hooks, $wp_cli_filter_active_theme ) {
				foreach ( $hooks as $hook ) {
					remove_filter( $hook, $wp_cli_filter_active_theme, 999 );
				}
				// Noop memoization added in WP 6.4 again.
				// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- WordPress core global.
				$GLOBALS['wp_stylesheet_path'] = null;
				// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- WordPress core global.
				$GLOBALS['wp_template_path'] = null;
			},
			0
		);
	}

	/**
	 * Whether or not this WordPress installation is multisite.
	 *
	 * For use after wp-config.php has loaded, but before the rest of WordPress
	 * is loaded.
	 */
	private function is_multisite() {
		if ( defined( 'MULTISITE' ) ) {
			return MULTISITE;
		}

		if ( defined( 'SUBDOMAIN_INSTALL' ) || defined( 'VHOST' ) || defined( 'SUNRISE' ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Error handler for `wp_die()` when the command is help to try to trap errors (db connection failure in particular) during WordPress load.
	 */
	public function help_wp_die_handler( $message ) {
		$help_exit_warning = 'Error during WordPress load.';
		if ( $message instanceof WP_Error ) {
			$help_exit_warning = Utils\wp_clean_error_message( $message->get_error_message() );
		} elseif ( is_string( $message ) ) {
			$help_exit_warning = Utils\wp_clean_error_message( $message );
		}
		$this->run_command_and_exit( $help_exit_warning );
	}

	/**
	 * Check whether there's a WP-CLI update available, and suggest update if so.
	 */
	private function auto_check_update() {

		// `wp cli update` only works with Phars at this time.
		if ( ! Utils\inside_phar() ) {
			return;
		}

		$existing_phar = realpath( $_SERVER['argv'][0] );
		// Phar needs to be writable to be easily updateable.
		if ( ! is_writable( $existing_phar ) || ! is_writable( dirname( $existing_phar ) ) ) {
			return;
		}

		// Only check for update when a human is operating.
		if ( ! function_exists( 'posix_isatty' ) || ! posix_isatty( STDOUT ) ) {
			return;
		}

		// Allow hosts and other providers to disable automatic check update.
		if ( getenv( 'WP_CLI_DISABLE_AUTO_CHECK_UPDATE' ) ) {
			return;
		}

		// Permit configuration of number of days between checks.
		$days_between_checks = getenv( 'WP_CLI_AUTO_CHECK_UPDATE_DAYS' );
		if ( false === $days_between_checks ) {
			$days_between_checks = 1;
		}

		$cache     = WP_CLI::get_cache();
		$cache_key = 'wp-cli-update-check';
		// Bail early on the first check, so we don't always check on an unwritable cache.
		if ( ! $cache->has( $cache_key ) ) {
			$cache->write( $cache_key, time() );
			return;
		}

		// Bail if last check is still within our update check time period.
		$last_check = (int) $cache->read( $cache_key );
		if ( ( time() - ( 24 * 60 * 60 * $days_between_checks ) ) < $last_check ) {
			return;
		}

		// In case the operation fails, ensure the timestamp has been updated.
		$cache->write( $cache_key, time() );

		// Check whether any updates are available.
		ob_start();
		WP_CLI::run_command(
			[ 'cli', 'check-update' ],
			[
				'format' => 'count',
			]
		);
		$count = ob_get_clean();
		if ( ! $count ) {
			return;
		}

		// Looks like an update is available, so let's prompt to update.
		WP_CLI::run_command( [ 'cli', 'update' ] );
		// If the Phar was replaced, we can't proceed with the original process.
		exit;
	}

	/**
	 * Get a suggestion on similar (sub)commands when the user entered an
	 * unknown (sub)command.
	 *
	 * @param string                $entry        User entry that didn't match an
	 *                                            existing command.
	 * @param CompositeCommand|null $root_command Root command to start search for
	 *                                            suggestions at.
	 *
	 * @return string Suggestion that fits the user entry, or an empty string.
	 */
	private function get_subcommand_suggestion( $entry, $root_command = null ) {
		$commands = [];
		if ( ( $root_command instanceof CompositeCommand ) === false ) {
			$root_command = WP_CLI::get_root_command();
		}
		$this->enumerate_commands( $root_command, $commands );

		return Utils\get_suggestion( $entry, $commands, $threshold = 2 );
	}

	/**
	 * Recursive method to enumerate all known commands.
	 *
	 * @param CompositeCommand $command Composite command to recurse over.
	 * @param array            $list    Reference to list accumulating results.
	 * @param string           $parent  Parent command to use as prefix.
	 */
	private function enumerate_commands( CompositeCommand $command, array &$list, $parent = '' ) {
		foreach ( $command->get_subcommands() as $subcommand ) {
			/** @var CompositeCommand $subcommand */
			$command_string = empty( $parent )
				? $subcommand->get_name()
				: "{$parent} {$subcommand->get_name()}";

			$list[] = $command_string;

			$this->enumerate_commands( $subcommand, $list, $command_string );
		}
	}

	/**
	 * Enables (almost) full PHP error reporting to stderr.
	 */
	private function enable_error_reporting() {
		if ( E_ALL !== error_reporting() ) {
			// Don't enable E_DEPRECATED as old versions of WP use PHP 4 style constructors and the mysql extension.
			error_reporting( E_ALL & ~E_DEPRECATED );
		}
		ini_set( 'display_errors', 'stderr' ); // phpcs:ignore WordPress.PHP.IniSet.display_errors_Disallowed
	}
}
<?php

namespace WP_CLI\Fetchers;

use WP_CLI;
use WP_User;

/**
 * Fetch a WordPress user based on one of its attributes.
 */
class User extends Base {

	/**
	 * The message to display when an item is not found.
	 *
	 * @var string
	 */
	protected $msg = "Invalid user ID, email or login: '%s'";

	/**
	 * Get a user object by one of its identifying attributes.
	 *
	 * @param string $arg The raw CLI argument.
	 * @return WP_User|false The item if found; false otherwise.
	 */
	public function get( $arg ) {

		if ( getenv( 'WP_CLI_FORCE_USER_LOGIN' ) ) {
			$this->msg = "Invalid user login: '%s'";
			return get_user_by( 'login', $arg );
		}

		if ( is_numeric( $arg ) ) {
			$check = get_user_by( 'login', $arg );
			$user  = get_user_by( 'id', $arg );
			if ( $check && $user ) {
				WP_CLI::warning(
					sprintf(
						'Ambiguous user match detected (both ID and user_login exist for identifier \'%d\'). WP-CLI will default to the ID, but you can force user_login instead with WP_CLI_FORCE_USER_LOGIN=1.',
						$arg
					)
				);
			}
		} elseif ( is_email( $arg ) ) {
			$user = get_user_by( 'email', $arg );
			// Logins can be emails.
			if ( ! $user ) {
				$user = get_user_by( 'login', $arg );
			}
		} else {
			$user = get_user_by( 'login', $arg );
		}

		return $user;
	}
}
<?php

namespace WP_CLI\Fetchers;

/**
 * Fetch a signup based on one of its attributes.
 */
class Signup extends Base {

	/**
	 * The message to display when an item is not found.
	 *
	 * @var string
	 */
	protected $msg = "Invalid signup ID, email, login, or activation key: '%s'";

	/**
	 * Get a signup.
	 *
	 * @param int|string $signup
	 * @return object|false
	 */
	public function get( $signup ) {
		return $this->get_signup( $signup );
	}

	/**
	 * Get a signup by one of its identifying attributes.
	 *
	 * @param string $arg The raw CLI argument.
	 * @return object|false The item if found; false otherwise.
	 */
	protected function get_signup( $arg ) {
		global $wpdb;

		$signup_object = null;

		// Fetch signup with signup_id.
		if ( is_numeric( $arg ) ) {
			$result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE signup_id = %d", $arg ) );

			if ( $result ) {
				$signup_object = $result;
			}
		}

		if ( ! $signup_object ) {
			// Try to fetch with other keys.
			foreach ( array( 'user_login', 'user_email', 'activation_key' ) as $field ) {
				// phpcs:ignore WordPress.DB.PreparedSQL
				$result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->signups WHERE $field = %s", $arg ) );

				if ( $result ) {
					$signup_object = $result;
					break;
				}
			}
		}

		if ( $signup_object ) {
			return $signup_object;
		}

		return false;
	}
}
<?php

namespace WP_CLI\Fetchers;

use WP_CLI;
use WP_CLI\ExitException;

/**
 * Fetch a WordPress entity for use in a subcommand.
 */
abstract class Base {

	/**
	 * The message to display when an item is not found.
	 *
	 * @var string
	 */
	protected $msg;

	/**
	 * @param string|int $arg The raw CLI argument.
	 * @return mixed|false The item if found; false otherwise.
	 */
	abstract public function get( $arg );

	/**
	 * Like get(), but calls WP_CLI::error() instead of returning false.
	 *
	 * @param string $arg The raw CLI argument.
	 * @return mixed The item if found.
	 * @throws ExitException If the item is not found.
	 */
	public function get_check( $arg ) {
		$item = $this->get( $arg );

		if ( ! $item ) {
			WP_CLI::error( sprintf( $this->msg, $arg ) );
		}

		return $item;
	}

	/**
	 * Get multiple items.
	 *
	 * @param array $args The raw CLI arguments.
	 * @return array The list of found items.
	 */
	public function get_many( $args ) {
		$items = [];

		foreach ( $args as $arg ) {
			$item = $this->get( $arg );

			if ( $item ) {
				$items[] = $item;
			} else {
				WP_CLI::warning( sprintf( $this->msg, $arg ) );
			}
		}

		return $items;
	}
}
<?php

namespace WP_CLI\Fetchers;

use WP_Comment;

/**
 * Fetch a WordPress comment based on one of its attributes.
 */
class Comment extends Base {

	/**
	 * The message to display when an item is not found.
	 *
	 * @var string
	 */
	protected $msg = 'Could not find the comment with ID %d.';

	/**
	 * Get a comment object by ID
	 *
	 * @param string $arg The raw CLI argument.
	 * @return WP_Comment|array|false The item if found; false otherwise.
	 */
	public function get( $arg ) {
		$comment_id = (int) $arg;
		$comment    = get_comment( $comment_id );

		if ( null === $comment ) {
			return false;
		}

		return $comment;
	}
}
<?php

namespace WP_CLI\Fetchers;

/**
 * Fetch a WordPress site based on one of its attributes.
 */
class Site extends Base {

	/**
	 * The message to display when an item is not found.
	 *
	 * @var string
	 */
	protected $msg = 'Could not find the site with ID %d.';

	/**
	 * Get a site object by ID
	 *
	 * @param int $site_id
	 * @return object|false
	 */
	public function get( $site_id ) {
		return $this->get_site( $site_id );
	}

	/**
	 * Get site (blog) data for a given id.
	 *
	 * @global wpdb $wpdb WordPress database abstraction object.
	 *
	 * @param string $arg The raw CLI argument.
	 * @return array|false The item if found; false otherwise.
	 */
	private function get_site( $arg ) {
		global $wpdb;

		// Load site data
		$site = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->blogs} WHERE blog_id = %d",
				$arg
			)
		);

		if ( ! empty( $site ) ) {
			// Only care about domain and path which are set here
			return $site;
		}

		return false;
	}
}
<?php

namespace WP_CLI\Fetchers;

use WP_Post;

/**
 * Fetch a WordPress post based on one of its attributes.
 */
class Post extends Base {

	/**
	 * The message to display when an item is not found.
	 *
	 * @var string
	 */
	protected $msg = 'Could not find the post with ID %d.';

	/**
	 * Get a post object by ID
	 *
	 * @param string $arg The raw CLI argument.
	 * @return WP_Post|array|false The item if found; false otherwise.
	 */
	public function get( $arg ) {
		$post = get_post( $arg );

		if ( null === $post ) {
			return false;
		}

		return $post;
	}
}
<?php

namespace WP_CLI;

use Composer\IO\NullIO;
use WP_CLI;

/**
 * A Composer IO class so we can provide some level of interactivity from WP-CLI
 */
class ComposerIO extends NullIO {

	/**
	 * {@inheritDoc}
	 */
	public function isVerbose() {
		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	public function write( $messages, $newline = true, $verbosity = self::NORMAL ) {
		self::output_clean_message( $messages );
	}

	/**
	 * {@inheritDoc}
	 */
	public function writeError( $messages, $newline = true, $verbosity = self::NORMAL ) {
		self::output_clean_message( $messages );
	}

	private static function output_clean_message( $messages ) {
		$messages = (array) preg_replace( '#<(https?)([^>]+)>#', '$1$2', $messages );
		foreach ( $messages as $message ) {
			// phpcs:ignore WordPress.WP.AlternativeFunctions.strip_tags_strip_tags
			WP_CLI::log( strip_tags( trim( $message ) ) );
		}
	}
}
<?php

namespace WP_CLI;

use WP_CLI;

class Completions {

	private $cur_word;
	private $words;
	private $opts = [];

	/**
	 * Instantiate a Completions object.
	 *
	 * @param string $line Line of shell input to compute a completion for.
	 */
	public function __construct( $line ) {
		// TODO: properly parse single and double quotes
		$this->words = explode( ' ', $line );

		// First word is always `wp`.
		array_shift( $this->words );

		// Last word is either empty or an incomplete subcommand.
		$this->cur_word = end( $this->words );
		if ( '' !== $this->cur_word && ! preg_match( '/^\-/', $this->cur_word ) ) {
			array_pop( $this->words );
		}

		$is_alias = false;
		$is_help  = false;
		if ( ! empty( $this->words[0] ) && preg_match( '/^@/', $this->words[0] ) ) {
			array_shift( $this->words );
			// `wp @al` is false, but `wp @all ` is true.
			if ( count( $this->words ) ) {
				$is_alias = true;
			}
		} elseif ( ! empty( $this->words[0] ) && 'help' === $this->words[0] ) {
			array_shift( $this->words );
			$is_help = true;
		}

		$r = $this->get_command( $this->words );
		if ( ! is_array( $r ) ) {
			return;
		}

		list( $command, $args, $assoc_args ) = $r;

		$spec = SynopsisParser::parse( $command->get_synopsis() );

		foreach ( $spec as $arg ) {
			if ( 'positional' === $arg['type'] && 'file' === $arg['name'] ) {
				$this->add( '<file> ' );
				return;
			}
		}

		if ( $command->can_have_subcommands() ) {
			// Add completion when command is `wp` and alias isn't set.
			if ( 'wp' === $command->get_name() && false === $is_alias && false === $is_help ) {
				$aliases = WP_CLI::get_configurator()->get_aliases();
				foreach ( $aliases as $name => $_ ) {
					$this->add( "$name " );
				}
			}
			foreach ( $command->get_subcommands() as $name => $_ ) {
				$this->add( "$name " );
			}
		} else {
			foreach ( $spec as $arg ) {
				if ( in_array( $arg['type'], [ 'flag', 'assoc' ], true ) ) {
					if ( isset( $assoc_args[ $arg['name'] ] ) ) {
						continue;
					}

					$opt = "--{$arg['name']}";

					if ( 'flag' === $arg['type'] ) {
						$opt .= ' ';
					} elseif ( ! $arg['value']['optional'] ) {
						$opt .= '=';
					}

					$this->add( $opt );
				}
			}

			foreach ( $this->get_global_parameters() as $param => $runtime ) {
				if ( isset( $assoc_args[ $param ] ) ) {
					continue;
				}

				$opt = "--{$param}";

				if ( '' === $runtime || ! is_string( $runtime ) ) {
					$opt .= ' ';
				} else {
					$opt .= '=';
				}

				$this->add( $opt );
			}
		}
	}

	/**
	 * Get the specific WP-CLI command that is being referenced.
	 *
	 * @param array $words Individual input line words.
	 *
	 * @return array|mixed Array with command and arguments, or error result if command detection failed.
	 */
	private function get_command( $words ) {
		$positional_args = [];
		$assoc_args      = [];

		# Avoid having to polyfill array_key_last().
		end( $words );
		$last_arg_i = key( $words );
		foreach ( $words as $i => $arg ) {
			if ( preg_match( '|^--([^=]+)(=?)|', $arg, $matches ) ) {
				if ( $i === $last_arg_i && '' === $matches[2] ) {
					continue;
				}
				$assoc_args[ $matches[1] ] = true;
			} else {
				$positional_args[] = $arg;
			}
		}

		$r = WP_CLI::get_runner()->find_command_to_run( $positional_args );
		if ( ! is_array( $r ) && array_pop( $positional_args ) === $this->cur_word ) {
			$r = WP_CLI::get_runner()->find_command_to_run( $positional_args );
		}

		if ( ! is_array( $r ) ) {
			return $r;
		}

		list( $command, $args ) = $r;

		return [ $command, $args, $assoc_args ];
	}

	/**
	 * Get global parameters.
	 *
	 * @return array Associative array of global parameters.
	 */
	private function get_global_parameters() {
		$params = [];
		foreach ( WP_CLI::get_configurator()->get_spec() as $key => $details ) {
			if ( false === $details['runtime'] ) {
				continue;
			}

			if ( isset( $details['deprecated'] ) ) {
				continue;
			}

			if ( isset( $details['hidden'] ) ) {
				continue;
			}
			$params[ $key ] = $details['runtime'];

			// Add additional option like `--[no-]color`.
			if ( true === $details['runtime'] ) {
				$params[ 'no-' . $key ] = '';
			}
		}

		return $params;
	}

	/**
	 * Store individual option.
	 *
	 * @param string $opt Option to store.
	 *
	 * @return void
	 */
	private function add( $opt ) {
		if ( '' !== $this->cur_word ) {
			if ( 0 !== strpos( $opt, $this->cur_word ) ) {
				return;
			}
		}

		$this->opts[] = $opt;
	}

	/**
	 * Render the stored options.
	 *
	 * @return void
	 */
	public function render() {
		foreach ( $this->opts as $opt ) {
			WP_CLI::line( $opt );
		}
	}
}
<?php

namespace WP_CLI;

/**
 * Results of an executed command.
 */
class ProcessRun {

	/**
	 * The full command executed by the system.
	 *
	 * @var string
	 */
	public $command;

	/**
	 * Captured output from the process' STDOUT.
	 *
	 * @var string
	 */
	public $stdout;

	/**
	 * Captured output from the process' STDERR.
	 *
	 * @var string
	 */
	public $stderr;

	/**
	 * The path of the working directory for the process or NULL if not specified.
	 *
	 * This defaults to current working directory.
	 *
	 * @var string|null
	 */
	public $cwd;

	/**
	 * Environment variables set for this process.
	 *
	 * @var array
	 */
	public $env;

	/**
	 * Exit code of the process.
	 *
	 * @var int
	 */
	public $return_code;

	/**
	 * The run time of the process.
	 *
	 * @var float
	 */
	public $run_time;

	/**
	 * @param array $props Properties of executed command.
	 */
	public function __construct( $props ) {
		foreach ( $props as $key => $value ) {
			$this->$key = $value;
		}
	}

	/**
	 * Return properties of executed command as a string.
	 *
	 * @return string
	 */
	public function __toString() {
		$out  = "$ $this->command\n";
		$out .= "$this->stdout\n$this->stderr";
		$out .= "cwd: $this->cwd\n";
		$out .= "run time: $this->run_time\n";
		$out .= "exit status: $this->return_code";

		return $out;
	}
}
<?php

namespace WP_CLI\Loggers;

use WP_CLI;

/**
 * Quiet logger only logs errors.
 */
class Quiet extends Base {

	/**
	 * @param bool $in_color Whether or not to Colorize strings.
	 */
	public function __construct( $in_color = false ) {
		$this->in_color = $in_color;
	}

	/**
	 * Informational messages aren't logged.
	 *
	 * @param string $message Message to write.
	 */
	public function info( $message ) {
		// Nothing.
	}

	/**
	 * Success messages aren't logged.
	 *
	 * @param string $message Message to write.
	 */
	public function success( $message ) {
		// Nothing.
	}

	/**
	 * Warning messages aren't logged.
	 *
	 * @param string $message Message to write.
	 */
	public function warning( $message ) {
		// Nothing.
	}

	/**
	 * Write an error message to STDERR, prefixed with "Error: ".
	 *
	 * @param string $message Message to write.
	 */
	public function error( $message ) {
		$this->_line( $message, 'Error', '%R', STDERR );
	}

	/**
	 * Similar to error( $message ), but outputs $message in a red box.
	 *
	 * @param  array $message_lines Message to write.
	 */
	public function error_multi_line( $message_lines ) {
		$message = implode( "\n", $message_lines );

		$this->_line( $message, 'Error', '%R', STDERR );
		$this->_line( '', '---------', '%R', STDERR );
	}
}
<?php

namespace WP_CLI\Loggers;

use cli\Colors;
use WP_CLI;
use WP_CLI\Runner;

/**
 * Base logger class
 */
abstract class Base {

	protected $in_color = false;

	abstract public function info( $message );

	abstract public function success( $message );

	abstract public function warning( $message );

	/**
	 * Retrieve the runner instance from the base CLI object. This facilitates
	 * unit testing, where the WP_CLI instance isn't available
	 *
	 * @return Runner Instance of the runner class
	 */
	protected function get_runner() {
		return WP_CLI::get_runner();
	}

	/**
	 * Write a message to STDERR, prefixed with "Debug: ".
	 *
	 * @param string $message Message to write.
	 * @param string|bool $group Organize debug message to a specific group.
	 * Use `false` for no group.
	 */
	public function debug( $message, $group = false ) {
		static $start_time = null;
		if ( null === $start_time ) {
			$start_time = microtime( true );
		}
		$debug = $this->get_runner()->config['debug'];
		if ( ! $debug ) {
			return;
		}
		if ( true !== $debug && $group !== $debug ) {
			return;
		}
		$time   = round( microtime( true ) - ( defined( 'WP_CLI_START_MICROTIME' ) ? WP_CLI_START_MICROTIME : $start_time ), 3 );
		$prefix = 'Debug';
		if ( $group && true === $debug ) {
			$prefix = 'Debug (' . $group . ')';
		}
		$this->_line( "$message ({$time}s)", $prefix, '%B', STDERR );
	}

	/**
	 * Write a string to a resource.
	 *
	 * @param resource $handle Commonly STDOUT or STDERR.
	 * @param string $str Message to write.
	 */
	protected function write( $handle, $str ) {
		fwrite( $handle, $str );
	}

	/**
	 * Output one line of message to a resource.
	 *
	 * @param string $message Message to write.
	 * @param string $label Prefix message with a label.
	 * @param string $color Colorize label with a given color.
	 * @param resource $handle Resource to write to. Defaults to STDOUT.
	 */
	protected function _line( $message, $label, $color, $handle = STDOUT ) { // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore -- Used in third party extensions.
		if ( class_exists( 'cli\Colors' ) ) {
			$label = Colors::colorize( "$color$label:%n", $this->in_color );
		} else {
			$label = "$label:";
		}
		$this->write( $handle, "$label $message\n" );
	}
}
<?php

namespace WP_CLI\Loggers;

use cli\Colors;

/**
 * Default logger for success, warning, error, and standard messages.
 */
class Regular extends Base {

	/**
	 * @param bool $in_color Whether or not to Colorize strings.
	 */
	public function __construct( $in_color ) {
		$this->in_color = $in_color;
	}

	/**
	 * Write an informational message to STDOUT.
	 *
	 * @param string $message Message to write.
	 */
	public function info( $message ) {
		$this->write( STDOUT, $message . "\n" );
	}

	/**
	 * Write a success message, prefixed with "Success: ".
	 *
	 * @param string $message Message to write.
	 */
	public function success( $message ) {
		$this->_line( $message, 'Success', '%G' );
	}

	/**
	 * Write a warning message to STDERR, prefixed with "Warning: ".
	 *
	 * @param string $message Message to write.
	 */
	public function warning( $message ) {
		$this->_line( $message, 'Warning', '%C', STDERR );
	}

	/**
	 * Write an message to STDERR, prefixed with "Error: ".
	 *
	 * @param string $message Message to write.
	 */
	public function error( $message ) {
		$this->_line( $message, 'Error', '%R', STDERR );
	}

	/**
	 * Similar to error( $message ), but outputs $message in a red box.
	 *
	 * @param  array $message_lines Message to write.
	 */
	public function error_multi_line( $message_lines ) {
		// Convert tabs to four spaces, as some shells will output the tabs as variable-length.
		$message_lines = array_map(
			function ( $line ) {
				return str_replace( "\t", '    ', $line );
			},
			$message_lines
		);

		$longest = max( array_map( 'strlen', $message_lines ) );

		// Write an empty line before the message.
		$empty_line = Colors::colorize( '%w%1 ' . str_repeat( ' ', $longest ) . ' %n' );
		$this->write( STDERR, "\n\t$empty_line\n" );

		foreach ( $message_lines as $line ) {
			$padding = str_repeat( ' ', $longest - strlen( $line ) );
			$line    = Colors::colorize( "%w%1 $line $padding%n" );
			$this->write( STDERR, "\t$line\n" );
		}

		// Write an empty line after the message.
		$this->write( STDERR, "\t$empty_line\n\n" );
	}
}
<?php

namespace WP_CLI\Loggers;

use WP_CLI;

/**
 * Execution logger captures all STDOUT and STDERR writes
 */
class Execution extends Regular {

	/**
	 * Captured writes to STDOUT.
	 */
	public $stdout = '';

	/**
	 * Captured writes to STDERR.
	 */
	public $stderr = '';

	/**
	 * @param bool $in_color Whether or not to Colorize strings.
	 */
	public function __construct( $in_color = false ) { // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod.Found -- Provides a default value.
		parent::__construct( $in_color );
	}

	/**
	 * Similar to error( $message ), but outputs $message in a red box.
	 *
	 * @param array $message_lines Message to write.
	 */
	public function error_multi_line( $message_lines ) {
		$message = implode( "\n", $message_lines );

		$this->write( STDERR, WP_CLI::colorize( "%RError:%n\n$message\n" ) );
		$this->write( STDERR, WP_CLI::colorize( "%R---------%n\n\n" ) );
	}

	/**
	 * Write a string to a resource.
	 *
	 * @param resource $handle Commonly STDOUT or STDERR.
	 * @param string $str Message to write.
	 */
	protected function write( $handle, $str ) {
		switch ( $handle ) {
			case STDOUT:
				$this->stdout .= $str;
				break;
			case STDERR:
				$this->stderr .= $str;
				break;
		}
	}

	/**
	 * Starts output buffering, using a callback to capture output from `echo`, `print`, `printf` (which write to the output buffer 'php://output' rather than STDOUT).
	 */
	public function ob_start() {
		ob_start( [ $this, 'ob_start_callback' ], 1 );
	}

	/**
	 * Callback for `ob_start()`.
	 *
	 * @param string $str String to write.
	 * @return string Returns zero-length string so nothing gets written to the output buffer.
	 */
	public function ob_start_callback( $str ) {
		$this->write( STDOUT, $str );
		return '';
	}

	/**
	 * To match `ob_start() above. Does an `ob_end_flush()`.
	 */
	public function ob_end() {
		ob_end_flush();
	}
}
<?php

namespace WP_CLI;

use Exception;
use RuntimeException;
use WP_CLI;

/**
 * Class RequestsLibrary.
 *
 * A class to manage the version and source of the Requests library used by WP-CLI.
 */
final class RequestsLibrary {

	/**
	 * Version 1 of the Requests library.
	 *
	 * @var string
	 */
	const VERSION_V1 = 'v1';

	/**
	 * Version 2 of the Requests library.
	 *
	 * @var string
	 */
	const VERSION_V2 = 'v2';

	/**
	 * Array of valid versions for the Requests library.
	 *
	 * @var array<string>
	 */
	const VALID_VERSIONS = [ self::VERSION_V1, self::VERSION_V2 ];

	/**
	 * Requests library bundled with WordPress Core being used.
	 *
	 * @var string
	 */
	const SOURCE_WP_CORE = 'wp-core';

	/**
	 * Requests library bundled with WP-CLI being used.
	 *
	 * @var string
	 */
	const SOURCE_WP_CLI = 'wp-cli';

	/**
	 * Array of valid source for the Requests library.
	 *
	 * @var array<string>
	 */
	const VALID_SOURCES = [ self::SOURCE_WP_CORE, self::SOURCE_WP_CLI ];

	/**
	 * Class name of the Requests main class for v1.
	 *
	 * @var string
	 */
	const CLASS_NAME_V1 = '\Requests';

	/**
	 * Class name of the Requests main class for v2.
	 *
	 * @var string
	 */
	const CLASS_NAME_V2 = '\WpOrg\Requests\Requests';

	/**
	 * Version of the Requests library being used.
	 *
	 * @var string
	 */
	private static $version = self::VERSION_V2;

	/**
	 * Source of the Requests library being used.
	 *
	 * @var string
	 */
	private static $source = self::SOURCE_WP_CLI;

	/**
	 * Class name of the Requests library being used.
	 *
	 * @var string
	 */
	private static $class_name = self::CLASS_NAME_V2;

	/**
	 * Check if the current version is v1.
	 *
	 * @return bool Whether the current version is v1.
	 */
	public static function is_v1() {
		return self::get_version() === self::VERSION_V1;
	}

	/**
	 * Check if the current version is v2.
	 *
	 * @return bool Whether the current version is v2.
	 */
	public static function is_v2() {
		return self::get_version() === self::VERSION_V2;
	}

	/**
	 * Check if the current source for the Requests library is WordPress Core.
	 *
	 * @return bool Whether the current source is WordPress Core.
	 */
	public static function is_core() {
		return self::get_source() === self::SOURCE_WP_CORE;
	}

	/**
	 * Check if the current source for the Requests library is WP-CLI.
	 *
	 * @return bool Whether the current source is WP-CLI.
	 */
	public static function is_cli() {
		return self::get_source() === self::SOURCE_WP_CLI;
	}

	/**
	 * Get the current version.
	 *
	 * @return string The current version.
	 */
	public static function get_version() {
		return self::$version;
	}

	/**
	 * Set the version of the library.
	 *
	 * @param string $version The version to set.
	 * @throws RuntimeException if the version is invalid.
	 */
	public static function set_version( $version ) {
		if ( ! is_string( $version ) ) {
			throw new RuntimeException( 'RequestsLibrary::$version must be a string.' );
		}

		if ( ! in_array( $version, self::VALID_VERSIONS, true ) ) {
			throw new RuntimeException(
				sprintf(
					'Invalid RequestsLibrary::$version, must be one of: %s.',
					implode( ', ', self::VALID_VERSIONS )
				)
			);
		}

		WP_CLI::debug( 'Setting RequestsLibrary::$version to ' . $version, 'bootstrap' );

		self::$version = $version;
	}

	/**
	 * Get the current class name.
	 *
	 * @return string The current class name.
	 */
	public static function get_class_name() {
		return self::$class_name;
	}

	/**
	 * Set the class name for the library.
	 *
	 * @param string $class_name The class name to set.
	 */
	public static function set_class_name( $class_name ) {
		if ( ! is_string( $class_name ) ) {
			throw new RuntimeException( 'RequestsLibrary::$class_name must be a string.' );
		}

		WP_CLI::debug( 'Setting RequestsLibrary::$class_name to ' . $class_name, 'bootstrap' );

		self::$class_name = $class_name;
	}

	/**
	 * Get the current source.
	 *
	 * @return string The current source.
	 */
	public static function get_source() {
		return self::$source;
	}

	/**
	 * Set the source of the library.
	 *
	 * @param string $source The source to set.
	 * @throws RuntimeException if the source is invalid.
	 */
	public static function set_source( $source ) {
		if ( ! is_string( $source ) ) {
			throw new RuntimeException( 'RequestsLibrary::$source must be a string.' );
		}

		if ( ! in_array( $source, self::VALID_SOURCES, true ) ) {
			throw new RuntimeException(
				sprintf(
					'Invalid RequestsLibrary::$source, must be one of: %s.',
					implode( ', ', self::VALID_SOURCES )
				)
			);
		}

		WP_CLI::debug( 'Setting RequestsLibrary::$source to ' . $source, 'bootstrap' );

		self::$source = $source;
	}

	/**
	 * Check if a given exception was issued by the Requests library.
	 *
	 * This is used because we cannot easily catch multiple different exception
	 * classes with PHP 5.6. Because of that, we catch generic exceptions, check if
	 * they match the Requests library, and re-throw them if they do not.
	 *
	 * @param Exception $exception Exception to check.
	 * @return bool Whether the provided exception was issued by the Requests library.
	 */
	public static function is_requests_exception( Exception $exception ) {
		return is_a( $exception, '\Requests_Exception' )
			|| is_a( $exception, '\WpOrg\Requests\Exception' );
	}

	/**
	 * Register the autoloader for the Requests library.
	 *
	 * This checks for the detected setup and register the corresponding
	 * autoloader if it is still needed.
	 */
	public static function register_autoloader() {
		$includes_path = defined( 'WPINC' ) ? WPINC : 'wp-includes';

		if ( self::is_v1() && ! class_exists( self::CLASS_NAME_V1 ) ) {
			if ( self::is_core() ) {
				require_once ABSPATH . $includes_path . '/class-requests.php';
			} else {
				require_once WP_CLI_VENDOR_DIR . '/rmccue/requests/library/Requests.php';
			}
			\Requests::register_autoloader();
		}

		if ( self::is_v2() && ! class_exists( self::CLASS_NAME_V2 ) ) {
			if ( self::is_core() ) {
				require_once ABSPATH . $includes_path . '/Requests/Autoload.php';
			} else {
				self::maybe_define_wp_cli_root();
				if ( file_exists( WP_CLI_ROOT . '/bundle/rmccue/requests/src/Autoload.php' ) ) {
					require_once WP_CLI_ROOT . '/bundle/rmccue/requests/src/Autoload.php';
				} else {
					require_once WP_CLI_VENDOR_DIR . '/rmccue/requests/src/Autoload.php';
				}
			}
			\WpOrg\Requests\Autoload::register();
		}
	}

	/**
	 * Get the path to the bundled certificate.
	 *
	 * @return string The path to the bundled certificate.
	 */
	public static function get_bundled_certificate_path() {
		if ( self::is_core() ) {
			$includes_path = defined( 'WPINC' ) ? WPINC : 'wp-includes';
			return ABSPATH . $includes_path . '/certificates/ca-bundle.crt';
		} elseif ( self::is_v1() ) {
			return WP_CLI_VENDOR_DIR . '/rmccue/requests/library/Requests/Transport/cacert.pem';
		} else {
			self::maybe_define_wp_cli_root();
			if ( file_exists( WP_CLI_ROOT . '/bundle/rmccue/requests/certificates/cacert.pem' ) ) {
				return WP_CLI_ROOT . '/bundle/rmccue/requests/certificates/cacert.pem';
			}
			return WP_CLI_VENDOR_DIR . '/rmccue/requests/certificates/cacert.pem';
		}
	}

	/**
	 * Define WP_CLI_ROOT if it is not already defined.
	 */
	private static function maybe_define_wp_cli_root() {
		if ( ! defined( 'WP_CLI_ROOT' ) ) {
			define( 'WP_CLI_ROOT', dirname( dirname( __DIR__ ) ) );
		}
	}
}
<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the MIT license. For more information, see
 * <https://www.doctrine-project.org>.
 */

namespace WP_CLI;

/**
 * Doctrine inflector has static methods for inflecting text.
 *
 * The methods in these classes are from several different sources collected
 * across several different php projects and several different authors. The
 * original author names and emails are not known.
 *
 * Pluralize & Singularize implementation are borrowed from CakePHP with some modifications.
 *
 * @link   www.doctrine-project.org
 * @since  1.0
 * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @author Jonathan H. Wage <jonwage@gmail.com>
 */
class Inflector {

	/**
	 * Plural inflector rules.
	 *
	 * @var array
	 */
	private static $plural = [
		'rules'       => [
			'/(s)tatus$/i'                         => '\1\2tatuses',
			'/(quiz)$/i'                           => '\1zes',
			'/^(ox)$/i'                            => '\1\2en',
			'/([m|l])ouse$/i'                      => '\1ice',
			'/(matr|vert|ind)(ix|ex)$/i'           => '\1ices',
			'/(x|ch|ss|sh)$/i'                     => '\1es',
			'/([^aeiouy]|qu)y$/i'                  => '\1ies',
			'/(hive)$/i'                           => '\1s',
			'/(?:([^f])fe|([lr])f)$/i'             => '\1\2ves',
			'/sis$/i'                              => 'ses',
			'/([ti])um$/i'                         => '\1a',
			'/(p)erson$/i'                         => '\1eople',
			'/(m)an$/i'                            => '\1en',
			'/(c)hild$/i'                          => '\1hildren',
			'/(f)oot$/i'                           => '\1eet',
			'/(buffal|her|potat|tomat|volcan)o$/i' => '\1\2oes',
			'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
			'/us$/i'                               => 'uses',
			'/(alias)$/i'                          => '\1es',
			'/(analys|ax|cris|test|thes)is$/i'     => '\1es',
			'/s$/'                                 => 's',
			'/^$/'                                 => '',
			'/$/'                                  => 's',
		],
		'uninflected' => [
			'.*[nrlm]ese',
			'.*deer',
			'.*fish',
			'.*measles',
			'.*ois',
			'.*pox',
			'.*sheep',
			'people',
			'cookie',
		],
		'irregular'   => [
			'atlas'        => 'atlases',
			'axe'          => 'axes',
			'beef'         => 'beefs',
			'brother'      => 'brothers',
			'cafe'         => 'cafes',
			'chateau'      => 'chateaux',
			'child'        => 'children',
			'cookie'       => 'cookies',
			'corpus'       => 'corpuses',
			'cow'          => 'cows',
			'criterion'    => 'criteria',
			'curriculum'   => 'curricula',
			'demo'         => 'demos',
			'domino'       => 'dominoes',
			'echo'         => 'echoes',
			'foot'         => 'feet',
			'fungus'       => 'fungi',
			'ganglion'     => 'ganglions',
			'genie'        => 'genies',
			'genus'        => 'genera',
			'graffito'     => 'graffiti',
			'hippopotamus' => 'hippopotami',
			'hoof'         => 'hoofs',
			'human'        => 'humans',
			'iris'         => 'irises',
			'leaf'         => 'leaves',
			'loaf'         => 'loaves',
			'man'          => 'men',
			'medium'       => 'media',
			'memorandum'   => 'memoranda',
			'money'        => 'monies',
			'mongoose'     => 'mongooses',
			'motto'        => 'mottoes',
			'move'         => 'moves',
			'mythos'       => 'mythoi',
			'niche'        => 'niches',
			'nucleus'      => 'nuclei',
			'numen'        => 'numina',
			'occiput'      => 'occiputs',
			'octopus'      => 'octopuses',
			'opus'         => 'opuses',
			'ox'           => 'oxen',
			'penis'        => 'penises',
			'person'       => 'people',
			'plateau'      => 'plateaux',
			'runner-up'    => 'runners-up',
			'sex'          => 'sexes',
			'soliloquy'    => 'soliloquies',
			'son-in-law'   => 'sons-in-law',
			'syllabus'     => 'syllabi',
			'testis'       => 'testes',
			'thief'        => 'thieves',
			'tooth'        => 'teeth',
			'tornado'      => 'tornadoes',
			'trilby'       => 'trilbys',
			'turf'         => 'turfs',
			'volcano'      => 'volcanoes',
		],
	];

	/**
	 * Singular inflector rules.
	 *
	 * @var array
	 */
	private static $singular = [
		'rules'       => [
			'/(s)tatuses$/i'                         => '\1\2tatus',
			'/^(.*)(menu)s$/i'                       => '\1\2',
			'/(quiz)zes$/i'                          => '\\1',
			'/(matr)ices$/i'                         => '\1ix',
			'/(vert|ind)ices$/i'                     => '\1ex',
			'/^(ox)en/i'                             => '\1',
			'/(alias)(es)*$/i'                       => '\1',
			'/(buffal|her|potat|tomat|volcan)oes$/i' => '\1o',
			'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
			'/([ftw]ax)es/i'                         => '\1',
			'/(analys|ax|cris|test|thes)es$/i'       => '\1is',
			'/(shoe|slave)s$/i'                      => '\1',
			'/(o)es$/i'                              => '\1',
			'/ouses$/'                               => 'ouse',
			'/([^a])uses$/'                          => '\1us',
			'/([m|l])ice$/i'                         => '\1ouse',
			'/(x|ch|ss|sh)es$/i'                     => '\1',
			'/(m)ovies$/i'                           => '\1\2ovie',
			'/(s)eries$/i'                           => '\1\2eries',
			'/([^aeiouy]|qu)ies$/i'                  => '\1y',
			'/([lr])ves$/i'                          => '\1f',
			'/(tive)s$/i'                            => '\1',
			'/(hive)s$/i'                            => '\1',
			'/(drive)s$/i'                           => '\1',
			'/([^fo])ves$/i'                         => '\1fe',
			'/(^analy)ses$/i'                        => '\1sis',
			'/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
			'/([ti])a$/i'                            => '\1um',
			'/(p)eople$/i'                           => '\1\2erson',
			'/(m)en$/i'                              => '\1an',
			'/(c)hildren$/i'                         => '\1\2hild',
			'/(f)eet$/i'                             => '\1oot',
			'/(n)ews$/i'                             => '\1\2ews',
			'/eaus$/'                                => 'eau',
			'/^(.*us)$/'                             => '\\1',
			'/s$/i'                                  => '',
		],
		'uninflected' => [
			'.*[nrlm]ese',
			'.*deer',
			'.*fish',
			'.*measles',
			'.*ois',
			'.*pox',
			'.*sheep',
			'.*ss',
		],
		'irregular'   => [
			'criteria' => 'criterion',
			'curves'   => 'curve',
			'emphases' => 'emphasis',
			'foes'     => 'foe',
			'hoaxes'   => 'hoax',
			'media'    => 'medium',
			'neuroses' => 'neurosis',
			'waves'    => 'wave',
			'oases'    => 'oasis',
		],
	];

	/**
	 * Words that should not be inflected.
	 *
	 * @var array
	 */
	private static $uninflected = [
		'Amoyese',
		'bison',
		'Borghese',
		'bream',
		'breeches',
		'britches',
		'buffalo',
		'cantus',
		'carp',
		'chassis',
		'clippers',
		'cod',
		'coitus',
		'Congoese',
		'contretemps',
		'corps',
		'debris',
		'diabetes',
		'djinn',
		'eland',
		'elk',
		'equipment',
		'Faroese',
		'flounder',
		'Foochowese',
		'gallows',
		'Genevese',
		'Genoese',
		'Gilbertese',
		'graffiti',
		'headquarters',
		'herpes',
		'hijinks',
		'Hottentotese',
		'information',
		'innings',
		'jackanapes',
		'Kiplingese',
		'Kongoese',
		'Lucchese',
		'mackerel',
		'Maltese',
		'.*?media',
		'mews',
		'moose',
		'mumps',
		'Nankingese',
		'news',
		'nexus',
		'Niasese',
		'Pekingese',
		'Piedmontese',
		'pincers',
		'Pistoiese',
		'pliers',
		'Portuguese',
		'proceedings',
		'rabies',
		'rice',
		'rhinoceros',
		'salmon',
		'Sarawakese',
		'scissors',
		'sea[- ]bass',
		'series',
		'Shavese',
		'shears',
		'siemens',
		'species',
		'staff',
		'swine',
		'testes',
		'trousers',
		'trout',
		'tuna',
		'Vermontese',
		'Wenchowese',
		'whiting',
		'wildebeest',
		'Yengeese',
	];

	/**
	 * Method cache array.
	 *
	 * @var array
	 */
	private static $cache = [];

	/**
	 * The initial state of Inflector so reset() works.
	 *
	 * @var array
	 */
	private static $initial_state = [];

	/**
	 * Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'.
	 *
	 * @param string $word The word to tableize.
	 *
	 * @return string The tableized word.
	 */
	public static function tableize( $word ) {
		return strtolower( preg_replace( '~(?<=\\w)([A-Z])~', '_$1', $word ) );
	}

	/**
	 * Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'.
	 *
	 * @param string $word The word to classify.
	 *
	 * @return string The classified word.
	 */
	public static function classify( $word ) {
		return str_replace( ' ', '', ucwords( strtr( $word, '_-', '  ' ) ) );
	}

	/**
	 * Camelizes a word. This uses the classify() method and turns the first character to lowercase.
	 *
	 * @param string $word The word to camelize.
	 *
	 * @return string The camelized word.
	 */
	public static function camelize( $word ) {
		return lcfirst( self::classify( $word ) );
	}

	/**
	 * Uppercases words with configurable delimiters between words.
	 *
	 * Takes a string and capitalizes all of the words, like PHP's built-in
	 * ucwords function.  This extends that behavior, however, by allowing the
	 * word delimiters to be configured, rather than only separating on
	 * whitespace.
	 *
	 * Here is an example:
	 * <code>
	 * <?php
	 * $string = 'top-o-the-morning to all_of_you!';
	 * echo \Doctrine\Common\Inflector\Inflector::ucwords($string);
	 * // Top-O-The-Morning To All_of_you!
	 *
	 * echo \Doctrine\Common\Inflector\Inflector::ucwords($string, '-_ ');
	 * // Top-O-The-Morning To All_Of_You!
	 * ?>
	 * </code>
	 *
	 * @param string $string The string to operate on.
	 * @param string $delimiters A list of word separators.
	 *
	 * @return string The string with all delimiter-separated words capitalized.
	 */
	public static function ucwords( $string, $delimiters = " \n\t\r\0\x0B-" ) {
		return preg_replace_callback(
			'/[^' . preg_quote( $delimiters, '/' ) . ']+/',
			function ( $matches ) {
				return ucfirst( $matches[0] );
			},
			$string
		);
	}

	/**
	 * Clears Inflectors inflected value caches, and resets the inflection
	 * rules to the initial values.
	 *
	 * @return void
	 */
	public static function reset() {
		if ( empty( self::$initial_state ) ) {
			self::$initial_state = get_class_vars( 'Inflector' );

			return;
		}

		foreach ( self::$initial_state as $key => $val ) {
			if ( 'initial_state' !== $key ) {
				self::${$key} = $val;
			}
		}
	}

	/**
	 * Adds custom inflection $rules, of either 'plural' or 'singular' $type.
	 *
	 * ### Usage:
	 *
	 * {{{
	 * Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
	 * Inflector::rules('plural', array(
	 *     'rules' => array('/^(inflect)ors$/i' => '\1ables'),
	 *     'uninflected' => array('dontinflectme'),
	 *     'irregular' => array('red' => 'redlings')
	 * ));
	 * }}}
	 *
	 * @param string  $type  The type of inflection, either 'plural' or 'singular'
	 * @param array   $rules An array of rules to be added.
	 * @param boolean $reset If true, will unset default inflections for all
	 *                       new rules that are being defined in $rules.
	 *
	 * @return void
	 */
	public static function rules( $type, $rules, $reset = false ) {
		foreach ( $rules as $rule => $pattern ) {
			if ( ! is_array( $pattern ) ) {
				continue;
			}

			if ( $reset ) {
				self::${$type}[ $rule ] = $pattern;
			} else {
				self::${$type}[ $rule ] = ( 'uninflected' === $rule )
					? array_merge( $pattern, self::${$type}[ $rule ] )
					: $pattern + self::${$type}[ $rule ];
			}

			unset( $rules[ $rule ], self::${$type}[ 'cache' . ucfirst( $rule ) ] );

			if ( isset( self::${$type}['merged'][ $rule ] ) ) {
				unset( self::${$type}['merged'][ $rule ] );
			}

			if ( 'plural' === $type ) {
				self::$cache['pluralize'] = [];
				self::$cache['tableize']  = [];
			} elseif ( 'singular' === $type ) {
				self::$cache['singularize'] = [];
			}
		}

		self::${$type}['rules'] = $rules + self::${$type}['rules'];
	}

	/**
	 * Returns a word in plural form.
	 *
	 * @param string $word The word in singular form.
	 *
	 * @return string The word in plural form.
	 */
	public static function pluralize( $word ) {
		if ( isset( self::$cache['pluralize'][ $word ] ) ) {
			return self::$cache['pluralize'][ $word ];
		}

		if ( ! isset( self::$plural['merged']['irregular'] ) ) {
			self::$plural['merged']['irregular'] = self::$plural['irregular'];
		}

		if ( ! isset( self::$plural['merged']['uninflected'] ) ) {
			self::$plural['merged']['uninflected'] = array_merge( self::$plural['uninflected'], self::$uninflected );
		}

		if ( ! isset( self::$plural['cacheUninflected'] ) || ! isset( self::$plural['cacheIrregular'] ) ) {
			self::$plural['cacheUninflected'] = '(?:' . implode( '|', self::$plural['merged']['uninflected'] ) . ')';
			self::$plural['cacheIrregular']   = '(?:' . implode( '|', array_keys( self::$plural['merged']['irregular'] ) ) . ')';
		}

		if ( preg_match( '/(.*)\\b(' . self::$plural['cacheIrregular'] . ')$/i', $word, $regs ) ) {
			self::$cache['pluralize'][ $word ] = $regs[1] . substr( $word, 0, 1 ) . substr( self::$plural['merged']['irregular'][ strtolower( $regs[2] ) ], 1 );

			return self::$cache['pluralize'][ $word ];
		}

		if ( preg_match( '/^(' . self::$plural['cacheUninflected'] . ')$/i', $word, $regs ) ) {
			self::$cache['pluralize'][ $word ] = $word;

			return $word;
		}

		foreach ( self::$plural['rules'] as $rule => $replacement ) {
			if ( preg_match( $rule, $word ) ) {
				self::$cache['pluralize'][ $word ] = preg_replace( $rule, $replacement, $word );

				return self::$cache['pluralize'][ $word ];
			}
		}

		// Just so a string is always returned.
		// This should never be reached.
		return $word;
	}

	/**
	 * Returns a word in singular form.
	 *
	 * @param string $word The word in plural form.
	 *
	 * @return string The word in singular form.
	 */
	public static function singularize( $word ) {
		if ( isset( self::$cache['singularize'][ $word ] ) ) {
			return self::$cache['singularize'][ $word ];
		}

		if ( ! isset( self::$singular['merged']['uninflected'] ) ) {
			self::$singular['merged']['uninflected'] = array_merge(
				self::$singular['uninflected'],
				self::$uninflected
			);
		}

		if ( ! isset( self::$singular['merged']['irregular'] ) ) {
			self::$singular['merged']['irregular'] = array_merge(
				self::$singular['irregular'],
				array_flip( self::$plural['irregular'] )
			);
		}

		if ( ! isset( self::$singular['cacheUninflected'] ) || ! isset( self::$singular['cacheIrregular'] ) ) {
			self::$singular['cacheUninflected'] = '(?:' . join( '|', self::$singular['merged']['uninflected'] ) . ')';
			self::$singular['cacheIrregular']   = '(?:' . join( '|', array_keys( self::$singular['merged']['irregular'] ) ) . ')';
		}

		if ( preg_match( '/(.*)\\b(' . self::$singular['cacheIrregular'] . ')$/i', $word, $regs ) ) {
			self::$cache['singularize'][ $word ] = $regs[1] . substr( $word, 0, 1 ) . substr( self::$singular['merged']['irregular'][ strtolower( $regs[2] ) ], 1 );

			return self::$cache['singularize'][ $word ];
		}

		if ( preg_match( '/^(' . self::$singular['cacheUninflected'] . ')$/i', $word, $regs ) ) {
			self::$cache['singularize'][ $word ] = $word;

			return $word;
		}

		foreach ( self::$singular['rules'] as $rule => $replacement ) {
			if ( preg_match( $rule, $word ) ) {
				self::$cache['singularize'][ $word ] = preg_replace( $rule, $replacement, $word );

				return self::$cache['singularize'][ $word ];
			}
		}

		self::$cache['singularize'][ $word ] = $word;

		return $word;
	}
}
<?php

namespace WP_CLI;

/**
 * Context that can be selected in order to run commands within a properly
 * set-up environment.
 */
interface Context {

	const ADMIN    = 'admin';
	const AUTO     = 'auto';
	const CLI      = 'cli';
	const FRONTEND = 'frontend';

	/**
	 * Debugging group to use for all context-related debug messages.
	 *
	 * @var string
	 */
	const DEBUG_GROUP = 'context';

	/**
	 * Process the context to set up the environment correctly.
	 *
	 * @param array $config Associative array of configuration data.
	 * @return void
	 */
	public function process( $config );
}
<?php

namespace WP_CLI;

/**
 * Escape route for not doing anything.
 */
final class NoOp {

	public function __set( $key, $value ) {
		// do nothing
	}

	public function __call( $method, $args ) {
		// do nothing
	}
}
<?php

/*
 * This file is heavily inspired and use code from Composer(getcomposer.org),
 * in particular Composer/Cache and Composer/Util/FileSystem from 1.0.0-alpha7
 *
 * The original code and this file are both released under MIT license.
 *
 * The copyright holders of the original code are:
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 */

namespace WP_CLI;

use DateTime;
use Exception;
use Symfony\Component\Finder\Finder;
use WP_CLI;

/**
 * Reads/writes to a filesystem cache
 */
class FileCache {

	/**
	 * @var string cache path
	 */
	protected $root;
	/**
	 * @var bool
	 */
	protected $enabled = true;
	/**
	 * @var int files time to live
	 */
	protected $ttl;
	/**
	 * @var int max total size
	 */
	protected $max_size;
	/**
	 * @var string key allowed chars (regex class)
	 */
	protected $whitelist;

	/**
	 * @param string $cache_dir  location of the cache
	 * @param int    $ttl        cache files default time to live (expiration)
	 * @param int    $max_size   max total cache size
	 * @param string $whitelist  List of characters that are allowed in path names (used in a regex character class)
	 */
	public function __construct( $cache_dir, $ttl, $max_size, $whitelist = 'a-z0-9._-' ) {
		$this->root      = Utils\trailingslashit( $cache_dir );
		$this->ttl       = (int) $ttl;
		$this->max_size  = (int) $max_size;
		$this->whitelist = $whitelist;

		if ( ! $this->ensure_dir_exists( $this->root ) ) {
			$this->enabled = false;
		}
	}

	/**
	 * Cache is enabled
	 *
	 * @return bool
	 */
	public function is_enabled() {
		return $this->enabled;
	}

	/**
	 * Cache root
	 *
	 * @return string
	 */
	public function get_root() {
		return $this->root;
	}


	/**
	 * Check if a file is in cache and return its filename
	 *
	 * @param string $key cache key
	 * @param int    $ttl time to live
	 * @return bool|string filename or false
	 */
	public function has( $key, $ttl = null ) {
		if ( ! $this->enabled ) {
			return false;
		}

		$filename = $this->filename( $key );

		if ( ! file_exists( $filename ) ) {
			return false;
		}

		// Use ttl param or global ttl.
		if ( null === $ttl ) {
			$ttl = $this->ttl;
		} elseif ( $this->ttl > 0 ) {
			$ttl = min( (int) $ttl, $this->ttl );
		} else {
			$ttl = (int) $ttl;
		}

		//
		if ( $ttl > 0 && ( filemtime( $filename ) + $ttl ) 