Index: vendor/guzzlehttp/guzzle/src/BodySummarizer.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/BodySummarizer.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/BodySummarizer.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,28 @@
+<?php
+
+namespace GuzzleHttp;
+
+use Psr\Http\Message\MessageInterface;
+
+final class BodySummarizer implements BodySummarizerInterface
+{
+    /**
+     * @var int|null
+     */
+    private $truncateAt;
+
+    public function __construct(?int $truncateAt = null)
+    {
+        $this->truncateAt = $truncateAt;
+    }
+
+    /**
+     * Returns a summarized message body.
+     */
+    public function summarize(MessageInterface $message): ?string
+    {
+        return $this->truncateAt === null
+            ? Psr7\Message::bodySummary($message)
+            : Psr7\Message::bodySummary($message, $this->truncateAt);
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,13 @@
+<?php
+
+namespace GuzzleHttp;
+
+use Psr\Http\Message\MessageInterface;
+
+interface BodySummarizerInterface
+{
+    /**
+     * Returns a summarized message body.
+     */
+    public function summarize(MessageInterface $message): ?string;
+}
Index: vendor/guzzlehttp/guzzle/src/Client.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Client.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Client.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,483 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Cookie\CookieJar;
+use GuzzleHttp\Exception\GuzzleException;
+use GuzzleHttp\Exception\InvalidArgumentException;
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * @final
+ */
+class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
+{
+    use ClientTrait;
+
+    /**
+     * @var array Default request options
+     */
+    private $config;
+
+    /**
+     * Clients accept an array of constructor parameters.
+     *
+     * Here's an example of creating a client using a base_uri and an array of
+     * default request options to apply to each request:
+     *
+     *     $client = new Client([
+     *         'base_uri'        => 'http://www.foo.com/1.0/',
+     *         'timeout'         => 0,
+     *         'allow_redirects' => false,
+     *         'proxy'           => '192.168.16.1:10'
+     *     ]);
+     *
+     * Client configuration settings include the following options:
+     *
+     * - handler: (callable) Function that transfers HTTP requests over the
+     *   wire. The function is called with a Psr7\Http\Message\RequestInterface
+     *   and array of transfer options, and must return a
+     *   GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
+     *   Psr7\Http\Message\ResponseInterface on success.
+     *   If no handler is provided, a default handler will be created
+     *   that enables all of the request options below by attaching all of the
+     *   default middleware to the handler.
+     * - base_uri: (string|UriInterface) Base URI of the client that is merged
+     *   into relative URIs. Can be a string or instance of UriInterface.
+     * - **: any request option
+     *
+     * @param array $config Client configuration settings.
+     *
+     * @see RequestOptions for a list of available request options.
+     */
+    public function __construct(array $config = [])
+    {
+        if (!isset($config['handler'])) {
+            $config['handler'] = HandlerStack::create();
+        } elseif (!\is_callable($config['handler'])) {
+            throw new InvalidArgumentException('handler must be a callable');
+        }
+
+        // Convert the base_uri to a UriInterface
+        if (isset($config['base_uri'])) {
+            $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']);
+        }
+
+        $this->configureDefaults($config);
+    }
+
+    /**
+     * @param string $method
+     * @param array  $args
+     *
+     * @return PromiseInterface|ResponseInterface
+     *
+     * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0.
+     */
+    public function __call($method, $args)
+    {
+        if (\count($args) < 1) {
+            throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
+        }
+
+        $uri = $args[0];
+        $opts = $args[1] ?? [];
+
+        return \substr($method, -5) === 'Async'
+            ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts)
+            : $this->request($method, $uri, $opts);
+    }
+
+    /**
+     * Asynchronously send an HTTP request.
+     *
+     * @param array $options Request options to apply to the given
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
+     */
+    public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface
+    {
+        // Merge the base URI into the request URI if needed.
+        $options = $this->prepareDefaults($options);
+
+        return $this->transfer(
+            $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
+            $options
+        );
+    }
+
+    /**
+     * Send an HTTP request.
+     *
+     * @param array $options Request options to apply to the given
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
+     *
+     * @throws GuzzleException
+     */
+    public function send(RequestInterface $request, array $options = []): ResponseInterface
+    {
+        $options[RequestOptions::SYNCHRONOUS] = true;
+
+        return $this->sendAsync($request, $options)->wait();
+    }
+
+    /**
+     * The HttpClient PSR (PSR-18) specify this method.
+     *
+     * {@inheritDoc}
+     */
+    public function sendRequest(RequestInterface $request): ResponseInterface
+    {
+        $options[RequestOptions::SYNCHRONOUS] = true;
+        $options[RequestOptions::ALLOW_REDIRECTS] = false;
+        $options[RequestOptions::HTTP_ERRORS] = false;
+
+        return $this->sendAsync($request, $options)->wait();
+    }
+
+    /**
+     * Create and send an asynchronous HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string              $method  HTTP method
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
+     */
+    public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface
+    {
+        $options = $this->prepareDefaults($options);
+        // Remove request modifying parameter because it can be done up-front.
+        $headers = $options['headers'] ?? [];
+        $body = $options['body'] ?? null;
+        $version = $options['version'] ?? '1.1';
+        // Merge the URI into the base URI.
+        $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options);
+        if (\is_array($body)) {
+            throw $this->invalidBody();
+        }
+        $request = new Psr7\Request($method, $uri, $headers, $body, $version);
+        // Remove the option so that they are not doubly-applied.
+        unset($options['headers'], $options['body'], $options['version']);
+
+        return $this->transfer($request, $options);
+    }
+
+    /**
+     * Create and send an HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string              $method  HTTP method.
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
+     *
+     * @throws GuzzleException
+     */
+    public function request(string $method, $uri = '', array $options = []): ResponseInterface
+    {
+        $options[RequestOptions::SYNCHRONOUS] = true;
+
+        return $this->requestAsync($method, $uri, $options)->wait();
+    }
+
+    /**
+     * Get a client configuration option.
+     *
+     * These options include default request options of the client, a "handler"
+     * (if utilized by the concrete client), and a "base_uri" if utilized by
+     * the concrete client.
+     *
+     * @param string|null $option The config option to retrieve.
+     *
+     * @return mixed
+     *
+     * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
+     */
+    public function getConfig(?string $option = null)
+    {
+        return $option === null
+            ? $this->config
+            : ($this->config[$option] ?? null);
+    }
+
+    private function buildUri(UriInterface $uri, array $config): UriInterface
+    {
+        if (isset($config['base_uri'])) {
+            $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri);
+        }
+
+        if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
+            $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion'];
+            $uri = Utils::idnUriConvert($uri, $idnOptions);
+        }
+
+        return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
+    }
+
+    /**
+     * Configures the default options for a client.
+     */
+    private function configureDefaults(array $config): void
+    {
+        $defaults = [
+            'allow_redirects' => RedirectMiddleware::$defaultSettings,
+            'http_errors' => true,
+            'decode_content' => true,
+            'verify' => true,
+            'cookies' => false,
+            'idn_conversion' => false,
+        ];
+
+        // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
+
+        // We can only trust the HTTP_PROXY environment variable in a CLI
+        // process due to the fact that PHP has no reliable mechanism to
+        // get environment variables that start with "HTTP_".
+        if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) {
+            $defaults['proxy']['http'] = $proxy;
+        }
+
+        if ($proxy = Utils::getenv('HTTPS_PROXY')) {
+            $defaults['proxy']['https'] = $proxy;
+        }
+
+        if ($noProxy = Utils::getenv('NO_PROXY')) {
+            $cleanedNoProxy = \str_replace(' ', '', $noProxy);
+            $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy);
+        }
+
+        $this->config = $config + $defaults;
+
+        if (!empty($config['cookies']) && $config['cookies'] === true) {
+            $this->config['cookies'] = new CookieJar();
+        }
+
+        // Add the default user-agent header.
+        if (!isset($this->config['headers'])) {
+            $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()];
+        } else {
+            // Add the User-Agent header if one was not already set.
+            foreach (\array_keys($this->config['headers']) as $name) {
+                if (\strtolower($name) === 'user-agent') {
+                    return;
+                }
+            }
+            $this->config['headers']['User-Agent'] = Utils::defaultUserAgent();
+        }
+    }
+
+    /**
+     * Merges default options into the array.
+     *
+     * @param array $options Options to modify by reference
+     */
+    private function prepareDefaults(array $options): array
+    {
+        $defaults = $this->config;
+
+        if (!empty($defaults['headers'])) {
+            // Default headers are only added if they are not present.
+            $defaults['_conditional'] = $defaults['headers'];
+            unset($defaults['headers']);
+        }
+
+        // Special handling for headers is required as they are added as
+        // conditional headers and as headers passed to a request ctor.
+        if (\array_key_exists('headers', $options)) {
+            // Allows default headers to be unset.
+            if ($options['headers'] === null) {
+                $defaults['_conditional'] = [];
+                unset($options['headers']);
+            } elseif (!\is_array($options['headers'])) {
+                throw new InvalidArgumentException('headers must be an array');
+            }
+        }
+
+        // Shallow merge defaults underneath options.
+        $result = $options + $defaults;
+
+        // Remove null values.
+        foreach ($result as $k => $v) {
+            if ($v === null) {
+                unset($result[$k]);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Transfers the given request and applies request options.
+     *
+     * The URI of the request is not modified and the request options are used
+     * as-is without merging in default options.
+     *
+     * @param array $options See \GuzzleHttp\RequestOptions.
+     */
+    private function transfer(RequestInterface $request, array $options): PromiseInterface
+    {
+        $request = $this->applyOptions($request, $options);
+        /** @var HandlerStack $handler */
+        $handler = $options['handler'];
+
+        try {
+            return P\Create::promiseFor($handler($request, $options));
+        } catch (\Exception $e) {
+            return P\Create::rejectionFor($e);
+        }
+    }
+
+    /**
+     * Applies the array of request options to a request.
+     */
+    private function applyOptions(RequestInterface $request, array &$options): RequestInterface
+    {
+        $modify = [
+            'set_headers' => [],
+        ];
+
+        if (isset($options['headers'])) {
+            if (array_keys($options['headers']) === range(0, count($options['headers']) - 1)) {
+                throw new InvalidArgumentException('The headers array must have header name as keys.');
+            }
+            $modify['set_headers'] = $options['headers'];
+            unset($options['headers']);
+        }
+
+        if (isset($options['form_params'])) {
+            if (isset($options['multipart'])) {
+                throw new InvalidArgumentException('You cannot use '
+                    .'form_params and multipart at the same time. Use the '
+                    .'form_params option if you want to send application/'
+                    .'x-www-form-urlencoded requests, and the multipart '
+                    .'option to send multipart/form-data requests.');
+            }
+            $options['body'] = \http_build_query($options['form_params'], '', '&');
+            unset($options['form_params']);
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
+            $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
+        }
+
+        if (isset($options['multipart'])) {
+            $options['body'] = new Psr7\MultipartStream($options['multipart']);
+            unset($options['multipart']);
+        }
+
+        if (isset($options['json'])) {
+            $options['body'] = Utils::jsonEncode($options['json']);
+            unset($options['json']);
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
+            $options['_conditional']['Content-Type'] = 'application/json';
+        }
+
+        if (!empty($options['decode_content'])
+            && $options['decode_content'] !== true
+        ) {
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']);
+            $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
+        }
+
+        if (isset($options['body'])) {
+            if (\is_array($options['body'])) {
+                throw $this->invalidBody();
+            }
+            $modify['body'] = Psr7\Utils::streamFor($options['body']);
+            unset($options['body']);
+        }
+
+        if (!empty($options['auth']) && \is_array($options['auth'])) {
+            $value = $options['auth'];
+            $type = isset($value[2]) ? \strtolower($value[2]) : 'basic';
+            switch ($type) {
+                case 'basic':
+                    // Ensure that we don't have the header in different case and set the new value.
+                    $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']);
+                    $modify['set_headers']['Authorization'] = 'Basic '
+                        .\base64_encode("$value[0]:$value[1]");
+                    break;
+                case 'digest':
+                    // @todo: Do not rely on curl
+                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST;
+                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
+                    break;
+                case 'ntlm':
+                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM;
+                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
+                    break;
+            }
+        }
+
+        if (isset($options['query'])) {
+            $value = $options['query'];
+            if (\is_array($value)) {
+                $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986);
+            }
+            if (!\is_string($value)) {
+                throw new InvalidArgumentException('query must be a string or array');
+            }
+            $modify['query'] = $value;
+            unset($options['query']);
+        }
+
+        // Ensure that sink is not an invalid value.
+        if (isset($options['sink'])) {
+            // TODO: Add more sink validation?
+            if (\is_bool($options['sink'])) {
+                throw new InvalidArgumentException('sink must not be a boolean');
+            }
+        }
+
+        if (isset($options['version'])) {
+            $modify['version'] = $options['version'];
+        }
+
+        $request = Psr7\Utils::modifyRequest($request, $modify);
+        if ($request->getBody() instanceof Psr7\MultipartStream) {
+            // Use a multipart/form-data POST if a Content-Type is not set.
+            // Ensure that we don't have the header in different case and set the new value.
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
+            $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
+                .$request->getBody()->getBoundary();
+        }
+
+        // Merge in conditional headers if they are not present.
+        if (isset($options['_conditional'])) {
+            // Build up the changes so it's in a single clone of the message.
+            $modify = [];
+            foreach ($options['_conditional'] as $k => $v) {
+                if (!$request->hasHeader($k)) {
+                    $modify['set_headers'][$k] = $v;
+                }
+            }
+            $request = Psr7\Utils::modifyRequest($request, $modify);
+            // Don't pass this internal value along to middleware/handlers.
+            unset($options['_conditional']);
+        }
+
+        return $request;
+    }
+
+    /**
+     * Return an InvalidArgumentException with pre-set message.
+     */
+    private function invalidBody(): InvalidArgumentException
+    {
+        return new InvalidArgumentException('Passing in the "body" request '
+            .'option as an array to send a request is not supported. '
+            .'Please use the "form_params" request option to send a '
+            .'application/x-www-form-urlencoded request, or the "multipart" '
+            .'request option to send a multipart/form-data request.');
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/ClientInterface.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/ClientInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/ClientInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,84 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\GuzzleException;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Client interface for sending HTTP requests.
+ */
+interface ClientInterface
+{
+    /**
+     * The Guzzle major version.
+     */
+    public const MAJOR_VERSION = 7;
+
+    /**
+     * Send an HTTP request.
+     *
+     * @param RequestInterface $request Request to send
+     * @param array            $options Request options to apply to the given
+     *                                  request and to the transfer.
+     *
+     * @throws GuzzleException
+     */
+    public function send(RequestInterface $request, array $options = []): ResponseInterface;
+
+    /**
+     * Asynchronously send an HTTP request.
+     *
+     * @param RequestInterface $request Request to send
+     * @param array            $options Request options to apply to the given
+     *                                  request and to the transfer.
+     */
+    public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface;
+
+    /**
+     * Create and send an HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string              $method  HTTP method.
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function request(string $method, $uri, array $options = []): ResponseInterface;
+
+    /**
+     * Create and send an asynchronous HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string              $method  HTTP method
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function requestAsync(string $method, $uri, array $options = []): PromiseInterface;
+
+    /**
+     * Get a client configuration option.
+     *
+     * These options include default request options of the client, a "handler"
+     * (if utilized by the concrete client), and a "base_uri" if utilized by
+     * the concrete client.
+     *
+     * @param string|null $option The config option to retrieve.
+     *
+     * @return mixed
+     *
+     * @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0.
+     */
+    public function getConfig(?string $option = null);
+}
Index: vendor/guzzlehttp/guzzle/src/ClientTrait.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/ClientTrait.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/ClientTrait.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,241 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\GuzzleException;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Client interface for sending HTTP requests.
+ */
+trait ClientTrait
+{
+    /**
+     * Create and send an HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string              $method  HTTP method.
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    abstract public function request(string $method, $uri, array $options = []): ResponseInterface;
+
+    /**
+     * Create and send an HTTP GET request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function get($uri, array $options = []): ResponseInterface
+    {
+        return $this->request('GET', $uri, $options);
+    }
+
+    /**
+     * Create and send an HTTP HEAD request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function head($uri, array $options = []): ResponseInterface
+    {
+        return $this->request('HEAD', $uri, $options);
+    }
+
+    /**
+     * Create and send an HTTP PUT request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function put($uri, array $options = []): ResponseInterface
+    {
+        return $this->request('PUT', $uri, $options);
+    }
+
+    /**
+     * Create and send an HTTP POST request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function post($uri, array $options = []): ResponseInterface
+    {
+        return $this->request('POST', $uri, $options);
+    }
+
+    /**
+     * Create and send an HTTP PATCH request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function patch($uri, array $options = []): ResponseInterface
+    {
+        return $this->request('PATCH', $uri, $options);
+    }
+
+    /**
+     * Create and send an HTTP DELETE request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     *
+     * @throws GuzzleException
+     */
+    public function delete($uri, array $options = []): ResponseInterface
+    {
+        return $this->request('DELETE', $uri, $options);
+    }
+
+    /**
+     * Create and send an asynchronous HTTP request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string              $method  HTTP method
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    abstract public function requestAsync(string $method, $uri, array $options = []): PromiseInterface;
+
+    /**
+     * Create and send an asynchronous HTTP GET request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function getAsync($uri, array $options = []): PromiseInterface
+    {
+        return $this->requestAsync('GET', $uri, $options);
+    }
+
+    /**
+     * Create and send an asynchronous HTTP HEAD request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function headAsync($uri, array $options = []): PromiseInterface
+    {
+        return $this->requestAsync('HEAD', $uri, $options);
+    }
+
+    /**
+     * Create and send an asynchronous HTTP PUT request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function putAsync($uri, array $options = []): PromiseInterface
+    {
+        return $this->requestAsync('PUT', $uri, $options);
+    }
+
+    /**
+     * Create and send an asynchronous HTTP POST request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function postAsync($uri, array $options = []): PromiseInterface
+    {
+        return $this->requestAsync('POST', $uri, $options);
+    }
+
+    /**
+     * Create and send an asynchronous HTTP PATCH request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function patchAsync($uri, array $options = []): PromiseInterface
+    {
+        return $this->requestAsync('PATCH', $uri, $options);
+    }
+
+    /**
+     * Create and send an asynchronous HTTP DELETE request.
+     *
+     * Use an absolute path to override the base path of the client, or a
+     * relative path to append to the base path of the client. The URL can
+     * contain the query string as well. Use an array to provide a URL
+     * template and additional variables to use in the URL template expansion.
+     *
+     * @param string|UriInterface $uri     URI object or string.
+     * @param array               $options Request options to apply.
+     */
+    public function deleteAsync($uri, array $options = []): PromiseInterface
+    {
+        return $this->requestAsync('DELETE', $uri, $options);
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,307 @@
+<?php
+
+namespace GuzzleHttp\Cookie;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Cookie jar that stores cookies as an array
+ */
+class CookieJar implements CookieJarInterface
+{
+    /**
+     * @var SetCookie[] Loaded cookie data
+     */
+    private $cookies = [];
+
+    /**
+     * @var bool
+     */
+    private $strictMode;
+
+    /**
+     * @param bool  $strictMode  Set to true to throw exceptions when invalid
+     *                           cookies are added to the cookie jar.
+     * @param array $cookieArray Array of SetCookie objects or a hash of
+     *                           arrays that can be used with the SetCookie
+     *                           constructor
+     */
+    public function __construct(bool $strictMode = false, array $cookieArray = [])
+    {
+        $this->strictMode = $strictMode;
+
+        foreach ($cookieArray as $cookie) {
+            if (!($cookie instanceof SetCookie)) {
+                $cookie = new SetCookie($cookie);
+            }
+            $this->setCookie($cookie);
+        }
+    }
+
+    /**
+     * Create a new Cookie jar from an associative array and domain.
+     *
+     * @param array  $cookies Cookies to create the jar from
+     * @param string $domain  Domain to set the cookies to
+     */
+    public static function fromArray(array $cookies, string $domain): self
+    {
+        $cookieJar = new self();
+        foreach ($cookies as $name => $value) {
+            $cookieJar->setCookie(new SetCookie([
+                'Domain' => $domain,
+                'Name' => $name,
+                'Value' => $value,
+                'Discard' => true,
+            ]));
+        }
+
+        return $cookieJar;
+    }
+
+    /**
+     * Evaluate if this cookie should be persisted to storage
+     * that survives between requests.
+     *
+     * @param SetCookie $cookie              Being evaluated.
+     * @param bool      $allowSessionCookies If we should persist session cookies
+     */
+    public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = false): bool
+    {
+        if ($cookie->getExpires() || $allowSessionCookies) {
+            if (!$cookie->getDiscard()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Finds and returns the cookie based on the name
+     *
+     * @param string $name cookie name to search for
+     *
+     * @return SetCookie|null cookie that was found or null if not found
+     */
+    public function getCookieByName(string $name): ?SetCookie
+    {
+        foreach ($this->cookies as $cookie) {
+            if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) {
+                return $cookie;
+            }
+        }
+
+        return null;
+    }
+
+    public function toArray(): array
+    {
+        return \array_map(static function (SetCookie $cookie): array {
+            return $cookie->toArray();
+        }, $this->getIterator()->getArrayCopy());
+    }
+
+    public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void
+    {
+        if (!$domain) {
+            $this->cookies = [];
+
+            return;
+        } elseif (!$path) {
+            $this->cookies = \array_filter(
+                $this->cookies,
+                static function (SetCookie $cookie) use ($domain): bool {
+                    return !$cookie->matchesDomain($domain);
+                }
+            );
+        } elseif (!$name) {
+            $this->cookies = \array_filter(
+                $this->cookies,
+                static function (SetCookie $cookie) use ($path, $domain): bool {
+                    return !($cookie->matchesPath($path)
+                        && $cookie->matchesDomain($domain));
+                }
+            );
+        } else {
+            $this->cookies = \array_filter(
+                $this->cookies,
+                static function (SetCookie $cookie) use ($path, $domain, $name) {
+                    return !($cookie->getName() == $name
+                        && $cookie->matchesPath($path)
+                        && $cookie->matchesDomain($domain));
+                }
+            );
+        }
+    }
+
+    public function clearSessionCookies(): void
+    {
+        $this->cookies = \array_filter(
+            $this->cookies,
+            static function (SetCookie $cookie): bool {
+                return !$cookie->getDiscard() && $cookie->getExpires();
+            }
+        );
+    }
+
+    public function setCookie(SetCookie $cookie): bool
+    {
+        // If the name string is empty (but not 0), ignore the set-cookie
+        // string entirely.
+        $name = $cookie->getName();
+        if (!$name && $name !== '0') {
+            return false;
+        }
+
+        // Only allow cookies with set and valid domain, name, value
+        $result = $cookie->validate();
+        if ($result !== true) {
+            if ($this->strictMode) {
+                throw new \RuntimeException('Invalid cookie: '.$result);
+            }
+            $this->removeCookieIfEmpty($cookie);
+
+            return false;
+        }
+
+        // Resolve conflicts with previously set cookies
+        foreach ($this->cookies as $i => $c) {
+            // Two cookies are identical, when their path, and domain are
+            // identical.
+            if ($c->getPath() != $cookie->getPath()
+                || $c->getDomain() != $cookie->getDomain()
+                || $c->getName() != $cookie->getName()
+            ) {
+                continue;
+            }
+
+            // The previously set cookie is a discard cookie and this one is
+            // not so allow the new cookie to be set
+            if (!$cookie->getDiscard() && $c->getDiscard()) {
+                unset($this->cookies[$i]);
+                continue;
+            }
+
+            // If the new cookie's expiration is further into the future, then
+            // replace the old cookie
+            if ($cookie->getExpires() > $c->getExpires()) {
+                unset($this->cookies[$i]);
+                continue;
+            }
+
+            // If the value has changed, we better change it
+            if ($cookie->getValue() !== $c->getValue()) {
+                unset($this->cookies[$i]);
+                continue;
+            }
+
+            // The cookie exists, so no need to continue
+            return false;
+        }
+
+        $this->cookies[] = $cookie;
+
+        return true;
+    }
+
+    public function count(): int
+    {
+        return \count($this->cookies);
+    }
+
+    /**
+     * @return \ArrayIterator<int, SetCookie>
+     */
+    public function getIterator(): \ArrayIterator
+    {
+        return new \ArrayIterator(\array_values($this->cookies));
+    }
+
+    public function extractCookies(RequestInterface $request, ResponseInterface $response): void
+    {
+        if ($cookieHeader = $response->getHeader('Set-Cookie')) {
+            foreach ($cookieHeader as $cookie) {
+                $sc = SetCookie::fromString($cookie);
+                if (!$sc->getDomain()) {
+                    $sc->setDomain($request->getUri()->getHost());
+                }
+                if (0 !== \strpos($sc->getPath(), '/')) {
+                    $sc->setPath($this->getCookiePathFromRequest($request));
+                }
+                if (!$sc->matchesDomain($request->getUri()->getHost())) {
+                    continue;
+                }
+                // Note: At this point `$sc->getDomain()` being a public suffix should
+                // be rejected, but we don't want to pull in the full PSL dependency.
+                $this->setCookie($sc);
+            }
+        }
+    }
+
+    /**
+     * Computes cookie path following RFC 6265 section 5.1.4
+     *
+     * @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
+     */
+    private function getCookiePathFromRequest(RequestInterface $request): string
+    {
+        $uriPath = $request->getUri()->getPath();
+        if ('' === $uriPath) {
+            return '/';
+        }
+        if (0 !== \strpos($uriPath, '/')) {
+            return '/';
+        }
+        if ('/' === $uriPath) {
+            return '/';
+        }
+        $lastSlashPos = \strrpos($uriPath, '/');
+        if (0 === $lastSlashPos || false === $lastSlashPos) {
+            return '/';
+        }
+
+        return \substr($uriPath, 0, $lastSlashPos);
+    }
+
+    public function withCookieHeader(RequestInterface $request): RequestInterface
+    {
+        $values = [];
+        $uri = $request->getUri();
+        $scheme = $uri->getScheme();
+        $host = $uri->getHost();
+        $path = $uri->getPath() ?: '/';
+
+        foreach ($this->cookies as $cookie) {
+            if ($cookie->matchesPath($path)
+                && $cookie->matchesDomain($host)
+                && !$cookie->isExpired()
+                && (!$cookie->getSecure() || $scheme === 'https')
+            ) {
+                $values[] = $cookie->getName().'='
+                    .$cookie->getValue();
+            }
+        }
+
+        return $values
+            ? $request->withHeader('Cookie', \implode('; ', $values))
+            : $request;
+    }
+
+    /**
+     * If a cookie already exists and the server asks to set it again with a
+     * null value, the cookie must be deleted.
+     */
+    private function removeCookieIfEmpty(SetCookie $cookie): void
+    {
+        $cookieValue = $cookie->getValue();
+        if ($cookieValue === null || $cookieValue === '') {
+            $this->clear(
+                $cookie->getDomain(),
+                $cookie->getPath(),
+                $cookie->getName()
+            );
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,80 @@
+<?php
+
+namespace GuzzleHttp\Cookie;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Stores HTTP cookies.
+ *
+ * It extracts cookies from HTTP requests, and returns them in HTTP responses.
+ * CookieJarInterface instances automatically expire contained cookies when
+ * necessary. Subclasses are also responsible for storing and retrieving
+ * cookies from a file, database, etc.
+ *
+ * @see https://docs.python.org/2/library/cookielib.html Inspiration
+ *
+ * @extends \IteratorAggregate<SetCookie>
+ */
+interface CookieJarInterface extends \Countable, \IteratorAggregate
+{
+    /**
+     * Create a request with added cookie headers.
+     *
+     * If no matching cookies are found in the cookie jar, then no Cookie
+     * header is added to the request and the same request is returned.
+     *
+     * @param RequestInterface $request Request object to modify.
+     *
+     * @return RequestInterface returns the modified request.
+     */
+    public function withCookieHeader(RequestInterface $request): RequestInterface;
+
+    /**
+     * Extract cookies from an HTTP response and store them in the CookieJar.
+     *
+     * @param RequestInterface  $request  Request that was sent
+     * @param ResponseInterface $response Response that was received
+     */
+    public function extractCookies(RequestInterface $request, ResponseInterface $response): void;
+
+    /**
+     * Sets a cookie in the cookie jar.
+     *
+     * @param SetCookie $cookie Cookie to set.
+     *
+     * @return bool Returns true on success or false on failure
+     */
+    public function setCookie(SetCookie $cookie): bool;
+
+    /**
+     * Remove cookies currently held in the cookie jar.
+     *
+     * Invoking this method without arguments will empty the whole cookie jar.
+     * If given a $domain argument only cookies belonging to that domain will
+     * be removed. If given a $domain and $path argument, cookies belonging to
+     * the specified path within that domain are removed. If given all three
+     * arguments, then the cookie with the specified name, path and domain is
+     * removed.
+     *
+     * @param string|null $domain Clears cookies matching a domain
+     * @param string|null $path   Clears cookies matching a domain and path
+     * @param string|null $name   Clears cookies matching a domain, path, and name
+     */
+    public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void;
+
+    /**
+     * Discard all sessions cookies.
+     *
+     * Removes cookies that don't have an expire field or a have a discard
+     * field set to true. To be called when the user agent shuts down according
+     * to RFC 2965.
+     */
+    public function clearSessionCookies(): void;
+
+    /**
+     * Converts the cookie jar to an array.
+     */
+    public function toArray(): array;
+}
Index: vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,101 @@
+<?php
+
+namespace GuzzleHttp\Cookie;
+
+use GuzzleHttp\Utils;
+
+/**
+ * Persists non-session cookies using a JSON formatted file
+ */
+class FileCookieJar extends CookieJar
+{
+    /**
+     * @var string filename
+     */
+    private $filename;
+
+    /**
+     * @var bool Control whether to persist session cookies or not.
+     */
+    private $storeSessionCookies;
+
+    /**
+     * Create a new FileCookieJar object
+     *
+     * @param string $cookieFile          File to store the cookie data
+     * @param bool   $storeSessionCookies Set to true to store session cookies
+     *                                    in the cookie jar.
+     *
+     * @throws \RuntimeException if the file cannot be found or created
+     */
+    public function __construct(string $cookieFile, bool $storeSessionCookies = false)
+    {
+        parent::__construct();
+        $this->filename = $cookieFile;
+        $this->storeSessionCookies = $storeSessionCookies;
+
+        if (\file_exists($cookieFile)) {
+            $this->load($cookieFile);
+        }
+    }
+
+    /**
+     * Saves the file when shutting down
+     */
+    public function __destruct()
+    {
+        $this->save($this->filename);
+    }
+
+    /**
+     * Saves the cookies to a file.
+     *
+     * @param string $filename File to save
+     *
+     * @throws \RuntimeException if the file cannot be found or created
+     */
+    public function save(string $filename): void
+    {
+        $json = [];
+        /** @var SetCookie $cookie */
+        foreach ($this as $cookie) {
+            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
+                $json[] = $cookie->toArray();
+            }
+        }
+
+        $jsonStr = Utils::jsonEncode($json);
+        if (false === \file_put_contents($filename, $jsonStr, \LOCK_EX)) {
+            throw new \RuntimeException("Unable to save file {$filename}");
+        }
+    }
+
+    /**
+     * Load cookies from a JSON formatted file.
+     *
+     * Old cookies are kept unless overwritten by newly loaded ones.
+     *
+     * @param string $filename Cookie file to load.
+     *
+     * @throws \RuntimeException if the file cannot be loaded.
+     */
+    public function load(string $filename): void
+    {
+        $json = \file_get_contents($filename);
+        if (false === $json) {
+            throw new \RuntimeException("Unable to load file {$filename}");
+        }
+        if ($json === '') {
+            return;
+        }
+
+        $data = Utils::jsonDecode($json, true);
+        if (\is_array($data)) {
+            foreach ($data as $cookie) {
+                $this->setCookie(new SetCookie($cookie));
+            }
+        } elseif (\is_scalar($data) && !empty($data)) {
+            throw new \RuntimeException("Invalid cookie file: {$filename}");
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,77 @@
+<?php
+
+namespace GuzzleHttp\Cookie;
+
+/**
+ * Persists cookies in the client session
+ */
+class SessionCookieJar extends CookieJar
+{
+    /**
+     * @var string session key
+     */
+    private $sessionKey;
+
+    /**
+     * @var bool Control whether to persist session cookies or not.
+     */
+    private $storeSessionCookies;
+
+    /**
+     * Create a new SessionCookieJar object
+     *
+     * @param string $sessionKey          Session key name to store the cookie
+     *                                    data in session
+     * @param bool   $storeSessionCookies Set to true to store session cookies
+     *                                    in the cookie jar.
+     */
+    public function __construct(string $sessionKey, bool $storeSessionCookies = false)
+    {
+        parent::__construct();
+        $this->sessionKey = $sessionKey;
+        $this->storeSessionCookies = $storeSessionCookies;
+        $this->load();
+    }
+
+    /**
+     * Saves cookies to session when shutting down
+     */
+    public function __destruct()
+    {
+        $this->save();
+    }
+
+    /**
+     * Save cookies to the client session
+     */
+    public function save(): void
+    {
+        $json = [];
+        /** @var SetCookie $cookie */
+        foreach ($this as $cookie) {
+            if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) {
+                $json[] = $cookie->toArray();
+            }
+        }
+
+        $_SESSION[$this->sessionKey] = \json_encode($json);
+    }
+
+    /**
+     * Load the contents of the client session into the data array
+     */
+    protected function load(): void
+    {
+        if (!isset($_SESSION[$this->sessionKey])) {
+            return;
+        }
+        $data = \json_decode($_SESSION[$this->sessionKey], true);
+        if (\is_array($data)) {
+            foreach ($data as $cookie) {
+                $this->setCookie(new SetCookie($cookie));
+            }
+        } elseif (\strlen($data)) {
+            throw new \RuntimeException('Invalid cookie data');
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,488 @@
+<?php
+
+namespace GuzzleHttp\Cookie;
+
+/**
+ * Set-Cookie object
+ */
+class SetCookie
+{
+    /**
+     * @var array
+     */
+    private static $defaults = [
+        'Name' => null,
+        'Value' => null,
+        'Domain' => null,
+        'Path' => '/',
+        'Max-Age' => null,
+        'Expires' => null,
+        'Secure' => false,
+        'Discard' => false,
+        'HttpOnly' => false,
+    ];
+
+    /**
+     * @var array Cookie data
+     */
+    private $data;
+
+    /**
+     * Create a new SetCookie object from a string.
+     *
+     * @param string $cookie Set-Cookie header string
+     */
+    public static function fromString(string $cookie): self
+    {
+        // Create the default return array
+        $data = self::$defaults;
+        // Explode the cookie string using a series of semicolons
+        $pieces = \array_filter(\array_map('trim', \explode(';', $cookie)));
+        // The name of the cookie (first kvp) must exist and include an equal sign.
+        if (!isset($pieces[0]) || \strpos($pieces[0], '=') === false) {
+            return new self($data);
+        }
+
+        // Add the cookie pieces into the parsed data array
+        foreach ($pieces as $part) {
+            $cookieParts = \explode('=', $part, 2);
+            $key = \trim($cookieParts[0]);
+            $value = isset($cookieParts[1])
+                ? \trim($cookieParts[1], " \n\r\t\0\x0B")
+                : true;
+
+            // Only check for non-cookies when cookies have been found
+            if (!isset($data['Name'])) {
+                $data['Name'] = $key;
+                $data['Value'] = $value;
+            } else {
+                foreach (\array_keys(self::$defaults) as $search) {
+                    if (!\strcasecmp($search, $key)) {
+                        if ($search === 'Max-Age') {
+                            if (is_numeric($value)) {
+                                $data[$search] = (int) $value;
+                            }
+                        } else {
+                            $data[$search] = $value;
+                        }
+                        continue 2;
+                    }
+                }
+                $data[$key] = $value;
+            }
+        }
+
+        return new self($data);
+    }
+
+    /**
+     * @param array $data Array of cookie data provided by a Cookie parser
+     */
+    public function __construct(array $data = [])
+    {
+        $this->data = self::$defaults;
+
+        if (isset($data['Name'])) {
+            $this->setName($data['Name']);
+        }
+
+        if (isset($data['Value'])) {
+            $this->setValue($data['Value']);
+        }
+
+        if (isset($data['Domain'])) {
+            $this->setDomain($data['Domain']);
+        }
+
+        if (isset($data['Path'])) {
+            $this->setPath($data['Path']);
+        }
+
+        if (isset($data['Max-Age'])) {
+            $this->setMaxAge($data['Max-Age']);
+        }
+
+        if (isset($data['Expires'])) {
+            $this->setExpires($data['Expires']);
+        }
+
+        if (isset($data['Secure'])) {
+            $this->setSecure($data['Secure']);
+        }
+
+        if (isset($data['Discard'])) {
+            $this->setDiscard($data['Discard']);
+        }
+
+        if (isset($data['HttpOnly'])) {
+            $this->setHttpOnly($data['HttpOnly']);
+        }
+
+        // Set the remaining values that don't have extra validation logic
+        foreach (array_diff(array_keys($data), array_keys(self::$defaults)) as $key) {
+            $this->data[$key] = $data[$key];
+        }
+
+        // Extract the Expires value and turn it into a UNIX timestamp if needed
+        if (!$this->getExpires() && $this->getMaxAge()) {
+            // Calculate the Expires date
+            $this->setExpires(\time() + $this->getMaxAge());
+        } elseif (null !== ($expires = $this->getExpires()) && !\is_numeric($expires)) {
+            $this->setExpires($expires);
+        }
+    }
+
+    public function __toString()
+    {
+        $str = $this->data['Name'].'='.($this->data['Value'] ?? '').'; ';
+        foreach ($this->data as $k => $v) {
+            if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) {
+                if ($k === 'Expires') {
+                    $str .= 'Expires='.\gmdate('D, d M Y H:i:s \G\M\T', $v).'; ';
+                } else {
+                    $str .= ($v === true ? $k : "{$k}={$v}").'; ';
+                }
+            }
+        }
+
+        return \rtrim($str, '; ');
+    }
+
+    public function toArray(): array
+    {
+        return $this->data;
+    }
+
+    /**
+     * Get the cookie name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->data['Name'];
+    }
+
+    /**
+     * Set the cookie name.
+     *
+     * @param string $name Cookie name
+     */
+    public function setName($name): void
+    {
+        if (!is_string($name)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Name'] = (string) $name;
+    }
+
+    /**
+     * Get the cookie value.
+     *
+     * @return string|null
+     */
+    public function getValue()
+    {
+        return $this->data['Value'];
+    }
+
+    /**
+     * Set the cookie value.
+     *
+     * @param string $value Cookie value
+     */
+    public function setValue($value): void
+    {
+        if (!is_string($value)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Value'] = (string) $value;
+    }
+
+    /**
+     * Get the domain.
+     *
+     * @return string|null
+     */
+    public function getDomain()
+    {
+        return $this->data['Domain'];
+    }
+
+    /**
+     * Set the domain of the cookie.
+     *
+     * @param string|null $domain
+     */
+    public function setDomain($domain): void
+    {
+        if (!is_string($domain) && null !== $domain) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Domain'] = null === $domain ? null : (string) $domain;
+    }
+
+    /**
+     * Get the path.
+     *
+     * @return string
+     */
+    public function getPath()
+    {
+        return $this->data['Path'];
+    }
+
+    /**
+     * Set the path of the cookie.
+     *
+     * @param string $path Path of the cookie
+     */
+    public function setPath($path): void
+    {
+        if (!is_string($path)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Path'] = (string) $path;
+    }
+
+    /**
+     * Maximum lifetime of the cookie in seconds.
+     *
+     * @return int|null
+     */
+    public function getMaxAge()
+    {
+        return null === $this->data['Max-Age'] ? null : (int) $this->data['Max-Age'];
+    }
+
+    /**
+     * Set the max-age of the cookie.
+     *
+     * @param int|null $maxAge Max age of the cookie in seconds
+     */
+    public function setMaxAge($maxAge): void
+    {
+        if (!is_int($maxAge) && null !== $maxAge) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Max-Age'] = $maxAge === null ? null : (int) $maxAge;
+    }
+
+    /**
+     * The UNIX timestamp when the cookie Expires.
+     *
+     * @return string|int|null
+     */
+    public function getExpires()
+    {
+        return $this->data['Expires'];
+    }
+
+    /**
+     * Set the unix timestamp for which the cookie will expire.
+     *
+     * @param int|string|null $timestamp Unix timestamp or any English textual datetime description.
+     */
+    public function setExpires($timestamp): void
+    {
+        if (!is_int($timestamp) && !is_string($timestamp) && null !== $timestamp) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int, string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Expires'] = null === $timestamp ? null : (\is_numeric($timestamp) ? (int) $timestamp : \strtotime((string) $timestamp));
+    }
+
+    /**
+     * Get whether or not this is a secure cookie.
+     *
+     * @return bool
+     */
+    public function getSecure()
+    {
+        return $this->data['Secure'];
+    }
+
+    /**
+     * Set whether or not the cookie is secure.
+     *
+     * @param bool $secure Set to true or false if secure
+     */
+    public function setSecure($secure): void
+    {
+        if (!is_bool($secure)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Secure'] = (bool) $secure;
+    }
+
+    /**
+     * Get whether or not this is a session cookie.
+     *
+     * @return bool|null
+     */
+    public function getDiscard()
+    {
+        return $this->data['Discard'];
+    }
+
+    /**
+     * Set whether or not this is a session cookie.
+     *
+     * @param bool $discard Set to true or false if this is a session cookie
+     */
+    public function setDiscard($discard): void
+    {
+        if (!is_bool($discard)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['Discard'] = (bool) $discard;
+    }
+
+    /**
+     * Get whether or not this is an HTTP only cookie.
+     *
+     * @return bool
+     */
+    public function getHttpOnly()
+    {
+        return $this->data['HttpOnly'];
+    }
+
+    /**
+     * Set whether or not this is an HTTP only cookie.
+     *
+     * @param bool $httpOnly Set to true or false if this is HTTP only
+     */
+    public function setHttpOnly($httpOnly): void
+    {
+        if (!is_bool($httpOnly)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->data['HttpOnly'] = (bool) $httpOnly;
+    }
+
+    /**
+     * Check if the cookie matches a path value.
+     *
+     * A request-path path-matches a given cookie-path if at least one of
+     * the following conditions holds:
+     *
+     * - The cookie-path and the request-path are identical.
+     * - The cookie-path is a prefix of the request-path, and the last
+     *   character of the cookie-path is %x2F ("/").
+     * - The cookie-path is a prefix of the request-path, and the first
+     *   character of the request-path that is not included in the cookie-
+     *   path is a %x2F ("/") character.
+     *
+     * @param string $requestPath Path to check against
+     */
+    public function matchesPath(string $requestPath): bool
+    {
+        $cookiePath = $this->getPath();
+
+        // Match on exact matches or when path is the default empty "/"
+        if ($cookiePath === '/' || $cookiePath == $requestPath) {
+            return true;
+        }
+
+        // Ensure that the cookie-path is a prefix of the request path.
+        if (0 !== \strpos($requestPath, $cookiePath)) {
+            return false;
+        }
+
+        // Match if the last character of the cookie-path is "/"
+        if (\substr($cookiePath, -1, 1) === '/') {
+            return true;
+        }
+
+        // Match if the first character not included in cookie path is "/"
+        return \substr($requestPath, \strlen($cookiePath), 1) === '/';
+    }
+
+    /**
+     * Check if the cookie matches a domain value.
+     *
+     * @param string $domain Domain to check against
+     */
+    public function matchesDomain(string $domain): bool
+    {
+        $cookieDomain = $this->getDomain();
+        if (null === $cookieDomain) {
+            return true;
+        }
+
+        // Remove the leading '.' as per spec in RFC 6265.
+        // https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3
+        $cookieDomain = \ltrim(\strtolower($cookieDomain), '.');
+
+        $domain = \strtolower($domain);
+
+        // Domain not set or exact match.
+        if ('' === $cookieDomain || $domain === $cookieDomain) {
+            return true;
+        }
+
+        // Matching the subdomain according to RFC 6265.
+        // https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3
+        if (\filter_var($domain, \FILTER_VALIDATE_IP)) {
+            return false;
+        }
+
+        return (bool) \preg_match('/\.'.\preg_quote($cookieDomain, '/').'$/', $domain);
+    }
+
+    /**
+     * Check if the cookie is expired.
+     */
+    public function isExpired(): bool
+    {
+        return $this->getExpires() !== null && \time() > $this->getExpires();
+    }
+
+    /**
+     * Check if the cookie is valid according to RFC 6265.
+     *
+     * @return bool|string Returns true if valid or an error message if invalid
+     */
+    public function validate()
+    {
+        $name = $this->getName();
+        if ($name === '') {
+            return 'The cookie name must not be empty';
+        }
+
+        // Check if any of the invalid characters are present in the cookie name
+        if (\preg_match(
+            '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/',
+            $name
+        )) {
+            return 'Cookie name must not contain invalid characters: ASCII '
+                .'Control characters (0-31;127), space, tab and the '
+                .'following characters: ()<>@,;:\"/?={}';
+        }
+
+        // Value must not be null. 0 and empty string are valid. Empty strings
+        // are technically against RFC 6265, but known to happen in the wild.
+        $value = $this->getValue();
+        if ($value === null) {
+            return 'The cookie value must not be empty';
+        }
+
+        // Domains must not be empty, but can be 0. "0" is not a valid internet
+        // domain, but may be used as server name in a private network.
+        $domain = $this->getDomain();
+        if ($domain === null || $domain === '') {
+            return 'The cookie domain must not be empty';
+        }
+
+        return true;
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,39 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Exception when an HTTP error occurs (4xx or 5xx error)
+ */
+class BadResponseException extends RequestException
+{
+    public function __construct(
+        string $message,
+        RequestInterface $request,
+        ResponseInterface $response,
+        ?\Throwable $previous = null,
+        array $handlerContext = []
+    ) {
+        parent::__construct($message, $request, $response, $previous, $handlerContext);
+    }
+
+    /**
+     * Current exception and the ones that extend it will always have a response.
+     */
+    public function hasResponse(): bool
+    {
+        return true;
+    }
+
+    /**
+     * This function narrows the return type from the parent class and does not allow it to be nullable.
+     */
+    public function getResponse(): ResponseInterface
+    {
+        /** @var ResponseInterface */
+        return parent::getResponse();
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/ClientException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/ClientException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/ClientException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,10 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+/**
+ * Exception when a client error is encountered (4xx codes)
+ */
+class ClientException extends BadResponseException
+{
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/ConnectException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,56 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+use Psr\Http\Client\NetworkExceptionInterface;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Exception thrown when a connection cannot be established.
+ *
+ * Note that no response is present for a ConnectException
+ */
+class ConnectException extends TransferException implements NetworkExceptionInterface
+{
+    /**
+     * @var RequestInterface
+     */
+    private $request;
+
+    /**
+     * @var array
+     */
+    private $handlerContext;
+
+    public function __construct(
+        string $message,
+        RequestInterface $request,
+        ?\Throwable $previous = null,
+        array $handlerContext = []
+    ) {
+        parent::__construct($message, 0, $previous);
+        $this->request = $request;
+        $this->handlerContext = $handlerContext;
+    }
+
+    /**
+     * Get the request that caused the exception
+     */
+    public function getRequest(): RequestInterface
+    {
+        return $this->request;
+    }
+
+    /**
+     * Get contextual information about the error from the underlying handler.
+     *
+     * The contents of this array will vary depending on which handler you are
+     * using. It may also be just an empty array. Relying on this data will
+     * couple you to a specific handler, but can give more debug information
+     * when needed.
+     */
+    public function getHandlerContext(): array
+    {
+        return $this->handlerContext;
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,9 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+use Psr\Http\Client\ClientExceptionInterface;
+
+interface GuzzleException extends ClientExceptionInterface
+{
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/InvalidArgumentException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,7 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+final class InvalidArgumentException extends \InvalidArgumentException implements GuzzleException
+{
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/RequestException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/RequestException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/RequestException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,150 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+use GuzzleHttp\BodySummarizer;
+use GuzzleHttp\BodySummarizerInterface;
+use Psr\Http\Client\RequestExceptionInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * HTTP Request exception
+ */
+class RequestException extends TransferException implements RequestExceptionInterface
+{
+    /**
+     * @var RequestInterface
+     */
+    private $request;
+
+    /**
+     * @var ResponseInterface|null
+     */
+    private $response;
+
+    /**
+     * @var array
+     */
+    private $handlerContext;
+
+    public function __construct(
+        string $message,
+        RequestInterface $request,
+        ?ResponseInterface $response = null,
+        ?\Throwable $previous = null,
+        array $handlerContext = []
+    ) {
+        // Set the code of the exception if the response is set and not future.
+        $code = $response ? $response->getStatusCode() : 0;
+        parent::__construct($message, $code, $previous);
+        $this->request = $request;
+        $this->response = $response;
+        $this->handlerContext = $handlerContext;
+    }
+
+    /**
+     * Wrap non-RequestExceptions with a RequestException
+     */
+    public static function wrapException(RequestInterface $request, \Throwable $e): RequestException
+    {
+        return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e);
+    }
+
+    /**
+     * Factory method to create a new exception with a normalized error message
+     *
+     * @param RequestInterface             $request        Request sent
+     * @param ResponseInterface            $response       Response received
+     * @param \Throwable|null              $previous       Previous exception
+     * @param array                        $handlerContext Optional handler context
+     * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer
+     */
+    public static function create(
+        RequestInterface $request,
+        ?ResponseInterface $response = null,
+        ?\Throwable $previous = null,
+        array $handlerContext = [],
+        ?BodySummarizerInterface $bodySummarizer = null
+    ): self {
+        if (!$response) {
+            return new self(
+                'Error completing request',
+                $request,
+                null,
+                $previous,
+                $handlerContext
+            );
+        }
+
+        $level = (int) \floor($response->getStatusCode() / 100);
+        if ($level === 4) {
+            $label = 'Client error';
+            $className = ClientException::class;
+        } elseif ($level === 5) {
+            $label = 'Server error';
+            $className = ServerException::class;
+        } else {
+            $label = 'Unsuccessful request';
+            $className = __CLASS__;
+        }
+
+        $uri = \GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri());
+
+        // Client Error: `GET /` resulted in a `404 Not Found` response:
+        // <html> ... (truncated)
+        $message = \sprintf(
+            '%s: `%s %s` resulted in a `%s %s` response',
+            $label,
+            $request->getMethod(),
+            $uri->__toString(),
+            $response->getStatusCode(),
+            $response->getReasonPhrase()
+        );
+
+        $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response);
+
+        if ($summary !== null) {
+            $message .= ":\n{$summary}\n";
+        }
+
+        return new $className($message, $request, $response, $previous, $handlerContext);
+    }
+
+    /**
+     * Get the request that caused the exception
+     */
+    public function getRequest(): RequestInterface
+    {
+        return $this->request;
+    }
+
+    /**
+     * Get the associated response
+     */
+    public function getResponse(): ?ResponseInterface
+    {
+        return $this->response;
+    }
+
+    /**
+     * Check if a response was received
+     */
+    public function hasResponse(): bool
+    {
+        return $this->response !== null;
+    }
+
+    /**
+     * Get contextual information about the error from the underlying handler.
+     *
+     * The contents of this array will vary depending on which handler you are
+     * using. It may also be just an empty array. Relying on this data will
+     * couple you to a specific handler, but can give more debug information
+     * when needed.
+     */
+    public function getHandlerContext(): array
+    {
+        return $this->handlerContext;
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/ServerException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/ServerException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/ServerException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,10 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+/**
+ * Exception when a server error is encountered (5xx codes)
+ */
+class ServerException extends BadResponseException
+{
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/TooManyRedirectsException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,7 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+class TooManyRedirectsException extends RequestException
+{
+}
Index: vendor/guzzlehttp/guzzle/src/Exception/TransferException.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Exception/TransferException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Exception/TransferException.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,7 @@
+<?php
+
+namespace GuzzleHttp\Exception;
+
+class TransferException extends \RuntimeException implements GuzzleException
+{
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,736 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Exception\ConnectException;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\FulfilledPromise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Psr7\LazyOpenStream;
+use GuzzleHttp\TransferStats;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Creates curl resources from a request
+ *
+ * @final
+ */
+class CurlFactory implements CurlFactoryInterface
+{
+    public const CURL_VERSION_STR = 'curl_version';
+
+    /**
+     * @deprecated
+     */
+    public const LOW_CURL_VERSION_NUMBER = '7.21.2';
+
+    /**
+     * @var resource[]|\CurlHandle[]
+     */
+    private $handles = [];
+
+    /**
+     * @var int Total number of idle handles to keep in cache
+     */
+    private $maxHandles;
+
+    /**
+     * @param int $maxHandles Maximum number of idle handles.
+     */
+    public function __construct(int $maxHandles)
+    {
+        $this->maxHandles = $maxHandles;
+    }
+
+    public function create(RequestInterface $request, array $options): EasyHandle
+    {
+        $protocolVersion = $request->getProtocolVersion();
+
+        if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
+            if (!self::supportsHttp2()) {
+                throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
+            }
+        } elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
+            throw new ConnectException(sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
+        }
+
+        if (isset($options['curl']['body_as_string'])) {
+            $options['_body_as_string'] = $options['curl']['body_as_string'];
+            unset($options['curl']['body_as_string']);
+        }
+
+        $easy = new EasyHandle();
+        $easy->request = $request;
+        $easy->options = $options;
+        $conf = $this->getDefaultConf($easy);
+        $this->applyMethod($easy, $conf);
+        $this->applyHandlerOptions($easy, $conf);
+        $this->applyHeaders($easy, $conf);
+        unset($conf['_headers']);
+
+        // Add handler options from the request configuration options
+        if (isset($options['curl'])) {
+            $conf = \array_replace($conf, $options['curl']);
+        }
+
+        $conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
+        $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init();
+        curl_setopt_array($easy->handle, $conf);
+
+        return $easy;
+    }
+
+    private static function supportsHttp2(): bool
+    {
+        static $supportsHttp2 = null;
+
+        if (null === $supportsHttp2) {
+            $supportsHttp2 = self::supportsTls12()
+                && defined('CURL_VERSION_HTTP2')
+                && (\CURL_VERSION_HTTP2 & \curl_version()['features']);
+        }
+
+        return $supportsHttp2;
+    }
+
+    private static function supportsTls12(): bool
+    {
+        static $supportsTls12 = null;
+
+        if (null === $supportsTls12) {
+            $supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
+        }
+
+        return $supportsTls12;
+    }
+
+    private static function supportsTls13(): bool
+    {
+        static $supportsTls13 = null;
+
+        if (null === $supportsTls13) {
+            $supportsTls13 = defined('CURL_SSLVERSION_TLSv1_3')
+                && (\CURL_SSLVERSION_TLSv1_3 & \curl_version()['features']);
+        }
+
+        return $supportsTls13;
+    }
+
+    public function release(EasyHandle $easy): void
+    {
+        $resource = $easy->handle;
+        unset($easy->handle);
+
+        if (\count($this->handles) >= $this->maxHandles) {
+            \curl_close($resource);
+        } else {
+            // Remove all callback functions as they can hold onto references
+            // and are not cleaned up by curl_reset. Using curl_setopt_array
+            // does not work for some reason, so removing each one
+            // individually.
+            \curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null);
+            \curl_setopt($resource, \CURLOPT_READFUNCTION, null);
+            \curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null);
+            \curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null);
+            \curl_reset($resource);
+            $this->handles[] = $resource;
+        }
+    }
+
+    /**
+     * Completes a cURL transaction, either returning a response promise or a
+     * rejected promise.
+     *
+     * @param callable(RequestInterface, array): PromiseInterface $handler
+     * @param CurlFactoryInterface                                $factory Dictates how the handle is released
+     */
+    public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface
+    {
+        if (isset($easy->options['on_stats'])) {
+            self::invokeStats($easy);
+        }
+
+        if (!$easy->response || $easy->errno) {
+            return self::finishError($handler, $easy, $factory);
+        }
+
+        // Return the response if it is present and there is no error.
+        $factory->release($easy);
+
+        // Rewind the body of the response if possible.
+        $body = $easy->response->getBody();
+        if ($body->isSeekable()) {
+            $body->rewind();
+        }
+
+        return new FulfilledPromise($easy->response);
+    }
+
+    private static function invokeStats(EasyHandle $easy): void
+    {
+        $curlStats = \curl_getinfo($easy->handle);
+        $curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME);
+        $stats = new TransferStats(
+            $easy->request,
+            $easy->response,
+            $curlStats['total_time'],
+            $easy->errno,
+            $curlStats
+        );
+        ($easy->options['on_stats'])($stats);
+    }
+
+    /**
+     * @param callable(RequestInterface, array): PromiseInterface $handler
+     */
+    private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface
+    {
+        // Get error information and release the handle to the factory.
+        $ctx = [
+            'errno' => $easy->errno,
+            'error' => \curl_error($easy->handle),
+            'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME),
+        ] + \curl_getinfo($easy->handle);
+        $ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
+        $factory->release($easy);
+
+        // Retry when nothing is present or when curl failed to rewind.
+        if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
+            return self::retryFailedRewind($handler, $easy, $ctx);
+        }
+
+        return self::createRejection($easy, $ctx);
+    }
+
+    private static function getCurlVersion(): string
+    {
+        static $curlVersion = null;
+
+        if (null === $curlVersion) {
+            $curlVersion = \curl_version()['version'];
+        }
+
+        return $curlVersion;
+    }
+
+    private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface
+    {
+        static $connectionErrors = [
+            \CURLE_OPERATION_TIMEOUTED => true,
+            \CURLE_COULDNT_RESOLVE_HOST => true,
+            \CURLE_COULDNT_CONNECT => true,
+            \CURLE_SSL_CONNECT_ERROR => true,
+            \CURLE_GOT_NOTHING => true,
+        ];
+
+        if ($easy->createResponseException) {
+            return P\Create::rejectionFor(
+                new RequestException(
+                    'An error was encountered while creating the response',
+                    $easy->request,
+                    $easy->response,
+                    $easy->createResponseException,
+                    $ctx
+                )
+            );
+        }
+
+        // If an exception was encountered during the onHeaders event, then
+        // return a rejected promise that wraps that exception.
+        if ($easy->onHeadersException) {
+            return P\Create::rejectionFor(
+                new RequestException(
+                    'An error was encountered during the on_headers event',
+                    $easy->request,
+                    $easy->response,
+                    $easy->onHeadersException,
+                    $ctx
+                )
+            );
+        }
+
+        $uri = $easy->request->getUri();
+
+        $sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
+
+        $message = \sprintf(
+            'cURL error %s: %s (%s)',
+            $ctx['errno'],
+            $sanitizedError,
+            'see https://curl.haxx.se/libcurl/c/libcurl-errors.html'
+        );
+
+        if ('' !== $sanitizedError) {
+            $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
+            if ($redactedUriString !== '' && false === \strpos($sanitizedError, $redactedUriString)) {
+                $message .= \sprintf(' for %s', $redactedUriString);
+            }
+        }
+
+        // Create a connection exception if it was a specific error code.
+        $error = isset($connectionErrors[$easy->errno])
+            ? new ConnectException($message, $easy->request, null, $ctx)
+            : new RequestException($message, $easy->request, $easy->response, null, $ctx);
+
+        return P\Create::rejectionFor($error);
+    }
+
+    private static function sanitizeCurlError(string $error, UriInterface $uri): string
+    {
+        if ('' === $error) {
+            return $error;
+        }
+
+        $baseUri = $uri->withQuery('')->withFragment('');
+        $baseUriString = $baseUri->__toString();
+
+        if ('' === $baseUriString) {
+            return $error;
+        }
+
+        $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
+
+        return str_replace($baseUriString, $redactedUriString, $error);
+    }
+
+    /**
+     * @return array<int|string, mixed>
+     */
+    private function getDefaultConf(EasyHandle $easy): array
+    {
+        $conf = [
+            '_headers' => $easy->request->getHeaders(),
+            \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(),
+            \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''),
+            \CURLOPT_RETURNTRANSFER => false,
+            \CURLOPT_HEADER => false,
+            \CURLOPT_CONNECTTIMEOUT => 300,
+        ];
+
+        if (\defined('CURLOPT_PROTOCOLS')) {
+            $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
+        }
+
+        $version = $easy->request->getProtocolVersion();
+
+        if ('2' === $version || '2.0' === $version) {
+            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
+        } elseif ('1.1' === $version) {
+            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
+        } else {
+            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
+        }
+
+        return $conf;
+    }
+
+    private function applyMethod(EasyHandle $easy, array &$conf): void
+    {
+        $body = $easy->request->getBody();
+        $size = $body->getSize();
+
+        if ($size === null || $size > 0) {
+            $this->applyBody($easy->request, $easy->options, $conf);
+
+            return;
+        }
+
+        $method = $easy->request->getMethod();
+        if ($method === 'PUT' || $method === 'POST') {
+            // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
+            if (!$easy->request->hasHeader('Content-Length')) {
+                $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
+            }
+        } elseif ($method === 'HEAD') {
+            $conf[\CURLOPT_NOBODY] = true;
+            unset(
+                $conf[\CURLOPT_WRITEFUNCTION],
+                $conf[\CURLOPT_READFUNCTION],
+                $conf[\CURLOPT_FILE],
+                $conf[\CURLOPT_INFILE]
+            );
+        }
+    }
+
+    private function applyBody(RequestInterface $request, array $options, array &$conf): void
+    {
+        $size = $request->hasHeader('Content-Length')
+            ? (int) $request->getHeaderLine('Content-Length')
+            : null;
+
+        // Send the body as a string if the size is less than 1MB OR if the
+        // [curl][body_as_string] request value is set.
+        if (($size !== null && $size < 1000000) || !empty($options['_body_as_string'])) {
+            $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody();
+            // Don't duplicate the Content-Length header
+            $this->removeHeader('Content-Length', $conf);
+            $this->removeHeader('Transfer-Encoding', $conf);
+        } else {
+            $conf[\CURLOPT_UPLOAD] = true;
+            if ($size !== null) {
+                $conf[\CURLOPT_INFILESIZE] = $size;
+                $this->removeHeader('Content-Length', $conf);
+            }
+            $body = $request->getBody();
+            if ($body->isSeekable()) {
+                $body->rewind();
+            }
+            $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body) {
+                return $body->read($length);
+            };
+        }
+
+        // If the Expect header is not present, prevent curl from adding it
+        if (!$request->hasHeader('Expect')) {
+            $conf[\CURLOPT_HTTPHEADER][] = 'Expect:';
+        }
+
+        // cURL sometimes adds a content-type by default. Prevent this.
+        if (!$request->hasHeader('Content-Type')) {
+            $conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:';
+        }
+    }
+
+    private function applyHeaders(EasyHandle $easy, array &$conf): void
+    {
+        foreach ($conf['_headers'] as $name => $values) {
+            foreach ($values as $value) {
+                $value = (string) $value;
+                if ($value === '') {
+                    // cURL requires a special format for empty headers.
+                    // See https://github.com/guzzle/guzzle/issues/1882 for more details.
+                    $conf[\CURLOPT_HTTPHEADER][] = "$name;";
+                } else {
+                    $conf[\CURLOPT_HTTPHEADER][] = "$name: $value";
+                }
+            }
+        }
+
+        // Remove the Accept header if one was not set
+        if (!$easy->request->hasHeader('Accept')) {
+            $conf[\CURLOPT_HTTPHEADER][] = 'Accept:';
+        }
+    }
+
+    /**
+     * Remove a header from the options array.
+     *
+     * @param string $name    Case-insensitive header to remove
+     * @param array  $options Array of options to modify
+     */
+    private function removeHeader(string $name, array &$options): void
+    {
+        foreach (\array_keys($options['_headers']) as $key) {
+            if (!\strcasecmp($key, $name)) {
+                unset($options['_headers'][$key]);
+
+                return;
+            }
+        }
+    }
+
+    private function applyHandlerOptions(EasyHandle $easy, array &$conf): void
+    {
+        $options = $easy->options;
+        if (isset($options['verify'])) {
+            if ($options['verify'] === false) {
+                unset($conf[\CURLOPT_CAINFO]);
+                $conf[\CURLOPT_SSL_VERIFYHOST] = 0;
+                $conf[\CURLOPT_SSL_VERIFYPEER] = false;
+            } else {
+                $conf[\CURLOPT_SSL_VERIFYHOST] = 2;
+                $conf[\CURLOPT_SSL_VERIFYPEER] = true;
+                if (\is_string($options['verify'])) {
+                    // Throw an error if the file/folder/link path is not valid or doesn't exist.
+                    if (!\file_exists($options['verify'])) {
+                        throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}");
+                    }
+                    // If it's a directory or a link to a directory use CURLOPT_CAPATH.
+                    // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
+                    if (
+                        \is_dir($options['verify'])
+                        || (
+                            \is_link($options['verify']) === true
+                            && ($verifyLink = \readlink($options['verify'])) !== false
+                            && \is_dir($verifyLink)
+                        )
+                    ) {
+                        $conf[\CURLOPT_CAPATH] = $options['verify'];
+                    } else {
+                        $conf[\CURLOPT_CAINFO] = $options['verify'];
+                    }
+                }
+            }
+        }
+
+        if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) {
+            $accept = $easy->request->getHeaderLine('Accept-Encoding');
+            if ($accept) {
+                $conf[\CURLOPT_ENCODING] = $accept;
+            } else {
+                // The empty string enables all available decoders and implicitly
+                // sets a matching 'Accept-Encoding' header.
+                $conf[\CURLOPT_ENCODING] = '';
+                // But as the user did not specify any encoding preference,
+                // let's leave it up to server by preventing curl from sending
+                // the header, which will be interpreted as 'Accept-Encoding: *'.
+                // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
+                $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
+            }
+        }
+
+        if (!isset($options['sink'])) {
+            // Use a default temp stream if no sink was set.
+            $options['sink'] = \GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'w+');
+        }
+        $sink = $options['sink'];
+        if (!\is_string($sink)) {
+            $sink = \GuzzleHttp\Psr7\Utils::streamFor($sink);
+        } elseif (!\is_dir(\dirname($sink))) {
+            // Ensure that the directory exists before failing in curl.
+            throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink));
+        } else {
+            $sink = new LazyOpenStream($sink, 'w+');
+        }
+        $easy->sink = $sink;
+        $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use ($sink): int {
+            return $sink->write($write);
+        };
+
+        $timeoutRequiresNoSignal = false;
+        if (isset($options['timeout'])) {
+            $timeoutRequiresNoSignal |= $options['timeout'] < 1;
+            $conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
+        }
+
+        // CURL default value is CURL_IPRESOLVE_WHATEVER
+        if (isset($options['force_ip_resolve'])) {
+            if ('v4' === $options['force_ip_resolve']) {
+                $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4;
+            } elseif ('v6' === $options['force_ip_resolve']) {
+                $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6;
+            }
+        }
+
+        if (isset($options['connect_timeout'])) {
+            $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
+            $conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
+        }
+
+        if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') {
+            $conf[\CURLOPT_NOSIGNAL] = true;
+        }
+
+        if (isset($options['proxy'])) {
+            if (!\is_array($options['proxy'])) {
+                $conf[\CURLOPT_PROXY] = $options['proxy'];
+            } else {
+                $scheme = $easy->request->getUri()->getScheme();
+                if (isset($options['proxy'][$scheme])) {
+                    $host = $easy->request->getUri()->getHost();
+                    if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
+                        unset($conf[\CURLOPT_PROXY]);
+                    } else {
+                        $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
+                    }
+                }
+            }
+        }
+
+        if (isset($options['crypto_method'])) {
+            $protocolVersion = $easy->request->getProtocolVersion();
+
+            // If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
+            if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
+                if (
+                    \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']
+                    || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']
+                    || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']
+                ) {
+                    $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
+                } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
+                    if (!self::supportsTls13()) {
+                        throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
+                    }
+                    $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
+                } else {
+                    throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
+                }
+            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
+                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
+            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
+                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
+            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
+                if (!self::supportsTls12()) {
+                    throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
+                }
+                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
+            } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
+                if (!self::supportsTls13()) {
+                    throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
+                }
+                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
+            } else {
+                throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
+            }
+        }
+
+        if (isset($options['cert'])) {
+            $cert = $options['cert'];
+            if (\is_array($cert)) {
+                $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1];
+                $cert = $cert[0];
+            }
+            if (!\file_exists($cert)) {
+                throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
+            }
+            // OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
+            // see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
+            $ext = pathinfo($cert, \PATHINFO_EXTENSION);
+            if (preg_match('#^(der|p12)$#i', $ext)) {
+                $conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext);
+            }
+            $conf[\CURLOPT_SSLCERT] = $cert;
+        }
+
+        if (isset($options['ssl_key'])) {
+            if (\is_array($options['ssl_key'])) {
+                if (\count($options['ssl_key']) === 2) {
+                    [$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key'];
+                } else {
+                    [$sslKey] = $options['ssl_key'];
+                }
+            }
+
+            $sslKey = $sslKey ?? $options['ssl_key'];
+
+            if (!\file_exists($sslKey)) {
+                throw new \InvalidArgumentException("SSL private key not found: {$sslKey}");
+            }
+            $conf[\CURLOPT_SSLKEY] = $sslKey;
+        }
+
+        if (isset($options['progress'])) {
+            $progress = $options['progress'];
+            if (!\is_callable($progress)) {
+                throw new \InvalidArgumentException('progress client option must be callable');
+            }
+            $conf[\CURLOPT_NOPROGRESS] = false;
+            $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use ($progress) {
+                $progress($downloadSize, $downloaded, $uploadSize, $uploaded);
+            };
+        }
+
+        if (!empty($options['debug'])) {
+            $conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']);
+            $conf[\CURLOPT_VERBOSE] = true;
+        }
+    }
+
+    /**
+     * This function ensures that a response was set on a transaction. If one
+     * was not set, then the request is retried if possible. This error
+     * typically means you are sending a payload, curl encountered a
+     * "Connection died, retrying a fresh connect" error, tried to rewind the
+     * stream, and then encountered a "necessary data rewind wasn't possible"
+     * error, causing the request to be sent through curl_multi_info_read()
+     * without an error status.
+     *
+     * @param callable(RequestInterface, array): PromiseInterface $handler
+     */
+    private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx): PromiseInterface
+    {
+        try {
+            // Only rewind if the body has been read from.
+            $body = $easy->request->getBody();
+            if ($body->tell() > 0) {
+                $body->rewind();
+            }
+        } catch (\RuntimeException $e) {
+            $ctx['error'] = 'The connection unexpectedly failed without '
+                .'providing an error. The request would have been retried, '
+                .'but attempting to rewind the request body failed. '
+                .'Exception: '.$e;
+
+            return self::createRejection($easy, $ctx);
+        }
+
+        // Retry no more than 3 times before giving up.
+        if (!isset($easy->options['_curl_retries'])) {
+            $easy->options['_curl_retries'] = 1;
+        } elseif ($easy->options['_curl_retries'] == 2) {
+            $ctx['error'] = 'The cURL request was retried 3 times '
+                .'and did not succeed. The most likely reason for the failure '
+                .'is that cURL was unable to rewind the body of the request '
+                .'and subsequent retries resulted in the same error. Turn on '
+                .'the debug option to see what went wrong. See '
+                .'https://bugs.php.net/bug.php?id=47204 for more information.';
+
+            return self::createRejection($easy, $ctx);
+        } else {
+            ++$easy->options['_curl_retries'];
+        }
+
+        return $handler($easy->request, $easy->options);
+    }
+
+    private function createHeaderFn(EasyHandle $easy): callable
+    {
+        if (isset($easy->options['on_headers'])) {
+            $onHeaders = $easy->options['on_headers'];
+
+            if (!\is_callable($onHeaders)) {
+                throw new \InvalidArgumentException('on_headers must be callable');
+            }
+        } else {
+            $onHeaders = null;
+        }
+
+        return static function ($ch, $h) use (
+            $onHeaders,
+            $easy,
+            &$startingResponse
+        ) {
+            $value = \trim($h);
+            if ($value === '') {
+                $startingResponse = true;
+                try {
+                    $easy->createResponse();
+                } catch (\Exception $e) {
+                    $easy->createResponseException = $e;
+
+                    return -1;
+                }
+                if ($onHeaders !== null) {
+                    try {
+                        $onHeaders($easy->response);
+                    } catch (\Exception $e) {
+                        // Associate the exception with the handle and trigger
+                        // a curl header write error by returning 0.
+                        $easy->onHeadersException = $e;
+
+                        return -1;
+                    }
+                }
+            } elseif ($startingResponse) {
+                $startingResponse = false;
+                $easy->headers = [$value];
+            } else {
+                $easy->headers[] = $value;
+            }
+
+            return \strlen($h);
+        };
+    }
+
+    public function __destruct()
+    {
+        foreach ($this->handles as $id => $handle) {
+            \curl_close($handle);
+            unset($this->handles[$id]);
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,25 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use Psr\Http\Message\RequestInterface;
+
+interface CurlFactoryInterface
+{
+    /**
+     * Creates a cURL handle resource.
+     *
+     * @param RequestInterface $request Request
+     * @param array            $options Transfer options
+     *
+     * @throws \RuntimeException when an option cannot be applied
+     */
+    public function create(RequestInterface $request, array $options): EasyHandle;
+
+    /**
+     * Release an easy handle, allowing it to be reused or closed.
+     *
+     * This function must call unset on the easy handle's "handle" property.
+     */
+    public function release(EasyHandle $easy): void;
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,49 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * HTTP handler that uses cURL easy handles as a transport layer.
+ *
+ * When using the CurlHandler, custom curl options can be specified as an
+ * associative array of curl option constants mapping to values in the
+ * **curl** key of the "client" key of the request.
+ *
+ * @final
+ */
+class CurlHandler
+{
+    /**
+     * @var CurlFactoryInterface
+     */
+    private $factory;
+
+    /**
+     * Accepts an associative array of options:
+     *
+     * - handle_factory: Optional curl factory used to create cURL handles.
+     *
+     * @param array{handle_factory?: ?CurlFactoryInterface} $options Array of options to use with the handler
+     */
+    public function __construct(array $options = [])
+    {
+        $this->factory = $options['handle_factory']
+            ?? new CurlFactory(3);
+    }
+
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        if (isset($options['delay'])) {
+            \usleep($options['delay'] * 1000);
+        }
+
+        $easy = $this->factory->create($request, $options);
+        \curl_exec($easy->handle);
+        $easy->errno = \curl_errno($easy->handle);
+
+        return CurlFactory::finish($this, $easy, $this->factory);
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,284 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use Closure;
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\Promise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Returns an asynchronous response using curl_multi_* functions.
+ *
+ * When using the CurlMultiHandler, custom curl options can be specified as an
+ * associative array of curl option constants mapping to values in the
+ * **curl** key of the provided request options.
+ *
+ * @final
+ */
+class CurlMultiHandler
+{
+    /**
+     * @var CurlFactoryInterface
+     */
+    private $factory;
+
+    /**
+     * @var int
+     */
+    private $selectTimeout;
+
+    /**
+     * @var int Will be higher than 0 when `curl_multi_exec` is still running.
+     */
+    private $active = 0;
+
+    /**
+     * @var array Request entry handles, indexed by handle id in `addRequest`.
+     *
+     * @see CurlMultiHandler::addRequest
+     */
+    private $handles = [];
+
+    /**
+     * @var array<int, float> An array of delay times, indexed by handle id in `addRequest`.
+     *
+     * @see CurlMultiHandler::addRequest
+     */
+    private $delays = [];
+
+    /**
+     * @var array<mixed> An associative array of CURLMOPT_* options and corresponding values for curl_multi_setopt()
+     */
+    private $options = [];
+
+    /** @var resource|\CurlMultiHandle */
+    private $_mh;
+
+    /**
+     * This handler accepts the following options:
+     *
+     * - handle_factory: An optional factory  used to create curl handles
+     * - select_timeout: Optional timeout (in seconds) to block before timing
+     *   out while selecting curl handles. Defaults to 1 second.
+     * - options: An associative array of CURLMOPT_* options and
+     *   corresponding values for curl_multi_setopt()
+     */
+    public function __construct(array $options = [])
+    {
+        $this->factory = $options['handle_factory'] ?? new CurlFactory(50);
+
+        if (isset($options['select_timeout'])) {
+            $this->selectTimeout = $options['select_timeout'];
+        } elseif ($selectTimeout = Utils::getenv('GUZZLE_CURL_SELECT_TIMEOUT')) {
+            @trigger_error('Since guzzlehttp/guzzle 7.2.0: Using environment variable GUZZLE_CURL_SELECT_TIMEOUT is deprecated. Use option "select_timeout" instead.', \E_USER_DEPRECATED);
+            $this->selectTimeout = (int) $selectTimeout;
+        } else {
+            $this->selectTimeout = 1;
+        }
+
+        $this->options = $options['options'] ?? [];
+
+        // unsetting the property forces the first access to go through
+        // __get().
+        unset($this->_mh);
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return resource|\CurlMultiHandle
+     *
+     * @throws \BadMethodCallException when another field as `_mh` will be gotten
+     * @throws \RuntimeException       when curl can not initialize a multi handle
+     */
+    public function __get($name)
+    {
+        if ($name !== '_mh') {
+            throw new \BadMethodCallException("Can not get other property as '_mh'.");
+        }
+
+        $multiHandle = \curl_multi_init();
+
+        if (false === $multiHandle) {
+            throw new \RuntimeException('Can not initialize curl multi handle.');
+        }
+
+        $this->_mh = $multiHandle;
+
+        foreach ($this->options as $option => $value) {
+            // A warning is raised in case of a wrong option.
+            curl_multi_setopt($this->_mh, $option, $value);
+        }
+
+        return $this->_mh;
+    }
+
+    public function __destruct()
+    {
+        if (isset($this->_mh)) {
+            \curl_multi_close($this->_mh);
+            unset($this->_mh);
+        }
+    }
+
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        $easy = $this->factory->create($request, $options);
+        $id = (int) $easy->handle;
+
+        $promise = new Promise(
+            [$this, 'execute'],
+            function () use ($id) {
+                return $this->cancel($id);
+            }
+        );
+
+        $this->addRequest(['easy' => $easy, 'deferred' => $promise]);
+
+        return $promise;
+    }
+
+    /**
+     * Ticks the curl event loop.
+     */
+    public function tick(): void
+    {
+        // Add any delayed handles if needed.
+        if ($this->delays) {
+            $currentTime = Utils::currentTime();
+            foreach ($this->delays as $id => $delay) {
+                if ($currentTime >= $delay) {
+                    unset($this->delays[$id]);
+                    \curl_multi_add_handle(
+                        $this->_mh,
+                        $this->handles[$id]['easy']->handle
+                    );
+                }
+            }
+        }
+
+        // Run curl_multi_exec in the queue to enable other async tasks to run
+        P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
+
+        // Step through the task queue which may add additional requests.
+        P\Utils::queue()->run();
+
+        if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) {
+            // Perform a usleep if a select returns -1.
+            // See: https://bugs.php.net/bug.php?id=61141
+            \usleep(250);
+        }
+
+        while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
+            // Prevent busy looping for slow HTTP requests.
+            \curl_multi_select($this->_mh, $this->selectTimeout);
+        }
+
+        $this->processMessages();
+    }
+
+    /**
+     * Runs \curl_multi_exec() inside the event loop, to prevent busy looping
+     */
+    private function tickInQueue(): void
+    {
+        if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) {
+            \curl_multi_select($this->_mh, 0);
+            P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue']));
+        }
+    }
+
+    /**
+     * Runs until all outstanding connections have completed.
+     */
+    public function execute(): void
+    {
+        $queue = P\Utils::queue();
+
+        while ($this->handles || !$queue->isEmpty()) {
+            // If there are no transfers, then sleep for the next delay
+            if (!$this->active && $this->delays) {
+                \usleep($this->timeToNext());
+            }
+            $this->tick();
+        }
+    }
+
+    private function addRequest(array $entry): void
+    {
+        $easy = $entry['easy'];
+        $id = (int) $easy->handle;
+        $this->handles[$id] = $entry;
+        if (empty($easy->options['delay'])) {
+            \curl_multi_add_handle($this->_mh, $easy->handle);
+        } else {
+            $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000);
+        }
+    }
+
+    /**
+     * Cancels a handle from sending and removes references to it.
+     *
+     * @param int $id Handle ID to cancel and remove.
+     *
+     * @return bool True on success, false on failure.
+     */
+    private function cancel($id): bool
+    {
+        if (!is_int($id)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an integer to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        // Cannot cancel if it has been processed.
+        if (!isset($this->handles[$id])) {
+            return false;
+        }
+
+        $handle = $this->handles[$id]['easy']->handle;
+        unset($this->delays[$id], $this->handles[$id]);
+        \curl_multi_remove_handle($this->_mh, $handle);
+        \curl_close($handle);
+
+        return true;
+    }
+
+    private function processMessages(): void
+    {
+        while ($done = \curl_multi_info_read($this->_mh)) {
+            if ($done['msg'] !== \CURLMSG_DONE) {
+                // if it's not done, then it would be premature to remove the handle. ref https://github.com/guzzle/guzzle/pull/2892#issuecomment-945150216
+                continue;
+            }
+            $id = (int) $done['handle'];
+            \curl_multi_remove_handle($this->_mh, $done['handle']);
+
+            if (!isset($this->handles[$id])) {
+                // Probably was cancelled.
+                continue;
+            }
+
+            $entry = $this->handles[$id];
+            unset($this->handles[$id], $this->delays[$id]);
+            $entry['easy']->errno = $done['result'];
+            $entry['deferred']->resolve(
+                CurlFactory::finish($this, $entry['easy'], $this->factory)
+            );
+        }
+    }
+
+    private function timeToNext(): int
+    {
+        $currentTime = Utils::currentTime();
+        $nextTime = \PHP_INT_MAX;
+        foreach ($this->delays as $time) {
+            if ($time < $nextTime) {
+                $nextTime = $time;
+            }
+        }
+
+        return ((int) \max(0, $nextTime - $currentTime)) * 1000000;
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,112 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Psr7\Response;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Represents a cURL easy handle and the data it populates.
+ *
+ * @internal
+ */
+final class EasyHandle
+{
+    /**
+     * @var resource|\CurlHandle cURL resource
+     */
+    public $handle;
+
+    /**
+     * @var StreamInterface Where data is being written
+     */
+    public $sink;
+
+    /**
+     * @var array Received HTTP headers so far
+     */
+    public $headers = [];
+
+    /**
+     * @var ResponseInterface|null Received response (if any)
+     */
+    public $response;
+
+    /**
+     * @var RequestInterface Request being sent
+     */
+    public $request;
+
+    /**
+     * @var array Request options
+     */
+    public $options = [];
+
+    /**
+     * @var int cURL error number (if any)
+     */
+    public $errno = 0;
+
+    /**
+     * @var \Throwable|null Exception during on_headers (if any)
+     */
+    public $onHeadersException;
+
+    /**
+     * @var \Exception|null Exception during createResponse (if any)
+     */
+    public $createResponseException;
+
+    /**
+     * Attach a response to the easy handle based on the received headers.
+     *
+     * @throws \RuntimeException if no headers have been received or the first
+     *                           header line is invalid.
+     */
+    public function createResponse(): void
+    {
+        [$ver, $status, $reason, $headers] = HeaderProcessor::parseHeaders($this->headers);
+
+        $normalizedKeys = Utils::normalizeHeaderKeys($headers);
+
+        if (!empty($this->options['decode_content']) && isset($normalizedKeys['content-encoding'])) {
+            $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']];
+            unset($headers[$normalizedKeys['content-encoding']]);
+            if (isset($normalizedKeys['content-length'])) {
+                $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']];
+
+                $bodyLength = (int) $this->sink->getSize();
+                if ($bodyLength) {
+                    $headers[$normalizedKeys['content-length']] = $bodyLength;
+                } else {
+                    unset($headers[$normalizedKeys['content-length']]);
+                }
+            }
+        }
+
+        // Attach a response to the easy handle with the parsed headers.
+        $this->response = new Response(
+            $status,
+            $headers,
+            $this->sink,
+            $ver,
+            $reason
+        );
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return void
+     *
+     * @throws \BadMethodCallException
+     */
+    public function __get($name)
+    {
+        $msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: '.$name;
+        throw new \BadMethodCallException($msg);
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,42 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Utils;
+
+/**
+ * @internal
+ */
+final class HeaderProcessor
+{
+    /**
+     * Returns the HTTP version, status code, reason phrase, and headers.
+     *
+     * @param string[] $headers
+     *
+     * @return array{0:string, 1:int, 2:?string, 3:array}
+     *
+     * @throws \RuntimeException
+     */
+    public static function parseHeaders(array $headers): array
+    {
+        if ($headers === []) {
+            throw new \RuntimeException('Expected a non-empty array of header data');
+        }
+
+        $parts = \explode(' ', \array_shift($headers), 3);
+        $version = \explode('/', $parts[0])[1] ?? null;
+
+        if ($version === null) {
+            throw new \RuntimeException('HTTP version missing from header data');
+        }
+
+        $status = $parts[1] ?? null;
+
+        if ($status === null) {
+            throw new \RuntimeException('HTTP status code missing from header data');
+        }
+
+        return [$version, (int) $status, $parts[2] ?? null, Utils::headersFromLines($headers)];
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,212 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\HandlerStack;
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\TransferStats;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+
+/**
+ * Handler that returns responses or throw exceptions from a queue.
+ *
+ * @final
+ */
+class MockHandler implements \Countable
+{
+    /**
+     * @var array
+     */
+    private $queue = [];
+
+    /**
+     * @var RequestInterface|null
+     */
+    private $lastRequest;
+
+    /**
+     * @var array
+     */
+    private $lastOptions = [];
+
+    /**
+     * @var callable|null
+     */
+    private $onFulfilled;
+
+    /**
+     * @var callable|null
+     */
+    private $onRejected;
+
+    /**
+     * Creates a new MockHandler that uses the default handler stack list of
+     * middlewares.
+     *
+     * @param array|null    $queue       Array of responses, callables, or exceptions.
+     * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled.
+     * @param callable|null $onRejected  Callback to invoke when the return value is rejected.
+     */
+    public static function createWithMiddleware(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null): HandlerStack
+    {
+        return HandlerStack::create(new self($queue, $onFulfilled, $onRejected));
+    }
+
+    /**
+     * The passed in value must be an array of
+     * {@see ResponseInterface} objects, Exceptions,
+     * callables, or Promises.
+     *
+     * @param array<int, mixed>|null $queue       The parameters to be passed to the append function, as an indexed array.
+     * @param callable|null          $onFulfilled Callback to invoke when the return value is fulfilled.
+     * @param callable|null          $onRejected  Callback to invoke when the return value is rejected.
+     */
+    public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null)
+    {
+        $this->onFulfilled = $onFulfilled;
+        $this->onRejected = $onRejected;
+
+        if ($queue) {
+            // array_values included for BC
+            $this->append(...array_values($queue));
+        }
+    }
+
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        if (!$this->queue) {
+            throw new \OutOfBoundsException('Mock queue is empty');
+        }
+
+        if (isset($options['delay']) && \is_numeric($options['delay'])) {
+            \usleep((int) $options['delay'] * 1000);
+        }
+
+        $this->lastRequest = $request;
+        $this->lastOptions = $options;
+        $response = \array_shift($this->queue);
+
+        if (isset($options['on_headers'])) {
+            if (!\is_callable($options['on_headers'])) {
+                throw new \InvalidArgumentException('on_headers must be callable');
+            }
+            try {
+                $options['on_headers']($response);
+            } catch (\Exception $e) {
+                $msg = 'An error was encountered during the on_headers event';
+                $response = new RequestException($msg, $request, $response, $e);
+            }
+        }
+
+        if (\is_callable($response)) {
+            $response = $response($request, $options);
+        }
+
+        $response = $response instanceof \Throwable
+            ? P\Create::rejectionFor($response)
+            : P\Create::promiseFor($response);
+
+        return $response->then(
+            function (?ResponseInterface $value) use ($request, $options) {
+                $this->invokeStats($request, $options, $value);
+                if ($this->onFulfilled) {
+                    ($this->onFulfilled)($value);
+                }
+
+                if ($value !== null && isset($options['sink'])) {
+                    $contents = (string) $value->getBody();
+                    $sink = $options['sink'];
+
+                    if (\is_resource($sink)) {
+                        \fwrite($sink, $contents);
+                    } elseif (\is_string($sink)) {
+                        \file_put_contents($sink, $contents);
+                    } elseif ($sink instanceof StreamInterface) {
+                        $sink->write($contents);
+                    }
+                }
+
+                return $value;
+            },
+            function ($reason) use ($request, $options) {
+                $this->invokeStats($request, $options, null, $reason);
+                if ($this->onRejected) {
+                    ($this->onRejected)($reason);
+                }
+
+                return P\Create::rejectionFor($reason);
+            }
+        );
+    }
+
+    /**
+     * Adds one or more variadic requests, exceptions, callables, or promises
+     * to the queue.
+     *
+     * @param mixed ...$values
+     */
+    public function append(...$values): void
+    {
+        foreach ($values as $value) {
+            if ($value instanceof ResponseInterface
+                || $value instanceof \Throwable
+                || $value instanceof PromiseInterface
+                || \is_callable($value)
+            ) {
+                $this->queue[] = $value;
+            } else {
+                throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found '.Utils::describeType($value));
+            }
+        }
+    }
+
+    /**
+     * Get the last received request.
+     */
+    public function getLastRequest(): ?RequestInterface
+    {
+        return $this->lastRequest;
+    }
+
+    /**
+     * Get the last received request options.
+     */
+    public function getLastOptions(): array
+    {
+        return $this->lastOptions;
+    }
+
+    /**
+     * Returns the number of remaining items in the queue.
+     */
+    public function count(): int
+    {
+        return \count($this->queue);
+    }
+
+    public function reset(): void
+    {
+        $this->queue = [];
+    }
+
+    /**
+     * @param mixed $reason Promise or reason.
+     */
+    private function invokeStats(
+        RequestInterface $request,
+        array $options,
+        ?ResponseInterface $response = null,
+        $reason = null
+    ): void {
+        if (isset($options['on_stats'])) {
+            $transferTime = $options['transfer_time'] ?? 0;
+            $stats = new TransferStats($request, $response, $transferTime, $reason);
+            ($options['on_stats'])($stats);
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/Proxy.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/Proxy.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/Proxy.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,51 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\RequestOptions;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Provides basic proxies for handlers.
+ *
+ * @final
+ */
+class Proxy
+{
+    /**
+     * Sends synchronous requests to a specific handler while sending all other
+     * requests to another handler.
+     *
+     * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for normal responses
+     * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $sync    Handler used for synchronous responses.
+     *
+     * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
+     */
+    public static function wrapSync(callable $default, callable $sync): callable
+    {
+        return static function (RequestInterface $request, array $options) use ($default, $sync): PromiseInterface {
+            return empty($options[RequestOptions::SYNCHRONOUS]) ? $default($request, $options) : $sync($request, $options);
+        };
+    }
+
+    /**
+     * Sends streaming requests to a streaming compatible handler while sending
+     * all other requests to a default handler.
+     *
+     * This, for example, could be useful for taking advantage of the
+     * performance benefits of curl while still supporting true streaming
+     * through the StreamHandler.
+     *
+     * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default   Handler used for non-streaming responses
+     * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $streaming Handler used for streaming responses
+     *
+     * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler.
+     */
+    public static function wrapStreaming(callable $default, callable $streaming): callable
+    {
+        return static function (RequestInterface $request, array $options) use ($default, $streaming): PromiseInterface {
+            return empty($options['stream']) ? $default($request, $options) : $streaming($request, $options);
+        };
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,621 @@
+<?php
+
+namespace GuzzleHttp\Handler;
+
+use GuzzleHttp\Exception\ConnectException;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\FulfilledPromise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Psr7;
+use GuzzleHttp\TransferStats;
+use GuzzleHttp\Utils;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\StreamInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * HTTP handler that uses PHP's HTTP stream wrapper.
+ *
+ * @final
+ */
+class StreamHandler
+{
+    /**
+     * @var array
+     */
+    private $lastHeaders = [];
+
+    /**
+     * Sends an HTTP request.
+     *
+     * @param RequestInterface $request Request to send.
+     * @param array            $options Request transfer options.
+     */
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        // Sleep if there is a delay specified.
+        if (isset($options['delay'])) {
+            \usleep($options['delay'] * 1000);
+        }
+
+        $protocolVersion = $request->getProtocolVersion();
+
+        if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
+            throw new ConnectException(sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request);
+        }
+
+        $startTime = isset($options['on_stats']) ? Utils::currentTime() : null;
+
+        try {
+            // Does not support the expect header.
+            $request = $request->withoutHeader('Expect');
+
+            // Append a content-length header if body size is zero to match
+            // cURL's behavior.
+            if (0 === $request->getBody()->getSize()) {
+                $request = $request->withHeader('Content-Length', '0');
+            }
+
+            return $this->createResponse(
+                $request,
+                $options,
+                $this->createStream($request, $options),
+                $startTime
+            );
+        } catch (\InvalidArgumentException $e) {
+            throw $e;
+        } catch (\Exception $e) {
+            // Determine if the error was a networking error.
+            $message = $e->getMessage();
+            // This list can probably get more comprehensive.
+            if (false !== \strpos($message, 'getaddrinfo') // DNS lookup failed
+                || false !== \strpos($message, 'Connection refused')
+                || false !== \strpos($message, "couldn't connect to host") // error on HHVM
+                || false !== \strpos($message, 'connection attempt failed')
+            ) {
+                $e = new ConnectException($e->getMessage(), $request, $e);
+            } else {
+                $e = RequestException::wrapException($request, $e);
+            }
+            $this->invokeStats($options, $request, $startTime, null, $e);
+
+            return P\Create::rejectionFor($e);
+        }
+    }
+
+    private function invokeStats(
+        array $options,
+        RequestInterface $request,
+        ?float $startTime,
+        ?ResponseInterface $response = null,
+        ?\Throwable $error = null
+    ): void {
+        if (isset($options['on_stats'])) {
+            $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []);
+            ($options['on_stats'])($stats);
+        }
+    }
+
+    /**
+     * @param resource $stream
+     */
+    private function createResponse(RequestInterface $request, array $options, $stream, ?float $startTime): PromiseInterface
+    {
+        $hdrs = $this->lastHeaders;
+        $this->lastHeaders = [];
+
+        try {
+            [$ver, $status, $reason, $headers] = HeaderProcessor::parseHeaders($hdrs);
+        } catch (\Exception $e) {
+            return P\Create::rejectionFor(
+                new RequestException('An error was encountered while creating the response', $request, null, $e)
+            );
+        }
+
+        [$stream, $headers] = $this->checkDecode($options, $headers, $stream);
+        $stream = Psr7\Utils::streamFor($stream);
+        $sink = $stream;
+
+        if (\strcasecmp('HEAD', $request->getMethod())) {
+            $sink = $this->createSink($stream, $options);
+        }
+
+        try {
+            $response = new Psr7\Response($status, $headers, $sink, $ver, $reason);
+        } catch (\Exception $e) {
+            return P\Create::rejectionFor(
+                new RequestException('An error was encountered while creating the response', $request, null, $e)
+            );
+        }
+
+        if (isset($options['on_headers'])) {
+            try {
+                $options['on_headers']($response);
+            } catch (\Exception $e) {
+                return P\Create::rejectionFor(
+                    new RequestException('An error was encountered during the on_headers event', $request, $response, $e)
+                );
+            }
+        }
+
+        // Do not drain when the request is a HEAD request because they have
+        // no body.
+        if ($sink !== $stream) {
+            $this->drain($stream, $sink, $response->getHeaderLine('Content-Length'));
+        }
+
+        $this->invokeStats($options, $request, $startTime, $response, null);
+
+        return new FulfilledPromise($response);
+    }
+
+    private function createSink(StreamInterface $stream, array $options): StreamInterface
+    {
+        if (!empty($options['stream'])) {
+            return $stream;
+        }
+
+        $sink = $options['sink'] ?? Psr7\Utils::tryFopen('php://temp', 'r+');
+
+        return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\Utils::streamFor($sink);
+    }
+
+    /**
+     * @param resource $stream
+     */
+    private function checkDecode(array $options, array $headers, $stream): array
+    {
+        // Automatically decode responses when instructed.
+        if (!empty($options['decode_content'])) {
+            $normalizedKeys = Utils::normalizeHeaderKeys($headers);
+            if (isset($normalizedKeys['content-encoding'])) {
+                $encoding = $headers[$normalizedKeys['content-encoding']];
+                if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') {
+                    $stream = new Psr7\InflateStream(Psr7\Utils::streamFor($stream));
+                    $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']];
+
+                    // Remove content-encoding header
+                    unset($headers[$normalizedKeys['content-encoding']]);
+
+                    // Fix content-length header
+                    if (isset($normalizedKeys['content-length'])) {
+                        $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']];
+                        $length = (int) $stream->getSize();
+                        if ($length === 0) {
+                            unset($headers[$normalizedKeys['content-length']]);
+                        } else {
+                            $headers[$normalizedKeys['content-length']] = [$length];
+                        }
+                    }
+                }
+            }
+        }
+
+        return [$stream, $headers];
+    }
+
+    /**
+     * Drains the source stream into the "sink" client option.
+     *
+     * @param string $contentLength Header specifying the amount of
+     *                              data to read.
+     *
+     * @throws \RuntimeException when the sink option is invalid.
+     */
+    private function drain(StreamInterface $source, StreamInterface $sink, string $contentLength): StreamInterface
+    {
+        // If a content-length header is provided, then stop reading once
+        // that number of bytes has been read. This can prevent infinitely
+        // reading from a stream when dealing with servers that do not honor
+        // Connection: Close headers.
+        Psr7\Utils::copyToStream(
+            $source,
+            $sink,
+            (\strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1
+        );
+
+        $sink->seek(0);
+        $source->close();
+
+        return $sink;
+    }
+
+    /**
+     * Create a resource and check to ensure it was created successfully
+     *
+     * @param callable $callback Callable that returns stream resource
+     *
+     * @return resource
+     *
+     * @throws \RuntimeException on error
+     */
+    private function createResource(callable $callback)
+    {
+        $errors = [];
+        \set_error_handler(static function ($_, $msg, $file, $line) use (&$errors): bool {
+            $errors[] = [
+                'message' => $msg,
+                'file' => $file,
+                'line' => $line,
+            ];
+
+            return true;
+        });
+
+        try {
+            $resource = $callback();
+        } finally {
+            \restore_error_handler();
+        }
+
+        if (!$resource) {
+            $message = 'Error creating resource: ';
+            foreach ($errors as $err) {
+                foreach ($err as $key => $value) {
+                    $message .= "[$key] $value".\PHP_EOL;
+                }
+            }
+            throw new \RuntimeException(\trim($message));
+        }
+
+        return $resource;
+    }
+
+    /**
+     * @return resource
+     */
+    private function createStream(RequestInterface $request, array $options)
+    {
+        static $methods;
+        if (!$methods) {
+            $methods = \array_flip(\get_class_methods(__CLASS__));
+        }
+
+        if (!\in_array($request->getUri()->getScheme(), ['http', 'https'])) {
+            throw new RequestException(\sprintf("The scheme '%s' is not supported.", $request->getUri()->getScheme()), $request);
+        }
+
+        // HTTP/1.1 streams using the PHP stream wrapper require a
+        // Connection: close header
+        if ($request->getProtocolVersion() === '1.1'
+            && !$request->hasHeader('Connection')
+        ) {
+            $request = $request->withHeader('Connection', 'close');
+        }
+
+        // Ensure SSL is verified by default
+        if (!isset($options['verify'])) {
+            $options['verify'] = true;
+        }
+
+        $params = [];
+        $context = $this->getDefaultContext($request);
+
+        if (isset($options['on_headers']) && !\is_callable($options['on_headers'])) {
+            throw new \InvalidArgumentException('on_headers must be callable');
+        }
+
+        if (!empty($options)) {
+            foreach ($options as $key => $value) {
+                $method = "add_{$key}";
+                if (isset($methods[$method])) {
+                    $this->{$method}($request, $context, $value, $params);
+                }
+            }
+        }
+
+        if (isset($options['stream_context'])) {
+            if (!\is_array($options['stream_context'])) {
+                throw new \InvalidArgumentException('stream_context must be an array');
+            }
+            $context = \array_replace_recursive($context, $options['stream_context']);
+        }
+
+        // Microsoft NTLM authentication only supported with curl handler
+        if (isset($options['auth'][2]) && 'ntlm' === $options['auth'][2]) {
+            throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler');
+        }
+
+        $uri = $this->resolveHost($request, $options);
+
+        $contextResource = $this->createResource(
+            static function () use ($context, $params) {
+                return \stream_context_create($context, $params);
+            }
+        );
+
+        return $this->createResource(
+            function () use ($uri, &$http_response_header, $contextResource, $context, $options, $request) {
+                $resource = @\fopen((string) $uri, 'r', false, $contextResource);
+                $this->lastHeaders = $http_response_header ?? [];
+
+                if (false === $resource) {
+                    throw new ConnectException(sprintf('Connection refused for URI %s', $uri), $request, null, $context);
+                }
+
+                if (isset($options['read_timeout'])) {
+                    $readTimeout = $options['read_timeout'];
+                    $sec = (int) $readTimeout;
+                    $usec = ($readTimeout - $sec) * 100000;
+                    \stream_set_timeout($resource, $sec, $usec);
+                }
+
+                return $resource;
+            }
+        );
+    }
+
+    private function resolveHost(RequestInterface $request, array $options): UriInterface
+    {
+        $uri = $request->getUri();
+
+        if (isset($options['force_ip_resolve']) && !\filter_var($uri->getHost(), \FILTER_VALIDATE_IP)) {
+            if ('v4' === $options['force_ip_resolve']) {
+                $records = \dns_get_record($uri->getHost(), \DNS_A);
+                if (false === $records || !isset($records[0]['ip'])) {
+                    throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request);
+                }
+
+                return $uri->withHost($records[0]['ip']);
+            }
+            if ('v6' === $options['force_ip_resolve']) {
+                $records = \dns_get_record($uri->getHost(), \DNS_AAAA);
+                if (false === $records || !isset($records[0]['ipv6'])) {
+                    throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request);
+                }
+
+                return $uri->withHost('['.$records[0]['ipv6'].']');
+            }
+        }
+
+        return $uri;
+    }
+
+    private function getDefaultContext(RequestInterface $request): array
+    {
+        $headers = '';
+        foreach ($request->getHeaders() as $name => $value) {
+            foreach ($value as $val) {
+                $headers .= "$name: $val\r\n";
+            }
+        }
+
+        $context = [
+            'http' => [
+                'method' => $request->getMethod(),
+                'header' => $headers,
+                'protocol_version' => $request->getProtocolVersion(),
+                'ignore_errors' => true,
+                'follow_location' => 0,
+            ],
+            'ssl' => [
+                'peer_name' => $request->getUri()->getHost(),
+            ],
+        ];
+
+        $body = (string) $request->getBody();
+
+        if ('' !== $body) {
+            $context['http']['content'] = $body;
+            // Prevent the HTTP handler from adding a Content-Type header.
+            if (!$request->hasHeader('Content-Type')) {
+                $context['http']['header'] .= "Content-Type:\r\n";
+            }
+        }
+
+        $context['http']['header'] = \rtrim($context['http']['header']);
+
+        return $context;
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_proxy(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        $uri = null;
+
+        if (!\is_array($value)) {
+            $uri = $value;
+        } else {
+            $scheme = $request->getUri()->getScheme();
+            if (isset($value[$scheme])) {
+                if (!isset($value['no']) || !Utils::isHostInNoProxy($request->getUri()->getHost(), $value['no'])) {
+                    $uri = $value[$scheme];
+                }
+            }
+        }
+
+        if (!$uri) {
+            return;
+        }
+
+        $parsed = $this->parse_proxy($uri);
+        $options['http']['proxy'] = $parsed['proxy'];
+
+        if ($parsed['auth']) {
+            if (!isset($options['http']['header'])) {
+                $options['http']['header'] = [];
+            }
+            $options['http']['header'] .= "\r\nProxy-Authorization: {$parsed['auth']}";
+        }
+    }
+
+    /**
+     * Parses the given proxy URL to make it compatible with the format PHP's stream context expects.
+     */
+    private function parse_proxy(string $url): array
+    {
+        $parsed = \parse_url($url);
+
+        if ($parsed !== false && isset($parsed['scheme']) && $parsed['scheme'] === 'http') {
+            if (isset($parsed['host']) && isset($parsed['port'])) {
+                $auth = null;
+                if (isset($parsed['user']) && isset($parsed['pass'])) {
+                    $auth = \base64_encode("{$parsed['user']}:{$parsed['pass']}");
+                }
+
+                return [
+                    'proxy' => "tcp://{$parsed['host']}:{$parsed['port']}",
+                    'auth' => $auth ? "Basic {$auth}" : null,
+                ];
+            }
+        }
+
+        // Return proxy as-is.
+        return [
+            'proxy' => $url,
+            'auth' => null,
+        ];
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_timeout(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        if ($value > 0) {
+            $options['http']['timeout'] = $value;
+        }
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_crypto_method(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        if (
+            $value === \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
+            || $value === \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
+            || $value === \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+            || (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && $value === \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT)
+        ) {
+            $options['http']['crypto_method'] = $value;
+
+            return;
+        }
+
+        throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_verify(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        if ($value === false) {
+            $options['ssl']['verify_peer'] = false;
+            $options['ssl']['verify_peer_name'] = false;
+
+            return;
+        }
+
+        if (\is_string($value)) {
+            $options['ssl']['cafile'] = $value;
+            if (!\file_exists($value)) {
+                throw new \RuntimeException("SSL CA bundle not found: $value");
+            }
+        } elseif ($value !== true) {
+            throw new \InvalidArgumentException('Invalid verify request option');
+        }
+
+        $options['ssl']['verify_peer'] = true;
+        $options['ssl']['verify_peer_name'] = true;
+        $options['ssl']['allow_self_signed'] = false;
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_cert(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        if (\is_array($value)) {
+            $options['ssl']['passphrase'] = $value[1];
+            $value = $value[0];
+        }
+
+        if (!\file_exists($value)) {
+            throw new \RuntimeException("SSL certificate not found: {$value}");
+        }
+
+        $options['ssl']['local_cert'] = $value;
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_progress(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        self::addNotification(
+            $params,
+            static function ($code, $a, $b, $c, $transferred, $total) use ($value) {
+                if ($code == \STREAM_NOTIFY_PROGRESS) {
+                    // The upload progress cannot be determined. Use 0 for cURL compatibility:
+                    // https://curl.se/libcurl/c/CURLOPT_PROGRESSFUNCTION.html
+                    $value($total, $transferred, 0, 0);
+                }
+            }
+        );
+    }
+
+    /**
+     * @param mixed $value as passed via Request transfer options.
+     */
+    private function add_debug(RequestInterface $request, array &$options, $value, array &$params): void
+    {
+        if ($value === false) {
+            return;
+        }
+
+        static $map = [
+            \STREAM_NOTIFY_CONNECT => 'CONNECT',
+            \STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED',
+            \STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT',
+            \STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS',
+            \STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS',
+            \STREAM_NOTIFY_REDIRECTED => 'REDIRECTED',
+            \STREAM_NOTIFY_PROGRESS => 'PROGRESS',
+            \STREAM_NOTIFY_FAILURE => 'FAILURE',
+            \STREAM_NOTIFY_COMPLETED => 'COMPLETED',
+            \STREAM_NOTIFY_RESOLVE => 'RESOLVE',
+        ];
+        static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max'];
+
+        $value = Utils::debugResource($value);
+        $ident = $request->getMethod().' '.$request->getUri()->withFragment('');
+        self::addNotification(
+            $params,
+            static function (int $code, ...$passed) use ($ident, $value, $map, $args): void {
+                \fprintf($value, '<%s> [%s] ', $ident, $map[$code]);
+                foreach (\array_filter($passed) as $i => $v) {
+                    \fwrite($value, $args[$i].': "'.$v.'" ');
+                }
+                \fwrite($value, "\n");
+            }
+        );
+    }
+
+    private static function addNotification(array &$params, callable $notify): void
+    {
+        // Wrap the existing function if needed.
+        if (!isset($params['notification'])) {
+            $params['notification'] = $notify;
+        } else {
+            $params['notification'] = self::callArray([
+                $params['notification'],
+                $notify,
+            ]);
+        }
+    }
+
+    private static function callArray(array $functions): callable
+    {
+        return static function (...$args) use ($functions) {
+            foreach ($functions as $fn) {
+                $fn(...$args);
+            }
+        };
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/HandlerStack.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/HandlerStack.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/HandlerStack.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,275 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Creates a composed Guzzle handler function by stacking middlewares on top of
+ * an HTTP handler function.
+ *
+ * @final
+ */
+class HandlerStack
+{
+    /**
+     * @var (callable(RequestInterface, array): PromiseInterface)|null
+     */
+    private $handler;
+
+    /**
+     * @var array{(callable(callable(RequestInterface, array): PromiseInterface): callable), (string|null)}[]
+     */
+    private $stack = [];
+
+    /**
+     * @var (callable(RequestInterface, array): PromiseInterface)|null
+     */
+    private $cached;
+
+    /**
+     * Creates a default handler stack that can be used by clients.
+     *
+     * The returned handler will wrap the provided handler or use the most
+     * appropriate default handler for your system. The returned HandlerStack has
+     * support for cookies, redirects, HTTP error exceptions, and preparing a body
+     * before sending.
+     *
+     * The returned handler stack can be passed to a client in the "handler"
+     * option.
+     *
+     * @param (callable(RequestInterface, array): PromiseInterface)|null $handler HTTP handler function to use with the stack. If no
+     *                                                                            handler is provided, the best handler for your
+     *                                                                            system will be utilized.
+     */
+    public static function create(?callable $handler = null): self
+    {
+        $stack = new self($handler ?: Utils::chooseHandler());
+        $stack->push(Middleware::httpErrors(), 'http_errors');
+        $stack->push(Middleware::redirect(), 'allow_redirects');
+        $stack->push(Middleware::cookies(), 'cookies');
+        $stack->push(Middleware::prepareBody(), 'prepare_body');
+
+        return $stack;
+    }
+
+    /**
+     * @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler.
+     */
+    public function __construct(?callable $handler = null)
+    {
+        $this->handler = $handler;
+    }
+
+    /**
+     * Invokes the handler stack as a composed handler
+     *
+     * @return ResponseInterface|PromiseInterface
+     */
+    public function __invoke(RequestInterface $request, array $options)
+    {
+        $handler = $this->resolve();
+
+        return $handler($request, $options);
+    }
+
+    /**
+     * Dumps a string representation of the stack.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        $depth = 0;
+        $stack = [];
+
+        if ($this->handler !== null) {
+            $stack[] = '0) Handler: '.$this->debugCallable($this->handler);
+        }
+
+        $result = '';
+        foreach (\array_reverse($this->stack) as $tuple) {
+            ++$depth;
+            $str = "{$depth}) Name: '{$tuple[1]}', ";
+            $str .= 'Function: '.$this->debugCallable($tuple[0]);
+            $result = "> {$str}\n{$result}";
+            $stack[] = $str;
+        }
+
+        foreach (\array_keys($stack) as $k) {
+            $result .= "< {$stack[$k]}\n";
+        }
+
+        return $result;
+    }
+
+    /**
+     * Set the HTTP handler that actually returns a promise.
+     *
+     * @param callable(RequestInterface, array): PromiseInterface $handler Accepts a request and array of options and
+     *                                                                     returns a Promise.
+     */
+    public function setHandler(callable $handler): void
+    {
+        $this->handler = $handler;
+        $this->cached = null;
+    }
+
+    /**
+     * Returns true if the builder has a handler.
+     */
+    public function hasHandler(): bool
+    {
+        return $this->handler !== null;
+    }
+
+    /**
+     * Unshift a middleware to the bottom of the stack.
+     *
+     * @param callable(callable): callable $middleware Middleware function
+     * @param string                       $name       Name to register for this middleware.
+     */
+    public function unshift(callable $middleware, ?string $name = null): void
+    {
+        \array_unshift($this->stack, [$middleware, $name]);
+        $this->cached = null;
+    }
+
+    /**
+     * Push a middleware to the top of the stack.
+     *
+     * @param callable(callable): callable $middleware Middleware function
+     * @param string                       $name       Name to register for this middleware.
+     */
+    public function push(callable $middleware, string $name = ''): void
+    {
+        $this->stack[] = [$middleware, $name];
+        $this->cached = null;
+    }
+
+    /**
+     * Add a middleware before another middleware by name.
+     *
+     * @param string                       $findName   Middleware to find
+     * @param callable(callable): callable $middleware Middleware function
+     * @param string                       $withName   Name to register for this middleware.
+     */
+    public function before(string $findName, callable $middleware, string $withName = ''): void
+    {
+        $this->splice($findName, $withName, $middleware, true);
+    }
+
+    /**
+     * Add a middleware after another middleware by name.
+     *
+     * @param string                       $findName   Middleware to find
+     * @param callable(callable): callable $middleware Middleware function
+     * @param string                       $withName   Name to register for this middleware.
+     */
+    public function after(string $findName, callable $middleware, string $withName = ''): void
+    {
+        $this->splice($findName, $withName, $middleware, false);
+    }
+
+    /**
+     * Remove a middleware by instance or name from the stack.
+     *
+     * @param callable|string $remove Middleware to remove by instance or name.
+     */
+    public function remove($remove): void
+    {
+        if (!is_string($remove) && !is_callable($remove)) {
+            trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a callable or string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__);
+        }
+
+        $this->cached = null;
+        $idx = \is_callable($remove) ? 0 : 1;
+        $this->stack = \array_values(\array_filter(
+            $this->stack,
+            static function ($tuple) use ($idx, $remove) {
+                return $tuple[$idx] !== $remove;
+            }
+        ));
+    }
+
+    /**
+     * Compose the middleware and handler into a single callable function.
+     *
+     * @return callable(RequestInterface, array): PromiseInterface
+     */
+    public function resolve(): callable
+    {
+        if ($this->cached === null) {
+            if (($prev = $this->handler) === null) {
+                throw new \LogicException('No handler has been specified');
+            }
+
+            foreach (\array_reverse($this->stack) as $fn) {
+                /** @var callable(RequestInterface, array): PromiseInterface $prev */
+                $prev = $fn[0]($prev);
+            }
+
+            $this->cached = $prev;
+        }
+
+        return $this->cached;
+    }
+
+    private function findByName(string $name): int
+    {
+        foreach ($this->stack as $k => $v) {
+            if ($v[1] === $name) {
+                return $k;
+            }
+        }
+
+        throw new \InvalidArgumentException("Middleware not found: $name");
+    }
+
+    /**
+     * Splices a function into the middleware list at a specific position.
+     */
+    private function splice(string $findName, string $withName, callable $middleware, bool $before): void
+    {
+        $this->cached = null;
+        $idx = $this->findByName($findName);
+        $tuple = [$middleware, $withName];
+
+        if ($before) {
+            if ($idx === 0) {
+                \array_unshift($this->stack, $tuple);
+            } else {
+                $replacement = [$tuple, $this->stack[$idx]];
+                \array_splice($this->stack, $idx, 1, $replacement);
+            }
+        } elseif ($idx === \count($this->stack) - 1) {
+            $this->stack[] = $tuple;
+        } else {
+            $replacement = [$this->stack[$idx], $tuple];
+            \array_splice($this->stack, $idx, 1, $replacement);
+        }
+    }
+
+    /**
+     * Provides a debug string for a given callable.
+     *
+     * @param callable|string $fn Function to write as a string.
+     */
+    private function debugCallable($fn): string
+    {
+        if (\is_string($fn)) {
+            return "callable({$fn})";
+        }
+
+        if (\is_array($fn)) {
+            return \is_string($fn[0])
+                ? "callable({$fn[0]}::{$fn[1]})"
+                : "callable(['".\get_class($fn[0])."', '{$fn[1]}'])";
+        }
+
+        /** @var object $fn */
+        return 'callable('.\spl_object_hash($fn).')';
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/MessageFormatter.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/MessageFormatter.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/MessageFormatter.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,199 @@
+<?php
+
+namespace GuzzleHttp;
+
+use Psr\Http\Message\MessageInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Formats log messages using variable substitutions for requests, responses,
+ * and other transactional data.
+ *
+ * The following variable substitutions are supported:
+ *
+ * - {request}:        Full HTTP request message
+ * - {response}:       Full HTTP response message
+ * - {ts}:             ISO 8601 date in GMT
+ * - {date_iso_8601}   ISO 8601 date in GMT
+ * - {date_common_log} Apache common log date using the configured timezone.
+ * - {host}:           Host of the request
+ * - {method}:         Method of the request
+ * - {uri}:            URI of the request
+ * - {version}:        Protocol version
+ * - {target}:         Request target of the request (path + query + fragment)
+ * - {hostname}:       Hostname of the machine that sent the request
+ * - {code}:           Status code of the response (if available)
+ * - {phrase}:         Reason phrase of the response  (if available)
+ * - {error}:          Any error messages (if available)
+ * - {req_header_*}:   Replace `*` with the lowercased name of a request header to add to the message
+ * - {res_header_*}:   Replace `*` with the lowercased name of a response header to add to the message
+ * - {req_headers}:    Request headers
+ * - {res_headers}:    Response headers
+ * - {req_body}:       Request body
+ * - {res_body}:       Response body
+ *
+ * @final
+ */
+class MessageFormatter implements MessageFormatterInterface
+{
+    /**
+     * Apache Common Log Format.
+     *
+     * @see https://httpd.apache.org/docs/2.4/logs.html#common
+     *
+     * @var string
+     */
+    public const CLF = '{hostname} {req_header_User-Agent} - [{date_common_log}] "{method} {target} HTTP/{version}" {code} {res_header_Content-Length}';
+    public const DEBUG = ">>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}";
+    public const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}';
+
+    /**
+     * @var string Template used to format log messages
+     */
+    private $template;
+
+    /**
+     * @param string $template Log message template
+     */
+    public function __construct(?string $template = self::CLF)
+    {
+        $this->template = $template ?: self::CLF;
+    }
+
+    /**
+     * Returns a formatted message string.
+     *
+     * @param RequestInterface       $request  Request that was sent
+     * @param ResponseInterface|null $response Response that was received
+     * @param \Throwable|null        $error    Exception that was received
+     */
+    public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string
+    {
+        $cache = [];
+
+        /** @var string */
+        return \preg_replace_callback(
+            '/{\s*([A-Za-z_\-\.0-9]+)\s*}/',
+            function (array $matches) use ($request, $response, $error, &$cache) {
+                if (isset($cache[$matches[1]])) {
+                    return $cache[$matches[1]];
+                }
+
+                $result = '';
+                switch ($matches[1]) {
+                    case 'request':
+                        $result = Psr7\Message::toString($request);
+                        break;
+                    case 'response':
+                        $result = $response ? Psr7\Message::toString($response) : '';
+                        break;
+                    case 'req_headers':
+                        $result = \trim($request->getMethod()
+                                .' '.$request->getRequestTarget())
+                            .' HTTP/'.$request->getProtocolVersion()."\r\n"
+                            .$this->headers($request);
+                        break;
+                    case 'res_headers':
+                        $result = $response ?
+                            \sprintf(
+                                'HTTP/%s %d %s',
+                                $response->getProtocolVersion(),
+                                $response->getStatusCode(),
+                                $response->getReasonPhrase()
+                            )."\r\n".$this->headers($response)
+                            : 'NULL';
+                        break;
+                    case 'req_body':
+                        $result = $request->getBody()->__toString();
+                        break;
+                    case 'res_body':
+                        if (!$response instanceof ResponseInterface) {
+                            $result = 'NULL';
+                            break;
+                        }
+
+                        $body = $response->getBody();
+
+                        if (!$body->isSeekable()) {
+                            $result = 'RESPONSE_NOT_LOGGEABLE';
+                            break;
+                        }
+
+                        $result = $response->getBody()->__toString();
+                        break;
+                    case 'ts':
+                    case 'date_iso_8601':
+                        $result = \gmdate('c');
+                        break;
+                    case 'date_common_log':
+                        $result = \date('d/M/Y:H:i:s O');
+                        break;
+                    case 'method':
+                        $result = $request->getMethod();
+                        break;
+                    case 'version':
+                        $result = $request->getProtocolVersion();
+                        break;
+                    case 'uri':
+                    case 'url':
+                        $result = $request->getUri()->__toString();
+                        break;
+                    case 'target':
+                        $result = $request->getRequestTarget();
+                        break;
+                    case 'req_version':
+                        $result = $request->getProtocolVersion();
+                        break;
+                    case 'res_version':
+                        $result = $response
+                            ? $response->getProtocolVersion()
+                            : 'NULL';
+                        break;
+                    case 'host':
+                        $result = $request->getHeaderLine('Host');
+                        break;
+                    case 'hostname':
+                        $result = \gethostname();
+                        break;
+                    case 'code':
+                        $result = $response ? $response->getStatusCode() : 'NULL';
+                        break;
+                    case 'phrase':
+                        $result = $response ? $response->getReasonPhrase() : 'NULL';
+                        break;
+                    case 'error':
+                        $result = $error ? $error->getMessage() : 'NULL';
+                        break;
+                    default:
+                        // handle prefixed dynamic headers
+                        if (\strpos($matches[1], 'req_header_') === 0) {
+                            $result = $request->getHeaderLine(\substr($matches[1], 11));
+                        } elseif (\strpos($matches[1], 'res_header_') === 0) {
+                            $result = $response
+                                ? $response->getHeaderLine(\substr($matches[1], 11))
+                                : 'NULL';
+                        }
+                }
+
+                $cache[$matches[1]] = $result;
+
+                return $result;
+            },
+            $this->template
+        );
+    }
+
+    /**
+     * Get headers from message as string
+     */
+    private function headers(MessageInterface $message): string
+    {
+        $result = '';
+        foreach ($message->getHeaders() as $name => $values) {
+            $result .= $name.': '.\implode(', ', $values)."\r\n";
+        }
+
+        return \trim($result);
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,18 @@
+<?php
+
+namespace GuzzleHttp;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+interface MessageFormatterInterface
+{
+    /**
+     * Returns a formatted message string.
+     *
+     * @param RequestInterface       $request  Request that was sent
+     * @param ResponseInterface|null $response Response that was received
+     * @param \Throwable|null        $error    Exception that was received
+     */
+    public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string;
+}
Index: vendor/guzzlehttp/guzzle/src/Middleware.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Middleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Middleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,268 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Cookie\CookieJarInterface;
+use GuzzleHttp\Exception\RequestException;
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Log\LoggerInterface;
+
+/**
+ * Functions used to create and wrap handlers with handler middleware.
+ */
+final class Middleware
+{
+    /**
+     * Middleware that adds cookies to requests.
+     *
+     * The options array must be set to a CookieJarInterface in order to use
+     * cookies. This is typically handled for you by a client.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function cookies(): callable
+    {
+        return static function (callable $handler): callable {
+            return static function ($request, array $options) use ($handler) {
+                if (empty($options['cookies'])) {
+                    return $handler($request, $options);
+                } elseif (!($options['cookies'] instanceof CookieJarInterface)) {
+                    throw new \InvalidArgumentException('cookies must be an instance of GuzzleHttp\Cookie\CookieJarInterface');
+                }
+                $cookieJar = $options['cookies'];
+                $request = $cookieJar->withCookieHeader($request);
+
+                return $handler($request, $options)
+                    ->then(
+                        static function (ResponseInterface $response) use ($cookieJar, $request): ResponseInterface {
+                            $cookieJar->extractCookies($request, $response);
+
+                            return $response;
+                        }
+                    );
+            };
+        };
+    }
+
+    /**
+     * Middleware that throws exceptions for 4xx or 5xx responses when the
+     * "http_errors" request option is set to true.
+     *
+     * @param BodySummarizerInterface|null $bodySummarizer The body summarizer to use in exception messages.
+     *
+     * @return callable(callable): callable Returns a function that accepts the next handler.
+     */
+    public static function httpErrors(?BodySummarizerInterface $bodySummarizer = null): callable
+    {
+        return static function (callable $handler) use ($bodySummarizer): callable {
+            return static function ($request, array $options) use ($handler, $bodySummarizer) {
+                if (empty($options['http_errors'])) {
+                    return $handler($request, $options);
+                }
+
+                return $handler($request, $options)->then(
+                    static function (ResponseInterface $response) use ($request, $bodySummarizer) {
+                        $code = $response->getStatusCode();
+                        if ($code < 400) {
+                            return $response;
+                        }
+                        throw RequestException::create($request, $response, null, [], $bodySummarizer);
+                    }
+                );
+            };
+        };
+    }
+
+    /**
+     * Middleware that pushes history data to an ArrayAccess container.
+     *
+     * @param array|\ArrayAccess<int, array> $container Container to hold the history (by reference).
+     *
+     * @return callable(callable): callable Returns a function that accepts the next handler.
+     *
+     * @throws \InvalidArgumentException if container is not an array or ArrayAccess.
+     */
+    public static function history(&$container): callable
+    {
+        if (!\is_array($container) && !$container instanceof \ArrayAccess) {
+            throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess');
+        }
+
+        return static function (callable $handler) use (&$container): callable {
+            return static function (RequestInterface $request, array $options) use ($handler, &$container) {
+                return $handler($request, $options)->then(
+                    static function ($value) use ($request, &$container, $options) {
+                        $container[] = [
+                            'request' => $request,
+                            'response' => $value,
+                            'error' => null,
+                            'options' => $options,
+                        ];
+
+                        return $value;
+                    },
+                    static function ($reason) use ($request, &$container, $options) {
+                        $container[] = [
+                            'request' => $request,
+                            'response' => null,
+                            'error' => $reason,
+                            'options' => $options,
+                        ];
+
+                        return P\Create::rejectionFor($reason);
+                    }
+                );
+            };
+        };
+    }
+
+    /**
+     * Middleware that invokes a callback before and after sending a request.
+     *
+     * The provided listener cannot modify or alter the response. It simply
+     * "taps" into the chain to be notified before returning the promise. The
+     * before listener accepts a request and options array, and the after
+     * listener accepts a request, options array, and response promise.
+     *
+     * @param callable $before Function to invoke before forwarding the request.
+     * @param callable $after  Function invoked after forwarding.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function tap(?callable $before = null, ?callable $after = null): callable
+    {
+        return static function (callable $handler) use ($before, $after): callable {
+            return static function (RequestInterface $request, array $options) use ($handler, $before, $after) {
+                if ($before) {
+                    $before($request, $options);
+                }
+                $response = $handler($request, $options);
+                if ($after) {
+                    $after($request, $options, $response);
+                }
+
+                return $response;
+            };
+        };
+    }
+
+    /**
+     * Middleware that handles request redirects.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function redirect(): callable
+    {
+        return static function (callable $handler): RedirectMiddleware {
+            return new RedirectMiddleware($handler);
+        };
+    }
+
+    /**
+     * Middleware that retries requests based on the boolean result of
+     * invoking the provided "decider" function.
+     *
+     * If no delay function is provided, a simple implementation of exponential
+     * backoff will be utilized.
+     *
+     * @param callable $decider Function that accepts the number of retries,
+     *                          a request, [response], and [exception] and
+     *                          returns true if the request is to be retried.
+     * @param callable $delay   Function that accepts the number of retries and
+     *                          returns the number of milliseconds to delay.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function retry(callable $decider, ?callable $delay = null): callable
+    {
+        return static function (callable $handler) use ($decider, $delay): RetryMiddleware {
+            return new RetryMiddleware($decider, $handler, $delay);
+        };
+    }
+
+    /**
+     * Middleware that logs requests, responses, and errors using a message
+     * formatter.
+     *
+     * @phpstan-param \Psr\Log\LogLevel::* $logLevel  Level at which to log requests.
+     *
+     * @param LoggerInterface                            $logger    Logs messages.
+     * @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings.
+     * @param string                                     $logLevel  Level at which to log requests.
+     *
+     * @return callable Returns a function that accepts the next handler.
+     */
+    public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable
+    {
+        // To be compatible with Guzzle 7.1.x we need to allow users to pass a MessageFormatter
+        if (!$formatter instanceof MessageFormatter && !$formatter instanceof MessageFormatterInterface) {
+            throw new \LogicException(sprintf('Argument 2 to %s::log() must be of type %s', self::class, MessageFormatterInterface::class));
+        }
+
+        return static function (callable $handler) use ($logger, $formatter, $logLevel): callable {
+            return static function (RequestInterface $request, array $options = []) use ($handler, $logger, $formatter, $logLevel) {
+                return $handler($request, $options)->then(
+                    static function ($response) use ($logger, $request, $formatter, $logLevel): ResponseInterface {
+                        $message = $formatter->format($request, $response);
+                        $logger->log($logLevel, $message);
+
+                        return $response;
+                    },
+                    static function ($reason) use ($logger, $request, $formatter): PromiseInterface {
+                        $response = $reason instanceof RequestException ? $reason->getResponse() : null;
+                        $message = $formatter->format($request, $response, P\Create::exceptionFor($reason));
+                        $logger->error($message);
+
+                        return P\Create::rejectionFor($reason);
+                    }
+                );
+            };
+        };
+    }
+
+    /**
+     * This middleware adds a default content-type if possible, a default
+     * content-length or transfer-encoding header, and the expect header.
+     */
+    public static function prepareBody(): callable
+    {
+        return static function (callable $handler): PrepareBodyMiddleware {
+            return new PrepareBodyMiddleware($handler);
+        };
+    }
+
+    /**
+     * Middleware that applies a map function to the request before passing to
+     * the next handler.
+     *
+     * @param callable $fn Function that accepts a RequestInterface and returns
+     *                     a RequestInterface.
+     */
+    public static function mapRequest(callable $fn): callable
+    {
+        return static function (callable $handler) use ($fn): callable {
+            return static function (RequestInterface $request, array $options) use ($handler, $fn) {
+                return $handler($fn($request), $options);
+            };
+        };
+    }
+
+    /**
+     * Middleware that applies a map function to the resolved promise's
+     * response.
+     *
+     * @param callable $fn Function that accepts a ResponseInterface and
+     *                     returns a ResponseInterface.
+     */
+    public static function mapResponse(callable $fn): callable
+    {
+        return static function (callable $handler) use ($fn): callable {
+            return static function (RequestInterface $request, array $options) use ($handler, $fn) {
+                return $handler($request, $options)->then($fn);
+            };
+        };
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Pool.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Pool.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Pool.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,125 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\EachPromise;
+use GuzzleHttp\Promise\PromiseInterface;
+use GuzzleHttp\Promise\PromisorInterface;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Sends an iterator of requests concurrently using a capped pool size.
+ *
+ * The pool will read from an iterator until it is cancelled or until the
+ * iterator is consumed. When a request is yielded, the request is sent after
+ * applying the "request_options" request options (if provided in the ctor).
+ *
+ * When a function is yielded by the iterator, the function is provided the
+ * "request_options" array that should be merged on top of any existing
+ * options, and the function MUST then return a wait-able promise.
+ *
+ * @final
+ */
+class Pool implements PromisorInterface
+{
+    /**
+     * @var EachPromise
+     */
+    private $each;
+
+    /**
+     * @param ClientInterface $client   Client used to send the requests.
+     * @param array|\Iterator $requests Requests or functions that return
+     *                                  requests to send concurrently.
+     * @param array           $config   Associative array of options
+     *                                  - concurrency: (int) Maximum number of requests to send concurrently
+     *                                  - options: Array of request options to apply to each request.
+     *                                  - fulfilled: (callable) Function to invoke when a request completes.
+     *                                  - rejected: (callable) Function to invoke when a request is rejected.
+     */
+    public function __construct(ClientInterface $client, $requests, array $config = [])
+    {
+        if (!isset($config['concurrency'])) {
+            $config['concurrency'] = 25;
+        }
+
+        if (isset($config['options'])) {
+            $opts = $config['options'];
+            unset($config['options']);
+        } else {
+            $opts = [];
+        }
+
+        $iterable = P\Create::iterFor($requests);
+        $requests = static function () use ($iterable, $client, $opts) {
+            foreach ($iterable as $key => $rfn) {
+                if ($rfn instanceof RequestInterface) {
+                    yield $key => $client->sendAsync($rfn, $opts);
+                } elseif (\is_callable($rfn)) {
+                    yield $key => $rfn($opts);
+                } else {
+                    throw new \InvalidArgumentException('Each value yielded by the iterator must be a Psr7\Http\Message\RequestInterface or a callable that returns a promise that fulfills with a Psr7\Message\Http\ResponseInterface object.');
+                }
+            }
+        };
+
+        $this->each = new EachPromise($requests(), $config);
+    }
+
+    /**
+     * Get promise
+     */
+    public function promise(): PromiseInterface
+    {
+        return $this->each->promise();
+    }
+
+    /**
+     * Sends multiple requests concurrently and returns an array of responses
+     * and exceptions that uses the same ordering as the provided requests.
+     *
+     * IMPORTANT: This method keeps every request and response in memory, and
+     * as such, is NOT recommended when sending a large number or an
+     * indeterminate number of requests concurrently.
+     *
+     * @param ClientInterface $client   Client used to send the requests
+     * @param array|\Iterator $requests Requests to send concurrently.
+     * @param array           $options  Passes through the options available in
+     *                                  {@see \GuzzleHttp\Pool::__construct}
+     *
+     * @return array Returns an array containing the response or an exception
+     *               in the same order that the requests were sent.
+     *
+     * @throws \InvalidArgumentException if the event format is incorrect.
+     */
+    public static function batch(ClientInterface $client, $requests, array $options = []): array
+    {
+        $res = [];
+        self::cmpCallback($options, 'fulfilled', $res);
+        self::cmpCallback($options, 'rejected', $res);
+        $pool = new static($client, $requests, $options);
+        $pool->promise()->wait();
+        \ksort($res);
+
+        return $res;
+    }
+
+    /**
+     * Execute callback(s)
+     */
+    private static function cmpCallback(array &$options, string $name, array &$results): void
+    {
+        if (!isset($options[$name])) {
+            $options[$name] = static function ($v, $k) use (&$results) {
+                $results[$k] = $v;
+            };
+        } else {
+            $currentFn = $options[$name];
+            $options[$name] = static function ($v, $k) use (&$results, $currentFn) {
+                $currentFn($v, $k);
+                $results[$k] = $v;
+            };
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,105 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+
+/**
+ * Prepares requests that contain a body, adding the Content-Length,
+ * Content-Type, and Expect headers.
+ *
+ * @final
+ */
+class PrepareBodyMiddleware
+{
+    /**
+     * @var callable(RequestInterface, array): PromiseInterface
+     */
+    private $nextHandler;
+
+    /**
+     * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke.
+     */
+    public function __construct(callable $nextHandler)
+    {
+        $this->nextHandler = $nextHandler;
+    }
+
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        $fn = $this->nextHandler;
+
+        // Don't do anything if the request has no body.
+        if ($request->getBody()->getSize() === 0) {
+            return $fn($request, $options);
+        }
+
+        $modify = [];
+
+        // Add a default content-type if possible.
+        if (!$request->hasHeader('Content-Type')) {
+            if ($uri = $request->getBody()->getMetadata('uri')) {
+                if (is_string($uri) && $type = Psr7\MimeType::fromFilename($uri)) {
+                    $modify['set_headers']['Content-Type'] = $type;
+                }
+            }
+        }
+
+        // Add a default content-length or transfer-encoding header.
+        if (!$request->hasHeader('Content-Length')
+            && !$request->hasHeader('Transfer-Encoding')
+        ) {
+            $size = $request->getBody()->getSize();
+            if ($size !== null) {
+                $modify['set_headers']['Content-Length'] = $size;
+            } else {
+                $modify['set_headers']['Transfer-Encoding'] = 'chunked';
+            }
+        }
+
+        // Add the expect header if needed.
+        $this->addExpectHeader($request, $options, $modify);
+
+        return $fn(Psr7\Utils::modifyRequest($request, $modify), $options);
+    }
+
+    /**
+     * Add expect header
+     */
+    private function addExpectHeader(RequestInterface $request, array $options, array &$modify): void
+    {
+        // Determine if the Expect header should be used
+        if ($request->hasHeader('Expect')) {
+            return;
+        }
+
+        $expect = $options['expect'] ?? null;
+
+        // Return if disabled or using HTTP/1.0
+        if ($expect === false || $request->getProtocolVersion() === '1.0') {
+            return;
+        }
+
+        // The expect header is unconditionally enabled
+        if ($expect === true) {
+            $modify['set_headers']['Expect'] = '100-Continue';
+
+            return;
+        }
+
+        // By default, send the expect header when the payload is > 1mb
+        if ($expect === null) {
+            $expect = 1048576;
+        }
+
+        // Always add if the body cannot be rewound, the size cannot be
+        // determined, or the size is greater than the cutoff threshold
+        $body = $request->getBody();
+        $size = $body->getSize();
+
+        if ($size === null || $size >= (int) $expect || !$body->isSeekable()) {
+            $modify['set_headers']['Expect'] = '100-Continue';
+        }
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,228 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\BadResponseException;
+use GuzzleHttp\Exception\TooManyRedirectsException;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Request redirect middleware.
+ *
+ * Apply this middleware like other middleware using
+ * {@see \GuzzleHttp\Middleware::redirect()}.
+ *
+ * @final
+ */
+class RedirectMiddleware
+{
+    public const HISTORY_HEADER = 'X-Guzzle-Redirect-History';
+
+    public const STATUS_HISTORY_HEADER = 'X-Guzzle-Redirect-Status-History';
+
+    /**
+     * @var array
+     */
+    public static $defaultSettings = [
+        'max' => 5,
+        'protocols' => ['http', 'https'],
+        'strict' => false,
+        'referer' => false,
+        'track_redirects' => false,
+    ];
+
+    /**
+     * @var callable(RequestInterface, array): PromiseInterface
+     */
+    private $nextHandler;
+
+    /**
+     * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke.
+     */
+    public function __construct(callable $nextHandler)
+    {
+        $this->nextHandler = $nextHandler;
+    }
+
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        $fn = $this->nextHandler;
+
+        if (empty($options['allow_redirects'])) {
+            return $fn($request, $options);
+        }
+
+        if ($options['allow_redirects'] === true) {
+            $options['allow_redirects'] = self::$defaultSettings;
+        } elseif (!\is_array($options['allow_redirects'])) {
+            throw new \InvalidArgumentException('allow_redirects must be true, false, or array');
+        } else {
+            // Merge the default settings with the provided settings
+            $options['allow_redirects'] += self::$defaultSettings;
+        }
+
+        if (empty($options['allow_redirects']['max'])) {
+            return $fn($request, $options);
+        }
+
+        return $fn($request, $options)
+            ->then(function (ResponseInterface $response) use ($request, $options) {
+                return $this->checkRedirect($request, $options, $response);
+            });
+    }
+
+    /**
+     * @return ResponseInterface|PromiseInterface
+     */
+    public function checkRedirect(RequestInterface $request, array $options, ResponseInterface $response)
+    {
+        if (\strpos((string) $response->getStatusCode(), '3') !== 0
+            || !$response->hasHeader('Location')
+        ) {
+            return $response;
+        }
+
+        $this->guardMax($request, $response, $options);
+        $nextRequest = $this->modifyRequest($request, $options, $response);
+
+        // If authorization is handled by curl, unset it if URI is cross-origin.
+        if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $nextRequest->getUri()) && defined('\CURLOPT_HTTPAUTH')) {
+            unset(
+                $options['curl'][\CURLOPT_HTTPAUTH],
+                $options['curl'][\CURLOPT_USERPWD]
+            );
+        }
+
+        if (isset($options['allow_redirects']['on_redirect'])) {
+            ($options['allow_redirects']['on_redirect'])(
+                $request,
+                $response,
+                $nextRequest->getUri()
+            );
+        }
+
+        $promise = $this($nextRequest, $options);
+
+        // Add headers to be able to track history of redirects.
+        if (!empty($options['allow_redirects']['track_redirects'])) {
+            return $this->withTracking(
+                $promise,
+                (string) $nextRequest->getUri(),
+                $response->getStatusCode()
+            );
+        }
+
+        return $promise;
+    }
+
+    /**
+     * Enable tracking on promise.
+     */
+    private function withTracking(PromiseInterface $promise, string $uri, int $statusCode): PromiseInterface
+    {
+        return $promise->then(
+            static function (ResponseInterface $response) use ($uri, $statusCode) {
+                // Note that we are pushing to the front of the list as this
+                // would be an earlier response than what is currently present
+                // in the history header.
+                $historyHeader = $response->getHeader(self::HISTORY_HEADER);
+                $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER);
+                \array_unshift($historyHeader, $uri);
+                \array_unshift($statusHeader, (string) $statusCode);
+
+                return $response->withHeader(self::HISTORY_HEADER, $historyHeader)
+                                ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader);
+            }
+        );
+    }
+
+    /**
+     * Check for too many redirects.
+     *
+     * @throws TooManyRedirectsException Too many redirects.
+     */
+    private function guardMax(RequestInterface $request, ResponseInterface $response, array &$options): void
+    {
+        $current = $options['__redirect_count']
+            ?? 0;
+        $options['__redirect_count'] = $current + 1;
+        $max = $options['allow_redirects']['max'];
+
+        if ($options['__redirect_count'] > $max) {
+            throw new TooManyRedirectsException("Will not follow more than {$max} redirects", $request, $response);
+        }
+    }
+
+    public function modifyRequest(RequestInterface $request, array $options, ResponseInterface $response): RequestInterface
+    {
+        // Request modifications to apply.
+        $modify = [];
+        $protocols = $options['allow_redirects']['protocols'];
+
+        // Use a GET request if this is an entity enclosing request and we are
+        // not forcing RFC compliance, but rather emulating what all browsers
+        // would do.
+        $statusCode = $response->getStatusCode();
+        if ($statusCode == 303
+            || ($statusCode <= 302 && !$options['allow_redirects']['strict'])
+        ) {
+            $safeMethods = ['GET', 'HEAD', 'OPTIONS'];
+            $requestMethod = $request->getMethod();
+
+            $modify['method'] = in_array($requestMethod, $safeMethods) ? $requestMethod : 'GET';
+            $modify['body'] = '';
+        }
+
+        $uri = self::redirectUri($request, $response, $protocols);
+        if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) {
+            $idnOptions = ($options['idn_conversion'] === true) ? \IDNA_DEFAULT : $options['idn_conversion'];
+            $uri = Utils::idnUriConvert($uri, $idnOptions);
+        }
+
+        $modify['uri'] = $uri;
+        Psr7\Message::rewindBody($request);
+
+        // Add the Referer header if it is told to do so and only
+        // add the header if we are not redirecting from https to http.
+        if ($options['allow_redirects']['referer']
+            && $modify['uri']->getScheme() === $request->getUri()->getScheme()
+        ) {
+            $uri = $request->getUri()->withUserInfo('');
+            $modify['set_headers']['Referer'] = (string) $uri;
+        } else {
+            $modify['remove_headers'][] = 'Referer';
+        }
+
+        // Remove Authorization and Cookie headers if URI is cross-origin.
+        if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $modify['uri'])) {
+            $modify['remove_headers'][] = 'Authorization';
+            $modify['remove_headers'][] = 'Cookie';
+        }
+
+        return Psr7\Utils::modifyRequest($request, $modify);
+    }
+
+    /**
+     * Set the appropriate URL on the request based on the location header.
+     */
+    private static function redirectUri(
+        RequestInterface $request,
+        ResponseInterface $response,
+        array $protocols
+    ): UriInterface {
+        $location = Psr7\UriResolver::resolve(
+            $request->getUri(),
+            new Psr7\Uri($response->getHeaderLine('Location'))
+        );
+
+        // Ensure that the redirect URI is allowed based on the protocols.
+        if (!\in_array($location->getScheme(), $protocols)) {
+            throw new BadResponseException(\sprintf('Redirect URI, %s, does not use one of the allowed redirect protocols: %s', $location, \implode(', ', $protocols)), $request, $response);
+        }
+
+        return $location;
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/RequestOptions.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/RequestOptions.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/RequestOptions.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,274 @@
+<?php
+
+namespace GuzzleHttp;
+
+/**
+ * This class contains a list of built-in Guzzle request options.
+ *
+ * @see https://docs.guzzlephp.org/en/latest/request-options.html
+ */
+final class RequestOptions
+{
+    /**
+     * allow_redirects: (bool|array) Controls redirect behavior. Pass false
+     * to disable redirects, pass true to enable redirects, pass an
+     * associative to provide custom redirect settings. Defaults to "false".
+     * This option only works if your handler has the RedirectMiddleware. When
+     * passing an associative array, you can provide the following key value
+     * pairs:
+     *
+     * - max: (int, default=5) maximum number of allowed redirects.
+     * - strict: (bool, default=false) Set to true to use strict redirects
+     *   meaning redirect POST requests with POST requests vs. doing what most
+     *   browsers do which is redirect POST requests with GET requests
+     * - referer: (bool, default=false) Set to true to enable the Referer
+     *   header.
+     * - protocols: (array, default=['http', 'https']) Allowed redirect
+     *   protocols.
+     * - on_redirect: (callable) PHP callable that is invoked when a redirect
+     *   is encountered. The callable is invoked with the request, the redirect
+     *   response that was received, and the effective URI. Any return value
+     *   from the on_redirect function is ignored.
+     */
+    public const ALLOW_REDIRECTS = 'allow_redirects';
+
+    /**
+     * auth: (array) Pass an array of HTTP authentication parameters to use
+     * with the request. The array must contain the username in index [0],
+     * the password in index [1], and you can optionally provide a built-in
+     * authentication type in index [2]. Pass null to disable authentication
+     * for a request.
+     */
+    public const AUTH = 'auth';
+
+    /**
+     * body: (resource|string|null|int|float|StreamInterface|callable|\Iterator)
+     * Body to send in the request.
+     */
+    public const BODY = 'body';
+
+    /**
+     * cert: (string|array) Set to a string to specify the path to a file
+     * containing a PEM formatted SSL client side certificate. If a password
+     * is required, then set cert to an array containing the path to the PEM
+     * file in the first array element followed by the certificate password
+     * in the second array element.
+     */
+    public const CERT = 'cert';
+
+    /**
+     * cookies: (bool|GuzzleHttp\Cookie\CookieJarInterface, default=false)
+     * Specifies whether or not cookies are used in a request or what cookie
+     * jar to use or what cookies to send. This option only works if your
+     * handler has the `cookie` middleware. Valid values are `false` and
+     * an instance of {@see Cookie\CookieJarInterface}.
+     */
+    public const COOKIES = 'cookies';
+
+    /**
+     * connect_timeout: (float, default=0) Float describing the number of
+     * seconds to wait while trying to connect to a server. Use 0 to wait
+     * 300 seconds (the default behavior).
+     */
+    public const CONNECT_TIMEOUT = 'connect_timeout';
+
+    /**
+     * crypto_method: (int) A value describing the minimum TLS protocol
+     * version to use.
+     *
+     * This setting must be set to one of the
+     * ``STREAM_CRYPTO_METHOD_TLS*_CLIENT`` constants. PHP 7.4 or higher is
+     * required in order to use TLS 1.3, and cURL 7.34.0 or higher is required
+     * in order to specify a crypto method, with cURL 7.52.0 or higher being
+     * required to use TLS 1.3.
+     */
+    public const CRYPTO_METHOD = 'crypto_method';
+
+    /**
+     * debug: (bool|resource) Set to true or set to a PHP stream returned by
+     * fopen()  enable debug output with the HTTP handler used to send a
+     * request.
+     */
+    public const DEBUG = 'debug';
+
+    /**
+     * decode_content: (bool, default=true) Specify whether or not
+     * Content-Encoding responses (gzip, deflate, etc.) are automatically
+     * decoded.
+     */
+    public const DECODE_CONTENT = 'decode_content';
+
+    /**
+     * delay: (int) The amount of time to delay before sending in milliseconds.
+     */
+    public const DELAY = 'delay';
+
+    /**
+     * expect: (bool|integer) Controls the behavior of the
+     * "Expect: 100-Continue" header.
+     *
+     * Set to `true` to enable the "Expect: 100-Continue" header for all
+     * requests that sends a body. Set to `false` to disable the
+     * "Expect: 100-Continue" header for all requests. Set to a number so that
+     * the size of the payload must be greater than the number in order to send
+     * the Expect header. Setting to a number will send the Expect header for
+     * all requests in which the size of the payload cannot be determined or
+     * where the body is not rewindable.
+     *
+     * By default, Guzzle will add the "Expect: 100-Continue" header when the
+     * size of the body of a request is greater than 1 MB and a request is
+     * using HTTP/1.1.
+     */
+    public const EXPECT = 'expect';
+
+    /**
+     * form_params: (array) Associative array of form field names to values
+     * where each value is a string or array of strings. Sets the Content-Type
+     * header to application/x-www-form-urlencoded when no Content-Type header
+     * is already present.
+     */
+    public const FORM_PARAMS = 'form_params';
+
+    /**
+     * headers: (array) Associative array of HTTP headers. Each value MUST be
+     * a string or array of strings.
+     */
+    public const HEADERS = 'headers';
+
+    /**
+     * http_errors: (bool, default=true) Set to false to disable exceptions
+     * when a non- successful HTTP response is received. By default,
+     * exceptions will be thrown for 4xx and 5xx responses. This option only
+     * works if your handler has the `httpErrors` middleware.
+     */
+    public const HTTP_ERRORS = 'http_errors';
+
+    /**
+     * idn: (bool|int, default=true) A combination of IDNA_* constants for
+     * idn_to_ascii() PHP's function (see "options" parameter). Set to false to
+     * disable IDN support completely, or to true to use the default
+     * configuration (IDNA_DEFAULT constant).
+     */
+    public const IDN_CONVERSION = 'idn_conversion';
+
+    /**
+     * json: (mixed) Adds JSON data to a request. The provided value is JSON
+     * encoded and a Content-Type header of application/json will be added to
+     * the request if no Content-Type header is already present.
+     */
+    public const JSON = 'json';
+
+    /**
+     * multipart: (array) Array of associative arrays, each containing a
+     * required "name" key mapping to the form field, name, a required
+     * "contents" key mapping to a StreamInterface|resource|string, an
+     * optional "headers" associative array of custom headers, and an
+     * optional "filename" key mapping to a string to send as the filename in
+     * the part. If no "filename" key is present, then no "filename" attribute
+     * will be added to the part.
+     */
+    public const MULTIPART = 'multipart';
+
+    /**
+     * on_headers: (callable) A callable that is invoked when the HTTP headers
+     * of the response have been received but the body has not yet begun to
+     * download.
+     */
+    public const ON_HEADERS = 'on_headers';
+
+    /**
+     * on_stats: (callable) allows you to get access to transfer statistics of
+     * a request and access the lower level transfer details of the handler
+     * associated with your client. ``on_stats`` is a callable that is invoked
+     * when a handler has finished sending a request. The callback is invoked
+     * with transfer statistics about the request, the response received, or
+     * the error encountered. Included in the data is the total amount of time
+     * taken to send the request.
+     */
+    public const ON_STATS = 'on_stats';
+
+    /**
+     * progress: (callable) Defines a function to invoke when transfer
+     * progress is made. The function accepts the following positional
+     * arguments: the total number of bytes expected to be downloaded, the
+     * number of bytes downloaded so far, the number of bytes expected to be
+     * uploaded, the number of bytes uploaded so far.
+     */
+    public const PROGRESS = 'progress';
+
+    /**
+     * proxy: (string|array) Pass a string to specify an HTTP proxy, or an
+     * array to specify different proxies for different protocols (where the
+     * key is the protocol and the value is a proxy string).
+     */
+    public const PROXY = 'proxy';
+
+    /**
+     * query: (array|string) Associative array of query string values to add
+     * to the request. This option uses PHP's http_build_query() to create
+     * the string representation. Pass a string value if you need more
+     * control than what this method provides
+     */
+    public const QUERY = 'query';
+
+    /**
+     * sink: (resource|string|StreamInterface) Where the data of the
+     * response is written to. Defaults to a PHP temp stream. Providing a
+     * string will write data to a file by the given name.
+     */
+    public const SINK = 'sink';
+
+    /**
+     * synchronous: (bool) Set to true to inform HTTP handlers that you intend
+     * on waiting on the response. This can be useful for optimizations. Note
+     * that a promise is still returned if you are using one of the async
+     * client methods.
+     */
+    public const SYNCHRONOUS = 'synchronous';
+
+    /**
+     * ssl_key: (array|string) Specify the path to a file containing a private
+     * SSL key in PEM format. If a password is required, then set to an array
+     * containing the path to the SSL key in the first array element followed
+     * by the password required for the certificate in the second element.
+     */
+    public const SSL_KEY = 'ssl_key';
+
+    /**
+     * stream: Set to true to attempt to stream a response rather than
+     * download it all up-front.
+     */
+    public const STREAM = 'stream';
+
+    /**
+     * verify: (bool|string, default=true) Describes the SSL certificate
+     * verification behavior of a request. Set to true to enable SSL
+     * certificate verification using the system CA bundle when available
+     * (the default). Set to false to disable certificate verification (this
+     * is insecure!). Set to a string to provide the path to a CA bundle on
+     * disk to enable verification using a custom certificate.
+     */
+    public const VERIFY = 'verify';
+
+    /**
+     * timeout: (float, default=0) Float describing the timeout of the
+     * request in seconds. Use 0 to wait indefinitely (the default behavior).
+     */
+    public const TIMEOUT = 'timeout';
+
+    /**
+     * read_timeout: (float, default=default_socket_timeout ini setting) Float describing
+     * the body read timeout, for stream requests.
+     */
+    public const READ_TIMEOUT = 'read_timeout';
+
+    /**
+     * version: (float) Specifies the HTTP protocol version to attempt to use.
+     */
+    public const VERSION = 'version';
+
+    /**
+     * force_ip_resolve: (bool) Force client to use only ipv4 or ipv6 protocol
+     */
+    public const FORCE_IP_RESOLVE = 'force_ip_resolve';
+}
Index: vendor/guzzlehttp/guzzle/src/RetryMiddleware.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/RetryMiddleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/RetryMiddleware.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,119 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Promise as P;
+use GuzzleHttp\Promise\PromiseInterface;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Middleware that retries requests based on the boolean result of
+ * invoking the provided "decider" function.
+ *
+ * @final
+ */
+class RetryMiddleware
+{
+    /**
+     * @var callable(RequestInterface, array): PromiseInterface
+     */
+    private $nextHandler;
+
+    /**
+     * @var callable
+     */
+    private $decider;
+
+    /**
+     * @var callable(int)
+     */
+    private $delay;
+
+    /**
+     * @param callable                                            $decider     Function that accepts the number of retries,
+     *                                                                         a request, [response], and [exception] and
+     *                                                                         returns true if the request is to be
+     *                                                                         retried.
+     * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke.
+     * @param (callable(int): int)|null                           $delay       Function that accepts the number of retries
+     *                                                                         and returns the number of
+     *                                                                         milliseconds to delay.
+     */
+    public function __construct(callable $decider, callable $nextHandler, ?callable $delay = null)
+    {
+        $this->decider = $decider;
+        $this->nextHandler = $nextHandler;
+        $this->delay = $delay ?: __CLASS__.'::exponentialDelay';
+    }
+
+    /**
+     * Default exponential backoff delay function.
+     *
+     * @return int milliseconds.
+     */
+    public static function exponentialDelay(int $retries): int
+    {
+        return (int) 2 ** ($retries - 1) * 1000;
+    }
+
+    public function __invoke(RequestInterface $request, array $options): PromiseInterface
+    {
+        if (!isset($options['retries'])) {
+            $options['retries'] = 0;
+        }
+
+        $fn = $this->nextHandler;
+
+        return $fn($request, $options)
+            ->then(
+                $this->onFulfilled($request, $options),
+                $this->onRejected($request, $options)
+            );
+    }
+
+    /**
+     * Execute fulfilled closure
+     */
+    private function onFulfilled(RequestInterface $request, array $options): callable
+    {
+        return function ($value) use ($request, $options) {
+            if (!($this->decider)(
+                $options['retries'],
+                $request,
+                $value,
+                null
+            )) {
+                return $value;
+            }
+
+            return $this->doRetry($request, $options, $value);
+        };
+    }
+
+    /**
+     * Execute rejected closure
+     */
+    private function onRejected(RequestInterface $req, array $options): callable
+    {
+        return function ($reason) use ($req, $options) {
+            if (!($this->decider)(
+                $options['retries'],
+                $req,
+                null,
+                $reason
+            )) {
+                return P\Create::rejectionFor($reason);
+            }
+
+            return $this->doRetry($req, $options);
+        };
+    }
+
+    private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null): PromiseInterface
+    {
+        $options['delay'] = ($this->delay)(++$options['retries'], $response, $request);
+
+        return $this($request, $options);
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/TransferStats.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/TransferStats.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/TransferStats.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,133 @@
+<?php
+
+namespace GuzzleHttp;
+
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\UriInterface;
+
+/**
+ * Represents data at the point after it was transferred either successfully
+ * or after a network error.
+ */
+final class TransferStats
+{
+    /**
+     * @var RequestInterface
+     */
+    private $request;
+
+    /**
+     * @var ResponseInterface|null
+     */
+    private $response;
+
+    /**
+     * @var float|null
+     */
+    private $transferTime;
+
+    /**
+     * @var array
+     */
+    private $handlerStats;
+
+    /**
+     * @var mixed|null
+     */
+    private $handlerErrorData;
+
+    /**
+     * @param RequestInterface       $request          Request that was sent.
+     * @param ResponseInterface|null $response         Response received (if any)
+     * @param float|null             $transferTime     Total handler transfer time.
+     * @param mixed                  $handlerErrorData Handler error data.
+     * @param array                  $handlerStats     Handler specific stats.
+     */
+    public function __construct(
+        RequestInterface $request,
+        ?ResponseInterface $response = null,
+        ?float $transferTime = null,
+        $handlerErrorData = null,
+        array $handlerStats = []
+    ) {
+        $this->request = $request;
+        $this->response = $response;
+        $this->transferTime = $transferTime;
+        $this->handlerErrorData = $handlerErrorData;
+        $this->handlerStats = $handlerStats;
+    }
+
+    public function getRequest(): RequestInterface
+    {
+        return $this->request;
+    }
+
+    /**
+     * Returns the response that was received (if any).
+     */
+    public function getResponse(): ?ResponseInterface
+    {
+        return $this->response;
+    }
+
+    /**
+     * Returns true if a response was received.
+     */
+    public function hasResponse(): bool
+    {
+        return $this->response !== null;
+    }
+
+    /**
+     * Gets handler specific error data.
+     *
+     * This might be an exception, a integer representing an error code, or
+     * anything else. Relying on this value assumes that you know what handler
+     * you are using.
+     *
+     * @return mixed
+     */
+    public function getHandlerErrorData()
+    {
+        return $this->handlerErrorData;
+    }
+
+    /**
+     * Get the effective URI the request was sent to.
+     */
+    public function getEffectiveUri(): UriInterface
+    {
+        return $this->request->getUri();
+    }
+
+    /**
+     * Get the estimated time the request was being transferred by the handler.
+     *
+     * @return float|null Time in seconds.
+     */
+    public function getTransferTime(): ?float
+    {
+        return $this->transferTime;
+    }
+
+    /**
+     * Gets an array of all of the handler specific transfer data.
+     */
+    public function getHandlerStats(): array
+    {
+        return $this->handlerStats;
+    }
+
+    /**
+     * Get a specific handler statistic from the handler by name.
+     *
+     * @param string $stat Handler specific transfer stat to retrieve.
+     *
+     * @return mixed|null
+     */
+    public function getHandlerStat(string $stat)
+    {
+        return $this->handlerStats[$stat] ?? null;
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/Utils.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/Utils.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/Utils.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,384 @@
+<?php
+
+namespace GuzzleHttp;
+
+use GuzzleHttp\Exception\InvalidArgumentException;
+use GuzzleHttp\Handler\CurlHandler;
+use GuzzleHttp\Handler\CurlMultiHandler;
+use GuzzleHttp\Handler\Proxy;
+use GuzzleHttp\Handler\StreamHandler;
+use Psr\Http\Message\UriInterface;
+
+final class Utils
+{
+    /**
+     * Debug function used to describe the provided value type and class.
+     *
+     * @param mixed $input
+     *
+     * @return string Returns a string containing the type of the variable and
+     *                if a class is provided, the class name.
+     */
+    public static function describeType($input): string
+    {
+        switch (\gettype($input)) {
+            case 'object':
+                return 'object('.\get_class($input).')';
+            case 'array':
+                return 'array('.\count($input).')';
+            default:
+                \ob_start();
+                \var_dump($input);
+                // normalize float vs double
+                /** @var string $varDumpContent */
+                $varDumpContent = \ob_get_clean();
+
+                return \str_replace('double(', 'float(', \rtrim($varDumpContent));
+        }
+    }
+
+    /**
+     * Parses an array of header lines into an associative array of headers.
+     *
+     * @param iterable $lines Header lines array of strings in the following
+     *                        format: "Name: Value"
+     */
+    public static function headersFromLines(iterable $lines): array
+    {
+        $headers = [];
+
+        foreach ($lines as $line) {
+            $parts = \explode(':', $line, 2);
+            $headers[\trim($parts[0])][] = isset($parts[1]) ? \trim($parts[1]) : null;
+        }
+
+        return $headers;
+    }
+
+    /**
+     * Returns a debug stream based on the provided variable.
+     *
+     * @param mixed $value Optional value
+     *
+     * @return resource
+     */
+    public static function debugResource($value = null)
+    {
+        if (\is_resource($value)) {
+            return $value;
+        }
+        if (\defined('STDOUT')) {
+            return \STDOUT;
+        }
+
+        return Psr7\Utils::tryFopen('php://output', 'w');
+    }
+
+    /**
+     * Chooses and creates a default handler to use based on the environment.
+     *
+     * The returned handler is not wrapped by any default middlewares.
+     *
+     * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
+     *
+     * @throws \RuntimeException if no viable Handler is available.
+     */
+    public static function chooseHandler(): callable
+    {
+        $handler = null;
+
+        if (\defined('CURLOPT_CUSTOMREQUEST') && \function_exists('curl_version') && version_compare(curl_version()['version'], '7.21.2') >= 0) {
+            if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) {
+                $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
+            } elseif (\function_exists('curl_exec')) {
+                $handler = new CurlHandler();
+            } elseif (\function_exists('curl_multi_exec')) {
+                $handler = new CurlMultiHandler();
+            }
+        }
+
+        if (\ini_get('allow_url_fopen')) {
+            $handler = $handler
+                ? Proxy::wrapStreaming($handler, new StreamHandler())
+                : new StreamHandler();
+        } elseif (!$handler) {
+            throw new \RuntimeException('GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.');
+        }
+
+        return $handler;
+    }
+
+    /**
+     * Get the default User-Agent string to use with Guzzle.
+     */
+    public static function defaultUserAgent(): string
+    {
+        return sprintf('GuzzleHttp/%d', ClientInterface::MAJOR_VERSION);
+    }
+
+    /**
+     * Returns the default cacert bundle for the current system.
+     *
+     * First, the openssl.cafile and curl.cainfo php.ini settings are checked.
+     * If those settings are not configured, then the common locations for
+     * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X
+     * and Windows are checked. If any of these file locations are found on
+     * disk, they will be utilized.
+     *
+     * Note: the result of this function is cached for subsequent calls.
+     *
+     * @throws \RuntimeException if no bundle can be found.
+     *
+     * @deprecated Utils::defaultCaBundle will be removed in guzzlehttp/guzzle:8.0. This method is not needed in PHP 5.6+.
+     */
+    public static function defaultCaBundle(): string
+    {
+        static $cached = null;
+        static $cafiles = [
+            // Red Hat, CentOS, Fedora (provided by the ca-certificates package)
+            '/etc/pki/tls/certs/ca-bundle.crt',
+            // Ubuntu, Debian (provided by the ca-certificates package)
+            '/etc/ssl/certs/ca-certificates.crt',
+            // FreeBSD (provided by the ca_root_nss package)
+            '/usr/local/share/certs/ca-root-nss.crt',
+            // SLES 12 (provided by the ca-certificates package)
+            '/var/lib/ca-certificates/ca-bundle.pem',
+            // OS X provided by homebrew (using the default path)
+            '/usr/local/etc/openssl/cert.pem',
+            // Google app engine
+            '/etc/ca-certificates.crt',
+            // Windows?
+            'C:\\windows\\system32\\curl-ca-bundle.crt',
+            'C:\\windows\\curl-ca-bundle.crt',
+        ];
+
+        if ($cached) {
+            return $cached;
+        }
+
+        if ($ca = \ini_get('openssl.cafile')) {
+            return $cached = $ca;
+        }
+
+        if ($ca = \ini_get('curl.cainfo')) {
+            return $cached = $ca;
+        }
+
+        foreach ($cafiles as $filename) {
+            if (\file_exists($filename)) {
+                return $cached = $filename;
+            }
+        }
+
+        throw new \RuntimeException(
+            <<< EOT
+No system CA bundle could be found in any of the the common system locations.
+PHP versions earlier than 5.6 are not properly configured to use the system's
+CA bundle by default. In order to verify peer certificates, you will need to
+supply the path on disk to a certificate bundle to the 'verify' request
+option: https://docs.guzzlephp.org/en/latest/request-options.html#verify. If
+you do not need a specific certificate bundle, then Mozilla provides a commonly
+used CA bundle which can be downloaded here (provided by the maintainer of
+cURL): https://curl.haxx.se/ca/cacert.pem. Once you have a CA bundle available
+on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path
+to the file, allowing you to omit the 'verify' request option. See
+https://curl.haxx.se/docs/sslcerts.html for more information.
+EOT
+        );
+    }
+
+    /**
+     * Creates an associative array of lowercase header names to the actual
+     * header casing.
+     */
+    public static function normalizeHeaderKeys(array $headers): array
+    {
+        $result = [];
+        foreach (\array_keys($headers) as $key) {
+            $result[\strtolower($key)] = $key;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns true if the provided host matches any of the no proxy areas.
+     *
+     * This method will strip a port from the host if it is present. Each pattern
+     * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a
+     * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" ==
+     * "baz.foo.com", but ".foo.com" != "foo.com").
+     *
+     * Areas are matched in the following cases:
+     * 1. "*" (without quotes) always matches any hosts.
+     * 2. An exact match.
+     * 3. The area starts with "." and the area is the last part of the host. e.g.
+     *    '.mit.edu' will match any host that ends with '.mit.edu'.
+     *
+     * @param string   $host         Host to check against the patterns.
+     * @param string[] $noProxyArray An array of host patterns.
+     *
+     * @throws InvalidArgumentException
+     */
+    public static function isHostInNoProxy(string $host, array $noProxyArray): bool
+    {
+        if (\strlen($host) === 0) {
+            throw new InvalidArgumentException('Empty host provided');
+        }
+
+        // Strip port if present.
+        [$host] = \explode(':', $host, 2);
+
+        foreach ($noProxyArray as $area) {
+            // Always match on wildcards.
+            if ($area === '*') {
+                return true;
+            }
+
+            if (empty($area)) {
+                // Don't match on empty values.
+                continue;
+            }
+
+            if ($area === $host) {
+                // Exact matches.
+                return true;
+            }
+            // Special match if the area when prefixed with ".". Remove any
+            // existing leading "." and add a new leading ".".
+            $area = '.'.\ltrim($area, '.');
+            if (\substr($host, -\strlen($area)) === $area) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Wrapper for json_decode that throws when an error occurs.
+     *
+     * @param string $json    JSON data to parse
+     * @param bool   $assoc   When true, returned objects will be converted
+     *                        into associative arrays.
+     * @param int    $depth   User specified recursion depth.
+     * @param int    $options Bitmask of JSON decode options.
+     *
+     * @return object|array|string|int|float|bool|null
+     *
+     * @throws InvalidArgumentException if the JSON cannot be decoded.
+     *
+     * @see https://www.php.net/manual/en/function.json-decode.php
+     */
+    public static function jsonDecode(string $json, bool $assoc = false, int $depth = 512, int $options = 0)
+    {
+        $data = \json_decode($json, $assoc, $depth, $options);
+        if (\JSON_ERROR_NONE !== \json_last_error()) {
+            throw new InvalidArgumentException('json_decode error: '.\json_last_error_msg());
+        }
+
+        return $data;
+    }
+
+    /**
+     * Wrapper for JSON encoding that throws when an error occurs.
+     *
+     * @param mixed $value   The value being encoded
+     * @param int   $options JSON encode option bitmask
+     * @param int   $depth   Set the maximum depth. Must be greater than zero.
+     *
+     * @throws InvalidArgumentException if the JSON cannot be encoded.
+     *
+     * @see https://www.php.net/manual/en/function.json-encode.php
+     */
+    public static function jsonEncode($value, int $options = 0, int $depth = 512): string
+    {
+        $json = \json_encode($value, $options, $depth);
+        if (\JSON_ERROR_NONE !== \json_last_error()) {
+            throw new InvalidArgumentException('json_encode error: '.\json_last_error_msg());
+        }
+
+        /** @var string */
+        return $json;
+    }
+
+    /**
+     * Wrapper for the hrtime() or microtime() functions
+     * (depending on the PHP version, one of the two is used)
+     *
+     * @return float UNIX timestamp
+     *
+     * @internal
+     */
+    public static function currentTime(): float
+    {
+        return (float) \function_exists('hrtime') ? \hrtime(true) / 1e9 : \microtime(true);
+    }
+
+    /**
+     * @throws InvalidArgumentException
+     *
+     * @internal
+     */
+    public static function idnUriConvert(UriInterface $uri, int $options = 0): UriInterface
+    {
+        if ($uri->getHost()) {
+            $asciiHost = self::idnToAsci($uri->getHost(), $options, $info);
+            if ($asciiHost === false) {
+                $errorBitSet = $info['errors'] ?? 0;
+
+                $errorConstants = array_filter(array_keys(get_defined_constants()), static function (string $name): bool {
+                    return substr($name, 0, 11) === 'IDNA_ERROR_';
+                });
+
+                $errors = [];
+                foreach ($errorConstants as $errorConstant) {
+                    if ($errorBitSet & constant($errorConstant)) {
+                        $errors[] = $errorConstant;
+                    }
+                }
+
+                $errorMessage = 'IDN conversion failed';
+                if ($errors) {
+                    $errorMessage .= ' (errors: '.implode(', ', $errors).')';
+                }
+
+                throw new InvalidArgumentException($errorMessage);
+            }
+            if ($uri->getHost() !== $asciiHost) {
+                // Replace URI only if the ASCII version is different
+                $uri = $uri->withHost($asciiHost);
+            }
+        }
+
+        return $uri;
+    }
+
+    /**
+     * @internal
+     */
+    public static function getenv(string $name): ?string
+    {
+        if (isset($_SERVER[$name])) {
+            return (string) $_SERVER[$name];
+        }
+
+        if (\PHP_SAPI === 'cli' && ($value = \getenv($name)) !== false && $value !== null) {
+            return (string) $value;
+        }
+
+        return null;
+    }
+
+    /**
+     * @return string|false
+     */
+    private static function idnToAsci(string $domain, int $options, ?array &$info = [])
+    {
+        if (\function_exists('idn_to_ascii') && \defined('INTL_IDNA_VARIANT_UTS46')) {
+            return \idn_to_ascii($domain, $options, \INTL_IDNA_VARIANT_UTS46, $info);
+        }
+
+        throw new \Error('ext-idn or symfony/polyfill-intl-idn not loaded or too old');
+    }
+}
Index: vendor/guzzlehttp/guzzle/src/functions.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/functions.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/functions.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,167 @@
+<?php
+
+namespace GuzzleHttp;
+
+/**
+ * Debug function used to describe the provided value type and class.
+ *
+ * @param mixed $input Any type of variable to describe the type of. This
+ *                     parameter misses a typehint because of that.
+ *
+ * @return string Returns a string containing the type of the variable and
+ *                if a class is provided, the class name.
+ *
+ * @deprecated describe_type will be removed in guzzlehttp/guzzle:8.0. Use Utils::describeType instead.
+ */
+function describe_type($input): string
+{
+    return Utils::describeType($input);
+}
+
+/**
+ * Parses an array of header lines into an associative array of headers.
+ *
+ * @param iterable $lines Header lines array of strings in the following
+ *                        format: "Name: Value"
+ *
+ * @deprecated headers_from_lines will be removed in guzzlehttp/guzzle:8.0. Use Utils::headersFromLines instead.
+ */
+function headers_from_lines(iterable $lines): array
+{
+    return Utils::headersFromLines($lines);
+}
+
+/**
+ * Returns a debug stream based on the provided variable.
+ *
+ * @param mixed $value Optional value
+ *
+ * @return resource
+ *
+ * @deprecated debug_resource will be removed in guzzlehttp/guzzle:8.0. Use Utils::debugResource instead.
+ */
+function debug_resource($value = null)
+{
+    return Utils::debugResource($value);
+}
+
+/**
+ * Chooses and creates a default handler to use based on the environment.
+ *
+ * The returned handler is not wrapped by any default middlewares.
+ *
+ * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system.
+ *
+ * @throws \RuntimeException if no viable Handler is available.
+ *
+ * @deprecated choose_handler will be removed in guzzlehttp/guzzle:8.0. Use Utils::chooseHandler instead.
+ */
+function choose_handler(): callable
+{
+    return Utils::chooseHandler();
+}
+
+/**
+ * Get the default User-Agent string to use with Guzzle.
+ *
+ * @deprecated default_user_agent will be removed in guzzlehttp/guzzle:8.0. Use Utils::defaultUserAgent instead.
+ */
+function default_user_agent(): string
+{
+    return Utils::defaultUserAgent();
+}
+
+/**
+ * Returns the default cacert bundle for the current system.
+ *
+ * First, the openssl.cafile and curl.cainfo php.ini settings are checked.
+ * If those settings are not configured, then the common locations for
+ * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X
+ * and Windows are checked. If any of these file locations are found on
+ * disk, they will be utilized.
+ *
+ * Note: the result of this function is cached for subsequent calls.
+ *
+ * @throws \RuntimeException if no bundle can be found.
+ *
+ * @deprecated default_ca_bundle will be removed in guzzlehttp/guzzle:8.0. This function is not needed in PHP 5.6+.
+ */
+function default_ca_bundle(): string
+{
+    return Utils::defaultCaBundle();
+}
+
+/**
+ * Creates an associative array of lowercase header names to the actual
+ * header casing.
+ *
+ * @deprecated normalize_header_keys will be removed in guzzlehttp/guzzle:8.0. Use Utils::normalizeHeaderKeys instead.
+ */
+function normalize_header_keys(array $headers): array
+{
+    return Utils::normalizeHeaderKeys($headers);
+}
+
+/**
+ * Returns true if the provided host matches any of the no proxy areas.
+ *
+ * This method will strip a port from the host if it is present. Each pattern
+ * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a
+ * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" ==
+ * "baz.foo.com", but ".foo.com" != "foo.com").
+ *
+ * Areas are matched in the following cases:
+ * 1. "*" (without quotes) always matches any hosts.
+ * 2. An exact match.
+ * 3. The area starts with "." and the area is the last part of the host. e.g.
+ *    '.mit.edu' will match any host that ends with '.mit.edu'.
+ *
+ * @param string   $host         Host to check against the patterns.
+ * @param string[] $noProxyArray An array of host patterns.
+ *
+ * @throws Exception\InvalidArgumentException
+ *
+ * @deprecated is_host_in_noproxy will be removed in guzzlehttp/guzzle:8.0. Use Utils::isHostInNoProxy instead.
+ */
+function is_host_in_noproxy(string $host, array $noProxyArray): bool
+{
+    return Utils::isHostInNoProxy($host, $noProxyArray);
+}
+
+/**
+ * Wrapper for json_decode that throws when an error occurs.
+ *
+ * @param string $json    JSON data to parse
+ * @param bool   $assoc   When true, returned objects will be converted
+ *                        into associative arrays.
+ * @param int    $depth   User specified recursion depth.
+ * @param int    $options Bitmask of JSON decode options.
+ *
+ * @return object|array|string|int|float|bool|null
+ *
+ * @throws Exception\InvalidArgumentException if the JSON cannot be decoded.
+ *
+ * @see https://www.php.net/manual/en/function.json-decode.php
+ * @deprecated json_decode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonDecode instead.
+ */
+function json_decode(string $json, bool $assoc = false, int $depth = 512, int $options = 0)
+{
+    return Utils::jsonDecode($json, $assoc, $depth, $options);
+}
+
+/**
+ * Wrapper for JSON encoding that throws when an error occurs.
+ *
+ * @param mixed $value   The value being encoded
+ * @param int   $options JSON encode option bitmask
+ * @param int   $depth   Set the maximum depth. Must be greater than zero.
+ *
+ * @throws Exception\InvalidArgumentException if the JSON cannot be encoded.
+ *
+ * @see https://www.php.net/manual/en/function.json-encode.php
+ * @deprecated json_encode will be removed in guzzlehttp/guzzle:8.0. Use Utils::jsonEncode instead.
+ */
+function json_encode($value, int $options = 0, int $depth = 512): string
+{
+    return Utils::jsonEncode($value, $options, $depth);
+}
Index: vendor/guzzlehttp/guzzle/src/functions_include.php
===================================================================
--- vendor/guzzlehttp/guzzle/src/functions_include.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
+++ vendor/guzzlehttp/guzzle/src/functions_include.php	(revision e3d4e0a8bc0f13135f27c0b055b5c00f64a28f01)
@@ -0,0 +1,6 @@
+<?php
+
+// Don't redefine the functions if included multiple times.
+if (!\function_exists('GuzzleHttp\describe_type')) {
+    require __DIR__.'/functions.php';
+}
