diff --git a/includes/src/vendor/klein/klein/tests/Klein/Tests/views/test.php b/includes/src/vendor/klein/klein/tests/Klein/Tests/views/test.php
new file mode 100644
index 0000000..f383522
--- /dev/null
+++ b/includes/src/vendor/klein/klein/tests/Klein/Tests/views/test.php
@@ -0,0 +1,2 @@
+My name is shared_data->get('name')); ?>.
+shared_data->get('verb')); ?>!
diff --git a/includes/src/vendor/klein/klein/tests/bootstrap.php b/includes/src/vendor/klein/klein/tests/bootstrap.php
new file mode 100644
index 0000000..1ca70e7
--- /dev/null
+++ b/includes/src/vendor/klein/klein/tests/bootstrap.php
@@ -0,0 +1,21 @@
+
+ * @author Trevor Suarez (Rican7) (contributor and v2 refactorer)
+ * @copyright (c) Chris O'Hara
+ * @link https://github.com/chriso/klein.php
+ * @license MIT
+ */
+
+// Set some configuration values
+ini_set('session.use_cookies', 0); // Don't send headers when testing sessions
+ini_set('session.cache_limiter', ''); // Don't send cache headers when testing sessions
+
+// Load our autoloader, and add our Test class namespace
+$autoloader = require(__DIR__ . '/../vendor/autoload.php');
+$autoloader->add('Klein\Tests', __DIR__);
+
+// Load our functions bootstrap
+require(__DIR__ . '/functions-bootstrap.php');
diff --git a/includes/src/vendor/klein/klein/tests/functions-bootstrap.php b/includes/src/vendor/klein/klein/tests/functions-bootstrap.php
new file mode 100644
index 0000000..a5fa65c
--- /dev/null
+++ b/includes/src/vendor/klein/klein/tests/functions-bootstrap.php
@@ -0,0 +1,52 @@
+
+ * @author Trevor Suarez (Rican7) (contributor and v2 refactorer)
+ * @copyright (c) Chris O'Hara
+ * @link https://github.com/chriso/klein.php
+ * @license MIT
+ */
+
+/**
+ * Really exploiting some functional/global PHP behaviors here. :P
+ */
+function implement_custom_fastcgi_function()
+{
+ // Check if the function doesn't exist
+ if (!function_exists('fastcgi_finish_request')) {
+ // Let's just define it then
+ function fastcgi_finish_request()
+ {
+ echo 'fastcgi_finish_request';
+ }
+ }
+}
+
+function implement_custom_apc_cache_functions()
+{
+ // Check if the function doesn't exist
+ if (!function_exists('apc_fetch')) {
+
+ function apc_fetch($key)
+ {
+ return false;
+ }
+
+ function apc_store($key, $value)
+ {
+ return false;
+ }
+ }
+}
+
+function test_num_args_wrapper($args)
+{
+ echo func_num_args();
+}
+
+function test_response_edit_wrapper($klein)
+{
+ $klein->response()->body('after callbacks!');
+}
diff --git a/includes/src/vendor/lobby/lobby/src/CSRF.php b/includes/src/vendor/lobby/lobby/src/CSRF.php
new file mode 100644
index 0000000..c7927c7
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/CSRF.php
@@ -0,0 +1,53 @@
+";
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Helper.php b/includes/src/vendor/lobby/lobby/src/Helper.php
new file mode 100644
index 0000000..9ac75ef
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Helper.php
@@ -0,0 +1,23 @@
+ $function_to_add, 'accepted_args' => $accepted_args);
+ unset( self::$mergedFilters[ $tag ] );
+ return true;
+ }
+
+ /**
+ * removeFilter Removes a function from a specified filter hook.
+ * @access public
+ * @since 0.1
+ * @param string $tag The filter hook to which the function to be removed is hooked.
+ * @param callback $function_to_remove The name of the function which should be removed.
+ * @param int $priority optional. The priority of the function (default: 10).
+ * @param int $accepted_args optional. The number of arguments the function accepts (default: 1).
+ * @return boolean Whether the function existed before it was removed.
+ */
+ public static function removeFilter( $tag, $function_to_remove, $priority = 10 ) {
+ $function_to_remove = self::_filterBuildUniqueID($tag, $function_to_remove, $priority);
+
+ $r = isset(self::$filters[$tag][$priority][$function_to_remove]);
+
+ if ( true === $r) {
+ unset(self::$filters[$tag][$priority][$function_to_remove]);
+ if ( empty(self::$filters[$tag][$priority]) )
+ unset(self::$filters[$tag][$priority]);
+ unset(self::$mergedFilters[$tag]);
+ }
+ return $r;
+ }
+
+ /**
+ * removeAllFilters Remove all of the hooks from a filter.
+ * @access public
+ * @since 0.1
+ * @param string $tag The filter to remove hooks from.
+ * @param int $priority The priority number to remove.
+ * @return bool True when finished.
+ */
+ public static function removeAllFilters($tag, $priority = false) {
+ if( isset(self::$filters[$tag]) ) {
+ if( false !== $priority && isset(self::$filters[$tag][$priority]) )
+ unset(self::$filters[$tag][$priority]);
+ else
+ unset(self::$filters[$tag]);
+ }
+
+ if( isset(self::$mergedFilters[$tag]) )
+ unset(self::$mergedFilters[$tag]);
+
+ return true;
+ }
+
+ /**
+ * hasFilter Check if any filter has been registered for a hook.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the filter hook.
+ * @param callback $function_to_check optional.
+ * @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered.
+ * When checking a specific function, the priority of that hook is returned, or false if the function is not attached.
+ * When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false
+ * (e.g.) 0, so use the === operator for testing the return value.
+ */
+ public static function hasFilter($tag, $function_to_check = false) {
+ $has = !empty(self::$filters[$tag]);
+ if ( false === $function_to_check || false == $has )
+ return $has;
+
+ if ( !$idx = self::_filterBuildUniqueID($tag, $function_to_check, false) )
+ return false;
+
+ foreach ( (array) array_keys(self::$filters[$tag]) as $priority ) {
+ if ( isset(self::$filters[$tag][$priority][$idx]) )
+ return $priority;
+ }
+ return false;
+ }
+
+ /**
+ * applyFilters Call the functions added to a filter hook.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the filter hook.
+ * @param mixed $value The value on which the filters hooked to $tag are applied on.
+ * @param mixed $var,... Additional variables passed to the functions hooked to $tag.
+ * @return mixed The filtered value after all hooked functions are applied to it.
+ */
+ public static function applyFilters($tag, $value) {
+ $args = array();
+ // Do 'all' actions first
+ if ( isset(self::$filters['all']) ) {
+ self::$currentFilter[] = $tag;
+ $args = func_get_args();
+ self::$__callAllHook($args);
+ }
+
+ if ( !isset(self::$filters[$tag]) ) {
+ if ( isset(self::$filters['all']) )
+ array_pop(self::$currentFilter);
+ return $value;
+ }
+
+ if ( !isset(self::$filters['all']) )
+ self::$currentFilter[] = $tag;
+
+ // Sort
+ if ( !isset( self::$mergedFilters[ $tag ] ) ) {
+ ksort(self::$filters[$tag]);
+ self::$mergedFilters[ $tag ] = true;
+ }
+
+ reset( self::$filters[ $tag ] );
+
+ if ( empty($args) )
+ $args = func_get_args();
+
+ do {
+ foreach( (array) current(self::$filters[$tag]) as $the_ )
+ if ( !is_null($the_['function']) ){
+ $args[1] = $value;
+ $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
+ }
+
+ } while ( next(self::$filters[$tag]) !== false );
+
+ array_pop( self::$currentFilter );
+
+ return $value;
+ }
+
+ /**
+ * applyFiltersRefArray Execute functions hooked on a specific filter hook, specifying arguments in an array.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the filter hook.
+ * @param array $args The arguments supplied to the functions hooked to $tag
+ * @return mixed The filtered value after all hooked functions are applied to it.
+ */
+ public static function applyFiltersRefArray($tag, $args) {
+ // Do 'all' actions first
+ if ( isset(self::$filters['all']) ) {
+ self::$currentFilter[] = $tag;
+ $all_args = func_get_args();
+ self::$__callAllHook($all_args);
+ }
+
+ if ( !isset(self::$filters[$tag]) ) {
+ if ( isset(self::$filters['all']) )
+ array_pop(self::$currentFilter);
+ return $args[0];
+ }
+
+ if ( !isset(self::$filters['all']) )
+ self::$currentFilter[] = $tag;
+
+ // Sort
+ if ( !isset( self::$mergedFilters[ $tag ] ) ) {
+ ksort(self::$filters[$tag]);
+ self::$mergedFilters[ $tag ] = true;
+ }
+
+ reset( self::$filters[ $tag ] );
+
+ do {
+ foreach( (array) current(self::$filters[$tag]) as $the_ )
+ if ( !is_null($the_['function']) )
+ $args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
+
+ } while ( next(self::$filters[$tag]) !== false );
+
+ array_pop( self::$currentFilter );
+
+ return $args[0];
+ }
+
+ /**
+ * ACTIONS
+ */
+
+ /**
+ * addAction Hooks a function on to a specific action.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the action to which the $function_to_add is hooked.
+ * @param callback $function_to_add The name of the function you wish to be called.
+ * @param int $priority optional. Used to specify the order in which the functions associated with a particular action are executed (default: 10). Lower numbers correspond with earlier execution, and functions with the same priority are executed in the order in which they were added to the action.
+ * @param int $accepted_args optional. The number of arguments the function accept (default 1).
+ */
+ public static function addAction($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
+ /**
+ * If same function to multiple tags (separated by comma [,])
+ */
+ if(preg_match("/\,/i", $tag) !== 0){
+ $output = array();
+ $tags = explode(",", $tag);
+ foreach($tags as $tag){
+ $output[] = self::addAction($tag, $function_to_add, $priority, $accepted_args);
+ }
+ return $output;
+ }
+
+ return self::addFilter($tag, $function_to_add, $priority, $accepted_args);
+ }
+
+ /**
+ * hasAction Check if any action has been registered for a hook.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the action hook.
+ * @param callback $function_to_check optional.
+ * @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered.
+ * When checking a specific function, the priority of that hook is returned, or false if the function is not attached.
+ * When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false
+ * (e.g.) 0, so use the === operator for testing the return value.
+ */
+ public static function hasAction($tag, $function_to_check = false) {
+ return self::hasFilter($tag, $function_to_check);
+ }
+
+ /**
+ * removeAction Removes a function from a specified action hook.
+ * @access public
+ * @since 0.1
+ * @param string $tag The action hook to which the function to be removed is hooked.
+ * @param callback $function_to_remove The name of the function which should be removed.
+ * @param int $priority optional The priority of the function (default: 10).
+ * @return boolean Whether the function is removed.
+ */
+ public static function removeAction( $tag, $function_to_remove, $priority = 10 ) {
+ return self::removeFilter( $tag, $function_to_remove, $priority );
+ }
+
+ /**
+ * removeAllActions Remove all of the hooks from an action.
+ * @access public
+ * @since 0.1
+ * @param string $tag The action to remove hooks from.
+ * @param int $priority The priority number to remove them from.
+ * @return bool True when finished.
+ */
+ public static function removeAllActions($tag, $priority = false) {
+ return self::removeAllFilters($tag, $priority);
+ }
+
+ /**
+ * doAction Execute functions hooked on a specific action hook.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the action to be executed.
+ * @param mixed $arg,... Optional additional arguments which are passed on to the functions hooked to the action.
+ * @return null Will return null if $tag does not exist in $filter array
+ */
+ public static function doAction($tag, $arg = '') {
+
+ if ( ! isset(self::$actions) )
+ self::$actions = array();
+
+ if ( ! isset(self::$actions[$tag]) )
+ self::$actions[$tag] = 1;
+ else
+ ++self::$actions[$tag];
+
+ // Do 'all' actions first
+ if ( isset(self::$filters['all']) ) {
+ self::$currentFilter[] = $tag;
+ $all_args = func_get_args();
+ self::$__callAllHook($all_args);
+ }
+
+ if ( !isset(self::$filters[$tag]) ) {
+ if ( isset(self::$filters['all']) )
+ array_pop(self::$currentFilter);
+ return;
+ }
+
+ if ( !isset(self::$filters['all']) )
+ self::$currentFilter[] = $tag;
+
+ $args = array();
+ if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
+ $args[] =& $arg[0];
+ else
+ $args[] = $arg;
+ for ( $a = 2; $a < func_num_args(); $a++ )
+ $args[] = func_get_arg($a);
+
+ // Sort
+ if ( !isset( self::$mergedFilters[ $tag ] ) ) {
+ ksort(self::$filters[$tag]);
+ self::$mergedFilters[ $tag ] = true;
+ }
+
+ reset( self::$filters[ $tag ] );
+
+ do {
+ foreach ( (array) current(self::$filters[$tag]) as $the_ )
+ if ( !is_null($the_['function']) )
+ call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
+
+ } while ( next(self::$filters[$tag]) !== false );
+
+ array_pop(self::$currentFilter);
+ }
+
+ /**
+ * doActionRefArray Execute functions hooked on a specific action hook, specifying arguments in an array.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the action to be executed.
+ * @param array $args The arguments supplied to the functions hooked to $tag
+ * @return null Will return null if $tag does not exist in $filter array
+ */
+ public static function doActionRefArray($tag, $args) {
+
+ if ( ! isset(self::$actions) )
+ self::$actions = array();
+
+ if ( ! isset(self::$actions[$tag]) )
+ self::$actions[$tag] = 1;
+ else
+ ++self::$actions[$tag];
+
+ // Do 'all' actions first
+ if ( isset(self::$filters['all']) ) {
+ self::$currentFilter[] = $tag;
+ $all_args = func_get_args();
+ self::$__callAllHook($all_args);
+ }
+
+ if ( !isset(self::$filters[$tag]) ) {
+ if ( isset(self::$filters['all']) )
+ array_pop(self::$currentFilter);
+ return;
+ }
+
+ if ( !isset(self::$filters['all']) )
+ self::$currentFilter[] = $tag;
+
+ // Sort
+ if ( !isset( $mergedFilters[ $tag ] ) ) {
+ ksort(self::$filters[$tag]);
+ $mergedFilters[ $tag ] = true;
+ }
+
+ reset( self::$filters[ $tag ] );
+
+ do {
+ foreach( (array) current(self::$filters[$tag]) as $the_ )
+ if ( !is_null($the_['function']) )
+ call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
+
+ } while ( next(self::$filters[$tag]) !== false );
+
+ array_pop(self::$currentFilter);
+ }
+
+ /**
+ * didAction Retrieve the number of times an action is fired.
+ * @access public
+ * @since 0.1
+ * @param string $tag The name of the action hook.
+ * @return int The number of times action hook $tag is fired
+ */
+ public static function didAction($tag) {
+
+ if ( ! isset( self::$actions ) || ! isset( self::$actions[$tag] ) )
+ return 0;
+
+ return self::$actions[$tag];
+ }
+
+ /**
+ * HELPERS
+ */
+
+ /**
+ * currentFilter Retrieve the name of the current filter or action.
+ * @access public
+ * @since 0.1
+ * @return string Hook name of the current filter or action.
+ */
+ public static function currentFilter() {
+ return end( self::$currentFilter );
+ }
+
+ /**
+ * Retrieve the name of the current action.
+ *
+ * @since 0.1.2
+ *
+ * @uses currentFilter()
+ *
+ * @return string Hook name of the current action.
+ */
+ function currentAction() {
+ return self::$currentFilter();
+ }
+
+ /**
+ * Retrieve the name of a filter currently being processed.
+ *
+ * The function currentFilter() only returns the most recent filter or action
+ * being executed. didAction() returns true once the action is initially
+ * processed. This function allows detection for any filter currently being
+ * executed (despite not being the most recent filter to fire, in the case of
+ * hooks called from hook callbacks) to be verified.
+ *
+ * @since 0.1.2
+ *
+ * @see currentFilter()
+ * @see didAction()
+ * @global array $wp_currentFilter Current filter.
+ *
+ * @param null|string $filter Optional. Filter to check. Defaults to null, which
+ * checks if any filter is currently being run.
+ * @return bool Whether the filter is currently in the stack
+ */
+ function doingFilter( $filter = null ) {
+ if ( null === $filter ) {
+ return ! empty( self::$currentFilter );
+ }
+ return in_array( $filter, self::$currentFilter );
+ }
+
+ /**
+ * Retrieve the name of an action currently being processed.
+ *
+ * @since 0.1.2
+ *
+ * @uses doingFilter()
+ *
+ * @param string|null $action Optional. Action to check. Defaults to null, which checks
+ * if any action is currently being run.
+ * @return bool Whether the action is currently in the stack.
+ */
+ public static function doingAction( $action = null ) {
+ return self::$doingFilter( $action );
+ }
+
+ /**
+ * _filterBuildUniqueID Build Unique ID for storage and retrieval.
+ * @param string $tag Used in counting how many hooks were applied
+ * @param callback $function Used for creating unique id
+ * @param int|bool $priority Used in counting how many hooks were applied. If === false and $function is an object reference, we return the unique id only if it already has one, false otherwise.
+ * @return string|bool Unique ID for usage as array key or false if $priority === false and $function is an object reference, and it does not already have a unique id.
+ */
+ private static function _filterBuildUniqueID($tag, $function, $priority) {
+ static $filter_id_count = 0;
+
+ if ( is_string($function) )
+ return $function;
+
+ if ( is_object($function) ) {
+ // Closures are currently implemented as objects
+ $function = array( $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];
+ } else {
+ $obj_idx = get_class($function[0]).$function[1];
+ if ( !isset($function[0]->filter_id) ) {
+ if ( false === $priority )
+ return false;
+ $obj_idx .= isset(self::$filters[$tag][$priority]) ? count((array)self::$filters[$tag][$priority]) : $filter_id_count;
+ $function[0]->filter_id = $filter_id_count;
+ ++$filter_id_count;
+ } else {
+ $obj_idx .= $function[0]->filter_id;
+ }
+
+ return $obj_idx;
+ }
+ } else if ( is_string($function[0]) ) {
+ // Static Calling
+ return $function[0].$function[1];
+ }
+ }
+
+ /**
+ * __callAllHook
+ * @access public
+ * @since 0.1
+ * @param (array) $args [description]
+ */
+ public static function __callAllHook($args) {
+ reset( self::$filters['all'] );
+ do {
+ foreach( (array) current(self::$filters['all']) as $the_ )
+ if ( !is_null($the_['function']) )
+ call_user_func_array($the_['function'], $args);
+
+ } while ( next(self::$filters['all']) !== false );
+ }
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Lobby/AppRouter.php b/includes/src/vendor/lobby/lobby/src/Lobby/AppRouter.php
new file mode 100644
index 0000000..142db5f
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Lobby/AppRouter.php
@@ -0,0 +1,41 @@
+app = $App;
+ $this->router = new Klein();
+ }
+
+ public function route($route, $callback) {
+ $app = $this->app;
+ $this->router->respond($route, function($request) use($app, $callback){
+ return call_user_func_array($callback, array($app, $request));
+ });
+ }
+
+ /**
+ * Parse the routes and return response content
+ */
+ public function dispatch(){
+ $request = Request::createFromGlobals();
+ $uri = $request->server()->get('REQUEST_URI');
+
+ /**
+ * Set the request URI without the "/app/ID" part in it
+ */
+ $request->server()->set('REQUEST_URI', substr($uri, strlen("/app/{$this->app->id}")));
+
+ return $this->router->dispatch($request, null, false, Klein::DISPATCH_CAPTURE_AND_RETURN);
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Lobby/CLI.php b/includes/src/vendor/lobby/lobby/src/Lobby/CLI.php
new file mode 100644
index 0000000..fd0157a
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Lobby/CLI.php
@@ -0,0 +1,38 @@
+addArgument("command");
+ }
+
+ protected function getCommandName(InputInterface $input) {
+ if($input->getFirstArgument())
+ return "lobby " . $input->getFirstArgument();
+ return "lobby";
+ }
+
+ /**
+ * Gets the default commands that should always be available.
+ *
+ * @return array An array of default Command instances
+ */
+ protected function getDefaultCommands(){
+ // Keep the core default commands to have the HelpCommand
+ // which is used when using the --help option
+ $defaultCommands = parent::getDefaultCommands();
+
+ $defaultCommands[] = new CLI\App();
+ $defaultCommands[] = new CLI\Lobby();
+
+ return $defaultCommands;
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Lobby/CLI/App.php b/includes/src/vendor/lobby/lobby/src/Lobby/CLI/App.php
new file mode 100644
index 0000000..022a28b
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Lobby/CLI/App.php
@@ -0,0 +1,44 @@
+setName("lobby app")
+ ->setDescription("Control an app")
+ ->setHelp("Helps you to manage an app");
+
+ $this->addOption("a", null, InputOption::VALUE_REQUIRED, "The App ID", 0);
+ $this->addOption("i", null, InputOption::VALUE_OPTIONAL, "Path to file in app to include", null);
+ $this->addOption("data", null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, "Parameters to pass to script", array());
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ $appID = $input->getOption("a");
+
+ $App = new \Lobby\Apps($appID);
+ if(!$App->exists){
+ $output->writeln("App doesn't exist>");
+ exit;
+ }
+
+ $AppClass = $App->getInstance();
+
+ $data = array();
+ if($input->getOption("data")){
+ foreach($input->getOption("data") as $v){
+ list($key, $value) = explode("=", $v);
+ $data[$key] = $value;
+ }
+ }
+
+ if($input->getOption("i"))
+ echo $AppClass->inc($input->getOption("i"), $data);
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Lobby/CLI/Lobby.php b/includes/src/vendor/lobby/lobby/src/Lobby/CLI/Lobby.php
new file mode 100644
index 0000000..19d53b4
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Lobby/CLI/Lobby.php
@@ -0,0 +1,27 @@
+setName("lobby")
+ ->setDescription("Control an app")
+ ->setHelp("Helps you to manage an app");
+ $this->addOption("v", null, InputOption::VALUE_OPTIONAL, "Show version", 1);
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ if($input->getOption("v")){
+ if($input->getOption("v") === "code")
+ $output->writeln(\Lobby::getVersion());
+ else
+ $output->writeln(\Lobby::getVersion(true));
+ }
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Lobby/FSObj.php b/includes/src/vendor/lobby/lobby/src/Lobby/FSObj.php
new file mode 100644
index 0000000..ce67f80
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Lobby/FSObj.php
@@ -0,0 +1,36 @@
+base = FS::rel($base);
+ }
+
+ /**
+ * Map static functions into object methods
+ */
+ public function __call($function, $args){
+ switch($function){
+ case "exists":
+ case "loc":
+ return FS::$function($this->base . "/" . $args[0]);
+ case "get":
+ return FS::get($this->base . "/" . $args[0]);
+ case "write":
+ case "remove":
+ return call_user_func_array(FS::$function, array(
+ $this->base . "/" . $args[0], $args[1], $args[2]
+ ));
+ }
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Request.php b/includes/src/vendor/lobby/lobby/src/Request.php
new file mode 100644
index 0000000..4f6c67e
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Request.php
@@ -0,0 +1,88 @@
+get($key, $default);
+ if($val !== null)
+ $val = urldecode($val);
+ return $val;
+ }
+
+ public static function getParam($key, $default = null){
+ return self::$request->query->get($key, $default);
+ }
+
+ public static function postParam($key, $default = null){
+ return self::$request->request->get($key, $default);
+ }
+
+ public static function getRequestObject(){
+ return self::$request;
+ }
+
+ public static function getRequestURI(){
+ return self::$requestURI;
+ }
+
+ public static function isGET(){
+ return self::$isGET;
+ }
+
+ public static function isPOST(){
+ return self::$isPOST;
+ }
+
+}
diff --git a/includes/src/vendor/lobby/lobby/src/Response.php b/includes/src/vendor/lobby/lobby/src/Response.php
new file mode 100644
index 0000000..fb3a3a9
--- /dev/null
+++ b/includes/src/vendor/lobby/lobby/src/Response.php
@@ -0,0 +1,177 @@
+setCharset("UTF-8");
+ }
+
+ public static function setStatusCode($status){
+ self::$response->setStatusCode($status);
+ }
+
+ public static function setContent($content){
+ if(self::$pageContent !== null)
+ self::$pageContent = null;
+ self::$response->setContent($content);
+ }
+
+ public static function setPage($content){
+ self::$pageContent = $content;
+ }
+
+ public static function getFile($location, $vars = array()){
+ extract($vars);
+ ob_start();
+ require FS::loc($location);
+ return ob_get_clean();
+ }
+
+ public static function loadPage($location){
+ self::setPage(self::getFile($location));
+ }
+
+ public static function getContent(){
+ return self::$response->getContent();
+ }
+
+ public static function getPageContent(){
+ return self::$pageContent;
+ }
+
+ public static function hasContent(){
+ return (self::$pageContent != null || self::$response->getContent() != null);
+ }
+
+ /**
+ * Display a plain error page
+ * Default: 400, If $title & $content is passed, 500
+ */
+ public static function showError($title = null, $description = null){
+ if($title === null){
+ self::setStatusCode(400);
+ $title = "404 Not Found";
+ $description = "The requested path was not found in Lobby";
+ }else{
+ self::setStatusCode(500);
+ }
+
+ self::setContent(self::getFile("includes/lib/lobby/inc/view.error.php", array(
+ "title" => $title,
+ "description" => $description
+ )));
+
+ self::send();
+ exit;
+ }
+
+ public static function send(){
+ if(self::$pageContent !== null){
+ ob_start();
+ require L_DIR . "/includes/lib/lobby/inc/view.page.php";
+ $html = ob_get_clean();
+ self::setContent($html);
+ }
+
+ self::$response->prepare(Request::getRequestObject());
+ self::$response->send();
+ }
+
+ /**
+ * Print the tag
+ */
+ public static function head($title = ""){
+ header('Content-type: text/html; charset=utf-8');
+ if($title != ""){
+ self::setTitle($title);
+ }
+
+ if(Assets::issetJS('jquery')){
+ /**
+ * Load jQuery, jQuery UI, Lobby Main, App separately without async
+ */
+ $url = L_URL . "/includes/serve-assets.php?type=js&assets=" . implode(",", array(
+ Assets::getJS('jquery'),
+ Assets::getJS('jqueryui'),
+ Assets::getJS('main'),
+ Assets::issetJS('app') ? Assets::getJS('app') : ""
+ ));
+ echo "";
+
+ Assets::removeJS("jquery");
+ Assets::removeJS("jqueryui");
+ Assets::removeJS("main");
+ }
+
+ $jsURLParams = array(
+ "THEME_URL" => Themes::getThemeURL()
+ );
+
+ if(Apps::isAppRunning()){
+ $jsURLParams["APP_URL"] = urlencode(Apps::getInfo("url"));
+ $jsURLParams["APP_SRC"] = urlencode(Apps::getInfo("srcURL"));
+ }
+
+ $jsURL = Assets::getServeURL("js", $jsURLParams);
+
+ echo "";
+
+ $cssServeParams = array(
+ "THEME_URL" => THEME_URL
+ );
+
+ /**
+ * CSS Files
+ */
+ if(Apps::isAppRunning()){
+ $cssServeParams["APP_URL"] = urlencode(Apps::getInfo("url"));
+ $cssServeParams["APP_SRC"] = urlencode(Apps::getInfo("srcURL"));
+ }
+ echo Assets::getServeLinkTag($cssServeParams);
+
+ echo "";
+
+ /* Title */
+ echo "" . self::$title . "";
+ }
+
+ /**
+ * Set the Page title
+ */
+ public static function setTitle($title = ""){
+ if($title != ""){
+ self::$title = $title;
+ if(self::$title == ""){
+ self::$title = "Lobby";
+ }else{
+ self::$title .= " - Lobby";
+ }
+ }
+ }
+
+ /**
+ * A redirect function that support HTTP status code for redirection
+ * 302 = Moved Temporarily
+ */
+ public static function redirect($url, $status = 302){
+ $url = \Lobby::u($url);
+ header("Location: $url", true, $status);
+ exit;
+ }
+
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/Auth/Basic.php b/includes/src/vendor/rmccue/requests/tests/Auth/Basic.php
new file mode 100644
index 0000000..9f19014
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Auth/Basic.php
@@ -0,0 +1,87 @@
+markTestSkipped($transport . ' is not available');
+ return;
+ }
+
+ $options = array(
+ 'auth' => array('user', 'passwd'),
+ 'transport' => $transport,
+ );
+ $request = Requests::get('http://httpbin.org/basic-auth/user/passwd', array(), $options);
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body);
+ $this->assertEquals(true, $result->authenticated);
+ $this->assertEquals('user', $result->user);
+ }
+
+ /**
+ * @dataProvider transportProvider
+ */
+ public function testUsingInstantiation($transport) {
+ if (!call_user_func(array($transport, 'test'))) {
+ $this->markTestSkipped($transport . ' is not available');
+ return;
+ }
+
+ $options = array(
+ 'auth' => new Requests_Auth_Basic(array('user', 'passwd')),
+ 'transport' => $transport,
+ );
+ $request = Requests::get('http://httpbin.org/basic-auth/user/passwd', array(), $options);
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body);
+ $this->assertEquals(true, $result->authenticated);
+ $this->assertEquals('user', $result->user);
+ }
+
+ /**
+ * @dataProvider transportProvider
+ */
+ public function testPOSTUsingInstantiation($transport) {
+ if (!call_user_func(array($transport, 'test'))) {
+ $this->markTestSkipped($transport . ' is not available');
+ return;
+ }
+
+ $options = array(
+ 'auth' => new Requests_Auth_Basic(array('user', 'passwd')),
+ 'transport' => $transport,
+ );
+ $data = 'test';
+ $request = Requests::post('http://httpbin.org/post', array(), $data, $options);
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body);
+
+ $auth = $result->headers->Authorization;
+ $auth = explode(' ', $auth);
+
+ $this->assertEquals(base64_encode('user:passwd'), $auth[1]);
+ $this->assertEquals('test', $result->data);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testMissingPassword() {
+ $auth = new Requests_Auth_Basic(array('user'));
+ }
+
+}
\ No newline at end of file
diff --git a/includes/src/vendor/rmccue/requests/tests/ChunkedEncoding.php b/includes/src/vendor/rmccue/requests/tests/ChunkedEncoding.php
new file mode 100644
index 0000000..fa87538
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/ChunkedEncoding.php
@@ -0,0 +1,68 @@
+body = $body;
+ $transport->chunked = true;
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+
+ $this->assertEquals($expected, $response->body);
+ }
+
+ /**
+ * Response says it's chunked, but actually isn't
+ */
+ public function testNotActuallyChunked() {
+ $transport = new MockTransport();
+ $transport->body = 'Hello! This is a non-chunked response!';
+ $transport->chunked = true;
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+
+ $this->assertEquals($transport->body, $response->body);
+ }
+
+ /**
+ * Response says it's chunked and starts looking like it is, but turns out
+ * that they're lying to us
+ */
+ public function testMixedChunkiness() {
+ $transport = new MockTransport();
+ $transport->body = "02\r\nab\r\nNot actually chunked!";
+ $transport->chunked = true;
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ $this->assertEquals($transport->body, $response->body);
+ }
+}
\ No newline at end of file
diff --git a/includes/src/vendor/rmccue/requests/tests/Cookies.php b/includes/src/vendor/rmccue/requests/tests/Cookies.php
new file mode 100644
index 0000000..0348fd8
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Cookies.php
@@ -0,0 +1,174 @@
+assertEquals('requests-testcookie', $cookie->name);
+ $this->assertEquals('testvalue', $cookie->value);
+ $this->assertEquals('testvalue', (string) $cookie);
+
+ $this->assertEquals('requests-testcookie=testvalue', $cookie->formatForHeader());
+ $this->assertEquals('requests-testcookie=testvalue', $cookie->formatForSetCookie());
+ }
+
+ public function testCookieWithAttributes() {
+ $attributes = array(
+ 'httponly',
+ 'path' => '/'
+ );
+ $cookie = new Requests_Cookie('requests-testcookie', 'testvalue', $attributes);
+
+ $this->assertEquals('requests-testcookie=testvalue', $cookie->formatForHeader());
+ $this->assertEquals('requests-testcookie=testvalue; httponly; path=/', $cookie->formatForSetCookie());
+ }
+
+ public function testEmptyCookieName() {
+ $cookie = Requests_Cookie::parse('test');
+ $this->assertEquals('', $cookie->name);
+ $this->assertEquals('test', $cookie->value);
+ }
+
+ public function testEmptyAttributes() {
+ $cookie = Requests_Cookie::parse('foo=bar; HttpOnly');
+ $this->assertTrue($cookie->attributes['httponly']);
+ }
+
+ public function testCookieJarSetter() {
+ $jar1 = new Requests_Cookie_Jar();
+ $jar1['requests-testcookie'] = 'testvalue';
+
+ $jar2 = new Requests_Cookie_Jar(array(
+ 'requests-testcookie' => 'testvalue',
+ ));
+ $this->assertEquals($jar1, $jar2);
+ }
+
+ public function testCookieJarUnsetter() {
+ $jar = new Requests_Cookie_Jar();
+ $jar['requests-testcookie'] = 'testvalue';
+
+ $this->assertEquals('testvalue', $jar['requests-testcookie']);
+
+ unset($jar['requests-testcookie']);
+ $this->assertEmpty($jar['requests-testcookie']);
+ $this->assertFalse(isset($jar['requests-testcookie']));
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testCookieJarAsList() {
+ $cookies = new Requests_Cookie_Jar();
+ $cookies[] = 'requests-testcookie1=testvalue1';
+ }
+
+ public function testCookieJarIterator() {
+ $cookies = array(
+ 'requests-testcookie1' => 'testvalue1',
+ 'requests-testcookie2' => 'testvalue2',
+ );
+ $jar = new Requests_Cookie_Jar($cookies);
+
+ foreach ($jar as $key => $value) {
+ $this->assertEquals($cookies[$key], $value);
+ }
+ }
+
+ public function testReceivingCookies() {
+ $options = array(
+ 'follow_redirects' => false,
+ );
+ $url = 'http://httpbin.org/cookies/set?requests-testcookie=testvalue';
+
+ $response = Requests::get($url, array(), $options);
+
+ $cookie = $response->cookies['requests-testcookie'];
+ $this->assertNotEmpty( $cookie );
+ $this->assertEquals( 'testvalue', $cookie->value );
+ }
+
+ public function testPersistenceOnRedirect() {
+ $options = array(
+ 'follow_redirects' => true,
+ );
+ $url = 'http://httpbin.org/cookies/set?requests-testcookie=testvalue';
+
+ $response = Requests::get($url, array(), $options);
+
+ $cookie = $response->cookies['requests-testcookie'];
+ $this->assertNotEmpty( $cookie );
+ $this->assertEquals( 'testvalue', $cookie->value );
+ }
+
+ protected function setCookieRequest($cookies) {
+ $options = array(
+ 'cookies' => $cookies,
+ );
+ $response = Requests::get('http://httpbin.org/cookies/set', array(), $options);
+
+ $data = json_decode($response->body, true);
+ $this->assertInternalType('array', $data);
+ $this->assertArrayHasKey('cookies', $data);
+ return $data['cookies'];
+ }
+
+ public function testSendingCookie() {
+ $cookies = array(
+ 'requests-testcookie1' => 'testvalue1',
+ );
+
+ $data = $this->setCookieRequest($cookies);
+
+ $this->assertArrayHasKey('requests-testcookie1', $data);
+ $this->assertEquals('testvalue1', $data['requests-testcookie1']);
+ }
+
+ public function testSendingCookieWithJar() {
+ $cookies = new Requests_Cookie_Jar(array(
+ 'requests-testcookie1' => 'testvalue1',
+ ));
+ $data = $this->setCookieRequest($cookies);
+
+ $this->assertArrayHasKey('requests-testcookie1', $data);
+ $this->assertEquals('testvalue1', $data['requests-testcookie1']);
+ }
+
+ public function testSendingMultipleCookies() {
+ $cookies = array(
+ 'requests-testcookie1' => 'testvalue1',
+ 'requests-testcookie2' => 'testvalue2',
+ );
+ $data = $this->setCookieRequest($cookies);
+
+ $this->assertArrayHasKey('requests-testcookie1', $data);
+ $this->assertEquals('testvalue1', $data['requests-testcookie1']);
+
+ $this->assertArrayHasKey('requests-testcookie2', $data);
+ $this->assertEquals('testvalue2', $data['requests-testcookie2']);
+ }
+
+ public function testSendingMultipleCookiesWithJar() {
+ $cookies = new Requests_Cookie_Jar(array(
+ 'requests-testcookie1' => 'testvalue1',
+ 'requests-testcookie2' => 'testvalue2',
+ ));
+ $data = $this->setCookieRequest($cookies);
+
+ $this->assertArrayHasKey('requests-testcookie1', $data);
+ $this->assertEquals('testvalue1', $data['requests-testcookie1']);
+
+ $this->assertArrayHasKey('requests-testcookie2', $data);
+ $this->assertEquals('testvalue2', $data['requests-testcookie2']);
+ }
+
+ public function testSendingPrebakedCookie() {
+ $cookies = new Requests_Cookie_Jar(array(
+ new Requests_Cookie('requests-testcookie', 'testvalue'),
+ ));
+ $data = $this->setCookieRequest($cookies);
+
+ $this->assertArrayHasKey('requests-testcookie', $data);
+ $this->assertEquals('testvalue', $data['requests-testcookie']);
+ }
+}
\ No newline at end of file
diff --git a/includes/src/vendor/rmccue/requests/tests/Encoding.php b/includes/src/vendor/rmccue/requests/tests/Encoding.php
new file mode 100644
index 0000000..7e2f138
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Encoding.php
@@ -0,0 +1,94 @@
+ $set) {
+ $real_set = self::mapData($key, $set);
+ $data = array_merge($data, $real_set);
+ }
+ return $data;
+ }
+
+ /**
+ * @dataProvider encodedData
+ */
+ public function testDecompress($original, $encoded) {
+ $decoded = Requests::decompress($encoded);
+ $this->assertEquals($original, $decoded);
+ }
+
+ /**
+ * @dataProvider encodedData
+ */
+ public function testCompatibleInflate($original, $encoded) {
+ $decoded = Requests::compatible_gzinflate($encoded);
+ $this->assertEquals($original, $decoded);
+ }
+
+ protected function bin2hex($field) {
+ $field = bin2hex($field);
+ $field = chunk_split($field,2,"\\x");
+ $field = "\\x" . substr($field,0,-2);
+ return $field;
+ }
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/IDNAEncoder.php b/includes/src/vendor/rmccue/requests/tests/IDNAEncoder.php
new file mode 100644
index 0000000..24df2de
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/IDNAEncoder.php
@@ -0,0 +1,102 @@
+assertEquals($expected, $result);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testASCIITooLong() {
+ $data = str_repeat("abcd", 20);
+ $result = Requests_IDNAEncoder::encode($data);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testEncodedTooLong() {
+ $data = str_repeat("\xe4\xbb\x96", 60);
+ $result = Requests_IDNAEncoder::encode($data);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testAlreadyPrefixed() {
+ $result = Requests_IDNAEncoder::encode("xn--\xe4\xbb\x96");
+ }
+
+ public function testASCIICharacter() {
+ $result = Requests_IDNAEncoder::encode("a");
+ $this->assertEquals('a', $result);
+ }
+
+ public function testTwoByteCharacter() {
+ $result = Requests_IDNAEncoder::encode("\xc2\xb6"); // Pilcrow character
+ $this->assertEquals('xn--tba', $result);
+ }
+
+ public function testThreeByteCharacter() {
+ $result = Requests_IDNAEncoder::encode("\xe2\x82\xac"); // Euro symbol
+ $this->assertEquals('xn--lzg', $result);
+ }
+
+ public function testFourByteCharacter() {
+ $result = Requests_IDNAEncoder::encode("\xf0\xa4\xad\xa2"); // Chinese symbol?
+ $this->assertEquals('xn--ww6j', $result);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testFiveByteCharacter() {
+ $result = Requests_IDNAEncoder::encode("\xfb\xb6\xb6\xb6\xb6");
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testSixByteCharacter() {
+ $result = Requests_IDNAEncoder::encode("\xfd\xb6\xb6\xb6\xb6\xb6");
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testInvalidASCIICharacterWithMultibyte() {
+ $result = Requests_IDNAEncoder::encode("\0\xc2\xb6");
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testUnfinishedMultibyte() {
+ $result = Requests_IDNAEncoder::encode("\xc2");
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testPartialMultibyte() {
+ $result = Requests_IDNAEncoder::encode("\xc2\xc2\xb6");
+ }
+}
\ No newline at end of file
diff --git a/includes/src/vendor/rmccue/requests/tests/IRI.php b/includes/src/vendor/rmccue/requests/tests/IRI.php
new file mode 100644
index 0000000..db0fef4
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/IRI.php
@@ -0,0 +1,418 @@
+assertEquals($expected, Requests_IRI::absolutize($base, $relative)->iri);
+ $this->assertEquals($expected, (string) Requests_IRI::absolutize($base, $relative));
+ }
+
+ /**
+ * @dataProvider rfc3986_tests
+ */
+ public function testBothStringRFC3986($relative, $expected)
+ {
+ $base = 'http://a/b/c/d;p?q';
+ $this->assertEquals($expected, Requests_IRI::absolutize($base, $relative)->iri);
+ $this->assertEquals($expected, (string) Requests_IRI::absolutize($base, $relative));
+ }
+
+ /**
+ * @dataProvider rfc3986_tests
+ */
+ public function testObjectRFC3986($relative, $expected)
+ {
+ $base = new Requests_IRI('http://a/b/c/d;p?q');
+ $expected = new Requests_IRI($expected);
+ $this->assertEquals($expected, Requests_IRI::absolutize($base, $relative));
+ }
+
+ public static function sp_tests()
+ {
+ return array(
+ array('http://a/b/c/d', 'f%0o', 'http://a/b/c/f%250o'),
+ array('http://a/b/', 'c', 'http://a/b/c'),
+ array('http://a/', 'b', 'http://a/b'),
+ array('http://a/', '/b', 'http://a/b'),
+ array('http://a/b', 'c', 'http://a/c'),
+ array('http://a/b/', "c\x0Ad", 'http://a/b/c%0Ad'),
+ array('http://a/b/', "c\x0A\x0B", 'http://a/b/c%0A%0B'),
+ array('http://a/b/c', '//0', 'http://0'),
+ array('http://a/b/c', '0', 'http://a/b/0'),
+ array('http://a/b/c', '?0', 'http://a/b/c?0'),
+ array('http://a/b/c', '#0', 'http://a/b/c#0'),
+ array('http://0/b/c', 'd', 'http://0/b/d'),
+ array('http://a/b/c?0', 'd', 'http://a/b/d'),
+ array('http://a/b/c#0', 'd', 'http://a/b/d'),
+ array('http://example.com', '//example.net', 'http://example.net'),
+ array('http:g', 'a', 'http:a'),
+ );
+ }
+
+ /**
+ * @dataProvider sp_tests
+ */
+ public function testStringSP($base, $relative, $expected)
+ {
+ $base = new Requests_IRI($base);
+ $this->assertEquals($expected, Requests_IRI::absolutize($base, $relative)->iri);
+ $this->assertEquals($expected, (string) Requests_IRI::absolutize($base, $relative));
+ }
+
+ /**
+ * @dataProvider sp_tests
+ */
+ public function testObjectSP($base, $relative, $expected)
+ {
+ $base = new Requests_IRI($base);
+ $expected = new Requests_IRI($expected);
+ $this->assertEquals($expected, Requests_IRI::absolutize($base, $relative));
+ }
+
+ public static function absolutize_tests()
+ {
+ return array(
+ array('http://example.com/', 'foo/111:bar', 'http://example.com/foo/111:bar'),
+ array('http://example.com/#foo', '', 'http://example.com'),
+ );
+ }
+
+ /**
+ * @dataProvider absolutize_tests
+ */
+ public function testAbsolutizeString($base, $relative, $expected)
+ {
+ $base = new Requests_IRI($base);
+ $this->assertEquals($expected, Requests_IRI::absolutize($base, $relative)->iri);
+ }
+
+ /**
+ * @dataProvider absolutize_tests
+ */
+ public function testAbsolutizeObject($base, $relative, $expected)
+ {
+ $base = new Requests_IRI($base);
+ $expected = new Requests_IRI($expected);
+ $this->assertEquals($expected, Requests_IRI::absolutize($base, $relative));
+ }
+
+ public static function normalization_tests()
+ {
+ return array(
+ array('example://a/b/c/%7Bfoo%7D', 'example://a/b/c/%7Bfoo%7D'),
+ array('eXAMPLE://a/./b/../b/%63/%7bfoo%7d', 'example://a/b/c/%7Bfoo%7D'),
+ array('example://%61/', 'example://a/'),
+ array('example://%41/', 'example://a/'),
+ array('example://A/', 'example://a/'),
+ array('example://a/', 'example://a/'),
+ array('example://%25A/', 'example://%25a/'),
+ array('HTTP://EXAMPLE.com/', 'http://example.com'),
+ array('http://example.com/', 'http://example.com'),
+ array('http://example.com:', 'http://example.com'),
+ array('http://example.com:80', 'http://example.com'),
+ array('http://@example.com', 'http://@example.com'),
+ array('http://', 'http://'),
+ array('http://example.com?', 'http://example.com?'),
+ array('http://example.com#', 'http://example.com#'),
+ array('https://example.com/', 'https://example.com'),
+ array('https://example.com:', 'https://example.com'),
+ array('https://@example.com', 'https://@example.com'),
+ array('https://example.com?', 'https://example.com?'),
+ array('https://example.com#', 'https://example.com#'),
+ array('file://localhost/foobar', 'file:/foobar'),
+ array('http://[0:0:0:0:0:0:0:1]', 'http://[::1]'),
+ array('http://[2001:db8:85a3:0000:0000:8a2e:370:7334]', 'http://[2001:db8:85a3::8a2e:370:7334]'),
+ array('http://[0:0:0:0:0:ffff:c0a8:a01]', 'http://[::ffff:c0a8:a01]'),
+ array('http://[ffff:0:0:0:0:0:0:0]', 'http://[ffff::]'),
+ array('http://[::ffff:192.0.2.128]', 'http://[::ffff:192.0.2.128]'),
+ array('http://[invalid]', 'http:'),
+ array('http://[0:0:0:0:0:0:0:1]:', 'http://[::1]'),
+ array('http://[0:0:0:0:0:0:0:1]:80', 'http://[::1]'),
+ array('http://[0:0:0:0:0:0:0:1]:1234', 'http://[::1]:1234'),
+ // Punycode decoding helps with normalisation of IRIs, but is not
+ // needed for URIs, so we don't really care about it for Requests
+ //array('http://xn--tdali-d8a8w.lv', 'http://tūdaliņ.lv'),
+ //array('http://t%C5%ABdali%C5%86.lv', 'http://tūdaliņ.lv'),
+ array('http://Aa@example.com', 'http://Aa@example.com'),
+ array('http://example.com?Aa', 'http://example.com?Aa'),
+ array('http://example.com/Aa', 'http://example.com/Aa'),
+ array('http://example.com#Aa', 'http://example.com#Aa'),
+ array('http://[0:0:0:0:0:0:0:0]', 'http://[::]'),
+ array('http:.', 'http:'),
+ array('http:..', 'http:'),
+ array('http:./', 'http:'),
+ array('http:../', 'http:'),
+ array('http://example.com/%3A', 'http://example.com/%3A'),
+ array('http://example.com/:', 'http://example.com/:'),
+ array('http://example.com/%C2', 'http://example.com/%C2'),
+ array('http://example.com/%C2a', 'http://example.com/%C2a'),
+ array('http://example.com/%C2%00', 'http://example.com/%C2%00'),
+ array('http://example.com/%C3%A9', 'http://example.com/é'),
+ array('http://example.com/%C3%A9%00', 'http://example.com/é%00'),
+ array('http://example.com/%C3%A9cole', 'http://example.com/école'),
+ array('http://example.com/%FF', 'http://example.com/%FF'),
+ array("http://example.com/\xF3\xB0\x80\x80", 'http://example.com/%F3%B0%80%80'),
+ array("http://example.com/\xF3\xB0\x80\x80%00", 'http://example.com/%F3%B0%80%80%00'),
+ array("http://example.com/\xF3\xB0\x80\x80a", 'http://example.com/%F3%B0%80%80a'),
+ array("http://example.com?\xF3\xB0\x80\x80", "http://example.com?\xF3\xB0\x80\x80"),
+ array("http://example.com?\xF3\xB0\x80\x80%00", "http://example.com?\xF3\xB0\x80\x80%00"),
+ array("http://example.com?\xF3\xB0\x80\x80a", "http://example.com?\xF3\xB0\x80\x80a"),
+ array("http://example.com/\xEE\x80\x80", 'http://example.com/%EE%80%80'),
+ array("http://example.com/\xEE\x80\x80%00", 'http://example.com/%EE%80%80%00'),
+ array("http://example.com/\xEE\x80\x80a", 'http://example.com/%EE%80%80a'),
+ array("http://example.com?\xEE\x80\x80", "http://example.com?\xEE\x80\x80"),
+ array("http://example.com?\xEE\x80\x80%00", "http://example.com?\xEE\x80\x80%00"),
+ array("http://example.com?\xEE\x80\x80a", "http://example.com?\xEE\x80\x80a"),
+ array("http://example.com/\xC2", 'http://example.com/%C2'),
+ array("http://example.com/\xC2a", 'http://example.com/%C2a'),
+ array("http://example.com/\xC2\x00", 'http://example.com/%C2%00'),
+ array("http://example.com/\xC3\xA9", 'http://example.com/é'),
+ array("http://example.com/\xC3\xA9\x00", 'http://example.com/é%00'),
+ array("http://example.com/\xC3\xA9cole", 'http://example.com/école'),
+ array("http://example.com/\xFF", 'http://example.com/%FF'),
+ array("http://example.com/\xFF%00", 'http://example.com/%FF%00'),
+ array("http://example.com/\xFFa", 'http://example.com/%FFa'),
+ array('http://example.com/%61', 'http://example.com/a'),
+ array('http://example.com?%26', 'http://example.com?%26'),
+ array('http://example.com?%61', 'http://example.com?a'),
+ array('///', '///'),
+ );
+ }
+
+ /**
+ * @dataProvider normalization_tests
+ */
+ public function testStringNormalization($input, $output)
+ {
+ $input = new Requests_IRI($input);
+ $this->assertEquals($output, $input->iri);
+ $this->assertEquals($output, (string) $input);
+ }
+
+ /**
+ * @dataProvider normalization_tests
+ */
+ public function testObjectNormalization($input, $output)
+ {
+ $input = new Requests_IRI($input);
+ $output = new Requests_IRI($output);
+ $this->assertEquals($output, $input);
+ }
+
+ public static function equivalence_tests()
+ {
+ return array(
+ array('http://É.com', 'http://%C3%89.com'),
+ );
+ }
+
+ /**
+ * @dataProvider equivalence_tests
+ */
+ public function testObjectEquivalence($input, $output)
+ {
+ $input = new Requests_IRI($input);
+ $output = new Requests_IRI($output);
+ $this->assertEquals($output, $input);
+ }
+
+ public static function not_equivalence_tests()
+ {
+ return array(
+ array('http://example.com/foo/bar', 'http://example.com/foo%2Fbar'),
+ );
+ }
+
+ /**
+ * @dataProvider not_equivalence_tests
+ */
+ public function testObjectNotEquivalence($input, $output)
+ {
+ $input = new Requests_IRI($input);
+ $output = new Requests_IRI($output);
+ $this->assertNotEquals($output, $input);
+ }
+
+ public function testInvalidAbsolutizeBase()
+ {
+ $this->assertFalse(Requests_IRI::absolutize('://not a URL', '../'));
+ }
+
+ public function testInvalidAbsolutizeRelative()
+ {
+ $this->assertFalse(Requests_IRI::absolutize('http://example.com/', 'http://example.com//not a URL'));
+ }
+
+ public function testFullGamut()
+ {
+ $iri = new Requests_IRI();
+ $iri->scheme = 'http';
+ $iri->userinfo = 'user:password';
+ $iri->host = 'example.com';
+ $iri->path = '/test/';
+ $iri->fragment = 'test';
+
+ $this->assertEquals('http', $iri->scheme);
+ $this->assertEquals('user:password', $iri->userinfo);
+ $this->assertEquals('example.com', $iri->host);
+ $this->assertEquals(80, $iri->port);
+ $this->assertEquals('/test/', $iri->path);
+ $this->assertEquals('test', $iri->fragment);
+ }
+
+ public function testReadAliased()
+ {
+ $iri = new Requests_IRI();
+ $iri->scheme = 'http';
+ $iri->userinfo = 'user:password';
+ $iri->host = 'example.com';
+ $iri->path = '/test/';
+ $iri->fragment = 'test';
+
+ $this->assertEquals('http', $iri->ischeme);
+ $this->assertEquals('user:password', $iri->iuserinfo);
+ $this->assertEquals('example.com', $iri->ihost);
+ $this->assertEquals(80, $iri->iport);
+ $this->assertEquals('/test/', $iri->ipath);
+ $this->assertEquals('test', $iri->ifragment);
+ }
+
+ public function testWriteAliased()
+ {
+ $iri = new Requests_IRI();
+ $iri->scheme = 'http';
+ $iri->iuserinfo = 'user:password';
+ $iri->ihost = 'example.com';
+ $iri->ipath = '/test/';
+ $iri->ifragment = 'test';
+
+ $this->assertEquals('http', $iri->scheme);
+ $this->assertEquals('user:password', $iri->userinfo);
+ $this->assertEquals('example.com', $iri->host);
+ $this->assertEquals(80, $iri->port);
+ $this->assertEquals('/test/', $iri->path);
+ $this->assertEquals('test', $iri->fragment);
+ }
+
+ /**
+ * @expectedException PHPUnit_Framework_Error_Notice
+ */
+ public function testNonexistantProperty()
+ {
+ $iri = new Requests_IRI();
+ $this->assertFalse(isset($iri->nonexistant_prop));
+ $should_fail = $iri->nonexistant_prop;
+ }
+
+ public function testBlankHost()
+ {
+ $iri = new Requests_IRI('http://example.com/a/?b=c#d');
+ $iri->host = null;
+
+ $this->assertEquals(null, $iri->host);
+ $this->assertEquals('http:/a/?b=c#d', (string) $iri);
+ }
+
+ public function testBadPort()
+ {
+ $iri = new Requests_IRI();
+ $iri->port = 'example';
+
+ $this->assertEquals(null, $iri->port);
+ }
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/Requests.php b/includes/src/vendor/rmccue/requests/tests/Requests.php
new file mode 100644
index 0000000..e13698e
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Requests.php
@@ -0,0 +1,140 @@
+assertEquals(200, $request->status_code);
+ }
+
+ /**
+ * Standard response header parsing
+ */
+ public function testHeaderParsing() {
+ $transport = new RawTransport();
+ $transport->data =
+ "HTTP/1.0 200 OK\r\n".
+ "Host: localhost\r\n".
+ "Host: ambiguous\r\n".
+ "Nospace:here\r\n".
+ "Muchspace: there \r\n".
+ "Empty:\r\n".
+ "Empty2: \r\n".
+ "Folded: one\r\n".
+ "\ttwo\r\n".
+ " three\r\n\r\n".
+ "stop\r\n";
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ $expected = new Requests_Response_Headers();
+ $expected['host'] = 'localhost,ambiguous';
+ $expected['nospace'] = 'here';
+ $expected['muchspace'] = 'there';
+ $expected['empty'] = '';
+ $expected['empty2'] = '';
+ $expected['folded'] = 'one two three';
+ foreach ($expected as $key => $value) {
+ $this->assertEquals($value, $response->headers[$key]);
+ }
+
+ foreach ($response->headers as $key => $value) {
+ $this->assertEquals($value, $expected[$key]);
+ }
+ }
+
+ public function testRawAccess() {
+ $transport = new RawTransport();
+ $transport->data =
+ "HTTP/1.0 200 OK\r\n".
+ "Host: localhost\r\n\r\n".
+ "Test";
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ $this->assertEquals($transport->data, $response->raw);
+ }
+
+ /**
+ * Headers with only \n delimiting should be treated as if they're \r\n
+ */
+ public function testHeaderOnlyLF() {
+ $transport = new RawTransport();
+ $transport->data = "HTTP/1.0 200 OK\r\nTest: value\nAnother-Test: value\r\n\r\n";
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ $this->assertEquals('value', $response->headers['test']);
+ $this->assertEquals('value', $response->headers['another-test']);
+ }
+
+ /**
+ * Check that invalid protocols are not accepted
+ *
+ * We do not support HTTP/0.9. If this is really an issue for you, file a
+ * new issue, and update your server/proxy to support a proper protocol.
+ *
+ * @expectedException Requests_Exception
+ */
+ public function testInvalidProtocolVersion() {
+ $transport = new RawTransport();
+ $transport->data = "HTTP/0.9 200 OK\r\n\r\n
Test";
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ }
+
+ /**
+ * HTTP/0.9 also appears to use a single CRLF instead of two
+ *
+ * @expectedException Requests_Exception
+ */
+ public function testSingleCRLFSeparator() {
+ $transport = new RawTransport();
+ $transport->data = "HTTP/0.9 200 OK\r\n
Test";
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testInvalidStatus() {
+ $transport = new RawTransport();
+ $transport->data = "HTTP/1.1 OK\r\nTest: value\nAnother-Test: value\r\n\r\nTest";
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ }
+
+ public function test30xWithoutLocation() {
+ $transport = new MockTransport();
+ $transport->code = 302;
+
+ $options = array(
+ 'transport' => $transport
+ );
+ $response = Requests::get('http://example.com/', array(), $options);
+ $this->assertEquals(302, $response->status_code);
+ $this->assertEquals(0, $response->redirects);
+ }
+}
\ No newline at end of file
diff --git a/includes/src/vendor/rmccue/requests/tests/Response/Headers.php b/includes/src/vendor/rmccue/requests/tests/Response/Headers.php
new file mode 100644
index 0000000..7541f37
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Response/Headers.php
@@ -0,0 +1,55 @@
+assertEquals('text/plain', $headers['Content-Type']);
+ }
+ public function testCaseInsensitiveArrayAccess() {
+ $headers = new Requests_Response_Headers();
+ $headers['Content-Type'] = 'text/plain';
+
+ $this->assertEquals('text/plain', $headers['CONTENT-TYPE']);
+ $this->assertEquals('text/plain', $headers['content-type']);
+ }
+
+ /**
+ * @depends testArrayAccess
+ */
+ public function testIteration() {
+ $headers = new Requests_Response_Headers();
+ $headers['Content-Type'] = 'text/plain';
+ $headers['Content-Length'] = 10;
+
+ foreach ($headers as $name => $value) {
+ switch (strtolower($name)) {
+ case 'content-type':
+ $this->assertEquals('text/plain', $value);
+ break;
+ case 'content-length':
+ $this->assertEquals(10, $value);
+ break;
+ default:
+ throw new Exception('Invalid name: ' . $name);
+ }
+ }
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testInvalidKey() {
+ $headers = new Requests_Response_Headers();
+ $headers[] = 'text/plain';
+ }
+
+ public function testMultipleHeaders() {
+ $headers = new Requests_Response_Headers();
+ $headers['Accept'] = 'text/html;q=1.0';
+ $headers['Accept'] = '*/*;q=0.1';
+
+ $this->assertEquals('text/html;q=1.0,*/*;q=0.1', $headers['Accept']);
+ }
+}
\ No newline at end of file
diff --git a/includes/src/vendor/rmccue/requests/tests/SSL.php b/includes/src/vendor/rmccue/requests/tests/SSL.php
new file mode 100644
index 0000000..62bb998
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/SSL.php
@@ -0,0 +1,108 @@
+assertTrue(Requests_SSL::match_domain($base, $dnsname));
+ }
+
+ /**
+ * @dataProvider domainNoMatchProvider
+ */
+ public function testNoMatch($base, $dnsname) {
+ $this->assertFalse(Requests_SSL::match_domain($base, $dnsname));
+ }
+
+ protected function fakeCertificate($dnsname, $with_san = true) {
+ $certificate = array(
+ 'subject' => array(
+ 'CN' => $dnsname
+ ),
+ );
+
+ if ($with_san !== false) {
+ // If SAN is set to true, default it to the dNSName
+ if ($with_san === true) {
+ $with_san = $dnsname;
+ }
+ $certificate['extensions'] = array(
+ 'subjectAltName' => 'DNS: ' . $with_san,
+ );
+ }
+
+ return $certificate;
+ }
+
+ /**
+ * @dataProvider domainMatchProvider
+ */
+ public function testMatchViaCertificate($base, $dnsname) {
+ $certificate = $this->fakeCertificate($dnsname);
+ $this->assertTrue(Requests_SSL::verify_certificate($base, $certificate));
+ }
+
+ /**
+ * @dataProvider domainNoMatchProvider
+ */
+ public function testNoMatchViaCertificate($base, $dnsname) {
+ $certificate = $this->fakeCertificate($dnsname);
+ $this->assertFalse(Requests_SSL::verify_certificate($base, $certificate));
+ }
+
+ public function testCNFallback() {
+ $certificate = $this->fakeCertificate('example.com', false);
+ $this->assertTrue(Requests_SSL::verify_certificate('example.com', $certificate));
+ }
+
+ public function testInvalidCNFallback() {
+ $certificate = $this->fakeCertificate('example.com', false);
+ $this->assertFalse(Requests_SSL::verify_certificate('example.net', $certificate));
+ }
+
+ /**
+ * Test a certificate with both CN and SAN fields
+ *
+ * As per RFC2818, if the SAN field exists, we should parse that and ignore
+ * the value of the CN field.
+ *
+ * @link http://tools.ietf.org/html/rfc2818#section-3.1
+ */
+ public function testIgnoreCNWithSAN() {
+ $certificate = $this->fakeCertificate('example.net', 'example.com');
+
+ $this->assertTrue(Requests_SSL::verify_certificate('example.com', $certificate), 'Checking SAN validation');
+ $this->assertFalse(Requests_SSL::verify_certificate('example.net', $certificate), 'Checking CN non-validation');
+ }
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/Session.php b/includes/src/vendor/rmccue/requests/tests/Session.php
new file mode 100644
index 0000000..676c609
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Session.php
@@ -0,0 +1,86 @@
+ 'testing',
+ 'X-TestHeader2' => 'requests-test'
+ );
+ $data = array(
+ 'testdata' => 'value1',
+ 'test2' => 'value2',
+ 'test3' => array(
+ 'foo' => 'bar',
+ 'abc' => 'xyz'
+ )
+ );
+ $options = array(
+ 'testoption' => 'test',
+ 'foo' => 'bar'
+ );
+
+ $session = new Requests_Session('http://example.com/', $headers, $data, $options);
+ $this->assertEquals('http://example.com/', $session->url);
+ $this->assertEquals($headers, $session->headers);
+ $this->assertEquals($data, $session->data);
+ $this->assertEquals($options['testoption'], $session->options['testoption']);
+
+ // Test via property access
+ $this->assertEquals($options['testoption'], $session->testoption);
+
+ // Test setting new property
+ $session->newoption = 'foobar';
+ $options['newoption'] = 'foobar';
+ $this->assertEquals($options['newoption'], $session->options['newoption']);
+
+ // Test unsetting property
+ unset($session->newoption);
+ $this->assertFalse(isset($session->newoption));
+
+ // Update property
+ $session->testoption = 'foobar';
+ $options['testoption'] = 'foobar';
+ $this->assertEquals($options['testoption'], $session->testoption);
+
+ // Test getting invalid property
+ $this->assertNull($session->invalidoption);
+ }
+
+ public function testURLResolution() {
+ $session = new Requests_Session('http://httpbin.org/');
+
+ // Set the cookies up
+ $response = $session->get('/get');
+ $this->assertTrue($response->success);
+ $this->assertEquals('http://httpbin.org/get', $response->url);
+
+ $data = json_decode($response->body, true);
+ $this->assertNotNull($data);
+ $this->assertArrayHasKey('url', $data);
+ $this->assertEquals('http://httpbin.org/get', $data['url']);
+ }
+
+ public function testSharedCookies() {
+ $session = new Requests_Session('http://httpbin.org/');
+
+ $options = array(
+ 'follow_redirects' => false
+ );
+ $response = $session->get('/cookies/set?requests-testcookie=testvalue', array(), $options);
+ $this->assertEquals(302, $response->status_code);
+
+ // Check the cookies
+ $response = $session->get('/cookies');
+ $this->assertTrue($response->success);
+
+ // Check the response
+ $data = json_decode($response->body, true);
+ $this->assertNotNull($data);
+ $this->assertArrayHasKey('cookies', $data);
+
+ $cookies = array(
+ 'requests-testcookie' => 'testvalue'
+ );
+ $this->assertEquals($cookies, $data['cookies']);
+ }
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/Transport/Base.php b/includes/src/vendor/rmccue/requests/tests/Transport/Base.php
new file mode 100644
index 0000000..8584efb
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Transport/Base.php
@@ -0,0 +1,683 @@
+transport, 'test');
+ $supported = call_user_func($callback);
+
+ if (!$supported) {
+ $this->markTestSkipped($this->transport . ' is not available');
+ return;
+ }
+
+ $ssl_supported = call_user_func($callback, array('ssl' => true));
+ if (!$ssl_supported) {
+ $this->skip_https = true;
+ }
+ }
+ protected $skip_https = false;
+
+ protected function getOptions($other = array()) {
+ $options = array(
+ 'transport' => $this->transport
+ );
+ $options = array_merge($options, $other);
+ return $options;
+ }
+
+ public function testSimpleGET() {
+ $request = Requests::get('http://httpbin.org/get', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/get', $result['url']);
+ $this->assertEmpty($result['args']);
+ }
+
+ public function testGETWithArgs() {
+ $request = Requests::get('http://httpbin.org/get?test=true&test2=test', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/get?test=true&test2=test', $result['url']);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['args']);
+ }
+
+ public function testGETWithData() {
+ $data = array(
+ 'test' => 'true',
+ 'test2' => 'test',
+ );
+ $request = Requests::request('http://httpbin.org/get', array(), $data, Requests::GET, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/get?test=true&test2=test', $result['url']);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['args']);
+ }
+
+ public function testGETWithNestedData() {
+ $this->markTestSkipped('httpbin changed their data format; this test will now fail');
+ $data = array(
+ 'test' => 'true',
+ 'test2' => array(
+ 'test3' => 'test',
+ 'test4' => 'test-too',
+ ),
+ );
+ $request = Requests::request('http://httpbin.org/get', array(), $data, Requests::GET, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/get?test=true&test2%5Btest3%5D=test&test2%5Btest4%5D=test-too', $result['url']);
+ $this->assertEquals(array('test' => 'true', 'test2[test3]' => 'test', 'test2[test4]' => 'test-too'), $result['args']);
+ }
+
+ public function testGETWithDataAndQuery() {
+ $data = array(
+ 'test2' => 'test',
+ );
+ $request = Requests::request('http://httpbin.org/get?test=true', array(), $data, Requests::GET, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/get?test=true&test2=test', $result['url']);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['args']);
+ }
+
+ public function testGETWithHeaders() {
+ $headers = array(
+ 'Requested-At' => time(),
+ );
+ $request = Requests::get('http://httpbin.org/get', $headers, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals($headers['Requested-At'], $result['headers']['Requested-At']);
+ }
+
+ public function testChunked() {
+ $request = Requests::get('http://httpbin.org/stream/1', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/stream/1', $result['url']);
+ $this->assertEmpty($result['args']);
+ }
+
+ public function testHEAD() {
+ $request = Requests::head('http://httpbin.org/get', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+ $this->assertEquals('', $request->body);
+ }
+
+ public function testRawPOST() {
+ $data = 'test';
+ $request = Requests::post('http://httpbin.org/post', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('test', $result['data']);
+ }
+
+ public function testFormPost() {
+ $data = 'test=true&test2=test';
+ $request = Requests::post('http://httpbin.org/post', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['form']);
+ }
+
+ public function testPOSTWithArray() {
+ $data = array(
+ 'test' => 'true',
+ 'test2' => 'test',
+ );
+ $request = Requests::post('http://httpbin.org/post', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['form']);
+ }
+
+ public function testPOSTWithNestedData() {
+ $data = array(
+ 'test' => 'true',
+ 'test2' => array(
+ 'test3' => 'test',
+ 'test4' => 'test-too',
+ ),
+ );
+ $request = Requests::post('http://httpbin.org/post', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2[test3]' => 'test', 'test2[test4]' => 'test-too'), $result['form']);
+ }
+
+ public function testRawPUT() {
+ $data = 'test';
+ $request = Requests::put('http://httpbin.org/put', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('test', $result['data']);
+ }
+
+ public function testFormPUT() {
+ $data = 'test=true&test2=test';
+ $request = Requests::put('http://httpbin.org/put', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['form']);
+ }
+
+ public function testPUTWithArray() {
+ $data = array(
+ 'test' => 'true',
+ 'test2' => 'test',
+ );
+ $request = Requests::put('http://httpbin.org/put', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['form']);
+ }
+
+ public function testRawPATCH() {
+ $data = 'test';
+ $request = Requests::patch('http://httpbin.org/patch', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('test', $result['data']);
+ }
+
+ public function testFormPATCH() {
+ $data = 'test=true&test2=test';
+ $request = Requests::patch('http://httpbin.org/patch', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code, $request->body);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['form']);
+ }
+
+ public function testPATCHWithArray() {
+ $data = array(
+ 'test' => 'true',
+ 'test2' => 'test',
+ );
+ $request = Requests::patch('http://httpbin.org/patch', array(), $data, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['form']);
+ }
+
+ public function testDELETE() {
+ $request = Requests::delete('http://httpbin.org/delete', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/delete', $result['url']);
+ $this->assertEmpty($result['args']);
+ }
+
+ public function testDELETEWithData() {
+ $data = array(
+ 'test' => 'true',
+ 'test2' => 'test',
+ );
+ $request = Requests::request('http://httpbin.org/delete', array(), $data, Requests::DELETE, $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/delete?test=true&test2=test', $result['url']);
+ $this->assertEquals(array('test' => 'true', 'test2' => 'test'), $result['args']);
+ }
+
+ public function testRedirects() {
+ $request = Requests::get('http://httpbin.org/redirect/6', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $this->assertEquals(6, $request->redirects);
+ }
+
+ public function testRelativeRedirects() {
+ $request = Requests::get('http://httpbin.org/relative-redirect/6', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $this->assertEquals(6, $request->redirects);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ * @todo This should also check that the type is "toomanyredirects"
+ */
+ public function testTooManyRedirects() {
+ $options = array(
+ 'redirects' => 10, // default, but force just in case
+ );
+ $request = Requests::get('http://httpbin.org/redirect/11', array(), $this->getOptions($options));
+ }
+
+ public static function statusCodeSuccessProvider() {
+ return array(
+ array(200, true),
+ array(201, true),
+ array(202, true),
+ array(203, true),
+ array(204, true),
+ array(205, true),
+ array(206, true),
+ array(300, false),
+ array(301, false),
+ array(302, false),
+ array(303, false),
+ array(304, false),
+ array(305, false),
+ array(306, false),
+ array(307, false),
+ array(400, false),
+ array(401, false),
+ array(402, false),
+ array(403, false),
+ array(404, false),
+ array(405, false),
+ array(406, false),
+ array(407, false),
+ array(408, false),
+ array(409, false),
+ array(410, false),
+ array(411, false),
+ array(412, false),
+ array(413, false),
+ array(414, false),
+ array(415, false),
+ array(416, false),
+ array(417, false),
+ array(418, false), // RFC 2324
+ array(428, false), // RFC 6585
+ array(429, false), // RFC 6585
+ array(431, false), // RFC 6585
+ array(500, false),
+ array(501, false),
+ array(502, false),
+ array(503, false),
+ array(504, false),
+ array(505, false),
+ array(511, false), // RFC 6585
+ );
+ }
+
+ /**
+ * @dataProvider statusCodeSuccessProvider
+ */
+ public function testStatusCode($code, $success) {
+ $url = sprintf('http://httpbin.org/status/%d', $code);
+ $options = array(
+ 'follow_redirects' => false,
+ );
+ $request = Requests::get($url, array(), $this->getOptions($options));
+ $this->assertEquals($code, $request->status_code);
+ $this->assertEquals($success, $request->success);
+ }
+
+ /**
+ * @dataProvider statusCodeSuccessProvider
+ */
+ public function testStatusCodeThrow($code, $success) {
+ $url = sprintf('http://httpbin.org/status/%d', $code);
+ $options = array(
+ 'follow_redirects' => false,
+ );
+
+ if (!$success) {
+ if ($code >= 400) {
+ $this->setExpectedException('Requests_Exception_HTTP_' . $code, $code);
+ }
+ elseif ($code >= 300 && $code < 400) {
+ $this->setExpectedException('Requests_Exception');
+ }
+ }
+ $request = Requests::get($url, array(), $this->getOptions($options));
+ $request->throw_for_status(false);
+ }
+
+ /**
+ * @dataProvider statusCodeSuccessProvider
+ */
+ public function testStatusCodeThrowAllowRedirects($code, $success) {
+ $url = sprintf('http://httpbin.org/status/%d', $code);
+ $options = array(
+ 'follow_redirects' => false,
+ );
+
+ if (!$success) {
+ if ($code >= 400) {
+ $this->setExpectedException('Requests_Exception_HTTP_' . $code, $code);
+ }
+ }
+ $request = Requests::get($url, array(), $this->getOptions($options));
+ $request->throw_for_status(true);
+ }
+
+ public function testStatusCodeUnknown(){
+ $request = Requests::get('http://httpbin.org/status/599', array(), $this->getOptions());
+ $this->assertEquals(599, $request->status_code);
+ $this->assertEquals(false, $request->success);
+ }
+
+ /**
+ * @expectedException Requests_Exception_HTTP_Unknown
+ */
+ public function testStatusCodeThrowUnknown(){
+ $request = Requests::get('http://httpbin.org/status/599', array(), $this->getOptions());
+ $request->throw_for_status(true);
+ }
+
+ public function testGzipped() {
+ $request = Requests::get('http://httpbin.org/gzip', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body);
+ $this->assertEquals(true, $result->gzipped);
+ }
+
+ public function testStreamToFile() {
+ $options = array(
+ 'filename' => tempnam(sys_get_temp_dir(), 'RLT') // RequestsLibraryTest
+ );
+ $request = Requests::get('http://httpbin.org/get', array(), $this->getOptions($options));
+ $this->assertEquals(200, $request->status_code);
+ $this->assertEmpty($request->body);
+
+ $contents = file_get_contents($options['filename']);
+ $result = json_decode($contents, true);
+ $this->assertEquals('http://httpbin.org/get', $result['url']);
+ $this->assertEmpty($result['args']);
+
+ unlink($options['filename']);
+ }
+
+ public function testNonblocking() {
+ $options = array(
+ 'blocking' => false
+ );
+ $request = Requests::get('http://httpbin.org/get', array(), $this->getOptions($options));
+ $empty = new Requests_Response();
+ $this->assertEquals($empty, $request);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testBadIP() {
+ $request = Requests::get('http://256.256.256.0/', array(), $this->getOptions());
+ }
+
+ public function testHTTPS() {
+ if ($this->skip_https) {
+ $this->markTestSkipped('SSL support is not available.');
+ return;
+ }
+
+ $request = Requests::get('https://httpbin.org/get', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+
+ $result = json_decode($request->body, true);
+ $this->assertEquals('http://httpbin.org/get', $result['url']);
+ $this->assertEmpty($result['args']);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testExpiredHTTPS() {
+ if ($this->skip_https) {
+ $this->markTestSkipped('SSL support is not available.');
+ return;
+ }
+
+ $request = Requests::get('https://testssl-expire.disig.sk/index.en.html', array(), $this->getOptions());
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testRevokedHTTPS() {
+ if ($this->skip_https) {
+ $this->markTestSkipped('SSL support is not available.');
+ return;
+ }
+
+ $request = Requests::get('https://testssl-revoked.disig.sk/index.en.html', array(), $this->getOptions());
+ }
+
+ /**
+ * Test that SSL fails with a bad certificate
+ *
+ * This is defined as invalid by
+ * https://onlinessl.netlock.hu/en/test-center/invalid-ssl-certificate.html
+ * and is used in testing in PhantomJS. That said, expect this to break.
+ *
+ * @expectedException Requests_Exception
+ */
+ public function testBadDomain() {
+ if ($this->skip_https) {
+ $this->markTestSkipped('SSL support is not available.');
+ return;
+ }
+
+ $request = Requests::get('https://tv.eurosport.com/', array(), $this->getOptions());
+ }
+
+ /**
+ * Test that the transport supports Server Name Indication with HTTPS
+ *
+ * sni.velox.ch is used for SNI testing, and the common name is set to
+ * `*.sni.velox.ch` as such. Without alternate name support, this will fail
+ * as `sni.velox.ch` is only in the alternate name
+ */
+ public function testAlternateNameSupport() {
+ if ($this->skip_https) {
+ $this->markTestSkipped('SSL support is not available.');
+ return;
+ }
+
+ $request = Requests::get('https://sni.velox.ch/', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+ }
+
+ /**
+ * Test that the transport supports Server Name Indication with HTTPS
+ *
+ * sni.velox.ch is used for SNI testing, and the common name is set to
+ * `*.sni.velox.ch` as such. Without SNI support, this will fail. Also tests
+ * our wildcard support.
+ */
+ public function testSNISupport() {
+ if ($this->skip_https) {
+ $this->markTestSkipped('SSL support is not available.');
+ return;
+ }
+
+ $request = Requests::get('https://abc.sni.velox.ch/', array(), $this->getOptions());
+ $this->assertEquals(200, $request->status_code);
+ }
+
+ /**
+ * @expectedException Requests_Exception
+ */
+ public function testTimeout() {
+ $options = array(
+ 'timeout' => 1,
+ );
+ $request = Requests::get('http://httpbin.org/delay/10', array(), $this->getOptions($options));
+ var_dump($request);
+ }
+
+ public function testMultiple() {
+ $requests = array(
+ 'test1' => array(
+ 'url' => 'http://httpbin.org/get'
+ ),
+ 'test2' => array(
+ 'url' => 'http://httpbin.org/get'
+ ),
+ );
+ $responses = Requests::request_multiple($requests, $this->getOptions());
+
+ // test1
+ $this->assertNotEmpty($responses['test1']);
+ $this->assertInstanceOf('Requests_Response', $responses['test1']);
+ $this->assertEquals(200, $responses['test1']->status_code);
+
+ $result = json_decode($responses['test1']->body, true);
+ $this->assertEquals('http://httpbin.org/get', $result['url']);
+ $this->assertEmpty($result['args']);
+
+ // test2
+ $this->assertNotEmpty($responses['test2']);
+ $this->assertInstanceOf('Requests_Response', $responses['test2']);
+ $this->assertEquals(200, $responses['test2']->status_code);
+
+ $result = json_decode($responses['test2']->body, true);
+ $this->assertEquals('http://httpbin.org/get', $result['url']);
+ $this->assertEmpty($result['args']);
+ }
+
+ public function testMultipleWithDifferingMethods() {
+ $requests = array(
+ 'get' => array(
+ 'url' => 'http://httpbin.org/get',
+ ),
+ 'post' => array(
+ 'url' => 'http://httpbin.org/post',
+ 'type' => Requests::POST,
+ 'data' => 'test',
+ ),
+ );
+ $responses = Requests::request_multiple($requests, $this->getOptions());
+
+ // get
+ $this->assertEquals(200, $responses['get']->status_code);
+
+ // post
+ $this->assertEquals(200, $responses['post']->status_code);
+ $result = json_decode($responses['post']->body, true);
+ $this->assertEquals('test', $result['data']);
+ }
+
+ /**
+ * @depends testTimeout
+ */
+ public function testMultipleWithFailure() {
+ $requests = array(
+ 'success' => array(
+ 'url' => 'http://httpbin.org/get',
+ ),
+ 'timeout' => array(
+ 'url' => 'http://httpbin.org/delay/10',
+ 'options' => array(
+ 'timeout' => 1,
+ ),
+ ),
+ );
+ $responses = Requests::request_multiple($requests, $this->getOptions());
+ $this->assertEquals(200, $responses['success']->status_code);
+ $this->assertInstanceOf('Requests_Exception', $responses['timeout']);
+ }
+
+ public function testMultipleUsingCallback() {
+ $requests = array(
+ 'get' => array(
+ 'url' => 'http://httpbin.org/get',
+ ),
+ 'post' => array(
+ 'url' => 'http://httpbin.org/post',
+ 'type' => Requests::POST,
+ 'data' => 'test',
+ ),
+ );
+ $this->completed = array();
+ $options = array(
+ 'complete' => array($this, 'completeCallback'),
+ );
+ $responses = Requests::request_multiple($requests, $this->getOptions($options));
+
+ $this->assertEquals($this->completed, $responses);
+ $this->completed = array();
+ }
+
+ public function testMultipleUsingCallbackAndFailure() {
+ $requests = array(
+ 'success' => array(
+ 'url' => 'http://httpbin.org/get',
+ ),
+ 'timeout' => array(
+ 'url' => 'http://httpbin.org/delay/10',
+ 'options' => array(
+ 'timeout' => 1,
+ ),
+ ),
+ );
+ $this->completed = array();
+ $options = array(
+ 'complete' => array($this, 'completeCallback'),
+ );
+ $responses = Requests::request_multiple($requests, $this->getOptions($options));
+
+ $this->assertEquals($this->completed, $responses);
+ $this->completed = array();
+ }
+
+ public function completeCallback($response, $key) {
+ $this->completed[$key] = $response;
+ }
+
+ public function testMultipleToFile() {
+ $requests = array(
+ 'get' => array(
+ 'url' => 'http://httpbin.org/get',
+ 'options' => array(
+ 'filename' => tempnam(sys_get_temp_dir(), 'RLT') // RequestsLibraryTest
+ ),
+ ),
+ 'post' => array(
+ 'url' => 'http://httpbin.org/post',
+ 'type' => Requests::POST,
+ 'data' => 'test',
+ 'options' => array(
+ 'filename' => tempnam(sys_get_temp_dir(), 'RLT') // RequestsLibraryTest
+ ),
+ ),
+ );
+ $responses = Requests::request_multiple($requests, $this->getOptions());
+
+ // GET request
+ $contents = file_get_contents($requests['get']['options']['filename']);
+ $result = json_decode($contents, true);
+ $this->assertEquals('http://httpbin.org/get', $result['url']);
+ $this->assertEmpty($result['args']);
+ unlink($requests['get']['options']['filename']);
+
+ // POST request
+ $contents = file_get_contents($requests['post']['options']['filename']);
+ $result = json_decode($contents, true);
+ $this->assertEquals('http://httpbin.org/post', $result['url']);
+ $this->assertEquals('test', $result['data']);
+ unlink($requests['post']['options']['filename']);
+ }
+
+ public function testHostHeader() {
+ $request = Requests::get('http://portquiz.positon.org:8080/', array(), $this->getOptions());
+ $responseDoc = new DOMDocument;
+ $responseDoc->loadHTML($request->body);
+ $portXpath = new DOMXPath($responseDoc);
+ $portXpathMatches = $portXpath->query('//p/b');
+ $this->assertEquals(8080, $portXpathMatches->item(0)->nodeValue);
+ }
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/Transport/cURL.php b/includes/src/vendor/rmccue/requests/tests/Transport/cURL.php
new file mode 100644
index 0000000..55390ad
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/Transport/cURL.php
@@ -0,0 +1,5 @@
+ '100 Continue',
+ 101 => '101 Switching Protocols',
+ 200 => '200 OK',
+ 201 => '201 Created',
+ 202 => '202 Accepted',
+ 203 => '203 Non-Authoritative Information',
+ 204 => '204 No Content',
+ 205 => '205 Reset Content',
+ 206 => '206 Partial Content',
+ 300 => '300 Multiple Choices',
+ 301 => '301 Moved Permanently',
+ 302 => '302 Found',
+ 303 => '303 See Other',
+ 304 => '304 Not Modified',
+ 305 => '305 Use Proxy',
+ 306 => '306 (Unused)',
+ 307 => '307 Temporary Redirect',
+ 400 => '400 Bad Request',
+ 401 => '401 Unauthorized',
+ 402 => '402 Payment Required',
+ 403 => '403 Forbidden',
+ 404 => '404 Not Found',
+ 405 => '405 Method Not Allowed',
+ 406 => '406 Not Acceptable',
+ 407 => '407 Proxy Authentication Required',
+ 408 => '408 Request Timeout',
+ 409 => '409 Conflict',
+ 410 => '410 Gone',
+ 411 => '411 Length Required',
+ 412 => '412 Precondition Failed',
+ 413 => '413 Request Entity Too Large',
+ 414 => '414 Request-URI Too Long',
+ 415 => '415 Unsupported Media Type',
+ 416 => '416 Requested Range Not Satisfiable',
+ 417 => '417 Expectation Failed',
+ 500 => '500 Internal Server Error',
+ 501 => '501 Not Implemented',
+ 502 => '502 Bad Gateway',
+ 503 => '503 Service Unavailable',
+ 504 => '504 Gateway Timeout',
+ 505 => '505 HTTP Version Not Supported',
+ );
+
+ public function request($url, $headers = array(), $data = array(), $options = array()) {
+ $status = self::$messages[$this->code];
+ $response = "HTTP/1.0 $status\r\n";
+ $response .= "Content-Type: text/plain\r\n";
+ if ($this->chunked) {
+ $response .= "Transfer-Encoding: chunked\r\n";
+ }
+ $response .= $this->raw_headers;
+ $response .= "Connection: close\r\n\r\n";
+ $response .= $this->body;
+ return $response;
+ }
+
+ public function request_multiple($requests, $options) {
+ $responses = array();
+ foreach ($requests as $id => $request) {
+ $handler = new MockTransport();
+ $handler->code = $request['options']['mock.code'];
+ $handler->chunked = $request['options']['mock.chunked'];
+ $handler->body = $request['options']['mock.body'];
+ $handler->raw_headers = $request['options']['mock.raw_headers'];
+ $responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
+
+ if (!empty($options['mock.parse'])) {
+ $request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
+ $request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id));
+ }
+ }
+
+ return $responses;
+ }
+
+ public static function test() {
+ return true;
+ }
+}
+
+class RawTransport implements Requests_Transport {
+ public $data = '';
+ public function request($url, $headers = array(), $data = array(), $options = array()) {
+ return $this->data;
+ }
+ public function request_multiple($requests, $options) {
+ foreach ($requests as $id => &$request) {
+ $handler = new RawTransport();
+ $handler->data = $request['options']['raw.data'];
+ $request = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
+ }
+
+ return $requests;
+ }
+ public static function test() {
+ return true;
+ }
+}
diff --git a/includes/src/vendor/rmccue/requests/tests/phpunit.xml.dist b/includes/src/vendor/rmccue/requests/tests/phpunit.xml.dist
new file mode 100644
index 0000000..847b9b6
--- /dev/null
+++ b/includes/src/vendor/rmccue/requests/tests/phpunit.xml.dist
@@ -0,0 +1,35 @@
+
+
+
+
+ Auth
+
+
+ Transport
+
+
+ ChunkedEncoding.php
+ Cookies.php
+ IDNAEncoder.php
+ IRI.php
+ Requests.php
+ Response/Headers.php
+ SSL.php
+
+
+
+
+
+
+
+
+
+ .
+
+
+ ../library
+
+
+
\ No newline at end of file
diff --git a/includes/src/vendor/symfony/console/Application.php b/includes/src/vendor/symfony/console/Application.php
new file mode 100644
index 0000000..6434ef7
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Application.php
@@ -0,0 +1,1115 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+use Symfony\Component\Console\Exception\ExceptionInterface;
+use Symfony\Component\Console\Helper\DebugFormatterHelper;
+use Symfony\Component\Console\Helper\ProcessHelper;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputAwareInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Event\ConsoleCommandEvent;
+use Symfony\Component\Console\Event\ConsoleExceptionEvent;
+use Symfony\Component\Console\Event\ConsoleTerminateEvent;
+use Symfony\Component\Console\Exception\CommandNotFoundException;
+use Symfony\Component\Console\Exception\LogicException;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+/**
+ * An Application is the container for a collection of commands.
+ *
+ * It is the main entry point of a Console application.
+ *
+ * This class is optimized for a standard CLI environment.
+ *
+ * Usage:
+ *
+ * $app = new Application('myapp', '1.0 (stable)');
+ * $app->add(new SimpleCommand());
+ * $app->run();
+ *
+ * @author Fabien Potencier
+ */
+class Application
+{
+ private $commands = array();
+ private $wantHelps = false;
+ private $runningCommand;
+ private $name;
+ private $version;
+ private $catchExceptions = true;
+ private $autoExit = true;
+ private $definition;
+ private $helperSet;
+ private $dispatcher;
+ private $terminalDimensions;
+ private $defaultCommand;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The name of the application
+ * @param string $version The version of the application
+ */
+ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
+ {
+ $this->name = $name;
+ $this->version = $version;
+ $this->defaultCommand = 'list';
+ $this->helperSet = $this->getDefaultHelperSet();
+ $this->definition = $this->getDefaultInputDefinition();
+
+ foreach ($this->getDefaultCommands() as $command) {
+ $this->add($command);
+ }
+ }
+
+ public function setDispatcher(EventDispatcherInterface $dispatcher)
+ {
+ $this->dispatcher = $dispatcher;
+ }
+
+ /**
+ * Runs the current application.
+ *
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return int 0 if everything went fine, or an error code
+ *
+ * @throws \Exception When doRun returns Exception
+ */
+ public function run(InputInterface $input = null, OutputInterface $output = null)
+ {
+ if (null === $input) {
+ $input = new ArgvInput();
+ }
+
+ if (null === $output) {
+ $output = new ConsoleOutput();
+ }
+
+ $this->configureIO($input, $output);
+
+ try {
+ $exitCode = $this->doRun($input, $output);
+ } catch (\Exception $e) {
+ if (!$this->catchExceptions) {
+ throw $e;
+ }
+
+ if ($output instanceof ConsoleOutputInterface) {
+ $this->renderException($e, $output->getErrorOutput());
+ } else {
+ $this->renderException($e, $output);
+ }
+
+ $exitCode = $e->getCode();
+ if (is_numeric($exitCode)) {
+ $exitCode = (int) $exitCode;
+ if (0 === $exitCode) {
+ $exitCode = 1;
+ }
+ } else {
+ $exitCode = 1;
+ }
+ }
+
+ if ($this->autoExit) {
+ if ($exitCode > 255) {
+ $exitCode = 255;
+ }
+
+ exit($exitCode);
+ }
+
+ return $exitCode;
+ }
+
+ /**
+ * Runs the current application.
+ *
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return int 0 if everything went fine, or an error code
+ */
+ public function doRun(InputInterface $input, OutputInterface $output)
+ {
+ if (true === $input->hasParameterOption(array('--version', '-V'), true)) {
+ $output->writeln($this->getLongVersion());
+
+ return 0;
+ }
+
+ $name = $this->getCommandName($input);
+ if (true === $input->hasParameterOption(array('--help', '-h'), true)) {
+ if (!$name) {
+ $name = 'help';
+ $input = new ArrayInput(array('command' => 'help'));
+ } else {
+ $this->wantHelps = true;
+ }
+ }
+
+ if (!$name) {
+ $name = $this->defaultCommand;
+ $input = new ArrayInput(array('command' => $this->defaultCommand));
+ }
+
+ // the command name MUST be the first element of the input
+ $command = $this->find($name);
+
+ $this->runningCommand = $command;
+ $exitCode = $this->doRunCommand($command, $input, $output);
+ $this->runningCommand = null;
+
+ return $exitCode;
+ }
+
+ /**
+ * Set a helper set to be used with the command.
+ *
+ * @param HelperSet $helperSet The helper set
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Get the helper set associated with the command.
+ *
+ * @return HelperSet The HelperSet instance associated with this command
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Set an input definition to be used with this application.
+ *
+ * @param InputDefinition $definition The input definition
+ */
+ public function setDefinition(InputDefinition $definition)
+ {
+ $this->definition = $definition;
+ }
+
+ /**
+ * Gets the InputDefinition related to this Application.
+ *
+ * @return InputDefinition The InputDefinition instance
+ */
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ /**
+ * Gets the help message.
+ *
+ * @return string A help message
+ */
+ public function getHelp()
+ {
+ return $this->getLongVersion();
+ }
+
+ /**
+ * Gets whether to catch exceptions or not during commands execution.
+ *
+ * @return bool Whether to catch exceptions or not during commands execution
+ */
+ public function areExceptionsCaught()
+ {
+ return $this->catchExceptions;
+ }
+
+ /**
+ * Sets whether to catch exceptions or not during commands execution.
+ *
+ * @param bool $boolean Whether to catch exceptions or not during commands execution
+ */
+ public function setCatchExceptions($boolean)
+ {
+ $this->catchExceptions = (bool) $boolean;
+ }
+
+ /**
+ * Gets whether to automatically exit after a command execution or not.
+ *
+ * @return bool Whether to automatically exit after a command execution or not
+ */
+ public function isAutoExitEnabled()
+ {
+ return $this->autoExit;
+ }
+
+ /**
+ * Sets whether to automatically exit after a command execution or not.
+ *
+ * @param bool $boolean Whether to automatically exit after a command execution or not
+ */
+ public function setAutoExit($boolean)
+ {
+ $this->autoExit = (bool) $boolean;
+ }
+
+ /**
+ * Gets the name of the application.
+ *
+ * @return string The application name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the application name.
+ *
+ * @param string $name The application name
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * Gets the application version.
+ *
+ * @return string The application version
+ */
+ public function getVersion()
+ {
+ return $this->version;
+ }
+
+ /**
+ * Sets the application version.
+ *
+ * @param string $version The application version
+ */
+ public function setVersion($version)
+ {
+ $this->version = $version;
+ }
+
+ /**
+ * Returns the long version of the application.
+ *
+ * @return string The long application version
+ */
+ public function getLongVersion()
+ {
+ if ('UNKNOWN' !== $this->getName()) {
+ if ('UNKNOWN' !== $this->getVersion()) {
+ return sprintf('%s version %s', $this->getName(), $this->getVersion());
+ }
+
+ return sprintf('%s', $this->getName());
+ }
+
+ return 'Console Tool';
+ }
+
+ /**
+ * Registers a new command.
+ *
+ * @param string $name The command name
+ *
+ * @return Command The newly created command
+ */
+ public function register($name)
+ {
+ return $this->add(new Command($name));
+ }
+
+ /**
+ * Adds an array of command objects.
+ *
+ * If a Command is not enabled it will not be added.
+ *
+ * @param Command[] $commands An array of commands
+ */
+ public function addCommands(array $commands)
+ {
+ foreach ($commands as $command) {
+ $this->add($command);
+ }
+ }
+
+ /**
+ * Adds a command object.
+ *
+ * If a command with the same name already exists, it will be overridden.
+ * If the command is not enabled it will not be added.
+ *
+ * @param Command $command A Command object
+ *
+ * @return Command|null The registered command if enabled or null
+ */
+ public function add(Command $command)
+ {
+ $command->setApplication($this);
+
+ if (!$command->isEnabled()) {
+ $command->setApplication(null);
+
+ return;
+ }
+
+ if (null === $command->getDefinition()) {
+ throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));
+ }
+
+ $this->commands[$command->getName()] = $command;
+
+ foreach ($command->getAliases() as $alias) {
+ $this->commands[$alias] = $command;
+ }
+
+ return $command;
+ }
+
+ /**
+ * Returns a registered command by name or alias.
+ *
+ * @param string $name The command name or alias
+ *
+ * @return Command A Command object
+ *
+ * @throws CommandNotFoundException When command name given does not exist
+ */
+ public function get($name)
+ {
+ if (!isset($this->commands[$name])) {
+ throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name));
+ }
+
+ $command = $this->commands[$name];
+
+ if ($this->wantHelps) {
+ $this->wantHelps = false;
+
+ $helpCommand = $this->get('help');
+ $helpCommand->setCommand($command);
+
+ return $helpCommand;
+ }
+
+ return $command;
+ }
+
+ /**
+ * Returns true if the command exists, false otherwise.
+ *
+ * @param string $name The command name or alias
+ *
+ * @return bool true if the command exists, false otherwise
+ */
+ public function has($name)
+ {
+ return isset($this->commands[$name]);
+ }
+
+ /**
+ * Returns an array of all unique namespaces used by currently registered commands.
+ *
+ * It does not return the global namespace which always exists.
+ *
+ * @return string[] An array of namespaces
+ */
+ public function getNamespaces()
+ {
+ $namespaces = array();
+ foreach ($this->all() as $command) {
+ $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
+
+ foreach ($command->getAliases() as $alias) {
+ $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
+ }
+ }
+
+ return array_values(array_unique(array_filter($namespaces)));
+ }
+
+ /**
+ * Finds a registered namespace by a name or an abbreviation.
+ *
+ * @param string $namespace A namespace or abbreviation to search for
+ *
+ * @return string A registered namespace
+ *
+ * @throws CommandNotFoundException When namespace is incorrect or ambiguous
+ */
+ public function findNamespace($namespace)
+ {
+ $allNamespaces = $this->getNamespaces();
+ $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace);
+ $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces);
+
+ if (empty($namespaces)) {
+ $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
+
+ if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
+ if (1 == count($alternatives)) {
+ $message .= "\n\nDid you mean this?\n ";
+ } else {
+ $message .= "\n\nDid you mean one of these?\n ";
+ }
+
+ $message .= implode("\n ", $alternatives);
+ }
+
+ throw new CommandNotFoundException($message, $alternatives);
+ }
+
+ $exact = in_array($namespace, $namespaces, true);
+ if (count($namespaces) > 1 && !$exact) {
+ throw new CommandNotFoundException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
+ }
+
+ return $exact ? $namespace : reset($namespaces);
+ }
+
+ /**
+ * Finds a command by name or alias.
+ *
+ * Contrary to get, this command tries to find the best
+ * match if you give it an abbreviation of a name or alias.
+ *
+ * @param string $name A command name or a command alias
+ *
+ * @return Command A Command instance
+ *
+ * @throws CommandNotFoundException When command name is incorrect or ambiguous
+ */
+ public function find($name)
+ {
+ $allCommands = array_keys($this->commands);
+ $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name);
+ $commands = preg_grep('{^'.$expr.'}', $allCommands);
+
+ if (empty($commands) || count(preg_grep('{^'.$expr.'$}', $commands)) < 1) {
+ if (false !== $pos = strrpos($name, ':')) {
+ // check if a namespace exists and contains commands
+ $this->findNamespace(substr($name, 0, $pos));
+ }
+
+ $message = sprintf('Command "%s" is not defined.', $name);
+
+ if ($alternatives = $this->findAlternatives($name, $allCommands)) {
+ if (1 == count($alternatives)) {
+ $message .= "\n\nDid you mean this?\n ";
+ } else {
+ $message .= "\n\nDid you mean one of these?\n ";
+ }
+ $message .= implode("\n ", $alternatives);
+ }
+
+ throw new CommandNotFoundException($message, $alternatives);
+ }
+
+ // filter out aliases for commands which are already on the list
+ if (count($commands) > 1) {
+ $commandList = $this->commands;
+ $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {
+ $commandName = $commandList[$nameOrAlias]->getName();
+
+ return $commandName === $nameOrAlias || !in_array($commandName, $commands);
+ });
+ }
+
+ $exact = in_array($name, $commands, true);
+ if (count($commands) > 1 && !$exact) {
+ $suggestions = $this->getAbbreviationSuggestions(array_values($commands));
+
+ throw new CommandNotFoundException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions), array_values($commands));
+ }
+
+ return $this->get($exact ? $name : reset($commands));
+ }
+
+ /**
+ * Gets the commands (registered in the given namespace if provided).
+ *
+ * The array keys are the full names and the values the command instances.
+ *
+ * @param string $namespace A namespace name
+ *
+ * @return Command[] An array of Command instances
+ */
+ public function all($namespace = null)
+ {
+ if (null === $namespace) {
+ return $this->commands;
+ }
+
+ $commands = array();
+ foreach ($this->commands as $name => $command) {
+ if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) {
+ $commands[$name] = $command;
+ }
+ }
+
+ return $commands;
+ }
+
+ /**
+ * Returns an array of possible abbreviations given a set of names.
+ *
+ * @param array $names An array of names
+ *
+ * @return array An array of abbreviations
+ */
+ public static function getAbbreviations($names)
+ {
+ $abbrevs = array();
+ foreach ($names as $name) {
+ for ($len = strlen($name); $len > 0; --$len) {
+ $abbrev = substr($name, 0, $len);
+ $abbrevs[$abbrev][] = $name;
+ }
+ }
+
+ return $abbrevs;
+ }
+
+ /**
+ * Renders a caught exception.
+ *
+ * @param \Exception $e An exception instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ public function renderException(\Exception $e, OutputInterface $output)
+ {
+ $output->writeln('', OutputInterface::VERBOSITY_QUIET);
+
+ do {
+ $title = sprintf(
+ ' [%s%s] ',
+ get_class($e),
+ $output->isVerbose() && 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : ''
+ );
+
+ $len = $this->stringWidth($title);
+
+ $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
+ // HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327
+ if (defined('HHVM_VERSION') && $width > 1 << 31) {
+ $width = 1 << 31;
+ }
+ $formatter = $output->getFormatter();
+ $lines = array();
+ foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
+ foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
+ // pre-format lines to get the right string length
+ $lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
+ $lines[] = array($line, $lineLength);
+
+ $len = max($lineLength, $len);
+ }
+ }
+
+ $messages = array();
+ $messages[] = $emptyLine = $formatter->format(sprintf('%s', str_repeat(' ', $len)));
+ $messages[] = $formatter->format(sprintf('%s%s', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
+ foreach ($lines as $line) {
+ $messages[] = $formatter->format(sprintf(' %s %s', $line[0], str_repeat(' ', $len - $line[1])));
+ }
+ $messages[] = $emptyLine;
+ $messages[] = '';
+
+ $output->writeln($messages, OutputInterface::OUTPUT_RAW | OutputInterface::VERBOSITY_QUIET);
+
+ if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
+ $output->writeln('Exception trace:', OutputInterface::VERBOSITY_QUIET);
+
+ // exception related properties
+ $trace = $e->getTrace();
+ array_unshift($trace, array(
+ 'function' => '',
+ 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a',
+ 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a',
+ 'args' => array(),
+ ));
+
+ for ($i = 0, $count = count($trace); $i < $count; ++$i) {
+ $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
+ $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
+ $function = $trace[$i]['function'];
+ $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';
+ $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';
+
+ $output->writeln(sprintf(' %s%s%s() at %s:%s', $class, $type, $function, $file, $line), OutputInterface::VERBOSITY_QUIET);
+ }
+
+ $output->writeln('', OutputInterface::VERBOSITY_QUIET);
+ }
+ } while ($e = $e->getPrevious());
+
+ if (null !== $this->runningCommand) {
+ $output->writeln(sprintf('%s', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
+ $output->writeln('', OutputInterface::VERBOSITY_QUIET);
+ }
+ }
+
+ /**
+ * Tries to figure out the terminal width in which this application runs.
+ *
+ * @return int|null
+ */
+ protected function getTerminalWidth()
+ {
+ $dimensions = $this->getTerminalDimensions();
+
+ return $dimensions[0];
+ }
+
+ /**
+ * Tries to figure out the terminal height in which this application runs.
+ *
+ * @return int|null
+ */
+ protected function getTerminalHeight()
+ {
+ $dimensions = $this->getTerminalDimensions();
+
+ return $dimensions[1];
+ }
+
+ /**
+ * Tries to figure out the terminal dimensions based on the current environment.
+ *
+ * @return array Array containing width and height
+ */
+ public function getTerminalDimensions()
+ {
+ if ($this->terminalDimensions) {
+ return $this->terminalDimensions;
+ }
+
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ // extract [w, H] from "wxh (WxH)"
+ if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
+ return array((int) $matches[1], (int) $matches[2]);
+ }
+ // extract [w, h] from "wxh"
+ if (preg_match('/^(\d+)x(\d+)$/', $this->getConsoleMode(), $matches)) {
+ return array((int) $matches[1], (int) $matches[2]);
+ }
+ }
+
+ if ($sttyString = $this->getSttyColumns()) {
+ // extract [w, h] from "rows h; columns w;"
+ if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) {
+ return array((int) $matches[2], (int) $matches[1]);
+ }
+ // extract [w, h] from "; h rows; w columns"
+ if (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) {
+ return array((int) $matches[2], (int) $matches[1]);
+ }
+ }
+
+ return array(null, null);
+ }
+
+ /**
+ * Sets terminal dimensions.
+ *
+ * Can be useful to force terminal dimensions for functional tests.
+ *
+ * @param int $width The width
+ * @param int $height The height
+ *
+ * @return Application The current application
+ */
+ public function setTerminalDimensions($width, $height)
+ {
+ $this->terminalDimensions = array($width, $height);
+
+ return $this;
+ }
+
+ /**
+ * Configures the input and output instances based on the user arguments and options.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function configureIO(InputInterface $input, OutputInterface $output)
+ {
+ if (true === $input->hasParameterOption(array('--ansi'), true)) {
+ $output->setDecorated(true);
+ } elseif (true === $input->hasParameterOption(array('--no-ansi'), true)) {
+ $output->setDecorated(false);
+ }
+
+ if (true === $input->hasParameterOption(array('--no-interaction', '-n'), true)) {
+ $input->setInteractive(false);
+ } elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
+ $inputStream = $this->getHelperSet()->get('question')->getInputStream();
+ if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
+ $input->setInteractive(false);
+ }
+ }
+
+ if (true === $input->hasParameterOption(array('--quiet', '-q'), true)) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
+ } else {
+ if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || $input->getParameterOption('--verbose', false, true) === 3) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
+ } elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || $input->getParameterOption('--verbose', false, true) === 2) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
+ } elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) {
+ $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
+ }
+ }
+ }
+
+ /**
+ * Runs the current command.
+ *
+ * If an event dispatcher has been attached to the application,
+ * events are also dispatched during the life-cycle of the command.
+ *
+ * @param Command $command A Command instance
+ * @param InputInterface $input An Input instance
+ * @param OutputInterface $output An Output instance
+ *
+ * @return int 0 if everything went fine, or an error code
+ *
+ * @throws \Exception when the command being run threw an exception
+ */
+ protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
+ {
+ foreach ($command->getHelperSet() as $helper) {
+ if ($helper instanceof InputAwareInterface) {
+ $helper->setInput($input);
+ }
+ }
+
+ if (null === $this->dispatcher) {
+ return $command->run($input, $output);
+ }
+
+ // bind before the console.command event, so the listeners have access to input options/arguments
+ try {
+ $command->mergeApplicationDefinition();
+ $input->bind($command->getDefinition());
+ } catch (ExceptionInterface $e) {
+ // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
+ }
+
+ $event = new ConsoleCommandEvent($command, $input, $output);
+ $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
+
+ if ($event->commandShouldRun()) {
+ try {
+ $exitCode = $command->run($input, $output);
+ } catch (\Exception $e) {
+ $event = new ConsoleExceptionEvent($command, $input, $output, $e, $e->getCode());
+ $this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
+
+ $e = $event->getException();
+
+ $event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
+ $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
+
+ throw $e;
+ }
+ } else {
+ $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
+ }
+
+ $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
+ $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
+
+ return $event->getExitCode();
+ }
+
+ /**
+ * Gets the name of the command based on input.
+ *
+ * @param InputInterface $input The input interface
+ *
+ * @return string The command name
+ */
+ protected function getCommandName(InputInterface $input)
+ {
+ return $input->getFirstArgument();
+ }
+
+ /**
+ * Gets the default input definition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getDefaultInputDefinition()
+ {
+ return new InputDefinition(array(
+ new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
+
+ new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
+ new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
+ new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
+ new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
+ new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
+ new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
+ new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
+ ));
+ }
+
+ /**
+ * Gets the default commands that should always be available.
+ *
+ * @return Command[] An array of default Command instances
+ */
+ protected function getDefaultCommands()
+ {
+ return array(new HelpCommand(), new ListCommand());
+ }
+
+ /**
+ * Gets the default helper set with the helpers that should always be available.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ protected function getDefaultHelperSet()
+ {
+ return new HelperSet(array(
+ new FormatterHelper(),
+ new DebugFormatterHelper(),
+ new ProcessHelper(),
+ new QuestionHelper(),
+ ));
+ }
+
+ /**
+ * Runs and parses stty -a if it's available, suppressing any error output.
+ *
+ * @return string
+ */
+ private function getSttyColumns()
+ {
+ if (!function_exists('proc_open')) {
+ return;
+ }
+
+ $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
+ $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
+ if (is_resource($process)) {
+ $info = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ return $info;
+ }
+ }
+
+ /**
+ * Runs and parses mode CON if it's available, suppressing any error output.
+ *
+ * @return string|null x or null if it could not be parsed
+ */
+ private function getConsoleMode()
+ {
+ if (!function_exists('proc_open')) {
+ return;
+ }
+
+ $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
+ $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, array('suppress_errors' => true));
+ if (is_resource($process)) {
+ $info = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_close($process);
+
+ if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) {
+ return $matches[2].'x'.$matches[1];
+ }
+ }
+ }
+
+ /**
+ * Returns abbreviated suggestions in string format.
+ *
+ * @param array $abbrevs Abbreviated suggestions to convert
+ *
+ * @return string A formatted string of abbreviated suggestions
+ */
+ private function getAbbreviationSuggestions($abbrevs)
+ {
+ return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');
+ }
+
+ /**
+ * Returns the namespace part of the command name.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @param string $name The full name of the command
+ * @param string $limit The maximum number of parts of the namespace
+ *
+ * @return string The namespace of the command
+ */
+ public function extractNamespace($name, $limit = null)
+ {
+ $parts = explode(':', $name);
+ array_pop($parts);
+
+ return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));
+ }
+
+ /**
+ * Finds alternative of $name among $collection,
+ * if nothing is found in $collection, try in $abbrevs.
+ *
+ * @param string $name The string
+ * @param array|\Traversable $collection The collection
+ *
+ * @return string[] A sorted array of similar string
+ */
+ private function findAlternatives($name, $collection)
+ {
+ $threshold = 1e3;
+ $alternatives = array();
+
+ $collectionParts = array();
+ foreach ($collection as $item) {
+ $collectionParts[$item] = explode(':', $item);
+ }
+
+ foreach (explode(':', $name) as $i => $subname) {
+ foreach ($collectionParts as $collectionName => $parts) {
+ $exists = isset($alternatives[$collectionName]);
+ if (!isset($parts[$i]) && $exists) {
+ $alternatives[$collectionName] += $threshold;
+ continue;
+ } elseif (!isset($parts[$i])) {
+ continue;
+ }
+
+ $lev = levenshtein($subname, $parts[$i]);
+ if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
+ $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
+ } elseif ($exists) {
+ $alternatives[$collectionName] += $threshold;
+ }
+ }
+ }
+
+ foreach ($collection as $item) {
+ $lev = levenshtein($name, $item);
+ if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {
+ $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
+ }
+ }
+
+ $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
+ asort($alternatives);
+
+ return array_keys($alternatives);
+ }
+
+ /**
+ * Sets the default Command name.
+ *
+ * @param string $commandName The Command name
+ */
+ public function setDefaultCommand($commandName)
+ {
+ $this->defaultCommand = $commandName;
+ }
+
+ private function stringWidth($string)
+ {
+ if (false === $encoding = mb_detect_encoding($string, null, true)) {
+ return strlen($string);
+ }
+
+ return mb_strwidth($string, $encoding);
+ }
+
+ private function splitStringByWidth($string, $width)
+ {
+ // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.
+ // additionally, array_slice() is not enough as some character has doubled width.
+ // we need a function to split string not by character count but by string width
+ if (false === $encoding = mb_detect_encoding($string, null, true)) {
+ return str_split($string, $width);
+ }
+
+ $utf8String = mb_convert_encoding($string, 'utf8', $encoding);
+ $lines = array();
+ $line = '';
+ foreach (preg_split('//u', $utf8String) as $char) {
+ // test if $char could be appended to current line
+ if (mb_strwidth($line.$char, 'utf8') <= $width) {
+ $line .= $char;
+ continue;
+ }
+ // if not, push current line to array and make new line
+ $lines[] = str_pad($line, $width);
+ $line = $char;
+ }
+ if ('' !== $line) {
+ $lines[] = count($lines) ? str_pad($line, $width) : $line;
+ }
+
+ mb_convert_variables($encoding, 'utf8', $lines);
+
+ return $lines;
+ }
+
+ /**
+ * Returns all namespaces of the command name.
+ *
+ * @param string $name The full name of the command
+ *
+ * @return string[] The namespaces of the command
+ */
+ private function extractAllNamespaces($name)
+ {
+ // -1 as third argument is needed to skip the command short name when exploding
+ $parts = explode(':', $name, -1);
+ $namespaces = array();
+
+ foreach ($parts as $part) {
+ if (count($namespaces)) {
+ $namespaces[] = end($namespaces).':'.$part;
+ } else {
+ $namespaces[] = $part;
+ }
+ }
+
+ return $namespaces;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/CHANGELOG.md b/includes/src/vendor/symfony/console/CHANGELOG.md
new file mode 100644
index 0000000..df37640
--- /dev/null
+++ b/includes/src/vendor/symfony/console/CHANGELOG.md
@@ -0,0 +1,79 @@
+CHANGELOG
+=========
+
+3.1.0
+-----
+
+ * added truncate method to FormatterHelper
+ * added setColumnWidth(s) method to Table
+
+2.8.3
+-----
+
+ * remove readline support from the question helper as it caused issues
+
+2.8.0
+-----
+
+ * use readline for user input in the question helper when available to allow
+ the use of arrow keys
+
+2.6.0
+-----
+
+ * added a Process helper
+ * added a DebugFormatter helper
+
+2.5.0
+-----
+
+ * deprecated the dialog helper (use the question helper instead)
+ * deprecated TableHelper in favor of Table
+ * deprecated ProgressHelper in favor of ProgressBar
+ * added ConsoleLogger
+ * added a question helper
+ * added a way to set the process name of a command
+ * added a way to set a default command instead of `ListCommand`
+
+2.4.0
+-----
+
+ * added a way to force terminal dimensions
+ * added a convenient method to detect verbosity level
+ * [BC BREAK] made descriptors use output instead of returning a string
+
+2.3.0
+-----
+
+ * added multiselect support to the select dialog helper
+ * added Table Helper for tabular data rendering
+ * added support for events in `Application`
+ * added a way to normalize EOLs in `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()`
+ * added a way to set the progress bar progress via the `setCurrent` method
+ * added support for multiple InputOption shortcuts, written as `'-a|-b|-c'`
+ * added two additional verbosity levels, VERBOSITY_VERY_VERBOSE and VERBOSITY_DEBUG
+
+2.2.0
+-----
+
+ * added support for colorization on Windows via ConEmu
+ * add a method to Dialog Helper to ask for a question and hide the response
+ * added support for interactive selections in console (DialogHelper::select())
+ * added support for autocompletion as you type in Dialog Helper
+
+2.1.0
+-----
+
+ * added ConsoleOutputInterface
+ * added the possibility to disable a command (Command::isEnabled())
+ * added suggestions when a command does not exist
+ * added a --raw option to the list command
+ * added support for STDERR in the console output class (errors are now sent
+ to STDERR)
+ * made the defaults (helper set, commands, input definition) in Application
+ more easily customizable
+ * added support for the shell even if readline is not available
+ * added support for process isolation in Symfony shell via
+ `--process-isolation` switch
+ * added support for `--`, which disables options parsing after that point
+ (tokens will be parsed as arguments)
diff --git a/includes/src/vendor/symfony/console/Command/Command.php b/includes/src/vendor/symfony/console/Command/Command.php
new file mode 100644
index 0000000..d212a32
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Command/Command.php
@@ -0,0 +1,631 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Exception\ExceptionInterface;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Base class for all commands.
+ *
+ * @author Fabien Potencier
+ */
+class Command
+{
+ private $application;
+ private $name;
+ private $processTitle;
+ private $aliases = array();
+ private $definition;
+ private $help;
+ private $description;
+ private $ignoreValidationErrors = false;
+ private $applicationDefinitionMerged = false;
+ private $applicationDefinitionMergedWithArgs = false;
+ private $code;
+ private $synopsis = array();
+ private $usages = array();
+ private $helperSet;
+
+ /**
+ * Constructor.
+ *
+ * @param string|null $name The name of the command; passing null means it must be set in configure()
+ *
+ * @throws LogicException When the command name is empty
+ */
+ public function __construct($name = null)
+ {
+ $this->definition = new InputDefinition();
+
+ if (null !== $name) {
+ $this->setName($name);
+ }
+
+ $this->configure();
+
+ if (!$this->name) {
+ throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
+ }
+ }
+
+ /**
+ * Ignores validation errors.
+ *
+ * This is mainly useful for the help command.
+ */
+ public function ignoreValidationErrors()
+ {
+ $this->ignoreValidationErrors = true;
+ }
+
+ /**
+ * Sets the application instance for this command.
+ *
+ * @param Application $application An Application instance
+ */
+ public function setApplication(Application $application = null)
+ {
+ $this->application = $application;
+ if ($application) {
+ $this->setHelperSet($application->getHelperSet());
+ } else {
+ $this->helperSet = null;
+ }
+ }
+
+ /**
+ * Sets the helper set.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Gets the helper set.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Gets the application instance for this command.
+ *
+ * @return Application An Application instance
+ */
+ public function getApplication()
+ {
+ return $this->application;
+ }
+
+ /**
+ * Checks whether the command is enabled or not in the current environment.
+ *
+ * Override this to check for x or y and return false if the command can not
+ * run properly under the current conditions.
+ *
+ * @return bool
+ */
+ public function isEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * Configures the current command.
+ */
+ protected function configure()
+ {
+ }
+
+ /**
+ * Executes the current command.
+ *
+ * This method is not abstract because you can use this class
+ * as a concrete class. In this case, instead of defining the
+ * execute() method, you set the code to execute by passing
+ * a Closure to the setCode() method.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return null|int null or 0 if everything went fine, or an error code
+ *
+ * @throws LogicException When this abstract method is not implemented
+ *
+ * @see setCode()
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ throw new LogicException('You must override the execute() method in the concrete command class.');
+ }
+
+ /**
+ * Interacts with the user.
+ *
+ * This method is executed before the InputDefinition is validated.
+ * This means that this is the only place where the command can
+ * interactively ask for values of missing required arguments.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Initializes the command just after the input has been validated.
+ *
+ * This is mainly useful when a lot of commands extends one main command
+ * where some things need to be initialized based on the input arguments and options.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ */
+ protected function initialize(InputInterface $input, OutputInterface $output)
+ {
+ }
+
+ /**
+ * Runs the command.
+ *
+ * The code to execute is either defined directly with the
+ * setCode() method or by overriding the execute() method
+ * in a sub-class.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ *
+ * @return int The command exit code
+ *
+ * @throws \Exception
+ *
+ * @see setCode()
+ * @see execute()
+ */
+ public function run(InputInterface $input, OutputInterface $output)
+ {
+ // force the creation of the synopsis before the merge with the app definition
+ $this->getSynopsis(true);
+ $this->getSynopsis(false);
+
+ // add the application arguments and options
+ $this->mergeApplicationDefinition();
+
+ // bind the input against the command specific arguments/options
+ try {
+ $input->bind($this->definition);
+ } catch (ExceptionInterface $e) {
+ if (!$this->ignoreValidationErrors) {
+ throw $e;
+ }
+ }
+
+ $this->initialize($input, $output);
+
+ if (null !== $this->processTitle) {
+ if (function_exists('cli_set_process_title')) {
+ cli_set_process_title($this->processTitle);
+ } elseif (function_exists('setproctitle')) {
+ setproctitle($this->processTitle);
+ } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
+ $output->writeln('Install the proctitle PECL to be able to change the process title.');
+ }
+ }
+
+ if ($input->isInteractive()) {
+ $this->interact($input, $output);
+ }
+
+ // The command name argument is often omitted when a command is executed directly with its run() method.
+ // It would fail the validation if we didn't make sure the command argument is present,
+ // since it's required by the application.
+ if ($input->hasArgument('command') && null === $input->getArgument('command')) {
+ $input->setArgument('command', $this->getName());
+ }
+
+ $input->validate();
+
+ if ($this->code) {
+ $statusCode = call_user_func($this->code, $input, $output);
+ } else {
+ $statusCode = $this->execute($input, $output);
+ }
+
+ return is_numeric($statusCode) ? (int) $statusCode : 0;
+ }
+
+ /**
+ * Sets the code to execute when running this command.
+ *
+ * If this method is used, it overrides the code defined
+ * in the execute() method.
+ *
+ * @param callable $code A callable(InputInterface $input, OutputInterface $output)
+ *
+ * @return Command The current instance
+ *
+ * @throws InvalidArgumentException
+ *
+ * @see execute()
+ */
+ public function setCode(callable $code)
+ {
+ if ($code instanceof \Closure) {
+ $r = new \ReflectionFunction($code);
+ if (null === $r->getClosureThis()) {
+ $code = \Closure::bind($code, $this);
+ }
+ }
+
+ $this->code = $code;
+
+ return $this;
+ }
+
+ /**
+ * Merges the application definition with the command definition.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
+ */
+ public function mergeApplicationDefinition($mergeArgs = true)
+ {
+ if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) {
+ return;
+ }
+
+ $this->definition->addOptions($this->application->getDefinition()->getOptions());
+
+ if ($mergeArgs) {
+ $currentArguments = $this->definition->getArguments();
+ $this->definition->setArguments($this->application->getDefinition()->getArguments());
+ $this->definition->addArguments($currentArguments);
+ }
+
+ $this->applicationDefinitionMerged = true;
+ if ($mergeArgs) {
+ $this->applicationDefinitionMergedWithArgs = true;
+ }
+ }
+
+ /**
+ * Sets an array of argument and option instances.
+ *
+ * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
+ *
+ * @return Command The current instance
+ */
+ public function setDefinition($definition)
+ {
+ if ($definition instanceof InputDefinition) {
+ $this->definition = $definition;
+ } else {
+ $this->definition->setDefinition($definition);
+ }
+
+ $this->applicationDefinitionMerged = false;
+
+ return $this;
+ }
+
+ /**
+ * Gets the InputDefinition attached to this Command.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ public function getDefinition()
+ {
+ return $this->definition;
+ }
+
+ /**
+ * Gets the InputDefinition to be used to create representations of this Command.
+ *
+ * Can be overridden to provide the original command representation when it would otherwise
+ * be changed by merging with the application InputDefinition.
+ *
+ * This method is not part of public API and should not be used directly.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ public function getNativeDefinition()
+ {
+ return $this->getDefinition();
+ }
+
+ /**
+ * Adds an argument.
+ *
+ * @param string $name The argument name
+ * @param int $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
+ * @param string $description A description text
+ * @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
+ *
+ * @return Command The current instance
+ */
+ public function addArgument($name, $mode = null, $description = '', $default = null)
+ {
+ $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
+
+ return $this;
+ }
+
+ /**
+ * Adds an option.
+ *
+ * @param string $name The option name
+ * @param string $shortcut The shortcut (can be null)
+ * @param int $mode The option mode: One of the InputOption::VALUE_* constants
+ * @param string $description A description text
+ * @param mixed $default The default value (must be null for InputOption::VALUE_NONE)
+ *
+ * @return Command The current instance
+ */
+ public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)
+ {
+ $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
+
+ return $this;
+ }
+
+ /**
+ * Sets the name of the command.
+ *
+ * This method can set both the namespace and the name if
+ * you separate them by a colon (:)
+ *
+ * $command->setName('foo:bar');
+ *
+ * @param string $name The command name
+ *
+ * @return Command The current instance
+ *
+ * @throws InvalidArgumentException When the name is invalid
+ */
+ public function setName($name)
+ {
+ $this->validateName($name);
+
+ $this->name = $name;
+
+ return $this;
+ }
+
+ /**
+ * Sets the process title of the command.
+ *
+ * This feature should be used only when creating a long process command,
+ * like a daemon.
+ *
+ * PHP 5.5+ or the proctitle PECL library is required
+ *
+ * @param string $title The process title
+ *
+ * @return Command The current instance
+ */
+ public function setProcessTitle($title)
+ {
+ $this->processTitle = $title;
+
+ return $this;
+ }
+
+ /**
+ * Returns the command name.
+ *
+ * @return string The command name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the description for the command.
+ *
+ * @param string $description The description for the command
+ *
+ * @return Command The current instance
+ */
+ public function setDescription($description)
+ {
+ $this->description = $description;
+
+ return $this;
+ }
+
+ /**
+ * Returns the description for the command.
+ *
+ * @return string The description for the command
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Sets the help for the command.
+ *
+ * @param string $help The help for the command
+ *
+ * @return Command The current instance
+ */
+ public function setHelp($help)
+ {
+ $this->help = $help;
+
+ return $this;
+ }
+
+ /**
+ * Returns the help for the command.
+ *
+ * @return string The help for the command
+ */
+ public function getHelp()
+ {
+ return $this->help;
+ }
+
+ /**
+ * Returns the processed help for the command replacing the %command.name% and
+ * %command.full_name% patterns with the real values dynamically.
+ *
+ * @return string The processed help for the command
+ */
+ public function getProcessedHelp()
+ {
+ $name = $this->name;
+
+ $placeholders = array(
+ '%command.name%',
+ '%command.full_name%',
+ );
+ $replacements = array(
+ $name,
+ $_SERVER['PHP_SELF'].' '.$name,
+ );
+
+ return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
+ }
+
+ /**
+ * Sets the aliases for the command.
+ *
+ * @param string[] $aliases An array of aliases for the command
+ *
+ * @return Command The current instance
+ *
+ * @throws InvalidArgumentException When an alias is invalid
+ */
+ public function setAliases($aliases)
+ {
+ if (!is_array($aliases) && !$aliases instanceof \Traversable) {
+ throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
+ }
+
+ foreach ($aliases as $alias) {
+ $this->validateName($alias);
+ }
+
+ $this->aliases = $aliases;
+
+ return $this;
+ }
+
+ /**
+ * Returns the aliases for the command.
+ *
+ * @return array An array of aliases for the command
+ */
+ public function getAliases()
+ {
+ return $this->aliases;
+ }
+
+ /**
+ * Returns the synopsis for the command.
+ *
+ * @param bool $short Whether to show the short version of the synopsis (with options folded) or not
+ *
+ * @return string The synopsis
+ */
+ public function getSynopsis($short = false)
+ {
+ $key = $short ? 'short' : 'long';
+
+ if (!isset($this->synopsis[$key])) {
+ $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
+ }
+
+ return $this->synopsis[$key];
+ }
+
+ /**
+ * Add a command usage example.
+ *
+ * @param string $usage The usage, it'll be prefixed with the command name
+ */
+ public function addUsage($usage)
+ {
+ if (0 !== strpos($usage, $this->name)) {
+ $usage = sprintf('%s %s', $this->name, $usage);
+ }
+
+ $this->usages[] = $usage;
+
+ return $this;
+ }
+
+ /**
+ * Returns alternative usages of the command.
+ *
+ * @return array
+ */
+ public function getUsages()
+ {
+ return $this->usages;
+ }
+
+ /**
+ * Gets a helper instance by name.
+ *
+ * @param string $name The helper name
+ *
+ * @return mixed The helper value
+ *
+ * @throws LogicException if no HelperSet is defined
+ * @throws InvalidArgumentException if the helper is not defined
+ */
+ public function getHelper($name)
+ {
+ if (null === $this->helperSet) {
+ throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
+ }
+
+ return $this->helperSet->get($name);
+ }
+
+ /**
+ * Validates a command name.
+ *
+ * It must be non-empty and parts can optionally be separated by ":".
+ *
+ * @param string $name
+ *
+ * @throws InvalidArgumentException When the name is invalid
+ */
+ private function validateName($name)
+ {
+ if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) {
+ throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name));
+ }
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Command/HelpCommand.php b/includes/src/vendor/symfony/console/Command/HelpCommand.php
new file mode 100644
index 0000000..b8fd911
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Command/HelpCommand.php
@@ -0,0 +1,86 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Helper\DescriptorHelper;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * HelpCommand displays the help for a given command.
+ *
+ * @author Fabien Potencier
+ */
+class HelpCommand extends Command
+{
+ private $command;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this->ignoreValidationErrors();
+
+ $this
+ ->setName('help')
+ ->setDefinition(array(
+ new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
+ new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),
+ ))
+ ->setDescription('Displays help for a command')
+ ->setHelp(<<<'EOF'
+The %command.name% command displays help for a given command:
+
+ php %command.full_name% list
+
+You can also output the help in other formats by using the --format option:
+
+ php %command.full_name% --format=xml list
+
+To display the list of available commands, please use the list command.
+EOF
+ )
+ ;
+ }
+
+ /**
+ * Sets the command.
+ *
+ * @param Command $command The command to set
+ */
+ public function setCommand(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ if (null === $this->command) {
+ $this->command = $this->getApplication()->find($input->getArgument('command_name'));
+ }
+
+ $helper = new DescriptorHelper();
+ $helper->describe($output, $this->command, array(
+ 'format' => $input->getOption('format'),
+ 'raw_text' => $input->getOption('raw'),
+ ));
+
+ $this->command = null;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Command/ListCommand.php b/includes/src/vendor/symfony/console/Command/ListCommand.php
new file mode 100644
index 0000000..179ddea
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Command/ListCommand.php
@@ -0,0 +1,90 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Command;
+
+use Symfony\Component\Console\Helper\DescriptorHelper;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputDefinition;
+
+/**
+ * ListCommand displays the list of all available commands for the application.
+ *
+ * @author Fabien Potencier
+ */
+class ListCommand extends Command
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('list')
+ ->setDefinition($this->createDefinition())
+ ->setDescription('Lists commands')
+ ->setHelp(<<<'EOF'
+The %command.name% command lists all commands:
+
+ php %command.full_name%
+
+You can also display the commands for a specific namespace:
+
+ php %command.full_name% test
+
+You can also output the information in other formats by using the --format option:
+
+ php %command.full_name% --format=xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php %command.full_name% --raw
+EOF
+ )
+ ;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getNativeDefinition()
+ {
+ return $this->createDefinition();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $helper = new DescriptorHelper();
+ $helper->describe($output, $this->getApplication(), array(
+ 'format' => $input->getOption('format'),
+ 'raw_text' => $input->getOption('raw'),
+ 'namespace' => $input->getArgument('namespace'),
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ private function createDefinition()
+ {
+ return new InputDefinition(array(
+ new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),
+ new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
+ ));
+ }
+}
diff --git a/includes/src/vendor/symfony/console/ConsoleEvents.php b/includes/src/vendor/symfony/console/ConsoleEvents.php
new file mode 100644
index 0000000..b3571e9
--- /dev/null
+++ b/includes/src/vendor/symfony/console/ConsoleEvents.php
@@ -0,0 +1,53 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console;
+
+/**
+ * Contains all events dispatched by an Application.
+ *
+ * @author Francesco Levorato
+ */
+final class ConsoleEvents
+{
+ /**
+ * The COMMAND event allows you to attach listeners before any command is
+ * executed by the console. It also allows you to modify the command, input and output
+ * before they are handled to the command.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent")
+ *
+ * @var string
+ */
+ const COMMAND = 'console.command';
+
+ /**
+ * The TERMINATE event allows you to attach listeners after a command is
+ * executed by the console.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent")
+ *
+ * @var string
+ */
+ const TERMINATE = 'console.terminate';
+
+ /**
+ * The EXCEPTION event occurs when an uncaught exception appears.
+ *
+ * This event allows you to deal with the exception or
+ * to modify the thrown exception.
+ *
+ * @Event("Symfony\Component\Console\Event\ConsoleExceptionEvent")
+ *
+ * @var string
+ */
+ const EXCEPTION = 'console.exception';
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/ApplicationDescription.php b/includes/src/vendor/symfony/console/Descriptor/ApplicationDescription.php
new file mode 100644
index 0000000..89961b9
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/ApplicationDescription.php
@@ -0,0 +1,160 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\CommandNotFoundException;
+
+/**
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class ApplicationDescription
+{
+ const GLOBAL_NAMESPACE = '_global';
+
+ /**
+ * @var Application
+ */
+ private $application;
+
+ /**
+ * @var null|string
+ */
+ private $namespace;
+
+ /**
+ * @var array
+ */
+ private $namespaces;
+
+ /**
+ * @var Command[]
+ */
+ private $commands;
+
+ /**
+ * @var Command[]
+ */
+ private $aliases;
+
+ /**
+ * Constructor.
+ *
+ * @param Application $application
+ * @param string|null $namespace
+ */
+ public function __construct(Application $application, $namespace = null)
+ {
+ $this->application = $application;
+ $this->namespace = $namespace;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNamespaces()
+ {
+ if (null === $this->namespaces) {
+ $this->inspectApplication();
+ }
+
+ return $this->namespaces;
+ }
+
+ /**
+ * @return Command[]
+ */
+ public function getCommands()
+ {
+ if (null === $this->commands) {
+ $this->inspectApplication();
+ }
+
+ return $this->commands;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return Command
+ *
+ * @throws CommandNotFoundException
+ */
+ public function getCommand($name)
+ {
+ if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
+ throw new CommandNotFoundException(sprintf('Command %s does not exist.', $name));
+ }
+
+ return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];
+ }
+
+ private function inspectApplication()
+ {
+ $this->commands = array();
+ $this->namespaces = array();
+
+ $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
+ foreach ($this->sortCommands($all) as $namespace => $commands) {
+ $names = array();
+
+ /** @var Command $command */
+ foreach ($commands as $name => $command) {
+ if (!$command->getName()) {
+ continue;
+ }
+
+ if ($command->getName() === $name) {
+ $this->commands[$name] = $command;
+ } else {
+ $this->aliases[$name] = $command;
+ }
+
+ $names[] = $name;
+ }
+
+ $this->namespaces[$namespace] = array('id' => $namespace, 'commands' => $names);
+ }
+ }
+
+ /**
+ * @param array $commands
+ *
+ * @return array
+ */
+ private function sortCommands(array $commands)
+ {
+ $namespacedCommands = array();
+ $globalCommands = array();
+ foreach ($commands as $name => $command) {
+ $key = $this->application->extractNamespace($name, 1);
+ if (!$key) {
+ $globalCommands['_global'][$name] = $command;
+ } else {
+ $namespacedCommands[$key][$name] = $command;
+ }
+ }
+ ksort($namespacedCommands);
+ $namespacedCommands = array_merge($globalCommands, $namespacedCommands);
+
+ foreach ($namespacedCommands as &$commandsSet) {
+ ksort($commandsSet);
+ }
+ // unset reference to keep scope clear
+ unset($commandsSet);
+
+ return $namespacedCommands;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/Descriptor.php b/includes/src/vendor/symfony/console/Descriptor/Descriptor.php
new file mode 100644
index 0000000..50dd86c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/Descriptor.php
@@ -0,0 +1,122 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+abstract class Descriptor implements DescriptorInterface
+{
+ /**
+ * @var OutputInterface
+ */
+ protected $output;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function describe(OutputInterface $output, $object, array $options = array())
+ {
+ $this->output = $output;
+
+ switch (true) {
+ case $object instanceof InputArgument:
+ $this->describeInputArgument($object, $options);
+ break;
+ case $object instanceof InputOption:
+ $this->describeInputOption($object, $options);
+ break;
+ case $object instanceof InputDefinition:
+ $this->describeInputDefinition($object, $options);
+ break;
+ case $object instanceof Command:
+ $this->describeCommand($object, $options);
+ break;
+ case $object instanceof Application:
+ $this->describeApplication($object, $options);
+ break;
+ default:
+ throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
+ }
+ }
+
+ /**
+ * Writes content to output.
+ *
+ * @param string $content
+ * @param bool $decorated
+ */
+ protected function write($content, $decorated = false)
+ {
+ $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
+ }
+
+ /**
+ * Describes an InputArgument instance.
+ *
+ * @param InputArgument $argument
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeInputArgument(InputArgument $argument, array $options = array());
+
+ /**
+ * Describes an InputOption instance.
+ *
+ * @param InputOption $option
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeInputOption(InputOption $option, array $options = array());
+
+ /**
+ * Describes an InputDefinition instance.
+ *
+ * @param InputDefinition $definition
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeInputDefinition(InputDefinition $definition, array $options = array());
+
+ /**
+ * Describes a Command instance.
+ *
+ * @param Command $command
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeCommand(Command $command, array $options = array());
+
+ /**
+ * Describes an Application instance.
+ *
+ * @param Application $application
+ * @param array $options
+ *
+ * @return string|mixed
+ */
+ abstract protected function describeApplication(Application $application, array $options = array());
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/DescriptorInterface.php b/includes/src/vendor/symfony/console/Descriptor/DescriptorInterface.php
new file mode 100644
index 0000000..3929b6d
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/DescriptorInterface.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Descriptor interface.
+ *
+ * @author Jean-François Simon
+ */
+interface DescriptorInterface
+{
+ /**
+ * Describes an InputArgument instance.
+ *
+ * @param OutputInterface $output
+ * @param object $object
+ * @param array $options
+ */
+ public function describe(OutputInterface $output, $object, array $options = array());
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/JsonDescriptor.php b/includes/src/vendor/symfony/console/Descriptor/JsonDescriptor.php
new file mode 100644
index 0000000..87e38fd
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/JsonDescriptor.php
@@ -0,0 +1,166 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * JSON descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class JsonDescriptor extends Descriptor
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ $this->writeData($this->getInputArgumentData($argument), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ $this->writeData($this->getInputOptionData($option), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ $this->writeData($this->getInputDefinitionData($definition), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $this->writeData($this->getCommandData($command), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+ $commands = array();
+
+ foreach ($description->getCommands() as $command) {
+ $commands[] = $this->getCommandData($command);
+ }
+
+ $data = $describedNamespace
+ ? array('commands' => $commands, 'namespace' => $describedNamespace)
+ : array('commands' => $commands, 'namespaces' => array_values($description->getNamespaces()));
+
+ $this->writeData($data, $options);
+ }
+
+ /**
+ * Writes data as json.
+ *
+ * @param array $data
+ * @param array $options
+ *
+ * @return array|string
+ */
+ private function writeData(array $data, array $options)
+ {
+ $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0));
+ }
+
+ /**
+ * @param InputArgument $argument
+ *
+ * @return array
+ */
+ private function getInputArgumentData(InputArgument $argument)
+ {
+ return array(
+ 'name' => $argument->getName(),
+ 'is_required' => $argument->isRequired(),
+ 'is_array' => $argument->isArray(),
+ 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()),
+ 'default' => $argument->getDefault(),
+ );
+ }
+
+ /**
+ * @param InputOption $option
+ *
+ * @return array
+ */
+ private function getInputOptionData(InputOption $option)
+ {
+ return array(
+ 'name' => '--'.$option->getName(),
+ 'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
+ 'accept_value' => $option->acceptValue(),
+ 'is_value_required' => $option->isValueRequired(),
+ 'is_multiple' => $option->isArray(),
+ 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()),
+ 'default' => $option->getDefault(),
+ );
+ }
+
+ /**
+ * @param InputDefinition $definition
+ *
+ * @return array
+ */
+ private function getInputDefinitionData(InputDefinition $definition)
+ {
+ $inputArguments = array();
+ foreach ($definition->getArguments() as $name => $argument) {
+ $inputArguments[$name] = $this->getInputArgumentData($argument);
+ }
+
+ $inputOptions = array();
+ foreach ($definition->getOptions() as $name => $option) {
+ $inputOptions[$name] = $this->getInputOptionData($option);
+ }
+
+ return array('arguments' => $inputArguments, 'options' => $inputOptions);
+ }
+
+ /**
+ * @param Command $command
+ *
+ * @return array
+ */
+ private function getCommandData(Command $command)
+ {
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ return array(
+ 'name' => $command->getName(),
+ 'usage' => array_merge(array($command->getSynopsis()), $command->getUsages(), $command->getAliases()),
+ 'description' => $command->getDescription(),
+ 'help' => $command->getProcessedHelp(),
+ 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
+ );
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/MarkdownDescriptor.php b/includes/src/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
new file mode 100644
index 0000000..d3d76a4
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/MarkdownDescriptor.php
@@ -0,0 +1,143 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * Markdown descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class MarkdownDescriptor extends Descriptor
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ $this->write(
+ '**'.$argument->getName().':**'."\n\n"
+ .'* Name: '.($argument->getName() ?: '')."\n"
+ .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n"
+ .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n"
+ .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n ", $argument->getDescription() ?: '')."\n"
+ .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ $this->write(
+ '**'.$option->getName().':**'."\n\n"
+ .'* Name: `--'.$option->getName().'`'."\n"
+ .'* Shortcut: '.($option->getShortcut() ? '`-'.implode('|-', explode('|', $option->getShortcut())).'`' : '')."\n"
+ .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n"
+ .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n"
+ .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n"
+ .'* Description: '.preg_replace('/\s*[\r\n]\s*/', "\n ", $option->getDescription() ?: '')."\n"
+ .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ if ($showArguments = count($definition->getArguments()) > 0) {
+ $this->write('### Arguments:');
+ foreach ($definition->getArguments() as $argument) {
+ $this->write("\n\n");
+ $this->write($this->describeInputArgument($argument));
+ }
+ }
+
+ if (count($definition->getOptions()) > 0) {
+ if ($showArguments) {
+ $this->write("\n\n");
+ }
+
+ $this->write('### Options:');
+ foreach ($definition->getOptions() as $option) {
+ $this->write("\n\n");
+ $this->write($this->describeInputOption($option));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ $this->write(
+ $command->getName()."\n"
+ .str_repeat('-', strlen($command->getName()))."\n\n"
+ .'* Description: '.($command->getDescription() ?: '')."\n"
+ .'* Usage:'."\n\n"
+ .array_reduce(array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
+ return $carry .= ' * `'.$usage.'`'."\n";
+ })
+ );
+
+ if ($help = $command->getProcessedHelp()) {
+ $this->write("\n");
+ $this->write($help);
+ }
+
+ if ($command->getNativeDefinition()) {
+ $this->write("\n\n");
+ $this->describeInputDefinition($command->getNativeDefinition());
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+
+ $this->write($application->getName()."\n".str_repeat('=', strlen($application->getName())));
+
+ foreach ($description->getNamespaces() as $namespace) {
+ if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+ $this->write("\n\n");
+ $this->write('**'.$namespace['id'].':**');
+ }
+
+ $this->write("\n\n");
+ $this->write(implode("\n", array_map(function ($commandName) {
+ return '* '.$commandName;
+ }, $namespace['commands'])));
+ }
+
+ foreach ($description->getCommands() as $command) {
+ $this->write("\n\n");
+ $this->write($this->describeCommand($command));
+ }
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/TextDescriptor.php b/includes/src/vendor/symfony/console/Descriptor/TextDescriptor.php
new file mode 100644
index 0000000..560ce15
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/TextDescriptor.php
@@ -0,0 +1,283 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * Text descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class TextDescriptor extends Descriptor
+{
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
+ $default = sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault()));
+ } else {
+ $default = '';
+ }
+
+ $totalWidth = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());
+ $spacingWidth = $totalWidth - strlen($argument->getName()) + 2;
+
+ $this->writeText(sprintf(' %s%s%s%s',
+ $argument->getName(),
+ str_repeat(' ', $spacingWidth),
+ // + 17 = 2 spaces + + + 2 spaces
+ preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $argument->getDescription()),
+ $default
+ ), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
+ $default = sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault()));
+ } else {
+ $default = '';
+ }
+
+ $value = '';
+ if ($option->acceptValue()) {
+ $value = '='.strtoupper($option->getName());
+
+ if ($option->isValueOptional()) {
+ $value = '['.$value.']';
+ }
+ }
+
+ $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions(array($option));
+ $synopsis = sprintf('%s%s',
+ $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ',
+ sprintf('--%s%s', $option->getName(), $value)
+ );
+
+ $spacingWidth = $totalWidth - strlen($synopsis) + 2;
+
+ $this->writeText(sprintf(' %s%s%s%s%s',
+ $synopsis,
+ str_repeat(' ', $spacingWidth),
+ // + 17 = 2 spaces + + + 2 spaces
+ preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 17), $option->getDescription()),
+ $default,
+ $option->isArray() ? ' (multiple values allowed)' : ''
+ ), $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
+ foreach ($definition->getArguments() as $argument) {
+ $totalWidth = max($totalWidth, strlen($argument->getName()));
+ }
+
+ if ($definition->getArguments()) {
+ $this->writeText('Arguments:', $options);
+ $this->writeText("\n");
+ foreach ($definition->getArguments() as $argument) {
+ $this->describeInputArgument($argument, array_merge($options, array('total_width' => $totalWidth)));
+ $this->writeText("\n");
+ }
+ }
+
+ if ($definition->getArguments() && $definition->getOptions()) {
+ $this->writeText("\n");
+ }
+
+ if ($definition->getOptions()) {
+ $laterOptions = array();
+
+ $this->writeText('Options:', $options);
+ foreach ($definition->getOptions() as $option) {
+ if (strlen($option->getShortcut()) > 1) {
+ $laterOptions[] = $option;
+ continue;
+ }
+ $this->writeText("\n");
+ $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
+ }
+ foreach ($laterOptions as $option) {
+ $this->writeText("\n");
+ $this->describeInputOption($option, array_merge($options, array('total_width' => $totalWidth)));
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $command->getSynopsis(true);
+ $command->getSynopsis(false);
+ $command->mergeApplicationDefinition(false);
+
+ $this->writeText('Usage:', $options);
+ foreach (array_merge(array($command->getSynopsis(true)), $command->getAliases(), $command->getUsages()) as $usage) {
+ $this->writeText("\n");
+ $this->writeText(' '.$usage, $options);
+ }
+ $this->writeText("\n");
+
+ $definition = $command->getNativeDefinition();
+ if ($definition->getOptions() || $definition->getArguments()) {
+ $this->writeText("\n");
+ $this->describeInputDefinition($definition, $options);
+ $this->writeText("\n");
+ }
+
+ if ($help = $command->getProcessedHelp()) {
+ $this->writeText("\n");
+ $this->writeText('Help:', $options);
+ $this->writeText("\n");
+ $this->writeText(' '.str_replace("\n", "\n ", $help), $options);
+ $this->writeText("\n");
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;
+ $description = new ApplicationDescription($application, $describedNamespace);
+
+ if (isset($options['raw_text']) && $options['raw_text']) {
+ $width = $this->getColumnWidth($description->getCommands());
+
+ foreach ($description->getCommands() as $command) {
+ $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
+ $this->writeText("\n");
+ }
+ } else {
+ if ('' != $help = $application->getHelp()) {
+ $this->writeText("$help\n\n", $options);
+ }
+
+ $this->writeText("Usage:\n", $options);
+ $this->writeText(" command [options] [arguments]\n\n", $options);
+
+ $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);
+
+ $this->writeText("\n");
+ $this->writeText("\n");
+
+ $width = $this->getColumnWidth($description->getCommands());
+
+ if ($describedNamespace) {
+ $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options);
+ } else {
+ $this->writeText('Available commands:', $options);
+ }
+
+ // add commands by namespace
+ foreach ($description->getNamespaces() as $namespace) {
+ if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
+ $this->writeText("\n");
+ $this->writeText(' '.$namespace['id'].'', $options);
+ }
+
+ foreach ($namespace['commands'] as $name) {
+ $this->writeText("\n");
+ $spacingWidth = $width - strlen($name);
+ $this->writeText(sprintf(' %s%s%s', $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)->getDescription()), $options);
+ }
+ }
+
+ $this->writeText("\n");
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ private function writeText($content, array $options = array())
+ {
+ $this->write(
+ isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
+ isset($options['raw_output']) ? !$options['raw_output'] : true
+ );
+ }
+
+ /**
+ * Formats input option/argument default value.
+ *
+ * @param mixed $default
+ *
+ * @return string
+ */
+ private function formatDefaultValue($default)
+ {
+ return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
+ }
+
+ /**
+ * @param Command[] $commands
+ *
+ * @return int
+ */
+ private function getColumnWidth(array $commands)
+ {
+ $widths = array();
+
+ foreach ($commands as $command) {
+ $widths[] = strlen($command->getName());
+ foreach ($command->getAliases() as $alias) {
+ $widths[] = strlen($alias);
+ }
+ }
+
+ return max($widths) + 2;
+ }
+
+ /**
+ * @param InputOption[] $options
+ *
+ * @return int
+ */
+ private function calculateTotalWidthForOptions($options)
+ {
+ $totalWidth = 0;
+ foreach ($options as $option) {
+ // "-" + shortcut + ", --" + name
+ $nameLength = 1 + max(strlen($option->getShortcut()), 1) + 4 + strlen($option->getName());
+
+ if ($option->acceptValue()) {
+ $valueLength = 1 + strlen($option->getName()); // = + value
+ $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ]
+
+ $nameLength += $valueLength;
+ }
+ $totalWidth = max($totalWidth, $nameLength);
+ }
+
+ return $totalWidth;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Descriptor/XmlDescriptor.php b/includes/src/vendor/symfony/console/Descriptor/XmlDescriptor.php
new file mode 100644
index 0000000..b5676be
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Descriptor/XmlDescriptor.php
@@ -0,0 +1,263 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+
+/**
+ * XML descriptor.
+ *
+ * @author Jean-François Simon
+ *
+ * @internal
+ */
+class XmlDescriptor extends Descriptor
+{
+ /**
+ * @param InputDefinition $definition
+ *
+ * @return \DOMDocument
+ */
+ public function getInputDefinitionDocument(InputDefinition $definition)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($definitionXML = $dom->createElement('definition'));
+
+ $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
+ foreach ($definition->getArguments() as $argument) {
+ $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
+ }
+
+ $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
+ foreach ($definition->getOptions() as $option) {
+ $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
+ }
+
+ return $dom;
+ }
+
+ /**
+ * @param Command $command
+ *
+ * @return \DOMDocument
+ */
+ public function getCommandDocument(Command $command)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($commandXML = $dom->createElement('command'));
+
+ $command->getSynopsis();
+ $command->mergeApplicationDefinition(false);
+
+ $commandXML->setAttribute('id', $command->getName());
+ $commandXML->setAttribute('name', $command->getName());
+
+ $commandXML->appendChild($usagesXML = $dom->createElement('usages'));
+
+ foreach (array_merge(array($command->getSynopsis()), $command->getAliases(), $command->getUsages()) as $usage) {
+ $usagesXML->appendChild($dom->createElement('usage', $usage));
+ }
+
+ $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription())));
+
+ $commandXML->appendChild($helpXML = $dom->createElement('help'));
+ $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp())));
+
+ $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition());
+ $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
+
+ return $dom;
+ }
+
+ /**
+ * @param Application $application
+ * @param string|null $namespace
+ *
+ * @return \DOMDocument
+ */
+ public function getApplicationDocument(Application $application, $namespace = null)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+ $dom->appendChild($rootXml = $dom->createElement('symfony'));
+
+ if ($application->getName() !== 'UNKNOWN') {
+ $rootXml->setAttribute('name', $application->getName());
+ if ($application->getVersion() !== 'UNKNOWN') {
+ $rootXml->setAttribute('version', $application->getVersion());
+ }
+ }
+
+ $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
+
+ $description = new ApplicationDescription($application, $namespace);
+
+ if ($namespace) {
+ $commandsXML->setAttribute('namespace', $namespace);
+ }
+
+ foreach ($description->getCommands() as $command) {
+ $this->appendDocument($commandsXML, $this->getCommandDocument($command));
+ }
+
+ if (!$namespace) {
+ $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
+
+ foreach ($description->getNamespaces() as $namespaceDescription) {
+ $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
+ $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);
+
+ foreach ($namespaceDescription['commands'] as $name) {
+ $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
+ $commandXML->appendChild($dom->createTextNode($name));
+ }
+ }
+ }
+
+ return $dom;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputArgument(InputArgument $argument, array $options = array())
+ {
+ $this->writeDocument($this->getInputArgumentDocument($argument));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputOption(InputOption $option, array $options = array())
+ {
+ $this->writeDocument($this->getInputOptionDocument($option));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeInputDefinition(InputDefinition $definition, array $options = array())
+ {
+ $this->writeDocument($this->getInputDefinitionDocument($definition));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeCommand(Command $command, array $options = array())
+ {
+ $this->writeDocument($this->getCommandDocument($command));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function describeApplication(Application $application, array $options = array())
+ {
+ $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null));
+ }
+
+ /**
+ * Appends document children to parent node.
+ *
+ * @param \DOMNode $parentNode
+ * @param \DOMNode $importedParent
+ */
+ private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
+ {
+ foreach ($importedParent->childNodes as $childNode) {
+ $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true));
+ }
+ }
+
+ /**
+ * Writes DOM document.
+ *
+ * @param \DOMDocument $dom
+ *
+ * @return \DOMDocument|string
+ */
+ private function writeDocument(\DOMDocument $dom)
+ {
+ $dom->formatOutput = true;
+ $this->write($dom->saveXML());
+ }
+
+ /**
+ * @param InputArgument $argument
+ *
+ * @return \DOMDocument
+ */
+ private function getInputArgumentDocument(InputArgument $argument)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+
+ $dom->appendChild($objectXML = $dom->createElement('argument'));
+ $objectXML->setAttribute('name', $argument->getName());
+ $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
+ $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
+
+ $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+ $defaults = is_array($argument->getDefault()) ? $argument->getDefault() : (is_bool($argument->getDefault()) ? array(var_export($argument->getDefault(), true)) : ($argument->getDefault() ? array($argument->getDefault()) : array()));
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+
+ return $dom;
+ }
+
+ /**
+ * @param InputOption $option
+ *
+ * @return \DOMDocument
+ */
+ private function getInputOptionDocument(InputOption $option)
+ {
+ $dom = new \DOMDocument('1.0', 'UTF-8');
+
+ $dom->appendChild($objectXML = $dom->createElement('option'));
+ $objectXML->setAttribute('name', '--'.$option->getName());
+ $pos = strpos($option->getShortcut(), '|');
+ if (false !== $pos) {
+ $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos));
+ $objectXML->setAttribute('shortcuts', '-'.implode('|-', explode('|', $option->getShortcut())));
+ } else {
+ $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : '');
+ }
+ $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
+ $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
+ $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
+ $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
+ $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
+
+ if ($option->acceptValue()) {
+ $defaults = is_array($option->getDefault()) ? $option->getDefault() : (is_bool($option->getDefault()) ? array(var_export($option->getDefault(), true)) : ($option->getDefault() ? array($option->getDefault()) : array()));
+ $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
+
+ if (!empty($defaults)) {
+ foreach ($defaults as $default) {
+ $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
+ $defaultXML->appendChild($dom->createTextNode($default));
+ }
+ }
+ }
+
+ return $dom;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Event/ConsoleCommandEvent.php b/includes/src/vendor/symfony/console/Event/ConsoleCommandEvent.php
new file mode 100644
index 0000000..92adf1e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Event/ConsoleCommandEvent.php
@@ -0,0 +1,62 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+/**
+ * Allows to do things before the command is executed, like skipping the command or changing the input.
+ *
+ * @author Fabien Potencier
+ */
+class ConsoleCommandEvent extends ConsoleEvent
+{
+ /**
+ * The return code for skipped commands, this will also be passed into the terminate event.
+ */
+ const RETURN_CODE_DISABLED = 113;
+
+ /**
+ * Indicates if the command should be run or skipped.
+ *
+ * @var bool
+ */
+ private $commandShouldRun = true;
+
+ /**
+ * Disables the command, so it won't be run.
+ *
+ * @return bool
+ */
+ public function disableCommand()
+ {
+ return $this->commandShouldRun = false;
+ }
+
+ /**
+ * Enables the command.
+ *
+ * @return bool
+ */
+ public function enableCommand()
+ {
+ return $this->commandShouldRun = true;
+ }
+
+ /**
+ * Returns true if the command is runnable, false otherwise.
+ *
+ * @return bool
+ */
+ public function commandShouldRun()
+ {
+ return $this->commandShouldRun;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Event/ConsoleEvent.php b/includes/src/vendor/symfony/console/Event/ConsoleEvent.php
new file mode 100644
index 0000000..ab620c4
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Event/ConsoleEvent.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Allows to inspect input and output of a command.
+ *
+ * @author Francesco Levorato
+ */
+class ConsoleEvent extends Event
+{
+ protected $command;
+
+ private $input;
+ private $output;
+
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output)
+ {
+ $this->command = $command;
+ $this->input = $input;
+ $this->output = $output;
+ }
+
+ /**
+ * Gets the command that is executed.
+ *
+ * @return Command A Command instance
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ /**
+ * Gets the input instance.
+ *
+ * @return InputInterface An InputInterface instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance.
+ *
+ * @return OutputInterface An OutputInterface instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Event/ConsoleExceptionEvent.php b/includes/src/vendor/symfony/console/Event/ConsoleExceptionEvent.php
new file mode 100644
index 0000000..603b7ee
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Event/ConsoleExceptionEvent.php
@@ -0,0 +1,67 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Allows to handle exception thrown in a command.
+ *
+ * @author Fabien Potencier
+ */
+class ConsoleExceptionEvent extends ConsoleEvent
+{
+ private $exception;
+ private $exitCode;
+
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, \Exception $exception, $exitCode)
+ {
+ parent::__construct($command, $input, $output);
+
+ $this->setException($exception);
+ $this->exitCode = (int) $exitCode;
+ }
+
+ /**
+ * Returns the thrown exception.
+ *
+ * @return \Exception The thrown exception
+ */
+ public function getException()
+ {
+ return $this->exception;
+ }
+
+ /**
+ * Replaces the thrown exception.
+ *
+ * This exception will be thrown if no response is set in the event.
+ *
+ * @param \Exception $exception The thrown exception
+ */
+ public function setException(\Exception $exception)
+ {
+ $this->exception = $exception;
+ }
+
+ /**
+ * Gets the exit code.
+ *
+ * @return int The command exit code
+ */
+ public function getExitCode()
+ {
+ return $this->exitCode;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Event/ConsoleTerminateEvent.php b/includes/src/vendor/symfony/console/Event/ConsoleTerminateEvent.php
new file mode 100644
index 0000000..b6a5d7c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Event/ConsoleTerminateEvent.php
@@ -0,0 +1,58 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Event;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Allows to manipulate the exit code of a command after its execution.
+ *
+ * @author Francesco Levorato
+ */
+class ConsoleTerminateEvent extends ConsoleEvent
+{
+ /**
+ * The exit code of the command.
+ *
+ * @var int
+ */
+ private $exitCode;
+
+ public function __construct(Command $command, InputInterface $input, OutputInterface $output, $exitCode)
+ {
+ parent::__construct($command, $input, $output);
+
+ $this->setExitCode($exitCode);
+ }
+
+ /**
+ * Sets the exit code.
+ *
+ * @param int $exitCode The command exit code
+ */
+ public function setExitCode($exitCode)
+ {
+ $this->exitCode = (int) $exitCode;
+ }
+
+ /**
+ * Gets the exit code.
+ *
+ * @return int The command exit code
+ */
+ public function getExitCode()
+ {
+ return $this->exitCode;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Exception/CommandNotFoundException.php b/includes/src/vendor/symfony/console/Exception/CommandNotFoundException.php
new file mode 100644
index 0000000..54f1a5b
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Exception/CommandNotFoundException.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Exception;
+
+/**
+ * Represents an incorrect command name typed in the console.
+ *
+ * @author Jérôme Tamarelle
+ */
+class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
+{
+ private $alternatives;
+
+ /**
+ * @param string $message Exception message to throw
+ * @param array $alternatives List of similar defined names
+ * @param int $code Exception code
+ * @param Exception $previous previous exception used for the exception chaining
+ */
+ public function __construct($message, array $alternatives = array(), $code = 0, \Exception $previous = null)
+ {
+ parent::__construct($message, $code, $previous);
+
+ $this->alternatives = $alternatives;
+ }
+
+ /**
+ * @return array A list of similar defined names
+ */
+ public function getAlternatives()
+ {
+ return $this->alternatives;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Exception/ExceptionInterface.php b/includes/src/vendor/symfony/console/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..491cc4c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Exception/ExceptionInterface.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Exception;
+
+/**
+ * ExceptionInterface.
+ *
+ * @author Jérôme Tamarelle
+ */
+interface ExceptionInterface
+{
+}
diff --git a/includes/src/vendor/symfony/console/Exception/InvalidArgumentException.php b/includes/src/vendor/symfony/console/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000..07cc0b6
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Exception/InvalidArgumentException.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Exception;
+
+/**
+ * @author Jérôme Tamarelle
+ */
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/includes/src/vendor/symfony/console/Exception/InvalidOptionException.php b/includes/src/vendor/symfony/console/Exception/InvalidOptionException.php
new file mode 100644
index 0000000..b2eec61
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Exception/InvalidOptionException.php
@@ -0,0 +1,21 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Exception;
+
+/**
+ * Represents an incorrect option name typed in the console.
+ *
+ * @author Jérôme Tamarelle
+ */
+class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/includes/src/vendor/symfony/console/Exception/LogicException.php b/includes/src/vendor/symfony/console/Exception/LogicException.php
new file mode 100644
index 0000000..fc37b8d
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Exception/LogicException.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Exception;
+
+/**
+ * @author Jérôme Tamarelle
+ */
+class LogicException extends \LogicException implements ExceptionInterface
+{
+}
diff --git a/includes/src/vendor/symfony/console/Exception/RuntimeException.php b/includes/src/vendor/symfony/console/Exception/RuntimeException.php
new file mode 100644
index 0000000..51d7d80
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Exception/RuntimeException.php
@@ -0,0 +1,19 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Exception;
+
+/**
+ * @author Jérôme Tamarelle
+ */
+class RuntimeException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/includes/src/vendor/symfony/console/Formatter/OutputFormatter.php b/includes/src/vendor/symfony/console/Formatter/OutputFormatter.php
new file mode 100644
index 0000000..56cd5e5
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Formatter/OutputFormatter.php
@@ -0,0 +1,240 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * Formatter class for console output.
+ *
+ * @author Konstantin Kudryashov
+ */
+class OutputFormatter implements OutputFormatterInterface
+{
+ private $decorated;
+ private $styles = array();
+ private $styleStack;
+
+ /**
+ * Escapes "<" special char in given text.
+ *
+ * @param string $text Text to escape
+ *
+ * @return string Escaped text
+ */
+ public static function escape($text)
+ {
+ $text = preg_replace('/([^\\\\]?)', '$1\\<', $text);
+
+ if ('\\' === substr($text, -1)) {
+ $len = strlen($text);
+ $text = rtrim($text, '\\');
+ $text .= str_repeat('<<', $len - strlen($text));
+ }
+
+ return $text;
+ }
+
+ /**
+ * Initializes console output formatter.
+ *
+ * @param bool $decorated Whether this formatter should actually decorate strings
+ * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
+ */
+ public function __construct($decorated = false, array $styles = array())
+ {
+ $this->decorated = (bool) $decorated;
+
+ $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
+ $this->setStyle('info', new OutputFormatterStyle('green'));
+ $this->setStyle('comment', new OutputFormatterStyle('yellow'));
+ $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
+
+ foreach ($styles as $name => $style) {
+ $this->setStyle($name, $style);
+ }
+
+ $this->styleStack = new OutputFormatterStyleStack();
+ }
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param bool $decorated Whether to decorate the messages or not
+ */
+ public function setDecorated($decorated)
+ {
+ $this->decorated = (bool) $decorated;
+ }
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return bool true if the output will decorate messages, false otherwise
+ */
+ public function isDecorated()
+ {
+ return $this->decorated;
+ }
+
+ /**
+ * Sets a new style.
+ *
+ * @param string $name The style name
+ * @param OutputFormatterStyleInterface $style The style instance
+ */
+ public function setStyle($name, OutputFormatterStyleInterface $style)
+ {
+ $this->styles[strtolower($name)] = $style;
+ }
+
+ /**
+ * Checks if output formatter has style with specified name.
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function hasStyle($name)
+ {
+ return isset($this->styles[strtolower($name)]);
+ }
+
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @param string $name
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @throws InvalidArgumentException When style isn't defined
+ */
+ public function getStyle($name)
+ {
+ if (!$this->hasStyle($name)) {
+ throw new InvalidArgumentException(sprintf('Undefined style: %s', $name));
+ }
+
+ return $this->styles[strtolower($name)];
+ }
+
+ /**
+ * Formats a message according to the given styles.
+ *
+ * @param string $message The message to style
+ *
+ * @return string The styled message
+ */
+ public function format($message)
+ {
+ $message = (string) $message;
+ $offset = 0;
+ $output = '';
+ $tagRegex = '[a-z][a-z0-9_=;-]*+';
+ preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
+ foreach ($matches[0] as $i => $match) {
+ $pos = $match[1];
+ $text = $match[0];
+
+ if (0 != $pos && '\\' == $message[$pos - 1]) {
+ continue;
+ }
+
+ // add the text up to the next tag
+ $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
+ $offset = $pos + strlen($text);
+
+ // opening tag?
+ if ($open = '/' != $text[1]) {
+ $tag = $matches[1][$i][0];
+ } else {
+ $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';
+ }
+
+ if (!$open && !$tag) {
+ // >
+ $this->styleStack->pop();
+ } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
+ $output .= $this->applyCurrentStyle($text);
+ } elseif ($open) {
+ $this->styleStack->push($style);
+ } else {
+ $this->styleStack->pop($style);
+ }
+ }
+
+ $output .= $this->applyCurrentStyle(substr($message, $offset));
+
+ if (false !== strpos($output, '<<')) {
+ return strtr($output, array('\\<' => '<', '<<' => '\\'));
+ }
+
+ return str_replace('\\<', '<', $output);
+ }
+
+ /**
+ * @return OutputFormatterStyleStack
+ */
+ public function getStyleStack()
+ {
+ return $this->styleStack;
+ }
+
+ /**
+ * Tries to create new style instance from string.
+ *
+ * @param string $string
+ *
+ * @return OutputFormatterStyle|bool false if string is not format string
+ */
+ private function createStyleFromString($string)
+ {
+ if (isset($this->styles[$string])) {
+ return $this->styles[$string];
+ }
+
+ if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {
+ return false;
+ }
+
+ $style = new OutputFormatterStyle();
+ foreach ($matches as $match) {
+ array_shift($match);
+
+ if ('fg' == $match[0]) {
+ $style->setForeground($match[1]);
+ } elseif ('bg' == $match[0]) {
+ $style->setBackground($match[1]);
+ } else {
+ try {
+ $style->setOption($match[1]);
+ } catch (\InvalidArgumentException $e) {
+ return false;
+ }
+ }
+ }
+
+ return $style;
+ }
+
+ /**
+ * Applies current style from stack to text, if must be applied.
+ *
+ * @param string $text Input text
+ *
+ * @return string Styled text
+ */
+ private function applyCurrentStyle($text)
+ {
+ return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/includes/src/vendor/symfony/console/Formatter/OutputFormatterInterface.php
new file mode 100644
index 0000000..5a52ba0
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Formatter/OutputFormatterInterface.php
@@ -0,0 +1,69 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter interface for console output.
+ *
+ * @author Konstantin Kudryashov
+ */
+interface OutputFormatterInterface
+{
+ /**
+ * Sets the decorated flag.
+ *
+ * @param bool $decorated Whether to decorate the messages or not
+ */
+ public function setDecorated($decorated);
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return bool true if the output will decorate messages, false otherwise
+ */
+ public function isDecorated();
+
+ /**
+ * Sets a new style.
+ *
+ * @param string $name The style name
+ * @param OutputFormatterStyleInterface $style The style instance
+ */
+ public function setStyle($name, OutputFormatterStyleInterface $style);
+
+ /**
+ * Checks if output formatter has style with specified name.
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+ public function hasStyle($name);
+
+ /**
+ * Gets style options from style with specified name.
+ *
+ * @param string $name
+ *
+ * @return OutputFormatterStyleInterface
+ */
+ public function getStyle($name);
+
+ /**
+ * Formats a message according to the given styles.
+ *
+ * @param string $message The message to style
+ *
+ * @return string The styled message
+ */
+ public function format($message);
+}
diff --git a/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyle.php
new file mode 100644
index 0000000..c7c6b4a
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyle.php
@@ -0,0 +1,221 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * Formatter style class for defining styles.
+ *
+ * @author Konstantin Kudryashov
+ */
+class OutputFormatterStyle implements OutputFormatterStyleInterface
+{
+ private static $availableForegroundColors = array(
+ 'black' => array('set' => 30, 'unset' => 39),
+ 'red' => array('set' => 31, 'unset' => 39),
+ 'green' => array('set' => 32, 'unset' => 39),
+ 'yellow' => array('set' => 33, 'unset' => 39),
+ 'blue' => array('set' => 34, 'unset' => 39),
+ 'magenta' => array('set' => 35, 'unset' => 39),
+ 'cyan' => array('set' => 36, 'unset' => 39),
+ 'white' => array('set' => 37, 'unset' => 39),
+ 'default' => array('set' => 39, 'unset' => 39),
+ );
+ private static $availableBackgroundColors = array(
+ 'black' => array('set' => 40, 'unset' => 49),
+ 'red' => array('set' => 41, 'unset' => 49),
+ 'green' => array('set' => 42, 'unset' => 49),
+ 'yellow' => array('set' => 43, 'unset' => 49),
+ 'blue' => array('set' => 44, 'unset' => 49),
+ 'magenta' => array('set' => 45, 'unset' => 49),
+ 'cyan' => array('set' => 46, 'unset' => 49),
+ 'white' => array('set' => 47, 'unset' => 49),
+ 'default' => array('set' => 49, 'unset' => 49),
+ );
+ private static $availableOptions = array(
+ 'bold' => array('set' => 1, 'unset' => 22),
+ 'underscore' => array('set' => 4, 'unset' => 24),
+ 'blink' => array('set' => 5, 'unset' => 25),
+ 'reverse' => array('set' => 7, 'unset' => 27),
+ 'conceal' => array('set' => 8, 'unset' => 28),
+ );
+
+ private $foreground;
+ private $background;
+ private $options = array();
+
+ /**
+ * Initializes output formatter style.
+ *
+ * @param string|null $foreground The style foreground color name
+ * @param string|null $background The style background color name
+ * @param array $options The style options
+ */
+ public function __construct($foreground = null, $background = null, array $options = array())
+ {
+ if (null !== $foreground) {
+ $this->setForeground($foreground);
+ }
+ if (null !== $background) {
+ $this->setBackground($background);
+ }
+ if (count($options)) {
+ $this->setOptions($options);
+ }
+ }
+
+ /**
+ * Sets style foreground color.
+ *
+ * @param string|null $color The color name
+ *
+ * @throws InvalidArgumentException When the color name isn't defined
+ */
+ public function setForeground($color = null)
+ {
+ if (null === $color) {
+ $this->foreground = null;
+
+ return;
+ }
+
+ if (!isset(static::$availableForegroundColors[$color])) {
+ throw new InvalidArgumentException(sprintf(
+ 'Invalid foreground color specified: "%s". Expected one of (%s)',
+ $color,
+ implode(', ', array_keys(static::$availableForegroundColors))
+ ));
+ }
+
+ $this->foreground = static::$availableForegroundColors[$color];
+ }
+
+ /**
+ * Sets style background color.
+ *
+ * @param string|null $color The color name
+ *
+ * @throws InvalidArgumentException When the color name isn't defined
+ */
+ public function setBackground($color = null)
+ {
+ if (null === $color) {
+ $this->background = null;
+
+ return;
+ }
+
+ if (!isset(static::$availableBackgroundColors[$color])) {
+ throw new InvalidArgumentException(sprintf(
+ 'Invalid background color specified: "%s". Expected one of (%s)',
+ $color,
+ implode(', ', array_keys(static::$availableBackgroundColors))
+ ));
+ }
+
+ $this->background = static::$availableBackgroundColors[$color];
+ }
+
+ /**
+ * Sets some specific style option.
+ *
+ * @param string $option The option name
+ *
+ * @throws InvalidArgumentException When the option name isn't defined
+ */
+ public function setOption($option)
+ {
+ if (!isset(static::$availableOptions[$option])) {
+ throw new InvalidArgumentException(sprintf(
+ 'Invalid option specified: "%s". Expected one of (%s)',
+ $option,
+ implode(', ', array_keys(static::$availableOptions))
+ ));
+ }
+
+ if (!in_array(static::$availableOptions[$option], $this->options)) {
+ $this->options[] = static::$availableOptions[$option];
+ }
+ }
+
+ /**
+ * Unsets some specific style option.
+ *
+ * @param string $option The option name
+ *
+ * @throws InvalidArgumentException When the option name isn't defined
+ */
+ public function unsetOption($option)
+ {
+ if (!isset(static::$availableOptions[$option])) {
+ throw new InvalidArgumentException(sprintf(
+ 'Invalid option specified: "%s". Expected one of (%s)',
+ $option,
+ implode(', ', array_keys(static::$availableOptions))
+ ));
+ }
+
+ $pos = array_search(static::$availableOptions[$option], $this->options);
+ if (false !== $pos) {
+ unset($this->options[$pos]);
+ }
+ }
+
+ /**
+ * Sets multiple style options at once.
+ *
+ * @param array $options
+ */
+ public function setOptions(array $options)
+ {
+ $this->options = array();
+
+ foreach ($options as $option) {
+ $this->setOption($option);
+ }
+ }
+
+ /**
+ * Applies the style to a given text.
+ *
+ * @param string $text The text to style
+ *
+ * @return string
+ */
+ public function apply($text)
+ {
+ $setCodes = array();
+ $unsetCodes = array();
+
+ if (null !== $this->foreground) {
+ $setCodes[] = $this->foreground['set'];
+ $unsetCodes[] = $this->foreground['unset'];
+ }
+ if (null !== $this->background) {
+ $setCodes[] = $this->background['set'];
+ $unsetCodes[] = $this->background['unset'];
+ }
+ if (count($this->options)) {
+ foreach ($this->options as $option) {
+ $setCodes[] = $option['set'];
+ $unsetCodes[] = $option['unset'];
+ }
+ }
+
+ if (0 === count($setCodes)) {
+ return $text;
+ }
+
+ return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
new file mode 100644
index 0000000..c36fda8
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+/**
+ * Formatter style interface for defining styles.
+ *
+ * @author Konstantin Kudryashov
+ */
+interface OutputFormatterStyleInterface
+{
+ /**
+ * Sets style foreground color.
+ *
+ * @param string $color The color name
+ */
+ public function setForeground($color = null);
+
+ /**
+ * Sets style background color.
+ *
+ * @param string $color The color name
+ */
+ public function setBackground($color = null);
+
+ /**
+ * Sets some specific style option.
+ *
+ * @param string $option The option name
+ */
+ public function setOption($option);
+
+ /**
+ * Unsets some specific style option.
+ *
+ * @param string $option The option name
+ */
+ public function unsetOption($option);
+
+ /**
+ * Sets multiple style options at once.
+ *
+ * @param array $options
+ */
+ public function setOptions(array $options);
+
+ /**
+ * Applies the style to a given text.
+ *
+ * @param string $text The text to style
+ *
+ * @return string
+ */
+ public function apply($text);
+}
diff --git a/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
new file mode 100644
index 0000000..e5d14ea
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php
@@ -0,0 +1,123 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Formatter;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * @author Jean-François Simon
+ */
+class OutputFormatterStyleStack
+{
+ /**
+ * @var OutputFormatterStyleInterface[]
+ */
+ private $styles;
+
+ /**
+ * @var OutputFormatterStyleInterface
+ */
+ private $emptyStyle;
+
+ /**
+ * Constructor.
+ *
+ * @param OutputFormatterStyleInterface|null $emptyStyle
+ */
+ public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
+ {
+ $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle();
+ $this->reset();
+ }
+
+ /**
+ * Resets stack (ie. empty internal arrays).
+ */
+ public function reset()
+ {
+ $this->styles = array();
+ }
+
+ /**
+ * Pushes a style in the stack.
+ *
+ * @param OutputFormatterStyleInterface $style
+ */
+ public function push(OutputFormatterStyleInterface $style)
+ {
+ $this->styles[] = $style;
+ }
+
+ /**
+ * Pops a style from the stack.
+ *
+ * @param OutputFormatterStyleInterface|null $style
+ *
+ * @return OutputFormatterStyleInterface
+ *
+ * @throws InvalidArgumentException When style tags incorrectly nested
+ */
+ public function pop(OutputFormatterStyleInterface $style = null)
+ {
+ if (empty($this->styles)) {
+ return $this->emptyStyle;
+ }
+
+ if (null === $style) {
+ return array_pop($this->styles);
+ }
+
+ foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {
+ if ($style->apply('') === $stackedStyle->apply('')) {
+ $this->styles = array_slice($this->styles, 0, $index);
+
+ return $stackedStyle;
+ }
+ }
+
+ throw new InvalidArgumentException('Incorrectly nested style tag found.');
+ }
+
+ /**
+ * Computes current style with stacks top codes.
+ *
+ * @return OutputFormatterStyle
+ */
+ public function getCurrent()
+ {
+ if (empty($this->styles)) {
+ return $this->emptyStyle;
+ }
+
+ return $this->styles[count($this->styles) - 1];
+ }
+
+ /**
+ * @param OutputFormatterStyleInterface $emptyStyle
+ *
+ * @return OutputFormatterStyleStack
+ */
+ public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
+ {
+ $this->emptyStyle = $emptyStyle;
+
+ return $this;
+ }
+
+ /**
+ * @return OutputFormatterStyleInterface
+ */
+ public function getEmptyStyle()
+ {
+ return $this->emptyStyle;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/DebugFormatterHelper.php b/includes/src/vendor/symfony/console/Helper/DebugFormatterHelper.php
new file mode 100644
index 0000000..1119b79
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/DebugFormatterHelper.php
@@ -0,0 +1,127 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Helps outputting debug information when running an external program from a command.
+ *
+ * An external program can be a Process, an HTTP request, or anything else.
+ *
+ * @author Fabien Potencier
+ */
+class DebugFormatterHelper extends Helper
+{
+ private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default');
+ private $started = array();
+ private $count = -1;
+
+ /**
+ * Starts a debug formatting session.
+ *
+ * @param string $id The id of the formatting session
+ * @param string $message The message to display
+ * @param string $prefix The prefix to use
+ *
+ * @return string
+ */
+ public function start($id, $message, $prefix = 'RUN')
+ {
+ $this->started[$id] = array('border' => ++$this->count % count($this->colors));
+
+ return sprintf("%s %s > %s>\n", $this->getBorder($id), $prefix, $message);
+ }
+
+ /**
+ * Adds progress to a formatting session.
+ *
+ * @param string $id The id of the formatting session
+ * @param string $buffer The message to display
+ * @param bool $error Whether to consider the buffer as error
+ * @param string $prefix The prefix for output
+ * @param string $errorPrefix The prefix for error output
+ *
+ * @return string
+ */
+ public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR')
+ {
+ $message = '';
+
+ if ($error) {
+ if (isset($this->started[$id]['out'])) {
+ $message .= "\n";
+ unset($this->started[$id]['out']);
+ }
+ if (!isset($this->started[$id]['err'])) {
+ $message .= sprintf('%s %s > ', $this->getBorder($id), $errorPrefix);
+ $this->started[$id]['err'] = true;
+ }
+
+ $message .= str_replace("\n", sprintf("\n%s %s > ", $this->getBorder($id), $errorPrefix), $buffer);
+ } else {
+ if (isset($this->started[$id]['err'])) {
+ $message .= "\n";
+ unset($this->started[$id]['err']);
+ }
+ if (!isset($this->started[$id]['out'])) {
+ $message .= sprintf('%s %s > ', $this->getBorder($id), $prefix);
+ $this->started[$id]['out'] = true;
+ }
+
+ $message .= str_replace("\n", sprintf("\n%s %s > ", $this->getBorder($id), $prefix), $buffer);
+ }
+
+ return $message;
+ }
+
+ /**
+ * Stops a formatting session.
+ *
+ * @param string $id The id of the formatting session
+ * @param string $message The message to display
+ * @param bool $successful Whether to consider the result as success
+ * @param string $prefix The prefix for the end output
+ *
+ * @return string
+ */
+ public function stop($id, $message, $successful, $prefix = 'RES')
+ {
+ $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
+
+ if ($successful) {
+ return sprintf("%s%s %s > %s>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
+ }
+
+ $message = sprintf("%s%s %s > %s>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
+
+ unset($this->started[$id]['out'], $this->started[$id]['err']);
+
+ return $message;
+ }
+
+ /**
+ * @param string $id The id of the formatting session
+ *
+ * @return string
+ */
+ private function getBorder($id)
+ {
+ return sprintf(' >', $this->colors[$this->started[$id]['border']]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'debug_formatter';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/DescriptorHelper.php b/includes/src/vendor/symfony/console/Helper/DescriptorHelper.php
new file mode 100644
index 0000000..a53b476
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/DescriptorHelper.php
@@ -0,0 +1,97 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Descriptor\DescriptorInterface;
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * This class adds helper method to describe objects in various formats.
+ *
+ * @author Jean-François Simon
+ */
+class DescriptorHelper extends Helper
+{
+ /**
+ * @var DescriptorInterface[]
+ */
+ private $descriptors = array();
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this
+ ->register('txt', new TextDescriptor())
+ ->register('xml', new XmlDescriptor())
+ ->register('json', new JsonDescriptor())
+ ->register('md', new MarkdownDescriptor())
+ ;
+ }
+
+ /**
+ * Describes an object if supported.
+ *
+ * Available options are:
+ * * format: string, the output format name
+ * * raw_text: boolean, sets output type as raw
+ *
+ * @param OutputInterface $output
+ * @param object $object
+ * @param array $options
+ *
+ * @throws InvalidArgumentException when the given format is not supported
+ */
+ public function describe(OutputInterface $output, $object, array $options = array())
+ {
+ $options = array_merge(array(
+ 'raw_text' => false,
+ 'format' => 'txt',
+ ), $options);
+
+ if (!isset($this->descriptors[$options['format']])) {
+ throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format']));
+ }
+
+ $descriptor = $this->descriptors[$options['format']];
+ $descriptor->describe($output, $object, $options);
+ }
+
+ /**
+ * Registers a descriptor.
+ *
+ * @param string $format
+ * @param DescriptorInterface $descriptor
+ *
+ * @return DescriptorHelper
+ */
+ public function register($format, DescriptorInterface $descriptor)
+ {
+ $this->descriptors[$format] = $descriptor;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'descriptor';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/FormatterHelper.php b/includes/src/vendor/symfony/console/Helper/FormatterHelper.php
new file mode 100644
index 0000000..6a48a77
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/FormatterHelper.php
@@ -0,0 +1,106 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * The Formatter class provides helpers to format messages.
+ *
+ * @author Fabien Potencier
+ */
+class FormatterHelper extends Helper
+{
+ /**
+ * Formats a message within a section.
+ *
+ * @param string $section The section name
+ * @param string $message The message
+ * @param string $style The style to apply to the section
+ *
+ * @return string The format section
+ */
+ public function formatSection($section, $message, $style = 'info')
+ {
+ return sprintf('<%s>[%s]%s> %s', $style, $section, $style, $message);
+ }
+
+ /**
+ * Formats a message as a block of text.
+ *
+ * @param string|array $messages The message to write in the block
+ * @param string $style The style to apply to the whole block
+ * @param bool $large Whether to return a large block
+ *
+ * @return string The formatter message
+ */
+ public function formatBlock($messages, $style, $large = false)
+ {
+ if (!is_array($messages)) {
+ $messages = array($messages);
+ }
+
+ $len = 0;
+ $lines = array();
+ foreach ($messages as $message) {
+ $message = OutputFormatter::escape($message);
+ $lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
+ $len = max($this->strlen($message) + ($large ? 4 : 2), $len);
+ }
+
+ $messages = $large ? array(str_repeat(' ', $len)) : array();
+ for ($i = 0; isset($lines[$i]); ++$i) {
+ $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
+ }
+ if ($large) {
+ $messages[] = str_repeat(' ', $len);
+ }
+
+ for ($i = 0; isset($messages[$i]); ++$i) {
+ $messages[$i] = sprintf('<%s>%s%s>', $style, $messages[$i], $style);
+ }
+
+ return implode("\n", $messages);
+ }
+
+ /**
+ * Truncates a message to the given length.
+ *
+ * @param string $message
+ * @param int $length
+ * @param string $suffix
+ *
+ * @return string
+ */
+ public function truncate($message, $length, $suffix = '...')
+ {
+ $computedLength = $length - $this->strlen($suffix);
+
+ if ($computedLength > $this->strlen($message)) {
+ return $message;
+ }
+
+ if (false === $encoding = mb_detect_encoding($message, null, true)) {
+ return substr($message, 0, $length).$suffix;
+ }
+
+ return mb_substr($message, 0, $length, $encoding).$suffix;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'formatter';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/Helper.php b/includes/src/vendor/symfony/console/Helper/Helper.php
new file mode 100644
index 0000000..43f9a16
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/Helper.php
@@ -0,0 +1,119 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * Helper is the base class for all helper classes.
+ *
+ * @author Fabien Potencier
+ */
+abstract class Helper implements HelperInterface
+{
+ protected $helperSet = null;
+
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet = null)
+ {
+ $this->helperSet = $helperSet;
+ }
+
+ /**
+ * Gets the helper set associated with this helper.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet()
+ {
+ return $this->helperSet;
+ }
+
+ /**
+ * Returns the length of a string, using mb_strwidth if it is available.
+ *
+ * @param string $string The string to check its length
+ *
+ * @return int The length of the string
+ */
+ public static function strlen($string)
+ {
+ if (false === $encoding = mb_detect_encoding($string, null, true)) {
+ return strlen($string);
+ }
+
+ return mb_strwidth($string, $encoding);
+ }
+
+ public static function formatTime($secs)
+ {
+ static $timeFormats = array(
+ array(0, '< 1 sec'),
+ array(1, '1 sec'),
+ array(2, 'secs', 1),
+ array(60, '1 min'),
+ array(120, 'mins', 60),
+ array(3600, '1 hr'),
+ array(7200, 'hrs', 3600),
+ array(86400, '1 day'),
+ array(172800, 'days', 86400),
+ );
+
+ foreach ($timeFormats as $index => $format) {
+ if ($secs >= $format[0]) {
+ if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0])
+ || $index == count($timeFormats) - 1
+ ) {
+ if (2 == count($format)) {
+ return $format[1];
+ }
+
+ return floor($secs / $format[2]).' '.$format[1];
+ }
+ }
+ }
+ }
+
+ public static function formatMemory($memory)
+ {
+ if ($memory >= 1024 * 1024 * 1024) {
+ return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
+ }
+
+ if ($memory >= 1024 * 1024) {
+ return sprintf('%.1f MiB', $memory / 1024 / 1024);
+ }
+
+ if ($memory >= 1024) {
+ return sprintf('%d KiB', $memory / 1024);
+ }
+
+ return sprintf('%d B', $memory);
+ }
+
+ public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string)
+ {
+ $isDecorated = $formatter->isDecorated();
+ $formatter->setDecorated(false);
+ // remove <...> formatting
+ $string = $formatter->format($string);
+ // remove already formatted characters
+ $string = preg_replace("/\033\[[^m]*m/", '', $string);
+ $formatter->setDecorated($isDecorated);
+
+ return self::strlen($string);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/HelperInterface.php b/includes/src/vendor/symfony/console/Helper/HelperInterface.php
new file mode 100644
index 0000000..5a923e0
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/HelperInterface.php
@@ -0,0 +1,41 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * HelperInterface is the interface all helpers must implement.
+ *
+ * @author Fabien Potencier
+ */
+interface HelperInterface
+{
+ /**
+ * Sets the helper set associated with this helper.
+ *
+ * @param HelperSet $helperSet A HelperSet instance
+ */
+ public function setHelperSet(HelperSet $helperSet = null);
+
+ /**
+ * Gets the helper set associated with this helper.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ public function getHelperSet();
+
+ /**
+ * Returns the canonical name of this helper.
+ *
+ * @return string The canonical name
+ */
+ public function getName();
+}
diff --git a/includes/src/vendor/symfony/console/Helper/HelperSet.php b/includes/src/vendor/symfony/console/Helper/HelperSet.php
new file mode 100644
index 0000000..6f12b39
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/HelperSet.php
@@ -0,0 +1,115 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * HelperSet represents a set of helpers to be used with a command.
+ *
+ * @author Fabien Potencier
+ */
+class HelperSet implements \IteratorAggregate
+{
+ /**
+ * @var Helper[]
+ */
+ private $helpers = array();
+ private $command;
+
+ /**
+ * Constructor.
+ *
+ * @param Helper[] $helpers An array of helper
+ */
+ public function __construct(array $helpers = array())
+ {
+ foreach ($helpers as $alias => $helper) {
+ $this->set($helper, is_int($alias) ? null : $alias);
+ }
+ }
+
+ /**
+ * Sets a helper.
+ *
+ * @param HelperInterface $helper The helper instance
+ * @param string $alias An alias
+ */
+ public function set(HelperInterface $helper, $alias = null)
+ {
+ $this->helpers[$helper->getName()] = $helper;
+ if (null !== $alias) {
+ $this->helpers[$alias] = $helper;
+ }
+
+ $helper->setHelperSet($this);
+ }
+
+ /**
+ * Returns true if the helper if defined.
+ *
+ * @param string $name The helper name
+ *
+ * @return bool true if the helper is defined, false otherwise
+ */
+ public function has($name)
+ {
+ return isset($this->helpers[$name]);
+ }
+
+ /**
+ * Gets a helper value.
+ *
+ * @param string $name The helper name
+ *
+ * @return HelperInterface The helper instance
+ *
+ * @throws InvalidArgumentException if the helper is not defined
+ */
+ public function get($name)
+ {
+ if (!$this->has($name)) {
+ throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
+ }
+
+ return $this->helpers[$name];
+ }
+
+ /**
+ * Sets the command associated with this helper set.
+ *
+ * @param Command $command A Command instance
+ */
+ public function setCommand(Command $command = null)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Gets the command associated with this helper set.
+ *
+ * @return Command A Command instance
+ */
+ public function getCommand()
+ {
+ return $this->command;
+ }
+
+ /**
+ * @return Helper[]
+ */
+ public function getIterator()
+ {
+ return new \ArrayIterator($this->helpers);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/InputAwareHelper.php b/includes/src/vendor/symfony/console/Helper/InputAwareHelper.php
new file mode 100644
index 0000000..4261767
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/InputAwareHelper.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputAwareInterface;
+
+/**
+ * An implementation of InputAwareInterface for Helpers.
+ *
+ * @author Wouter J
+ */
+abstract class InputAwareHelper extends Helper implements InputAwareInterface
+{
+ protected $input;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setInput(InputInterface $input)
+ {
+ $this->input = $input;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/ProcessHelper.php b/includes/src/vendor/symfony/console/Helper/ProcessHelper.php
new file mode 100644
index 0000000..2c46a2c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/ProcessHelper.php
@@ -0,0 +1,144 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Process\Exception\ProcessFailedException;
+use Symfony\Component\Process\Process;
+use Symfony\Component\Process\ProcessBuilder;
+
+/**
+ * The ProcessHelper class provides helpers to run external processes.
+ *
+ * @author Fabien Potencier
+ */
+class ProcessHelper extends Helper
+{
+ /**
+ * Runs an external process.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param string|array|Process $cmd An instance of Process or an array of arguments to escape and run or a command to run
+ * @param string|null $error An error message that must be displayed if something went wrong
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ * @param int $verbosity The threshold for verbosity
+ *
+ * @return Process The process that ran
+ */
+ public function run(OutputInterface $output, $cmd, $error = null, callable $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+
+ $formatter = $this->getHelperSet()->get('debug_formatter');
+
+ if (is_array($cmd)) {
+ $process = ProcessBuilder::create($cmd)->getProcess();
+ } elseif ($cmd instanceof Process) {
+ $process = $cmd;
+ } else {
+ $process = new Process($cmd);
+ }
+
+ if ($verbosity <= $output->getVerbosity()) {
+ $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine())));
+ }
+
+ if ($output->isDebug()) {
+ $callback = $this->wrapCallback($output, $process, $callback);
+ }
+
+ $process->run($callback);
+
+ if ($verbosity <= $output->getVerbosity()) {
+ $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode());
+ $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
+ }
+
+ if (!$process->isSuccessful() && null !== $error) {
+ $output->writeln(sprintf('%s', $this->escapeString($error)));
+ }
+
+ return $process;
+ }
+
+ /**
+ * Runs the process.
+ *
+ * This is identical to run() except that an exception is thrown if the process
+ * exits with a non-zero exit code.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param string|Process $cmd An instance of Process or a command to run
+ * @param string|null $error An error message that must be displayed if something went wrong
+ * @param callable|null $callback A PHP callback to run whenever there is some
+ * output available on STDOUT or STDERR
+ *
+ * @return Process The process that ran
+ *
+ * @throws ProcessFailedException
+ *
+ * @see run()
+ */
+ public function mustRun(OutputInterface $output, $cmd, $error = null, callable $callback = null)
+ {
+ $process = $this->run($output, $cmd, $error, $callback);
+
+ if (!$process->isSuccessful()) {
+ throw new ProcessFailedException($process);
+ }
+
+ return $process;
+ }
+
+ /**
+ * Wraps a Process callback to add debugging output.
+ *
+ * @param OutputInterface $output An OutputInterface interface
+ * @param Process $process The Process
+ * @param callable|null $callback A PHP callable
+ *
+ * @return callable
+ */
+ public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+
+ $formatter = $this->getHelperSet()->get('debug_formatter');
+
+ return function ($type, $buffer) use ($output, $process, $callback, $formatter) {
+ $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));
+
+ if (null !== $callback) {
+ call_user_func($callback, $type, $buffer);
+ }
+ };
+ }
+
+ private function escapeString($str)
+ {
+ return str_replace('<', '\\<', $str);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'process';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/ProgressBar.php b/includes/src/vendor/symfony/console/Helper/ProgressBar.php
new file mode 100644
index 0000000..6aea12e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/ProgressBar.php
@@ -0,0 +1,600 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * The ProgressBar provides helpers to display progress output.
+ *
+ * @author Fabien Potencier
+ * @author Chris Jones
+ */
+class ProgressBar
+{
+ // options
+ private $barWidth = 28;
+ private $barChar;
+ private $emptyBarChar = '-';
+ private $progressChar = '>';
+ private $format;
+ private $internalFormat;
+ private $redrawFreq = 1;
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+ private $step = 0;
+ private $max;
+ private $startTime;
+ private $stepWidth;
+ private $percent = 0.0;
+ private $formatLineCount;
+ private $messages = array();
+ private $overwrite = true;
+ private $firstRun = true;
+
+ private static $formatters;
+ private static $formats;
+
+ /**
+ * Constructor.
+ *
+ * @param OutputInterface $output An OutputInterface instance
+ * @param int $max Maximum steps (0 if unknown)
+ */
+ public function __construct(OutputInterface $output, $max = 0)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+
+ $this->output = $output;
+ $this->setMaxSteps($max);
+
+ if (!$this->output->isDecorated()) {
+ // disable overwrite when output does not support ANSI codes.
+ $this->overwrite = false;
+
+ // set a reasonable redraw frequency so output isn't flooded
+ $this->setRedrawFrequency($max / 10);
+ }
+
+ $this->startTime = time();
+ }
+
+ /**
+ * Sets a placeholder formatter for a given name.
+ *
+ * This method also allow you to override an existing placeholder.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ * @param callable $callable A PHP callable
+ */
+ public static function setPlaceholderFormatterDefinition($name, callable $callable)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ self::$formatters[$name] = $callable;
+ }
+
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ *
+ * @return callable|null A PHP callable
+ */
+ public static function getPlaceholderFormatterDefinition($name)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
+ }
+
+ /**
+ * Sets a format for a given name.
+ *
+ * This method also allow you to override an existing format.
+ *
+ * @param string $name The format name
+ * @param string $format A format string
+ */
+ public static function setFormatDefinition($name, $format)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ self::$formats[$name] = $format;
+ }
+
+ /**
+ * Gets the format for a given name.
+ *
+ * @param string $name The format name
+ *
+ * @return string|null A format string
+ */
+ public static function getFormatDefinition($name)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ return isset(self::$formats[$name]) ? self::$formats[$name] : null;
+ }
+
+ /**
+ * Associates a text with a named placeholder.
+ *
+ * The text is displayed when the progress bar is rendered but only
+ * when the corresponding placeholder is part of the custom format line
+ * (by wrapping the name with %).
+ *
+ * @param string $message The text to associate with the placeholder
+ * @param string $name The name of the placeholder
+ */
+ public function setMessage($message, $name = 'message')
+ {
+ $this->messages[$name] = $message;
+ }
+
+ public function getMessage($name = 'message')
+ {
+ return $this->messages[$name];
+ }
+
+ /**
+ * Gets the progress bar start time.
+ *
+ * @return int The progress bar start time
+ */
+ public function getStartTime()
+ {
+ return $this->startTime;
+ }
+
+ /**
+ * Gets the progress bar maximal steps.
+ *
+ * @return int The progress bar max steps
+ */
+ public function getMaxSteps()
+ {
+ return $this->max;
+ }
+
+ /**
+ * Gets the current step position.
+ *
+ * @return int The progress bar step
+ */
+ public function getProgress()
+ {
+ return $this->step;
+ }
+
+ /**
+ * Gets the progress bar step width.
+ *
+ * @return int The progress bar step width
+ */
+ private function getStepWidth()
+ {
+ return $this->stepWidth;
+ }
+
+ /**
+ * Gets the current progress bar percent.
+ *
+ * @return float The current progress bar percent
+ */
+ public function getProgressPercent()
+ {
+ return $this->percent;
+ }
+
+ /**
+ * Sets the progress bar width.
+ *
+ * @param int $size The progress bar size
+ */
+ public function setBarWidth($size)
+ {
+ $this->barWidth = (int) $size;
+ }
+
+ /**
+ * Gets the progress bar width.
+ *
+ * @return int The progress bar size
+ */
+ public function getBarWidth()
+ {
+ return $this->barWidth;
+ }
+
+ /**
+ * Sets the bar character.
+ *
+ * @param string $char A character
+ */
+ public function setBarCharacter($char)
+ {
+ $this->barChar = $char;
+ }
+
+ /**
+ * Gets the bar character.
+ *
+ * @return string A character
+ */
+ public function getBarCharacter()
+ {
+ if (null === $this->barChar) {
+ return $this->max ? '=' : $this->emptyBarChar;
+ }
+
+ return $this->barChar;
+ }
+
+ /**
+ * Sets the empty bar character.
+ *
+ * @param string $char A character
+ */
+ public function setEmptyBarCharacter($char)
+ {
+ $this->emptyBarChar = $char;
+ }
+
+ /**
+ * Gets the empty bar character.
+ *
+ * @return string A character
+ */
+ public function getEmptyBarCharacter()
+ {
+ return $this->emptyBarChar;
+ }
+
+ /**
+ * Sets the progress bar character.
+ *
+ * @param string $char A character
+ */
+ public function setProgressCharacter($char)
+ {
+ $this->progressChar = $char;
+ }
+
+ /**
+ * Gets the progress bar character.
+ *
+ * @return string A character
+ */
+ public function getProgressCharacter()
+ {
+ return $this->progressChar;
+ }
+
+ /**
+ * Sets the progress bar format.
+ *
+ * @param string $format The format
+ */
+ public function setFormat($format)
+ {
+ $this->format = null;
+ $this->internalFormat = $format;
+ }
+
+ /**
+ * Sets the redraw frequency.
+ *
+ * @param int|float $freq The frequency in steps
+ */
+ public function setRedrawFrequency($freq)
+ {
+ $this->redrawFreq = max((int) $freq, 1);
+ }
+
+ /**
+ * Starts the progress output.
+ *
+ * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
+ */
+ public function start($max = null)
+ {
+ $this->startTime = time();
+ $this->step = 0;
+ $this->percent = 0.0;
+
+ if (null !== $max) {
+ $this->setMaxSteps($max);
+ }
+
+ $this->display();
+ }
+
+ /**
+ * Advances the progress output X steps.
+ *
+ * @param int $step Number of steps to advance
+ *
+ * @throws LogicException
+ */
+ public function advance($step = 1)
+ {
+ $this->setProgress($this->step + $step);
+ }
+
+ /**
+ * Sets whether to overwrite the progressbar, false for new line.
+ *
+ * @param bool $overwrite
+ */
+ public function setOverwrite($overwrite)
+ {
+ $this->overwrite = (bool) $overwrite;
+ }
+
+ /**
+ * Sets the current progress.
+ *
+ * @param int $step The current progress
+ *
+ * @throws LogicException
+ */
+ public function setProgress($step)
+ {
+ $step = (int) $step;
+ if ($step < $this->step) {
+ throw new LogicException('You can\'t regress the progress bar.');
+ }
+
+ if ($this->max && $step > $this->max) {
+ $this->max = $step;
+ }
+
+ $prevPeriod = (int) ($this->step / $this->redrawFreq);
+ $currPeriod = (int) ($step / $this->redrawFreq);
+ $this->step = $step;
+ $this->percent = $this->max ? (float) $this->step / $this->max : 0;
+ if ($prevPeriod !== $currPeriod || $this->max === $step) {
+ $this->display();
+ }
+ }
+
+ /**
+ * Finishes the progress output.
+ */
+ public function finish()
+ {
+ if (!$this->max) {
+ $this->max = $this->step;
+ }
+
+ if ($this->step === $this->max && !$this->overwrite) {
+ // prevent double 100% output
+ return;
+ }
+
+ $this->setProgress($this->max);
+ }
+
+ /**
+ * Outputs the current progress string.
+ */
+ public function display()
+ {
+ if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+ return;
+ }
+
+ if (null === $this->format) {
+ $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
+ }
+
+ $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) {
+ if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
+ $text = call_user_func($formatter, $this, $this->output);
+ } elseif (isset($this->messages[$matches[1]])) {
+ $text = $this->messages[$matches[1]];
+ } else {
+ return $matches[0];
+ }
+
+ if (isset($matches[2])) {
+ $text = sprintf('%'.$matches[2], $text);
+ }
+
+ return $text;
+ }, $this->format));
+ }
+
+ /**
+ * Removes the progress bar from the current line.
+ *
+ * This is useful if you wish to write some output
+ * while a progress bar is running.
+ * Call display() to show the progress bar again.
+ */
+ public function clear()
+ {
+ if (!$this->overwrite) {
+ return;
+ }
+
+ if (null === $this->format) {
+ $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
+ }
+
+ $this->overwrite('');
+ }
+
+ /**
+ * Sets the progress bar format.
+ *
+ * @param string $format The format
+ */
+ private function setRealFormat($format)
+ {
+ // try to use the _nomax variant if available
+ if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
+ $this->format = self::getFormatDefinition($format.'_nomax');
+ } elseif (null !== self::getFormatDefinition($format)) {
+ $this->format = self::getFormatDefinition($format);
+ } else {
+ $this->format = $format;
+ }
+
+ $this->formatLineCount = substr_count($this->format, "\n");
+ }
+
+ /**
+ * Sets the progress bar maximal steps.
+ *
+ * @param int $max The progress bar max steps
+ */
+ private function setMaxSteps($max)
+ {
+ $this->max = max(0, (int) $max);
+ $this->stepWidth = $this->max ? Helper::strlen($this->max) : 4;
+ }
+
+ /**
+ * Overwrites a previous message to the output.
+ *
+ * @param string $message The message
+ */
+ private function overwrite($message)
+ {
+ if ($this->overwrite) {
+ if (!$this->firstRun) {
+ // Move the cursor to the beginning of the line
+ $this->output->write("\x0D");
+
+ // Erase the line
+ $this->output->write("\x1B[2K");
+
+ // Erase previous lines
+ if ($this->formatLineCount > 0) {
+ $this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount));
+ }
+ }
+ } elseif ($this->step > 0) {
+ $this->output->writeln('');
+ }
+
+ $this->firstRun = false;
+
+ $this->output->write($message);
+ }
+
+ private function determineBestFormat()
+ {
+ switch ($this->output->getVerbosity()) {
+ // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return $this->max ? 'verbose' : 'verbose_nomax';
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ return $this->max ? 'very_verbose' : 'very_verbose_nomax';
+ case OutputInterface::VERBOSITY_DEBUG:
+ return $this->max ? 'debug' : 'debug_nomax';
+ default:
+ return $this->max ? 'normal' : 'normal_nomax';
+ }
+ }
+
+ private static function initPlaceholderFormatters()
+ {
+ return array(
+ 'bar' => function (ProgressBar $bar, OutputInterface $output) {
+ $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth());
+ $display = str_repeat($bar->getBarCharacter(), $completeBars);
+ if ($completeBars < $bar->getBarWidth()) {
+ $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter());
+ $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
+ }
+
+ return $display;
+ },
+ 'elapsed' => function (ProgressBar $bar) {
+ return Helper::formatTime(time() - $bar->getStartTime());
+ },
+ 'remaining' => function (ProgressBar $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
+ }
+
+ if (!$bar->getProgress()) {
+ $remaining = 0;
+ } else {
+ $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress()));
+ }
+
+ return Helper::formatTime($remaining);
+ },
+ 'estimated' => function (ProgressBar $bar) {
+ if (!$bar->getMaxSteps()) {
+ throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
+ }
+
+ if (!$bar->getProgress()) {
+ $estimated = 0;
+ } else {
+ $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps());
+ }
+
+ return Helper::formatTime($estimated);
+ },
+ 'memory' => function (ProgressBar $bar) {
+ return Helper::formatMemory(memory_get_usage(true));
+ },
+ 'current' => function (ProgressBar $bar) {
+ return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT);
+ },
+ 'max' => function (ProgressBar $bar) {
+ return $bar->getMaxSteps();
+ },
+ 'percent' => function (ProgressBar $bar) {
+ return floor($bar->getProgressPercent() * 100);
+ },
+ );
+ }
+
+ private static function initFormats()
+ {
+ return array(
+ 'normal' => ' %current%/%max% [%bar%] %percent:3s%%',
+ 'normal_nomax' => ' %current% [%bar%]',
+
+ 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%',
+ 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
+
+ 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%',
+ 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%',
+
+ 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%',
+ 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%',
+ );
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/ProgressIndicator.php b/includes/src/vendor/symfony/console/Helper/ProgressIndicator.php
new file mode 100644
index 0000000..f90a85c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/ProgressIndicator.php
@@ -0,0 +1,288 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * @author Kevin Bond
+ */
+class ProgressIndicator
+{
+ private $output;
+ private $startTime;
+ private $format;
+ private $message;
+ private $indicatorValues;
+ private $indicatorCurrent;
+ private $indicatorChangeInterval;
+ private $indicatorUpdateTime;
+ private $lastMessagesLength;
+ private $started = false;
+
+ private static $formatters;
+ private static $formats;
+
+ /**
+ * @param OutputInterface $output
+ * @param string|null $format Indicator format
+ * @param int $indicatorChangeInterval Change interval in milliseconds
+ * @param array|null $indicatorValues Animated indicator characters
+ */
+ public function __construct(OutputInterface $output, $format = null, $indicatorChangeInterval = 100, $indicatorValues = null)
+ {
+ $this->output = $output;
+
+ if (null === $format) {
+ $format = $this->determineBestFormat();
+ }
+
+ if (null === $indicatorValues) {
+ $indicatorValues = array('-', '\\', '|', '/');
+ }
+
+ $indicatorValues = array_values($indicatorValues);
+
+ if (2 > count($indicatorValues)) {
+ throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
+ }
+
+ $this->format = self::getFormatDefinition($format);
+ $this->indicatorChangeInterval = $indicatorChangeInterval;
+ $this->indicatorValues = $indicatorValues;
+ $this->startTime = time();
+ }
+
+ /**
+ * Sets the current indicator message.
+ *
+ * @param string|null $message
+ */
+ public function setMessage($message)
+ {
+ $this->message = $message;
+
+ $this->display();
+ }
+
+ /**
+ * Starts the indicator output.
+ *
+ * @param $message
+ */
+ public function start($message)
+ {
+ if ($this->started) {
+ throw new LogicException('Progress indicator already started.');
+ }
+
+ $this->message = $message;
+ $this->started = true;
+ $this->lastMessagesLength = 0;
+ $this->startTime = time();
+ $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
+ $this->indicatorCurrent = 0;
+
+ $this->display();
+ }
+
+ /**
+ * Advances the indicator.
+ */
+ public function advance()
+ {
+ if (!$this->started) {
+ throw new LogicException('Progress indicator has not yet been started.');
+ }
+
+ if (!$this->output->isDecorated()) {
+ return;
+ }
+
+ $currentTime = $this->getCurrentTimeInMilliseconds();
+
+ if ($currentTime < $this->indicatorUpdateTime) {
+ return;
+ }
+
+ $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
+ ++$this->indicatorCurrent;
+
+ $this->display();
+ }
+
+ /**
+ * Finish the indicator with message.
+ *
+ * @param $message
+ */
+ public function finish($message)
+ {
+ if (!$this->started) {
+ throw new LogicException('Progress indicator has not yet been started.');
+ }
+
+ $this->message = $message;
+ $this->display();
+ $this->output->writeln('');
+ $this->started = false;
+ }
+
+ /**
+ * Gets the format for a given name.
+ *
+ * @param string $name The format name
+ *
+ * @return string|null A format string
+ */
+ public static function getFormatDefinition($name)
+ {
+ if (!self::$formats) {
+ self::$formats = self::initFormats();
+ }
+
+ return isset(self::$formats[$name]) ? self::$formats[$name] : null;
+ }
+
+ /**
+ * Sets a placeholder formatter for a given name.
+ *
+ * This method also allow you to override an existing placeholder.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ * @param callable $callable A PHP callable
+ */
+ public static function setPlaceholderFormatterDefinition($name, $callable)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ self::$formatters[$name] = $callable;
+ }
+
+ /**
+ * Gets the placeholder formatter for a given name.
+ *
+ * @param string $name The placeholder name (including the delimiter char like %)
+ *
+ * @return callable|null A PHP callable
+ */
+ public static function getPlaceholderFormatterDefinition($name)
+ {
+ if (!self::$formatters) {
+ self::$formatters = self::initPlaceholderFormatters();
+ }
+
+ return isset(self::$formatters[$name]) ? self::$formatters[$name] : null;
+ }
+
+ private function display()
+ {
+ if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
+ return;
+ }
+
+ $self = $this;
+
+ $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) {
+ if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) {
+ return call_user_func($formatter, $self);
+ }
+
+ return $matches[0];
+ }, $this->format));
+ }
+
+ private function determineBestFormat()
+ {
+ switch ($this->output->getVerbosity()) {
+ // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
+ case OutputInterface::VERBOSITY_VERBOSE:
+ return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
+ case OutputInterface::VERBOSITY_VERY_VERBOSE:
+ case OutputInterface::VERBOSITY_DEBUG:
+ return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
+ default:
+ return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
+ }
+ }
+
+ /**
+ * Overwrites a previous message to the output.
+ *
+ * @param string $message The message
+ */
+ private function overwrite($message)
+ {
+ // append whitespace to match the line's length
+ if (null !== $this->lastMessagesLength) {
+ if ($this->lastMessagesLength > Helper::strlenWithoutDecoration($this->output->getFormatter(), $message)) {
+ $message = str_pad($message, $this->lastMessagesLength, "\x20", STR_PAD_RIGHT);
+ }
+ }
+
+ if ($this->output->isDecorated()) {
+ $this->output->write("\x0D");
+ $this->output->write($message);
+ } else {
+ $this->output->writeln($message);
+ }
+
+ $this->lastMessagesLength = 0;
+
+ $len = Helper::strlenWithoutDecoration($this->output->getFormatter(), $message);
+
+ if ($len > $this->lastMessagesLength) {
+ $this->lastMessagesLength = $len;
+ }
+ }
+
+ private function getCurrentTimeInMilliseconds()
+ {
+ return round(microtime(true) * 1000);
+ }
+
+ private static function initPlaceholderFormatters()
+ {
+ return array(
+ 'indicator' => function (ProgressIndicator $indicator) {
+ return $indicator->indicatorValues[$indicator->indicatorCurrent % count($indicator->indicatorValues)];
+ },
+ 'message' => function (ProgressIndicator $indicator) {
+ return $indicator->message;
+ },
+ 'elapsed' => function (ProgressIndicator $indicator) {
+ return Helper::formatTime(time() - $indicator->startTime);
+ },
+ 'memory' => function () {
+ return Helper::formatMemory(memory_get_usage(true));
+ },
+ );
+ }
+
+ private static function initFormats()
+ {
+ return array(
+ 'normal' => ' %indicator% %message%',
+ 'normal_no_ansi' => ' %message%',
+
+ 'verbose' => ' %indicator% %message% (%elapsed:6s%)',
+ 'verbose_no_ansi' => ' %message% (%elapsed:6s%)',
+
+ 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)',
+ 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)',
+ );
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/QuestionHelper.php b/includes/src/vendor/symfony/console/Helper/QuestionHelper.php
new file mode 100644
index 0000000..c6f5a40
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/QuestionHelper.php
@@ -0,0 +1,445 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Question\Question;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+
+/**
+ * The QuestionHelper class provides helpers to interact with the user.
+ *
+ * @author Fabien Potencier
+ */
+class QuestionHelper extends Helper
+{
+ private $inputStream;
+ private static $shell;
+ private static $stty;
+
+ /**
+ * Asks a question to the user.
+ *
+ * @param InputInterface $input An InputInterface instance
+ * @param OutputInterface $output An OutputInterface instance
+ * @param Question $question The question to ask
+ *
+ * @return string The user answer
+ *
+ * @throws RuntimeException If there is no data to read in the input stream
+ */
+ public function ask(InputInterface $input, OutputInterface $output, Question $question)
+ {
+ if ($output instanceof ConsoleOutputInterface) {
+ $output = $output->getErrorOutput();
+ }
+
+ if (!$input->isInteractive()) {
+ return $question->getDefault();
+ }
+
+ if (!$question->getValidator()) {
+ return $this->doAsk($output, $question);
+ }
+
+ $interviewer = function () use ($output, $question) {
+ return $this->doAsk($output, $question);
+ };
+
+ return $this->validateAttempts($interviewer, $output, $question);
+ }
+
+ /**
+ * Sets the input stream to read from when interacting with the user.
+ *
+ * This is mainly useful for testing purpose.
+ *
+ * @param resource $stream The input stream
+ *
+ * @throws InvalidArgumentException In case the stream is not a resource
+ */
+ public function setInputStream($stream)
+ {
+ if (!is_resource($stream)) {
+ throw new InvalidArgumentException('Input stream must be a valid resource.');
+ }
+
+ $this->inputStream = $stream;
+ }
+
+ /**
+ * Returns the helper's input stream.
+ *
+ * @return resource
+ */
+ public function getInputStream()
+ {
+ return $this->inputStream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'question';
+ }
+
+ /**
+ * Asks the question to the user.
+ *
+ * @param OutputInterface $output
+ * @param Question $question
+ *
+ * @return bool|mixed|null|string
+ *
+ * @throws \Exception
+ * @throws \RuntimeException
+ */
+ private function doAsk(OutputInterface $output, Question $question)
+ {
+ $this->writePrompt($output, $question);
+
+ $inputStream = $this->inputStream ?: STDIN;
+ $autocomplete = $question->getAutocompleterValues();
+
+ if (null === $autocomplete || !$this->hasSttyAvailable()) {
+ $ret = false;
+ if ($question->isHidden()) {
+ try {
+ $ret = trim($this->getHiddenResponse($output, $inputStream));
+ } catch (\RuntimeException $e) {
+ if (!$question->isHiddenFallback()) {
+ throw $e;
+ }
+ }
+ }
+
+ if (false === $ret) {
+ $ret = fgets($inputStream, 4096);
+ if (false === $ret) {
+ throw new \RuntimeException('Aborted');
+ }
+ $ret = trim($ret);
+ }
+ } else {
+ $ret = trim($this->autocomplete($output, $question, $inputStream));
+ }
+
+ $ret = strlen($ret) > 0 ? $ret : $question->getDefault();
+
+ if ($normalizer = $question->getNormalizer()) {
+ return $normalizer($ret);
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Outputs the question prompt.
+ *
+ * @param OutputInterface $output
+ * @param Question $question
+ */
+ protected function writePrompt(OutputInterface $output, Question $question)
+ {
+ $message = $question->getQuestion();
+
+ if ($question instanceof ChoiceQuestion) {
+ $maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));
+
+ $messages = (array) $question->getQuestion();
+ foreach ($question->getChoices() as $key => $value) {
+ $width = $maxWidth - $this->strlen($key);
+ $messages[] = ' ['.$key.str_repeat(' ', $width).'] '.$value;
+ }
+
+ $output->writeln($messages);
+
+ $message = $question->getPrompt();
+ }
+
+ $output->write($message);
+ }
+
+ /**
+ * Outputs an error message.
+ *
+ * @param OutputInterface $output
+ * @param \Exception $error
+ */
+ protected function writeError(OutputInterface $output, \Exception $error)
+ {
+ if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
+ $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
+ } else {
+ $message = ''.$error->getMessage().'';
+ }
+
+ $output->writeln($message);
+ }
+
+ /**
+ * Autocompletes a question.
+ *
+ * @param OutputInterface $output
+ * @param Question $question
+ *
+ * @return string
+ */
+ private function autocomplete(OutputInterface $output, Question $question, $inputStream)
+ {
+ $autocomplete = $question->getAutocompleterValues();
+ $ret = '';
+
+ $i = 0;
+ $ofs = -1;
+ $matches = $autocomplete;
+ $numMatches = count($matches);
+
+ $sttyMode = shell_exec('stty -g');
+
+ // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
+ shell_exec('stty -icanon -echo');
+
+ // Add highlighted text style
+ $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
+
+ // Read a keypress
+ while (!feof($inputStream)) {
+ $c = fread($inputStream, 1);
+
+ // Backspace Character
+ if ("\177" === $c) {
+ if (0 === $numMatches && 0 !== $i) {
+ --$i;
+ // Move cursor backwards
+ $output->write("\033[1D");
+ }
+
+ if ($i === 0) {
+ $ofs = -1;
+ $matches = $autocomplete;
+ $numMatches = count($matches);
+ } else {
+ $numMatches = 0;
+ }
+
+ // Pop the last character off the end of our string
+ $ret = substr($ret, 0, $i);
+ } elseif ("\033" === $c) {
+ // Did we read an escape sequence?
+ $c .= fread($inputStream, 2);
+
+ // A = Up Arrow. B = Down Arrow
+ if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
+ if ('A' === $c[2] && -1 === $ofs) {
+ $ofs = 0;
+ }
+
+ if (0 === $numMatches) {
+ continue;
+ }
+
+ $ofs += ('A' === $c[2]) ? -1 : 1;
+ $ofs = ($numMatches + $ofs) % $numMatches;
+ }
+ } elseif (ord($c) < 32) {
+ if ("\t" === $c || "\n" === $c) {
+ if ($numMatches > 0 && -1 !== $ofs) {
+ $ret = $matches[$ofs];
+ // Echo out remaining chars for current match
+ $output->write(substr($ret, $i));
+ $i = strlen($ret);
+ }
+
+ if ("\n" === $c) {
+ $output->write($c);
+ break;
+ }
+
+ $numMatches = 0;
+ }
+
+ continue;
+ } else {
+ $output->write($c);
+ $ret .= $c;
+ ++$i;
+
+ $numMatches = 0;
+ $ofs = 0;
+
+ foreach ($autocomplete as $value) {
+ // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
+ if (0 === strpos($value, $ret) && $i !== strlen($value)) {
+ $matches[$numMatches++] = $value;
+ }
+ }
+ }
+
+ // Erase characters from cursor to end of line
+ $output->write("\033[K");
+
+ if ($numMatches > 0 && -1 !== $ofs) {
+ // Save cursor position
+ $output->write("\0337");
+ // Write highlighted text
+ $output->write(''.substr($matches[$ofs], $i).'');
+ // Restore cursor position
+ $output->write("\0338");
+ }
+ }
+
+ // Reset stty so it behaves normally again
+ shell_exec(sprintf('stty %s', $sttyMode));
+
+ return $ret;
+ }
+
+ /**
+ * Gets a hidden response from user.
+ *
+ * @param OutputInterface $output An Output instance
+ *
+ * @return string The answer
+ *
+ * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
+ */
+ private function getHiddenResponse(OutputInterface $output, $inputStream)
+ {
+ if ('\\' === DIRECTORY_SEPARATOR) {
+ $exe = __DIR__.'/../Resources/bin/hiddeninput.exe';
+
+ // handle code running from a phar
+ if ('phar:' === substr(__FILE__, 0, 5)) {
+ $tmpExe = sys_get_temp_dir().'/hiddeninput.exe';
+ copy($exe, $tmpExe);
+ $exe = $tmpExe;
+ }
+
+ $value = rtrim(shell_exec($exe));
+ $output->writeln('');
+
+ if (isset($tmpExe)) {
+ unlink($tmpExe);
+ }
+
+ return $value;
+ }
+
+ if ($this->hasSttyAvailable()) {
+ $sttyMode = shell_exec('stty -g');
+
+ shell_exec('stty -echo');
+ $value = fgets($inputStream, 4096);
+ shell_exec(sprintf('stty %s', $sttyMode));
+
+ if (false === $value) {
+ throw new RuntimeException('Aborted');
+ }
+
+ $value = trim($value);
+ $output->writeln('');
+
+ return $value;
+ }
+
+ if (false !== $shell = $this->getShell()) {
+ $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';
+ $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd);
+ $value = rtrim(shell_exec($command));
+ $output->writeln('');
+
+ return $value;
+ }
+
+ throw new RuntimeException('Unable to hide the response.');
+ }
+
+ /**
+ * Validates an attempt.
+ *
+ * @param callable $interviewer A callable that will ask for a question and return the result
+ * @param OutputInterface $output An Output instance
+ * @param Question $question A Question instance
+ *
+ * @return string The validated response
+ *
+ * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
+ */
+ private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question)
+ {
+ $error = null;
+ $attempts = $question->getMaxAttempts();
+ while (null === $attempts || $attempts--) {
+ if (null !== $error) {
+ $this->writeError($output, $error);
+ }
+
+ try {
+ return call_user_func($question->getValidator(), $interviewer());
+ } catch (\Exception $error) {
+ }
+ }
+
+ throw $error;
+ }
+
+ /**
+ * Returns a valid unix shell.
+ *
+ * @return string|bool The valid shell name, false in case no valid shell is found
+ */
+ private function getShell()
+ {
+ if (null !== self::$shell) {
+ return self::$shell;
+ }
+
+ self::$shell = false;
+
+ if (file_exists('/usr/bin/env')) {
+ // handle other OSs with bash/zsh/ksh/csh if available to hide the answer
+ $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null";
+ foreach (array('bash', 'zsh', 'ksh', 'csh') as $sh) {
+ if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {
+ self::$shell = $sh;
+ break;
+ }
+ }
+ }
+
+ return self::$shell;
+ }
+
+ /**
+ * Returns whether Stty is available or not.
+ *
+ * @return bool
+ */
+ private function hasSttyAvailable()
+ {
+ if (null !== self::$stty) {
+ return self::$stty;
+ }
+
+ exec('stty 2>&1', $output, $exitcode);
+
+ return self::$stty = $exitcode === 0;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/includes/src/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
new file mode 100644
index 0000000..aeddb76
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/SymfonyQuestionHelper.php
@@ -0,0 +1,119 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Exception\LogicException;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+/**
+ * Symfony Style Guide compliant question helper.
+ *
+ * @author Kevin Bond
+ */
+class SymfonyQuestionHelper extends QuestionHelper
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function ask(InputInterface $input, OutputInterface $output, Question $question)
+ {
+ $validator = $question->getValidator();
+ $question->setValidator(function ($value) use ($validator) {
+ if (null !== $validator) {
+ $value = $validator($value);
+ }
+
+ // make required
+ if (!is_array($value) && !is_bool($value) && 0 === strlen($value)) {
+ throw new LogicException('A value is required.');
+ }
+
+ return $value;
+ });
+
+ return parent::ask($input, $output, $question);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writePrompt(OutputInterface $output, Question $question)
+ {
+ $text = $question->getQuestion();
+ $default = $question->getDefault();
+
+ switch (true) {
+ case null === $default:
+ $text = sprintf(' %s:', $text);
+
+ break;
+
+ case $question instanceof ConfirmationQuestion:
+ $text = sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no');
+
+ break;
+
+ case $question instanceof ChoiceQuestion && $question->isMultiselect():
+ $choices = $question->getChoices();
+ $default = explode(',', $default);
+
+ foreach ($default as $key => $value) {
+ $default[$key] = $choices[trim($value)];
+ }
+
+ $text = sprintf(' %s [%s]:', $text, implode(', ', $default));
+
+ break;
+
+ case $question instanceof ChoiceQuestion:
+ $choices = $question->getChoices();
+ $text = sprintf(' %s [%s]:', $text, $choices[$default]);
+
+ break;
+
+ default:
+ $text = sprintf(' %s [%s]:', $text, $default);
+ }
+
+ $output->writeln($text);
+
+ if ($question instanceof ChoiceQuestion) {
+ $width = max(array_map('strlen', array_keys($question->getChoices())));
+
+ foreach ($question->getChoices() as $key => $value) {
+ $output->writeln(sprintf(" [%-${width}s] %s", $key, $value));
+ }
+ }
+
+ $output->write(' > ');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function writeError(OutputInterface $output, \Exception $error)
+ {
+ if ($output instanceof SymfonyStyle) {
+ $output->newLine();
+ $output->error($error->getMessage());
+
+ return;
+ }
+
+ parent::writeError($output, $error);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/Table.php b/includes/src/vendor/symfony/console/Helper/Table.php
new file mode 100644
index 0000000..7f2dd1b
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/Table.php
@@ -0,0 +1,704 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * Provides helpers to display a table.
+ *
+ * @author Fabien Potencier
+ * @author Саша Стаменковић
+ * @author Abdellatif Ait boudad
+ * @author Max Grigorian
+ */
+class Table
+{
+ /**
+ * Table headers.
+ *
+ * @var array
+ */
+ private $headers = array();
+
+ /**
+ * Table rows.
+ *
+ * @var array
+ */
+ private $rows = array();
+
+ /**
+ * Column widths cache.
+ *
+ * @var array
+ */
+ private $effectiveColumnWidths = array();
+
+ /**
+ * Number of columns cache.
+ *
+ * @var array
+ */
+ private $numberOfColumns;
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+
+ /**
+ * @var TableStyle
+ */
+ private $style;
+
+ /**
+ * @var array
+ */
+ private $columnStyles = array();
+
+ /**
+ * User set column widths.
+ *
+ * @var array
+ */
+ private $columnWidths = array();
+
+ private static $styles;
+
+ public function __construct(OutputInterface $output)
+ {
+ $this->output = $output;
+
+ if (!self::$styles) {
+ self::$styles = self::initStyles();
+ }
+
+ $this->setStyle('default');
+ }
+
+ /**
+ * Sets a style definition.
+ *
+ * @param string $name The style name
+ * @param TableStyle $style A TableStyle instance
+ */
+ public static function setStyleDefinition($name, TableStyle $style)
+ {
+ if (!self::$styles) {
+ self::$styles = self::initStyles();
+ }
+
+ self::$styles[$name] = $style;
+ }
+
+ /**
+ * Gets a style definition by name.
+ *
+ * @param string $name The style name
+ *
+ * @return TableStyle A TableStyle instance
+ */
+ public static function getStyleDefinition($name)
+ {
+ if (!self::$styles) {
+ self::$styles = self::initStyles();
+ }
+
+ if (!self::$styles[$name]) {
+ throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
+ }
+
+ return self::$styles[$name];
+ }
+
+ /**
+ * Sets table style.
+ *
+ * @param TableStyle|string $name The style name or a TableStyle instance
+ *
+ * @return Table
+ */
+ public function setStyle($name)
+ {
+ if ($name instanceof TableStyle) {
+ $this->style = $name;
+ } elseif (isset(self::$styles[$name])) {
+ $this->style = self::$styles[$name];
+ } else {
+ throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Gets the current table style.
+ *
+ * @return TableStyle
+ */
+ public function getStyle()
+ {
+ return $this->style;
+ }
+
+ /**
+ * Sets table column style.
+ *
+ * @param int $columnIndex Column index
+ * @param TableStyle|string $name The style name or a TableStyle instance
+ *
+ * @return Table
+ */
+ public function setColumnStyle($columnIndex, $name)
+ {
+ $columnIndex = intval($columnIndex);
+
+ if ($name instanceof TableStyle) {
+ $this->columnStyles[$columnIndex] = $name;
+ } elseif (isset(self::$styles[$name])) {
+ $this->columnStyles[$columnIndex] = self::$styles[$name];
+ } else {
+ throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name));
+ }
+
+ return $this;
+ }
+
+ /**
+ * Gets the current style for a column.
+ *
+ * If style was not set, it returns the global table style.
+ *
+ * @param int $columnIndex Column index
+ *
+ * @return TableStyle
+ */
+ public function getColumnStyle($columnIndex)
+ {
+ if (isset($this->columnStyles[$columnIndex])) {
+ return $this->columnStyles[$columnIndex];
+ }
+
+ return $this->getStyle();
+ }
+
+ /**
+ * Sets the minimum width of a column.
+ *
+ * @param int $columnIndex Column index
+ * @param int $width Minimum column width in characters
+ *
+ * @return Table
+ */
+ public function setColumnWidth($columnIndex, $width)
+ {
+ $this->columnWidths[intval($columnIndex)] = intval($width);
+
+ return $this;
+ }
+
+ /**
+ * Sets the minimum width of all columns.
+ *
+ * @param array $widths
+ *
+ * @return Table
+ */
+ public function setColumnWidths(array $widths)
+ {
+ $this->columnWidths = array();
+ foreach ($widths as $index => $width) {
+ $this->setColumnWidth($index, $width);
+ }
+
+ return $this;
+ }
+
+ public function setHeaders(array $headers)
+ {
+ $headers = array_values($headers);
+ if (!empty($headers) && !is_array($headers[0])) {
+ $headers = array($headers);
+ }
+
+ $this->headers = $headers;
+
+ return $this;
+ }
+
+ public function setRows(array $rows)
+ {
+ $this->rows = array();
+
+ return $this->addRows($rows);
+ }
+
+ public function addRows(array $rows)
+ {
+ foreach ($rows as $row) {
+ $this->addRow($row);
+ }
+
+ return $this;
+ }
+
+ public function addRow($row)
+ {
+ if ($row instanceof TableSeparator) {
+ $this->rows[] = $row;
+
+ return $this;
+ }
+
+ if (!is_array($row)) {
+ throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
+ }
+
+ $this->rows[] = array_values($row);
+
+ return $this;
+ }
+
+ public function setRow($column, array $row)
+ {
+ $this->rows[$column] = $row;
+
+ return $this;
+ }
+
+ /**
+ * Renders table to output.
+ *
+ * Example:
+ * +---------------+-----------------------+------------------+
+ * | ISBN | Title | Author |
+ * +---------------+-----------------------+------------------+
+ * | 99921-58-10-7 | Divine Comedy | Dante Alighieri |
+ * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+ * +---------------+-----------------------+------------------+
+ */
+ public function render()
+ {
+ $this->calculateNumberOfColumns();
+ $rows = $this->buildTableRows($this->rows);
+ $headers = $this->buildTableRows($this->headers);
+
+ $this->calculateColumnsWidth(array_merge($headers, $rows));
+
+ $this->renderRowSeparator();
+ if (!empty($headers)) {
+ foreach ($headers as $header) {
+ $this->renderRow($header, $this->style->getCellHeaderFormat());
+ $this->renderRowSeparator();
+ }
+ }
+ foreach ($rows as $row) {
+ if ($row instanceof TableSeparator) {
+ $this->renderRowSeparator();
+ } else {
+ $this->renderRow($row, $this->style->getCellRowFormat());
+ }
+ }
+ if (!empty($rows)) {
+ $this->renderRowSeparator();
+ }
+
+ $this->cleanup();
+ }
+
+ /**
+ * Renders horizontal header separator.
+ *
+ * Example: +-----+-----------+-------+
+ */
+ private function renderRowSeparator()
+ {
+ if (0 === $count = $this->numberOfColumns) {
+ return;
+ }
+
+ if (!$this->style->getHorizontalBorderChar() && !$this->style->getCrossingChar()) {
+ return;
+ }
+
+ $markup = $this->style->getCrossingChar();
+ for ($column = 0; $column < $count; ++$column) {
+ $markup .= str_repeat($this->style->getHorizontalBorderChar(), $this->effectiveColumnWidths[$column]).$this->style->getCrossingChar();
+ }
+
+ $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup));
+ }
+
+ /**
+ * Renders vertical column separator.
+ */
+ private function renderColumnSeparator()
+ {
+ return sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar());
+ }
+
+ /**
+ * Renders table row.
+ *
+ * Example: | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
+ *
+ * @param array $row
+ * @param string $cellFormat
+ */
+ private function renderRow(array $row, $cellFormat)
+ {
+ if (empty($row)) {
+ return;
+ }
+
+ $rowContent = $this->renderColumnSeparator();
+ foreach ($this->getRowColumns($row) as $column) {
+ $rowContent .= $this->renderCell($row, $column, $cellFormat);
+ $rowContent .= $this->renderColumnSeparator();
+ }
+ $this->output->writeln($rowContent);
+ }
+
+ /**
+ * Renders table cell with padding.
+ *
+ * @param array $row
+ * @param int $column
+ * @param string $cellFormat
+ */
+ private function renderCell(array $row, $column, $cellFormat)
+ {
+ $cell = isset($row[$column]) ? $row[$column] : '';
+ $width = $this->effectiveColumnWidths[$column];
+ if ($cell instanceof TableCell && $cell->getColspan() > 1) {
+ // add the width of the following columns(numbers of colspan).
+ foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
+ $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn];
+ }
+ }
+
+ // str_pad won't work properly with multi-byte strings, we need to fix the padding
+ if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
+ $width += strlen($cell) - mb_strwidth($cell, $encoding);
+ }
+
+ $style = $this->getColumnStyle($column);
+
+ if ($cell instanceof TableSeparator) {
+ return sprintf($style->getBorderFormat(), str_repeat($style->getHorizontalBorderChar(), $width));
+ }
+
+ $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
+ $content = sprintf($style->getCellRowContentFormat(), $cell);
+
+ return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType()));
+ }
+
+ /**
+ * Calculate number of columns for this table.
+ */
+ private function calculateNumberOfColumns()
+ {
+ if (null !== $this->numberOfColumns) {
+ return;
+ }
+
+ $columns = array(0);
+ foreach (array_merge($this->headers, $this->rows) as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+
+ $columns[] = $this->getNumberOfColumns($row);
+ }
+
+ $this->numberOfColumns = max($columns);
+ }
+
+ private function buildTableRows($rows)
+ {
+ $unmergedRows = array();
+ for ($rowKey = 0; $rowKey < count($rows); ++$rowKey) {
+ $rows = $this->fillNextRows($rows, $rowKey);
+
+ // Remove any new line breaks and replace it with a new line
+ foreach ($rows[$rowKey] as $column => $cell) {
+ if (!strstr($cell, "\n")) {
+ continue;
+ }
+ $lines = explode("\n", $cell);
+ foreach ($lines as $lineKey => $line) {
+ if ($cell instanceof TableCell) {
+ $line = new TableCell($line, array('colspan' => $cell->getColspan()));
+ }
+ if (0 === $lineKey) {
+ $rows[$rowKey][$column] = $line;
+ } else {
+ $unmergedRows[$rowKey][$lineKey][$column] = $line;
+ }
+ }
+ }
+ }
+
+ $tableRows = array();
+ foreach ($rows as $rowKey => $row) {
+ $tableRows[] = $this->fillCells($row);
+ if (isset($unmergedRows[$rowKey])) {
+ $tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
+ }
+ }
+
+ return $tableRows;
+ }
+
+ /**
+ * fill rows that contains rowspan > 1.
+ *
+ * @param array $rows
+ * @param int $line
+ *
+ * @return array
+ */
+ private function fillNextRows($rows, $line)
+ {
+ $unmergedRows = array();
+ foreach ($rows[$line] as $column => $cell) {
+ if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
+ $nbLines = $cell->getRowspan() - 1;
+ $lines = array($cell);
+ if (strstr($cell, "\n")) {
+ $lines = explode("\n", $cell);
+ $nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
+
+ $rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
+ unset($lines[0]);
+ }
+
+ // create a two dimensional array (rowspan x colspan)
+ $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, array()), $unmergedRows);
+ foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
+ $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
+ $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
+ }
+ }
+ }
+
+ foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
+ // we need to know if $unmergedRow will be merged or inserted into $rows
+ if (isset($rows[$unmergedRowKey]) && is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
+ foreach ($unmergedRow as $cellKey => $cell) {
+ // insert cell into row at cellKey position
+ array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell));
+ }
+ } else {
+ $row = $this->copyRow($rows, $unmergedRowKey - 1);
+ foreach ($unmergedRow as $column => $cell) {
+ if (!empty($cell)) {
+ $row[$column] = $unmergedRow[$column];
+ }
+ }
+ array_splice($rows, $unmergedRowKey, 0, array($row));
+ }
+ }
+
+ return $rows;
+ }
+
+ /**
+ * fill cells for a row that contains colspan > 1.
+ *
+ * @param array $row
+ *
+ * @return array
+ */
+ private function fillCells($row)
+ {
+ $newRow = array();
+ foreach ($row as $column => $cell) {
+ $newRow[] = $cell;
+ if ($cell instanceof TableCell && $cell->getColspan() > 1) {
+ foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {
+ // insert empty value at column position
+ $newRow[] = '';
+ }
+ }
+ }
+
+ return $newRow ?: $row;
+ }
+
+ /**
+ * @param array $rows
+ * @param int $line
+ *
+ * @return array
+ */
+ private function copyRow($rows, $line)
+ {
+ $row = $rows[$line];
+ foreach ($row as $cellKey => $cellValue) {
+ $row[$cellKey] = '';
+ if ($cellValue instanceof TableCell) {
+ $row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan()));
+ }
+ }
+
+ return $row;
+ }
+
+ /**
+ * Gets number of columns by row.
+ *
+ * @param array $row
+ *
+ * @return int
+ */
+ private function getNumberOfColumns(array $row)
+ {
+ $columns = count($row);
+ foreach ($row as $column) {
+ $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0;
+ }
+
+ return $columns;
+ }
+
+ /**
+ * Gets list of columns for the given row.
+ *
+ * @param array $row
+ *
+ * @return array
+ */
+ private function getRowColumns($row)
+ {
+ $columns = range(0, $this->numberOfColumns - 1);
+ foreach ($row as $cellKey => $cell) {
+ if ($cell instanceof TableCell && $cell->getColspan() > 1) {
+ // exclude grouped columns.
+ $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
+ }
+ }
+
+ return $columns;
+ }
+
+ /**
+ * Calculates columns widths.
+ *
+ * @param array $rows
+ */
+ private function calculateColumnsWidth($rows)
+ {
+ for ($column = 0; $column < $this->numberOfColumns; ++$column) {
+ $lengths = array();
+ foreach ($rows as $row) {
+ if ($row instanceof TableSeparator) {
+ continue;
+ }
+
+ foreach ($row as $i => $cell) {
+ if ($cell instanceof TableCell) {
+ $textLength = strlen($cell);
+ if ($textLength > 0) {
+ $contentColumns = str_split($cell, ceil($textLength / $cell->getColspan()));
+ foreach ($contentColumns as $position => $content) {
+ $row[$i + $position] = $content;
+ }
+ }
+ }
+ }
+
+ $lengths[] = $this->getCellWidth($row, $column);
+ }
+
+ $this->effectiveColumnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
+ }
+ }
+
+ /**
+ * Gets column width.
+ *
+ * @return int
+ */
+ private function getColumnSeparatorWidth()
+ {
+ return strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
+ }
+
+ /**
+ * Gets cell width.
+ *
+ * @param array $row
+ * @param int $column
+ *
+ * @return int
+ */
+ private function getCellWidth(array $row, $column)
+ {
+ $cellWidth = 0;
+
+ if (isset($row[$column])) {
+ $cell = $row[$column];
+ $cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
+ }
+
+ $columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0;
+
+ return max($cellWidth, $columnWidth);
+ }
+
+ /**
+ * Called after rendering to cleanup cache data.
+ */
+ private function cleanup()
+ {
+ $this->effectiveColumnWidths = array();
+ $this->numberOfColumns = null;
+ }
+
+ private static function initStyles()
+ {
+ $borderless = new TableStyle();
+ $borderless
+ ->setHorizontalBorderChar('=')
+ ->setVerticalBorderChar(' ')
+ ->setCrossingChar(' ')
+ ;
+
+ $compact = new TableStyle();
+ $compact
+ ->setHorizontalBorderChar('')
+ ->setVerticalBorderChar(' ')
+ ->setCrossingChar('')
+ ->setCellRowContentFormat('%s')
+ ;
+
+ $styleGuide = new TableStyle();
+ $styleGuide
+ ->setHorizontalBorderChar('-')
+ ->setVerticalBorderChar(' ')
+ ->setCrossingChar(' ')
+ ->setCellHeaderFormat('%s')
+ ;
+
+ return array(
+ 'default' => new TableStyle(),
+ 'borderless' => $borderless,
+ 'compact' => $compact,
+ 'symfony-style-guide' => $styleGuide,
+ );
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/TableCell.php b/includes/src/vendor/symfony/console/Helper/TableCell.php
new file mode 100644
index 0000000..69442d4
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/TableCell.php
@@ -0,0 +1,79 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * @author Abdellatif Ait boudad
+ */
+class TableCell
+{
+ /**
+ * @var string
+ */
+ private $value;
+
+ /**
+ * @var array
+ */
+ private $options = array(
+ 'rowspan' => 1,
+ 'colspan' => 1,
+ );
+
+ /**
+ * @param string $value
+ * @param array $options
+ */
+ public function __construct($value = '', array $options = array())
+ {
+ $this->value = $value;
+
+ // check option names
+ if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
+ throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff)));
+ }
+
+ $this->options = array_merge($this->options, $options);
+ }
+
+ /**
+ * Returns the cell value.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Gets number of colspan.
+ *
+ * @return int
+ */
+ public function getColspan()
+ {
+ return (int) $this->options['colspan'];
+ }
+
+ /**
+ * Gets number of rowspan.
+ *
+ * @return int
+ */
+ public function getRowspan()
+ {
+ return (int) $this->options['rowspan'];
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/TableSeparator.php b/includes/src/vendor/symfony/console/Helper/TableSeparator.php
new file mode 100644
index 0000000..8cc73e6
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/TableSeparator.php
@@ -0,0 +1,28 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+/**
+ * Marks a row as being a separator.
+ *
+ * @author Fabien Potencier
+ */
+class TableSeparator extends TableCell
+{
+ /**
+ * @param array $options
+ */
+ public function __construct(array $options = array())
+ {
+ parent::__construct('', $options);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Helper/TableStyle.php b/includes/src/vendor/symfony/console/Helper/TableStyle.php
new file mode 100644
index 0000000..d7e28ff
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Helper/TableStyle.php
@@ -0,0 +1,258 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Helper;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Defines the styles for a Table.
+ *
+ * @author Fabien Potencier
+ * @author Саша Стаменковић
+ */
+class TableStyle
+{
+ private $paddingChar = ' ';
+ private $horizontalBorderChar = '-';
+ private $verticalBorderChar = '|';
+ private $crossingChar = '+';
+ private $cellHeaderFormat = '%s';
+ private $cellRowFormat = '%s';
+ private $cellRowContentFormat = ' %s ';
+ private $borderFormat = '%s';
+ private $padType = STR_PAD_RIGHT;
+
+ /**
+ * Sets padding character, used for cell padding.
+ *
+ * @param string $paddingChar
+ *
+ * @return TableStyle
+ */
+ public function setPaddingChar($paddingChar)
+ {
+ if (!$paddingChar) {
+ throw new LogicException('The padding char must not be empty');
+ }
+
+ $this->paddingChar = $paddingChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets padding character, used for cell padding.
+ *
+ * @return string
+ */
+ public function getPaddingChar()
+ {
+ return $this->paddingChar;
+ }
+
+ /**
+ * Sets horizontal border character.
+ *
+ * @param string $horizontalBorderChar
+ *
+ * @return TableStyle
+ */
+ public function setHorizontalBorderChar($horizontalBorderChar)
+ {
+ $this->horizontalBorderChar = $horizontalBorderChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets horizontal border character.
+ *
+ * @return string
+ */
+ public function getHorizontalBorderChar()
+ {
+ return $this->horizontalBorderChar;
+ }
+
+ /**
+ * Sets vertical border character.
+ *
+ * @param string $verticalBorderChar
+ *
+ * @return TableStyle
+ */
+ public function setVerticalBorderChar($verticalBorderChar)
+ {
+ $this->verticalBorderChar = $verticalBorderChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets vertical border character.
+ *
+ * @return string
+ */
+ public function getVerticalBorderChar()
+ {
+ return $this->verticalBorderChar;
+ }
+
+ /**
+ * Sets crossing character.
+ *
+ * @param string $crossingChar
+ *
+ * @return TableStyle
+ */
+ public function setCrossingChar($crossingChar)
+ {
+ $this->crossingChar = $crossingChar;
+
+ return $this;
+ }
+
+ /**
+ * Gets crossing character.
+ *
+ * @return string $crossingChar
+ */
+ public function getCrossingChar()
+ {
+ return $this->crossingChar;
+ }
+
+ /**
+ * Sets header cell format.
+ *
+ * @param string $cellHeaderFormat
+ *
+ * @return TableStyle
+ */
+ public function setCellHeaderFormat($cellHeaderFormat)
+ {
+ $this->cellHeaderFormat = $cellHeaderFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets header cell format.
+ *
+ * @return string
+ */
+ public function getCellHeaderFormat()
+ {
+ return $this->cellHeaderFormat;
+ }
+
+ /**
+ * Sets row cell format.
+ *
+ * @param string $cellRowFormat
+ *
+ * @return TableStyle
+ */
+ public function setCellRowFormat($cellRowFormat)
+ {
+ $this->cellRowFormat = $cellRowFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets row cell format.
+ *
+ * @return string
+ */
+ public function getCellRowFormat()
+ {
+ return $this->cellRowFormat;
+ }
+
+ /**
+ * Sets row cell content format.
+ *
+ * @param string $cellRowContentFormat
+ *
+ * @return TableStyle
+ */
+ public function setCellRowContentFormat($cellRowContentFormat)
+ {
+ $this->cellRowContentFormat = $cellRowContentFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets row cell content format.
+ *
+ * @return string
+ */
+ public function getCellRowContentFormat()
+ {
+ return $this->cellRowContentFormat;
+ }
+
+ /**
+ * Sets table border format.
+ *
+ * @param string $borderFormat
+ *
+ * @return TableStyle
+ */
+ public function setBorderFormat($borderFormat)
+ {
+ $this->borderFormat = $borderFormat;
+
+ return $this;
+ }
+
+ /**
+ * Gets table border format.
+ *
+ * @return string
+ */
+ public function getBorderFormat()
+ {
+ return $this->borderFormat;
+ }
+
+ /**
+ * Sets cell padding type.
+ *
+ * @param int $padType STR_PAD_*
+ *
+ * @return TableStyle
+ */
+ public function setPadType($padType)
+ {
+ if (!in_array($padType, array(STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH), true)) {
+ throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
+ }
+
+ $this->padType = $padType;
+
+ return $this;
+ }
+
+ /**
+ * Gets cell padding type.
+ *
+ * @return int
+ */
+ public function getPadType()
+ {
+ return $this->padType;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/ArgvInput.php b/includes/src/vendor/symfony/console/Input/ArgvInput.php
new file mode 100644
index 0000000..4a0fa91
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/ArgvInput.php
@@ -0,0 +1,339 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\RuntimeException;
+
+/**
+ * ArgvInput represents an input coming from the CLI arguments.
+ *
+ * Usage:
+ *
+ * $input = new ArgvInput();
+ *
+ * By default, the `$_SERVER['argv']` array is used for the input values.
+ *
+ * This can be overridden by explicitly passing the input values in the constructor:
+ *
+ * $input = new ArgvInput($_SERVER['argv']);
+ *
+ * If you pass it yourself, don't forget that the first element of the array
+ * is the name of the running application.
+ *
+ * When passing an argument to the constructor, be sure that it respects
+ * the same rules as the argv one. It's almost always better to use the
+ * `StringInput` when you want to provide your own input.
+ *
+ * @author Fabien Potencier
+ *
+ * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
+ * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
+ */
+class ArgvInput extends Input
+{
+ private $tokens;
+ private $parsed;
+
+ /**
+ * Constructor.
+ *
+ * @param array|null $argv An array of parameters from the CLI (in the argv format)
+ * @param InputDefinition|null $definition A InputDefinition instance
+ */
+ public function __construct(array $argv = null, InputDefinition $definition = null)
+ {
+ if (null === $argv) {
+ $argv = $_SERVER['argv'];
+ }
+
+ // strip the application name
+ array_shift($argv);
+
+ $this->tokens = $argv;
+
+ parent::__construct($definition);
+ }
+
+ protected function setTokens(array $tokens)
+ {
+ $this->tokens = $tokens;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function parse()
+ {
+ $parseOptions = true;
+ $this->parsed = $this->tokens;
+ while (null !== $token = array_shift($this->parsed)) {
+ if ($parseOptions && '' == $token) {
+ $this->parseArgument($token);
+ } elseif ($parseOptions && '--' == $token) {
+ $parseOptions = false;
+ } elseif ($parseOptions && 0 === strpos($token, '--')) {
+ $this->parseLongOption($token);
+ } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
+ $this->parseShortOption($token);
+ } else {
+ $this->parseArgument($token);
+ }
+ }
+ }
+
+ /**
+ * Parses a short option.
+ *
+ * @param string $token The current token
+ */
+ private function parseShortOption($token)
+ {
+ $name = substr($token, 1);
+
+ if (strlen($name) > 1) {
+ if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
+ // an option with a value (with no space)
+ $this->addShortOption($name[0], substr($name, 1));
+ } else {
+ $this->parseShortOptionSet($name);
+ }
+ } else {
+ $this->addShortOption($name, null);
+ }
+ }
+
+ /**
+ * Parses a short option set.
+ *
+ * @param string $name The current token
+ *
+ * @throws RuntimeException When option given doesn't exist
+ */
+ private function parseShortOptionSet($name)
+ {
+ $len = strlen($name);
+ for ($i = 0; $i < $len; ++$i) {
+ if (!$this->definition->hasShortcut($name[$i])) {
+ throw new RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
+ }
+
+ $option = $this->definition->getOptionForShortcut($name[$i]);
+ if ($option->acceptValue()) {
+ $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
+
+ break;
+ } else {
+ $this->addLongOption($option->getName(), null);
+ }
+ }
+ }
+
+ /**
+ * Parses a long option.
+ *
+ * @param string $token The current token
+ */
+ private function parseLongOption($token)
+ {
+ $name = substr($token, 2);
+
+ if (false !== $pos = strpos($name, '=')) {
+ $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
+ } else {
+ $this->addLongOption($name, null);
+ }
+ }
+
+ /**
+ * Parses an argument.
+ *
+ * @param string $token The current token
+ *
+ * @throws RuntimeException When too many arguments are given
+ */
+ private function parseArgument($token)
+ {
+ $c = count($this->arguments);
+
+ // if input is expecting another argument, add it
+ if ($this->definition->hasArgument($c)) {
+ $arg = $this->definition->getArgument($c);
+ $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;
+
+ // if last argument isArray(), append token to last argument
+ } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
+ $arg = $this->definition->getArgument($c - 1);
+ $this->arguments[$arg->getName()][] = $token;
+
+ // unexpected argument
+ } else {
+ throw new RuntimeException('Too many arguments.');
+ }
+ }
+
+ /**
+ * Adds a short option value.
+ *
+ * @param string $shortcut The short option key
+ * @param mixed $value The value for the option
+ *
+ * @throws RuntimeException When option given doesn't exist
+ */
+ private function addShortOption($shortcut, $value)
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+
+ /**
+ * Adds a long option value.
+ *
+ * @param string $name The long option key
+ * @param mixed $value The value for the option
+ *
+ * @throws RuntimeException When option given doesn't exist
+ */
+ private function addLongOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ $option = $this->definition->getOption($name);
+
+ // Convert empty values to null
+ if (!isset($value[0])) {
+ $value = null;
+ }
+
+ if (null !== $value && !$option->acceptValue()) {
+ throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
+ }
+
+ if (null === $value && $option->acceptValue() && count($this->parsed)) {
+ // if option accepts an optional or mandatory argument
+ // let's see if there is one provided
+ $next = array_shift($this->parsed);
+ if (isset($next[0]) && '-' !== $next[0]) {
+ $value = $next;
+ } elseif (empty($next)) {
+ $value = '';
+ } else {
+ array_unshift($this->parsed, $next);
+ }
+ }
+
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
+ }
+
+ if (!$option->isArray()) {
+ $value = $option->isValueOptional() ? $option->getDefault() : true;
+ }
+ }
+
+ if ($option->isArray()) {
+ $this->options[$name][] = $value;
+ } else {
+ $this->options[$name] = $value;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFirstArgument()
+ {
+ foreach ($this->tokens as $token) {
+ if ($token && '-' === $token[0]) {
+ continue;
+ }
+
+ return $token;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasParameterOption($values, $onlyParams = false)
+ {
+ $values = (array) $values;
+
+ foreach ($this->tokens as $token) {
+ if ($onlyParams && $token === '--') {
+ return false;
+ }
+ foreach ($values as $value) {
+ if ($token === $value || 0 === strpos($token, $value.'=')) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParameterOption($values, $default = false, $onlyParams = false)
+ {
+ $values = (array) $values;
+ $tokens = $this->tokens;
+
+ while (0 < count($tokens)) {
+ $token = array_shift($tokens);
+ if ($onlyParams && $token === '--') {
+ return false;
+ }
+
+ foreach ($values as $value) {
+ if ($token === $value || 0 === strpos($token, $value.'=')) {
+ if (false !== $pos = strpos($token, '=')) {
+ return substr($token, $pos + 1);
+ }
+
+ return array_shift($tokens);
+ }
+ }
+ }
+
+ return $default;
+ }
+
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $tokens = array_map(function ($token) {
+ if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
+ return $match[1].$this->escapeToken($match[2]);
+ }
+
+ if ($token && $token[0] !== '-') {
+ return $this->escapeToken($token);
+ }
+
+ return $token;
+ }, $this->tokens);
+
+ return implode(' ', $tokens);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/ArrayInput.php b/includes/src/vendor/symfony/console/Input/ArrayInput.php
new file mode 100644
index 0000000..a44b6b2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/ArrayInput.php
@@ -0,0 +1,204 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\InvalidOptionException;
+
+/**
+ * ArrayInput represents an input provided as an array.
+ *
+ * Usage:
+ *
+ * $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
+ *
+ * @author Fabien Potencier
+ */
+class ArrayInput extends Input
+{
+ private $parameters;
+
+ /**
+ * Constructor.
+ *
+ * @param array $parameters An array of parameters
+ * @param InputDefinition|null $definition A InputDefinition instance
+ */
+ public function __construct(array $parameters, InputDefinition $definition = null)
+ {
+ $this->parameters = $parameters;
+
+ parent::__construct($definition);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFirstArgument()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if ($key && '-' === $key[0]) {
+ continue;
+ }
+
+ return $value;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasParameterOption($values, $onlyParams = false)
+ {
+ $values = (array) $values;
+
+ foreach ($this->parameters as $k => $v) {
+ if (!is_int($k)) {
+ $v = $k;
+ }
+
+ if ($onlyParams && $v === '--') {
+ return false;
+ }
+
+ if (in_array($v, $values)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParameterOption($values, $default = false, $onlyParams = false)
+ {
+ $values = (array) $values;
+
+ foreach ($this->parameters as $k => $v) {
+ if ($onlyParams && ($k === '--' || (is_int($k) && $v === '--'))) {
+ return false;
+ }
+
+ if (is_int($k)) {
+ if (in_array($v, $values)) {
+ return true;
+ }
+ } elseif (in_array($k, $values)) {
+ return $v;
+ }
+ }
+
+ return $default;
+ }
+
+ /**
+ * Returns a stringified representation of the args passed to the command.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $params = array();
+ foreach ($this->parameters as $param => $val) {
+ if ($param && '-' === $param[0]) {
+ $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : '');
+ } else {
+ $params[] = $this->escapeToken($val);
+ }
+ }
+
+ return implode(' ', $params);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function parse()
+ {
+ foreach ($this->parameters as $key => $value) {
+ if ($key === '--') {
+ return;
+ }
+ if (0 === strpos($key, '--')) {
+ $this->addLongOption(substr($key, 2), $value);
+ } elseif ('-' === $key[0]) {
+ $this->addShortOption(substr($key, 1), $value);
+ } else {
+ $this->addArgument($key, $value);
+ }
+ }
+ }
+
+ /**
+ * Adds a short option value.
+ *
+ * @param string $shortcut The short option key
+ * @param mixed $value The value for the option
+ *
+ * @throws InvalidOptionException When option given doesn't exist
+ */
+ private function addShortOption($shortcut, $value)
+ {
+ if (!$this->definition->hasShortcut($shortcut)) {
+ throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
+ }
+
+ /**
+ * Adds a long option value.
+ *
+ * @param string $name The long option key
+ * @param mixed $value The value for the option
+ *
+ * @throws InvalidOptionException When option given doesn't exist
+ * @throws InvalidOptionException When a required value is missing
+ */
+ private function addLongOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ $option = $this->definition->getOption($name);
+
+ if (null === $value) {
+ if ($option->isValueRequired()) {
+ throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name));
+ }
+
+ $value = $option->isValueOptional() ? $option->getDefault() : true;
+ }
+
+ $this->options[$name] = $value;
+ }
+
+ /**
+ * Adds an argument value.
+ *
+ * @param string $name The argument name
+ * @param mixed $value The value for the argument
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ */
+ private function addArgument($name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $this->arguments[$name] = $value;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/Input.php b/includes/src/vendor/symfony/console/Input/Input.php
new file mode 100644
index 0000000..817292e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/Input.php
@@ -0,0 +1,194 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+
+/**
+ * Input is the base class for all concrete Input classes.
+ *
+ * Three concrete classes are provided by default:
+ *
+ * * `ArgvInput`: The input comes from the CLI arguments (argv)
+ * * `StringInput`: The input is provided as a string
+ * * `ArrayInput`: The input is provided as an array
+ *
+ * @author Fabien Potencier
+ */
+abstract class Input implements InputInterface
+{
+ /**
+ * @var InputDefinition
+ */
+ protected $definition;
+ protected $options = array();
+ protected $arguments = array();
+ protected $interactive = true;
+
+ /**
+ * Constructor.
+ *
+ * @param InputDefinition|null $definition A InputDefinition instance
+ */
+ public function __construct(InputDefinition $definition = null)
+ {
+ if (null === $definition) {
+ $this->definition = new InputDefinition();
+ } else {
+ $this->bind($definition);
+ $this->validate();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function bind(InputDefinition $definition)
+ {
+ $this->arguments = array();
+ $this->options = array();
+ $this->definition = $definition;
+
+ $this->parse();
+ }
+
+ /**
+ * Processes command line arguments.
+ */
+ abstract protected function parse();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validate()
+ {
+ $definition = $this->definition;
+ $givenArguments = $this->arguments;
+
+ $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {
+ return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
+ });
+
+ if (count($missingArguments) > 0) {
+ throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isInteractive()
+ {
+ return $this->interactive;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setInteractive($interactive)
+ {
+ $this->interactive = (bool) $interactive;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getArguments()
+ {
+ return array_merge($this->definition->getArgumentDefaults(), $this->arguments);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getArgument($name)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setArgument($name, $value)
+ {
+ if (!$this->definition->hasArgument($name)) {
+ throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $this->arguments[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasArgument($name)
+ {
+ return $this->definition->hasArgument($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOptions()
+ {
+ return array_merge($this->definition->getOptionDefaults(), $this->options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOption($name)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+ }
+
+ return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setOption($name, $value)
+ {
+ if (!$this->definition->hasOption($name)) {
+ throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));
+ }
+
+ $this->options[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasOption($name)
+ {
+ return $this->definition->hasOption($name);
+ }
+
+ /**
+ * Escapes a token through escapeshellarg if it contains unsafe chars.
+ *
+ * @param string $token
+ *
+ * @return string
+ */
+ public function escapeToken($token)
+ {
+ return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/InputArgument.php b/includes/src/vendor/symfony/console/Input/InputArgument.php
new file mode 100644
index 0000000..048ee4f
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/InputArgument.php
@@ -0,0 +1,131 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Represents a command line argument.
+ *
+ * @author Fabien Potencier
+ */
+class InputArgument
+{
+ const REQUIRED = 1;
+ const OPTIONAL = 2;
+ const IS_ARRAY = 4;
+
+ private $name;
+ private $mode;
+ private $default;
+ private $description;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The argument name
+ * @param int $mode The argument mode: self::REQUIRED or self::OPTIONAL
+ * @param string $description A description text
+ * @param mixed $default The default value (for self::OPTIONAL mode only)
+ *
+ * @throws InvalidArgumentException When argument mode is not valid
+ */
+ public function __construct($name, $mode = null, $description = '', $default = null)
+ {
+ if (null === $mode) {
+ $mode = self::OPTIONAL;
+ } elseif (!is_int($mode) || $mode > 7 || $mode < 1) {
+ throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode));
+ }
+
+ $this->name = $name;
+ $this->mode = $mode;
+ $this->description = $description;
+
+ $this->setDefault($default);
+ }
+
+ /**
+ * Returns the argument name.
+ *
+ * @return string The argument name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns true if the argument is required.
+ *
+ * @return bool true if parameter mode is self::REQUIRED, false otherwise
+ */
+ public function isRequired()
+ {
+ return self::REQUIRED === (self::REQUIRED & $this->mode);
+ }
+
+ /**
+ * Returns true if the argument can take multiple values.
+ *
+ * @return bool true if mode is self::IS_ARRAY, false otherwise
+ */
+ public function isArray()
+ {
+ return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $default The default value
+ *
+ * @throws LogicException When incorrect default value is given
+ */
+ public function setDefault($default = null)
+ {
+ if (self::REQUIRED === $this->mode && null !== $default) {
+ throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
+ }
+
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = array();
+ } elseif (!is_array($default)) {
+ throw new LogicException('A default value for an array argument must be an array.');
+ }
+ }
+
+ $this->default = $default;
+ }
+
+ /**
+ * Returns the default value.
+ *
+ * @return mixed The default value
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns the description text.
+ *
+ * @return string The description text
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/InputAwareInterface.php b/includes/src/vendor/symfony/console/Input/InputAwareInterface.php
new file mode 100644
index 0000000..d0f11e9
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/InputAwareInterface.php
@@ -0,0 +1,28 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+/**
+ * InputAwareInterface should be implemented by classes that depends on the
+ * Console Input.
+ *
+ * @author Wouter J
+ */
+interface InputAwareInterface
+{
+ /**
+ * Sets the Console Input.
+ *
+ * @param InputInterface
+ */
+ public function setInput(InputInterface $input);
+}
diff --git a/includes/src/vendor/symfony/console/Input/InputDefinition.php b/includes/src/vendor/symfony/console/Input/InputDefinition.php
new file mode 100644
index 0000000..e9944db
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/InputDefinition.php
@@ -0,0 +1,411 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * A InputDefinition represents a set of valid command line arguments and options.
+ *
+ * Usage:
+ *
+ * $definition = new InputDefinition(array(
+ * new InputArgument('name', InputArgument::REQUIRED),
+ * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
+ * ));
+ *
+ * @author Fabien Potencier
+ */
+class InputDefinition
+{
+ private $arguments;
+ private $requiredCount;
+ private $hasAnArrayArgument = false;
+ private $hasOptional;
+ private $options;
+ private $shortcuts;
+
+ /**
+ * Constructor.
+ *
+ * @param array $definition An array of InputArgument and InputOption instance
+ */
+ public function __construct(array $definition = array())
+ {
+ $this->setDefinition($definition);
+ }
+
+ /**
+ * Sets the definition of the input.
+ *
+ * @param array $definition The definition array
+ */
+ public function setDefinition(array $definition)
+ {
+ $arguments = array();
+ $options = array();
+ foreach ($definition as $item) {
+ if ($item instanceof InputOption) {
+ $options[] = $item;
+ } else {
+ $arguments[] = $item;
+ }
+ }
+
+ $this->setArguments($arguments);
+ $this->setOptions($options);
+ }
+
+ /**
+ * Sets the InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ */
+ public function setArguments($arguments = array())
+ {
+ $this->arguments = array();
+ $this->requiredCount = 0;
+ $this->hasOptional = false;
+ $this->hasAnArrayArgument = false;
+ $this->addArguments($arguments);
+ }
+
+ /**
+ * Adds an array of InputArgument objects.
+ *
+ * @param InputArgument[] $arguments An array of InputArgument objects
+ */
+ public function addArguments($arguments = array())
+ {
+ if (null !== $arguments) {
+ foreach ($arguments as $argument) {
+ $this->addArgument($argument);
+ }
+ }
+ }
+
+ /**
+ * Adds an InputArgument object.
+ *
+ * @param InputArgument $argument An InputArgument object
+ *
+ * @throws LogicException When incorrect argument is given
+ */
+ public function addArgument(InputArgument $argument)
+ {
+ if (isset($this->arguments[$argument->getName()])) {
+ throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName()));
+ }
+
+ if ($this->hasAnArrayArgument) {
+ throw new LogicException('Cannot add an argument after an array argument.');
+ }
+
+ if ($argument->isRequired() && $this->hasOptional) {
+ throw new LogicException('Cannot add a required argument after an optional one.');
+ }
+
+ if ($argument->isArray()) {
+ $this->hasAnArrayArgument = true;
+ }
+
+ if ($argument->isRequired()) {
+ ++$this->requiredCount;
+ } else {
+ $this->hasOptional = true;
+ }
+
+ $this->arguments[$argument->getName()] = $argument;
+ }
+
+ /**
+ * Returns an InputArgument by name or by position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return InputArgument An InputArgument object
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ */
+ public function getArgument($name)
+ {
+ if (!$this->hasArgument($name)) {
+ throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));
+ }
+
+ $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+ return $arguments[$name];
+ }
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return bool true if the InputArgument object exists, false otherwise
+ */
+ public function hasArgument($name)
+ {
+ $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;
+
+ return isset($arguments[$name]);
+ }
+
+ /**
+ * Gets the array of InputArgument objects.
+ *
+ * @return InputArgument[] An array of InputArgument objects
+ */
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ /**
+ * Returns the number of InputArguments.
+ *
+ * @return int The number of InputArguments
+ */
+ public function getArgumentCount()
+ {
+ return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);
+ }
+
+ /**
+ * Returns the number of required InputArguments.
+ *
+ * @return int The number of required InputArguments
+ */
+ public function getArgumentRequiredCount()
+ {
+ return $this->requiredCount;
+ }
+
+ /**
+ * Gets the default values.
+ *
+ * @return array An array of default values
+ */
+ public function getArgumentDefaults()
+ {
+ $values = array();
+ foreach ($this->arguments as $argument) {
+ $values[$argument->getName()] = $argument->getDefault();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Sets the InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ */
+ public function setOptions($options = array())
+ {
+ $this->options = array();
+ $this->shortcuts = array();
+ $this->addOptions($options);
+ }
+
+ /**
+ * Adds an array of InputOption objects.
+ *
+ * @param InputOption[] $options An array of InputOption objects
+ */
+ public function addOptions($options = array())
+ {
+ foreach ($options as $option) {
+ $this->addOption($option);
+ }
+ }
+
+ /**
+ * Adds an InputOption object.
+ *
+ * @param InputOption $option An InputOption object
+ *
+ * @throws LogicException When option given already exist
+ */
+ public function addOption(InputOption $option)
+ {
+ if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
+ throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName()));
+ }
+
+ if ($option->getShortcut()) {
+ foreach (explode('|', $option->getShortcut()) as $shortcut) {
+ if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
+ throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut));
+ }
+ }
+ }
+
+ $this->options[$option->getName()] = $option;
+ if ($option->getShortcut()) {
+ foreach (explode('|', $option->getShortcut()) as $shortcut) {
+ $this->shortcuts[$shortcut] = $option->getName();
+ }
+ }
+ }
+
+ /**
+ * Returns an InputOption by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return InputOption A InputOption object
+ *
+ * @throws InvalidArgumentException When option given doesn't exist
+ */
+ public function getOption($name)
+ {
+ if (!$this->hasOption($name)) {
+ throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name));
+ }
+
+ return $this->options[$name];
+ }
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ */
+ public function hasOption($name)
+ {
+ return isset($this->options[$name]);
+ }
+
+ /**
+ * Gets the array of InputOption objects.
+ *
+ * @return InputOption[] An array of InputOption objects
+ */
+ public function getOptions()
+ {
+ return $this->options;
+ }
+
+ /**
+ * Returns true if an InputOption object exists by shortcut.
+ *
+ * @param string $name The InputOption shortcut
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ */
+ public function hasShortcut($name)
+ {
+ return isset($this->shortcuts[$name]);
+ }
+
+ /**
+ * Gets an InputOption by shortcut.
+ *
+ * @param string $shortcut the Shortcut name
+ *
+ * @return InputOption An InputOption object
+ */
+ public function getOptionForShortcut($shortcut)
+ {
+ return $this->getOption($this->shortcutToName($shortcut));
+ }
+
+ /**
+ * Gets an array of default values.
+ *
+ * @return array An array of all default values
+ */
+ public function getOptionDefaults()
+ {
+ $values = array();
+ foreach ($this->options as $option) {
+ $values[$option->getName()] = $option->getDefault();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Returns the InputOption name given a shortcut.
+ *
+ * @param string $shortcut The shortcut
+ *
+ * @return string The InputOption name
+ *
+ * @throws InvalidArgumentException When option given does not exist
+ */
+ private function shortcutToName($shortcut)
+ {
+ if (!isset($this->shortcuts[$shortcut])) {
+ throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut));
+ }
+
+ return $this->shortcuts[$shortcut];
+ }
+
+ /**
+ * Gets the synopsis.
+ *
+ * @param bool $short Whether to return the short version (with options folded) or not
+ *
+ * @return string The synopsis
+ */
+ public function getSynopsis($short = false)
+ {
+ $elements = array();
+
+ if ($short && $this->getOptions()) {
+ $elements[] = '[options]';
+ } elseif (!$short) {
+ foreach ($this->getOptions() as $option) {
+ $value = '';
+ if ($option->acceptValue()) {
+ $value = sprintf(
+ ' %s%s%s',
+ $option->isValueOptional() ? '[' : '',
+ strtoupper($option->getName()),
+ $option->isValueOptional() ? ']' : ''
+ );
+ }
+
+ $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';
+ $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);
+ }
+ }
+
+ if (count($elements) && $this->getArguments()) {
+ $elements[] = '[--]';
+ }
+
+ foreach ($this->getArguments() as $argument) {
+ $element = '<'.$argument->getName().'>';
+ if (!$argument->isRequired()) {
+ $element = '['.$element.']';
+ } elseif ($argument->isArray()) {
+ $element = $element.' ('.$element.')';
+ }
+
+ if ($argument->isArray()) {
+ $element .= '...';
+ }
+
+ $elements[] = $element;
+ }
+
+ return implode(' ', $elements);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/InputInterface.php b/includes/src/vendor/symfony/console/Input/InputInterface.php
new file mode 100644
index 0000000..bc66466
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/InputInterface.php
@@ -0,0 +1,159 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+
+/**
+ * InputInterface is the interface implemented by all input classes.
+ *
+ * @author Fabien Potencier
+ */
+interface InputInterface
+{
+ /**
+ * Returns the first argument from the raw parameters (not parsed).
+ *
+ * @return string The value of the first argument or null otherwise
+ */
+ public function getFirstArgument();
+
+ /**
+ * Returns true if the raw parameters (not parsed) contain a value.
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The values to look for in the raw parameters (can be an array)
+ * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
+ *
+ * @return bool true if the value is contained in the raw parameters
+ */
+ public function hasParameterOption($values, $onlyParams = false);
+
+ /**
+ * Returns the value of a raw option (not parsed).
+ *
+ * This method is to be used to introspect the input parameters
+ * before they have been validated. It must be used carefully.
+ *
+ * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
+ * @param mixed $default The default value to return if no result is found
+ * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal
+ *
+ * @return mixed The option value
+ */
+ public function getParameterOption($values, $default = false, $onlyParams = false);
+
+ /**
+ * Binds the current Input instance with the given arguments and options.
+ *
+ * @param InputDefinition $definition A InputDefinition instance
+ */
+ public function bind(InputDefinition $definition);
+
+ /**
+ * Validates the input.
+ *
+ * @throws RuntimeException When not enough arguments are given
+ */
+ public function validate();
+
+ /**
+ * Returns all the given arguments merged with the default values.
+ *
+ * @return array
+ */
+ public function getArguments();
+
+ /**
+ * Returns the argument value for a given argument name.
+ *
+ * @param string $name The argument name
+ *
+ * @return mixed The argument value
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ */
+ public function getArgument($name);
+
+ /**
+ * Sets an argument value by name.
+ *
+ * @param string $name The argument name
+ * @param string $value The argument value
+ *
+ * @throws InvalidArgumentException When argument given doesn't exist
+ */
+ public function setArgument($name, $value);
+
+ /**
+ * Returns true if an InputArgument object exists by name or position.
+ *
+ * @param string|int $name The InputArgument name or position
+ *
+ * @return bool true if the InputArgument object exists, false otherwise
+ */
+ public function hasArgument($name);
+
+ /**
+ * Returns all the given options merged with the default values.
+ *
+ * @return array
+ */
+ public function getOptions();
+
+ /**
+ * Returns the option value for a given option name.
+ *
+ * @param string $name The option name
+ *
+ * @return mixed The option value
+ *
+ * @throws InvalidArgumentException When option given doesn't exist
+ */
+ public function getOption($name);
+
+ /**
+ * Sets an option value by name.
+ *
+ * @param string $name The option name
+ * @param string|bool $value The option value
+ *
+ * @throws InvalidArgumentException When option given doesn't exist
+ */
+ public function setOption($name, $value);
+
+ /**
+ * Returns true if an InputOption object exists by name.
+ *
+ * @param string $name The InputOption name
+ *
+ * @return bool true if the InputOption object exists, false otherwise
+ */
+ public function hasOption($name);
+
+ /**
+ * Is this input means interactive?
+ *
+ * @return bool
+ */
+ public function isInteractive();
+
+ /**
+ * Sets the input interactivity.
+ *
+ * @param bool $interactive If the input should be interactive
+ */
+ public function setInteractive($interactive);
+}
diff --git a/includes/src/vendor/symfony/console/Input/InputOption.php b/includes/src/vendor/symfony/console/Input/InputOption.php
new file mode 100644
index 0000000..f08c5f2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/InputOption.php
@@ -0,0 +1,212 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Represents a command line option.
+ *
+ * @author Fabien Potencier
+ */
+class InputOption
+{
+ const VALUE_NONE = 1;
+ const VALUE_REQUIRED = 2;
+ const VALUE_OPTIONAL = 4;
+ const VALUE_IS_ARRAY = 8;
+
+ private $name;
+ private $shortcut;
+ private $mode;
+ private $default;
+ private $description;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name The option name
+ * @param string|array $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
+ * @param int $mode The option mode: One of the VALUE_* constants
+ * @param string $description A description text
+ * @param mixed $default The default value (must be null for self::VALUE_NONE)
+ *
+ * @throws InvalidArgumentException If option mode is invalid or incompatible
+ */
+ public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
+ {
+ if (0 === strpos($name, '--')) {
+ $name = substr($name, 2);
+ }
+
+ if (empty($name)) {
+ throw new InvalidArgumentException('An option name cannot be empty.');
+ }
+
+ if (empty($shortcut)) {
+ $shortcut = null;
+ }
+
+ if (null !== $shortcut) {
+ if (is_array($shortcut)) {
+ $shortcut = implode('|', $shortcut);
+ }
+ $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-'));
+ $shortcuts = array_filter($shortcuts);
+ $shortcut = implode('|', $shortcuts);
+
+ if (empty($shortcut)) {
+ throw new InvalidArgumentException('An option shortcut cannot be empty.');
+ }
+ }
+
+ if (null === $mode) {
+ $mode = self::VALUE_NONE;
+ } elseif (!is_int($mode) || $mode > 15 || $mode < 1) {
+ throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode));
+ }
+
+ $this->name = $name;
+ $this->shortcut = $shortcut;
+ $this->mode = $mode;
+ $this->description = $description;
+
+ if ($this->isArray() && !$this->acceptValue()) {
+ throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
+ }
+
+ $this->setDefault($default);
+ }
+
+ /**
+ * Returns the option shortcut.
+ *
+ * @return string The shortcut
+ */
+ public function getShortcut()
+ {
+ return $this->shortcut;
+ }
+
+ /**
+ * Returns the option name.
+ *
+ * @return string The name
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Returns true if the option accepts a value.
+ *
+ * @return bool true if value mode is not self::VALUE_NONE, false otherwise
+ */
+ public function acceptValue()
+ {
+ return $this->isValueRequired() || $this->isValueOptional();
+ }
+
+ /**
+ * Returns true if the option requires a value.
+ *
+ * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise
+ */
+ public function isValueRequired()
+ {
+ return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
+ }
+
+ /**
+ * Returns true if the option takes an optional value.
+ *
+ * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise
+ */
+ public function isValueOptional()
+ {
+ return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
+ }
+
+ /**
+ * Returns true if the option can take multiple values.
+ *
+ * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise
+ */
+ public function isArray()
+ {
+ return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
+ }
+
+ /**
+ * Sets the default value.
+ *
+ * @param mixed $default The default value
+ *
+ * @throws LogicException When incorrect default value is given
+ */
+ public function setDefault($default = null)
+ {
+ if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
+ throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
+ }
+
+ if ($this->isArray()) {
+ if (null === $default) {
+ $default = array();
+ } elseif (!is_array($default)) {
+ throw new LogicException('A default value for an array option must be an array.');
+ }
+ }
+
+ $this->default = $this->acceptValue() ? $default : false;
+ }
+
+ /**
+ * Returns the default value.
+ *
+ * @return mixed The default value
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns the description text.
+ *
+ * @return string The description text
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Checks whether the given option equals this one.
+ *
+ * @param InputOption $option option to compare
+ *
+ * @return bool
+ */
+ public function equals(InputOption $option)
+ {
+ return $option->getName() === $this->getName()
+ && $option->getShortcut() === $this->getShortcut()
+ && $option->getDefault() === $this->getDefault()
+ && $option->isArray() === $this->isArray()
+ && $option->isValueRequired() === $this->isValueRequired()
+ && $option->isValueOptional() === $this->isValueOptional()
+ ;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Input/StringInput.php b/includes/src/vendor/symfony/console/Input/StringInput.php
new file mode 100644
index 0000000..9ce0217
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Input/StringInput.php
@@ -0,0 +1,74 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Input;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * StringInput represents an input provided as a string.
+ *
+ * Usage:
+ *
+ * $input = new StringInput('foo --bar="foobar"');
+ *
+ * @author Fabien Potencier
+ */
+class StringInput extends ArgvInput
+{
+ const REGEX_STRING = '([^\s]+?)(?:\s|(?setTokens($this->tokenize($input));
+ }
+
+ /**
+ * Tokenizes a string.
+ *
+ * @param string $input The input to tokenize
+ *
+ * @return array An array of tokens
+ *
+ * @throws InvalidArgumentException When unable to parse input (should never happen)
+ */
+ private function tokenize($input)
+ {
+ $tokens = array();
+ $length = strlen($input);
+ $cursor = 0;
+ while ($cursor < $length) {
+ if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
+ } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
+ $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
+ } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
+ $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
+ } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
+ $tokens[] = stripcslashes($match[1]);
+ } else {
+ // should never happen
+ throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
+ }
+
+ $cursor += strlen($match[0]);
+ }
+
+ return $tokens;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/LICENSE b/includes/src/vendor/symfony/console/LICENSE
new file mode 100644
index 0000000..12a7453
--- /dev/null
+++ b/includes/src/vendor/symfony/console/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2016 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/includes/src/vendor/symfony/console/Logger/ConsoleLogger.php b/includes/src/vendor/symfony/console/Logger/ConsoleLogger.php
new file mode 100644
index 0000000..1f7417e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Logger/ConsoleLogger.php
@@ -0,0 +1,119 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Logger;
+
+use Psr\Log\AbstractLogger;
+use Psr\Log\InvalidArgumentException;
+use Psr\Log\LogLevel;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\ConsoleOutputInterface;
+
+/**
+ * PSR-3 compliant console logger.
+ *
+ * @author Kévin Dunglas
+ *
+ * @link http://www.php-fig.org/psr/psr-3/
+ */
+class ConsoleLogger extends AbstractLogger
+{
+ const INFO = 'info';
+ const ERROR = 'error';
+
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+ /**
+ * @var array
+ */
+ private $verbosityLevelMap = array(
+ LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL,
+ LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
+ LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
+ LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG,
+ );
+ /**
+ * @var array
+ */
+ private $formatLevelMap = array(
+ LogLevel::EMERGENCY => self::ERROR,
+ LogLevel::ALERT => self::ERROR,
+ LogLevel::CRITICAL => self::ERROR,
+ LogLevel::ERROR => self::ERROR,
+ LogLevel::WARNING => self::INFO,
+ LogLevel::NOTICE => self::INFO,
+ LogLevel::INFO => self::INFO,
+ LogLevel::DEBUG => self::INFO,
+ );
+
+ /**
+ * @param OutputInterface $output
+ * @param array $verbosityLevelMap
+ * @param array $formatLevelMap
+ */
+ public function __construct(OutputInterface $output, array $verbosityLevelMap = array(), array $formatLevelMap = array())
+ {
+ $this->output = $output;
+ $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
+ $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function log($level, $message, array $context = array())
+ {
+ if (!isset($this->verbosityLevelMap[$level])) {
+ throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level));
+ }
+
+ // Write to the error output if necessary and available
+ if ($this->formatLevelMap[$level] === self::ERROR && $this->output instanceof ConsoleOutputInterface) {
+ $output = $this->output->getErrorOutput();
+ } else {
+ $output = $this->output;
+ }
+
+ if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
+ $output->writeln(sprintf('<%1$s>[%2$s] %3$s%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)));
+ }
+ }
+
+ /**
+ * Interpolates context values into the message placeholders.
+ *
+ * @author PHP Framework Interoperability Group
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return string
+ */
+ private function interpolate($message, array $context)
+ {
+ // build a replacement array with braces around the context keys
+ $replace = array();
+ foreach ($context as $key => $val) {
+ if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
+ $replace[sprintf('{%s}', $key)] = $val;
+ }
+ }
+
+ // interpolate replacement values into the message and return
+ return strtr($message, $replace);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Output/BufferedOutput.php b/includes/src/vendor/symfony/console/Output/BufferedOutput.php
new file mode 100644
index 0000000..5682fc2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/BufferedOutput.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+/**
+ * @author Jean-François Simon
+ */
+class BufferedOutput extends Output
+{
+ /**
+ * @var string
+ */
+ private $buffer = '';
+
+ /**
+ * Empties buffer and returns its content.
+ *
+ * @return string
+ */
+ public function fetch()
+ {
+ $content = $this->buffer;
+ $this->buffer = '';
+
+ return $content;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($message, $newline)
+ {
+ $this->buffer .= $message;
+
+ if ($newline) {
+ $this->buffer .= "\n";
+ }
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Output/ConsoleOutput.php b/includes/src/vendor/symfony/console/Output/ConsoleOutput.php
new file mode 100644
index 0000000..007f3f0
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/ConsoleOutput.php
@@ -0,0 +1,157 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR.
+ *
+ * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR.
+ *
+ * $output = new ConsoleOutput();
+ *
+ * This is equivalent to:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ * $stdErr = new StreamOutput(fopen('php://stderr', 'w'));
+ *
+ * @author Fabien Potencier
+ */
+class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
+{
+ /**
+ * @var StreamOutput
+ */
+ private $stderr;
+
+ /**
+ * Constructor.
+ *
+ * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
+ * @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
+ * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
+ */
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
+
+ $actualDecorated = $this->isDecorated();
+ $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
+
+ if (null === $decorated) {
+ $this->setDecorated($actualDecorated && $this->stderr->isDecorated());
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ parent::setDecorated($decorated);
+ $this->stderr->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ parent::setFormatter($formatter);
+ $this->stderr->setFormatter($formatter);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ parent::setVerbosity($level);
+ $this->stderr->setVerbosity($level);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getErrorOutput()
+ {
+ return $this->stderr;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setErrorOutput(OutputInterface $error)
+ {
+ $this->stderr = $error;
+ }
+
+ /**
+ * Returns true if current environment supports writing console output to
+ * STDOUT.
+ *
+ * @return bool
+ */
+ protected function hasStdoutSupport()
+ {
+ return false === $this->isRunningOS400();
+ }
+
+ /**
+ * Returns true if current environment supports writing console output to
+ * STDERR.
+ *
+ * @return bool
+ */
+ protected function hasStderrSupport()
+ {
+ return false === $this->isRunningOS400();
+ }
+
+ /**
+ * Checks if current executing environment is IBM iSeries (OS400), which
+ * doesn't properly convert character-encodings between ASCII to EBCDIC.
+ *
+ * @return bool
+ */
+ private function isRunningOS400()
+ {
+ $checks = array(
+ function_exists('php_uname') ? php_uname('s') : '',
+ getenv('OSTYPE'),
+ PHP_OS,
+ );
+
+ return false !== stripos(implode(';', $checks), 'OS400');
+ }
+
+ /**
+ * @return resource
+ */
+ private function openOutputStream()
+ {
+ if (!$this->hasStdoutSupport()) {
+ return fopen('php://output', 'w');
+ }
+
+ return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w');
+ }
+
+ /**
+ * @return resource
+ */
+ private function openErrorStream()
+ {
+ return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Output/ConsoleOutputInterface.php b/includes/src/vendor/symfony/console/Output/ConsoleOutputInterface.php
new file mode 100644
index 0000000..5eb4fc7
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/ConsoleOutputInterface.php
@@ -0,0 +1,35 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+/**
+ * ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
+ * This adds information about stderr output stream.
+ *
+ * @author Dariusz Górecki
+ */
+interface ConsoleOutputInterface extends OutputInterface
+{
+ /**
+ * Gets the OutputInterface for errors.
+ *
+ * @return OutputInterface
+ */
+ public function getErrorOutput();
+
+ /**
+ * Sets the OutputInterface used for errors.
+ *
+ * @param OutputInterface $error
+ */
+ public function setErrorOutput(OutputInterface $error);
+}
diff --git a/includes/src/vendor/symfony/console/Output/NullOutput.php b/includes/src/vendor/symfony/console/Output/NullOutput.php
new file mode 100644
index 0000000..218f285
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/NullOutput.php
@@ -0,0 +1,123 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * NullOutput suppresses all output.
+ *
+ * $output = new NullOutput();
+ *
+ * @author Fabien Potencier
+ * @author Tobias Schultze
+ */
+class NullOutput implements OutputInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormatter()
+ {
+ // to comply with the interface we must return a OutputFormatterInterface
+ return new OutputFormatter();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDecorated()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVerbosity()
+ {
+ return self::VERBOSITY_QUIET;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isQuiet()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isVerbose()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isVeryVerbose()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDebug()
+ {
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeln($messages, $options = self::OUTPUT_NORMAL)
+ {
+ // do nothing
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
+ {
+ // do nothing
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Output/Output.php b/includes/src/vendor/symfony/console/Output/Output.php
new file mode 100644
index 0000000..c12015c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/Output.php
@@ -0,0 +1,177 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+
+/**
+ * Base class for output classes.
+ *
+ * There are five levels of verbosity:
+ *
+ * * normal: no option passed (normal output)
+ * * verbose: -v (more output)
+ * * very verbose: -vv (highly extended output)
+ * * debug: -vvv (all debug output)
+ * * quiet: -q (no output)
+ *
+ * @author Fabien Potencier
+ */
+abstract class Output implements OutputInterface
+{
+ private $verbosity;
+ private $formatter;
+
+ /**
+ * Constructor.
+ *
+ * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
+ * @param bool $decorated Whether to decorate messages
+ * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
+ */
+ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = false, OutputFormatterInterface $formatter = null)
+ {
+ $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity;
+ $this->formatter = $formatter ?: new OutputFormatter();
+ $this->formatter->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ $this->formatter = $formatter;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormatter()
+ {
+ return $this->formatter;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ $this->formatter->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDecorated()
+ {
+ return $this->formatter->isDecorated();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ $this->verbosity = (int) $level;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVerbosity()
+ {
+ return $this->verbosity;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isQuiet()
+ {
+ return self::VERBOSITY_QUIET === $this->verbosity;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isVerbose()
+ {
+ return self::VERBOSITY_VERBOSE <= $this->verbosity;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isVeryVerbose()
+ {
+ return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDebug()
+ {
+ return self::VERBOSITY_DEBUG <= $this->verbosity;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeln($messages, $options = self::OUTPUT_NORMAL)
+ {
+ $this->write($messages, true, $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL)
+ {
+ $messages = (array) $messages;
+
+ $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
+ $type = $types & $options ?: self::OUTPUT_NORMAL;
+
+ $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
+ $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;
+
+ if ($verbosity > $this->getVerbosity()) {
+ return;
+ }
+
+ foreach ($messages as $message) {
+ switch ($type) {
+ case OutputInterface::OUTPUT_NORMAL:
+ $message = $this->formatter->format($message);
+ break;
+ case OutputInterface::OUTPUT_RAW:
+ break;
+ case OutputInterface::OUTPUT_PLAIN:
+ $message = strip_tags($this->formatter->format($message));
+ break;
+ }
+
+ $this->doWrite($message, $newline);
+ }
+ }
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string $message A message to write to the output
+ * @param bool $newline Whether to add a newline or not
+ */
+ abstract protected function doWrite($message, $newline);
+}
diff --git a/includes/src/vendor/symfony/console/Output/OutputInterface.php b/includes/src/vendor/symfony/console/Output/OutputInterface.php
new file mode 100644
index 0000000..a291ca7
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/OutputInterface.php
@@ -0,0 +1,119 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * OutputInterface is the interface implemented by all Output classes.
+ *
+ * @author Fabien Potencier
+ */
+interface OutputInterface
+{
+ const VERBOSITY_QUIET = 16;
+ const VERBOSITY_NORMAL = 32;
+ const VERBOSITY_VERBOSE = 64;
+ const VERBOSITY_VERY_VERBOSE = 128;
+ const VERBOSITY_DEBUG = 256;
+
+ const OUTPUT_NORMAL = 1;
+ const OUTPUT_RAW = 2;
+ const OUTPUT_PLAIN = 4;
+
+ /**
+ * Writes a message to the output.
+ *
+ * @param string|array $messages The message as an array of lines or a single string
+ * @param bool $newline Whether to add a newline
+ * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
+ */
+ public function write($messages, $newline = false, $options = 0);
+
+ /**
+ * Writes a message to the output and adds a newline at the end.
+ *
+ * @param string|array $messages The message as an array of lines of a single string
+ * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
+ */
+ public function writeln($messages, $options = 0);
+
+ /**
+ * Sets the verbosity of the output.
+ *
+ * @param int $level The level of verbosity (one of the VERBOSITY constants)
+ */
+ public function setVerbosity($level);
+
+ /**
+ * Gets the current verbosity of the output.
+ *
+ * @return int The current level of verbosity (one of the VERBOSITY constants)
+ */
+ public function getVerbosity();
+
+ /**
+ * Returns whether verbosity is quiet (-q).
+ *
+ * @return bool true if verbosity is set to VERBOSITY_QUIET, false otherwise
+ */
+ public function isQuiet();
+
+ /**
+ * Returns whether verbosity is verbose (-v).
+ *
+ * @return bool true if verbosity is set to VERBOSITY_VERBOSE, false otherwise
+ */
+ public function isVerbose();
+
+ /**
+ * Returns whether verbosity is very verbose (-vv).
+ *
+ * @return bool true if verbosity is set to VERBOSITY_VERY_VERBOSE, false otherwise
+ */
+ public function isVeryVerbose();
+
+ /**
+ * Returns whether verbosity is debug (-vvv).
+ *
+ * @return bool true if verbosity is set to VERBOSITY_DEBUG, false otherwise
+ */
+ public function isDebug();
+
+ /**
+ * Sets the decorated flag.
+ *
+ * @param bool $decorated Whether to decorate the messages
+ */
+ public function setDecorated($decorated);
+
+ /**
+ * Gets the decorated flag.
+ *
+ * @return bool true if the output will decorate messages, false otherwise
+ */
+ public function isDecorated();
+
+ /**
+ * Sets output formatter.
+ *
+ * @param OutputFormatterInterface $formatter
+ */
+ public function setFormatter(OutputFormatterInterface $formatter);
+
+ /**
+ * Returns current output formatter instance.
+ *
+ * @return OutputFormatterInterface
+ */
+ public function getFormatter();
+}
diff --git a/includes/src/vendor/symfony/console/Output/StreamOutput.php b/includes/src/vendor/symfony/console/Output/StreamOutput.php
new file mode 100644
index 0000000..9e6b748
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Output/StreamOutput.php
@@ -0,0 +1,105 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Output;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+
+/**
+ * StreamOutput writes the output to a given stream.
+ *
+ * Usage:
+ *
+ * $output = new StreamOutput(fopen('php://stdout', 'w'));
+ *
+ * As `StreamOutput` can use any stream, you can also use a file:
+ *
+ * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
+ *
+ * @author Fabien Potencier
+ */
+class StreamOutput extends Output
+{
+ private $stream;
+
+ /**
+ * Constructor.
+ *
+ * @param resource $stream A stream resource
+ * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
+ * @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
+ * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
+ *
+ * @throws InvalidArgumentException When first argument is not a real stream
+ */
+ public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null, OutputFormatterInterface $formatter = null)
+ {
+ if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) {
+ throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
+ }
+
+ $this->stream = $stream;
+
+ if (null === $decorated) {
+ $decorated = $this->hasColorSupport();
+ }
+
+ parent::__construct($verbosity, $decorated, $formatter);
+ }
+
+ /**
+ * Gets the stream attached to this StreamOutput instance.
+ *
+ * @return resource A stream resource
+ */
+ public function getStream()
+ {
+ return $this->stream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function doWrite($message, $newline)
+ {
+ if (false === @fwrite($this->stream, $message) || ($newline && (false === @fwrite($this->stream, PHP_EOL)))) {
+ // should never happen
+ throw new RuntimeException('Unable to write output.');
+ }
+
+ fflush($this->stream);
+ }
+
+ /**
+ * Returns true if the stream supports colorization.
+ *
+ * Colorization is disabled if not supported by the stream:
+ *
+ * - Windows before 10.0.10586 without Ansicon, ConEmu or Mintty
+ * - non tty consoles
+ *
+ * @return bool true if the stream supports colorization, false otherwise
+ */
+ protected function hasColorSupport()
+ {
+ if (DIRECTORY_SEPARATOR === '\\') {
+ return
+ 0 >= version_compare('10.0.10586', PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD)
+ || false !== getenv('ANSICON')
+ || 'ON' === getenv('ConEmuANSI')
+ || 'xterm' === getenv('TERM');
+ }
+
+ return function_exists('posix_isatty') && @posix_isatty($this->stream);
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Question/ChoiceQuestion.php b/includes/src/vendor/symfony/console/Question/ChoiceQuestion.php
new file mode 100644
index 0000000..39c4a85
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Question/ChoiceQuestion.php
@@ -0,0 +1,187 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+
+/**
+ * Represents a choice question.
+ *
+ * @author Fabien Potencier
+ */
+class ChoiceQuestion extends Question
+{
+ private $choices;
+ private $multiselect = false;
+ private $prompt = ' > ';
+ private $errorMessage = 'Value "%s" is invalid';
+
+ /**
+ * Constructor.
+ *
+ * @param string $question The question to ask to the user
+ * @param array $choices The list of available choices
+ * @param mixed $default The default answer to return
+ */
+ public function __construct($question, array $choices, $default = null)
+ {
+ parent::__construct($question, $default);
+
+ $this->choices = $choices;
+ $this->setValidator($this->getDefaultValidator());
+ $this->setAutocompleterValues($choices);
+ }
+
+ /**
+ * Returns available choices.
+ *
+ * @return array
+ */
+ public function getChoices()
+ {
+ return $this->choices;
+ }
+
+ /**
+ * Sets multiselect option.
+ *
+ * When multiselect is set to true, multiple choices can be answered.
+ *
+ * @param bool $multiselect
+ *
+ * @return ChoiceQuestion The current instance
+ */
+ public function setMultiselect($multiselect)
+ {
+ $this->multiselect = $multiselect;
+ $this->setValidator($this->getDefaultValidator());
+
+ return $this;
+ }
+
+ /**
+ * Returns whether the choices are multiselect.
+ *
+ * @return bool
+ */
+ public function isMultiselect()
+ {
+ return $this->multiselect;
+ }
+
+ /**
+ * Gets the prompt for choices.
+ *
+ * @return string
+ */
+ public function getPrompt()
+ {
+ return $this->prompt;
+ }
+
+ /**
+ * Sets the prompt for choices.
+ *
+ * @param string $prompt
+ *
+ * @return ChoiceQuestion The current instance
+ */
+ public function setPrompt($prompt)
+ {
+ $this->prompt = $prompt;
+
+ return $this;
+ }
+
+ /**
+ * Sets the error message for invalid values.
+ *
+ * The error message has a string placeholder (%s) for the invalid value.
+ *
+ * @param string $errorMessage
+ *
+ * @return ChoiceQuestion The current instance
+ */
+ public function setErrorMessage($errorMessage)
+ {
+ $this->errorMessage = $errorMessage;
+ $this->setValidator($this->getDefaultValidator());
+
+ return $this;
+ }
+
+ /**
+ * Returns the default answer validator.
+ *
+ * @return callable
+ */
+ private function getDefaultValidator()
+ {
+ $choices = $this->choices;
+ $errorMessage = $this->errorMessage;
+ $multiselect = $this->multiselect;
+ $isAssoc = $this->isAssoc($choices);
+
+ return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
+ // Collapse all spaces.
+ $selectedChoices = str_replace(' ', '', $selected);
+
+ if ($multiselect) {
+ // Check for a separated comma values
+ if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
+ throw new InvalidArgumentException(sprintf($errorMessage, $selected));
+ }
+ $selectedChoices = explode(',', $selectedChoices);
+ } else {
+ $selectedChoices = array($selected);
+ }
+
+ $multiselectChoices = array();
+ foreach ($selectedChoices as $value) {
+ $results = array();
+ foreach ($choices as $key => $choice) {
+ if ($choice === $value) {
+ $results[] = $key;
+ }
+ }
+
+ if (count($results) > 1) {
+ throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
+ }
+
+ $result = array_search($value, $choices);
+
+ if (!$isAssoc) {
+ if (false !== $result) {
+ $result = $choices[$result];
+ } elseif (isset($choices[$value])) {
+ $result = $choices[$value];
+ }
+ } elseif (false === $result && isset($choices[$value])) {
+ $result = $value;
+ }
+
+ if (false === $result) {
+ throw new InvalidArgumentException(sprintf($errorMessage, $value));
+ }
+
+ $multiselectChoices[] = (string) $result;
+ }
+
+ if ($multiselect) {
+ return $multiselectChoices;
+ }
+
+ return current($multiselectChoices);
+ };
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Question/ConfirmationQuestion.php b/includes/src/vendor/symfony/console/Question/ConfirmationQuestion.php
new file mode 100644
index 0000000..29d9887
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Question/ConfirmationQuestion.php
@@ -0,0 +1,61 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+/**
+ * Represents a yes/no question.
+ *
+ * @author Fabien Potencier
+ */
+class ConfirmationQuestion extends Question
+{
+ private $trueAnswerRegex;
+
+ /**
+ * Constructor.
+ *
+ * @param string $question The question to ask to the user
+ * @param bool $default The default answer to return, true or false
+ * @param string $trueAnswerRegex A regex to match the "yes" answer
+ */
+ public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')
+ {
+ parent::__construct($question, (bool) $default);
+
+ $this->trueAnswerRegex = $trueAnswerRegex;
+ $this->setNormalizer($this->getDefaultNormalizer());
+ }
+
+ /**
+ * Returns the default answer normalizer.
+ *
+ * @return callable
+ */
+ private function getDefaultNormalizer()
+ {
+ $default = $this->getDefault();
+ $regex = $this->trueAnswerRegex;
+
+ return function ($answer) use ($default, $regex) {
+ if (is_bool($answer)) {
+ return $answer;
+ }
+
+ $answerIsTrue = (bool) preg_match($regex, $answer);
+ if (false === $default) {
+ return $answer && $answerIsTrue;
+ }
+
+ return !$answer || $answerIsTrue;
+ };
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Question/Question.php b/includes/src/vendor/symfony/console/Question/Question.php
new file mode 100644
index 0000000..7a69279
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Question/Question.php
@@ -0,0 +1,250 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Question;
+
+use Symfony\Component\Console\Exception\InvalidArgumentException;
+use Symfony\Component\Console\Exception\LogicException;
+
+/**
+ * Represents a Question.
+ *
+ * @author Fabien Potencier
+ */
+class Question
+{
+ private $question;
+ private $attempts;
+ private $hidden = false;
+ private $hiddenFallback = true;
+ private $autocompleterValues;
+ private $validator;
+ private $default;
+ private $normalizer;
+
+ /**
+ * Constructor.
+ *
+ * @param string $question The question to ask to the user
+ * @param mixed $default The default answer to return if the user enters nothing
+ */
+ public function __construct($question, $default = null)
+ {
+ $this->question = $question;
+ $this->default = $default;
+ }
+
+ /**
+ * Returns the question.
+ *
+ * @return string
+ */
+ public function getQuestion()
+ {
+ return $this->question;
+ }
+
+ /**
+ * Returns the default answer.
+ *
+ * @return mixed
+ */
+ public function getDefault()
+ {
+ return $this->default;
+ }
+
+ /**
+ * Returns whether the user response must be hidden.
+ *
+ * @return bool
+ */
+ public function isHidden()
+ {
+ return $this->hidden;
+ }
+
+ /**
+ * Sets whether the user response must be hidden or not.
+ *
+ * @param bool $hidden
+ *
+ * @return Question The current instance
+ *
+ * @throws LogicException In case the autocompleter is also used
+ */
+ public function setHidden($hidden)
+ {
+ if ($this->autocompleterValues) {
+ throw new LogicException('A hidden question cannot use the autocompleter.');
+ }
+
+ $this->hidden = (bool) $hidden;
+
+ return $this;
+ }
+
+ /**
+ * In case the response can not be hidden, whether to fallback on non-hidden question or not.
+ *
+ * @return bool
+ */
+ public function isHiddenFallback()
+ {
+ return $this->hiddenFallback;
+ }
+
+ /**
+ * Sets whether to fallback on non-hidden question if the response can not be hidden.
+ *
+ * @param bool $fallback
+ *
+ * @return Question The current instance
+ */
+ public function setHiddenFallback($fallback)
+ {
+ $this->hiddenFallback = (bool) $fallback;
+
+ return $this;
+ }
+
+ /**
+ * Gets values for the autocompleter.
+ *
+ * @return null|array|\Traversable
+ */
+ public function getAutocompleterValues()
+ {
+ return $this->autocompleterValues;
+ }
+
+ /**
+ * Sets values for the autocompleter.
+ *
+ * @param null|array|\Traversable $values
+ *
+ * @return Question The current instance
+ *
+ * @throws InvalidArgumentException
+ * @throws LogicException
+ */
+ public function setAutocompleterValues($values)
+ {
+ if (is_array($values)) {
+ $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values);
+ }
+
+ if (null !== $values && !is_array($values)) {
+ if (!$values instanceof \Traversable || !$values instanceof \Countable) {
+ throw new InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');
+ }
+ }
+
+ if ($this->hidden) {
+ throw new LogicException('A hidden question cannot use the autocompleter.');
+ }
+
+ $this->autocompleterValues = $values;
+
+ return $this;
+ }
+
+ /**
+ * Sets a validator for the question.
+ *
+ * @param null|callable $validator
+ *
+ * @return Question The current instance
+ */
+ public function setValidator(callable $validator = null)
+ {
+ $this->validator = $validator;
+
+ return $this;
+ }
+
+ /**
+ * Gets the validator for the question.
+ *
+ * @return null|callable
+ */
+ public function getValidator()
+ {
+ return $this->validator;
+ }
+
+ /**
+ * Sets the maximum number of attempts.
+ *
+ * Null means an unlimited number of attempts.
+ *
+ * @param null|int $attempts
+ *
+ * @return Question The current instance
+ *
+ * @throws InvalidArgumentException In case the number of attempts is invalid.
+ */
+ public function setMaxAttempts($attempts)
+ {
+ if (null !== $attempts && $attempts < 1) {
+ throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
+ }
+
+ $this->attempts = $attempts;
+
+ return $this;
+ }
+
+ /**
+ * Gets the maximum number of attempts.
+ *
+ * Null means an unlimited number of attempts.
+ *
+ * @return null|int
+ */
+ public function getMaxAttempts()
+ {
+ return $this->attempts;
+ }
+
+ /**
+ * Sets a normalizer for the response.
+ *
+ * The normalizer can be a callable (a string), a closure or a class implementing __invoke.
+ *
+ * @param callable $normalizer
+ *
+ * @return Question The current instance
+ */
+ public function setNormalizer(callable $normalizer)
+ {
+ $this->normalizer = $normalizer;
+
+ return $this;
+ }
+
+ /**
+ * Gets the normalizer for the response.
+ *
+ * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
+ *
+ * @return callable
+ */
+ public function getNormalizer()
+ {
+ return $this->normalizer;
+ }
+
+ protected function isAssoc($array)
+ {
+ return (bool) count(array_filter(array_keys($array), 'is_string'));
+ }
+}
diff --git a/includes/src/vendor/symfony/console/README.md b/includes/src/vendor/symfony/console/README.md
new file mode 100644
index 0000000..664a37c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/README.md
@@ -0,0 +1,20 @@
+Console Component
+=================
+
+The Console component eases the creation of beautiful and testable command line
+interfaces.
+
+Resources
+---------
+
+ * [Documentation](https://symfony.com/doc/current/components/console/index.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
+
+Credits
+-------
+
+`Resources/bin/hiddeninput.exe` is a third party binary provided within this
+component. Find sources and license at https://github.com/Seldaek/hidden-input.
diff --git a/includes/src/vendor/symfony/console/Resources/bin/hiddeninput.exe b/includes/src/vendor/symfony/console/Resources/bin/hiddeninput.exe
new file mode 100644
index 0000000..c8cf65e
Binary files /dev/null and b/includes/src/vendor/symfony/console/Resources/bin/hiddeninput.exe differ
diff --git a/includes/src/vendor/symfony/console/Style/OutputStyle.php b/includes/src/vendor/symfony/console/Style/OutputStyle.php
new file mode 100644
index 0000000..de7be1e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Style/OutputStyle.php
@@ -0,0 +1,148 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Style;
+
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Decorates output to add console style guide helpers.
+ *
+ * @author Kevin Bond
+ */
+abstract class OutputStyle implements OutputInterface, StyleInterface
+{
+ private $output;
+
+ /**
+ * @param OutputInterface $output
+ */
+ public function __construct(OutputInterface $output)
+ {
+ $this->output = $output;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function newLine($count = 1)
+ {
+ $this->output->write(str_repeat(PHP_EOL, $count));
+ }
+
+ /**
+ * @param int $max
+ *
+ * @return ProgressBar
+ */
+ public function createProgressBar($max = 0)
+ {
+ return new ProgressBar($this->output, $max);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
+ {
+ $this->output->write($messages, $newline, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeln($messages, $type = self::OUTPUT_NORMAL)
+ {
+ $this->output->writeln($messages, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setVerbosity($level)
+ {
+ $this->output->setVerbosity($level);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getVerbosity()
+ {
+ return $this->output->getVerbosity();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setDecorated($decorated)
+ {
+ $this->output->setDecorated($decorated);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDecorated()
+ {
+ return $this->output->isDecorated();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setFormatter(OutputFormatterInterface $formatter)
+ {
+ $this->output->setFormatter($formatter);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormatter()
+ {
+ return $this->output->getFormatter();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isQuiet()
+ {
+ return $this->output->isQuiet();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isVerbose()
+ {
+ return $this->output->isVerbose();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isVeryVerbose()
+ {
+ return $this->output->isVeryVerbose();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isDebug()
+ {
+ return $this->output->isDebug();
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Style/StyleInterface.php b/includes/src/vendor/symfony/console/Style/StyleInterface.php
new file mode 100644
index 0000000..2448547
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Style/StyleInterface.php
@@ -0,0 +1,159 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Style;
+
+/**
+ * Output style helpers.
+ *
+ * @author Kevin Bond
+ */
+interface StyleInterface
+{
+ /**
+ * Formats a command title.
+ *
+ * @param string $message
+ */
+ public function title($message);
+
+ /**
+ * Formats a section title.
+ *
+ * @param string $message
+ */
+ public function section($message);
+
+ /**
+ * Formats a list.
+ *
+ * @param array $elements
+ */
+ public function listing(array $elements);
+
+ /**
+ * Formats informational text.
+ *
+ * @param string|array $message
+ */
+ public function text($message);
+
+ /**
+ * Formats a success result bar.
+ *
+ * @param string|array $message
+ */
+ public function success($message);
+
+ /**
+ * Formats an error result bar.
+ *
+ * @param string|array $message
+ */
+ public function error($message);
+
+ /**
+ * Formats an warning result bar.
+ *
+ * @param string|array $message
+ */
+ public function warning($message);
+
+ /**
+ * Formats a note admonition.
+ *
+ * @param string|array $message
+ */
+ public function note($message);
+
+ /**
+ * Formats a caution admonition.
+ *
+ * @param string|array $message
+ */
+ public function caution($message);
+
+ /**
+ * Formats a table.
+ *
+ * @param array $headers
+ * @param array $rows
+ */
+ public function table(array $headers, array $rows);
+
+ /**
+ * Asks a question.
+ *
+ * @param string $question
+ * @param string|null $default
+ * @param callable|null $validator
+ *
+ * @return string
+ */
+ public function ask($question, $default = null, $validator = null);
+
+ /**
+ * Asks a question with the user input hidden.
+ *
+ * @param string $question
+ * @param callable|null $validator
+ *
+ * @return string
+ */
+ public function askHidden($question, $validator = null);
+
+ /**
+ * Asks for confirmation.
+ *
+ * @param string $question
+ * @param bool $default
+ *
+ * @return bool
+ */
+ public function confirm($question, $default = true);
+
+ /**
+ * Asks a choice question.
+ *
+ * @param string $question
+ * @param array $choices
+ * @param string|int|null $default
+ *
+ * @return string
+ */
+ public function choice($question, array $choices, $default = null);
+
+ /**
+ * Add newline(s).
+ *
+ * @param int $count The number of newlines
+ */
+ public function newLine($count = 1);
+
+ /**
+ * Starts the progress output.
+ *
+ * @param int $max Maximum steps (0 if unknown)
+ */
+ public function progressStart($max = 0);
+
+ /**
+ * Advances the progress output X steps.
+ *
+ * @param int $step Number of steps to advance
+ */
+ public function progressAdvance($step = 1);
+
+ /**
+ * Finishes the progress output.
+ */
+ public function progressFinish();
+}
diff --git a/includes/src/vendor/symfony/console/Style/SymfonyStyle.php b/includes/src/vendor/symfony/console/Style/SymfonyStyle.php
new file mode 100644
index 0000000..a9c5744
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Style/SymfonyStyle.php
@@ -0,0 +1,435 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Style;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Exception\RuntimeException;
+use Symfony\Component\Console\Formatter\OutputFormatter;
+use Symfony\Component\Console\Helper\Helper;
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\BufferedOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
+
+/**
+ * Output decorator helpers for the Symfony Style Guide.
+ *
+ * @author Kevin Bond
+ */
+class SymfonyStyle extends OutputStyle
+{
+ const MAX_LINE_LENGTH = 120;
+
+ private $input;
+ private $questionHelper;
+ private $progressBar;
+ private $lineLength;
+ private $bufferedOutput;
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ public function __construct(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter());
+ // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
+ $this->lineLength = min($this->getTerminalWidth() - (int) (DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
+
+ parent::__construct($output);
+ }
+
+ /**
+ * Formats a message as a block of text.
+ *
+ * @param string|array $messages The message to write in the block
+ * @param string|null $type The block type (added in [] on first line)
+ * @param string|null $style The style to apply to the whole block
+ * @param string $prefix The prefix for the block
+ * @param bool $padding Whether to add vertical padding
+ */
+ public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false)
+ {
+ $messages = is_array($messages) ? array_values($messages) : array($messages);
+
+ $this->autoPrependBlock();
+ $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, true));
+ $this->newLine();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function title($message)
+ {
+ $this->autoPrependBlock();
+ $this->writeln(array(
+ sprintf('%s>', $message),
+ sprintf('%s>', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
+ ));
+ $this->newLine();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function section($message)
+ {
+ $this->autoPrependBlock();
+ $this->writeln(array(
+ sprintf('%s>', $message),
+ sprintf('%s>', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))),
+ ));
+ $this->newLine();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function listing(array $elements)
+ {
+ $this->autoPrependText();
+ $elements = array_map(function ($element) {
+ return sprintf(' * %s', $element);
+ }, $elements);
+
+ $this->writeln($elements);
+ $this->newLine();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function text($message)
+ {
+ $this->autoPrependText();
+
+ $messages = is_array($message) ? array_values($message) : array($message);
+ foreach ($messages as $message) {
+ $this->writeln(sprintf(' %s', $message));
+ }
+ }
+
+ /**
+ * Formats a command comment.
+ *
+ * @param string|array $message
+ */
+ public function comment($message)
+ {
+ $messages = is_array($message) ? array_values($message) : array($message);
+
+ $this->autoPrependBlock();
+ $this->writeln($this->createBlock($messages, null, null, ' // >'));
+ $this->newLine();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function success($message)
+ {
+ $this->block($message, 'OK', 'fg=black;bg=green', ' ', true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function error($message)
+ {
+ $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function warning($message)
+ {
+ $this->block($message, 'WARNING', 'fg=white;bg=red', ' ', true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function note($message)
+ {
+ $this->block($message, 'NOTE', 'fg=yellow', ' ! ');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function caution($message)
+ {
+ $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function table(array $headers, array $rows)
+ {
+ $style = clone Table::getStyleDefinition('symfony-style-guide');
+ $style->setCellHeaderFormat('%s');
+
+ $table = new Table($this);
+ $table->setHeaders($headers);
+ $table->setRows($rows);
+ $table->setStyle($style);
+
+ $table->render();
+ $this->newLine();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function ask($question, $default = null, $validator = null)
+ {
+ $question = new Question($question, $default);
+ $question->setValidator($validator);
+
+ return $this->askQuestion($question);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function askHidden($question, $validator = null)
+ {
+ $question = new Question($question);
+
+ $question->setHidden(true);
+ $question->setValidator($validator);
+
+ return $this->askQuestion($question);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function confirm($question, $default = true)
+ {
+ return $this->askQuestion(new ConfirmationQuestion($question, $default));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function choice($question, array $choices, $default = null)
+ {
+ if (null !== $default) {
+ $values = array_flip($choices);
+ $default = $values[$default];
+ }
+
+ return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function progressStart($max = 0)
+ {
+ $this->progressBar = $this->createProgressBar($max);
+ $this->progressBar->start();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function progressAdvance($step = 1)
+ {
+ $this->getProgressBar()->advance($step);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function progressFinish()
+ {
+ $this->getProgressBar()->finish();
+ $this->newLine(2);
+ $this->progressBar = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createProgressBar($max = 0)
+ {
+ $progressBar = parent::createProgressBar($max);
+
+ if ('\\' !== DIRECTORY_SEPARATOR) {
+ $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591
+ $progressBar->setProgressCharacter('');
+ $progressBar->setBarCharacter('▓'); // dark shade character \u2593
+ }
+
+ return $progressBar;
+ }
+
+ /**
+ * @param Question $question
+ *
+ * @return string
+ */
+ public function askQuestion(Question $question)
+ {
+ if ($this->input->isInteractive()) {
+ $this->autoPrependBlock();
+ }
+
+ if (!$this->questionHelper) {
+ $this->questionHelper = new SymfonyQuestionHelper();
+ }
+
+ $answer = $this->questionHelper->ask($this->input, $this, $question);
+
+ if ($this->input->isInteractive()) {
+ $this->newLine();
+ $this->bufferedOutput->write("\n");
+ }
+
+ return $answer;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeln($messages, $type = self::OUTPUT_NORMAL)
+ {
+ parent::writeln($messages, $type);
+ $this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
+ {
+ parent::write($messages, $newline, $type);
+ $this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function newLine($count = 1)
+ {
+ parent::newLine($count);
+ $this->bufferedOutput->write(str_repeat("\n", $count));
+ }
+
+ /**
+ * @return ProgressBar
+ */
+ private function getProgressBar()
+ {
+ if (!$this->progressBar) {
+ throw new RuntimeException('The ProgressBar is not started.');
+ }
+
+ return $this->progressBar;
+ }
+
+ private function getTerminalWidth()
+ {
+ $application = new Application();
+ $dimensions = $application->getTerminalDimensions();
+
+ return $dimensions[0] ?: self::MAX_LINE_LENGTH;
+ }
+
+ private function autoPrependBlock()
+ {
+ $chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
+
+ if (!isset($chars[0])) {
+ return $this->newLine(); //empty history, so we should start with a new line.
+ }
+ //Prepend new line for each non LF chars (This means no blank line was output before)
+ $this->newLine(2 - substr_count($chars, "\n"));
+ }
+
+ private function autoPrependText()
+ {
+ $fetched = $this->bufferedOutput->fetch();
+ //Prepend new line if last char isn't EOL:
+ if ("\n" !== substr($fetched, -1)) {
+ $this->newLine();
+ }
+ }
+
+ private function reduceBuffer($messages)
+ {
+ // We need to know if the two last chars are PHP_EOL
+ // Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
+ return array_map(function ($value) {
+ return substr($value, -4);
+ }, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
+ }
+
+ private function createBlock($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = false)
+ {
+ $indentLength = 0;
+ $prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix);
+ $lines = array();
+
+ if (null !== $type) {
+ $type = sprintf('[%s] ', $type);
+ $indentLength = strlen($type);
+ $lineIndentation = str_repeat(' ', $indentLength);
+ }
+
+ // wrap and add newlines for each element
+ foreach ($messages as $key => $message) {
+ if ($escape) {
+ $message = OutputFormatter::escape($message);
+ }
+
+ $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true)));
+
+ if (count($messages) > 1 && $key < count($messages) - 1) {
+ $lines[] = '';
+ }
+ }
+
+ $firstLineIndex = 0;
+ if ($padding && $this->isDecorated()) {
+ $firstLineIndex = 1;
+ array_unshift($lines, '');
+ $lines[] = '';
+ }
+
+ foreach ($lines as $i => &$line) {
+ if (null !== $type) {
+ $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
+ }
+
+ $line = $prefix.$line;
+ $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
+
+ if ($style) {
+ $line = sprintf('<%s>%s>', $style, $line);
+ }
+ }
+
+ return $lines;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tester/ApplicationTester.php b/includes/src/vendor/symfony/console/Tester/ApplicationTester.php
new file mode 100644
index 0000000..c0f8c72
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tester/ApplicationTester.php
@@ -0,0 +1,176 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\ConsoleOutput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+/**
+ * Eases the testing of console applications.
+ *
+ * When testing an application, don't forget to disable the auto exit flag:
+ *
+ * $application = new Application();
+ * $application->setAutoExit(false);
+ *
+ * @author Fabien Potencier
+ */
+class ApplicationTester
+{
+ private $application;
+ private $input;
+ private $statusCode;
+ /**
+ * @var OutputInterface
+ */
+ private $output;
+ private $captureStreamsIndependently = false;
+
+ public function __construct(Application $application)
+ {
+ $this->application = $application;
+ }
+
+ /**
+ * Executes the application.
+ *
+ * Available options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ * * capture_stderr_separately: Make output of stdOut and stdErr separately available
+ *
+ * @param array $input An array of arguments and options
+ * @param array $options An array of options
+ *
+ * @return int The command exit code
+ */
+ public function run(array $input, $options = array())
+ {
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->captureStreamsIndependently = array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
+ if (!$this->captureStreamsIndependently) {
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+ } else {
+ $this->output = new ConsoleOutput(
+ isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL,
+ isset($options['decorated']) ? $options['decorated'] : null
+ );
+
+ $errorOutput = new StreamOutput(fopen('php://memory', 'w', false));
+ $errorOutput->setFormatter($this->output->getFormatter());
+ $errorOutput->setVerbosity($this->output->getVerbosity());
+ $errorOutput->setDecorated($this->output->isDecorated());
+
+ $reflectedOutput = new \ReflectionObject($this->output);
+ $strErrProperty = $reflectedOutput->getProperty('stderr');
+ $strErrProperty->setAccessible(true);
+ $strErrProperty->setValue($this->output, $errorOutput);
+
+ $reflectedParent = $reflectedOutput->getParentClass();
+ $streamProperty = $reflectedParent->getProperty('stream');
+ $streamProperty->setAccessible(true);
+ $streamProperty->setValue($this->output, fopen('php://memory', 'w', false));
+ }
+
+ return $this->statusCode = $this->application->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the application.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string The display
+ */
+ public function getDisplay($normalize = false)
+ {
+ rewind($this->output->getStream());
+
+ $display = stream_get_contents($this->output->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the output written to STDERR by the application.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string
+ */
+ public function getErrorOutput($normalize = false)
+ {
+ if (!$this->captureStreamsIndependently) {
+ throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
+ }
+
+ rewind($this->output->getErrorOutput()->getStream());
+
+ $display = stream_get_contents($this->output->getErrorOutput()->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the application.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the application.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ /**
+ * Gets the status code returned by the last execution of the application.
+ *
+ * @return int The status code
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tester/CommandTester.php b/includes/src/vendor/symfony/console/Tester/CommandTester.php
new file mode 100644
index 0000000..f95298b
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tester/CommandTester.php
@@ -0,0 +1,132 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tester;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Eases the testing of console commands.
+ *
+ * @author Fabien Potencier
+ */
+class CommandTester
+{
+ private $command;
+ private $input;
+ private $output;
+ private $statusCode;
+
+ /**
+ * Constructor.
+ *
+ * @param Command $command A Command instance to test
+ */
+ public function __construct(Command $command)
+ {
+ $this->command = $command;
+ }
+
+ /**
+ * Executes the command.
+ *
+ * Available execution options:
+ *
+ * * interactive: Sets the input interactive flag
+ * * decorated: Sets the output decorated flag
+ * * verbosity: Sets the output verbosity flag
+ *
+ * @param array $input An array of command arguments and options
+ * @param array $options An array of execution options
+ *
+ * @return int The command exit code
+ */
+ public function execute(array $input, array $options = array())
+ {
+ // set the command name automatically if the application requires
+ // this argument and no command name was passed
+ if (!isset($input['command'])
+ && (null !== $application = $this->command->getApplication())
+ && $application->getDefinition()->hasArgument('command')
+ ) {
+ $input = array_merge(array('command' => $this->command->getName()), $input);
+ }
+
+ $this->input = new ArrayInput($input);
+ if (isset($options['interactive'])) {
+ $this->input->setInteractive($options['interactive']);
+ }
+
+ $this->output = new StreamOutput(fopen('php://memory', 'w', false));
+ if (isset($options['decorated'])) {
+ $this->output->setDecorated($options['decorated']);
+ }
+ if (isset($options['verbosity'])) {
+ $this->output->setVerbosity($options['verbosity']);
+ }
+
+ return $this->statusCode = $this->command->run($this->input, $this->output);
+ }
+
+ /**
+ * Gets the display returned by the last execution of the command.
+ *
+ * @param bool $normalize Whether to normalize end of lines to \n or not
+ *
+ * @return string The display
+ */
+ public function getDisplay($normalize = false)
+ {
+ rewind($this->output->getStream());
+
+ $display = stream_get_contents($this->output->getStream());
+
+ if ($normalize) {
+ $display = str_replace(PHP_EOL, "\n", $display);
+ }
+
+ return $display;
+ }
+
+ /**
+ * Gets the input instance used by the last execution of the command.
+ *
+ * @return InputInterface The current input instance
+ */
+ public function getInput()
+ {
+ return $this->input;
+ }
+
+ /**
+ * Gets the output instance used by the last execution of the command.
+ *
+ * @return OutputInterface The current output instance
+ */
+ public function getOutput()
+ {
+ return $this->output;
+ }
+
+ /**
+ * Gets the status code returned by the last execution of the application.
+ *
+ * @return int The status code
+ */
+ public function getStatusCode()
+ {
+ return $this->statusCode;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/ApplicationTest.php b/includes/src/vendor/symfony/console/Tests/ApplicationTest.php
new file mode 100644
index 0000000..974056d
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/ApplicationTest.php
@@ -0,0 +1,1143 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Input\ArgvInput;
+use Symfony\Component\Console\Input\ArrayInput;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Output\Output;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+use Symfony\Component\Console\Tester\ApplicationTester;
+use Symfony\Component\Console\Event\ConsoleCommandEvent;
+use Symfony\Component\Console\Event\ConsoleExceptionEvent;
+use Symfony\Component\Console\Event\ConsoleTerminateEvent;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+
+class ApplicationTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixturesPath;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
+ require_once self::$fixturesPath.'/FooCommand.php';
+ require_once self::$fixturesPath.'/Foo1Command.php';
+ require_once self::$fixturesPath.'/Foo2Command.php';
+ require_once self::$fixturesPath.'/Foo3Command.php';
+ require_once self::$fixturesPath.'/Foo4Command.php';
+ require_once self::$fixturesPath.'/Foo5Command.php';
+ require_once self::$fixturesPath.'/FoobarCommand.php';
+ require_once self::$fixturesPath.'/BarBucCommand.php';
+ require_once self::$fixturesPath.'/FooSubnamespaced1Command.php';
+ require_once self::$fixturesPath.'/FooSubnamespaced2Command.php';
+ }
+
+ protected function normalizeLineBreaks($text)
+ {
+ return str_replace(PHP_EOL, "\n", $text);
+ }
+
+ /**
+ * Replaces the dynamic placeholders of the command help text with a static version.
+ * The placeholder %command.full_name% includes the script path that is not predictable
+ * and can not be tested against.
+ */
+ protected function ensureStaticCommandHelp(Application $application)
+ {
+ foreach ($application->all() as $command) {
+ $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+ }
+ }
+
+ public function testConstructor()
+ {
+ $application = new Application('foo', 'bar');
+ $this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument');
+ $this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument');
+ $this->assertEquals(array('help', 'list'), array_keys($application->all()), '__construct() registered the help and list commands by default');
+ }
+
+ public function testSetGetName()
+ {
+ $application = new Application();
+ $application->setName('foo');
+ $this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application');
+ }
+
+ public function testSetGetVersion()
+ {
+ $application = new Application();
+ $application->setVersion('bar');
+ $this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application');
+ }
+
+ public function testGetLongVersion()
+ {
+ $application = new Application('foo', 'bar');
+ $this->assertEquals('foo version bar', $application->getLongVersion(), '->getLongVersion() returns the long version of the application');
+ }
+
+ public function testHelp()
+ {
+ $application = new Application();
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->getHelp() returns a help message');
+ }
+
+ public function testAll()
+ {
+ $application = new Application();
+ $commands = $application->all();
+ $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands');
+
+ $application->add(new \FooCommand());
+ $commands = $application->all('foo');
+ $this->assertCount(1, $commands, '->all() takes a namespace as its first argument');
+ }
+
+ public function testRegister()
+ {
+ $application = new Application();
+ $command = $application->register('foo');
+ $this->assertEquals('foo', $command->getName(), '->register() registers a new command');
+ }
+
+ public function testAdd()
+ {
+ $application = new Application();
+ $application->add($foo = new \FooCommand());
+ $commands = $application->all();
+ $this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command');
+
+ $application = new Application();
+ $application->addCommands(array($foo = new \FooCommand(), $foo1 = new \Foo1Command()));
+ $commands = $application->all();
+ $this->assertEquals(array($foo, $foo1), array($commands['foo:bar'], $commands['foo:bar1']), '->addCommands() registers an array of commands');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor.
+ */
+ public function testAddCommandWithEmptyConstructor()
+ {
+ $application = new Application();
+ $application->add(new \Foo5Command());
+ }
+
+ public function testHasGet()
+ {
+ $application = new Application();
+ $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered');
+ $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered');
+
+ $application->add($foo = new \FooCommand());
+ $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered');
+ $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name');
+ $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias');
+
+ $application = new Application();
+ $application->add($foo = new \FooCommand());
+ // simulate --help
+ $r = new \ReflectionObject($application);
+ $p = $r->getProperty('wantHelps');
+ $p->setAccessible(true);
+ $p->setValue($application, true);
+ $command = $application->get('foo:bar');
+ $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input');
+ }
+
+ public function testSilentHelp()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('-h' => true, '-q' => true), array('decorated' => false));
+
+ $this->assertEmpty($tester->getDisplay(true));
+ }
+
+ /**
+ * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
+ * @expectedExceptionMessage The command "foofoo" does not exist.
+ */
+ public function testGetInvalidCommand()
+ {
+ $application = new Application();
+ $application->get('foofoo');
+ }
+
+ public function testGetNamespaces()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $this->assertEquals(array('foo'), $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces');
+ }
+
+ public function testFindNamespace()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
+ $this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation');
+ $application->add(new \Foo2Command());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists');
+ }
+
+ public function testFindNamespaceWithSubnamespaces()
+ {
+ $application = new Application();
+ $application->add(new \FooSubnamespaced1Command());
+ $application->add(new \FooSubnamespaced2Command());
+ $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces');
+ }
+
+ /**
+ * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
+ * @expectedExceptionMessage The namespace "f" is ambiguous (foo, foo1).
+ */
+ public function testFindAmbiguousNamespace()
+ {
+ $application = new Application();
+ $application->add(new \BarBucCommand());
+ $application->add(new \FooCommand());
+ $application->add(new \Foo2Command());
+ $application->findNamespace('f');
+ }
+
+ /**
+ * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
+ * @expectedExceptionMessage There are no commands defined in the "bar" namespace.
+ */
+ public function testFindInvalidNamespace()
+ {
+ $application = new Application();
+ $application->findNamespace('bar');
+ }
+
+ /**
+ * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
+ * @expectedExceptionMessage Command "foo1" is not defined
+ */
+ public function testFindUniqueNameButNamespaceName()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ $application->find($commandName = 'foo1');
+ }
+
+ public function testFind()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+
+ $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists');
+ $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists');
+ $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists');
+ $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist');
+ $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias');
+ }
+
+ /**
+ * @dataProvider provideAmbiguousAbbreviations
+ */
+ public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage)
+ {
+ $this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage);
+
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ $application->find($abbreviation);
+ }
+
+ public function provideAmbiguousAbbreviations()
+ {
+ return array(
+ array('f', 'Command "f" is not defined.'),
+ array('a', 'Command "a" is ambiguous (afoobar, afoobar1 and 1 more).'),
+ array('foo:b', 'Command "foo:b" is ambiguous (foo:bar, foo:bar1 and 1 more).'),
+ );
+ }
+
+ public function testFindCommandEqualNamespace()
+ {
+ $application = new Application();
+ $application->add(new \Foo3Command());
+ $application->add(new \Foo4Command());
+
+ $this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name');
+ $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name');
+ }
+
+ public function testFindCommandWithAmbiguousNamespacesButUniqueName()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \FoobarCommand());
+
+ $this->assertInstanceOf('FoobarCommand', $application->find('f:f'));
+ }
+
+ public function testFindCommandWithMissingNamespace()
+ {
+ $application = new Application();
+ $application->add(new \Foo4Command());
+
+ $this->assertInstanceOf('Foo4Command', $application->find('f::t'));
+ }
+
+ /**
+ * @dataProvider provideInvalidCommandNamesSingle
+ * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
+ * @expectedExceptionMessage Did you mean this
+ */
+ public function testFindAlternativeExceptionMessageSingle($name)
+ {
+ $application = new Application();
+ $application->add(new \Foo3Command());
+ $application->find($name);
+ }
+
+ public function provideInvalidCommandNamesSingle()
+ {
+ return array(
+ array('foo3:baR'),
+ array('foO3:bar'),
+ );
+ }
+
+ public function testFindAlternativeExceptionMessageMultiple()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ // Command + plural
+ try {
+ $application->find('foo:baR');
+ $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ $this->assertRegExp('/foo1:bar/', $e->getMessage());
+ $this->assertRegExp('/foo:bar/', $e->getMessage());
+ }
+
+ // Namespace + plural
+ try {
+ $application->find('foo2:bar');
+ $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ $this->assertRegExp('/foo1/', $e->getMessage());
+ }
+
+ $application->add(new \Foo3Command());
+ $application->add(new \Foo4Command());
+
+ // Subnamespace + plural
+ try {
+ $a = $application->find('foo3:');
+ $this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e);
+ $this->assertRegExp('/foo3:bar/', $e->getMessage());
+ $this->assertRegExp('/foo3:bar:toh/', $e->getMessage());
+ }
+ }
+
+ public function testFindAlternativeCommands()
+ {
+ $application = new Application();
+
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+
+ try {
+ $application->find($commandName = 'Unknown command');
+ $this->fail('->find() throws a CommandNotFoundException if command does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist');
+ $this->assertSame(array(), $e->getAlternatives());
+ $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without alternatives');
+ }
+
+ // Test if "bar1" command throw a "CommandNotFoundException" and does not contain
+ // "foo:bar" as alternative because "bar1" is too far from "foo:bar"
+ try {
+ $application->find($commandName = 'bar1');
+ $this->fail('->find() throws a CommandNotFoundException if command does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist');
+ $this->assertSame(array('afoobar1', 'foo:bar1'), $e->getAlternatives());
+ $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives');
+ $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"');
+ $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"');
+ $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative');
+ }
+ }
+
+ public function testFindAlternativeCommandsWithAnAlias()
+ {
+ $fooCommand = new \FooCommand();
+ $fooCommand->setAliases(array('foo2'));
+
+ $application = new Application();
+ $application->add($fooCommand);
+
+ $result = $application->find('foo');
+
+ $this->assertSame($fooCommand, $result);
+ }
+
+ public function testFindAlternativeNamespace()
+ {
+ $application = new Application();
+
+ $application->add(new \FooCommand());
+ $application->add(new \Foo1Command());
+ $application->add(new \Foo2Command());
+ $application->add(new \Foo3Command());
+
+ try {
+ $application->find('Unknown-namespace:Unknown-command');
+ $this->fail('->find() throws a CommandNotFoundException if namespace does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist');
+ $this->assertSame(array(), $e->getAlternatives());
+ $this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, without alternatives');
+ }
+
+ try {
+ $application->find('foo2:command');
+ $this->fail('->find() throws a CommandNotFoundException if namespace does not exist');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist');
+ $this->assertCount(3, $e->getAlternatives());
+ $this->assertContains('foo', $e->getAlternatives());
+ $this->assertContains('foo1', $e->getAlternatives());
+ $this->assertContains('foo3', $e->getAlternatives());
+ $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative');
+ $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"');
+ $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"');
+ $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"');
+ }
+ }
+
+ public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getNamespaces'));
+ $application->expects($this->once())
+ ->method('getNamespaces')
+ ->will($this->returnValue(array('foo:sublong', 'bar:sub')));
+
+ $this->assertEquals('foo:sublong', $application->findNamespace('f:sub'));
+ }
+
+ /**
+ * @expectedException Symfony\Component\Console\Exception\CommandNotFoundException
+ * @expectedExceptionMessage Command "foo::bar" is not defined.
+ */
+ public function testFindWithDoubleColonInNameThrowsException()
+ {
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $application->add(new \Foo4Command());
+ $application->find('foo::bar');
+ }
+
+ public function testSetCatchExceptions()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $tester = new ApplicationTester($application);
+
+ $application->setCatchExceptions(true);
+ $this->assertTrue($application->areExceptionsCaught());
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getErrorOutput(true), '->setCatchExceptions() sets the catch exception flag');
+ $this->assertSame('', $tester->getDisplay(true));
+
+ $application->setCatchExceptions(false);
+ try {
+ $tester->run(array('command' => 'foo'), array('decorated' => false));
+ $this->fail('->setCatchExceptions() sets the catch exception flag');
+ } catch (\Exception $e) {
+ $this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag');
+ $this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag');
+ }
+ }
+
+ public function testAutoExitSetting()
+ {
+ $application = new Application();
+ $this->assertTrue($application->isAutoExitEnabled());
+
+ $application->setAutoExit(false);
+ $this->assertFalse($application->isAutoExitEnabled());
+ }
+
+ public function testRenderException()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exception');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE, 'capture_stderr_separately' => true));
+ $this->assertContains('Exception trace', $tester->getErrorOutput(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose');
+
+ $tester->run(array('command' => 'list', '--foo' => true), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getErrorOutput(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command');
+
+ $application->add(new \Foo3Command());
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE));
+ $this->assertRegExp('/\[Exception\]\s*First exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is default and verbosity is verbose');
+ $this->assertRegExp('/\[Exception\]\s*Second exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is 0 and verbosity is verbose');
+ $this->assertRegExp('/\[Exception \(404\)\]\s*Third exception/', $tester->getDisplay(), '->renderException() renders a pretty exception with code exception when code exception is 404 and verbosity is verbose');
+
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo3:bar'), array('decorated' => true, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(32));
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal');
+ }
+
+ public function testRenderExceptionWithDoubleWidthCharacters()
+ {
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(120));
+ $application->register('foo')->setCode(function () {
+ throw new \Exception('エラーメッセージ');
+ });
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $tester->run(array('command' => 'foo'), array('decorated' => true, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions');
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('getTerminalWidth'));
+ $application->setAutoExit(false);
+ $application->expects($this->any())
+ ->method('getTerminalWidth')
+ ->will($this->returnValue(32));
+ $application->register('foo')->setCode(function () {
+ throw new \Exception('コマンドの実行中にエラーが発生しました。');
+ });
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'), array('decorated' => false, 'capture_stderr_separately' => true));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal');
+ }
+
+ public function testRun()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add($command = new \Foo1Command());
+ $_SERVER['argv'] = array('cli.php', 'foo:bar1');
+
+ ob_start();
+ $application->run();
+ ob_end_clean();
+
+ $this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given');
+ $this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given');
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $this->ensureStaticCommandHelp($application);
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array(), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed');
+
+ $tester->run(array('--help' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed');
+
+ $tester->run(array('-h' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed');
+
+ $tester->run(array('command' => 'list', '--help' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed');
+
+ $tester->run(array('command' => 'list', '-h' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed');
+
+ $tester->run(array('--ansi' => true));
+ $this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed');
+
+ $tester->run(array('--no-ansi' => true));
+ $this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed');
+
+ $tester->run(array('--version' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed');
+
+ $tester->run(array('-V' => true), array('decorated' => false));
+ $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed');
+
+ $tester->run(array('command' => 'list', '--quiet' => true));
+ $this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed');
+
+ $tester->run(array('command' => 'list', '-q' => true));
+ $this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => true));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 1));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 2));
+ $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 3));
+ $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed');
+
+ $tester->run(array('command' => 'list', '--verbose' => 4));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed');
+
+ $tester->run(array('command' => 'list', '-v' => true));
+ $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $tester->run(array('command' => 'list', '-vv' => true));
+ $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $tester->run(array('command' => 'list', '-vvv' => true));
+ $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed');
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add(new \FooCommand());
+ $tester = new ApplicationTester($application);
+
+ $tester->run(array('command' => 'foo:bar', '--no-interaction' => true), array('decorated' => false));
+ $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed');
+
+ $tester->run(array('command' => 'foo:bar', '-n' => true), array('decorated' => false));
+ $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed');
+ }
+
+ /**
+ * Issue #9285.
+ *
+ * If the "verbose" option is just before an argument in ArgvInput,
+ * an argument value should not be treated as verbosity value.
+ * This test will fail with "Not enough arguments." if broken
+ */
+ public function testVerboseValueNotBreakArguments()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->add(new \FooCommand());
+
+ $output = new StreamOutput(fopen('php://memory', 'w', false));
+
+ $input = new ArgvInput(array('cli.php', '-v', 'foo:bar'));
+ $application->run($input, $output);
+
+ $input = new ArgvInput(array('cli.php', '--verbose', 'foo:bar'));
+ $application->run($input, $output);
+ }
+
+ public function testRunReturnsIntegerExitCode()
+ {
+ $exception = new \Exception('', 4);
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
+ $application->setAutoExit(false);
+ $application->expects($this->once())
+ ->method('doRun')
+ ->will($this->throwException($exception));
+
+ $exitCode = $application->run(new ArrayInput(array()), new NullOutput());
+
+ $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception');
+ }
+
+ public function testRunReturnsExitCodeOneForExceptionCodeZero()
+ {
+ $exception = new \Exception('', 0);
+
+ $application = $this->getMock('Symfony\Component\Console\Application', array('doRun'));
+ $application->setAutoExit(false);
+ $application->expects($this->once())
+ ->method('doRun')
+ ->will($this->throwException($exception));
+
+ $exitCode = $application->run(new ArrayInput(array()), new NullOutput());
+
+ $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage An option with shortcut "e" already exists.
+ */
+ public function testAddingOptionWithDuplicateShortcut()
+ {
+ $dispatcher = new EventDispatcher();
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application->setDispatcher($dispatcher);
+
+ $application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'Environment'));
+
+ $application
+ ->register('foo')
+ ->setAliases(array('f'))
+ ->setDefinition(array(new InputOption('survey', 'e', InputOption::VALUE_REQUIRED, 'My option with a shortcut.')))
+ ->setCode(function (InputInterface $input, OutputInterface $output) {})
+ ;
+
+ $input = new ArrayInput(array('command' => 'foo'));
+ $output = new NullOutput();
+
+ $application->run($input, $output);
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @dataProvider getAddingAlreadySetDefinitionElementData
+ */
+ public function testAddingAlreadySetDefinitionElementData($def)
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+ $application
+ ->register('foo')
+ ->setDefinition(array($def))
+ ->setCode(function (InputInterface $input, OutputInterface $output) {})
+ ;
+
+ $input = new ArrayInput(array('command' => 'foo'));
+ $output = new NullOutput();
+ $application->run($input, $output);
+ }
+
+ public function getAddingAlreadySetDefinitionElementData()
+ {
+ return array(
+ array(new InputArgument('command', InputArgument::REQUIRED)),
+ array(new InputOption('quiet', '', InputOption::VALUE_NONE)),
+ array(new InputOption('query', 'q', InputOption::VALUE_NONE)),
+ );
+ }
+
+ public function testGetDefaultHelperSetReturnsDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+ }
+
+ public function testAddingSingleHelperSetOverwritesDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setHelperSet(new HelperSet(array(new FormatterHelper())));
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+
+ // no other default helper set should be returned
+ $this->assertFalse($helperSet->has('dialog'));
+ $this->assertFalse($helperSet->has('progress'));
+ }
+
+ public function testOverwritingDefaultHelperSetOverwritesDefaultValues()
+ {
+ $application = new CustomApplication();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setHelperSet(new HelperSet(array(new FormatterHelper())));
+
+ $helperSet = $application->getHelperSet();
+
+ $this->assertTrue($helperSet->has('formatter'));
+
+ // no other default helper set should be returned
+ $this->assertFalse($helperSet->has('dialog'));
+ $this->assertFalse($helperSet->has('progress'));
+ }
+
+ public function testGetDefaultInputDefinitionReturnsDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $inputDefinition = $application->getDefinition();
+
+ $this->assertTrue($inputDefinition->hasArgument('command'));
+
+ $this->assertTrue($inputDefinition->hasOption('help'));
+ $this->assertTrue($inputDefinition->hasOption('quiet'));
+ $this->assertTrue($inputDefinition->hasOption('verbose'));
+ $this->assertTrue($inputDefinition->hasOption('version'));
+ $this->assertTrue($inputDefinition->hasOption('ansi'));
+ $this->assertTrue($inputDefinition->hasOption('no-ansi'));
+ $this->assertTrue($inputDefinition->hasOption('no-interaction'));
+ }
+
+ public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues()
+ {
+ $application = new CustomApplication();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $inputDefinition = $application->getDefinition();
+
+ // check whether the default arguments and options are not returned any more
+ $this->assertFalse($inputDefinition->hasArgument('command'));
+
+ $this->assertFalse($inputDefinition->hasOption('help'));
+ $this->assertFalse($inputDefinition->hasOption('quiet'));
+ $this->assertFalse($inputDefinition->hasOption('verbose'));
+ $this->assertFalse($inputDefinition->hasOption('version'));
+ $this->assertFalse($inputDefinition->hasOption('ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-interaction'));
+
+ $this->assertTrue($inputDefinition->hasOption('custom'));
+ }
+
+ public function testSettingCustomInputDefinitionOverwritesDefaultValues()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->setDefinition(new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.'))));
+
+ $inputDefinition = $application->getDefinition();
+
+ // check whether the default arguments and options are not returned any more
+ $this->assertFalse($inputDefinition->hasArgument('command'));
+
+ $this->assertFalse($inputDefinition->hasOption('help'));
+ $this->assertFalse($inputDefinition->hasOption('quiet'));
+ $this->assertFalse($inputDefinition->hasOption('verbose'));
+ $this->assertFalse($inputDefinition->hasOption('version'));
+ $this->assertFalse($inputDefinition->hasOption('ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-ansi'));
+ $this->assertFalse($inputDefinition->hasOption('no-interaction'));
+
+ $this->assertTrue($inputDefinition->hasOption('custom'));
+ }
+
+ public function testRunWithDispatcher()
+ {
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->setDispatcher($this->getDispatcher());
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ $this->assertEquals('before.foo.after.'.PHP_EOL, $tester->getDisplay());
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage caught
+ */
+ public function testRunWithExceptionAndDispatcher()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher());
+ $application->setAutoExit(false);
+ $application->setCatchExceptions(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ throw new \RuntimeException('foo');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ }
+
+ public function testRunDispatchesAllEventsWithException()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher());
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+
+ throw new \RuntimeException('foo');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo'));
+ $this->assertContains('before.foo.caught.after.', $tester->getDisplay());
+ }
+
+ public function testRunWithDispatcherSkippingCommand()
+ {
+ $application = new Application();
+ $application->setDispatcher($this->getDispatcher(true));
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $exitCode = $tester->run(array('command' => 'foo'));
+ $this->assertContains('before.after.', $tester->getDisplay());
+ $this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode);
+ }
+
+ public function testRunWithDispatcherAccessingInputOptions()
+ {
+ $noInteractionValue = null;
+ $quietValue = null;
+
+ $dispatcher = $this->getDispatcher();
+ $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) {
+ $input = $event->getInput();
+
+ $noInteractionValue = $input->getOption('no-interaction');
+ $quietValue = $input->getOption('quiet');
+ });
+
+ $application = new Application();
+ $application->setDispatcher($dispatcher);
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo', '--no-interaction' => true));
+
+ $this->assertTrue($noInteractionValue);
+ $this->assertFalse($quietValue);
+ }
+
+ public function testRunWithDispatcherAddingInputOptions()
+ {
+ $extraValue = null;
+
+ $dispatcher = $this->getDispatcher();
+ $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) {
+ $definition = $event->getCommand()->getDefinition();
+ $input = $event->getInput();
+
+ $definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED));
+ $input->bind($definition);
+
+ $extraValue = $input->getOption('extra');
+ });
+
+ $application = new Application();
+ $application->setDispatcher($dispatcher);
+ $application->setAutoExit(false);
+
+ $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->write('foo.');
+ });
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'foo', '--extra' => 'some test value'));
+
+ $this->assertEquals('some test value', $extraValue);
+ }
+
+ public function testTerminalDimensions()
+ {
+ $application = new Application();
+ $originalDimensions = $application->getTerminalDimensions();
+ $this->assertCount(2, $originalDimensions);
+
+ $width = 80;
+ if ($originalDimensions[0] == $width) {
+ $width = 100;
+ }
+
+ $application->setTerminalDimensions($width, 80);
+ $this->assertSame(array($width, 80), $application->getTerminalDimensions());
+ }
+
+ protected function getDispatcher($skipCommand = false)
+ {
+ $dispatcher = new EventDispatcher();
+ $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use ($skipCommand) {
+ $event->getOutput()->write('before.');
+
+ if ($skipCommand) {
+ $event->disableCommand();
+ }
+ });
+ $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($skipCommand) {
+ $event->getOutput()->writeln('after.');
+
+ if (!$skipCommand) {
+ $event->setExitCode(113);
+ }
+ });
+ $dispatcher->addListener('console.exception', function (ConsoleExceptionEvent $event) {
+ $event->getOutput()->write('caught.');
+
+ $event->setException(new \LogicException('caught.', $event->getExitCode(), $event->getException()));
+ });
+
+ return $dispatcher;
+ }
+
+ public function testSetRunCustomDefaultCommand()
+ {
+ $command = new \FooCommand();
+
+ $application = new Application();
+ $application->setAutoExit(false);
+ $application->add($command);
+ $application->setDefaultCommand($command->getName());
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array());
+ $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
+
+ $application = new CustomDefaultCommandApplication();
+ $application->setAutoExit(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array());
+
+ $this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
+ }
+
+ /**
+ * @requires function posix_isatty
+ */
+ public function testCanCheckIfTerminalIsInteractive()
+ {
+ $application = new CustomDefaultCommandApplication();
+ $application->setAutoExit(false);
+
+ $tester = new ApplicationTester($application);
+ $tester->run(array('command' => 'help'));
+
+ $this->assertFalse($tester->getInput()->hasParameterOption(array('--no-interaction', '-n')));
+
+ $inputStream = $application->getHelperSet()->get('question')->getInputStream();
+ $this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream));
+ }
+}
+
+class CustomApplication extends Application
+{
+ /**
+ * Overwrites the default input definition.
+ *
+ * @return InputDefinition An InputDefinition instance
+ */
+ protected function getDefaultInputDefinition()
+ {
+ return new InputDefinition(array(new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')));
+ }
+
+ /**
+ * Gets the default helper set with the helpers that should always be available.
+ *
+ * @return HelperSet A HelperSet instance
+ */
+ protected function getDefaultHelperSet()
+ {
+ return new HelperSet(array(new FormatterHelper()));
+ }
+}
+
+class CustomDefaultCommandApplication extends Application
+{
+ /**
+ * Overwrites the constructor in order to set a different default command.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $command = new \FooCommand();
+ $this->add($command);
+ $this->setDefaultCommand($command->getName());
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Command/CommandTest.php b/includes/src/vendor/symfony/console/Tests/Command/CommandTest.php
new file mode 100644
index 0000000..53a6009
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Command/CommandTest.php
@@ -0,0 +1,360 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\FormatterHelper;
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\StringInput;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Output\NullOutput;
+use Symfony\Component\Console\Tester\CommandTester;
+
+class CommandTest extends \PHPUnit_Framework_TestCase
+{
+ protected static $fixturesPath;
+
+ public static function setUpBeforeClass()
+ {
+ self::$fixturesPath = __DIR__.'/../Fixtures/';
+ require_once self::$fixturesPath.'/TestCommand.php';
+ }
+
+ public function testConstructor()
+ {
+ $command = new Command('foo:bar');
+ $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage The command defined in "Symfony\Component\Console\Command\Command" cannot have an empty name.
+ */
+ public function testCommandNameCannotBeEmpty()
+ {
+ new Command();
+ }
+
+ public function testSetApplication()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application');
+ }
+
+ public function testSetGetDefinition()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setDefinition($definition = new InputDefinition());
+ $this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface');
+ $this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance');
+ $command->setDefinition(array(new InputArgument('foo'), new InputOption('bar')));
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument');
+ $command->setDefinition(new InputDefinition());
+ }
+
+ public function testAddArgument()
+ {
+ $command = new \TestCommand();
+ $ret = $command->addArgument('foo');
+ $this->assertEquals($command, $ret, '->addArgument() implements a fluent interface');
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command');
+ }
+
+ public function testAddOption()
+ {
+ $command = new \TestCommand();
+ $ret = $command->addOption('foo');
+ $this->assertEquals($command, $ret, '->addOption() implements a fluent interface');
+ $this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command');
+ }
+
+ public function testGetNamespaceGetNameSetName()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name');
+ $command->setName('foo');
+ $this->assertEquals('foo', $command->getName(), '->setName() sets the command name');
+
+ $ret = $command->setName('foobar:bar');
+ $this->assertEquals($command, $ret, '->setName() implements a fluent interface');
+ $this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name');
+ }
+
+ /**
+ * @dataProvider provideInvalidCommandNames
+ */
+ public function testInvalidCommandNames($name)
+ {
+ $this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name));
+
+ $command = new \TestCommand();
+ $command->setName($name);
+ }
+
+ public function provideInvalidCommandNames()
+ {
+ return array(
+ array(''),
+ array('foo:'),
+ );
+ }
+
+ public function testGetSetDescription()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description');
+ $ret = $command->setDescription('description1');
+ $this->assertEquals($command, $ret, '->setDescription() implements a fluent interface');
+ $this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description');
+ }
+
+ public function testGetSetHelp()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help');
+ $ret = $command->setHelp('help1');
+ $this->assertEquals($command, $ret, '->setHelp() implements a fluent interface');
+ $this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help');
+ $command->setHelp('');
+ $this->assertEquals('', $command->getHelp(), '->getHelp() does not fall back to the description');
+ }
+
+ public function testGetProcessedHelp()
+ {
+ $command = new \TestCommand();
+ $command->setHelp('The %command.name% command does... Example: php %command.full_name%.');
+ $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly');
+ $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%');
+
+ $command = new \TestCommand();
+ $command->setHelp('');
+ $this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description');
+ }
+
+ public function testGetSetAliases()
+ {
+ $command = new \TestCommand();
+ $this->assertEquals(array('name'), $command->getAliases(), '->getAliases() returns the aliases');
+ $ret = $command->setAliases(array('name1'));
+ $this->assertEquals($command, $ret, '->setAliases() implements a fluent interface');
+ $this->assertEquals(array('name1'), $command->getAliases(), '->setAliases() sets the aliases');
+ }
+
+ public function testGetSynopsis()
+ {
+ $command = new \TestCommand();
+ $command->addOption('foo');
+ $command->addArgument('bar');
+ $this->assertEquals('namespace:name [--foo] [--] []', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
+ }
+
+ public function testGetHelper()
+ {
+ $application = new Application();
+ $command = new \TestCommand();
+ $command->setApplication($application);
+ $formatterHelper = new FormatterHelper();
+ $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage Cannot retrieve helper "formatter" because there is no HelperSet defined.
+ */
+ public function testGetHelperWithoutHelperSet()
+ {
+ $command = new \TestCommand();
+ $command->getHelper('formatter');
+ }
+
+ public function testMergeApplicationDefinition()
+ {
+ $application1 = new Application();
+ $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
+ $application1->getDefinition()->addOptions(array(new InputOption('bar')));
+ $command = new \TestCommand();
+ $command->setApplication($application1);
+ $command->setDefinition($definition = new InputDefinition(array(new InputArgument('bar'), new InputOption('foo'))));
+
+ $r = new \ReflectionObject($command);
+ $m = $r->getMethod('mergeApplicationDefinition');
+ $m->setAccessible(true);
+ $m->invoke($command);
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
+ $this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments');
+ $this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options');
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options');
+
+ $m->invoke($command);
+ $this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options');
+ }
+
+ public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs()
+ {
+ $application1 = new Application();
+ $application1->getDefinition()->addArguments(array(new InputArgument('foo')));
+ $application1->getDefinition()->addOptions(array(new InputOption('bar')));
+ $command = new \TestCommand();
+ $command->setApplication($application1);
+ $command->setDefinition($definition = new InputDefinition(array()));
+
+ $r = new \ReflectionObject($command);
+ $m = $r->getMethod('mergeApplicationDefinition');
+ $m->setAccessible(true);
+ $m->invoke($command, false);
+ $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the command options');
+ $this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments');
+
+ $m->invoke($command, true);
+ $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments');
+
+ $m->invoke($command);
+ $this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments');
+ }
+
+ public function testRunInteractive()
+ {
+ $tester = new CommandTester(new \TestCommand());
+
+ $tester->execute(array(), array('interactive' => true));
+
+ $this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive');
+ }
+
+ public function testRunNonInteractive()
+ {
+ $tester = new CommandTester(new \TestCommand());
+
+ $tester->execute(array(), array('interactive' => false));
+
+ $this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive');
+ }
+
+ /**
+ * @expectedException \LogicException
+ * @expectedExceptionMessage You must override the execute() method in the concrete command class.
+ */
+ public function testExecuteMethodNeedsToBeOverridden()
+ {
+ $command = new Command('foo');
+ $command->run(new StringInput(''), new NullOutput());
+ }
+
+ /**
+ * @expectedException Symfony\Component\Console\Exception\InvalidOptionException
+ * @expectedExceptionMessage The "--bar" option does not exist.
+ */
+ public function testRunWithInvalidOption()
+ {
+ $command = new \TestCommand();
+ $tester = new CommandTester($command);
+ $tester->execute(array('--bar' => true));
+ }
+
+ public function testRunReturnsIntegerExitCode()
+ {
+ $command = new \TestCommand();
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+ $this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)');
+
+ $command = $this->getMock('TestCommand', array('execute'));
+ $command->expects($this->once())
+ ->method('execute')
+ ->will($this->returnValue('2.3'));
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+ $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)');
+ }
+
+ public function testRunWithApplication()
+ {
+ $command = new \TestCommand();
+ $command->setApplication(new Application());
+ $exitCode = $command->run(new StringInput(''), new NullOutput());
+
+ $this->assertSame(0, $exitCode, '->run() returns an integer exit code');
+ }
+
+ public function testRunReturnsAlwaysInteger()
+ {
+ $command = new \TestCommand();
+
+ $this->assertSame(0, $command->run(new StringInput(''), new NullOutput()));
+ }
+
+ public function testSetCode()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setCode(function (InputInterface $input, OutputInterface $output) {
+ $output->writeln('from the code...');
+ });
+ $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
+ }
+
+ public function getSetCodeBindToClosureTests()
+ {
+ return array(
+ array(true, 'not bound to the command'),
+ array(false, 'bound to the command'),
+ );
+ }
+
+ /**
+ * @dataProvider getSetCodeBindToClosureTests
+ */
+ public function testSetCodeBindToClosure($previouslyBound, $expected)
+ {
+ $code = createClosure();
+ if ($previouslyBound) {
+ $code = $code->bindTo($this);
+ }
+
+ $command = new \TestCommand();
+ $command->setCode($code);
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay());
+ }
+
+ public function testSetCodeWithNonClosureCallable()
+ {
+ $command = new \TestCommand();
+ $ret = $command->setCode(array($this, 'callableMethodCommand'));
+ $this->assertEquals($command, $ret, '->setCode() implements a fluent interface');
+ $tester = new CommandTester($command);
+ $tester->execute(array());
+ $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
+ }
+
+ public function callableMethodCommand(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('from the code...');
+ }
+}
+
+// In order to get an unbound closure, we should create it outside a class
+// scope.
+function createClosure()
+{
+ return function (InputInterface $input, OutputInterface $output) {
+ $output->writeln($this instanceof Command ? 'bound to the command' : 'not bound to the command');
+ };
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Command/HelpCommandTest.php b/includes/src/vendor/symfony/console/Tests/Command/HelpCommandTest.php
new file mode 100644
index 0000000..10bb324
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Command/HelpCommandTest.php
@@ -0,0 +1,70 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Console\Command\HelpCommand;
+use Symfony\Component\Console\Command\ListCommand;
+use Symfony\Component\Console\Application;
+
+class HelpCommandTest extends \PHPUnit_Framework_TestCase
+{
+ public function testExecuteForCommandAlias()
+ {
+ $command = new HelpCommand();
+ $command->setApplication(new Application());
+ $commandTester = new CommandTester($command);
+ $commandTester->execute(array('command_name' => 'li'), array('decorated' => false));
+ $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
+ $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
+ $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias');
+ }
+
+ public function testExecuteForCommand()
+ {
+ $command = new HelpCommand();
+ $commandTester = new CommandTester($command);
+ $command->setCommand(new ListCommand());
+ $commandTester->execute(array(), array('decorated' => false));
+ $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ }
+
+ public function testExecuteForCommandWithXmlOption()
+ {
+ $command = new HelpCommand();
+ $commandTester = new CommandTester($command);
+ $command->setCommand(new ListCommand());
+ $commandTester->execute(array('--format' => 'xml'));
+ $this->assertContains('getDisplay(), '->execute() returns an XML help text if --xml is passed');
+ }
+
+ public function testExecuteForApplicationCommand()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($application->get('help'));
+ $commandTester->execute(array('command_name' => 'list'));
+ $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ }
+
+ public function testExecuteForApplicationCommandWithXmlOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($application->get('help'));
+ $commandTester->execute(array('command_name' => 'list', '--format' => 'xml'));
+ $this->assertContains('list [--raw] [--format FORMAT] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command');
+ $this->assertContains('getDisplay(), '->execute() returns an XML help text if --format=xml is passed');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Command/ListCommandTest.php b/includes/src/vendor/symfony/console/Tests/Command/ListCommandTest.php
new file mode 100644
index 0000000..a166a04
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Command/ListCommandTest.php
@@ -0,0 +1,112 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Command;
+
+use Symfony\Component\Console\Tester\CommandTester;
+use Symfony\Component\Console\Application;
+
+class ListCommandTest extends \PHPUnit_Framework_TestCase
+{
+ public function testExecuteListsCommands()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName()), array('decorated' => false));
+
+ $this->assertRegExp('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands');
+ }
+
+ public function testExecuteListsCommandsWithXmlOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--format' => 'xml'));
+ $this->assertRegExp('//', $commandTester->getDisplay(), '->execute() returns a list of available commands in XML if --xml is passed');
+ }
+
+ public function testExecuteListsCommandsWithRawOption()
+ {
+ $application = new Application();
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--raw' => true));
+ $output = <<<'EOF'
+help Displays help for a command
+list Lists commands
+
+EOF;
+
+ $this->assertEquals($output, $commandTester->getDisplay(true));
+ }
+
+ public function testExecuteListsCommandsWithNamespaceArgument()
+ {
+ require_once realpath(__DIR__.'/../Fixtures/FooCommand.php');
+ $application = new Application();
+ $application->add(new \FooCommand());
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), 'namespace' => 'foo', '--raw' => true));
+ $output = <<<'EOF'
+foo:bar The foo:bar command
+
+EOF;
+
+ $this->assertEquals($output, $commandTester->getDisplay(true));
+ }
+
+ public function testExecuteListsCommandsOrder()
+ {
+ require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php');
+ $application = new Application();
+ $application->add(new \Foo6Command());
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName()), array('decorated' => false));
+ $output = <<<'EOF'
+Console Tool
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display this help message
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands:
+ help Displays help for a command
+ list Lists commands
+ 0foo
+ 0foo:bar 0foo:bar command
+EOF;
+
+ $this->assertEquals($output, trim($commandTester->getDisplay(true)));
+ }
+
+ public function testExecuteListsCommandsOrderRaw()
+ {
+ require_once realpath(__DIR__.'/../Fixtures/Foo6Command.php');
+ $application = new Application();
+ $application->add(new \Foo6Command());
+ $commandTester = new CommandTester($command = $application->get('list'));
+ $commandTester->execute(array('command' => $command->getName(), '--raw' => true));
+ $output = <<<'EOF'
+help Displays help for a command
+list Lists commands
+0foo:bar 0foo:bar command
+EOF;
+
+ $this->assertEquals($output, trim($commandTester->getDisplay(true)));
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php b/includes/src/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php
new file mode 100644
index 0000000..c36c4a8
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Descriptor/AbstractDescriptorTest.php
@@ -0,0 +1,106 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\BufferedOutput;
+
+abstract class AbstractDescriptorTest extends \PHPUnit_Framework_TestCase
+{
+ /** @dataProvider getDescribeInputArgumentTestData */
+ public function testDescribeInputArgument(InputArgument $argument, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $argument);
+ }
+
+ /** @dataProvider getDescribeInputOptionTestData */
+ public function testDescribeInputOption(InputOption $option, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $option);
+ }
+
+ /** @dataProvider getDescribeInputDefinitionTestData */
+ public function testDescribeInputDefinition(InputDefinition $definition, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $definition);
+ }
+
+ /** @dataProvider getDescribeCommandTestData */
+ public function testDescribeCommand(Command $command, $expectedDescription)
+ {
+ $this->assertDescription($expectedDescription, $command);
+ }
+
+ /** @dataProvider getDescribeApplicationTestData */
+ public function testDescribeApplication(Application $application, $expectedDescription)
+ {
+ // Replaces the dynamic placeholders of the command help text with a static version.
+ // The placeholder %command.full_name% includes the script path that is not predictable
+ // and can not be tested against.
+ foreach ($application->all() as $command) {
+ $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp()));
+ }
+
+ $this->assertDescription($expectedDescription, $application);
+ }
+
+ public function getDescribeInputArgumentTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputArguments());
+ }
+
+ public function getDescribeInputOptionTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputOptions());
+ }
+
+ public function getDescribeInputDefinitionTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getInputDefinitions());
+ }
+
+ public function getDescribeCommandTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getCommands());
+ }
+
+ public function getDescribeApplicationTestData()
+ {
+ return $this->getDescriptionTestData(ObjectsProvider::getApplications());
+ }
+
+ abstract protected function getDescriptor();
+
+ abstract protected function getFormat();
+
+ private function getDescriptionTestData(array $objects)
+ {
+ $data = array();
+ foreach ($objects as $name => $object) {
+ $description = file_get_contents(sprintf('%s/../Fixtures/%s.%s', __DIR__, $name, $this->getFormat()));
+ $data[] = array($object, $description);
+ }
+
+ return $data;
+ }
+
+ protected function assertDescription($expectedDescription, $describedObject)
+ {
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
+ $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
+ $this->assertEquals(trim($expectedDescription), trim(str_replace(PHP_EOL, "\n", $output->fetch())));
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php b/includes/src/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php
new file mode 100644
index 0000000..f9a1561
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Descriptor/JsonDescriptorTest.php
@@ -0,0 +1,35 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\JsonDescriptor;
+use Symfony\Component\Console\Output\BufferedOutput;
+
+class JsonDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new JsonDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'json';
+ }
+
+ protected function assertDescription($expectedDescription, $describedObject)
+ {
+ $output = new BufferedOutput(BufferedOutput::VERBOSITY_NORMAL, true);
+ $this->getDescriptor()->describe($output, $describedObject, array('raw_output' => true));
+ $this->assertEquals(json_decode(trim($expectedDescription), true), json_decode(trim(str_replace(PHP_EOL, "\n", $output->fetch())), true));
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php b/includes/src/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php
new file mode 100644
index 0000000..c85e8a5
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Descriptor/MarkdownDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\MarkdownDescriptor;
+
+class MarkdownDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new MarkdownDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'md';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php b/includes/src/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php
new file mode 100644
index 0000000..45b3b2f
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Descriptor/ObjectsProvider.php
@@ -0,0 +1,77 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputDefinition;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorApplication2;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand1;
+use Symfony\Component\Console\Tests\Fixtures\DescriptorCommand2;
+
+/**
+ * @author Jean-François Simon
+ */
+class ObjectsProvider
+{
+ public static function getInputArguments()
+ {
+ return array(
+ 'input_argument_1' => new InputArgument('argument_name', InputArgument::REQUIRED),
+ 'input_argument_2' => new InputArgument('argument_name', InputArgument::IS_ARRAY, 'argument description'),
+ 'input_argument_3' => new InputArgument('argument_name', InputArgument::OPTIONAL, 'argument description', 'default_value'),
+ 'input_argument_4' => new InputArgument('argument_name', InputArgument::REQUIRED, "multiline\nargument description"),
+ );
+ }
+
+ public static function getInputOptions()
+ {
+ return array(
+ 'input_option_1' => new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+ 'input_option_2' => new InputOption('option_name', 'o', InputOption::VALUE_OPTIONAL, 'option description', 'default_value'),
+ 'input_option_3' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, 'option description'),
+ 'input_option_4' => new InputOption('option_name', 'o', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'option description', array()),
+ 'input_option_5' => new InputOption('option_name', 'o', InputOption::VALUE_REQUIRED, "multiline\noption description"),
+ 'input_option_6' => new InputOption('option_name', array('o', 'O'), InputOption::VALUE_REQUIRED, 'option with multiple shortcuts'),
+ );
+ }
+
+ public static function getInputDefinitions()
+ {
+ return array(
+ 'input_definition_1' => new InputDefinition(),
+ 'input_definition_2' => new InputDefinition(array(new InputArgument('argument_name', InputArgument::REQUIRED))),
+ 'input_definition_3' => new InputDefinition(array(new InputOption('option_name', 'o', InputOption::VALUE_NONE))),
+ 'input_definition_4' => new InputDefinition(array(
+ new InputArgument('argument_name', InputArgument::REQUIRED),
+ new InputOption('option_name', 'o', InputOption::VALUE_NONE),
+ )),
+ );
+ }
+
+ public static function getCommands()
+ {
+ return array(
+ 'command_1' => new DescriptorCommand1(),
+ 'command_2' => new DescriptorCommand2(),
+ );
+ }
+
+ public static function getApplications()
+ {
+ return array(
+ 'application_1' => new DescriptorApplication1(),
+ 'application_2' => new DescriptorApplication2(),
+ );
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php b/includes/src/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php
new file mode 100644
index 0000000..350b679
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Descriptor/TextDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\TextDescriptor;
+
+class TextDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new TextDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'txt';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php b/includes/src/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php
new file mode 100644
index 0000000..59a5d1e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Descriptor/XmlDescriptorTest.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Descriptor;
+
+use Symfony\Component\Console\Descriptor\XmlDescriptor;
+
+class XmlDescriptorTest extends AbstractDescriptorTest
+{
+ protected function getDescriptor()
+ {
+ return new XmlDescriptor();
+ }
+
+ protected function getFormat()
+ {
+ return 'xml';
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php b/includes/src/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php
new file mode 100644
index 0000000..52b619e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/BarBucCommand.php
@@ -0,0 +1,11 @@
+setName('bar:buc');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php
new file mode 100644
index 0000000..132b6d5
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorApplication1.php
@@ -0,0 +1,18 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication1 extends Application
+{
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php
new file mode 100644
index 0000000..ff55135
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorApplication2.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Application;
+
+class DescriptorApplication2 extends Application
+{
+ public function __construct()
+ {
+ parent::__construct('My Symfony application', 'v1.0');
+ $this->add(new DescriptorCommand1());
+ $this->add(new DescriptorCommand2());
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php
new file mode 100644
index 0000000..ede05d7
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorCommand1.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+
+class DescriptorCommand1 extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('descriptor:command1')
+ ->setAliases(array('alias1', 'alias2'))
+ ->setDescription('command 1 description')
+ ->setHelp('command 1 help')
+ ;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php
new file mode 100644
index 0000000..51106b9
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/DescriptorCommand2.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputOption;
+
+class DescriptorCommand2 extends Command
+{
+ protected function configure()
+ {
+ $this
+ ->setName('descriptor:command2')
+ ->setDescription('command 2 description')
+ ->setHelp('command 2 help')
+ ->addUsage('-o|--option_name ')
+ ->addUsage('')
+ ->addArgument('argument_name', InputArgument::REQUIRED)
+ ->addOption('option_name', 'o', InputOption::VALUE_NONE)
+ ;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/DummyOutput.php b/includes/src/vendor/symfony/console/Tests/Fixtures/DummyOutput.php
new file mode 100644
index 0000000..0070c0a
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/DummyOutput.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Console\Tests\Fixtures;
+
+use Symfony\Component\Console\Output\BufferedOutput;
+
+/**
+ * Dummy output.
+ *
+ * @author Kévin Dunglas
+ */
+class DummyOutput extends BufferedOutput
+{
+ /**
+ * @return array
+ */
+ public function getLogs()
+ {
+ $logs = array();
+ foreach (explode("\n", trim($this->fetch())) as $message) {
+ preg_match('/^\[(.*)\] (.*)/', $message, $matches);
+ $logs[] = sprintf('%s %s', $matches[1], $matches[2]);
+ }
+
+ return $logs;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Foo1Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo1Command.php
new file mode 100644
index 0000000..254162f
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo1Command.php
@@ -0,0 +1,26 @@
+setName('foo:bar1')
+ ->setDescription('The foo:bar1 command')
+ ->setAliases(array('afoobar1'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Foo2Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo2Command.php
new file mode 100644
index 0000000..8071dc8
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo2Command.php
@@ -0,0 +1,21 @@
+setName('foo1:bar')
+ ->setDescription('The foo1:bar command')
+ ->setAliases(array('afoobar2'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Foo3Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo3Command.php
new file mode 100644
index 0000000..adb3a2d
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo3Command.php
@@ -0,0 +1,29 @@
+setName('foo3:bar')
+ ->setDescription('The foo3:bar command')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ try {
+ try {
+ throw new \Exception('First exception
this is html
');
+ } catch (\Exception $e) {
+ throw new \Exception('Second exception comment', 0, $e);
+ }
+ } catch (\Exception $e) {
+ throw new \Exception('Third exception comment>', 404, $e);
+ }
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Foo4Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo4Command.php
new file mode 100644
index 0000000..1c54639
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo4Command.php
@@ -0,0 +1,11 @@
+setName('foo3:bar:toh');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Foo5Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo5Command.php
new file mode 100644
index 0000000..a1c6082
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Foo5Command.php
@@ -0,0 +1,10 @@
+setName('0foo:bar')->setDescription('0foo:bar command');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/FooCommand.php b/includes/src/vendor/symfony/console/Tests/Fixtures/FooCommand.php
new file mode 100644
index 0000000..355e0ad
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/FooCommand.php
@@ -0,0 +1,33 @@
+setName('foo:bar')
+ ->setDescription('The foo:bar command')
+ ->setAliases(array('afoobar'))
+ ;
+ }
+
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('interact called');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+
+ $output->writeln('called');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php
new file mode 100644
index 0000000..fc50c72
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced1Command.php
@@ -0,0 +1,26 @@
+setName('foo:bar:baz')
+ ->setDescription('The foo:bar:baz command')
+ ->setAliases(array('foobarbaz'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php b/includes/src/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php
new file mode 100644
index 0000000..1cf31ff
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/FooSubnamespaced2Command.php
@@ -0,0 +1,26 @@
+setName('foo:go:bret')
+ ->setDescription('The foo:bar:go command')
+ ->setAliases(array('foobargo'))
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php b/includes/src/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php
new file mode 100644
index 0000000..9681628
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/FoobarCommand.php
@@ -0,0 +1,25 @@
+setName('foobar:foo')
+ ->setDescription('The foobar:foo command')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $this->input = $input;
+ $this->output = $output;
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php
new file mode 100644
index 0000000..996fafb
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_0.php
@@ -0,0 +1,11 @@
+caution('Lorem ipsum dolor sit amet');
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php
new file mode 100644
index 0000000..6634cd5
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_1.php
@@ -0,0 +1,13 @@
+title('Title');
+ $output->warning('Lorem ipsum dolor sit amet');
+ $output->title('Title');
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php
new file mode 100644
index 0000000..4120df9
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_10.php
@@ -0,0 +1,17 @@
+block(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
+ 'CUSTOM',
+ 'fg=white;bg=green',
+ 'X ',
+ true
+ );
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php
new file mode 100644
index 0000000..678afea
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_11.php
@@ -0,0 +1,12 @@
+block($word, 'CUSTOM', 'fg=white;bg=blue', ' § ', false);
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php
new file mode 100644
index 0000000..4386e56
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_12.php
@@ -0,0 +1,13 @@
+comment(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
+ );
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php
new file mode 100644
index 0000000..fe08436
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_13.php
@@ -0,0 +1,15 @@
+setDecorated(true);
+ $output = new SymfonyStyle($input, $output);
+ $output->comment(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum'
+ );
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php
new file mode 100644
index 0000000..e719f71
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_14.php
@@ -0,0 +1,17 @@
+block(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
+ null,
+ null,
+ '$ ',
+ true
+ );
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php
new file mode 100644
index 0000000..29e555b
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_15.php
@@ -0,0 +1,14 @@
+block(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
+ 'TEST'
+ );
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php
new file mode 100644
index 0000000..f21fc10
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_16.php
@@ -0,0 +1,15 @@
+setDecorated(true);
+ $output = new SymfonyStyleWithForcedLineLength($input, $output);
+ $output->success(
+ 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
+ 'TEST'
+ );
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php
new file mode 100644
index 0000000..6004e3d
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_2.php
@@ -0,0 +1,16 @@
+warning('Warning');
+ $output->caution('Caution');
+ $output->error('Error');
+ $output->success('Success');
+ $output->note('Note');
+ $output->block('Custom block', 'CUSTOM', 'fg=white;bg=green', 'X ', true);
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php
new file mode 100644
index 0000000..c7a08f1
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_3.php
@@ -0,0 +1,12 @@
+title('First title');
+ $output->title('Second title');
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php
new file mode 100644
index 0000000..afea70c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_4.php
@@ -0,0 +1,34 @@
+write('Lorem ipsum dolor sit amet');
+ $output->title('First title');
+
+ $output->writeln('Lorem ipsum dolor sit amet');
+ $output->title('Second title');
+
+ $output->write('Lorem ipsum dolor sit amet');
+ $output->write('');
+ $output->title('Third title');
+
+ //Ensure edge case by appending empty strings to history:
+ $output->write('Lorem ipsum dolor sit amet');
+ $output->write(array('', '', ''));
+ $output->title('Fourth title');
+
+ //Ensure have manual control over number of blank lines:
+ $output->writeln('Lorem ipsum dolor sit amet');
+ $output->writeln(array('', '')); //Should append an extra blank line
+ $output->title('Fifth title');
+
+ $output->writeln('Lorem ipsum dolor sit amet');
+ $output->newLine(2); //Should append an extra blank line
+ $output->title('Fifth title');
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php
new file mode 100644
index 0000000..d2c68a9
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_5.php
@@ -0,0 +1,37 @@
+writeln('Lorem ipsum dolor sit amet');
+ $output->listing(array(
+ 'Lorem ipsum dolor sit amet',
+ 'consectetur adipiscing elit',
+ ));
+
+ //Even using write:
+ $output->write('Lorem ipsum dolor sit amet');
+ $output->listing(array(
+ 'Lorem ipsum dolor sit amet',
+ 'consectetur adipiscing elit',
+ ));
+
+ $output->write('Lorem ipsum dolor sit amet');
+ $output->text(array(
+ 'Lorem ipsum dolor sit amet',
+ 'consectetur adipiscing elit',
+ ));
+
+ $output->newLine();
+
+ $output->write('Lorem ipsum dolor sit amet');
+ $output->comment(array(
+ 'Lorem ipsum dolor sit amet',
+ 'consectetur adipiscing elit',
+ ));
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php
new file mode 100644
index 0000000..f1d7990
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_6.php
@@ -0,0 +1,16 @@
+listing(array(
+ 'Lorem ipsum dolor sit amet',
+ 'consectetur adipiscing elit',
+ ));
+ $output->success('Lorem ipsum dolor sit amet');
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php
new file mode 100644
index 0000000..cbfea73
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_7.php
@@ -0,0 +1,15 @@
+title('Title');
+ $output->askHidden('Hidden question');
+ $output->choice('Choice question with default', array('choice1', 'choice2'), 'choice1');
+ $output->confirm('Confirmation with yes default', true);
+ $output->text('Duis aute irure dolor in reprehenderit in voluptate velit esse');
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php
new file mode 100644
index 0000000..0244fd2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_8.php
@@ -0,0 +1,26 @@
+ 3))),
+ array('ISBN', 'Title', 'Author'),
+ );
+
+ $rows = array(
+ array(
+ '978-0521567817',
+ 'De Monarchia',
+ new TableCell("Dante Alighieri\nspans multiple rows", array('rowspan' => 2)),
+ ),
+ array('978-0804169127', 'Divine Comedy'),
+ );
+
+ $output = new SymfonyStyleWithForcedLineLength($input, $output);
+ $output->table($headers, $rows);
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php
new file mode 100644
index 0000000..6420730
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/command/command_9.php
@@ -0,0 +1,11 @@
+block(array('Custom block', 'Second custom block line'), 'CUSTOM', 'fg=white;bg=green', 'X ', true);
+};
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt
new file mode 100644
index 0000000..a42e0f7
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_0.txt
@@ -0,0 +1,3 @@
+
+ ! [CAUTION] Lorem ipsum dolor sit amet
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt
new file mode 100644
index 0000000..334875f
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_1.txt
@@ -0,0 +1,9 @@
+
+Title
+=====
+
+ [WARNING] Lorem ipsum dolor sit amet
+
+Title
+=====
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt
new file mode 100644
index 0000000..385c6a2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_10.txt
@@ -0,0 +1,7 @@
+
+X [CUSTOM] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
+X dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+X commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
+X nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
+X anim id est laborum
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt
new file mode 100644
index 0000000..190d784
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_11.txt
@@ -0,0 +1,4 @@
+
+ § [CUSTOM] Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophatto
+ § peristeralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt
new file mode 100644
index 0000000..9983af8
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_12.txt
@@ -0,0 +1,6 @@
+
+ // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ // aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ // Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
+ // sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt
new file mode 100644
index 0000000..0f3704b
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_13.txt
@@ -0,0 +1,7 @@
+
+[39;49m // [39;49mLorem ipsum dolor sit [33mamet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et [39m
+[39;49m // [39;49m[33mdolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea [39m
+[39;49m // [39;49m[33mcommodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla [39m
+[39;49m // [39;49m[33mpariatur.[39m Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
+[39;49m // [39;49mid est laborum
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt
new file mode 100644
index 0000000..1d0d37e
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_14.txt
@@ -0,0 +1,6 @@
+
+$ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+$ aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+$ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
+$ occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt
new file mode 100644
index 0000000..66404b8
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_15.txt
@@ -0,0 +1,7 @@
+
+ [TEST] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore
+ magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
+ pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
+ laborum
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt
new file mode 100644
index 0000000..a0d1801
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_16.txt
@@ -0,0 +1,8 @@
+
+[30;42m [39;49m
+[30;42m [OK] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore [39;49m
+[30;42m magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo [39;49m
+[30;42m consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. [39;49m
+[30;42m Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum [39;49m
+[30;42m [39;49m
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt
new file mode 100644
index 0000000..ca60976
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_2.txt
@@ -0,0 +1,13 @@
+
+ [WARNING] Warning
+
+ ! [CAUTION] Caution
+
+ [ERROR] Error
+
+ [OK] Success
+
+ ! [NOTE] Note
+
+X [CUSTOM] Custom block
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt
new file mode 100644
index 0000000..f4b6d58
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_3.txt
@@ -0,0 +1,7 @@
+
+First title
+===========
+
+Second title
+============
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt
new file mode 100644
index 0000000..2646d85
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_4.txt
@@ -0,0 +1,32 @@
+Lorem ipsum dolor sit amet
+
+First title
+===========
+
+Lorem ipsum dolor sit amet
+
+Second title
+============
+
+Lorem ipsum dolor sit amet
+
+Third title
+===========
+
+Lorem ipsum dolor sit amet
+
+Fourth title
+============
+
+Lorem ipsum dolor sit amet
+
+
+Fifth title
+===========
+
+Lorem ipsum dolor sit amet
+
+
+Fifth title
+===========
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt
new file mode 100644
index 0000000..be4a2db
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_5.txt
@@ -0,0 +1,18 @@
+Lorem ipsum dolor sit amet
+ * Lorem ipsum dolor sit amet
+ * consectetur adipiscing elit
+
+Lorem ipsum dolor sit amet
+ * Lorem ipsum dolor sit amet
+ * consectetur adipiscing elit
+
+Lorem ipsum dolor sit amet
+ Lorem ipsum dolor sit amet
+ consectetur adipiscing elit
+
+Lorem ipsum dolor sit amet
+
+ // Lorem ipsum dolor sit amet
+ //
+ // consectetur adipiscing elit
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt
new file mode 100644
index 0000000..5f2d33c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_6.txt
@@ -0,0 +1,6 @@
+
+ * Lorem ipsum dolor sit amet
+ * consectetur adipiscing elit
+
+ [OK] Lorem ipsum dolor sit amet
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt
new file mode 100644
index 0000000..ecea977
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_7.txt
@@ -0,0 +1,5 @@
+
+Title
+=====
+
+ Duis aute irure dolor in reprehenderit in voluptate velit esse
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt
new file mode 100644
index 0000000..005b846
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_8.txt
@@ -0,0 +1,9 @@
+ ---------------- --------------- ---------------------
+ Main table title
+ ---------------- --------------- ---------------------
+ ISBN Title Author
+ ---------------- --------------- ---------------------
+ 978-0521567817 De Monarchia Dante Alighieri
+ 978-0804169127 Divine Comedy spans multiple rows
+ ---------------- --------------- ---------------------
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt
new file mode 100644
index 0000000..069c0d5
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/Style/SymfonyStyle/output/output_9.txt
@@ -0,0 +1,5 @@
+
+X [CUSTOM] Custom block
+X
+X Second custom block line
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/TestCommand.php b/includes/src/vendor/symfony/console/Tests/Fixtures/TestCommand.php
new file mode 100644
index 0000000..dcd3273
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/TestCommand.php
@@ -0,0 +1,28 @@
+setName('namespace:name')
+ ->setAliases(array('name'))
+ ->setDescription('description')
+ ->setHelp('help')
+ ;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('execute called');
+ }
+
+ protected function interact(InputInterface $input, OutputInterface $output)
+ {
+ $output->writeln('interact called');
+ }
+}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.json b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.json
new file mode 100644
index 0000000..b3ad97d
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.json
@@ -0,0 +1 @@
+{"commands":[{"name":"help","usage":["help [--format FORMAT] [--raw] [--] []"],"description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"list","usage":["list [--raw] [--format FORMAT] [--] []"],"description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"}}}}],"namespaces":[{"id":"_global","commands":["help","list"]}]}
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.md b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.md
new file mode 100644
index 0000000..f1d88c5
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.md
@@ -0,0 +1,181 @@
+UNKNOWN
+=======
+
+* help
+* list
+
+help
+----
+
+* Description: Displays help for a command
+* Usage:
+
+ * `help [--format FORMAT] [--raw] [--] []`
+
+The help command displays help for a given command:
+
+ php app/console help list
+
+You can also output the help in other formats by using the --format option:
+
+ php app/console help --format=xml list
+
+To display the list of available commands, please use the list command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: The output format (txt, xml, json, or md)
+* Default: `'txt'`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage:
+
+ * `list [--raw] [--format FORMAT] [--] []`
+
+The list command lists all commands:
+
+ php app/console list
+
+You can also display the commands for a specific namespace:
+
+ php app/console list test
+
+You can also output the information in other formats by using the --format option:
+
+ php app/console list --format=xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php app/console list --raw
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: The output format (txt, xml, json, or md)
+* Default: `'txt'`
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.txt
new file mode 100644
index 0000000..c4cf8f2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.txt
@@ -0,0 +1,17 @@
+Console Tool
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display this help message
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands:
+ help Displays help for a command
+ list Lists commands
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.xml b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.xml
new file mode 100644
index 0000000..8514f23
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_1.xml
@@ -0,0 +1,104 @@
+
+
+
+
+
+ help [--format FORMAT] [--raw] [--] [<command_name>]
+
+ Displays help for a command
+ The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+ You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+ To display the list of available commands, please use the <info>list</info> command.
+
+
+ The command name
+
+ help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ list [--raw] [--format FORMAT] [--] [<namespace>]
+
+ Lists commands
+ The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+ You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+ You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+
+ The namespace name
+
+
+
+
+
+
+
+
+
+
+
+ help
+ list
+
+
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.json b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.json
new file mode 100644
index 0000000..e8870ba
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.json
@@ -0,0 +1 @@
+{"commands":[{"name":"help","usage":["help [--format FORMAT] [--raw] [--] []"],"description":"Displays help for a command","help":"The help<\/info> command displays help for a given command:\n\n php app\/console help list<\/info>\n\nYou can also output the help in other formats by using the --format<\/comment> option:\n\n php app\/console help --format=xml list<\/info>\n\nTo display the list of available commands, please use the list<\/info> command.","definition":{"arguments":{"command_name":{"name":"command_name","is_required":false,"is_array":false,"description":"The command name","default":"help"}},"options":{"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"},"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command help","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"list","usage":["list [--raw] [--format FORMAT] [--] []"],"description":"Lists commands","help":"The list<\/info> command lists all commands:\n\n php app\/console list<\/info>\n\nYou can also display the commands for a specific namespace:\n\n php app\/console list test<\/info>\n\nYou can also output the information in other formats by using the --format<\/comment> option:\n\n php app\/console list --format=xml<\/info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n php app\/console list --raw<\/info>","definition":{"arguments":{"namespace":{"name":"namespace","is_required":false,"is_array":false,"description":"The namespace name","default":null}},"options":{"raw":{"name":"--raw","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"To output raw command list","default":false},"format":{"name":"--format","shortcut":"","accept_value":true,"is_value_required":true,"is_multiple":false,"description":"The output format (txt, xml, json, or md)","default":"txt"}}}},{"name":"descriptor:command1","usage":["descriptor:command1", "alias1", "alias2"],"description":"command 1 description","help":"command 1 help","definition":{"arguments":[],"options":{"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}},{"name":"descriptor:command2","usage":["descriptor:command2 [-o|--option_name] [--] ", "descriptor:command2 -o|--option_name ", "descriptor:command2 "],"description":"command 2 description","help":"command 2 help","definition":{"arguments":{"argument_name":{"name":"argument_name","is_required":true,"is_array":false,"description":"","default":null}},"options":{"option_name":{"name":"--option_name","shortcut":"-o","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"","default":false},"help":{"name":"--help","shortcut":"-h","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this help message","default":false},"quiet":{"name":"--quiet","shortcut":"-q","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not output any message","default":false},"verbose":{"name":"--verbose","shortcut":"-v|-vv|-vvv","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug","default":false},"version":{"name":"--version","shortcut":"-V","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Display this application version","default":false},"ansi":{"name":"--ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Force ANSI output","default":false},"no-ansi":{"name":"--no-ansi","shortcut":"","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Disable ANSI output","default":false},"no-interaction":{"name":"--no-interaction","shortcut":"-n","accept_value":false,"is_value_required":false,"is_multiple":false,"description":"Do not ask any interactive question","default":false}}}}],"namespaces":[{"id":"_global","commands":["alias1","alias2","help","list"]},{"id":"descriptor","commands":["descriptor:command1","descriptor:command2"]}]}
\ No newline at end of file
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.md b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.md
new file mode 100644
index 0000000..63b2d9a
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.md
@@ -0,0 +1,376 @@
+My Symfony application
+======================
+
+* alias1
+* alias2
+* help
+* list
+
+**descriptor:**
+
+* descriptor:command1
+* descriptor:command2
+
+help
+----
+
+* Description: Displays help for a command
+* Usage:
+
+ * `help [--format FORMAT] [--raw] [--] []`
+
+The help command displays help for a given command:
+
+ php app/console help list
+
+You can also output the help in other formats by using the --format option:
+
+ php app/console help --format=xml list
+
+To display the list of available commands, please use the list command.
+
+### Arguments:
+
+**command_name:**
+
+* Name: command_name
+* Is required: no
+* Is array: no
+* Description: The command name
+* Default: `'help'`
+
+### Options:
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: The output format (txt, xml, json, or md)
+* Default: `'txt'`
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command help
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
+
+list
+----
+
+* Description: Lists commands
+* Usage:
+
+ * `list [--raw] [--format FORMAT] [--] []`
+
+The list command lists all commands:
+
+ php app/console list
+
+You can also display the commands for a specific namespace:
+
+ php app/console list test
+
+You can also output the information in other formats by using the --format option:
+
+ php app/console list --format=xml
+
+It's also possible to get raw list of commands (useful for embedding command runner):
+
+ php app/console list --raw
+
+### Arguments:
+
+**namespace:**
+
+* Name: namespace
+* Is required: no
+* Is array: no
+* Description: The namespace name
+* Default: `NULL`
+
+### Options:
+
+**raw:**
+
+* Name: `--raw`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: To output raw command list
+* Default: `false`
+
+**format:**
+
+* Name: `--format`
+* Shortcut:
+* Accept value: yes
+* Is value required: yes
+* Is multiple: no
+* Description: The output format (txt, xml, json, or md)
+* Default: `'txt'`
+
+descriptor:command1
+-------------------
+
+* Description: command 1 description
+* Usage:
+
+ * `descriptor:command1`
+ * `alias1`
+ * `alias2`
+
+command 1 help
+
+### Options:
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
+
+descriptor:command2
+-------------------
+
+* Description: command 2 description
+* Usage:
+
+ * `descriptor:command2 [-o|--option_name] [--] `
+ * `descriptor:command2 -o|--option_name `
+ * `descriptor:command2 `
+
+command 2 help
+
+### Arguments:
+
+**argument_name:**
+
+* Name: argument_name
+* Is required: yes
+* Is array: no
+* Description:
+* Default: `NULL`
+
+### Options:
+
+**option_name:**
+
+* Name: `--option_name`
+* Shortcut: `-o`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description:
+* Default: `false`
+
+**help:**
+
+* Name: `--help`
+* Shortcut: `-h`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this help message
+* Default: `false`
+
+**quiet:**
+
+* Name: `--quiet`
+* Shortcut: `-q`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not output any message
+* Default: `false`
+
+**verbose:**
+
+* Name: `--verbose`
+* Shortcut: `-v|-vv|-vvv`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+* Default: `false`
+
+**version:**
+
+* Name: `--version`
+* Shortcut: `-V`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Display this application version
+* Default: `false`
+
+**ansi:**
+
+* Name: `--ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Force ANSI output
+* Default: `false`
+
+**no-ansi:**
+
+* Name: `--no-ansi`
+* Shortcut:
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Disable ANSI output
+* Default: `false`
+
+**no-interaction:**
+
+* Name: `--no-interaction`
+* Shortcut: `-n`
+* Accept value: no
+* Is value required: no
+* Is multiple: no
+* Description: Do not ask any interactive question
+* Default: `false`
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.txt
new file mode 100644
index 0000000..292aa82
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.txt
@@ -0,0 +1,22 @@
+My Symfony application version v1.0
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display this help message
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands:
+ alias1 command 1 description
+ alias2 command 1 description
+ help Displays help for a command
+ list Lists commands
+ descriptor
+ descriptor:command1 command 1 description
+ descriptor:command2 command 2 description
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.xml b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.xml
new file mode 100644
index 0000000..62e3cfc
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_2.xml
@@ -0,0 +1,184 @@
+
+
+
+
+
+ help [--format FORMAT] [--raw] [--] [<command_name>]
+
+ Displays help for a command
+ The <info>help</info> command displays help for a given command:
+
+ <info>php app/console help list</info>
+
+ You can also output the help in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console help --format=xml list</info>
+
+ To display the list of available commands, please use the <info>list</info> command.
+
+
+ The command name
+
+ help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ list [--raw] [--format FORMAT] [--] [<namespace>]
+
+ Lists commands
+ The <info>list</info> command lists all commands:
+
+ <info>php app/console list</info>
+
+ You can also display the commands for a specific namespace:
+
+ <info>php app/console list test</info>
+
+ You can also output the information in other formats by using the <comment>--format</comment> option:
+
+ <info>php app/console list --format=xml</info>
+
+ It's also possible to get raw list of commands (useful for embedding command runner):
+
+ <info>php app/console list --raw</info>
+
+
+ The namespace name
+
+
+
+
+
+
+
+
+
+
+ descriptor:command1
+ alias1
+ alias2
+
+ command 1 description
+ command 1 help
+
+
+
+
+
+
+
+
+
+
+
+
+
+ descriptor:command2 [-o|--option_name] [--] <argument_name>
+ descriptor:command2 -o|--option_name <argument_name>
+ descriptor:command2 <argument_name>
+
+ command 2 description
+ command 2 help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ alias1
+ alias2
+ help
+ list
+
+
+ descriptor:command1
+ descriptor:command2
+
+
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_astext1.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_astext1.txt
new file mode 100644
index 0000000..19dacb2
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_astext1.txt
@@ -0,0 +1,20 @@
+Console Tool
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display this help message
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands:
+ afoobar The foo:bar command
+ help Displays help for a command
+ list Lists commands
+ foo
+ foo:bar The foo:bar command
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_astext2.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_astext2.txt
new file mode 100644
index 0000000..c99ccdd
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_astext2.txt
@@ -0,0 +1,16 @@
+Console Tool
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display this help message
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi Force ANSI output
+ --no-ansi Disable ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands for the "foo" namespace:
+ foo:bar The foo:bar command
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt
new file mode 100644
index 0000000..0c16e3c
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_gethelp.txt
@@ -0,0 +1 @@
+Console Tool
\ No newline at end of file
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt
new file mode 100644
index 0000000..919cec4
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception1.txt
@@ -0,0 +1,6 @@
+
+
+ [Symfony\Component\Console\Exception\CommandNotFoundException]
+ Command "foo" is not defined.
+
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt
new file mode 100644
index 0000000..6456171
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception2.txt
@@ -0,0 +1,8 @@
+
+
+ [Symfony\Component\Console\Exception\InvalidOptionException]
+ The "--foo" option does not exist.
+
+
+list [--raw] [--format FORMAT] [--] []
+
diff --git a/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt b/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt
new file mode 100644
index 0000000..8276137
--- /dev/null
+++ b/includes/src/vendor/symfony/console/Tests/Fixtures/application_renderexception3.txt
@@ -0,0 +1,18 @@
+
+
+ [Exception]
+ Third exception comment
+
+
+
+ [Exception]
+ Second exception comment
+
+
+
+ [Exception]
+ First exception