From e3821f9e58fadf16a89b3becb4a00e58d466f390 Mon Sep 17 00:00:00 2001
From: kenjis <action@github.com>
Date: Sun, 26 Mar 2023 01:13:46 +0000
Subject: [PATCH] Release v4.3.3

---
 app/Common.php                                |  2 +-
 app/Config/Encryption.php                     |  9 +++
 composer.json                                 |  2 +-
 system/API/ResponseTrait.php                  |  2 +
 system/Cache/Handlers/FileHandler.php         |  2 +-
 system/Cache/Handlers/RedisHandler.php        |  3 +-
 system/CodeIgniter.php                        |  2 +-
 system/Commands/Database/MigrateRollback.php  |  2 +-
 .../Utilities/Routes/ControllerFinder.php     |  1 +
 system/Database/BaseBuilder.php               | 10 ++-
 system/Debug/Exceptions.php                   |  8 +-
 system/Email/Email.php                        |  5 +-
 system/Filters/FilterInterface.php            |  4 +-
 system/HTTP/DownloadResponse.php              |  5 +-
 system/HTTP/RequestInterface.php              |  4 +-
 system/HTTP/RequestTrait.php                  |  8 +-
 system/HTTP/ResponseTrait.php                 |  6 +-
 system/Helpers/text_helper.php                | 76 +++++++++++++++++--
 system/Helpers/url_helper.php                 |  9 ++-
 .../SplFileInfoRepresentation.php             |  2 +-
 .../resources/compiled/solarized-dark.css     |  2 +-
 21 files changed, 127 insertions(+), 37 deletions(-)

diff --git a/app/Common.php b/app/Common.php
index 23e3e614..95f55442 100644
--- a/app/Common.php
+++ b/app/Common.php
@@ -11,5 +11,5 @@
  * loaded early on, and may also contain additional functions
  * that you'd like to use throughout your entire application
  *
- * @see: https://codeigniter4.github.io/CodeIgniter4/
+ * @see: https://codeigniter.com/user_guide/extending/common.html
  */
diff --git a/app/Config/Encryption.php b/app/Config/Encryption.php
index e37b4e2a..28344134 100644
--- a/app/Config/Encryption.php
+++ b/app/Config/Encryption.php
@@ -80,4 +80,13 @@ class Encryption extends BaseConfig
      * Set to 'authentication' for CI3 Encryption compatibility.
      */
     public string $authKeyInfo = '';
+
+    /**
+     * Cipher to use.
+     * This setting is only used by OpenSSLHandler.
+     *
+     * Set to 'AES-128-CBC' to decrypt encrypted data that encrypted
+     * by CI3 Encryption default configuration.
+     */
+    public string $cipher = 'AES-256-CTR';
 }
diff --git a/composer.json b/composer.json
index 2f3022a9..905e123c 100644
--- a/composer.json
+++ b/composer.json
@@ -13,7 +13,7 @@
         "psr/log": "^1.1"
     },
     "require-dev": {
-        "kint-php/kint": "^5.0.3",
+        "kint-php/kint": "^5.0.4",
         "codeigniter/coding-standard": "^1.5",
         "fakerphp/faker": "^1.9",
         "friendsofphp/php-cs-fixer": "3.13.0",
diff --git a/system/API/ResponseTrait.php b/system/API/ResponseTrait.php
index 0b357f0a..9e8bad77 100644
--- a/system/API/ResponseTrait.php
+++ b/system/API/ResponseTrait.php
@@ -92,8 +92,10 @@ protected function respond($data = null, ?int $status = null, string $message =
         if ($data === null && $status === null) {
             $status = 404;
             $output = null;
+            $this->format($data);
         } elseif ($data === null && is_numeric($status)) {
             $output = null;
+            $this->format($data);
         } else {
             $status = empty($status) ? 200 : $status;
             $output = $this->format($data);
diff --git a/system/Cache/Handlers/FileHandler.php b/system/Cache/Handlers/FileHandler.php
index b95d7f9e..c217c7ed 100644
--- a/system/Cache/Handlers/FileHandler.php
+++ b/system/Cache/Handlers/FileHandler.php
@@ -346,7 +346,7 @@ protected function getDirFileInfo(string $sourceDir, bool $topLevelOnly = true,
             while (false !== ($file = readdir($fp))) {
                 if (is_dir($sourceDir . $file) && $file[0] !== '.' && $topLevelOnly === false) {
                     $this->getDirFileInfo($sourceDir . $file . DIRECTORY_SEPARATOR, $topLevelOnly, true);
-                } elseif ($file[0] !== '.') {
+                } elseif (! is_dir($sourceDir . $file) && $file[0] !== '.') {
                     $_filedata[$file]                  = $this->getFileInfo($sourceDir . $file);
                     $_filedata[$file]['relative_path'] = $relativePath;
                 }
diff --git a/system/Cache/Handlers/RedisHandler.php b/system/Cache/Handlers/RedisHandler.php
index 8b3af585..6874a86c 100644
--- a/system/Cache/Handlers/RedisHandler.php
+++ b/system/Cache/Handlers/RedisHandler.php
@@ -233,12 +233,11 @@ public function getCacheInfo()
      */
     public function getMetaData(string $key)
     {
-        $key   = static::validateKey($key, $this->prefix);
         $value = $this->get($key);
 
         if ($value !== null) {
             $time = Time::now()->getTimestamp();
-            $ttl  = $this->redis->ttl($key);
+            $ttl  = $this->redis->ttl(static::validateKey($key, $this->prefix));
 
             return [
                 'expire' => $ttl > 0 ? $time + $ttl : null,
diff --git a/system/CodeIgniter.php b/system/CodeIgniter.php
index d370e34c..42ddaa0c 100644
--- a/system/CodeIgniter.php
+++ b/system/CodeIgniter.php
@@ -47,7 +47,7 @@ class CodeIgniter
     /**
      * The current version of CodeIgniter Framework
      */
-    public const CI_VERSION = '4.3.2';
+    public const CI_VERSION = '4.3.3';
 
     /**
      * App startup time.
diff --git a/system/Commands/Database/MigrateRollback.php b/system/Commands/Database/MigrateRollback.php
index 17434da4..c29ce84b 100644
--- a/system/Commands/Database/MigrateRollback.php
+++ b/system/Commands/Database/MigrateRollback.php
@@ -57,7 +57,7 @@ class MigrateRollback extends BaseCommand
      * @var array
      */
     protected $options = [
-        '-b' => 'Specify a batch to roll back to; e.g. "3" to return to batch #3 or "-2" to roll back twice',
+        '-b' => 'Specify a batch to roll back to; e.g. "3" to return to batch #3',
         '-g' => 'Set database group',
         '-f' => 'Force command - this option allows you to bypass the confirmation question when running this command in a production environment',
     ];
diff --git a/system/Commands/Utilities/Routes/ControllerFinder.php b/system/Commands/Utilities/Routes/ControllerFinder.php
index 7e786587..e7d828c0 100644
--- a/system/Commands/Utilities/Routes/ControllerFinder.php
+++ b/system/Commands/Utilities/Routes/ControllerFinder.php
@@ -44,6 +44,7 @@ public function find(): array
         $nsArray = explode('\\', trim($this->namespace, '\\'));
         $count   = count($nsArray);
         $ns      = '';
+        $files   = [];
 
         for ($i = 0; $i < $count; $i++) {
             $ns .= '\\' . array_shift($nsArray);
diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php
index 653f4301..fab6e30d 100644
--- a/system/Database/BaseBuilder.php
+++ b/system/Database/BaseBuilder.php
@@ -2021,9 +2021,9 @@ private function setAlias(string $alias): BaseBuilder
     /**
      * Sets update fields for upsert, update
      *
-     * @param string|string[] $set
-     * @param bool            $addToDefault adds update fields to the default ones
-     * @param array|null      $ignore       ignores items in set
+     * @param RawSql[]|string|string[] $set
+     * @param bool                     $addToDefault adds update fields to the default ones
+     * @param array|null               $ignore       ignores items in set
      *
      * @return $this
      */
@@ -3082,6 +3082,10 @@ protected function compileWhereHaving(string $qbKey): string
                     continue;
                 }
 
+                if ($qbkey instanceof RawSql) {
+                    continue;
+                }
+
                 if ($qbkey['condition'] instanceof RawSql) {
                     $qbkey = $qbkey['condition'];
 
diff --git a/system/Debug/Exceptions.php b/system/Debug/Exceptions.php
index 6dc098d4..531e95fd 100644
--- a/system/Debug/Exceptions.php
+++ b/system/Debug/Exceptions.php
@@ -119,6 +119,11 @@ public function exceptionHandler(Throwable $exception)
 
         [$statusCode, $exitCode] = $this->determineCodes($exception);
 
+        // Get the first exception.
+        while ($prevException = $exception->getPrevious()) {
+            $exception = $prevException;
+        }
+
         if ($this->config->log === true && ! in_array($statusCode, $this->config->ignoreCodes, true)) {
             log_message('critical', "{message}\nin {exFile} on line {exLine}.\n{trace}", [
                 'message' => $exception->getMessage(),
@@ -531,9 +536,6 @@ private static function renderBacktrace(array $backtrace): string
                     case is_resource($value):
                         return sprintf('resource (%s)', get_resource_type($value));
 
-                    case is_string($value):
-                        return var_export(clean_path($value), true);
-
                     default:
                         return var_export($value, true);
                 }
diff --git a/system/Email/Email.php b/system/Email/Email.php
index 488a5ee7..fe68ff2d 100644
--- a/system/Email/Email.php
+++ b/system/Email/Email.php
@@ -1883,7 +1883,10 @@ protected function SMTPConnect()
             $crypto = stream_socket_enable_crypto(
                 $this->SMTPConnect,
                 true,
-                STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+                STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT
+                | STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
+                | STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
+                | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT
             );
 
             if ($crypto !== true) {
diff --git a/system/Filters/FilterInterface.php b/system/Filters/FilterInterface.php
index 32a18de7..8055d11e 100644
--- a/system/Filters/FilterInterface.php
+++ b/system/Filters/FilterInterface.php
@@ -29,7 +29,7 @@ interface FilterInterface
      * sent back to the client, allowing for error pages,
      * redirects, etc.
      *
-     * @param null $arguments
+     * @param array|null $arguments
      *
      * @return mixed
      */
@@ -41,7 +41,7 @@ public function before(RequestInterface $request, $arguments = null);
      * to stop execution of other after filters, short of
      * throwing an Exception or Error.
      *
-     * @param null $arguments
+     * @param array|null $arguments
      *
      * @return mixed
      */
diff --git a/system/HTTP/DownloadResponse.php b/system/HTTP/DownloadResponse.php
index 899bec85..d5824da1 100644
--- a/system/HTTP/DownloadResponse.php
+++ b/system/HTTP/DownloadResponse.php
@@ -227,9 +227,8 @@ public function setContentType(string $mime, string $charset = 'UTF-8')
      */
     public function noCache(): self
     {
-        $this->removeHeader('Cache-control');
-
-        $this->setHeader('Cache-control', ['private', 'no-transform', 'no-store', 'must-revalidate']);
+        $this->removeHeader('Cache-Control');
+        $this->setHeader('Cache-Control', ['private', 'no-transform', 'no-store', 'must-revalidate']);
 
         return $this;
     }
diff --git a/system/HTTP/RequestInterface.php b/system/HTTP/RequestInterface.php
index fd2cdfbb..367c4949 100644
--- a/system/HTTP/RequestInterface.php
+++ b/system/HTTP/RequestInterface.php
@@ -40,8 +40,8 @@ public function isValidIP(string $ip, ?string $which = null): bool;
      * Fetch an item from the $_SERVER array.
      * Supplied by RequestTrait.
      *
-     * @param string $index  Index for item to be fetched from $_SERVER
-     * @param null   $filter A filter name to be applied
+     * @param array|string|null $index  Index for item to be fetched from $_SERVER
+     * @param int|null          $filter A filter name to be applied
      *
      * @return mixed
      */
diff --git a/system/HTTP/RequestTrait.php b/system/HTTP/RequestTrait.php
index 5dc0359b..2392ecbc 100644
--- a/system/HTTP/RequestTrait.php
+++ b/system/HTTP/RequestTrait.php
@@ -192,7 +192,7 @@ private function getClientIP(string $header): ?string
      *
      * @param array|string|null $index  Index for item to be fetched from $_SERVER
      * @param int|null          $filter A filter name to be applied
-     * @param null              $flags
+     * @param array|int|null    $flags
      *
      * @return mixed
      */
@@ -204,9 +204,9 @@ public function getServer($index = null, $filter = null, $flags = null)
     /**
      * Fetch an item from the $_ENV array.
      *
-     * @param null $index  Index for item to be fetched from $_ENV
-     * @param null $filter A filter name to be applied
-     * @param null $flags
+     * @param array|string|null $index  Index for item to be fetched from $_ENV
+     * @param int|null          $filter A filter name to be applied
+     * @param array|int|null    $flags
      *
      * @return mixed
      */
diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php
index 0ad3239e..dd490e90 100644
--- a/system/HTTP/ResponseTrait.php
+++ b/system/HTTP/ResponseTrait.php
@@ -345,8 +345,8 @@ protected function formatBody($body, string $format)
      */
     public function noCache()
     {
-        $this->removeHeader('Cache-control');
-        $this->setHeader('Cache-control', ['no-store', 'max-age=0', 'no-cache']);
+        $this->removeHeader('Cache-Control');
+        $this->setHeader('Cache-Control', ['no-store', 'max-age=0', 'no-cache']);
 
         return $this;
     }
@@ -399,7 +399,7 @@ public function setCache(array $options = [])
             unset($options['last-modified']);
         }
 
-        $this->setHeader('Cache-control', $options);
+        $this->setHeader('Cache-Control', $options);
 
         return $this;
     }
diff --git a/system/Helpers/text_helper.php b/system/Helpers/text_helper.php
index 51b2c7db..7b52fa34 100755
--- a/system/Helpers/text_helper.php
+++ b/system/Helpers/text_helper.php
@@ -543,7 +543,6 @@ function random_string(string $type = 'alnum', int $len = 8): string
     {
         switch ($type) {
             case 'alnum':
-            case 'numeric':
             case 'nozero':
             case 'alpha':
                 switch ($type) {
@@ -555,16 +554,18 @@ function random_string(string $type = 'alnum', int $len = 8): string
                         $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                         break;
 
-                    case 'numeric':
-                        $pool = '0123456789';
-                        break;
-
                     case 'nozero':
                         $pool = '123456789';
                         break;
                 }
 
-                return substr(str_shuffle(str_repeat($pool, (int) ceil($len / strlen($pool)))), 0, $len);
+                return _from_random($len, $pool);
+
+            case 'numeric':
+                $max  = 10 ** $len - 1;
+                $rand = random_int(0, $max);
+
+                return sprintf('%0' . $len . 'd', $rand);
 
             case 'md5':
                 return md5(uniqid((string) mt_rand(), true));
@@ -586,6 +587,69 @@ function random_string(string $type = 'alnum', int $len = 8): string
     }
 }
 
+if (! function_exists('_from_random')) {
+    /**
+     * The following function was derived from code of Symfony (v6.2.7 - 2023-02-28)
+     * https://github.com/symfony/symfony/blob/80cac46a31d4561804c17d101591a4f59e6db3a2/src/Symfony/Component/String/ByteString.php#L45
+     * Code subject to the MIT license (https://github.com/symfony/symfony/blob/v6.2.7/LICENSE).
+     * Copyright (c) 2004-present Fabien Potencier
+     *
+     * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03)
+     * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16
+     * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE).
+     * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/)
+     *
+     * @internal Outside the framework this should not be used directly.
+     */
+    function _from_random(int $length, string $pool): string
+    {
+        if ($length <= 0) {
+            throw new InvalidArgumentException(
+                sprintf('A strictly positive length is expected, "%d" given.', $length)
+            );
+        }
+
+        $poolSize = \strlen($pool);
+        $bits     = (int) ceil(log($poolSize, 2.0));
+        if ($bits <= 0 || $bits > 56) {
+            throw new InvalidArgumentException(
+                'The length of the alphabet must in the [2^1, 2^56] range.'
+            );
+        }
+
+        $string = '';
+
+        while ($length > 0) {
+            $urandomLength = (int) ceil(2 * $length * $bits / 8.0);
+            $data          = random_bytes($urandomLength);
+            $unpackedData  = 0;
+            $unpackedBits  = 0;
+
+            for ($i = 0; $i < $urandomLength && $length > 0; $i++) {
+                // Unpack 8 bits
+                $unpackedData = ($unpackedData << 8) | \ord($data[$i]);
+                $unpackedBits += 8;
+
+                // While we have enough bits to select a character from the alphabet, keep
+                // consuming the random data
+                for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) {
+                    $index = ($unpackedData & ((1 << $bits) - 1));
+                    $unpackedData >>= $bits;
+                    // Unfortunately, the alphabet size is not necessarily a power of two.
+                    // Worst case, it is 2^k + 1, which means we need (k+1) bits and we
+                    // have around a 50% chance of missing as k gets larger
+                    if ($index < $poolSize) {
+                        $string .= $pool[$index];
+                        $length--;
+                    }
+                }
+            }
+        }
+
+        return $string;
+    }
+}
+
 if (! function_exists('increment_string')) {
     /**
      * Add's _1 to a string or increment the ending number to allow _2, _3, etc
diff --git a/system/Helpers/url_helper.php b/system/Helpers/url_helper.php
index 1a064a76..8443c7a0 100644
--- a/system/Helpers/url_helper.php
+++ b/system/Helpers/url_helper.php
@@ -117,13 +117,20 @@ function site_url($relativePath = '', ?string $scheme = null, ?App $config = nul
     {
         $uri = _get_uri($relativePath, $config);
 
-        return URI::createURIString(
+        $uriString = URI::createURIString(
             $scheme ?? $uri->getScheme(),
             $uri->getAuthority(),
             $uri->getPath(),
             $uri->getQuery(),
             $uri->getFragment()
         );
+
+        // For protocol-relative links
+        if ($scheme === '') {
+            $uriString = '//' . $uriString;
+        }
+
+        return $uriString;
     }
 }
 
diff --git a/system/ThirdParty/Kint/Zval/Representation/SplFileInfoRepresentation.php b/system/ThirdParty/Kint/Zval/Representation/SplFileInfoRepresentation.php
index 44980d7e..6424ee6a 100644
--- a/system/ThirdParty/Kint/Zval/Representation/SplFileInfoRepresentation.php
+++ b/system/ThirdParty/Kint/Zval/Representation/SplFileInfoRepresentation.php
@@ -57,7 +57,7 @@ public function __construct(SplFileInfo $fileInfo)
         $this->path = $fileInfo->getPathname();
 
         try {
-            if ($fileInfo->getRealPath()) {
+            if (\strlen($this->path) && $fileInfo->getRealPath()) {
                 $this->perms = $fileInfo->getPerms();
                 $this->size = $fileInfo->getSize();
                 $this->owner = $fileInfo->getOwner();
diff --git a/system/ThirdParty/Kint/resources/compiled/solarized-dark.css b/system/ThirdParty/Kint/resources/compiled/solarized-dark.css
index 1d3c28b0..4ab5e287 100644
--- a/system/ThirdParty/Kint/resources/compiled/solarized-dark.css
+++ b/system/ThirdParty/Kint/resources/compiled/solarized-dark.css
@@ -1 +1 @@
-.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:#073642}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#839496}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#839496;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#002b36;border:1px solid #586e75;color:#839496;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2 2"><path fill="%23FFF" d="M0 0h1v2h1V1H0z"/></svg>');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}input.kint-note-input{width:100%}body{background:#073642;color:#fff}.kint-rich{box-shadow:0 0 5px 3px #073642}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd}
+.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:#073642}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:block}.kint-rich.kint-folder dd.kint-foldout{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll;display:none}.kint-rich.kint-folder dd.kint-foldout.kint-show{display:block}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#839496}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#839496;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#002b36;border:1px solid #586e75;color:#839496;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul.kint-tab-contents>li{display:none}.kint-rich ul.kint-tab-contents>li.kint-show{display:block}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2 2"><path fill="%23FFF" d="M0 0h1v2h1V1H0z"/></svg>');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}input.kint-note-input{width:100%}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd}