From a187153b5ec5ae23bec9ac569347fe27e8ba3fd8 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Fri, 25 Feb 2022 14:14:21 +0000
Subject: [PATCH 1/7] fix(csrf): uncomment csrf filter to validate user
 requests' token

---
 app/Config/Filters.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Config/Filters.php b/app/Config/Filters.php
index 9481194ed4..fb459ebe65 100644
--- a/app/Config/Filters.php
+++ b/app/Config/Filters.php
@@ -44,7 +44,7 @@ class Filters extends BaseConfig
     public array $globals = [
         'before' => [
             // 'honeypot',
-            // 'csrf',
+            'csrf',
             // 'invalidchars',
         ],
         'after' => [
-- 
GitLab


From 23efe4b2c87445c635f9327fb91aa6c37c2b8c3a Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Fri, 25 Feb 2022 14:23:00 +0000
Subject: [PATCH 2/7] feat(security): randomize csrf token for added security

---
 app/Config/Security.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/Config/Security.php b/app/Config/Security.php
index eedbb270f0..92c105d8e9 100644
--- a/app/Config/Security.php
+++ b/app/Config/Security.php
@@ -26,7 +26,7 @@ class Security extends BaseConfig
      *
      * Randomize the CSRF Token for added security.
      */
-    public bool $tokenRandomize = false;
+    public bool $tokenRandomize = true;
 
     /**
      * --------------------------------------------------------------------------
-- 
GitLab


From 089866f6fa6e25b354f78a5843ed5e0a462127fd Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Fri, 25 Feb 2022 14:45:13 +0000
Subject: [PATCH 3/7] fix(csrf): add missing csrf token to some forms

---
 themes/cp_admin/fediverse/blocked_actors.php                | 2 ++
 themes/cp_admin/fediverse/blocked_domains.php               | 2 ++
 themes/cp_app/episode/_partials/comment_actions.php         | 1 +
 .../cp_app/episode/_partials/comment_actions_from_post.php  | 1 +
 themes/cp_app/episode/_partials/comment_card.php            | 2 ++
 themes/cp_app/episode/_partials/comment_reply_actions.php   | 2 ++
 themes/cp_app/episode/_partials/comment_with_replies.php    | 6 ++++--
 themes/cp_app/post/_partials/post_with_replies.php          | 6 ++++--
 8 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/themes/cp_admin/fediverse/blocked_actors.php b/themes/cp_admin/fediverse/blocked_actors.php
index 3446545a90..e60865cb5a 100644
--- a/themes/cp_admin/fediverse/blocked_actors.php
+++ b/themes/cp_admin/fediverse/blocked_actors.php
@@ -12,6 +12,8 @@
 <?= $this->section('content') ?>
 
 <form action="<?= route_to('fediverse-attempt-block-actor') ?>" method="POST" class="flex flex-col max-w-md">
+    <?= csrf_field() ?>
+
     <Forms.Field name="handle" label="<?= lang('Fediverse.block_lists_form.handle') ?>" hint="<?= lang('Fediverse.block_lists_form.handle_hint') ?>" required="true" />
     <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.block_lists_form.submit') ?></Button>
 </form>
diff --git a/themes/cp_admin/fediverse/blocked_domains.php b/themes/cp_admin/fediverse/blocked_domains.php
index 3ff9ae87cd..c3b701f720 100644
--- a/themes/cp_admin/fediverse/blocked_domains.php
+++ b/themes/cp_admin/fediverse/blocked_domains.php
@@ -12,6 +12,8 @@
 <?= $this->section('content') ?>
 
 <form action="<?= route_to('fediverse-attempt-block-domain') ?>" method="POST" class="flex flex-col max-w-md">
+    <?= csrf_field() ?>
+
     <Forms.Field name="domain" label="<?= lang('Fediverse.block_lists_form.domain') ?>" required="true" />
     <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.block_lists_form.submit') ?></Button>
 </form>
diff --git a/themes/cp_app/episode/_partials/comment_actions.php b/themes/cp_app/episode/_partials/comment_actions.php
index 0ca8c8c5a1..c1fe1244a0 100644
--- a/themes/cp_app/episode/_partials/comment_actions.php
+++ b/themes/cp_app/episode/_partials/comment_actions.php
@@ -1,6 +1,7 @@
 <footer>
     <?php if (can_user_interact()): ?>
         <form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $comment->episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+            <?= csrf_field() ?>
             <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
     'Comment.likes',
     [
diff --git a/themes/cp_app/episode/_partials/comment_actions_from_post.php b/themes/cp_app/episode/_partials/comment_actions_from_post.php
index bba0f41242..fbbb08c246 100644
--- a/themes/cp_app/episode/_partials/comment_actions_from_post.php
+++ b/themes/cp_app/episode/_partials/comment_actions_from_post.php
@@ -1,6 +1,7 @@
 <footer>
     <?php if (can_user_interact()): ?>
         <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+        <?= csrf_field() ?>
         <button type="submit" name="action" value="favourite" class="inline-flex items-center hover:underline group" title="<?= lang(
     'Comment.likes',
     [
diff --git a/themes/cp_app/episode/_partials/comment_card.php b/themes/cp_app/episode/_partials/comment_card.php
index 7c534fab50..a54c51c157 100644
--- a/themes/cp_app/episode/_partials/comment_card.php
+++ b/themes/cp_app/episode/_partials/comment_card.php
@@ -22,6 +22,8 @@
             <footer>
                 <?php if (can_user_interact()): ?>
                     <form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+                    <?= csrf_field() ?>
+
                     <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
                             'Comment.likes',
                             [
diff --git a/themes/cp_app/episode/_partials/comment_reply_actions.php b/themes/cp_app/episode/_partials/comment_reply_actions.php
index a727b66619..2f4be594ea 100644
--- a/themes/cp_app/episode/_partials/comment_reply_actions.php
+++ b/themes/cp_app/episode/_partials/comment_reply_actions.php
@@ -1,6 +1,8 @@
 <footer>
     <?php if (can_user_interact()): ?>
         <form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $reply->episode->slug, $reply->id) ?>" method="POST" class="flex items-center gap-x-4">
+            <?= csrf_field() ?>
+
             <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
     'Comment.likes',
     [
diff --git a/themes/cp_app/episode/_partials/comment_with_replies.php b/themes/cp_app/episode/_partials/comment_with_replies.php
index f6382360df..17c291fb3f 100644
--- a/themes/cp_app/episode/_partials/comment_with_replies.php
+++ b/themes/cp_app/episode/_partials/comment_with_replies.php
@@ -13,9 +13,11 @@ if ($comment->in_reply_to_id): ?>
 
 <?php if (can_user_interact()): ?>
 <form action="<?= route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 gap-x-2 bg-base">
+    <?= csrf_field() ?>
+
     <img src="<?= interact_as_actor()
-    ->avatar_image_url ?>" alt="<?= interact_as_actor()
-    ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+        ->avatar_image_url ?>" alt="<?= interact_as_actor()
+        ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
     <div class="flex flex-col flex-1">
         <Forms.Textarea
             name="message"
diff --git a/themes/cp_app/post/_partials/post_with_replies.php b/themes/cp_app/post/_partials/post_with_replies.php
index 91075d56b3..245fe09784 100644
--- a/themes/cp_app/post/_partials/post_with_replies.php
+++ b/themes/cp_app/post/_partials/post_with_replies.php
@@ -18,9 +18,11 @@ if ($post->in_reply_to_id): ?>
     <div class="px-6 pt-8 pb-4 bg-base">
         <?php if (can_user_interact()): ?>
             <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $post->id) ?>" method="POST" class="flex gap-x-2" >
+                <?= csrf_field() ?>
+
                 <img src="<?= interact_as_actor()
-            ->avatar_image_url ?>" alt="<?= interact_as_actor()
-            ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+                    ->avatar_image_url ?>" alt="<?= interact_as_actor()
+                    ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
                 <div class="flex flex-col flex-1">
                     <Forms.Textarea
                         name="message"
-- 
GitLab


From 716471dad9652025eb89114bf8f9440356cbe910 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Mon, 28 Feb 2022 17:09:17 +0000
Subject: [PATCH 4/7] build: use CI4 v4.1.9 production package + update php and
 js dependencies to latest

---
 app/Config/Database.php                       |    4 +-
 app/Config/Fediverse.php                      |   14 +-
 app/Config/Filters.php                        |    3 +-
 app/Config/Paths.php                          |    2 +-
 app/Controllers/ColorsController.php          |    1 +
 app/Controllers/EpisodeCommentController.php  |    1 +
 app/Controllers/EpisodeController.php         |    1 +
 app/Controllers/MapController.php             |    3 +
 app/Controllers/PostController.php            |    3 +-
 app/Controllers/WebmanifestController.php     |    2 +-
 app/Database/Seeds/AuthSeeder.php             |    4 +-
 .../Seeds/FakePodcastsAnalyticsSeeder.php     |    1 +
 .../Seeds/FakeWebsiteAnalyticsSeeder.php      |    1 +
 app/Entities/Episode.php                      |    3 +-
 app/Entities/EpisodeComment.php               |    1 -
 app/Entities/Location.php                     |    1 +
 app/Entities/Media/Audio.php                  |    1 -
 app/Entities/Media/Image.php                  |    1 -
 app/Entities/Podcast.php                      |    6 +-
 app/Helpers/auth_helper.php                   |    4 -
 app/Helpers/components_helper.php             |    2 +-
 app/Helpers/media_helper.php                  |    3 +
 app/Helpers/misc_helper.php                   |    7 +
 app/Helpers/rss_helper.php                    |   11 +
 app/Helpers/seo_helper.php                    |    1 +
 app/Helpers/svg_helper.php                    |    1 +
 app/Libraries/MediaClipper/VideoClipper.php   |   15 +-
 app/Libraries/PodcastActor.php                |    1 +
 app/Libraries/Router.php                      |    3 +-
 app/Libraries/SimpleRSSElement.php            |    6 +-
 app/Libraries/TranscriptParser.php            |    3 +-
 app/Libraries/View.php                        |    1 -
 .../ViewComponents/ComponentRenderer.php      |    3 +-
 app/Libraries/Vite/Vite.php                   |    2 +
 app/Models/CategoryModel.php                  |    1 +
 app/Models/ClipModel.php                      |    2 +-
 app/Models/EpisodeCommentModel.php            |    1 +
 app/Models/EpisodeModel.php                   |    1 +
 app/Models/MediaModel.php                     |    6 +-
 app/Models/PersonModel.php                    |    2 +
 app/Models/PlatformModel.php                  |    2 +
 app/Models/PodcastModel.php                   |    2 +
 app/Views/Components/DropdownMenu.php         |    2 +
 app/Views/Components/Forms/FormComponent.php  |    5 +-
 app/Views/Components/ReadMore.php             |    2 +
 app/Views/errors/cli/error_exception.php      |   46 +-
 app/Views/errors/html/error_exception.php     |  294 +-
 composer.json                                 |   30 +-
 composer.lock                                 | 3067 +++++--------
 ecs.php                                       |    7 +-
 .../Admin/Controllers/EpisodeController.php   |    2 +
 .../Admin/Controllers/PodcastController.php   |    1 +
 .../Controllers/PodcastImportController.php   |    5 +
 .../Controllers/PodcastPlatformController.php |    2 +
 .../Admin/Controllers/SchedulerController.php |    1 +
 .../Admin/Controllers/SettingsController.php  |    1 +
 .../Admin/Controllers/SoundbiteController.php |    2 +-
 .../Controllers/VideoClipsController.php      |    4 +-
 .../Analytics/Helpers/analytics_helper.php    |   11 +-
 .../Models/AnalyticsPodcastByCountryModel.php |    1 +
 .../Models/AnalyticsPodcastByPlayerModel.php  |    5 +
 .../Models/AnalyticsPodcastByRegionModel.php  |    1 +
 .../Models/AnalyticsPodcastByServiceModel.php |    1 +
 .../Models/AnalyticsPodcastModel.php          |    8 +
 .../Models/AnalyticsWebsiteByBrowserModel.php |    1 +
 .../AnalyticsWebsiteByEntryPageModel.php      |    1 +
 .../Models/AnalyticsWebsiteByRefererModel.php |    3 +
 modules/Auth/Filters/PermissionFilter.php     |    1 +
 .../Fediverse/Controllers/ActorController.php |    3 +
 .../Fediverse/Helpers/fediverse_helper.php    |    9 +-
 .../Fediverse/Models/BlockedDomainModel.php   |    2 +-
 modules/Fediverse/Models/FollowModel.php      |    6 -
 .../Objects/OrderedCollectionPage.php         |    1 +
 .../Install/Controllers/InstallController.php |    1 +
 package-lock.json                             | 3871 ++++++++++-------
 package.json                                  |   66 +-
 phpstan.neon                                  |   23 +-
 phpunit.xml.dist                              |    2 +-
 rector.php                                    |   25 +-
 tests/_support/Libraries/ConfigReader.php     |    2 -
 themes/cp_admin/episode/video_clips_new.php   |    1 +
 81 files changed, 3919 insertions(+), 3730 deletions(-)

diff --git a/app/Config/Database.php b/app/Config/Database.php
index 372fcb870d..e0813199a5 100644
--- a/app/Config/Database.php
+++ b/app/Config/Database.php
@@ -24,7 +24,7 @@ class Database extends Config
     /**
      * The default database connection.
      *
-     * @var array<string, string|bool|int|array>
+     * @var array<string, mixed>
      */
     public array $default = [
         'DSN' => '',
@@ -51,7 +51,7 @@ class Database extends Config
      *
      * @noRector StringClassNameToClassConstantRector
      *
-     * @var array<string, string|bool|int|array>
+     * @var array<string, mixed>
      */
     public array $tests = [
         'DSN' => '',
diff --git a/app/Config/Fediverse.php b/app/Config/Fediverse.php
index 6e82183aeb..32378b014a 100644
--- a/app/Config/Fediverse.php
+++ b/app/Config/Fediverse.php
@@ -11,6 +11,7 @@ declare(strict_types=1);
 namespace Config;
 
 use App\Libraries\NoteObject;
+use Exception;
 use Modules\Fediverse\Config\Fediverse as FediverseBaseConfig;
 
 class Fediverse extends FediverseBaseConfig
@@ -26,10 +27,15 @@ class Fediverse extends FediverseBaseConfig
     {
         parent::__construct();
 
-        $defaultBanner = config('Images')
-            ->podcastBannerDefaultPaths[service('settings')->get('App.theme')] ?? config(
-                'Images'
-            )->podcastBannerDefaultPaths['default'];
+        try {
+            $appTheme = service('settings')
+                ->get('App.theme');
+            $defaultBanner = config('Images')
+                ->podcastBannerDefaultPaths[$appTheme] ?? config('Images')->podcastBannerDefaultPaths['default'];
+        } catch (Exception) {
+            $defaultBanner = config('Images')
+                ->podcastBannerDefaultPaths['default'];
+        }
 
         ['dirname' => $dirname, 'extension' => $extension, 'filename' => $filename] = pathinfo(
             $defaultBanner['path']
diff --git a/app/Config/Filters.php b/app/Config/Filters.php
index fb459ebe65..7a505b477d 100644
--- a/app/Config/Filters.php
+++ b/app/Config/Filters.php
@@ -50,7 +50,6 @@ class Filters extends BaseConfig
         'after' => [
             'toolbar',
             // 'honeypot',
-            // 'honeypot',
             // 'secureheaders',
         ],
     ];
@@ -79,7 +78,7 @@ class Filters extends BaseConfig
 
         $this->filters = [
             'login' => [
-                'before' => [config('Admin') ->gateway . '*', config('Analytics') ->gateway . '*'],
+                'before' => [config('Admin')->gateway . '*', config('Analytics')->gateway . '*'],
             ],
         ];
     }
diff --git a/app/Config/Paths.php b/app/Config/Paths.php
index 92fcea0121..1f5aaa433b 100644
--- a/app/Config/Paths.php
+++ b/app/Config/Paths.php
@@ -26,7 +26,7 @@ class Paths
      * the path if the folder is not in the same directory as this file.
      */
     public string $systemDirectory =
-        __DIR__ . '/../../vendor/codeigniter4/codeigniter4/system';
+        __DIR__ . '/../../vendor/codeigniter4/framework/system';
 
     /**
      * ---------------------------------------------------------------
diff --git a/app/Controllers/ColorsController.php b/app/Controllers/ColorsController.php
index 92fc4de58e..50a44db81d 100644
--- a/app/Controllers/ColorsController.php
+++ b/app/Controllers/ColorsController.php
@@ -33,6 +33,7 @@ class ColorsController extends Controller
                 foreach ($color as $variable => $value) {
                     $colorsCssBody .= "--color-{$variable}: {$value[0]} {$value[1]}% {$value[2]}%;";
                 }
+
                 $colorsCssBody .= '}';
             }
 
diff --git a/app/Controllers/EpisodeCommentController.php b/app/Controllers/EpisodeCommentController.php
index d0c46cf118..b061733688 100644
--- a/app/Controllers/EpisodeCommentController.php
+++ b/app/Controllers/EpisodeCommentController.php
@@ -109,6 +109,7 @@ class EpisodeCommentController extends BaseController
                 helper('form');
                 return view('episode/comment', $data);
             }
+
             return view('episode/comment', $data, [
                 'cache' => DECADE,
                 'cache_name' => $cacheName,
diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php
index 3f3c3be4fd..b4c574497f 100644
--- a/app/Controllers/EpisodeController.php
+++ b/app/Controllers/EpisodeController.php
@@ -134,6 +134,7 @@ class EpisodeController extends BaseController
 
                 return view('episode/activity', $data);
             }
+
             // The page cache is set to a decade so it is deleted manually upon podcast update
             return view('episode/activity', $data, [
                 'cache' => $secondsToNextUnpublishedEpisode
diff --git a/app/Controllers/MapController.php b/app/Controllers/MapController.php
index a5e0108c9b..a0a390b2fe 100644
--- a/app/Controllers/MapController.php
+++ b/app/Controllers/MapController.php
@@ -34,6 +34,7 @@ class MapController extends BaseController
                 'cache_name' => $cacheName,
             ]);
         }
+
         return $found;
     }
 
@@ -59,10 +60,12 @@ class MapController extends BaseController
                     'episode_title' => $episode->title,
                 ];
             }
+
             // The page cache is set to a decade so it is deleted manually upon episode update
             cache()
                 ->save($cacheName, $found, DECADE);
         }
+
         return $this->response->setJSON($found);
     }
 }
diff --git a/app/Controllers/PostController.php b/app/Controllers/PostController.php
index e79501aa9b..0104015e3a 100644
--- a/app/Controllers/PostController.php
+++ b/app/Controllers/PostController.php
@@ -87,7 +87,6 @@ class PostController extends FediversePostController
 
         if (! ($cachedView = cache($cacheName))) {
             $data = [
-                // @phpstan-ignore-next-line
                 'metatags' => get_post_metatags($this->post),
                 'post' => $this->post,
                 'podcast' => $this->podcast,
@@ -98,6 +97,7 @@ class PostController extends FediversePostController
                 helper('form');
                 return view('post/post', $data);
             }
+
             return view('post/post', $data, [
                 'cache' => DECADE,
                 'cache_name' => $cacheName,
@@ -246,7 +246,6 @@ class PostController extends FediversePostController
 
         if (! ($cachedView = cache($cacheName))) {
             $data = [
-                // @phpstan-ignore-next-line
                 'metatags' => get_remote_actions_metatags($this->post, $action),
                 'podcast' => $this->podcast,
                 'actor' => $this->actor,
diff --git a/app/Controllers/WebmanifestController.php b/app/Controllers/WebmanifestController.php
index 1bf20ce76b..5ac61f929f 100644
--- a/app/Controllers/WebmanifestController.php
+++ b/app/Controllers/WebmanifestController.php
@@ -18,7 +18,7 @@ use CodeIgniter\HTTP\ResponseInterface;
 class WebmanifestController extends Controller
 {
     /**
-     * @var array<string, string>
+     * @var array<string, array<string, string>>
      */
     public const THEME_COLORS = [
         'pine' => [
diff --git a/app/Database/Seeds/AuthSeeder.php b/app/Database/Seeds/AuthSeeder.php
index 965c110104..dff5c8eb87 100644
--- a/app/Database/Seeds/AuthSeeder.php
+++ b/app/Database/Seeds/AuthSeeder.php
@@ -37,7 +37,7 @@ class AuthSeeder extends Seeder
      *
      * ``` context => [ [action, description], [action, description], ... ] ```
      *
-     * @var array<string, array<string, string|array>[]>
+     * @var array<string, array<string, string|string[]>[]>
      */
     protected array $permissions = [
         'settings' => [
@@ -302,12 +302,14 @@ class AuthSeeder extends Seeder
                 ->ignore(true)
                 ->insertBatch($dataPermissions);
         }
+
         if ($this->db->table('auth_groups')->countAll() < count($dataGroups)) {
             $this->db
                 ->table('auth_groups')
                 ->ignore(true)
                 ->insertBatch($dataGroups);
         }
+
         if ($this->db->table('auth_groups_permissions')->countAll() < count($dataGroupsPermissions)) {
             $this->db
                 ->table('auth_groups_permissions')
diff --git a/app/Database/Seeds/FakePodcastsAnalyticsSeeder.php b/app/Database/Seeds/FakePodcastsAnalyticsSeeder.php
index fe87bd4c03..d05870d897 100644
--- a/app/Database/Seeds/FakePodcastsAnalyticsSeeder.php
+++ b/app/Database/Seeds/FakePodcastsAnalyticsSeeder.php
@@ -169,6 +169,7 @@ class FakePodcastsAnalyticsSeeder extends Seeder
                         ];
                     }
                 }
+
                 $this->db
                     ->table('analytics_podcasts')
                     ->ignore(true)
diff --git a/app/Database/Seeds/FakeWebsiteAnalyticsSeeder.php b/app/Database/Seeds/FakeWebsiteAnalyticsSeeder.php
index 9cf5f80ca8..ea7c230222 100644
--- a/app/Database/Seeds/FakeWebsiteAnalyticsSeeder.php
+++ b/app/Database/Seeds/FakeWebsiteAnalyticsSeeder.php
@@ -248,6 +248,7 @@ class FakeWebsiteAnalyticsSeeder extends Seeder
                         ];
                     }
                 }
+
                 $this->db
                     ->table('analytics_website_by_browser')
                     ->ignore(true)
diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index ebd648fd5c..3dceb5b5f8 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -367,6 +367,7 @@ class Episode extends Entity
         if ($this->transcript !== null) {
             return $this->transcript->file_url;
         }
+
         return $this->transcript_remote_url;
     }
 
@@ -611,7 +612,7 @@ class Episode extends Entity
             'elements' => $this->custom_rss,
         ], $xmlNode);
 
-        return str_replace(['<item>', '</item>'], '', $xmlNode->asXML());
+        return (string) str_replace(['<item>', '</item>'], '', $xmlNode->asXML());
     }
 
     /**
diff --git a/app/Entities/EpisodeComment.php b/app/Entities/EpisodeComment.php
index 85e57b3f60..43769ddace 100644
--- a/app/Entities/EpisodeComment.php
+++ b/app/Entities/EpisodeComment.php
@@ -102,7 +102,6 @@ class EpisodeComment extends UuidEntity
                 ->getActorById($this->actor_id);
         }
 
-        // @phpstan-ignore-next-line
         return $this->actor;
     }
 
diff --git a/app/Entities/Location.php b/app/Entities/Location.php
index 0895641989..ba9c4ea7b5 100644
--- a/app/Entities/Location.php
+++ b/app/Entities/Location.php
@@ -45,6 +45,7 @@ class Location extends Entity
             $latitude = floatval($geoArray[0]);
             $longitude = floatval($geoArray[1]);
         }
+
         parent::__construct([
             'name' => $name,
             'geo' => $geo,
diff --git a/app/Entities/Media/Audio.php b/app/Entities/Media/Audio.php
index 7b0a289a4b..90a9c1eb6a 100644
--- a/app/Entities/Media/Audio.php
+++ b/app/Entities/Media/Audio.php
@@ -43,7 +43,6 @@ class Audio extends BaseMedia
 
         $this->attributes['file_mimetype'] = $audioMetadata['mime_type'];
         $this->attributes['file_size'] = $audioMetadata['filesize'];
-        // @phpstan-ignore-next-line
         $this->attributes['description'] = @$audioMetadata['id3v2']['comments']['comment'][0];
         $this->attributes['file_metadata'] = json_encode($audioMetadata, JSON_INVALID_UTF8_SUBSTITUTE);
 
diff --git a/app/Entities/Media/Image.php b/app/Entities/Media/Image.php
index 754ce86fc9..e57426c091 100644
--- a/app/Entities/Media/Image.php
+++ b/app/Entities/Media/Image.php
@@ -48,7 +48,6 @@ class Image extends BaseMedia
     {
         parent::setFile($file);
 
-        // @phpstan-ignore-next-line
         if ($this->file_mimetype === 'image/jpeg' && $metadata = @exif_read_data(
             media_path($this->file_path),
             null,
diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php
index 4553b1d3f9..1b859e2cc2 100644
--- a/app/Entities/Podcast.php
+++ b/app/Entities/Podcast.php
@@ -202,7 +202,6 @@ class Podcast extends Entity
                 ->getActorById($this->actor_id);
         }
 
-        // @phpstan-ignore-next-line
         return $this->actor;
     }
 
@@ -517,11 +516,12 @@ class Podcast extends Entity
     }
 
     /**
-     * @return int[]
+     * @return int[]|string[]
      */
     public function getOtherCategoriesIds(): array
     {
         if ($this->other_categories_ids === null) {
+            // @phpstan-ignore-next-line
             $this->other_categories_ids = array_column($this->getOtherCategories(), 'id');
         }
 
@@ -586,7 +586,7 @@ class Podcast extends Entity
             'elements' => $this->custom_rss,
         ], $xmlNode);
 
-        return str_replace(['<channel>', '</channel>'], '', $xmlNode->asXML());
+        return (string) str_replace(['<channel>', '</channel>'], '', $xmlNode->asXML());
     }
 
     /**
diff --git a/app/Helpers/auth_helper.php b/app/Helpers/auth_helper.php
index e31df3352d..3c1bc815d1 100644
--- a/app/Helpers/auth_helper.php
+++ b/app/Helpers/auth_helper.php
@@ -9,7 +9,6 @@ declare(strict_types=1);
  */
 
 use App\Models\ActorModel;
-use CodeIgniter\Database\Exceptions\DataException;
 use Modules\Auth\Entities\User;
 use Modules\Fediverse\Entities\Actor;
 
@@ -83,9 +82,6 @@ if (! function_exists('interact_as_actor')) {
 }
 
 if (! function_exists('can_user_interact')) {
-    /**
-     * @throws DataException
-     */
     function can_user_interact(): bool
     {
         return (bool) interact_as_actor();
diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php
index cb61ae4471..f17c71944b 100644
--- a/app/Helpers/components_helper.php
+++ b/app/Helpers/components_helper.php
@@ -84,6 +84,7 @@ if (! function_exists('data_table')) {
                 foreach ($columns as $column) {
                     $rowData[] = $column['cell']($row, ...$rest);
                 }
+
                 $table->addRow($rowData);
             }
         } else {
@@ -141,7 +142,6 @@ if (! function_exists('publication_button')) {
      */
     function publication_button(int $podcastId, int $episodeId, string $publicationStatus): string
     {
-        /** @phpstan-ignore-next-line */
         switch ($publicationStatus) {
             case 'not_published':
                 $label = lang('Episode.publish');
diff --git a/app/Helpers/media_helper.php b/app/Helpers/media_helper.php
index 5ca25bf1b6..598559cdc8 100644
--- a/app/Helpers/media_helper.php
+++ b/app/Helpers/media_helper.php
@@ -92,6 +92,7 @@ if (! function_exists('download_file')) {
         return new File($tmpFilePath);
     }
 }
+
 if (! function_exists('media_path')) {
     /**
      * Prefixes the root media path to a given uri
@@ -104,6 +105,7 @@ if (! function_exists('media_path')) {
         if (is_array($uri)) {
             $uri = implode('/', $uri);
         }
+
         $uri = trim($uri, '/');
 
         return config('App')->mediaRoot . '/' . $uri;
@@ -122,6 +124,7 @@ if (! function_exists('media_base_url')) {
         if (is_array($uri)) {
             $uri = implode('/', $uri);
         }
+
         $uri = trim($uri, '/');
 
         $appConfig = config('App');
diff --git a/app/Helpers/misc_helper.php b/app/Helpers/misc_helper.php
index 727d53b631..bc3b66d9ee 100644
--- a/app/Helpers/misc_helper.php
+++ b/app/Helpers/misc_helper.php
@@ -151,14 +151,17 @@ if (! function_exists('format_duration')) {
         if ($seconds < 60) {
             return '0:' . sprintf('%02d', $seconds);
         }
+
         if ($seconds < 3600) {
             // < 1 hour: returns MM:SS
             return ltrim(gmdate('i:s', $seconds), '0');
         }
+
         if ($seconds < 36000) {
             // < 10 hours: returns H:MM:SS
             return ltrim(gmdate('H:i:s', $seconds), '0');
         }
+
         return gmdate('H:i:s', $seconds);
     }
 }
@@ -177,14 +180,17 @@ if (! function_exists('format_duration_symbol')) {
         if ($seconds < 60) {
             return $seconds . 's';
         }
+
         if ($seconds < 3600) {
             // < 1 hour: returns MM:SS
             return ltrim(gmdate('i\m\i\n s\s', $seconds), '0');
         }
+
         if ($seconds < 36000) {
             // < 10 hours: returns H:MM:SS
             return ltrim(gmdate('h\h i\m\i\n s\s', $seconds), '0');
         }
+
         return gmdate('h\h i\m\i\n s\s', $seconds);
     }
 }
@@ -232,6 +238,7 @@ if (! function_exists('file_upload_max_size')) {
                 $max_size = $upload_max;
             }
         }
+
         return $max_size;
     }
 }
diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php
index d9b8e17974..6359256b44 100644
--- a/app/Helpers/rss_helper.php
+++ b/app/Helpers/rss_helper.php
@@ -68,10 +68,12 @@ if (! function_exists('get_rss_feed')) {
             if ($podcast->location->geo !== null) {
                 $locationElement->addAttribute('geo', $podcast->location->geo);
             }
+
             if ($podcast->location->osm !== null) {
                 $locationElement->addAttribute('osm', $podcast->location->osm);
             }
         }
+
         if ($podcast->payment_pointer !== null) {
             $valueElement = $channel->addChild('value', null, $podcastNamespace);
             $valueElement->addAttribute('type', 'webmonetization');
@@ -83,6 +85,7 @@ if (! function_exists('get_rss_feed')) {
             $recipientElement->addAttribute('address', $podcast->payment_pointer);
             $recipientElement->addAttribute('split', '100');
         }
+
         $channel
             ->addChild('locked', $podcast->is_locked ? 'yes' : 'no', $podcastNamespace)
             ->addAttribute('owner', $podcast->owner_email);
@@ -96,6 +99,7 @@ if (! function_exists('get_rss_feed')) {
             if ($podcastingPlatform->account_id !== null) {
                 $podcastingPlatformElement->addAttribute('id', $podcastingPlatform->account_id);
             }
+
             if ($podcastingPlatform->link_url !== null) {
                 $podcastingPlatformElement->addAttribute('url', htmlspecialchars($podcastingPlatform->link_url));
             }
@@ -242,6 +246,7 @@ if (! function_exists('get_rss_feed')) {
         if ($podcast->is_blocked) {
             $channel->addChild('block', 'Yes', $itunesNamespace);
         }
+
         if ($podcast->is_completed) {
             $channel->addChild('complete', 'Yes', $itunesNamespace);
         }
@@ -283,10 +288,12 @@ if (! function_exists('get_rss_feed')) {
                 if ($episode->location->geo !== null) {
                     $locationElement->addAttribute('geo', $episode->location->geo);
                 }
+
                 if ($episode->location->osm !== null) {
                     $locationElement->addAttribute('osm', $episode->location->osm);
                 }
             }
+
             $item->addChildWithCDATA('description', $episode->getDescriptionHtml($serviceSlug));
             $item->addChild('duration', (string) $episode->audio->duration, $itunesNamespace);
             $item->addChild('link', $episode->link);
@@ -420,6 +427,7 @@ if (! function_exists('add_category_tag')) {
             $itunesCategoryChild->addAttribute('text', $category->apple_category);
             $node->addChild('category', $category->parent->apple_category);
         }
+
         $node->addChild('category', $category->apple_category);
     }
 }
@@ -445,10 +453,12 @@ if (! function_exists('rss_to_array')) {
         foreach ($rssNode->attributes() as $key => $value) {
             $arrayNode['attributes'][$key] = (string) $value;
         }
+
         $textcontent = trim((string) $rssNode);
         if (strlen($textcontent) > 0) {
             $arrayNode['content'] = $textcontent;
         }
+
         foreach ($nameSpaces as $currentNameSpace) {
             foreach ($rssNode->children($currentNameSpace) as $childXmlNode) {
                 $arrayNode['elements'][] = rss_to_array($childXmlNode);
@@ -485,6 +495,7 @@ if (! function_exists('array_to_rss')) {
                         $childXmlNode->addAttribute($attributeKey, $attributeValue);
                     }
                 }
+
                 array_to_rss($childArrayNode, $childXmlNode);
             }
         }
diff --git a/app/Helpers/seo_helper.php b/app/Helpers/seo_helper.php
index dc6bbe8497..436c64d426 100644
--- a/app/Helpers/seo_helper.php
+++ b/app/Helpers/seo_helper.php
@@ -25,6 +25,7 @@ if (! function_exists('get_podcast_metatags')) {
         if ($podcast->category->parent_id !== null) {
             $category .= $podcast->category->parent->apple_category . ' › ';
         }
+
         $category .= $podcast->category->apple_category;
 
         $schema = new Schema(
diff --git a/app/Helpers/svg_helper.php b/app/Helpers/svg_helper.php
index 64d4ea4e14..ffd5e5c705 100644
--- a/app/Helpers/svg_helper.php
+++ b/app/Helpers/svg_helper.php
@@ -55,6 +55,7 @@ if (! function_exists('svg')) {
         if ($class) {
             $svgContents = str_replace('<svg', '<svg class="' . $class . '"', $svgContents);
         }
+
         return $svgContents;
     }
 }
diff --git a/app/Libraries/MediaClipper/VideoClipper.php b/app/Libraries/MediaClipper/VideoClipper.php
index 11c8d2ddd2..e4c06367ea 100644
--- a/app/Libraries/MediaClipper/VideoClipper.php
+++ b/app/Libraries/MediaClipper/VideoClipper.php
@@ -17,8 +17,6 @@ use GdImage;
 /**
  * TODO: refactor this by splitting process modules into different classes (image generation, subtitles clip, video
  * generation)
- *
- * @phpstan-ignore-next-line
  */
 class VideoClipper
 {
@@ -299,7 +297,7 @@ class VideoClipper
     {
         $background = $this->generateBackground($this->dimensions['width'], $this->dimensions['height']);
 
-        if ($background === null) {
+        if (! $background instanceof \GdImage) {
             return false;
         }
 
@@ -384,6 +382,7 @@ class VideoClipper
                 $this->dimensions['episodeNumbering']['paddingY'],
             );
         }
+
         $this->addParagraphToImage(
             $background,
             $this->dimensions['episodeTitle']['x'],
@@ -409,6 +408,7 @@ class VideoClipper
         if (! $cleanedQuotes) {
             return false;
         }
+
         imagefilter($cleanedQuotes, IMG_FILTER_CONTRAST, 255);
         imagefilter($cleanedQuotes, IMG_FILTER_COLORIZE, ...$this->colors['quotes']);
 
@@ -526,6 +526,7 @@ class VideoClipper
         if ($src === false) {
             return false;
         }
+
         imagecopy($src, $source, 0, 0, 0, 0, $corner, $corner);
         imagecopy($src, $source, $corner, 0, $ws - $corner, 0, $corner, $corner);
         imagecopy($src, $source, $corner, $corner, $ws - $corner, $hs - $corner, $corner, $corner);
@@ -577,6 +578,7 @@ class VideoClipper
         if ($dest === false) {
             return false;
         }
+
         imagealphablending($dest, false);
         imagefilledrectangle($dest, 0, 0, $s, $s, $alphacolor);
         imagecopyresampled($dest, $img, 0, 0, 0, 0, $s, $s, $ns, $ns);
@@ -652,7 +654,7 @@ class VideoClipper
      *
      * @return array<string, mixed>|false
      */
-    private function calculateTextBox(int $fontSize, int $fontAngle, string $fontFile, string $text): array | false
+    private function calculateTextBox(int $fontSize, int $fontAngle, string $fontFile, string $text): array|bool
     {
         /************
         simple function that calculates the *exact* bounding box (single pixel precision).
@@ -664,6 +666,7 @@ class VideoClipper
         if (! $bbox) {
             return false;
         }
+
         $minX = min([$bbox[0], $bbox[2], $bbox[4], $bbox[6]]);
         $maxX = max([$bbox[0], $bbox[2], $bbox[4], $bbox[6]]);
         $minY = min([$bbox[1], $bbox[3], $bbox[5], $bbox[7]]);
@@ -755,7 +758,7 @@ class VideoClipper
         int $lineWidth,
         int $numberOfLines,
         int $paragraphIndent = 0,
-    ): array | false {
+    ): array|bool {
         // check length of text
         $bbox = $this->calculateTextBox($fontsize, 0, $fontPath, $text);
         if (! $bbox) {
@@ -783,6 +786,7 @@ class VideoClipper
             if (! $wordBox) {
                 return false;
             }
+
             $wordWidth = $wordBox['width'];
 
             if (($wordWidth + $length) > $lineWidth) {
@@ -791,6 +795,7 @@ class VideoClipper
                     $lines[$numberOfLines - 1] .= '…';
                     break;
                 }
+
                 $lines[$lineNumber] = '';
                 $length = 0;
 
diff --git a/app/Libraries/PodcastActor.php b/app/Libraries/PodcastActor.php
index a395a36f0d..61b188b53d 100644
--- a/app/Libraries/PodcastActor.php
+++ b/app/Libraries/PodcastActor.php
@@ -39,6 +39,7 @@ class PodcastActor extends ActorObject
         if ($podcast->category->parent_id !== null) {
             $category .= $podcast->category->parent->apple_category . ' › ';
         }
+
         $category .= $podcast->category->apple_category;
 
         $this->category = $category;
diff --git a/app/Libraries/Router.php b/app/Libraries/Router.php
index e693dbdd1f..37ba92c9bb 100644
--- a/app/Libraries/Router.php
+++ b/app/Libraries/Router.php
@@ -27,7 +27,6 @@ class Router extends CodeIgniterRouter
      * @param string $uri The URI path to compare against the routes
      *
      * @return boolean Whether the route was matched or not.
-     * @throws RedirectException
      */
     protected function checkRoutes(string $uri): bool
     {
@@ -75,6 +74,7 @@ class Router extends CodeIgniterRouter
                         $this->collection->getRedirectCode($key),
                     );
                 }
+
                 // Store our locale so CodeIgniter object can
                 // assign it to the Request.
                 if (isset($localeSegment)) {
@@ -135,6 +135,7 @@ class Router extends CodeIgniterRouter
                                     ][$available]['namespace'],
                                 );
                             }
+
                             $val =
                                 $this->collection->getDefaultNamespace() .
                                 $this->directory .
diff --git a/app/Libraries/SimpleRSSElement.php b/app/Libraries/SimpleRSSElement.php
index 30ae1103dc..5df1f9790a 100644
--- a/app/Libraries/SimpleRSSElement.php
+++ b/app/Libraries/SimpleRSSElement.php
@@ -24,7 +24,7 @@ class SimpleRSSElement extends SimpleXMLElement
      *
      * @return static The addChild method returns a SimpleXMLElement object representing the child added to the XML node.
      */
-    public function addChildWithCDATA(string $name, string $value = '', ?string $namespace = null)
+    public function addChildWithCDATA(string $name, string $value = '', ?string $namespace = null): static
     {
         $newChild = parent::addChild($name, '', $namespace);
 
@@ -52,7 +52,7 @@ class SimpleRSSElement extends SimpleXMLElement
      *
      * @return static The addChild method returns a SimpleXMLElement object representing the child added to the XML node.
      */
-    public function addChild($name, $value = null, $namespace = null, $escape = true)
+    public function addChild($name, $value = null, $namespace = null, $escape = true): static
     {
         $newChild = parent::addChild($name, '', $namespace);
 
@@ -64,9 +64,11 @@ class SimpleRSSElement extends SimpleXMLElement
                 if (! $no instanceof DOMDocument) {
                     return $newChild;
                 }
+
                 if (is_array($value)) {
                     return $newChild;
                 }
+
                 /** @noRector RecastingRemovalRector */
                 $node->appendChild($no->createTextNode((string) $value));
             }
diff --git a/app/Libraries/TranscriptParser.php b/app/Libraries/TranscriptParser.php
index 8e9335a6ba..c54fec4e9a 100644
--- a/app/Libraries/TranscriptParser.php
+++ b/app/Libraries/TranscriptParser.php
@@ -54,7 +54,6 @@ class TranscriptParser
 
         $lines = explode(PHP_EOL, $this->transcriptContent);
         foreach ($lines as $line) {
-            // @phpstan-ignore-next-line
             switch ($state) {
                 case SRT_STATE_SUBNUMBER:
                     $subNum = trim($line);
@@ -82,8 +81,10 @@ class TranscriptParser
                         if ($subText !== '') {
                             $subText .= PHP_EOL . $line;
                         }
+
                         $subText .= $line;
                     }
+
                     break;
 
             }
diff --git a/app/Libraries/View.php b/app/Libraries/View.php
index 4215dd1a41..1fbb09ecec 100644
--- a/app/Libraries/View.php
+++ b/app/Libraries/View.php
@@ -85,7 +85,6 @@ class View extends CodeIgniterView
         $renderVars = $this->renderVars;
 
         $output = (function (): string {
-            /** @phpstan-ignore-next-line */
             extract($this->tempData);
             ob_start();
             include $this->renderVars['file'];
diff --git a/app/Libraries/ViewComponents/ComponentRenderer.php b/app/Libraries/ViewComponents/ComponentRenderer.php
index 37a16eee1e..4d284420a0 100644
--- a/app/Libraries/ViewComponents/ComponentRenderer.php
+++ b/app/Libraries/ViewComponents/ComponentRenderer.php
@@ -228,10 +228,10 @@ class ComponentRenderer
         if (! file_exists($filePath)) {
             return null;
         }
+
         $className = service('locator')
             ->getClassname($filePath);
 
-        /** @phpstan-ignore-next-line */
         if (! class_exists($className)) {
             return null;
         }
@@ -247,7 +247,6 @@ class ComponentRenderer
     private function renderView(string $view, array $data): string
     {
         return (function (string $view, $data): string {
-            /** @phpstan-ignore-next-line */
             extract($data);
             ob_start();
             eval('?>' . file_get_contents($view));
diff --git a/app/Libraries/Vite/Vite.php b/app/Libraries/Vite/Vite.php
index a7192eed13..4f66a79199 100644
--- a/app/Libraries/Vite/Vite.php
+++ b/app/Libraries/Vite/Vite.php
@@ -52,6 +52,7 @@ class Vite
                         die("Could not load css manifest: <strong>{$manifestCSSPath}</strong> file not found!");
                     }
                 }
+
                 $this->manifestCSSData = $cachedManifestCSS;
             }
 
@@ -80,6 +81,7 @@ class Vite
                     die("Could not load manifest: <strong>{$manifestPath}</strong> file not found!");
                 }
             }
+
             $this->manifestData = $cachedManifest;
         }
 
diff --git a/app/Models/CategoryModel.php b/app/Models/CategoryModel.php
index e5ef3d9f9b..1e6b553928 100644
--- a/app/Models/CategoryModel.php
+++ b/app/Models/CategoryModel.php
@@ -69,6 +69,7 @@ class CategoryModel extends Model
                     if ($category->parent !== null) {
                         $result[$category->id] = lang('Podcast.category_options.' . $category->parent->code) . ' › ';
                     }
+
                     $result[$category->id] .= lang('Podcast.category_options.' . $category->code);
                     return $result;
                 },
diff --git a/app/Models/ClipModel.php b/app/Models/ClipModel.php
index 3fd4ca32fe..79cab11cdf 100644
--- a/app/Models/ClipModel.php
+++ b/app/Models/ClipModel.php
@@ -73,7 +73,6 @@ class ClipModel extends Model
         ConnectionInterface &$db = null,
         ValidationInterface $validation = null
     ) {
-        // @phpstan-ignore-next-line
         switch ($type) {
             case 'audio':
                 $this->returnType = Soundbite::class;
@@ -226,6 +225,7 @@ class ClipModel extends Model
             cache()
                 ->save($cacheName, $found, DECADE);
         }
+
         return $found;
     }
 
diff --git a/app/Models/EpisodeCommentModel.php b/app/Models/EpisodeCommentModel.php
index d54d096612..d3bb982c7d 100644
--- a/app/Models/EpisodeCommentModel.php
+++ b/app/Models/EpisodeCommentModel.php
@@ -200,6 +200,7 @@ class EpisodeCommentModel extends UuidModel
             $this->uuidUseBytes = false;
             return $this->updateBatch($commentsLikesCount, 'id');
         }
+
         return 0;
     }
 
diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php
index b0b716acea..3d2eb63825 100644
--- a/app/Models/EpisodeModel.php
+++ b/app/Models/EpisodeModel.php
@@ -215,6 +215,7 @@ class EpisodeModel extends Model
                 $where['YEAR(published_at)'] = $year;
                 $where['season_number'] = null;
             }
+
             if ($season) {
                 $where['season_number'] = $season;
             }
diff --git a/app/Models/MediaModel.php b/app/Models/MediaModel.php
index e56f60b753..0357eb675b 100644
--- a/app/Models/MediaModel.php
+++ b/app/Models/MediaModel.php
@@ -16,6 +16,7 @@ use App\Entities\Media\Document;
 use App\Entities\Media\Image;
 use App\Entities\Media\Transcript;
 use App\Entities\Media\Video;
+use CodeIgniter\Database\BaseResult;
 use CodeIgniter\Database\ConnectionInterface;
 use CodeIgniter\Model;
 use CodeIgniter\Validation\ValidationInterface;
@@ -88,7 +89,6 @@ class MediaModel extends Model
         ConnectionInterface &$db = null,
         ValidationInterface $validation = null
     ) {
-        // @phpstan-ignore-next-line
         switch ($fileType) {
             case 'audio':
                 $this->returnType = Audio::class;
@@ -113,7 +113,7 @@ class MediaModel extends Model
         parent::__construct($db, $validation);
     }
 
-    public function getMediaById(int $mediaId): Document | Audio | Video | Image | Transcript | Chapters
+    public function getMediaById(int $mediaId): mixed
     {
         $cacheName = "media#{$mediaId}";
         if (! ($found = cache($cacheName))) {
@@ -172,7 +172,7 @@ class MediaModel extends Model
         return $result;
     }
 
-    public function deleteMedia(object $media): bool
+    public function deleteMedia(object $media): bool|BaseResult
     {
         $media->deleteFile();
 
diff --git a/app/Models/PersonModel.php b/app/Models/PersonModel.php
index 6678906201..a01bb233e6 100644
--- a/app/Models/PersonModel.php
+++ b/app/Models/PersonModel.php
@@ -389,10 +389,12 @@ class PersonModel extends Model
                     ];
                 }
             }
+
             return $this->db->table('episodes_persons')
                 ->ignore(true)
                 ->insertBatch($data);
         }
+
         return 0;
     }
 
diff --git a/app/Models/PlatformModel.php b/app/Models/PlatformModel.php
index e58c7ab37e..990f4f5956 100644
--- a/app/Models/PlatformModel.php
+++ b/app/Models/PlatformModel.php
@@ -60,6 +60,7 @@ class PlatformModel extends Model
             cache()
                 ->save('platforms', $found, DECADE);
         }
+
         return $found;
     }
 
@@ -72,6 +73,7 @@ class PlatformModel extends Model
             cache()
                 ->save($cacheName, $found, DECADE);
         }
+
         return $found;
     }
 
diff --git a/app/Models/PodcastModel.php b/app/Models/PodcastModel.php
index 1c7e5db58a..aa2d018aa5 100644
--- a/app/Models/PodcastModel.php
+++ b/app/Models/PodcastModel.php
@@ -403,6 +403,7 @@ class PodcastModel extends Model
                     $secondsToNextUnpublishedEpisode ? $secondsToNextUnpublishedEpisode : DECADE
                 );
         }
+
         return $defaultQuery;
     }
 
@@ -504,6 +505,7 @@ class PodcastModel extends Model
                 (new ActorModel())->update($podcast->actor_id, $podcastActor);
             }
         }
+
         return $data;
     }
 
diff --git a/app/Views/Components/DropdownMenu.php b/app/Views/Components/DropdownMenu.php
index 7803b9fc63..be3cc412c8 100644
--- a/app/Views/Components/DropdownMenu.php
+++ b/app/Views/Components/DropdownMenu.php
@@ -11,6 +11,8 @@ class DropdownMenu extends Component
 {
     public string $id = '';
 
+    public string $labelledby;
+
     public string $placement = 'bottom-end';
 
     public string $offsetX = '0';
diff --git a/app/Views/Components/Forms/FormComponent.php b/app/Views/Components/Forms/FormComponent.php
index 251187efba..941f0814c1 100644
--- a/app/Views/Components/Forms/FormComponent.php
+++ b/app/Views/Components/Forms/FormComponent.php
@@ -18,7 +18,10 @@ class FormComponent extends Component
 
     protected bool $readonly = false;
 
-    public function __construct($attributes)
+    /**
+     * @param array<string, string> $attributes
+     */
+    public function __construct(array $attributes)
     {
         parent::__construct($attributes);
 
diff --git a/app/Views/Components/ReadMore.php b/app/Views/Components/ReadMore.php
index bf9685e896..016a60b35d 100644
--- a/app/Views/Components/ReadMore.php
+++ b/app/Views/Components/ReadMore.php
@@ -8,6 +8,8 @@ use ViewComponents\Component;
 
 class ReadMore extends Component
 {
+    public string $id;
+
     public function render(): string
     {
         $readMoreLabel = lang('Common.read_more');
diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php
index 8e16272f6c..b9c4941c1e 100644
--- a/app/Views/errors/cli/error_exception.php
+++ b/app/Views/errors/cli/error_exception.php
@@ -6,12 +6,13 @@ use CodeIgniter\CLI\CLI;
 
 // The main Exception
 CLI::newLine();
-CLI::write('[' . $exception::class . ']', 'light_gray', 'red');
+CLI::write('[' . get_class($exception) . ']', 'light_gray', 'red');
 CLI::newLine();
 CLI::write($message);
 CLI::newLine();
-CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green', ), );
+CLI::write('at ' . CLI::color(clean_path($exception->getFile()) . ':' . $exception->getLine(), 'green'));
 CLI::newLine();
+
 // The backtrace
 if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) {
     $backtraces = $exception->getTrace();
@@ -21,41 +22,42 @@ if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) {
     }
 
     foreach ($backtraces as $i => $error) {
-        $padFile = '    ';
-        $c = str_pad($i + 1, 3, ' ', STR_PAD_LEFT);
+        $padFile = '    '; // 4 spaces
+        $padClass = '       '; // 7 spaces
+        $c = str_pad((string) ($i + 1), 3, ' ', STR_PAD_LEFT);
 
         if (isset($error['file'])) {
             $filepath = clean_path($error['file']) . ':' . $error['line'];
 
             CLI::write($c . $padFile . CLI::color($filepath, 'yellow'));
         } else {
-            CLI::write($c . $padFile . CLI::color('[internal function]', 'yellow'), );
+            CLI::write($c . $padFile . CLI::color('[internal function]', 'yellow'));
         }
 
         $function = '';
 
         if (isset($error['class'])) {
-            $type =
-                $error['type'] === '->'
-                    ? '()' . $error['type']
-                    : $error['type'];
-            $function .=
-                $padClass . $error['class'] . $type . $error['function'];
+            $type = ($error['type'] === '->') ? '()' . $error['type'] : $error['type'];
+            $function .= $padClass . $error['class'] . $type . $error['function'];
         } elseif (! isset($error['class']) && isset($error['function'])) {
             $function .= $padClass . $error['function'];
         }
 
-        $args = implode(
-            ', ',
-            array_map(function ($value) {
-                return match (true) {
-                    is_object($value) => 'Object(' . $value::class . ')',
-                    is_array($value) => $value !== [] ? '[...]' : '[]',
-                    $value === null => 'null',
-                    default => var_export($value, true),
-                };
-            }, array_values($error['args'] ?? [])),
-        );
+        $args = implode(', ', array_map(static function ($value) {
+            switch (true) {
+                case is_object($value):
+                    return 'Object(' . get_class($value) . ')';
+
+                case is_array($value):
+                    return count($value) ? '[...]' : '[]';
+
+                case $value === null:
+                    return 'null'; // return the lowercased version
+
+                default:
+                    return var_export($value, true);
+            }
+        }, array_values($error['args'] ?? [])));
 
         $function .= '(' . $args . ')';
 
diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php
index f26f54b6c4..9e9e9a9af9 100644
--- a/app/Views/errors/html/error_exception.php
+++ b/app/Views/errors/html/error_exception.php
@@ -1,26 +1,21 @@
 <?php declare(strict_types=1);
 
-use CodeIgniter\CodeIgniter;
-use Config\Services;
-
-$errorId = uniqid('error', true); ?>
+$error_id = uniqid('error', true); ?>
 <!doctype html>
 <html>
-
 <head>
 	<meta charset="UTF-8">
 	<meta name="robots" content="noindex">
 
 	<title><?= esc($title) ?></title>
 	<style type="text/css">
-		<?= preg_replace('~[\r\n\t ]+~', ' ', file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.css')) ?>
+		<?= preg_replace('#[\r\n\t ]+#', ' ', file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.css')) ?>
 	</style>
 
 	<script type="text/javascript">
 		<?= file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug.js') ?>
 	</script>
 </head>
-
 <body onload="init()">
 
 	<!-- Header -->
@@ -29,7 +24,8 @@ $errorId = uniqid('error', true); ?>
 			<h1><?= esc($title), esc($exception->getCode() ? ' #' . $exception->getCode() : '') ?></h1>
 			<p>
 				<?= nl2br(esc($exception->getMessage())) ?>
-				<a href="https://www.duckduckgo.com/?q=<?= urlencode($title . ' ' . preg_replace('~\'.*\'|".*"~Us', '', $exception->getMessage())) ?>" rel="noreferrer" target="_blank">search &rarr;</a>
+				<a href="https://www.duckduckgo.com/?q=<?= urlencode($title . ' ' . preg_replace('#\'.*\'|".*"#Us', '', $exception->getMessage())) ?>"
+				   rel="noreferrer" target="_blank">search &rarr;</a>
 			</p>
 		</div>
 	</div>
@@ -38,7 +34,7 @@ $errorId = uniqid('error', true); ?>
 	<div class="container">
 		<p><b><?= esc(static::cleanPath($file, $line)) ?></b> at line <b><?= esc($line) ?></b></p>
 
-		<?php if (is_file($file)): ?>
+		<?php if (is_file($file)) : ?>
 			<div class="source">
 				<?= static::highlightFile($file, $line, 15); ?>
 			</div>
@@ -62,79 +58,79 @@ $errorId = uniqid('error', true); ?>
 			<div class="content" id="backtrace">
 
 				<ol class="trace">
-					<?php foreach ($trace as $index => $row): ?>
-
-						<li>
-							<p>
-								<!-- Trace info -->
-								<?php if (isset($row['file']) && is_file($row['file'])): ?>
-									<?php
-									if (isset($row['function']) && in_array($row['function'], ['include', 'include_once', 'require', 'require_once'], true)) {
-									    echo esc($row['function'] . ' ' . static::cleanPath($row['file']));
-									} else {
-									    echo esc(static::cleanPath($row['file']) . ' : ' . $row['line']);
-									}
-									?>
-								<?php else: ?>
-									{PHP internal code}
+				<?php foreach ($trace as $index => $row) : ?>
+
+					<li>
+						<p>
+							<!-- Trace info -->
+							<?php if (isset($row['file']) && is_file($row['file'])) :?>
+								<?php
+                                if (isset($row['function']) && in_array($row['function'], ['include', 'include_once', 'require', 'require_once'], true)) {
+                                    echo esc($row['function'] . ' ' . static::cleanPath($row['file']));
+                                } else {
+                                    echo esc(static::cleanPath($row['file']) . ' : ' . $row['line']);
+                                }
+                                ?>
+							<?php else : ?>
+								{PHP internal code}
+							<?php endif; ?>
+
+							<!-- Class/Method -->
+							<?php if (isset($row['class'])) : ?>
+								&nbsp;&nbsp;&mdash;&nbsp;&nbsp;<?= esc($row['class'] . $row['type'] . $row['function']) ?>
+								<?php if (! empty($row['args'])) : ?>
+									<?php $args_id = $error_id . 'args' . $index ?>
+									( <a href="#" onclick="return toggle('<?= esc($args_id, 'attr') ?>');">arguments</a> )
+									<div class="args" id="<?= esc($args_id, 'attr') ?>">
+										<table cellspacing="0">
+
+										<?php
+                                        $params = null;
+                                        // Reflection by name is not available for closure function
+                                        if (substr($row['function'], -1) !== '}') {
+                                            $mirror = isset($row['class']) ? new \ReflectionMethod($row['class'], $row['function']) : new \ReflectionFunction($row['function']);
+                                            $params = $mirror->getParameters();
+                                        }
+
+                                        foreach ($row['args'] as $key => $value) : ?>
+											<tr>
+												<td><code><?= esc(isset($params[$key]) ? '$' . $params[$key]->name : "#{$key}") ?></code></td>
+												<td><pre><?= esc(print_r($value, true)) ?></pre></td>
+											</tr>
+										<?php endforeach ?>
+
+										</table>
+									</div>
+								<?php else : ?>
+									()
 								<?php endif; ?>
+							<?php endif; ?>
+
+							<?php if (! isset($row['class']) && isset($row['function'])) : ?>
+								&nbsp;&nbsp;&mdash;&nbsp;&nbsp;	<?= esc($row['function']) ?>()
+							<?php endif; ?>
+						</p>
 
-								<!-- Class/Method -->
-								<?php if (isset($row['class'])) : ?>
-									&nbsp;&nbsp;&mdash;&nbsp;&nbsp;<?= esc($row['class'] . $row['type'] . $row['function']) ?>
-									<?php if (! empty($row['args'])) : ?>
-										<?php $args_id = $errorId . 'args' . $index ?>
-										( <a href="#" onclick="return toggle('<?= esc($args_id, 'attr') ?>');">arguments</a> )
-							<div class="args" id="<?= esc($args_id, 'attr') ?>">
-								<table cellspacing="0">
-
-									<?php
-										$params = null;
-										// Reflection by name is not available for closure function
-										if (! str_ends_with($row['function'], '}')) {
-										    $mirror = isset($row['class']) ? new ReflectionMethod($row['class'], $row['function']) : new ReflectionFunction($row['function']);
-										    $params = $mirror->getParameters();
-										}
-										foreach ($row['args'] as $key => $value): ?>
-										<tr>
-											<td><code><?= esc(isset($params[$key]) ? '$' . $params[$key]->name : "#{$key}") ?></code></td>
-											<td>
-												<pre><?= esc(print_r($value, true)) ?></pre>
-											</td>
-										</tr>
-									<?php endforeach; ?>
-
-								</table>
+						<!-- Source? -->
+						<?php if (isset($row['file']) && is_file($row['file']) && isset($row['class'])) : ?>
+							<div class="source">
+								<?= static::highlightFile($row['file'], $row['line']) ?>
 							</div>
-						<?php else: ?>
-							()
 						<?php endif; ?>
-					<?php endif; ?>
-
-					<?php if (! isset($row['class']) && isset($row['function'])): ?>
-						&nbsp;&nbsp;&mdash;&nbsp;&nbsp; <?= esc($row['function']) ?>()
-					<?php endif; ?>
-					</p>
-
-					<!-- Source? -->
-					<?php if (isset($row['file']) && is_file($row['file']) && isset($row['class'])): ?>
-						<div class="source">
-							<?= static::highlightFile($row['file'], $row['line']) ?>
-						</div>
-					<?php endif; ?>
-						</li>
-
-					<?php endforeach; ?>
+					</li>
+
+				<?php endforeach; ?>
 				</ol>
 
 			</div>
 
 			<!-- Server -->
 			<div class="content" id="server">
-				<?php foreach (['_SERVER', '_SESSION'] as $var): ?>
-					<?php if (empty($GLOBALS[$var]) || ! is_array($GLOBALS[$var])) {
-										    continue;
-										} ?>
+				<?php foreach (['_SERVER', '_SESSION'] as $var) : ?>
+					<?php
+                    if (empty($GLOBALS[$var]) || ! is_array($GLOBALS[$var])) {
+                        continue;
+                    } ?>
 
 					<h3>$<?= esc($var) ?></h3>
 
@@ -146,26 +142,26 @@ $errorId = uniqid('error', true); ?>
 							</tr>
 						</thead>
 						<tbody>
-							<?php foreach ($GLOBALS[$var] as $key => $value): ?>
-								<tr>
-									<td><?= esc($key) ?></td>
-									<td>
-										<?php if (is_string($value)): ?>
-											<?= esc($value) ?>
-										<?php else: ?>
-											<pre><?= esc(print_r($value, true)) ?></pre>
-										<?php endif; ?>
-									</td>
-								</tr>
-							<?php endforeach; ?>
+						<?php foreach ($GLOBALS[$var] as $key => $value) : ?>
+							<tr>
+								<td><?= esc($key) ?></td>
+								<td>
+									<?php if (is_string($value)) : ?>
+										<?= esc($value) ?>
+									<?php else: ?>
+										<pre><?= esc(print_r($value, true)) ?></pre>
+									<?php endif; ?>
+								</td>
+							</tr>
+						<?php endforeach; ?>
 						</tbody>
 					</table>
 
-				<?php endforeach; ?>
+				<?php endforeach ?>
 
 				<!-- Constants -->
 				<?php $constants = get_defined_constants(true); ?>
-				<?php if (! empty($constants['user'])): ?>
+				<?php if (! empty($constants['user'])) : ?>
 					<h3>Constants</h3>
 
 					<table>
@@ -176,18 +172,18 @@ $errorId = uniqid('error', true); ?>
 							</tr>
 						</thead>
 						<tbody>
-							<?php foreach ($constants['user'] as $key => $value): ?>
-								<tr>
-									<td><?= esc($key) ?></td>
-									<td>
-										<?php if (is_string($value)): ?>
-											<?= esc($value) ?>
-										<?php else: ?>
-											<pre><?= esc(print_r($value, true)) ?></pre>
-										<?php endif; ?>
-									</td>
-								</tr>
-							<?php endforeach; ?>
+						<?php foreach ($constants['user'] as $key => $value) : ?>
+							<tr>
+								<td><?= esc($key) ?></td>
+								<td>
+									<?php if (is_string($value)) : ?>
+										<?= esc($value) ?>
+									<?php else: ?>
+										<pre><?= esc(print_r($value, true)) ?></pre>
+									<?php endif; ?>
+								</td>
+							</tr>
+						<?php endforeach; ?>
 						</tbody>
 					</table>
 				<?php endif; ?>
@@ -195,7 +191,7 @@ $errorId = uniqid('error', true); ?>
 
 			<!-- Request -->
 			<div class="content" id="request">
-				<?php $request = Services::request(); ?>
+				<?php $request = \Config\Services::request(); ?>
 
 				<table>
 					<tbody>
@@ -233,10 +229,11 @@ $errorId = uniqid('error', true); ?>
 
 
 				<?php $empty = true; ?>
-				<?php foreach (['_GET', '_POST', '_COOKIE'] as $var): ?>
-					<?php if (empty($GLOBALS[$var]) || ! is_array($GLOBALS[$var])) {
-										    continue;
-										} ?>
+				<?php foreach (['_GET', '_POST', '_COOKIE'] as $var) : ?>
+					<?php
+                    if (empty($GLOBALS[$var]) || ! is_array($GLOBALS[$var])) {
+                        continue;
+                    } ?>
 
 					<?php $empty = false; ?>
 
@@ -250,24 +247,24 @@ $errorId = uniqid('error', true); ?>
 							</tr>
 						</thead>
 						<tbody>
-							<?php foreach ($GLOBALS[$var] as $key => $value): ?>
-								<tr>
-									<td><?= esc($key) ?></td>
-									<td>
-										<?php if (is_string($value)): ?>
-											<?= esc($value) ?>
-										<?php else: ?>
-											<pre><?= esc(print_r($value, true)) ?></pre>
-										<?php endif; ?>
-									</td>
-								</tr>
-							<?php endforeach; ?>
+						<?php foreach ($GLOBALS[$var] as $key => $value) : ?>
+							<tr>
+								<td><?= esc($key) ?></td>
+								<td>
+									<?php if (is_string($value)) : ?>
+										<?= esc($value) ?>
+									<?php else: ?>
+										<pre><?= esc(print_r($value, true)) ?></pre>
+									<?php endif; ?>
+								</td>
+							</tr>
+						<?php endforeach; ?>
 						</tbody>
 					</table>
 
-				<?php endforeach; ?>
+				<?php endforeach ?>
 
-				<?php if ($empty): ?>
+				<?php if ($empty) : ?>
 
 					<div class="alert">
 						No $_GET, $_POST, or $_COOKIE Information to show.
@@ -276,7 +273,7 @@ $errorId = uniqid('error', true); ?>
 				<?php endif; ?>
 
 				<?php $headers = $request->getHeaders(); ?>
-				<?php if (! empty($headers)): ?>
+				<?php if (! empty($headers)) : ?>
 
 					<h3>Headers</h3>
 
@@ -288,20 +285,22 @@ $errorId = uniqid('error', true); ?>
 							</tr>
 						</thead>
 						<tbody>
-							<?php foreach ($headers as $value): ?>
-								<?php if (empty($value)) {
-										    continue;
-										} ?>
-								<?php if (! is_array($value)) {
-										    $value = [$value];
-										} ?>
-								<?php foreach ($value as $h) : ?>
-									<tr>
-										<td><?= esc($h->getName(), 'html') ?></td>
-										<td><?= esc($h->getValueLine(), 'html') ?></td>
-									</tr>
-								<?php endforeach; ?>
+						<?php foreach ($headers as $value) : ?>
+							<?php
+                            if (empty($value)) {
+                                continue;
+                            }
+
+                            if (! is_array($value)) {
+                                $value = [$value];
+                            } ?>
+							<?php foreach ($value as $h) : ?>
+								<tr>
+									<td><?= esc($h->getName(), 'html') ?></td>
+									<td><?= esc($h->getValueLine(), 'html') ?></td>
+								</tr>
 							<?php endforeach; ?>
+						<?php endforeach; ?>
 						</tbody>
 					</table>
 
@@ -310,9 +309,9 @@ $errorId = uniqid('error', true); ?>
 
 			<!-- Response -->
 			<?php
-			$response = Services::response();
-			$response->setStatusCode(http_response_code());
-			?>
+                $response = \Config\Services::response();
+                $response->setStatusCode(http_response_code());
+            ?>
 			<div class="content" id="response">
 				<table>
 					<tr>
@@ -322,8 +321,8 @@ $errorId = uniqid('error', true); ?>
 				</table>
 
 				<?php $headers = $response->getHeaders(); ?>
-				<?php if ($headers !== []): ?>
-					<?php natsort($headers); ?>
+				<?php if (! empty($headers)) : ?>
+					<?php natsort($headers) ?>
 
 					<h3>Headers</h3>
 
@@ -335,12 +334,12 @@ $errorId = uniqid('error', true); ?>
 							</tr>
 						</thead>
 						<tbody>
-							<?php foreach (array_keys($headers) as $name): ?>
-								<tr>
-									<td><?= esc($name, 'html') ?></td>
-									<td><?= esc($response->getHeaderLine($name), 'html') ?></td>
-								</tr>
-							<?php endforeach; ?>
+						<?php foreach ($headers as $name => $value) : ?>
+							<tr>
+								<td><?= esc($name, 'html') ?></td>
+								<td><?= esc($response->getHeaderLine($name), 'html') ?></td>
+							</tr>
+						<?php endforeach; ?>
 						</tbody>
 					</table>
 
@@ -352,9 +351,9 @@ $errorId = uniqid('error', true); ?>
 				<?php $files = get_included_files(); ?>
 
 				<ol>
-					<?php foreach ($files as $file): ?>
-						<li><?= esc(static::cleanPath($file)) ?></li>
-					<?php endforeach; ?>
+				<?php foreach ($files as $file) :?>
+					<li><?= esc(static::cleanPath($file)) ?></li>
+				<?php endforeach ?>
 				</ol>
 			</div>
 
@@ -389,13 +388,12 @@ $errorId = uniqid('error', true); ?>
 
 			<p>
 				Displayed at <?= esc(date('H:i:sa')) ?> &mdash;
-				PHP: <?= esc(PHP_VERSION) ?> &mdash;
-				CodeIgniter: <?= esc(CodeIgniter::CI_VERSION) ?>
+				PHP: <?= esc(PHP_VERSION) ?>  &mdash;
+				CodeIgniter: <?= esc(\CodeIgniter\CodeIgniter::CI_VERSION) ?>
 			</p>
 
 		</div>
 	</div>
 
 </body>
-
 </html>
diff --git a/composer.json b/composer.json
index bec69002e9..48c49f71ef 100644
--- a/composer.json
+++ b/composer.json
@@ -7,11 +7,11 @@
   "license": "AGPL-3.0-or-later",
   "require": {
     "php": "^8.0",
+    "codeigniter4/framework": "^4",
     "james-heinrich/getid3": "^2.0.x-dev",
     "whichbrowser/parser": "^v2.1.1",
-    "geoip2/geoip2": "^v2.11.0",
+    "geoip2/geoip2": "^v2.12.2",
     "myth/auth": "dev-develop",
-    "codeigniter4/codeigniter4": "dev-develop",
     "league/commonmark": "^2.2",
     "vlucas/phpdotenv": "^v5.3.0",
     "league/html-to-markdown": "^v5.0.1",
@@ -21,21 +21,18 @@
     "phpseclib/phpseclib": "~2.0.30",
     "michalsn/codeigniter4-uuid": "dev-develop",
     "essence/essence": "^3.5.4",
-    "codeigniter4/settings": "dev-develop",
+    "codeigniter4/settings": "^v1.0",
     "chrisjean/php-ico": "^1.0",
     "melbahja/seo": "^2.0"
   },
   "require-dev": {
-    "mikey179/vfsstream": "^v1.6.8",
-    "phpunit/phpunit": "^9.5.4",
-    "rector/rector": "^0.11.5",
-    "captainhook/captainhook": "^5.10.0",
-    "phpstan/phpstan": "^0.12.85",
-    "phpstan/extension-installer": "^1.1.0",
-    "rector/rector-phpstan-rules": "^0.2.9",
-    "symplify/phpstan-extensions": "^v9.3.12",
-    "symplify/easy-coding-standard": "^v9.3.12",
-    "symplify/coding-standard": "^v9.3.12"
+    "mikey179/vfsstream": "v1.6.10",
+    "phpunit/phpunit": "^9.5.16",
+    "captainhook/captainhook": "^5.10.7",
+    "symplify/easy-coding-standard": "^10.1",
+    "phpstan/phpstan": "^1.4",
+    "rector/rector": "^0.12.16",
+    "symplify/coding-standard": "^10.1"
   },
   "autoload": {
     "psr-4": {
@@ -80,14 +77,7 @@
     "source": "https://code.castopod.org/adaures/castopod.git",
     "discord": "https://castopod.org/discord"
   },
-  "minimum-stability": "dev",
   "prefer-stable": true,
-  "repositories": [
-    {
-      "type": "vcs",
-      "url": "https://github.com/codeigniter4/codeigniter4"
-    }
-  ],
   "config": {
     "allow-plugins": {
       "phpstan/extension-installer": true
diff --git a/composer.lock b/composer.lock
index 6b1d37352e..aa1b0a3771 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
     "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
     "This file is @generated automatically"
   ],
-  "content-hash": "597109bb66c8ddbe5f80bcfd8ceb523b",
+  "content-hash": "add27ad337cf2e046fb9d4d7a249ef70",
   "packages": [
     {
       "name": "adaures/ipcat-php",
@@ -75,16 +75,16 @@
     },
     {
       "name": "brick/math",
-      "version": "0.9.2",
+      "version": "0.9.3",
       "source": {
         "type": "git",
         "url": "https://github.com/brick/math.git",
-        "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0"
+        "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/brick/math/zipball/dff976c2f3487d42c1db75a3b180e2b9f0e72ce0",
-        "reference": "dff976c2f3487d42c1db75a3b180e2b9f0e72ce0",
+        "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae",
+        "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae",
         "shasum": ""
       },
       "require": {
@@ -94,7 +94,7 @@
       "require-dev": {
         "php-coveralls/php-coveralls": "^2.2",
         "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0",
-        "vimeo/psalm": "4.3.2"
+        "vimeo/psalm": "4.9.2"
       },
       "type": "library",
       "autoload": {
@@ -117,15 +117,19 @@
       ],
       "support": {
         "issues": "https://github.com/brick/math/issues",
-        "source": "https://github.com/brick/math/tree/0.9.2"
+        "source": "https://github.com/brick/math/tree/0.9.3"
       },
       "funding": [
+        {
+          "url": "https://github.com/BenMorel",
+          "type": "github"
+        },
         {
           "url": "https://tidelift.com/funding/github/packagist/brick/math",
           "type": "tidelift"
         }
       ],
-      "time": "2021-01-20T22:51:39+00:00"
+      "time": "2021-08-15T20:50:18+00:00"
     },
     {
       "name": "chrisjean/php-ico",
@@ -168,17 +172,17 @@
       "time": "2016-09-27T22:00:56+00:00"
     },
     {
-      "name": "codeigniter4/codeigniter4",
-      "version": "dev-develop",
+      "name": "codeigniter4/framework",
+      "version": "v4.1.9",
       "source": {
         "type": "git",
-        "url": "https://github.com/codeigniter4/CodeIgniter4.git",
-        "reference": "8449d13724d460a4e5573f49027cd9f862449a29"
+        "url": "https://github.com/codeigniter4/framework.git",
+        "reference": "4ec623a6b8269dd09f570ab514e5864276bb7f56"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/codeigniter4/CodeIgniter4/zipball/8449d13724d460a4e5573f49027cd9f862449a29",
-        "reference": "8449d13724d460a4e5573f49027cd9f862449a29",
+        "url": "https://api.github.com/repos/codeigniter4/framework/zipball/4ec623a6b8269dd09f570ab514e5864276bb7f56",
+        "reference": "4ec623a6b8269dd09f570ab514e5864276bb7f56",
         "shasum": ""
       },
       "require": {
@@ -197,74 +201,42 @@
         "friendsofphp/php-cs-fixer": "^3.1",
         "mikey179/vfsstream": "^1.6",
         "nexusphp/cs-config": "^3.3",
-        "nexusphp/tachycardia": "^1.0",
-        "phpstan/phpstan": "^1.0",
         "phpunit/phpunit": "^9.1",
-        "predis/predis": "^1.1",
-        "rector/rector": "0.12.11"
+        "predis/predis": "^1.1"
       },
       "suggest": {
         "ext-fileinfo": "Improves mime type detection for files"
       },
-      "default-branch": true,
       "type": "project",
-      "extra": {
-        "branch-alias": {
-          "dev-develop": "4.x-dev"
-        }
-      },
       "autoload": {
         "psr-4": {
           "CodeIgniter\\": "system/"
         },
         "exclude-from-classmap": ["**/Database/Migrations/**"]
       },
-      "autoload-dev": {
-        "psr-4": {
-          "CodeIgniter\\": "tests/system/",
-          "CodeIgniter\\AutoReview\\": "tests/AutoReview/",
-          "Utils\\": "utils/"
-        }
-      },
-      "scripts": {
-        "post-update-cmd": [
-          "CodeIgniter\\ComposerScripts::postUpdate",
-          "bash -c \"if [ -f admin/setup.sh ]; then bash admin/setup.sh; fi\""
-        ],
-        "analyze": ["phpstan analyse"],
-        "test": ["phpunit"],
-        "cs": [
-          "php-cs-fixer fix --verbose --dry-run --diff --config=.no-header.php-cs-fixer.dist.php",
-          "php-cs-fixer fix --verbose --dry-run --diff"
-        ],
-        "cs-fix": [
-          "php-cs-fixer fix --verbose --diff --config=.no-header.php-cs-fixer.dist.php",
-          "php-cs-fixer fix --verbose --diff"
-        ]
-      },
+      "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
       "description": "The CodeIgniter framework v4",
       "homepage": "https://codeigniter.com",
       "support": {
         "forum": "http://forum.codeigniter.com/",
-        "source": "https://github.com/codeigniter4/CodeIgniter4",
         "slack": "https://codeigniterchat.slack.com",
-        "issues": "https://github.com/codeigniter4/CodeIgniter4/issues"
+        "source": "https://github.com/codeigniter4/CodeIgniter4"
       },
-      "time": "2022-01-10T01:36:11+00:00"
+      "time": "2022-02-26T00:51:52+00:00"
     },
     {
       "name": "codeigniter4/settings",
-      "version": "dev-develop",
+      "version": "v1.0.0",
       "source": {
         "type": "git",
         "url": "https://github.com/codeigniter4/settings.git",
-        "reference": "5d758e5e0a3f9dda9f66303d82ccfbb82e979577"
+        "reference": "01a38cf971fa11292b7893a0cf2c497bfcaaf33c"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/codeigniter4/settings/zipball/5d758e5e0a3f9dda9f66303d82ccfbb82e979577",
-        "reference": "5d758e5e0a3f9dda9f66303d82ccfbb82e979577",
+        "url": "https://api.github.com/repos/codeigniter4/settings/zipball/01a38cf971fa11292b7893a0cf2c497bfcaaf33c",
+        "reference": "01a38cf971fa11292b7893a0cf2c497bfcaaf33c",
         "shasum": ""
       },
       "require": {
@@ -276,11 +248,10 @@
         "mockery/mockery": "^1.0",
         "nexusphp/tachycardia": "^1.0",
         "php-coveralls/php-coveralls": "^2.4",
-        "phpstan/phpstan": "^0.12",
+        "phpstan/phpstan": "^0.12 || ^1.0",
         "phpunit/phpunit": "^9.0",
         "squizlabs/php_codesniffer": "^3.3"
       },
-      "default-branch": true,
       "type": "library",
       "autoload": {
         "psr-4": {
@@ -302,22 +273,22 @@
       "keywords": ["Settings", "codeigniter", "codeigniter4"],
       "support": {
         "issues": "https://github.com/codeigniter4/settings/issues",
-        "source": "https://github.com/codeigniter4/settings/tree/develop"
+        "source": "https://github.com/codeigniter4/settings/tree/v1.0.0"
       },
-      "time": "2021-08-16T05:07:59+00:00"
+      "time": "2021-11-09T04:54:23+00:00"
     },
     {
       "name": "composer/ca-bundle",
-      "version": "1.2.10",
+      "version": "1.3.1",
       "source": {
         "type": "git",
         "url": "https://github.com/composer/ca-bundle.git",
-        "reference": "9fdb22c2e97a614657716178093cd1da90a64aa8"
+        "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/composer/ca-bundle/zipball/9fdb22c2e97a614657716178093cd1da90a64aa8",
-        "reference": "9fdb22c2e97a614657716178093cd1da90a64aa8",
+        "url": "https://api.github.com/repos/composer/ca-bundle/zipball/4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b",
+        "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b",
         "shasum": ""
       },
       "require": {
@@ -329,7 +300,7 @@
         "phpstan/phpstan": "^0.12.55",
         "psr/log": "^1.0",
         "symfony/phpunit-bridge": "^4.2 || ^5",
-        "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
+        "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
       },
       "type": "library",
       "extra": {
@@ -356,7 +327,7 @@
       "support": {
         "irc": "irc://irc.freenode.org/composer",
         "issues": "https://github.com/composer/ca-bundle/issues",
-        "source": "https://github.com/composer/ca-bundle/tree/1.2.10"
+        "source": "https://github.com/composer/ca-bundle/tree/1.3.1"
       },
       "funding": [
         {
@@ -372,7 +343,7 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-06-07T13:58:28+00:00"
+      "time": "2021-10-28T20:44:15+00:00"
     },
     {
       "name": "dflydev/dot-access-data",
@@ -618,16 +589,16 @@
     },
     {
       "name": "geoip2/geoip2",
-      "version": "v2.11.0",
+      "version": "v2.12.2",
       "source": {
         "type": "git",
         "url": "https://github.com/maxmind/GeoIP2-php.git",
-        "reference": "d01be5894a5c1a3381c58c9b1795cd07f96c30f7"
+        "reference": "83adb44ac4b9553d36b579a14673ed124583082f"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/d01be5894a5c1a3381c58c9b1795cd07f96c30f7",
-        "reference": "d01be5894a5c1a3381c58c9b1795cd07f96c30f7",
+        "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/83adb44ac4b9553d36b579a14673ed124583082f",
+        "reference": "83adb44ac4b9553d36b579a14673ed124583082f",
         "shasum": ""
       },
       "require": {
@@ -637,7 +608,8 @@
         "php": ">=7.2"
       },
       "require-dev": {
-        "friendsofphp/php-cs-fixer": "2.*",
+        "friendsofphp/php-cs-fixer": "3.*",
+        "phpstan/phpstan": "*",
         "phpunit/phpunit": "^8.0 || ^9.0",
         "squizlabs/php_codesniffer": "3.*"
       },
@@ -661,37 +633,32 @@
       "keywords": ["IP", "geoip", "geoip2", "geolocation", "maxmind"],
       "support": {
         "issues": "https://github.com/maxmind/GeoIP2-php/issues",
-        "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.11.0"
+        "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.12.2"
       },
-      "time": "2020-10-01T18:48:34+00:00"
+      "time": "2021-11-30T18:15:25+00:00"
     },
     {
       "name": "graham-campbell/result-type",
-      "version": "v1.0.1",
+      "version": "v1.0.4",
       "source": {
         "type": "git",
         "url": "https://github.com/GrahamCampbell/Result-Type.git",
-        "reference": "7e279d2cd5d7fbb156ce46daada972355cea27bb"
+        "reference": "0690bde05318336c7221785f2a932467f98b64ca"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/7e279d2cd5d7fbb156ce46daada972355cea27bb",
-        "reference": "7e279d2cd5d7fbb156ce46daada972355cea27bb",
+        "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca",
+        "reference": "0690bde05318336c7221785f2a932467f98b64ca",
         "shasum": ""
       },
       "require": {
-        "php": "^7.0|^8.0",
-        "phpoption/phpoption": "^1.7.3"
+        "php": "^7.0 || ^8.0",
+        "phpoption/phpoption": "^1.8"
       },
       "require-dev": {
-        "phpunit/phpunit": "^6.5|^7.5|^8.5|^9.0"
+        "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
       },
       "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-master": "1.0-dev"
-        }
-      },
       "autoload": {
         "psr-4": {
           "GrahamCampbell\\ResultType\\": "src/"
@@ -702,7 +669,8 @@
       "authors": [
         {
           "name": "Graham Campbell",
-          "email": "graham@alt-three.com"
+          "email": "hello@gjcampbell.co.uk",
+          "homepage": "https://github.com/GrahamCampbell"
         }
       ],
       "description": "An Implementation Of The Result Type",
@@ -715,7 +683,7 @@
       ],
       "support": {
         "issues": "https://github.com/GrahamCampbell/Result-Type/issues",
-        "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.1"
+        "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4"
       },
       "funding": [
         {
@@ -727,7 +695,7 @@
           "type": "tidelift"
         }
       ],
-      "time": "2020-04-13T13:17:36+00:00"
+      "time": "2021-11-21T21:41:47+00:00"
     },
     {
       "name": "james-heinrich/getid3",
@@ -805,16 +773,16 @@
     },
     {
       "name": "kint-php/kint",
-      "version": "4.1.1",
+      "version": "4.1.2",
       "source": {
         "type": "git",
         "url": "https://github.com/kint-php/kint.git",
-        "reference": "e64b939f9ceb9620abd982e2a66a3289fcf4e837"
+        "reference": "fa53c4333cda79dc9cb002cfa029abe994d0ae00"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/kint-php/kint/zipball/e64b939f9ceb9620abd982e2a66a3289fcf4e837",
-        "reference": "e64b939f9ceb9620abd982e2a66a3289fcf4e837",
+        "url": "https://api.github.com/repos/kint-php/kint/zipball/fa53c4333cda79dc9cb002cfa029abe994d0ae00",
+        "reference": "fa53c4333cda79dc9cb002cfa029abe994d0ae00",
         "shasum": ""
       },
       "require": {
@@ -829,6 +797,7 @@
         "vimeo/psalm": "^4.0"
       },
       "suggest": {
+        "kint-php/kint-helpers": "Provides extra helper functions",
         "kint-php/kint-twig": "Provides d() and s() functions in twig templates"
       },
       "type": "library",
@@ -855,9 +824,9 @@
       "keywords": ["debug", "kint", "php"],
       "support": {
         "issues": "https://github.com/kint-php/kint/issues",
-        "source": "https://github.com/kint-php/kint/tree/4.1.1"
+        "source": "https://github.com/kint-php/kint/tree/4.1.2"
       },
-      "time": "2022-01-02T10:30:48+00:00"
+      "time": "2022-02-22T20:32:24+00:00"
     },
     {
       "name": "laminas/laminas-escaper",
@@ -918,16 +887,16 @@
     },
     {
       "name": "league/commonmark",
-      "version": "2.2.1",
+      "version": "2.2.3",
       "source": {
         "type": "git",
         "url": "https://github.com/thephpleague/commonmark.git",
-        "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a"
+        "reference": "47b015bc4e50fd4438c1ffef6139a1fb65d2ab71"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a",
-        "reference": "f8afb78f087777b040e0ab8a6b6ca93f6fc3f18a",
+        "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/47b015bc4e50fd4438c1ffef6139a1fb65d2ab71",
+        "reference": "47b015bc4e50fd4438c1ffef6139a1fb65d2ab71",
         "shasum": ""
       },
       "require": {
@@ -1016,7 +985,7 @@
           "type": "tidelift"
         }
       ],
-      "time": "2022-01-25T14:37:33+00:00"
+      "time": "2022-02-26T21:24:45+00:00"
     },
     {
       "name": "league/config",
@@ -1100,16 +1069,16 @@
     },
     {
       "name": "league/html-to-markdown",
-      "version": "5.0.1",
+      "version": "5.0.2",
       "source": {
         "type": "git",
         "url": "https://github.com/thephpleague/html-to-markdown.git",
-        "reference": "e5600a2c5ce7b7571b16732c7086940f56f7abec"
+        "reference": "4d0394e120dc14b0d5c52fd1755fd48656da2ec9"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/e5600a2c5ce7b7571b16732c7086940f56f7abec",
-        "reference": "e5600a2c5ce7b7571b16732c7086940f56f7abec",
+        "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/4d0394e120dc14b0d5c52fd1755fd48656da2ec9",
+        "reference": "4d0394e120dc14b0d5c52fd1755fd48656da2ec9",
         "shasum": ""
       },
       "require": {
@@ -1158,7 +1127,7 @@
       "keywords": ["html", "markdown"],
       "support": {
         "issues": "https://github.com/thephpleague/html-to-markdown/issues",
-        "source": "https://github.com/thephpleague/html-to-markdown/tree/5.0.1"
+        "source": "https://github.com/thephpleague/html-to-markdown/tree/5.0.2"
       },
       "funding": [
         {
@@ -1178,20 +1147,20 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-09-17T20:00:27+00:00"
+      "time": "2021-11-06T05:38:26+00:00"
     },
     {
       "name": "maxmind-db/reader",
-      "version": "v1.10.1",
+      "version": "v1.11.0",
       "source": {
         "type": "git",
         "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
-        "reference": "569bd44d97d30a4ec12c7793a33004a76d4caf18"
+        "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/569bd44d97d30a4ec12c7793a33004a76d4caf18",
-        "reference": "569bd44d97d30a4ec12c7793a33004a76d4caf18",
+        "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b1f3c0699525336d09cc5161a2861268d9f2ae5b",
+        "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b",
         "shasum": ""
       },
       "require": {
@@ -1201,7 +1170,7 @@
         "ext-maxminddb": "<1.10.1,>=2.0.0"
       },
       "require-dev": {
-        "friendsofphp/php-cs-fixer": "*",
+        "friendsofphp/php-cs-fixer": "3.*",
         "php-coveralls/php-coveralls": "^2.1",
         "phpstan/phpstan": "*",
         "phpunit/phpcov": ">=6.0.0",
@@ -1233,9 +1202,9 @@
       "keywords": ["database", "geoip", "geoip2", "geolocation", "maxmind"],
       "support": {
         "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
-        "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.10.1"
+        "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.11.0"
       },
-      "time": "2021-04-14T17:49:35+00:00"
+      "time": "2021-10-18T15:23:10+00:00"
     },
     {
       "name": "maxmind/web-service-common",
@@ -1396,12 +1365,12 @@
       "source": {
         "type": "git",
         "url": "https://github.com/lonnieezell/myth-auth.git",
-        "reference": "9bba52bd710a0c35a0b2d8cef64a70706224648a"
+        "reference": "e84d0660cd42bbe84077613e141d5acf683020cd"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/lonnieezell/myth-auth/zipball/9bba52bd710a0c35a0b2d8cef64a70706224648a",
-        "reference": "9bba52bd710a0c35a0b2d8cef64a70706224648a",
+        "url": "https://api.github.com/repos/lonnieezell/myth-auth/zipball/e84d0660cd42bbe84077613e141d5acf683020cd",
+        "reference": "e84d0660cd42bbe84077613e141d5acf683020cd",
         "shasum": ""
       },
       "require": {
@@ -1414,10 +1383,13 @@
         "codeigniter4/codeigniter4": "dev-develop",
         "codeigniter4/codeigniter4-standard": "^1.0",
         "fakerphp/faker": "^1.9",
+        "friendsofphp/php-cs-fixer": "^3.0",
         "mockery/mockery": "^1.0",
+        "nexusphp/cs-config": "^3.1",
+        "nexusphp/tachycardia": "^1.0",
+        "php-coveralls/php-coveralls": "^2.4",
         "phpstan/phpstan": "^0.12",
-        "phpunit/phpunit": "^9.2",
-        "squizlabs/php_codesniffer": "^3.5"
+        "phpunit/phpunit": "^9.2"
       },
       "default-branch": true,
       "type": "library",
@@ -1442,19 +1414,23 @@
       "keywords": ["Authentication", "authorization", "codeigniter"],
       "support": {
         "issues": "https://github.com/lonnieezell/myth-auth/issues",
-        "source": "https://github.com/lonnieezell/myth-auth/tree/v1.0"
+        "source": "https://github.com/lonnieezell/myth-auth/tree/develop"
       },
       "funding": [
         {
           "url": "https://github.com/lonnieezell",
           "type": "github"
         },
+        {
+          "url": "https://github.com/mgatner",
+          "type": "github"
+        },
         {
           "url": "https://www.patreon.com/lonnieezell",
           "type": "patreon"
         }
       ],
-      "time": "2021-06-10T04:25:01+00:00"
+      "time": "2021-12-10T20:09:56+00:00"
     },
     {
       "name": "nette/schema",
@@ -1511,27 +1487,27 @@
     },
     {
       "name": "nette/utils",
-      "version": "v3.2.2",
+      "version": "v3.2.7",
       "source": {
         "type": "git",
         "url": "https://github.com/nette/utils.git",
-        "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c"
+        "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/nette/utils/zipball/967cfc4f9a1acd5f1058d76715a424c53343c20c",
-        "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c",
+        "url": "https://api.github.com/repos/nette/utils/zipball/0af4e3de4df9f1543534beab255ccf459e7a2c99",
+        "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2 <8.1"
+        "php": ">=7.2 <8.2"
       },
       "conflict": {
         "nette/di": "<3.0.6"
       },
       "require-dev": {
         "nette/tester": "~2.0",
-        "phpstan/phpstan": "^0.12",
+        "phpstan/phpstan": "^1.0",
         "tracy/tracy": "^2.3"
       },
       "suggest": {
@@ -1584,9 +1560,9 @@
       ],
       "support": {
         "issues": "https://github.com/nette/utils/issues",
-        "source": "https://github.com/nette/utils/tree/v3.2.2"
+        "source": "https://github.com/nette/utils/tree/v3.2.7"
       },
-      "time": "2021-03-03T22:53:25+00:00"
+      "time": "2022-01-24T11:29:14+00:00"
     },
     {
       "name": "opawg/user-agents-php",
@@ -1626,29 +1602,29 @@
     },
     {
       "name": "phpoption/phpoption",
-      "version": "1.7.5",
+      "version": "1.8.1",
       "source": {
         "type": "git",
         "url": "https://github.com/schmittjoh/php-option.git",
-        "reference": "994ecccd8f3283ecf5ac33254543eb0ac946d525"
+        "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/994ecccd8f3283ecf5ac33254543eb0ac946d525",
-        "reference": "994ecccd8f3283ecf5ac33254543eb0ac946d525",
+        "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15",
+        "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15",
         "shasum": ""
       },
       "require": {
-        "php": "^5.5.9 || ^7.0 || ^8.0"
+        "php": "^7.0 || ^8.0"
       },
       "require-dev": {
         "bamarni/composer-bin-plugin": "^1.4.1",
-        "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0 || ^8.0 || ^9.0"
+        "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
       },
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-master": "1.7-dev"
+          "dev-master": "1.8-dev"
         }
       },
       "autoload": {
@@ -1661,18 +1637,20 @@
       "authors": [
         {
           "name": "Johannes M. Schmitt",
-          "email": "schmittjoh@gmail.com"
+          "email": "schmittjoh@gmail.com",
+          "homepage": "https://github.com/schmittjoh"
         },
         {
           "name": "Graham Campbell",
-          "email": "graham@alt-three.com"
+          "email": "hello@gjcampbell.co.uk",
+          "homepage": "https://github.com/GrahamCampbell"
         }
       ],
       "description": "Option Type for PHP",
       "keywords": ["language", "option", "php", "type"],
       "support": {
         "issues": "https://github.com/schmittjoh/php-option/issues",
-        "source": "https://github.com/schmittjoh/php-option/tree/1.7.5"
+        "source": "https://github.com/schmittjoh/php-option/tree/1.8.1"
       },
       "funding": [
         {
@@ -1684,20 +1662,20 @@
           "type": "tidelift"
         }
       ],
-      "time": "2020-07-20T17:29:33+00:00"
+      "time": "2021-12-04T23:24:31+00:00"
     },
     {
       "name": "phpseclib/phpseclib",
-      "version": "2.0.31",
+      "version": "2.0.36",
       "source": {
         "type": "git",
         "url": "https://github.com/phpseclib/phpseclib.git",
-        "reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4"
+        "reference": "a97547126396548c224703a267a30af1592be146"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/233a920cb38636a43b18d428f9a8db1f0a1a08f4",
-        "reference": "233a920cb38636a43b18d428f9a8db1f0a1a08f4",
+        "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/a97547126396548c224703a267a30af1592be146",
+        "reference": "a97547126396548c224703a267a30af1592be146",
         "shasum": ""
       },
       "require": {
@@ -1773,7 +1751,7 @@
       ],
       "support": {
         "issues": "https://github.com/phpseclib/phpseclib/issues",
-        "source": "https://github.com/phpseclib/phpseclib/tree/2.0.31"
+        "source": "https://github.com/phpseclib/phpseclib/tree/2.0.36"
       },
       "funding": [
         {
@@ -1789,7 +1767,7 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-04-06T13:56:45+00:00"
+      "time": "2022-01-30T08:48:36+00:00"
     },
     {
       "name": "psr/cache",
@@ -1924,20 +1902,21 @@
     },
     {
       "name": "ramsey/collection",
-      "version": "1.1.3",
+      "version": "1.2.2",
       "source": {
         "type": "git",
         "url": "https://github.com/ramsey/collection.git",
-        "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1"
+        "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1",
-        "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1",
+        "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a",
+        "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a",
         "shasum": ""
       },
       "require": {
-        "php": "^7.2 || ^8"
+        "php": "^7.3 || ^8",
+        "symfony/polyfill-php81": "^1.23"
       },
       "require-dev": {
         "captainhook/captainhook": "^5.3",
@@ -1947,6 +1926,7 @@
         "hamcrest/hamcrest-php": "^2",
         "jangregor/phpstan-prophecy": "^0.8",
         "mockery/mockery": "^1.3",
+        "phpspec/prophecy-phpunit": "^2.0",
         "phpstan/extension-installer": "^1",
         "phpstan/phpstan": "^0.12.32",
         "phpstan/phpstan-mockery": "^0.12.5",
@@ -1972,11 +1952,11 @@
           "homepage": "https://benramsey.com"
         }
       ],
-      "description": "A PHP 7.2+ library for representing and manipulating collections.",
+      "description": "A PHP library for representing and manipulating collections.",
       "keywords": ["array", "collection", "hash", "map", "queue", "set"],
       "support": {
         "issues": "https://github.com/ramsey/collection/issues",
-        "source": "https://github.com/ramsey/collection/tree/1.1.3"
+        "source": "https://github.com/ramsey/collection/tree/1.2.2"
       },
       "funding": [
         {
@@ -1988,53 +1968,54 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-01-21T17:40:04+00:00"
+      "time": "2021-10-10T03:01:02+00:00"
     },
     {
       "name": "ramsey/uuid",
-      "version": "4.1.1",
+      "version": "4.2.3",
       "source": {
         "type": "git",
         "url": "https://github.com/ramsey/uuid.git",
-        "reference": "cd4032040a750077205918c86049aa0f43d22947"
+        "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947",
-        "reference": "cd4032040a750077205918c86049aa0f43d22947",
+        "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df",
+        "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df",
         "shasum": ""
       },
       "require": {
         "brick/math": "^0.8 || ^0.9",
         "ext-json": "*",
-        "php": "^7.2 || ^8",
+        "php": "^7.2 || ^8.0",
         "ramsey/collection": "^1.0",
-        "symfony/polyfill-ctype": "^1.8"
+        "symfony/polyfill-ctype": "^1.8",
+        "symfony/polyfill-php80": "^1.14"
       },
       "replace": {
         "rhumsaa/uuid": "self.version"
       },
       "require-dev": {
-        "codeception/aspect-mock": "^3",
-        "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0",
+        "captainhook/captainhook": "^5.10",
+        "captainhook/plugin-composer": "^5.3",
+        "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
         "doctrine/annotations": "^1.8",
-        "goaop/framework": "^2",
+        "ergebnis/composer-normalize": "^2.15",
         "mockery/mockery": "^1.3",
         "moontoast/math": "^1.1",
         "paragonie/random-lib": "^2",
+        "php-mock/php-mock": "^2.2",
         "php-mock/php-mock-mockery": "^1.3",
-        "php-mock/php-mock-phpunit": "^2.5",
         "php-parallel-lint/php-parallel-lint": "^1.1",
-        "phpbench/phpbench": "^0.17.1",
+        "phpbench/phpbench": "^1.0",
         "phpstan/extension-installer": "^1.0",
         "phpstan/phpstan": "^0.12",
         "phpstan/phpstan-mockery": "^0.12",
         "phpstan/phpstan-phpunit": "^0.12",
-        "phpunit/phpunit": "^8.5",
-        "psy/psysh": "^0.10.0",
-        "slevomat/coding-standard": "^6.0",
+        "phpunit/phpunit": "^8.5 || ^9",
+        "slevomat/coding-standard": "^7.0",
         "squizlabs/php_codesniffer": "^3.5",
-        "vimeo/psalm": "3.9.4"
+        "vimeo/psalm": "^4.9"
       },
       "suggest": {
         "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
@@ -2047,7 +2028,10 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-master": "4.x-dev"
+          "dev-main": "4.x-dev"
+        },
+        "captainhook": {
+          "force-install": true
         }
       },
       "autoload": {
@@ -2059,42 +2043,44 @@
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
       "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).",
-      "homepage": "https://github.com/ramsey/uuid",
       "keywords": ["guid", "identifier", "uuid"],
       "support": {
         "issues": "https://github.com/ramsey/uuid/issues",
-        "rss": "https://github.com/ramsey/uuid/releases.atom",
-        "source": "https://github.com/ramsey/uuid"
+        "source": "https://github.com/ramsey/uuid/tree/4.2.3"
       },
       "funding": [
         {
           "url": "https://github.com/ramsey",
           "type": "github"
+        },
+        {
+          "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
+          "type": "tidelift"
         }
       ],
-      "time": "2020-08-18T17:17:46+00:00"
+      "time": "2021-09-25T23:10:38+00:00"
     },
     {
       "name": "symfony/deprecation-contracts",
-      "version": "v2.4.0",
+      "version": "v3.0.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/deprecation-contracts.git",
-        "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
+        "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
-        "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
+        "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced",
+        "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.1"
+        "php": ">=8.0.2"
       },
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "2.4-dev"
+          "dev-main": "3.0-dev"
         },
         "thanks": {
           "name": "symfony/contracts",
@@ -2119,7 +2105,7 @@
       "description": "A generic function and convention to trigger deprecation notices",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
+        "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0"
       },
       "funding": [
         {
@@ -2135,25 +2121,28 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-03-23T23:28:01+00:00"
+      "time": "2021-11-01T23:48:49+00:00"
     },
     {
       "name": "symfony/polyfill-ctype",
-      "version": "v1.23.0",
+      "version": "v1.24.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/polyfill-ctype.git",
-        "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+        "reference": "30885182c981ab175d4d034db0f6f469898070ab"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
-        "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+        "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
+        "reference": "30885182c981ab175d4d034db0f6f469898070ab",
         "shasum": ""
       },
       "require": {
         "php": ">=7.1"
       },
+      "provide": {
+        "ext-ctype": "*"
+      },
       "suggest": {
         "ext-ctype": "For best performance"
       },
@@ -2168,10 +2157,10 @@
         }
       },
       "autoload": {
+        "files": ["bootstrap.php"],
         "psr-4": {
           "Symfony\\Polyfill\\Ctype\\": ""
-        },
-        "files": ["bootstrap.php"]
+        }
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
@@ -2189,7 +2178,7 @@
       "homepage": "https://symfony.com",
       "keywords": ["compatibility", "ctype", "polyfill", "portable"],
       "support": {
-        "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
+        "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
       },
       "funding": [
         {
@@ -2205,25 +2194,28 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-02-19T12:13:01+00:00"
+      "time": "2021-10-20T20:35:02+00:00"
     },
     {
       "name": "symfony/polyfill-mbstring",
-      "version": "v1.23.0",
+      "version": "v1.24.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/polyfill-mbstring.git",
-        "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1"
+        "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
-        "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
+        "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
+        "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
         "shasum": ""
       },
       "require": {
         "php": ">=7.1"
       },
+      "provide": {
+        "ext-mbstring": "*"
+      },
       "suggest": {
         "ext-mbstring": "For best performance"
       },
@@ -2238,10 +2230,10 @@
         }
       },
       "autoload": {
+        "files": ["bootstrap.php"],
         "psr-4": {
           "Symfony\\Polyfill\\Mbstring\\": ""
-        },
-        "files": ["bootstrap.php"]
+        }
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
@@ -2259,7 +2251,7 @@
       "homepage": "https://symfony.com",
       "keywords": ["compatibility", "mbstring", "polyfill", "portable", "shim"],
       "support": {
-        "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0"
+        "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
       },
       "funding": [
         {
@@ -2275,20 +2267,20 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-27T09:27:20+00:00"
+      "time": "2021-11-30T18:21:41+00:00"
     },
     {
       "name": "symfony/polyfill-php80",
-      "version": "v1.23.0",
+      "version": "v1.24.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/polyfill-php80.git",
-        "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
+        "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
-        "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
+        "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
+        "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
         "shasum": ""
       },
       "require": {
@@ -2305,10 +2297,10 @@
         }
       },
       "autoload": {
+        "files": ["bootstrap.php"],
         "psr-4": {
           "Symfony\\Polyfill\\Php80\\": ""
         },
-        "files": ["bootstrap.php"],
         "classmap": ["Resources/stubs"]
       },
       "notification-url": "https://packagist.org/downloads/",
@@ -2331,7 +2323,7 @@
       "homepage": "https://symfony.com",
       "keywords": ["compatibility", "polyfill", "portable", "shim"],
       "support": {
-        "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.0"
+        "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
       },
       "funding": [
         {
@@ -2347,35 +2339,103 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-02-19T12:13:01+00:00"
+      "time": "2021-09-13T13:58:33+00:00"
+    },
+    {
+      "name": "symfony/polyfill-php81",
+      "version": "v1.24.0",
+      "source": {
+        "type": "git",
+        "url": "https://github.com/symfony/polyfill-php81.git",
+        "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"
+      },
+      "dist": {
+        "type": "zip",
+        "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
+        "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
+        "shasum": ""
+      },
+      "require": {
+        "php": ">=7.1"
+      },
+      "type": "library",
+      "extra": {
+        "branch-alias": {
+          "dev-main": "1.23-dev"
+        },
+        "thanks": {
+          "name": "symfony/polyfill",
+          "url": "https://github.com/symfony/polyfill"
+        }
+      },
+      "autoload": {
+        "files": ["bootstrap.php"],
+        "psr-4": {
+          "Symfony\\Polyfill\\Php81\\": ""
+        },
+        "classmap": ["Resources/stubs"]
+      },
+      "notification-url": "https://packagist.org/downloads/",
+      "license": ["MIT"],
+      "authors": [
+        {
+          "name": "Nicolas Grekas",
+          "email": "p@tchwork.com"
+        },
+        {
+          "name": "Symfony Community",
+          "homepage": "https://symfony.com/contributors"
+        }
+      ],
+      "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+      "homepage": "https://symfony.com",
+      "keywords": ["compatibility", "polyfill", "portable", "shim"],
+      "support": {
+        "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0"
+      },
+      "funding": [
+        {
+          "url": "https://symfony.com/sponsor",
+          "type": "custom"
+        },
+        {
+          "url": "https://github.com/fabpot",
+          "type": "github"
+        },
+        {
+          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+          "type": "tidelift"
+        }
+      ],
+      "time": "2021-09-13T13:58:11+00:00"
     },
     {
       "name": "vlucas/phpdotenv",
-      "version": "v5.3.0",
+      "version": "v5.4.1",
       "source": {
         "type": "git",
         "url": "https://github.com/vlucas/phpdotenv.git",
-        "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56"
+        "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/b3eac5c7ac896e52deab4a99068e3f4ab12d9e56",
-        "reference": "b3eac5c7ac896e52deab4a99068e3f4ab12d9e56",
+        "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f",
+        "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f",
         "shasum": ""
       },
       "require": {
         "ext-pcre": "*",
-        "graham-campbell/result-type": "^1.0.1",
+        "graham-campbell/result-type": "^1.0.2",
         "php": "^7.1.3 || ^8.0",
-        "phpoption/phpoption": "^1.7.4",
-        "symfony/polyfill-ctype": "^1.17",
-        "symfony/polyfill-mbstring": "^1.17",
-        "symfony/polyfill-php80": "^1.17"
+        "phpoption/phpoption": "^1.8",
+        "symfony/polyfill-ctype": "^1.23",
+        "symfony/polyfill-mbstring": "^1.23.1",
+        "symfony/polyfill-php80": "^1.23.1"
       },
       "require-dev": {
         "bamarni/composer-bin-plugin": "^1.4.1",
         "ext-filter": "*",
-        "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5.1"
+        "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10"
       },
       "suggest": {
         "ext-filter": "Required to use the boolean validator."
@@ -2383,7 +2443,7 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-master": "5.3-dev"
+          "dev-master": "5.4-dev"
         }
       },
       "autoload": {
@@ -2396,20 +2456,20 @@
       "authors": [
         {
           "name": "Graham Campbell",
-          "email": "graham@alt-three.com",
-          "homepage": "https://gjcampbell.co.uk/"
+          "email": "hello@gjcampbell.co.uk",
+          "homepage": "https://github.com/GrahamCampbell"
         },
         {
           "name": "Vance Lucas",
           "email": "vance@vancelucas.com",
-          "homepage": "https://vancelucas.com/"
+          "homepage": "https://github.com/vlucas"
         }
       ],
       "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
       "keywords": ["dotenv", "env", "environment"],
       "support": {
         "issues": "https://github.com/vlucas/phpdotenv/issues",
-        "source": "https://github.com/vlucas/phpdotenv/tree/v5.3.0"
+        "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1"
       },
       "funding": [
         {
@@ -2421,7 +2481,7 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-01-20T15:23:13+00:00"
+      "time": "2021-12-12T23:22:04+00:00"
     },
     {
       "name": "whichbrowser/parser",
@@ -2481,16 +2541,16 @@
   "packages-dev": [
     {
       "name": "captainhook/captainhook",
-      "version": "5.10.1",
+      "version": "5.10.7",
       "source": {
         "type": "git",
         "url": "https://github.com/captainhookphp/captainhook.git",
-        "reference": "03f31d3c6bdec50c831381f27ecad48c73840726"
+        "reference": "be731c609e6669c5d4dbf9bf8efbb18188f0d288"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/captainhookphp/captainhook/zipball/03f31d3c6bdec50c831381f27ecad48c73840726",
-        "reference": "03f31d3c6bdec50c831381f27ecad48c73840726",
+        "url": "https://api.github.com/repos/captainhookphp/captainhook/zipball/be731c609e6669c5d4dbf9bf8efbb18188f0d288",
+        "reference": "be731c609e6669c5d4dbf9bf8efbb18188f0d288",
         "shasum": ""
       },
       "require": {
@@ -2500,16 +2560,16 @@
         "php": ">=7.2",
         "sebastianfeldmann/camino": "^0.9.2",
         "sebastianfeldmann/cli": "^3.3",
-        "sebastianfeldmann/git": "^3.7",
-        "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0",
-        "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0",
-        "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0"
+        "sebastianfeldmann/git": "^3.8.1",
+        "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
+        "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0",
+        "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
       },
       "replace": {
         "sebastianfeldmann/captainhook": "*"
       },
       "require-dev": {
-        "composer/composer": "~1",
+        "composer/composer": "~1 || ^2.0",
         "mikey179/vfsstream": "~1"
       },
       "bin": ["bin/captainhook"],
@@ -2548,7 +2608,7 @@
       ],
       "support": {
         "issues": "https://github.com/captainhookphp/captainhook/issues",
-        "source": "https://github.com/captainhookphp/captainhook/tree/5.10.1"
+        "source": "https://github.com/captainhookphp/captainhook/tree/5.10.7"
       },
       "funding": [
         {
@@ -2556,27 +2616,91 @@
           "type": "github"
         }
       ],
-      "time": "2021-05-25T21:21:59+00:00"
+      "time": "2022-02-21T19:53:55+00:00"
+    },
+    {
+      "name": "composer/pcre",
+      "version": "3.0.0",
+      "source": {
+        "type": "git",
+        "url": "https://github.com/composer/pcre.git",
+        "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd"
+      },
+      "dist": {
+        "type": "zip",
+        "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd",
+        "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd",
+        "shasum": ""
+      },
+      "require": {
+        "php": "^7.4 || ^8.0"
+      },
+      "require-dev": {
+        "phpstan/phpstan": "^1.3",
+        "phpstan/phpstan-strict-rules": "^1.1",
+        "symfony/phpunit-bridge": "^5"
+      },
+      "type": "library",
+      "extra": {
+        "branch-alias": {
+          "dev-main": "3.x-dev"
+        }
+      },
+      "autoload": {
+        "psr-4": {
+          "Composer\\Pcre\\": "src"
+        }
+      },
+      "notification-url": "https://packagist.org/downloads/",
+      "license": ["MIT"],
+      "authors": [
+        {
+          "name": "Jordi Boggiano",
+          "email": "j.boggiano@seld.be",
+          "homepage": "http://seld.be"
+        }
+      ],
+      "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
+      "keywords": ["PCRE", "preg", "regex", "regular expression"],
+      "support": {
+        "issues": "https://github.com/composer/pcre/issues",
+        "source": "https://github.com/composer/pcre/tree/3.0.0"
+      },
+      "funding": [
+        {
+          "url": "https://packagist.com",
+          "type": "custom"
+        },
+        {
+          "url": "https://github.com/composer",
+          "type": "github"
+        },
+        {
+          "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+          "type": "tidelift"
+        }
+      ],
+      "time": "2022-02-25T20:21:48+00:00"
     },
     {
       "name": "composer/semver",
-      "version": "3.2.5",
+      "version": "3.2.9",
       "source": {
         "type": "git",
         "url": "https://github.com/composer/semver.git",
-        "reference": "31f3ea725711245195f62e54ffa402d8ef2fdba9"
+        "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/composer/semver/zipball/31f3ea725711245195f62e54ffa402d8ef2fdba9",
-        "reference": "31f3ea725711245195f62e54ffa402d8ef2fdba9",
+        "url": "https://api.github.com/repos/composer/semver/zipball/a951f614bd64dcd26137bc9b7b2637ddcfc57649",
+        "reference": "a951f614bd64dcd26137bc9b7b2637ddcfc57649",
         "shasum": ""
       },
       "require": {
         "php": "^5.3.2 || ^7.0 || ^8.0"
       },
       "require-dev": {
-        "phpstan/phpstan": "^0.12.54",
+        "phpstan/phpstan": "^1.4",
         "symfony/phpunit-bridge": "^4.2 || ^5"
       },
       "type": "library",
@@ -2614,7 +2738,7 @@
       "support": {
         "irc": "irc://irc.freenode.org/composer",
         "issues": "https://github.com/composer/semver/issues",
-        "source": "https://github.com/composer/semver/tree/3.2.5"
+        "source": "https://github.com/composer/semver/tree/3.2.9"
       },
       "funding": [
         {
@@ -2630,29 +2754,31 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-24T12:41:47+00:00"
+      "time": "2022-02-04T13:58:43+00:00"
     },
     {
       "name": "composer/xdebug-handler",
-      "version": "2.0.1",
+      "version": "3.0.3",
       "source": {
         "type": "git",
         "url": "https://github.com/composer/xdebug-handler.git",
-        "reference": "964adcdd3a28bf9ed5d9ac6450064e0d71ed7496"
+        "reference": "ced299686f41dce890debac69273b47ffe98a40c"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/964adcdd3a28bf9ed5d9ac6450064e0d71ed7496",
-        "reference": "964adcdd3a28bf9ed5d9ac6450064e0d71ed7496",
+        "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
+        "reference": "ced299686f41dce890debac69273b47ffe98a40c",
         "shasum": ""
       },
       "require": {
-        "php": "^5.3.2 || ^7.0 || ^8.0",
-        "psr/log": "^1.0"
+        "composer/pcre": "^1 || ^2 || ^3",
+        "php": "^7.2.5 || ^8.0",
+        "psr/log": "^1 || ^2 || ^3"
       },
       "require-dev": {
-        "phpstan/phpstan": "^0.12.55",
-        "symfony/phpunit-bridge": "^4.2 || ^5"
+        "phpstan/phpstan": "^1.0",
+        "phpstan/phpstan-strict-rules": "^1.1",
+        "symfony/phpunit-bridge": "^6.0"
       },
       "type": "library",
       "autoload": {
@@ -2673,7 +2799,7 @@
       "support": {
         "irc": "irc://irc.freenode.org/composer",
         "issues": "https://github.com/composer/xdebug-handler/issues",
-        "source": "https://github.com/composer/xdebug-handler/tree/2.0.1"
+        "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
       },
       "funding": [
         {
@@ -2689,76 +2815,20 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-05T19:37:51+00:00"
-    },
-    {
-      "name": "danielstjules/stringy",
-      "version": "3.1.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/danielstjules/Stringy.git",
-        "reference": "df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/danielstjules/Stringy/zipball/df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e",
-        "reference": "df24ab62d2d8213bbbe88cc36fc35a4503b4bd7e",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=5.4.0",
-        "symfony/polyfill-mbstring": "~1.1"
-      },
-      "require-dev": {
-        "phpunit/phpunit": "~4.0"
-      },
-      "type": "library",
-      "autoload": {
-        "psr-4": {
-          "Stringy\\": "src/"
-        },
-        "files": ["src/Create.php"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Daniel St. Jules",
-          "email": "danielst.jules@gmail.com",
-          "homepage": "http://www.danielstjules.com"
-        }
-      ],
-      "description": "A string manipulation library with multibyte support",
-      "homepage": "https://github.com/danielstjules/Stringy",
-      "keywords": [
-        "UTF",
-        "helpers",
-        "manipulation",
-        "methods",
-        "multibyte",
-        "string",
-        "utf-8",
-        "utility",
-        "utils"
-      ],
-      "support": {
-        "issues": "https://github.com/danielstjules/Stringy/issues",
-        "source": "https://github.com/danielstjules/Stringy"
-      },
-      "time": "2017-06-12T01:10:27+00:00"
+      "time": "2022-02-25T21:32:43+00:00"
     },
     {
       "name": "doctrine/annotations",
-      "version": "1.13.1",
+      "version": "1.13.2",
       "source": {
         "type": "git",
         "url": "https://github.com/doctrine/annotations.git",
-        "reference": "e6e7b7d5b45a2f2abc5460cc6396480b2b1d321f"
+        "reference": "5b668aef16090008790395c02c893b1ba13f7e08"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/doctrine/annotations/zipball/e6e7b7d5b45a2f2abc5460cc6396480b2b1d321f",
-        "reference": "e6e7b7d5b45a2f2abc5460cc6396480b2b1d321f",
+        "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08",
+        "reference": "5b668aef16090008790395c02c893b1ba13f7e08",
         "shasum": ""
       },
       "require": {
@@ -2809,9 +2879,9 @@
       "keywords": ["annotations", "docblock", "parser"],
       "support": {
         "issues": "https://github.com/doctrine/annotations/issues",
-        "source": "https://github.com/doctrine/annotations/tree/1.13.1"
+        "source": "https://github.com/doctrine/annotations/tree/1.13.2"
       },
-      "time": "2021-05-16T18:07:53+00:00"
+      "time": "2021-08-05T19:00:23+00:00"
     },
     {
       "name": "doctrine/instantiator",
@@ -2879,32 +2949,28 @@
     },
     {
       "name": "doctrine/lexer",
-      "version": "1.2.1",
+      "version": "1.2.3",
       "source": {
         "type": "git",
         "url": "https://github.com/doctrine/lexer.git",
-        "reference": "e864bbf5904cb8f5bb334f99209b48018522f042"
+        "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042",
-        "reference": "e864bbf5904cb8f5bb334f99209b48018522f042",
+        "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229",
+        "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229",
         "shasum": ""
       },
       "require": {
-        "php": "^7.2 || ^8.0"
+        "php": "^7.1 || ^8.0"
       },
       "require-dev": {
-        "doctrine/coding-standard": "^6.0",
-        "phpstan/phpstan": "^0.11.8",
-        "phpunit/phpunit": "^8.2"
+        "doctrine/coding-standard": "^9.0",
+        "phpstan/phpstan": "^1.3",
+        "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+        "vimeo/psalm": "^4.11"
       },
       "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-master": "1.2.x-dev"
-        }
-      },
       "autoload": {
         "psr-4": {
           "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
@@ -2931,7 +2997,7 @@
       "keywords": ["annotations", "docblock", "lexer", "parser", "php"],
       "support": {
         "issues": "https://github.com/doctrine/lexer/issues",
-        "source": "https://github.com/doctrine/lexer/tree/1.2.1"
+        "source": "https://github.com/doctrine/lexer/tree/1.2.3"
       },
       "funding": [
         {
@@ -2947,59 +3013,60 @@
           "type": "tidelift"
         }
       ],
-      "time": "2020-05-25T17:44:05+00:00"
+      "time": "2022-02-28T11:07:21+00:00"
     },
     {
       "name": "friendsofphp/php-cs-fixer",
-      "version": "v3.0.0",
+      "version": "v3.6.0",
       "source": {
         "type": "git",
         "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
-        "reference": "c15377bdfa8d1ecf186f1deadec39c89984e1167"
+        "reference": "1975e4453eb2726d1f50da0ce7fa91295029a4fa"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/c15377bdfa8d1ecf186f1deadec39c89984e1167",
-        "reference": "c15377bdfa8d1ecf186f1deadec39c89984e1167",
+        "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1975e4453eb2726d1f50da0ce7fa91295029a4fa",
+        "reference": "1975e4453eb2726d1f50da0ce7fa91295029a4fa",
         "shasum": ""
       },
       "require": {
         "composer/semver": "^3.2",
-        "composer/xdebug-handler": "^2.0",
-        "doctrine/annotations": "^1.12",
+        "composer/xdebug-handler": "^3.0",
+        "doctrine/annotations": "^1.13",
         "ext-json": "*",
         "ext-tokenizer": "*",
-        "php": "^7.1.3 || ^8.0",
+        "php": "^7.4 || ^8.0",
         "php-cs-fixer/diff": "^2.0",
-        "symfony/console": "^4.4.20 || ^5.1.3",
-        "symfony/event-dispatcher": "^4.4.20 || ^5.0",
-        "symfony/filesystem": "^4.4.20 || ^5.0",
-        "symfony/finder": "^4.4.20 || ^5.0",
-        "symfony/options-resolver": "^4.4.20 || ^5.0",
-        "symfony/polyfill-php72": "^1.22",
-        "symfony/process": "^4.4.20 || ^5.0",
-        "symfony/stopwatch": "^4.4.20 || ^5.0"
+        "symfony/console": "^5.4 || ^6.0",
+        "symfony/event-dispatcher": "^5.4 || ^6.0",
+        "symfony/filesystem": "^5.4 || ^6.0",
+        "symfony/finder": "^5.4 || ^6.0",
+        "symfony/options-resolver": "^5.4 || ^6.0",
+        "symfony/polyfill-mbstring": "^1.23",
+        "symfony/polyfill-php80": "^1.23",
+        "symfony/polyfill-php81": "^1.23",
+        "symfony/process": "^5.4 || ^6.0",
+        "symfony/stopwatch": "^5.4 || ^6.0"
       },
       "require-dev": {
         "justinrainbow/json-schema": "^5.2",
-        "keradus/cli-executor": "^1.4",
-        "mikey179/vfsstream": "^1.6.8",
-        "php-coveralls/php-coveralls": "^2.4.3",
+        "keradus/cli-executor": "^1.5",
+        "mikey179/vfsstream": "^1.6.10",
+        "php-coveralls/php-coveralls": "^2.5.2",
         "php-cs-fixer/accessible-object": "^1.1",
         "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
         "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
-        "phpspec/prophecy": "^1.10.3",
-        "phpspec/prophecy-phpunit": "^1.1 || ^2.0",
-        "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5",
+        "phpspec/prophecy": "^1.15",
+        "phpspec/prophecy-phpunit": "^2.0",
+        "phpunit/phpunit": "^9.5",
         "phpunitgoodpractices/polyfill": "^1.5",
         "phpunitgoodpractices/traits": "^1.9.1",
-        "symfony/phpunit-bridge": "^5.2.4",
-        "symfony/yaml": "^4.4.20 || ^5.0"
+        "symfony/phpunit-bridge": "^6.0",
+        "symfony/yaml": "^5.4 || ^6.0"
       },
       "suggest": {
         "ext-dom": "For handling output formats in XML",
-        "ext-mbstring": "For handling non-UTF8 characters.",
-        "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible."
+        "ext-mbstring": "For handling non-UTF8 characters."
       },
       "bin": ["php-cs-fixer"],
       "type": "application",
@@ -3023,7 +3090,7 @@
       "description": "A tool to automatically fix PHP code style",
       "support": {
         "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues",
-        "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.0.0"
+        "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.6.0"
       },
       "funding": [
         {
@@ -3031,20 +3098,20 @@
           "type": "github"
         }
       ],
-      "time": "2021-05-03T21:51:58+00:00"
+      "time": "2022-02-07T18:02:40+00:00"
     },
     {
       "name": "mikey179/vfsstream",
-      "version": "v1.6.8",
+      "version": "v1.6.10",
       "source": {
         "type": "git",
         "url": "https://github.com/bovigo/vfsStream.git",
-        "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe"
+        "reference": "250c0825537d501e327df879fb3d4cd751933b85"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe",
-        "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe",
+        "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/250c0825537d501e327df879fb3d4cd751933b85",
+        "reference": "250c0825537d501e327df879fb3d4cd751933b85",
         "shasum": ""
       },
       "require": {
@@ -3080,7 +3147,7 @@
         "source": "https://github.com/bovigo/vfsStream/tree/master",
         "wiki": "https://github.com/bovigo/vfsStream/wiki"
       },
-      "time": "2019-10-30T15:31:00+00:00"
+      "time": "2021-09-25T08:05:01+00:00"
     },
     {
       "name": "myclabs/deep-copy",
@@ -3099,9 +3166,6 @@
       "require": {
         "php": "^7.1 || ^8.0"
       },
-      "replace": {
-        "myclabs/deep-copy": "self.version"
-      },
       "require-dev": {
         "doctrine/collections": "^1.0",
         "doctrine/common": "^2.6",
@@ -3109,10 +3173,10 @@
       },
       "type": "library",
       "autoload": {
+        "files": ["src/DeepCopy/deep_copy.php"],
         "psr-4": {
           "DeepCopy\\": "src/DeepCopy/"
-        },
-        "files": ["src/DeepCopy/deep_copy.php"]
+        }
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
@@ -3132,16 +3196,16 @@
     },
     {
       "name": "nette/neon",
-      "version": "v3.2.2",
+      "version": "v3.3.2",
       "source": {
         "type": "git",
         "url": "https://github.com/nette/neon.git",
-        "reference": "e4ca6f4669121ca6876b1d048c612480e39a28d5"
+        "reference": "54b287d8c2cdbe577b02e28ca1713e275b05ece2"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/nette/neon/zipball/e4ca6f4669121ca6876b1d048c612480e39a28d5",
-        "reference": "e4ca6f4669121ca6876b1d048c612480e39a28d5",
+        "url": "https://api.github.com/repos/nette/neon/zipball/54b287d8c2cdbe577b02e28ca1713e275b05ece2",
+        "reference": "54b287d8c2cdbe577b02e28ca1713e275b05ece2",
         "shasum": ""
       },
       "require": {
@@ -3151,12 +3215,13 @@
       "require-dev": {
         "nette/tester": "^2.0",
         "phpstan/phpstan": "^0.12",
-        "tracy/tracy": "^2.3"
+        "tracy/tracy": "^2.7"
       },
+      "bin": ["bin/neon-lint"],
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-master": "3.2-dev"
+          "dev-master": "3.3-dev"
         }
       },
       "autoload": {
@@ -3179,22 +3244,22 @@
       "keywords": ["export", "import", "neon", "nette", "yaml"],
       "support": {
         "issues": "https://github.com/nette/neon/issues",
-        "source": "https://github.com/nette/neon/tree/v3.2.2"
+        "source": "https://github.com/nette/neon/tree/v3.3.2"
       },
-      "time": "2021-02-28T12:30:32+00:00"
+      "time": "2021-11-25T15:57:41+00:00"
     },
     {
       "name": "nikic/php-parser",
-      "version": "v4.10.5",
+      "version": "v4.13.2",
       "source": {
         "type": "git",
         "url": "https://github.com/nikic/PHP-Parser.git",
-        "reference": "4432ba399e47c66624bc73c8c0f811e5c109576f"
+        "reference": "210577fe3cf7badcc5814d99455df46564f3c077"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4432ba399e47c66624bc73c8c0f811e5c109576f",
-        "reference": "4432ba399e47c66624bc73c8c0f811e5c109576f",
+        "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077",
+        "reference": "210577fe3cf7badcc5814d99455df46564f3c077",
         "shasum": ""
       },
       "require": {
@@ -3228,22 +3293,22 @@
       "keywords": ["parser", "php"],
       "support": {
         "issues": "https://github.com/nikic/PHP-Parser/issues",
-        "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.5"
+        "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2"
       },
-      "time": "2021-05-03T19:11:20+00:00"
+      "time": "2021-11-30T19:35:32+00:00"
     },
     {
       "name": "phar-io/manifest",
-      "version": "2.0.1",
+      "version": "2.0.3",
       "source": {
         "type": "git",
         "url": "https://github.com/phar-io/manifest.git",
-        "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
+        "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
-        "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
+        "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+        "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
         "shasum": ""
       },
       "require": {
@@ -3284,22 +3349,22 @@
       "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
       "support": {
         "issues": "https://github.com/phar-io/manifest/issues",
-        "source": "https://github.com/phar-io/manifest/tree/master"
+        "source": "https://github.com/phar-io/manifest/tree/2.0.3"
       },
-      "time": "2020-06-27T14:33:11+00:00"
+      "time": "2021-07-20T11:28:43+00:00"
     },
     {
       "name": "phar-io/version",
-      "version": "3.1.0",
+      "version": "3.2.1",
       "source": {
         "type": "git",
         "url": "https://github.com/phar-io/version.git",
-        "reference": "bae7c545bef187884426f042434e561ab1ddb182"
+        "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
-        "reference": "bae7c545bef187884426f042434e561ab1ddb182",
+        "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+        "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
         "shasum": ""
       },
       "require": {
@@ -3331,9 +3396,9 @@
       "description": "Library for handling version information and constraints",
       "support": {
         "issues": "https://github.com/phar-io/version/issues",
-        "source": "https://github.com/phar-io/version/tree/3.1.0"
+        "source": "https://github.com/phar-io/version/tree/3.2.1"
       },
-      "time": "2021-02-23T14:00:09+00:00"
+      "time": "2022-02-21T01:04:05+00:00"
     },
     {
       "name": "php-cs-fixer/diff",
@@ -3434,16 +3499,16 @@
     },
     {
       "name": "phpdocumentor/reflection-docblock",
-      "version": "5.2.2",
+      "version": "5.3.0",
       "source": {
         "type": "git",
         "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-        "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
+        "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
-        "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
+        "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
+        "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
         "shasum": ""
       },
       "require": {
@@ -3454,7 +3519,8 @@
         "webmozart/assert": "^1.9.1"
       },
       "require-dev": {
-        "mockery/mockery": "~1.3.2"
+        "mockery/mockery": "~1.3.2",
+        "psalm/phar": "^4.8"
       },
       "type": "library",
       "extra": {
@@ -3482,22 +3548,22 @@
       "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
       "support": {
         "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
-        "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
+        "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0"
       },
-      "time": "2020-09-03T19:13:55+00:00"
+      "time": "2021-10-19T17:43:47+00:00"
     },
     {
       "name": "phpdocumentor/type-resolver",
-      "version": "1.4.0",
+      "version": "1.6.0",
       "source": {
         "type": "git",
         "url": "https://github.com/phpDocumentor/TypeResolver.git",
-        "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
+        "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
-        "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
+        "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706",
+        "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706",
         "shasum": ""
       },
       "require": {
@@ -3505,7 +3571,8 @@
         "phpdocumentor/reflection-common": "^2.0"
       },
       "require-dev": {
-        "ext-tokenizer": "*"
+        "ext-tokenizer": "*",
+        "psalm/phar": "^4.8"
       },
       "type": "library",
       "extra": {
@@ -3529,39 +3596,39 @@
       "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
       "support": {
         "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-        "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0"
+        "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0"
       },
-      "time": "2020-09-17T18:55:26+00:00"
+      "time": "2022-01-04T19:58:01+00:00"
     },
     {
       "name": "phpspec/prophecy",
-      "version": "1.13.0",
+      "version": "v1.15.0",
       "source": {
         "type": "git",
         "url": "https://github.com/phpspec/prophecy.git",
-        "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
+        "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
-        "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
+        "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
+        "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
         "shasum": ""
       },
       "require": {
         "doctrine/instantiator": "^1.2",
-        "php": "^7.2 || ~8.0, <8.1",
+        "php": "^7.2 || ~8.0, <8.2",
         "phpdocumentor/reflection-docblock": "^5.2",
         "sebastian/comparator": "^3.0 || ^4.0",
         "sebastian/recursion-context": "^3.0 || ^4.0"
       },
       "require-dev": {
-        "phpspec/phpspec": "^6.0",
+        "phpspec/phpspec": "^6.0 || ^7.0",
         "phpunit/phpunit": "^8.0 || ^9.0"
       },
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-master": "1.11.x-dev"
+          "dev-master": "1.x-dev"
         }
       },
       "autoload": {
@@ -3587,141 +3654,56 @@
       "keywords": ["Double", "Dummy", "fake", "mock", "spy", "stub"],
       "support": {
         "issues": "https://github.com/phpspec/prophecy/issues",
-        "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
+        "source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
       },
-      "time": "2021-03-17T13:42:18+00:00"
+      "time": "2021-12-08T12:19:24+00:00"
     },
     {
-      "name": "phpstan/extension-installer",
-      "version": "1.1.0",
+      "name": "phpstan/phpstan",
+      "version": "1.4.6",
       "source": {
         "type": "git",
-        "url": "https://github.com/phpstan/extension-installer.git",
-        "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051"
+        "url": "https://github.com/phpstan/phpstan.git",
+        "reference": "8a7761f1c520e0dad6e04d862fdc697445457cfe"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
-        "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
+        "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8a7761f1c520e0dad6e04d862fdc697445457cfe",
+        "reference": "8a7761f1c520e0dad6e04d862fdc697445457cfe",
         "shasum": ""
       },
       "require": {
-        "composer-plugin-api": "^1.1 || ^2.0",
-        "php": "^7.1 || ^8.0",
-        "phpstan/phpstan": ">=0.11.6"
+        "php": "^7.1|^8.0"
       },
-      "require-dev": {
-        "composer/composer": "^1.8",
-        "phing/phing": "^2.16.3",
-        "php-parallel-lint/php-parallel-lint": "^1.2.0",
-        "phpstan/phpstan-strict-rules": "^0.11 || ^0.12"
+      "conflict": {
+        "phpstan/phpstan-shim": "*"
       },
-      "type": "composer-plugin",
+      "bin": ["phpstan", "phpstan.phar"],
+      "type": "library",
       "extra": {
-        "class": "PHPStan\\ExtensionInstaller\\Plugin"
+        "branch-alias": {
+          "dev-master": "1.4-dev"
+        }
       },
       "autoload": {
-        "psr-4": {
-          "PHPStan\\ExtensionInstaller\\": "src/"
-        }
+        "files": ["bootstrap.php"]
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
-      "description": "Composer plugin for automatic installation of PHPStan extensions",
+      "description": "PHPStan - PHP Static Analysis Tool",
       "support": {
-        "issues": "https://github.com/phpstan/extension-installer/issues",
-        "source": "https://github.com/phpstan/extension-installer/tree/1.1.0"
-      },
-      "time": "2020-12-13T13:06:13+00:00"
-    },
-    {
-      "name": "phpstan/phpdoc-parser",
-      "version": "0.5.4",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/phpstan/phpdoc-parser.git",
-        "reference": "e352d065af1ae9b41c12d1dfd309e90f7b1f55c9"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/e352d065af1ae9b41c12d1dfd309e90f7b1f55c9",
-        "reference": "e352d065af1ae9b41c12d1dfd309e90f7b1f55c9",
-        "shasum": ""
-      },
-      "require": {
-        "php": "^7.1 || ^8.0"
-      },
-      "require-dev": {
-        "phing/phing": "^2.16.3",
-        "php-parallel-lint/php-parallel-lint": "^1.2",
-        "phpstan/extension-installer": "^1.0",
-        "phpstan/phpstan": "^0.12.60",
-        "phpstan/phpstan-strict-rules": "^0.12.5",
-        "phpunit/phpunit": "^7.5.20",
-        "symfony/process": "^5.2"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-master": "0.5-dev"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "PHPStan\\PhpDocParser\\": ["src/"]
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "PHPDoc parser with support for nullable, intersection and generic types",
-      "support": {
-        "issues": "https://github.com/phpstan/phpdoc-parser/issues",
-        "source": "https://github.com/phpstan/phpdoc-parser/tree/0.5.4"
-      },
-      "time": "2021-04-03T14:46:19+00:00"
-    },
-    {
-      "name": "phpstan/phpstan",
-      "version": "0.12.88",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/phpstan/phpstan.git",
-        "reference": "464d1a81af49409c41074aa6640ed0c4cbd9bb68"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/phpstan/phpstan/zipball/464d1a81af49409c41074aa6640ed0c4cbd9bb68",
-        "reference": "464d1a81af49409c41074aa6640ed0c4cbd9bb68",
-        "shasum": ""
-      },
-      "require": {
-        "php": "^7.1|^8.0"
-      },
-      "conflict": {
-        "phpstan/phpstan-shim": "*"
-      },
-      "bin": ["phpstan", "phpstan.phar"],
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-master": "0.12-dev"
-        }
-      },
-      "autoload": {
-        "files": ["bootstrap.php"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "PHPStan - PHP Static Analysis Tool",
-      "support": {
-        "issues": "https://github.com/phpstan/phpstan/issues",
-        "source": "https://github.com/phpstan/phpstan/tree/0.12.88"
+        "issues": "https://github.com/phpstan/phpstan/issues",
+        "source": "https://github.com/phpstan/phpstan/tree/1.4.6"
       },
       "funding": [
         {
           "url": "https://github.com/ondrejmirtes",
           "type": "github"
         },
+        {
+          "url": "https://github.com/phpstan",
+          "type": "github"
+        },
         {
           "url": "https://www.patreon.com/phpstan",
           "type": "patreon"
@@ -3731,27 +3713,27 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-17T12:24:49+00:00"
+      "time": "2022-02-06T12:56:13+00:00"
     },
     {
       "name": "phpunit/php-code-coverage",
-      "version": "9.2.6",
+      "version": "9.2.14",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-        "reference": "f6293e1b30a2354e8428e004689671b83871edde"
+        "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde",
-        "reference": "f6293e1b30a2354e8428e004689671b83871edde",
+        "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f4d60b6afe5546421462b76cd4e633ebc364ab4",
+        "reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4",
         "shasum": ""
       },
       "require": {
         "ext-dom": "*",
         "ext-libxml": "*",
         "ext-xmlwriter": "*",
-        "nikic/php-parser": "^4.10.2",
+        "nikic/php-parser": "^4.13.0",
         "php": ">=7.3",
         "phpunit/php-file-iterator": "^3.0.3",
         "phpunit/php-text-template": "^2.0.2",
@@ -3792,7 +3774,7 @@
       "keywords": ["coverage", "testing", "xunit"],
       "support": {
         "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
-        "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6"
+        "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.14"
       },
       "funding": [
         {
@@ -3800,20 +3782,20 @@
           "type": "github"
         }
       ],
-      "time": "2021-03-28T07:26:59+00:00"
+      "time": "2022-02-28T12:38:02+00:00"
     },
     {
       "name": "phpunit/php-file-iterator",
-      "version": "3.0.5",
+      "version": "3.0.6",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-        "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8"
+        "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8",
-        "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8",
+        "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+        "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
         "shasum": ""
       },
       "require": {
@@ -3845,7 +3827,7 @@
       "keywords": ["filesystem", "iterator"],
       "support": {
         "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
-        "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5"
+        "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
       },
       "funding": [
         {
@@ -3853,7 +3835,7 @@
           "type": "github"
         }
       ],
-      "time": "2020-09-28T05:57:25+00:00"
+      "time": "2021-12-02T12:48:52+00:00"
     },
     {
       "name": "phpunit/php-invoker",
@@ -4020,16 +4002,16 @@
     },
     {
       "name": "phpunit/phpunit",
-      "version": "9.5.5",
+      "version": "9.5.16",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianbergmann/phpunit.git",
-        "reference": "89ff45ea9d70e35522fb6654a2ebc221158de276"
+        "reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/89ff45ea9d70e35522fb6654a2ebc221158de276",
-        "reference": "89ff45ea9d70e35522fb6654a2ebc221158de276",
+        "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5ff8c545a50226c569310a35f4fa89d79f1ddfdc",
+        "reference": "5ff8c545a50226c569310a35f4fa89d79f1ddfdc",
         "shasum": ""
       },
       "require": {
@@ -4041,11 +4023,11 @@
         "ext-xml": "*",
         "ext-xmlwriter": "*",
         "myclabs/deep-copy": "^1.10.1",
-        "phar-io/manifest": "^2.0.1",
+        "phar-io/manifest": "^2.0.3",
         "phar-io/version": "^3.0.2",
         "php": ">=7.3",
         "phpspec/prophecy": "^1.12.1",
-        "phpunit/php-code-coverage": "^9.2.3",
+        "phpunit/php-code-coverage": "^9.2.13",
         "phpunit/php-file-iterator": "^3.0.5",
         "phpunit/php-invoker": "^3.1.1",
         "phpunit/php-text-template": "^2.0.3",
@@ -4059,7 +4041,7 @@
         "sebastian/global-state": "^5.0.1",
         "sebastian/object-enumerator": "^4.0.3",
         "sebastian/resource-operations": "^3.0.3",
-        "sebastian/type": "^2.3.2",
+        "sebastian/type": "^2.3.4",
         "sebastian/version": "^3.0.2"
       },
       "require-dev": {
@@ -4078,8 +4060,8 @@
         }
       },
       "autoload": {
-        "classmap": ["src/"],
-        "files": ["src/Framework/Assert/Functions.php"]
+        "files": ["src/Framework/Assert/Functions.php"],
+        "classmap": ["src/"]
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["BSD-3-Clause"],
@@ -4095,11 +4077,11 @@
       "keywords": ["phpunit", "testing", "xunit"],
       "support": {
         "issues": "https://github.com/sebastianbergmann/phpunit/issues",
-        "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.5"
+        "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.16"
       },
       "funding": [
         {
-          "url": "https://phpunit.de/donate.html",
+          "url": "https://phpunit.de/sponsors.html",
           "type": "custom"
         },
         {
@@ -4107,26 +4089,31 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-05T04:49:07+00:00"
+      "time": "2022-02-23T17:10:58+00:00"
     },
     {
       "name": "psr/container",
-      "version": "1.1.1",
+      "version": "2.0.2",
       "source": {
         "type": "git",
         "url": "https://github.com/php-fig/container.git",
-        "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
+        "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
-        "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
+        "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+        "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.0"
+        "php": ">=7.4.0"
       },
       "type": "library",
+      "extra": {
+        "branch-alias": {
+          "dev-master": "2.0.x-dev"
+        }
+      },
       "autoload": {
         "psr-4": {
           "Psr\\Container\\": "src/"
@@ -4151,35 +4138,35 @@
       ],
       "support": {
         "issues": "https://github.com/php-fig/container/issues",
-        "source": "https://github.com/php-fig/container/tree/1.1.1"
+        "source": "https://github.com/php-fig/container/tree/2.0.2"
       },
-      "time": "2021-03-05T17:36:06+00:00"
+      "time": "2021-11-05T16:47:00+00:00"
     },
     {
       "name": "rector/rector",
-      "version": "0.11.16",
+      "version": "0.12.16",
       "source": {
         "type": "git",
         "url": "https://github.com/rectorphp/rector.git",
-        "reference": "5c030ad7cefa59075e0fe14604cd4982ceaa2bd0"
+        "reference": "13412efd0dfda2e2c310dd24397281804441cf7a"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/rectorphp/rector/zipball/5c030ad7cefa59075e0fe14604cd4982ceaa2bd0",
-        "reference": "5c030ad7cefa59075e0fe14604cd4982ceaa2bd0",
+        "url": "https://api.github.com/repos/rectorphp/rector/zipball/13412efd0dfda2e2c310dd24397281804441cf7a",
+        "reference": "13412efd0dfda2e2c310dd24397281804441cf7a",
         "shasum": ""
       },
       "require": {
         "php": "^7.1|^8.0",
-        "phpstan/phpstan": ">=0.12.86 <=0.12.88"
+        "phpstan/phpstan": "^1.4.2"
       },
       "conflict": {
-        "phpstan/phpdoc-parser": "<=0.5.3",
-        "phpstan/phpstan": "<=0.12.82",
+        "phpstan/phpdoc-parser": "<1.2",
         "rector/rector-cakephp": "*",
         "rector/rector-doctrine": "*",
+        "rector/rector-laravel": "*",
         "rector/rector-nette": "*",
-        "rector/rector-nette-to-symfony": "*",
+        "rector/rector-phpoffice": "*",
         "rector/rector-phpunit": "*",
         "rector/rector-prefixed": "*",
         "rector/rector-symfony": "*"
@@ -4188,7 +4175,7 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "0.10-dev"
+          "dev-main": "0.12-dev"
         }
       },
       "autoload": {
@@ -4196,10 +4183,10 @@
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
-      "description": "Prefixed and PHP 7.1 downgraded version of rector/rector",
+      "description": "Instant Upgrade and Automated Refactoring of any PHP code",
       "support": {
         "issues": "https://github.com/rectorphp/rector/issues",
-        "source": "https://github.com/rectorphp/rector/tree/0.11.16"
+        "source": "https://github.com/rectorphp/rector/tree/0.12.16"
       },
       "funding": [
         {
@@ -4207,53 +4194,7 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-08T08:41:04+00:00"
-    },
-    {
-      "name": "rector/rector-phpstan-rules",
-      "version": "0.2.12",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/rectorphp/phpstan-rules.git",
-        "reference": "84b2034aab951be7e86dc6cc7e141ee92a3d115b"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/rectorphp/phpstan-rules/zipball/84b2034aab951be7e86dc6cc7e141ee92a3d115b",
-        "reference": "84b2034aab951be7e86dc6cc7e141ee92a3d115b",
-        "shasum": ""
-      },
-      "require": {
-        "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "phpstan/phpstan": "^0.12.86",
-        "symplify/phpstan-rules": "^9.3.5"
-      },
-      "require-dev": {
-        "phpstan/extension-installer": "^1.1",
-        "phpunit/phpunit": "^9.5",
-        "symplify/easy-coding-standard": "^9.3",
-        "symplify/phpstan-extensions": "^9.3"
-      },
-      "type": "phpstan-extension",
-      "extra": {
-        "phpstan": {
-          "includes": ["config/config.neon"]
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Rector\\PHPStanRules\\": "src"
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "PHPStan rules for Rector projects - with focus on static reflection, constant re-use and Rector design patterns",
-      "support": {
-        "issues": "https://github.com/rectorphp/phpstan-rules/issues",
-        "source": "https://github.com/rectorphp/phpstan-rules/tree/0.2.12"
-      },
-      "time": "2021-05-20T22:31:19+00:00"
+      "time": "2022-02-09T14:50:55+00:00"
     },
     {
       "name": "sebastian/cli-parser",
@@ -4643,16 +4584,16 @@
     },
     {
       "name": "sebastian/exporter",
-      "version": "4.0.3",
+      "version": "4.0.4",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianbergmann/exporter.git",
-        "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65"
+        "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65",
-        "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65",
+        "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9",
+        "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9",
         "shasum": ""
       },
       "require": {
@@ -4697,11 +4638,11 @@
         }
       ],
       "description": "Provides the functionality to export PHP variables for visualization",
-      "homepage": "http://www.github.com/sebastianbergmann/exporter",
+      "homepage": "https://www.github.com/sebastianbergmann/exporter",
       "keywords": ["export", "exporter"],
       "support": {
         "issues": "https://github.com/sebastianbergmann/exporter/issues",
-        "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3"
+        "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4"
       },
       "funding": [
         {
@@ -4709,20 +4650,20 @@
           "type": "github"
         }
       ],
-      "time": "2020-09-28T05:24:23+00:00"
+      "time": "2021-11-11T14:18:36+00:00"
     },
     {
       "name": "sebastian/global-state",
-      "version": "5.0.2",
+      "version": "5.0.5",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianbergmann/global-state.git",
-        "reference": "a90ccbddffa067b51f574dea6eb25d5680839455"
+        "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455",
-        "reference": "a90ccbddffa067b51f574dea6eb25d5680839455",
+        "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+        "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
         "shasum": ""
       },
       "require": {
@@ -4759,7 +4700,7 @@
       "keywords": ["global state"],
       "support": {
         "issues": "https://github.com/sebastianbergmann/global-state/issues",
-        "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.2"
+        "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
       },
       "funding": [
         {
@@ -4767,7 +4708,7 @@
           "type": "github"
         }
       ],
-      "time": "2020-10-26T15:55:19+00:00"
+      "time": "2022-02-14T08:28:10+00:00"
     },
     {
       "name": "sebastian/lines-of-code",
@@ -5038,16 +4979,16 @@
     },
     {
       "name": "sebastian/type",
-      "version": "2.3.2",
+      "version": "2.3.4",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianbergmann/type.git",
-        "reference": "0d1c587401514d17e8f9258a27e23527cb1b06c1"
+        "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0d1c587401514d17e8f9258a27e23527cb1b06c1",
-        "reference": "0d1c587401514d17e8f9258a27e23527cb1b06c1",
+        "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
+        "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
         "shasum": ""
       },
       "require": {
@@ -5078,7 +5019,7 @@
       "homepage": "https://github.com/sebastianbergmann/type",
       "support": {
         "issues": "https://github.com/sebastianbergmann/type/issues",
-        "source": "https://github.com/sebastianbergmann/type/tree/2.3.2"
+        "source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
       },
       "funding": [
         {
@@ -5086,7 +5027,7 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-04T13:02:07+00:00"
+      "time": "2021-06-15T12:49:02+00:00"
     },
     {
       "name": "sebastian/version",
@@ -5139,16 +5080,16 @@
     },
     {
       "name": "sebastianfeldmann/camino",
-      "version": "0.9.4",
+      "version": "0.9.5",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianfeldmann/camino.git",
-        "reference": "3b611368e22e8565c3a6504613136402ed9e6f69"
+        "reference": "bf2e4c8b2a029e9eade43666132b61331e3e8184"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianfeldmann/camino/zipball/3b611368e22e8565c3a6504613136402ed9e6f69",
-        "reference": "3b611368e22e8565c3a6504613136402ed9e6f69",
+        "url": "https://api.github.com/repos/sebastianfeldmann/camino/zipball/bf2e4c8b2a029e9eade43666132b61331e3e8184",
+        "reference": "bf2e4c8b2a029e9eade43666132b61331e3e8184",
         "shasum": ""
       },
       "require": {
@@ -5178,7 +5119,7 @@
       "keywords": ["file system", "path"],
       "support": {
         "issues": "https://github.com/sebastianfeldmann/camino/issues",
-        "source": "https://github.com/sebastianfeldmann/camino/tree/0.9.4"
+        "source": "https://github.com/sebastianfeldmann/camino/tree/0.9.5"
       },
       "funding": [
         {
@@ -5186,20 +5127,20 @@
           "type": "github"
         }
       ],
-      "time": "2020-12-08T09:25:24+00:00"
+      "time": "2022-01-03T13:15:10+00:00"
     },
     {
       "name": "sebastianfeldmann/cli",
-      "version": "3.3.3",
+      "version": "3.4.1",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianfeldmann/cli.git",
-        "reference": "c4a677f229976c88cc8f50b1477ab15244a4f6d8"
+        "reference": "8a932e99e9455981fb32fa6c085492462fe8f8cf"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianfeldmann/cli/zipball/c4a677f229976c88cc8f50b1477ab15244a4f6d8",
-        "reference": "c4a677f229976c88cc8f50b1477ab15244a4f6d8",
+        "url": "https://api.github.com/repos/sebastianfeldmann/cli/zipball/8a932e99e9455981fb32fa6c085492462fe8f8cf",
+        "reference": "8a932e99e9455981fb32fa6c085492462fe8f8cf",
         "shasum": ""
       },
       "require": {
@@ -5232,7 +5173,7 @@
       "keywords": ["cli"],
       "support": {
         "issues": "https://github.com/sebastianfeldmann/cli/issues",
-        "source": "https://github.com/sebastianfeldmann/cli/tree/3.3.3"
+        "source": "https://github.com/sebastianfeldmann/cli/tree/3.4.1"
       },
       "funding": [
         {
@@ -5240,20 +5181,20 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-03T16:02:45+00:00"
+      "time": "2021-12-20T14:59:49+00:00"
     },
     {
       "name": "sebastianfeldmann/git",
-      "version": "3.7.1",
+      "version": "3.8.2",
       "source": {
         "type": "git",
         "url": "https://github.com/sebastianfeldmann/git.git",
-        "reference": "406b98e09c37249ce586be8ed5766bf0ca389490"
+        "reference": "e30b5ed4a87c6b16339bfc6a79c141aba83bade4"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/sebastianfeldmann/git/zipball/406b98e09c37249ce586be8ed5766bf0ca389490",
-        "reference": "406b98e09c37249ce586be8ed5766bf0ca389490",
+        "url": "https://api.github.com/repos/sebastianfeldmann/git/zipball/e30b5ed4a87c6b16339bfc6a79c141aba83bade4",
+        "reference": "e30b5ed4a87c6b16339bfc6a79c141aba83bade4",
         "shasum": ""
       },
       "require": {
@@ -5262,6 +5203,9 @@
         "php": ">=7.2",
         "sebastianfeldmann/cli": "^3.0"
       },
+      "require-dev": {
+        "mikey179/vfsstream": "^1.6"
+      },
       "type": "library",
       "extra": {
         "branch-alias": {
@@ -5286,7 +5230,7 @@
       "keywords": ["git"],
       "support": {
         "issues": "https://github.com/sebastianfeldmann/git/issues",
-        "source": "https://github.com/sebastianfeldmann/git/tree/3.7.1"
+        "source": "https://github.com/sebastianfeldmann/git/tree/3.8.2"
       },
       "funding": [
         {
@@ -5294,39 +5238,38 @@
           "type": "github"
         }
       ],
-      "time": "2021-05-29T12:47:08+00:00"
+      "time": "2022-02-17T19:43:52+00:00"
     },
     {
       "name": "symfony/config",
-      "version": "v5.3.0",
+      "version": "v6.0.3",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/config.git",
-        "reference": "9f4a448c2d7fd2c90882dfff930b627ddbe16810"
+        "reference": "c14f32ae4cd2a3c29d8825c5093463ac08ade7d8"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/config/zipball/9f4a448c2d7fd2c90882dfff930b627ddbe16810",
-        "reference": "9f4a448c2d7fd2c90882dfff930b627ddbe16810",
+        "url": "https://api.github.com/repos/symfony/config/zipball/c14f32ae4cd2a3c29d8825c5093463ac08ade7d8",
+        "reference": "c14f32ae4cd2a3c29d8825c5093463ac08ade7d8",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/filesystem": "^4.4|^5.0",
+        "php": ">=8.0.2",
+        "symfony/deprecation-contracts": "^2.1|^3",
+        "symfony/filesystem": "^5.4|^6.0",
         "symfony/polyfill-ctype": "~1.8",
-        "symfony/polyfill-php80": "^1.15",
         "symfony/polyfill-php81": "^1.22"
       },
       "conflict": {
         "symfony/finder": "<4.4"
       },
       "require-dev": {
-        "symfony/event-dispatcher": "^4.4|^5.0",
-        "symfony/finder": "^4.4|^5.0",
-        "symfony/messenger": "^4.4|^5.0",
-        "symfony/service-contracts": "^1.1|^2",
-        "symfony/yaml": "^4.4|^5.0"
+        "symfony/event-dispatcher": "^5.4|^6.0",
+        "symfony/finder": "^5.4|^6.0",
+        "symfony/messenger": "^5.4|^6.0",
+        "symfony/service-contracts": "^1.1|^2|^3",
+        "symfony/yaml": "^5.4|^6.0"
       },
       "suggest": {
         "symfony/yaml": "To use the yaml reference dumper"
@@ -5353,7 +5296,7 @@
       "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/config/tree/v5.3.0"
+        "source": "https://github.com/symfony/config/tree/v6.0.3"
       },
       "funding": [
         {
@@ -5369,49 +5312,46 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2022-01-03T09:53:43+00:00"
     },
     {
       "name": "symfony/console",
-      "version": "v5.3.0",
+      "version": "v6.0.5",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/console.git",
-        "reference": "058553870f7809087fa80fa734704a21b9bcaeb2"
+        "reference": "3bebf4108b9e07492a2a4057d207aa5a77d146b1"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/console/zipball/058553870f7809087fa80fa734704a21b9bcaeb2",
-        "reference": "058553870f7809087fa80fa734704a21b9bcaeb2",
+        "url": "https://api.github.com/repos/symfony/console/zipball/3bebf4108b9e07492a2a4057d207aa5a77d146b1",
+        "reference": "3bebf4108b9e07492a2a4057d207aa5a77d146b1",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/deprecation-contracts": "^2.1",
+        "php": ">=8.0.2",
         "symfony/polyfill-mbstring": "~1.0",
-        "symfony/polyfill-php73": "^1.8",
-        "symfony/polyfill-php80": "^1.15",
-        "symfony/service-contracts": "^1.1|^2",
-        "symfony/string": "^5.1"
+        "symfony/service-contracts": "^1.1|^2|^3",
+        "symfony/string": "^5.4|^6.0"
       },
       "conflict": {
-        "symfony/dependency-injection": "<4.4",
-        "symfony/dotenv": "<5.1",
-        "symfony/event-dispatcher": "<4.4",
-        "symfony/lock": "<4.4",
-        "symfony/process": "<4.4"
+        "symfony/dependency-injection": "<5.4",
+        "symfony/dotenv": "<5.4",
+        "symfony/event-dispatcher": "<5.4",
+        "symfony/lock": "<5.4",
+        "symfony/process": "<5.4"
       },
       "provide": {
-        "psr/log-implementation": "1.0"
+        "psr/log-implementation": "1.0|2.0|3.0"
       },
       "require-dev": {
-        "psr/log": "~1.0",
-        "symfony/config": "^4.4|^5.0",
-        "symfony/dependency-injection": "^4.4|^5.0",
-        "symfony/event-dispatcher": "^4.4|^5.0",
-        "symfony/lock": "^4.4|^5.0",
-        "symfony/process": "^4.4|^5.0",
-        "symfony/var-dumper": "^4.4|^5.0"
+        "psr/log": "^1|^2|^3",
+        "symfony/config": "^5.4|^6.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symfony/event-dispatcher": "^5.4|^6.0",
+        "symfony/lock": "^5.4|^6.0",
+        "symfony/process": "^5.4|^6.0",
+        "symfony/var-dumper": "^5.4|^6.0"
       },
       "suggest": {
         "psr/log": "For using the console logger",
@@ -5442,7 +5382,7 @@
       "homepage": "https://symfony.com",
       "keywords": ["cli", "command line", "console", "terminal"],
       "support": {
-        "source": "https://github.com/symfony/console/tree/v5.3.0"
+        "source": "https://github.com/symfony/console/tree/v6.0.5"
       },
       "funding": [
         {
@@ -5458,44 +5398,44 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2022-02-25T10:48:52+00:00"
     },
     {
       "name": "symfony/dependency-injection",
-      "version": "v5.3.0",
+      "version": "v6.0.5",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/dependency-injection.git",
-        "reference": "94d973cb742d8c5c5dcf9534220e6b73b09af1d4"
+        "reference": "481846cbd2441cf3444340ee53486fc24da525bd"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/94d973cb742d8c5c5dcf9534220e6b73b09af1d4",
-        "reference": "94d973cb742d8c5c5dcf9534220e6b73b09af1d4",
+        "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/481846cbd2441cf3444340ee53486fc24da525bd",
+        "reference": "481846cbd2441cf3444340ee53486fc24da525bd",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "psr/container": "^1.1.1",
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/polyfill-php80": "^1.15",
-        "symfony/service-contracts": "^1.1.6|^2"
+        "php": ">=8.0.2",
+        "psr/container": "^1.1|^2.0",
+        "symfony/deprecation-contracts": "^2.1|^3",
+        "symfony/polyfill-php81": "^1.22",
+        "symfony/service-contracts": "^1.1.6|^2.0|^3.0"
       },
       "conflict": {
         "ext-psr": "<1.1|>=2",
-        "symfony/config": "<5.3",
-        "symfony/finder": "<4.4",
-        "symfony/proxy-manager-bridge": "<4.4",
-        "symfony/yaml": "<4.4"
+        "symfony/config": "<5.4",
+        "symfony/finder": "<5.4",
+        "symfony/proxy-manager-bridge": "<5.4",
+        "symfony/yaml": "<5.4"
       },
       "provide": {
-        "psr/container-implementation": "1.0",
-        "symfony/service-implementation": "1.0|2.0"
+        "psr/container-implementation": "1.1|2.0",
+        "symfony/service-implementation": "1.1|2.0|3.0"
       },
       "require-dev": {
-        "symfony/config": "^5.3",
-        "symfony/expression-language": "^4.4|^5.0",
-        "symfony/yaml": "^4.4|^5.0"
+        "symfony/config": "^5.4|^6.0",
+        "symfony/expression-language": "^5.4|^6.0",
+        "symfony/yaml": "^5.4|^6.0"
       },
       "suggest": {
         "symfony/config": "",
@@ -5526,72 +5466,7 @@
       "description": "Allows you to standardize and centralize the way objects are constructed in your application",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/dependency-injection/tree/v5.3.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-05-26T17:57:12+00:00"
-    },
-    {
-      "name": "symfony/error-handler",
-      "version": "v5.3.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/error-handler.git",
-        "reference": "0e6768b8c0dcef26df087df2bbbaa143867a59b2"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/error-handler/zipball/0e6768b8c0dcef26df087df2bbbaa143867a59b2",
-        "reference": "0e6768b8c0dcef26df087df2bbbaa143867a59b2",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.2.5",
-        "psr/log": "^1.0",
-        "symfony/polyfill-php80": "^1.15",
-        "symfony/var-dumper": "^4.4|^5.0"
-      },
-      "require-dev": {
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/http-kernel": "^4.4|^5.0",
-        "symfony/serializer": "^4.4|^5.0"
-      },
-      "type": "library",
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Component\\ErrorHandler\\": ""
-        },
-        "exclude-from-classmap": ["/Tests/"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Fabien Potencier",
-          "email": "fabien@symfony.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Provides tools to manage errors and ease debugging PHP code",
-      "homepage": "https://symfony.com",
-      "support": {
-        "source": "https://github.com/symfony/error-handler/tree/v5.3.0"
+        "source": "https://github.com/symfony/dependency-injection/tree/v6.0.5"
       },
       "funding": [
         {
@@ -5607,44 +5482,42 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2022-02-24T10:01:27+00:00"
     },
     {
       "name": "symfony/event-dispatcher",
-      "version": "v5.3.0",
+      "version": "v6.0.3",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/event-dispatcher.git",
-        "reference": "67a5f354afa8e2f231081b3fa11a5912f933c3ce"
+        "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/67a5f354afa8e2f231081b3fa11a5912f933c3ce",
-        "reference": "67a5f354afa8e2f231081b3fa11a5912f933c3ce",
+        "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934",
+        "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/event-dispatcher-contracts": "^2",
-        "symfony/polyfill-php80": "^1.15"
+        "php": ">=8.0.2",
+        "symfony/event-dispatcher-contracts": "^2|^3"
       },
       "conflict": {
-        "symfony/dependency-injection": "<4.4"
+        "symfony/dependency-injection": "<5.4"
       },
       "provide": {
         "psr/event-dispatcher-implementation": "1.0",
-        "symfony/event-dispatcher-implementation": "2.0"
+        "symfony/event-dispatcher-implementation": "2.0|3.0"
       },
       "require-dev": {
-        "psr/log": "~1.0",
-        "symfony/config": "^4.4|^5.0",
-        "symfony/dependency-injection": "^4.4|^5.0",
-        "symfony/error-handler": "^4.4|^5.0",
-        "symfony/expression-language": "^4.4|^5.0",
-        "symfony/http-foundation": "^4.4|^5.0",
-        "symfony/service-contracts": "^1.1|^2",
-        "symfony/stopwatch": "^4.4|^5.0"
+        "psr/log": "^1|^2|^3",
+        "symfony/config": "^5.4|^6.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symfony/error-handler": "^5.4|^6.0",
+        "symfony/expression-language": "^5.4|^6.0",
+        "symfony/http-foundation": "^5.4|^6.0",
+        "symfony/service-contracts": "^1.1|^2|^3",
+        "symfony/stopwatch": "^5.4|^6.0"
       },
       "suggest": {
         "symfony/dependency-injection": "",
@@ -5672,7 +5545,7 @@
       "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.0"
+        "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3"
       },
       "funding": [
         {
@@ -5688,24 +5561,24 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2022-01-02T09:55:41+00:00"
     },
     {
       "name": "symfony/event-dispatcher-contracts",
-      "version": "v2.4.0",
+      "version": "v3.0.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/event-dispatcher-contracts.git",
-        "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11"
+        "reference": "aa5422287b75594b90ee9cd807caf8f0df491385"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/69fee1ad2332a7cbab3aca13591953da9cdb7a11",
-        "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11",
+        "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385",
+        "reference": "aa5422287b75594b90ee9cd807caf8f0df491385",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
+        "php": ">=8.0.2",
         "psr/event-dispatcher": "^1"
       },
       "suggest": {
@@ -5714,7 +5587,7 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "2.4-dev"
+          "dev-main": "3.0-dev"
         },
         "thanks": {
           "name": "symfony/contracts",
@@ -5749,7 +5622,7 @@
         "standards"
       ],
       "support": {
-        "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.4.0"
+        "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0"
       },
       "funding": [
         {
@@ -5765,25 +5638,26 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-03-23T23:28:01+00:00"
+      "time": "2021-07-15T12:33:35+00:00"
     },
     {
       "name": "symfony/filesystem",
-      "version": "v5.3.0",
+      "version": "v6.0.5",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/filesystem.git",
-        "reference": "348116319d7fb7d1faa781d26a48922428013eb2"
+        "reference": "6646c13f787057d64701a3a0235cf9567c6ccbbd"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/filesystem/zipball/348116319d7fb7d1faa781d26a48922428013eb2",
-        "reference": "348116319d7fb7d1faa781d26a48922428013eb2",
+        "url": "https://api.github.com/repos/symfony/filesystem/zipball/6646c13f787057d64701a3a0235cf9567c6ccbbd",
+        "reference": "6646c13f787057d64701a3a0235cf9567c6ccbbd",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/polyfill-ctype": "~1.8"
+        "php": ">=8.0.2",
+        "symfony/polyfill-ctype": "~1.8",
+        "symfony/polyfill-mbstring": "~1.8"
       },
       "type": "library",
       "autoload": {
@@ -5807,7 +5681,7 @@
       "description": "Provides basic utilities for the filesystem",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/filesystem/tree/v5.3.0"
+        "source": "https://github.com/symfony/filesystem/tree/v6.0.5"
       },
       "funding": [
         {
@@ -5823,24 +5697,24 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2022-02-28T07:42:30+00:00"
     },
     {
       "name": "symfony/finder",
-      "version": "v5.3.0",
+      "version": "v6.0.3",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/finder.git",
-        "reference": "0ae3f047bed4edff6fd35b26a9a6bfdc92c953c6"
+        "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/finder/zipball/0ae3f047bed4edff6fd35b26a9a6bfdc92c953c6",
-        "reference": "0ae3f047bed4edff6fd35b26a9a6bfdc92c953c6",
+        "url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430",
+        "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5"
+        "php": ">=8.0.2"
       },
       "type": "library",
       "autoload": {
@@ -5864,7 +5738,7 @@
       "description": "Finds files and directories via an intuitive fluent interface",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/finder/tree/v5.3.0"
+        "source": "https://github.com/symfony/finder/tree/v6.0.3"
       },
       "funding": [
         {
@@ -5880,67 +5754,50 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T12:52:38+00:00"
+      "time": "2022-01-26T17:23:29+00:00"
     },
     {
-      "name": "symfony/http-client-contracts",
-      "version": "v2.4.0",
+      "name": "symfony/options-resolver",
+      "version": "v6.0.3",
       "source": {
         "type": "git",
-        "url": "https://github.com/symfony/http-client-contracts.git",
-        "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4"
+        "url": "https://github.com/symfony/options-resolver.git",
+        "reference": "51f7006670febe4cbcbae177cbffe93ff833250d"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4",
-        "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4",
+        "url": "https://api.github.com/repos/symfony/options-resolver/zipball/51f7006670febe4cbcbae177cbffe93ff833250d",
+        "reference": "51f7006670febe4cbcbae177cbffe93ff833250d",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5"
-      },
-      "suggest": {
-        "symfony/http-client-implementation": ""
+        "php": ">=8.0.2",
+        "symfony/deprecation-contracts": "^2.1|^3"
       },
       "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "2.4-dev"
-        },
-        "thanks": {
-          "name": "symfony/contracts",
-          "url": "https://github.com/symfony/contracts"
-        }
-      },
       "autoload": {
         "psr-4": {
-          "Symfony\\Contracts\\HttpClient\\": ""
-        }
+          "Symfony\\Component\\OptionsResolver\\": ""
+        },
+        "exclude-from-classmap": ["/Tests/"]
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
       "authors": [
         {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
+          "name": "Fabien Potencier",
+          "email": "fabien@symfony.com"
         },
         {
           "name": "Symfony Community",
           "homepage": "https://symfony.com/contributors"
         }
       ],
-      "description": "Generic abstractions related to HTTP clients",
+      "description": "Provides an improved replacement for the array_replace PHP function",
       "homepage": "https://symfony.com",
-      "keywords": [
-        "abstractions",
-        "contracts",
-        "decoupling",
-        "interfaces",
-        "interoperability",
-        "standards"
-      ],
+      "keywords": ["config", "configuration", "options"],
       "support": {
-        "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0"
+        "source": "https://github.com/symfony/options-resolver/tree/v6.0.3"
       },
       "funding": [
         {
@@ -5956,60 +5813,68 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-04-11T23:07:08+00:00"
+      "time": "2022-01-02T09:55:41+00:00"
     },
     {
-      "name": "symfony/http-foundation",
-      "version": "v5.3.1",
+      "name": "symfony/polyfill-intl-grapheme",
+      "version": "v1.24.0",
       "source": {
         "type": "git",
-        "url": "https://github.com/symfony/http-foundation.git",
-        "reference": "8827b90cf8806e467124ad476acd15216c2fceb6"
+        "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+        "reference": "81b86b50cf841a64252b439e738e97f4a34e2783"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8827b90cf8806e467124ad476acd15216c2fceb6",
-        "reference": "8827b90cf8806e467124ad476acd15216c2fceb6",
+        "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783",
+        "reference": "81b86b50cf841a64252b439e738e97f4a34e2783",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/polyfill-mbstring": "~1.1",
-        "symfony/polyfill-php80": "^1.15"
-      },
-      "require-dev": {
-        "predis/predis": "~1.0",
-        "symfony/cache": "^4.4|^5.0",
-        "symfony/expression-language": "^4.4|^5.0",
-        "symfony/mime": "^4.4|^5.0"
+        "php": ">=7.1"
       },
       "suggest": {
-        "symfony/mime": "To use the file extension guesser"
+        "ext-intl": "For best performance"
       },
       "type": "library",
+      "extra": {
+        "branch-alias": {
+          "dev-main": "1.23-dev"
+        },
+        "thanks": {
+          "name": "symfony/polyfill",
+          "url": "https://github.com/symfony/polyfill"
+        }
+      },
       "autoload": {
+        "files": ["bootstrap.php"],
         "psr-4": {
-          "Symfony\\Component\\HttpFoundation\\": ""
-        },
-        "exclude-from-classmap": ["/Tests/"]
+          "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+        }
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
       "authors": [
         {
-          "name": "Fabien Potencier",
-          "email": "fabien@symfony.com"
+          "name": "Nicolas Grekas",
+          "email": "p@tchwork.com"
         },
         {
           "name": "Symfony Community",
           "homepage": "https://symfony.com/contributors"
         }
       ],
-      "description": "Defines an object-oriented layer for the HTTP specification",
+      "description": "Symfony polyfill for intl's grapheme_* functions",
       "homepage": "https://symfony.com",
+      "keywords": [
+        "compatibility",
+        "grapheme",
+        "intl",
+        "polyfill",
+        "portable",
+        "shim"
+      ],
       "support": {
-        "source": "https://github.com/symfony/http-foundation/tree/v5.3.1"
+        "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0"
       },
       "funding": [
         {
@@ -6025,99 +5890,69 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-06-02T09:32:00+00:00"
+      "time": "2021-11-23T21:10:46+00:00"
     },
     {
-      "name": "symfony/http-kernel",
-      "version": "v5.3.1",
+      "name": "symfony/polyfill-intl-normalizer",
+      "version": "v1.24.0",
       "source": {
         "type": "git",
-        "url": "https://github.com/symfony/http-kernel.git",
-        "reference": "74eb022e3bac36b3d3a897951a98759f2b32b864"
+        "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+        "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/http-kernel/zipball/74eb022e3bac36b3d3a897951a98759f2b32b864",
-        "reference": "74eb022e3bac36b3d3a897951a98759f2b32b864",
+        "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
+        "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "psr/log": "~1.0",
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/error-handler": "^4.4|^5.0",
-        "symfony/event-dispatcher": "^5.0",
-        "symfony/http-client-contracts": "^1.1|^2",
-        "symfony/http-foundation": "^5.3",
-        "symfony/polyfill-ctype": "^1.8",
-        "symfony/polyfill-php73": "^1.9",
-        "symfony/polyfill-php80": "^1.15"
-      },
-      "conflict": {
-        "symfony/browser-kit": "<4.4",
-        "symfony/cache": "<5.0",
-        "symfony/config": "<5.0",
-        "symfony/console": "<4.4",
-        "symfony/dependency-injection": "<5.3",
-        "symfony/doctrine-bridge": "<5.0",
-        "symfony/form": "<5.0",
-        "symfony/http-client": "<5.0",
-        "symfony/mailer": "<5.0",
-        "symfony/messenger": "<5.0",
-        "symfony/translation": "<5.0",
-        "symfony/twig-bridge": "<5.0",
-        "symfony/validator": "<5.0",
-        "twig/twig": "<2.13"
-      },
-      "provide": {
-        "psr/log-implementation": "1.0"
-      },
-      "require-dev": {
-        "psr/cache": "^1.0|^2.0|^3.0",
-        "symfony/browser-kit": "^4.4|^5.0",
-        "symfony/config": "^5.0",
-        "symfony/console": "^4.4|^5.0",
-        "symfony/css-selector": "^4.4|^5.0",
-        "symfony/dependency-injection": "^5.3",
-        "symfony/dom-crawler": "^4.4|^5.0",
-        "symfony/expression-language": "^4.4|^5.0",
-        "symfony/finder": "^4.4|^5.0",
-        "symfony/process": "^4.4|^5.0",
-        "symfony/routing": "^4.4|^5.0",
-        "symfony/stopwatch": "^4.4|^5.0",
-        "symfony/translation": "^4.4|^5.0",
-        "symfony/translation-contracts": "^1.1|^2",
-        "twig/twig": "^2.13|^3.0.4"
+        "php": ">=7.1"
       },
       "suggest": {
-        "symfony/browser-kit": "",
-        "symfony/config": "",
-        "symfony/console": "",
-        "symfony/dependency-injection": ""
+        "ext-intl": "For best performance"
       },
       "type": "library",
+      "extra": {
+        "branch-alias": {
+          "dev-main": "1.23-dev"
+        },
+        "thanks": {
+          "name": "symfony/polyfill",
+          "url": "https://github.com/symfony/polyfill"
+        }
+      },
       "autoload": {
+        "files": ["bootstrap.php"],
         "psr-4": {
-          "Symfony\\Component\\HttpKernel\\": ""
+          "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
         },
-        "exclude-from-classmap": ["/Tests/"]
+        "classmap": ["Resources/stubs"]
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
       "authors": [
         {
-          "name": "Fabien Potencier",
-          "email": "fabien@symfony.com"
+          "name": "Nicolas Grekas",
+          "email": "p@tchwork.com"
         },
         {
           "name": "Symfony Community",
           "homepage": "https://symfony.com/contributors"
         }
       ],
-      "description": "Provides a structured process for converting a Request into a Response",
+      "description": "Symfony polyfill for intl's Normalizer class and related functions",
       "homepage": "https://symfony.com",
+      "keywords": [
+        "compatibility",
+        "intl",
+        "normalizer",
+        "polyfill",
+        "portable",
+        "shim"
+      ],
       "support": {
-        "source": "https://github.com/symfony/http-kernel/tree/v5.3.1"
+        "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0"
       },
       "funding": [
         {
@@ -6133,444 +5968,24 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-06-02T10:07:12+00:00"
-    },
-    {
-      "name": "symfony/options-resolver",
-      "version": "v5.3.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/options-resolver.git",
-        "reference": "162e886ca035869866d233a2bfef70cc28f9bbe5"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/options-resolver/zipball/162e886ca035869866d233a2bfef70cc28f9bbe5",
-        "reference": "162e886ca035869866d233a2bfef70cc28f9bbe5",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.2.5",
-        "symfony/deprecation-contracts": "^2.1",
-        "symfony/polyfill-php73": "~1.0",
-        "symfony/polyfill-php80": "^1.15"
-      },
-      "type": "library",
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Component\\OptionsResolver\\": ""
-        },
-        "exclude-from-classmap": ["/Tests/"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Fabien Potencier",
-          "email": "fabien@symfony.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Provides an improved replacement for the array_replace PHP function",
-      "homepage": "https://symfony.com",
-      "keywords": ["config", "configuration", "options"],
-      "support": {
-        "source": "https://github.com/symfony/options-resolver/tree/v5.3.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-05-26T17:43:10+00:00"
-    },
-    {
-      "name": "symfony/polyfill-intl-grapheme",
-      "version": "v1.23.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
-        "reference": "24b72c6baa32c746a4d0840147c9715e42bb68ab"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/24b72c6baa32c746a4d0840147c9715e42bb68ab",
-        "reference": "24b72c6baa32c746a4d0840147c9715e42bb68ab",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.1"
-      },
-      "suggest": {
-        "ext-intl": "For best performance"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "1.23-dev"
-        },
-        "thanks": {
-          "name": "symfony/polyfill",
-          "url": "https://github.com/symfony/polyfill"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
-        },
-        "files": ["bootstrap.php"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Symfony polyfill for intl's grapheme_* functions",
-      "homepage": "https://symfony.com",
-      "keywords": [
-        "compatibility",
-        "grapheme",
-        "intl",
-        "polyfill",
-        "portable",
-        "shim"
-      ],
-      "support": {
-        "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-05-27T09:17:38+00:00"
-    },
-    {
-      "name": "symfony/polyfill-intl-normalizer",
-      "version": "v1.23.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
-        "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
-        "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.1"
-      },
-      "suggest": {
-        "ext-intl": "For best performance"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "1.23-dev"
-        },
-        "thanks": {
-          "name": "symfony/polyfill",
-          "url": "https://github.com/symfony/polyfill"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
-        },
-        "files": ["bootstrap.php"],
-        "classmap": ["Resources/stubs"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Symfony polyfill for intl's Normalizer class and related functions",
-      "homepage": "https://symfony.com",
-      "keywords": [
-        "compatibility",
-        "intl",
-        "normalizer",
-        "polyfill",
-        "portable",
-        "shim"
-      ],
-      "support": {
-        "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-02-19T12:13:01+00:00"
-    },
-    {
-      "name": "symfony/polyfill-php72",
-      "version": "v1.23.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/polyfill-php72.git",
-        "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
-        "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.1"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "1.23-dev"
-        },
-        "thanks": {
-          "name": "symfony/polyfill",
-          "url": "https://github.com/symfony/polyfill"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Polyfill\\Php72\\": ""
-        },
-        "files": ["bootstrap.php"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
-      "homepage": "https://symfony.com",
-      "keywords": ["compatibility", "polyfill", "portable", "shim"],
-      "support": {
-        "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-05-27T09:17:38+00:00"
-    },
-    {
-      "name": "symfony/polyfill-php73",
-      "version": "v1.23.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/polyfill-php73.git",
-        "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010",
-        "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.1"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "1.23-dev"
-        },
-        "thanks": {
-          "name": "symfony/polyfill",
-          "url": "https://github.com/symfony/polyfill"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Polyfill\\Php73\\": ""
-        },
-        "files": ["bootstrap.php"],
-        "classmap": ["Resources/stubs"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
-      "homepage": "https://symfony.com",
-      "keywords": ["compatibility", "polyfill", "portable", "shim"],
-      "support": {
-        "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-02-19T12:13:01+00:00"
-    },
-    {
-      "name": "symfony/polyfill-php81",
-      "version": "v1.23.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/polyfill-php81.git",
-        "reference": "e66119f3de95efc359483f810c4c3e6436279436"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436",
-        "reference": "e66119f3de95efc359483f810c4c3e6436279436",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.1"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "1.23-dev"
-        },
-        "thanks": {
-          "name": "symfony/polyfill",
-          "url": "https://github.com/symfony/polyfill"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Polyfill\\Php81\\": ""
-        },
-        "files": ["bootstrap.php"],
-        "classmap": ["Resources/stubs"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
-      ],
-      "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
-      "homepage": "https://symfony.com",
-      "keywords": ["compatibility", "polyfill", "portable", "shim"],
-      "support": {
-        "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-05-21T13:25:03+00:00"
+      "time": "2021-02-19T12:13:01+00:00"
     },
     {
       "name": "symfony/process",
-      "version": "v5.3.0",
+      "version": "v6.0.5",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/process.git",
-        "reference": "53e36cb1c160505cdaf1ef201501669c4c317191"
+        "reference": "1ccceccc6497e96f4f646218f04b97ae7d9fa7a1"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/process/zipball/53e36cb1c160505cdaf1ef201501669c4c317191",
-        "reference": "53e36cb1c160505cdaf1ef201501669c4c317191",
+        "url": "https://api.github.com/repos/symfony/process/zipball/1ccceccc6497e96f4f646218f04b97ae7d9fa7a1",
+        "reference": "1ccceccc6497e96f4f646218f04b97ae7d9fa7a1",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/polyfill-php80": "^1.15"
+        "php": ">=8.0.2"
       },
       "type": "library",
       "autoload": {
@@ -6594,7 +6009,7 @@
       "description": "Executes commands in sub-processes",
       "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/process/tree/v5.3.0"
+        "source": "https://github.com/symfony/process/tree/v6.0.5"
       },
       "funding": [
         {
@@ -6610,25 +6025,28 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T12:52:38+00:00"
+      "time": "2022-01-30T18:19:12+00:00"
     },
     {
       "name": "symfony/service-contracts",
-      "version": "v2.4.0",
+      "version": "v3.0.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symfony/service-contracts.git",
-        "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb"
+        "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb",
-        "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb",
+        "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603",
+        "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "psr/container": "^1.1"
+        "php": ">=8.0.2",
+        "psr/container": "^2.0"
+      },
+      "conflict": {
+        "ext-psr": "<1.1|>=2"
       },
       "suggest": {
         "symfony/service-implementation": ""
@@ -6636,7 +6054,7 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "2.4-dev"
+          "dev-main": "3.0-dev"
         },
         "thanks": {
           "name": "symfony/contracts",
@@ -6665,71 +6083,13 @@
       "keywords": [
         "abstractions",
         "contracts",
-        "decoupling",
-        "interfaces",
-        "interoperability",
-        "standards"
-      ],
-      "support": {
-        "source": "https://github.com/symfony/service-contracts/tree/v2.4.0"
-      },
-      "funding": [
-        {
-          "url": "https://symfony.com/sponsor",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/fabpot",
-          "type": "github"
-        },
-        {
-          "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-          "type": "tidelift"
-        }
-      ],
-      "time": "2021-04-01T10:43:52+00:00"
-    },
-    {
-      "name": "symfony/stopwatch",
-      "version": "v5.3.0",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symfony/stopwatch.git",
-        "reference": "313d02f59d6543311865007e5ff4ace05b35ee65"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symfony/stopwatch/zipball/313d02f59d6543311865007e5ff4ace05b35ee65",
-        "reference": "313d02f59d6543311865007e5ff4ace05b35ee65",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.2.5",
-        "symfony/service-contracts": "^1.0|^2"
-      },
-      "type": "library",
-      "autoload": {
-        "psr-4": {
-          "Symfony\\Component\\Stopwatch\\": ""
-        },
-        "exclude-from-classmap": ["/Tests/"]
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "authors": [
-        {
-          "name": "Fabien Potencier",
-          "email": "fabien@symfony.com"
-        },
-        {
-          "name": "Symfony Community",
-          "homepage": "https://symfony.com/contributors"
-        }
+        "decoupling",
+        "interfaces",
+        "interoperability",
+        "standards"
       ],
-      "description": "Provides a way to profile code",
-      "homepage": "https://symfony.com",
       "support": {
-        "source": "https://github.com/symfony/stopwatch/tree/v5.3.0"
+        "source": "https://github.com/symfony/service-contracts/tree/v3.0.0"
       },
       "funding": [
         {
@@ -6745,61 +6105,49 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2021-11-04T17:53:12+00:00"
     },
     {
-      "name": "symfony/string",
-      "version": "v5.3.0",
+      "name": "symfony/stopwatch",
+      "version": "v6.0.5",
       "source": {
         "type": "git",
-        "url": "https://github.com/symfony/string.git",
-        "reference": "a9a0f8b6aafc5d2d1c116dcccd1573a95153515b"
+        "url": "https://github.com/symfony/stopwatch.git",
+        "reference": "f2c1780607ec6502f2121d9729fd8150a655d337"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/string/zipball/a9a0f8b6aafc5d2d1c116dcccd1573a95153515b",
-        "reference": "a9a0f8b6aafc5d2d1c116dcccd1573a95153515b",
+        "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f2c1780607ec6502f2121d9729fd8150a655d337",
+        "reference": "f2c1780607ec6502f2121d9729fd8150a655d337",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/polyfill-ctype": "~1.8",
-        "symfony/polyfill-intl-grapheme": "~1.0",
-        "symfony/polyfill-intl-normalizer": "~1.0",
-        "symfony/polyfill-mbstring": "~1.0",
-        "symfony/polyfill-php80": "~1.15"
-      },
-      "require-dev": {
-        "symfony/error-handler": "^4.4|^5.0",
-        "symfony/http-client": "^4.4|^5.0",
-        "symfony/translation-contracts": "^1.1|^2",
-        "symfony/var-exporter": "^4.4|^5.0"
+        "php": ">=8.0.2",
+        "symfony/service-contracts": "^1|^2|^3"
       },
       "type": "library",
       "autoload": {
         "psr-4": {
-          "Symfony\\Component\\String\\": ""
+          "Symfony\\Component\\Stopwatch\\": ""
         },
-        "files": ["Resources/functions.php"],
         "exclude-from-classmap": ["/Tests/"]
       },
       "notification-url": "https://packagist.org/downloads/",
       "license": ["MIT"],
       "authors": [
         {
-          "name": "Nicolas Grekas",
-          "email": "p@tchwork.com"
+          "name": "Fabien Potencier",
+          "email": "fabien@symfony.com"
         },
         {
           "name": "Symfony Community",
           "homepage": "https://symfony.com/contributors"
         }
       ],
-      "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+      "description": "Provides a way to profile code",
       "homepage": "https://symfony.com",
-      "keywords": ["grapheme", "i18n", "string", "unicode", "utf-8", "utf8"],
       "support": {
-        "source": "https://github.com/symfony/string/tree/v5.3.0"
+        "source": "https://github.com/symfony/stopwatch/tree/v6.0.5"
       },
       "funding": [
         {
@@ -6815,48 +6163,43 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-26T17:43:10+00:00"
+      "time": "2022-02-21T17:15:17+00:00"
     },
     {
-      "name": "symfony/var-dumper",
-      "version": "v5.3.0",
+      "name": "symfony/string",
+      "version": "v6.0.3",
       "source": {
         "type": "git",
-        "url": "https://github.com/symfony/var-dumper.git",
-        "reference": "1d3953e627fe4b5f6df503f356b6545ada6351f3"
+        "url": "https://github.com/symfony/string.git",
+        "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1d3953e627fe4b5f6df503f356b6545ada6351f3",
-        "reference": "1d3953e627fe4b5f6df503f356b6545ada6351f3",
+        "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2",
+        "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.2.5",
-        "symfony/polyfill-mbstring": "~1.0",
-        "symfony/polyfill-php80": "^1.15"
+        "php": ">=8.0.2",
+        "symfony/polyfill-ctype": "~1.8",
+        "symfony/polyfill-intl-grapheme": "~1.0",
+        "symfony/polyfill-intl-normalizer": "~1.0",
+        "symfony/polyfill-mbstring": "~1.0"
       },
       "conflict": {
-        "phpunit/phpunit": "<5.4.3",
-        "symfony/console": "<4.4"
+        "symfony/translation-contracts": "<2.0"
       },
       "require-dev": {
-        "ext-iconv": "*",
-        "symfony/console": "^4.4|^5.0",
-        "symfony/process": "^4.4|^5.0",
-        "twig/twig": "^2.13|^3.0.4"
-      },
-      "suggest": {
-        "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
-        "ext-intl": "To show region name in time zone dump",
-        "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+        "symfony/error-handler": "^5.4|^6.0",
+        "symfony/http-client": "^5.4|^6.0",
+        "symfony/translation-contracts": "^2.0|^3.0",
+        "symfony/var-exporter": "^5.4|^6.0"
       },
-      "bin": ["Resources/bin/var-dump-server"],
       "type": "library",
       "autoload": {
-        "files": ["Resources/functions/dump.php"],
+        "files": ["Resources/functions.php"],
         "psr-4": {
-          "Symfony\\Component\\VarDumper\\": ""
+          "Symfony\\Component\\String\\": ""
         },
         "exclude-from-classmap": ["/Tests/"]
       },
@@ -6872,11 +6215,11 @@
           "homepage": "https://symfony.com/contributors"
         }
       ],
-      "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+      "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
       "homepage": "https://symfony.com",
-      "keywords": ["debug", "dump"],
+      "keywords": ["grapheme", "i18n", "string", "unicode", "utf-8", "utf8"],
       "support": {
-        "source": "https://github.com/symfony/var-dumper/tree/v5.3.0"
+        "source": "https://github.com/symfony/string/tree/v6.0.3"
       },
       "funding": [
         {
@@ -6892,83 +6235,55 @@
           "type": "tidelift"
         }
       ],
-      "time": "2021-05-27T12:28:50+00:00"
-    },
-    {
-      "name": "symplify/astral",
-      "version": "v9.3.22",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symplify/astral.git",
-        "reference": "2d205265eacad08eb5b620ddfa71b334ce992233"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symplify/astral/zipball/2d205265eacad08eb5b620ddfa71b334ce992233",
-        "reference": "2d205265eacad08eb5b620ddfa71b334ce992233",
-        "shasum": ""
-      },
-      "require": {
-        "nette/utils": "^3.2",
-        "nikic/php-parser": "4.10.5",
-        "php": ">=7.3",
-        "symfony/dependency-injection": "^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/autowire-array-parameter": "^9.3.22",
-        "symplify/package-builder": "^9.3.22"
-      },
-      "require-dev": {
-        "phpunit/phpunit": "^9.5",
-        "symplify/easy-testing": "^9.3.22"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "9.4-dev"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symplify\\Astral\\": "src"
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "Toolking for smart daily work with AST",
-      "support": {
-        "source": "https://github.com/symplify/astral/tree/v9.3.22"
-      },
-      "funding": [
-        {
-          "url": "https://www.paypal.me/rectorphp",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/tomasvotruba",
-          "type": "github"
-        }
-      ],
-      "time": "2021-06-10T09:28:23+00:00"
+      "time": "2022-01-02T09:55:41+00:00"
     },
     {
       "name": "symplify/autowire-array-parameter",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/autowire-array-parameter.git",
-        "reference": "7794f4d1eafa7e32905e8b38d37eae7b597ed1a8"
+        "reference": "2d2302ac04294a9c7af06e5e29a6363749f17bae"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/autowire-array-parameter/zipball/7794f4d1eafa7e32905e8b38d37eae7b597ed1a8",
-        "reference": "7794f4d1eafa7e32905e8b38d37eae7b597ed1a8",
+        "url": "https://api.github.com/repos/symplify/autowire-array-parameter/zipball/2d2302ac04294a9c7af06e5e29a6363749f17bae",
+        "reference": "2d2302ac04294a9c7af06e5e29a6363749f17bae",
         "shasum": ""
       },
       "require": {
         "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "symfony/dependency-injection": "^5.2",
-        "symplify/package-builder": "^9.3.22"
+        "php": ">=8.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symplify/package-builder": "^10.1"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/composer-json-manipulator": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/easy-testing": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/rule-doc-generator-contracts": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/smart-file-system": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/symplify-kernel": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
         "phpunit/phpunit": "^9.5"
@@ -6976,7 +6291,7 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -6988,7 +6303,7 @@
       "license": ["MIT"],
       "description": "Autowire array parameters for your Symfony applications",
       "support": {
-        "source": "https://github.com/symplify/autowire-array-parameter/tree/v9.3.22"
+        "source": "https://github.com/symplify/autowire-array-parameter/tree/10.1.0"
       },
       "funding": [
         {
@@ -7000,46 +6315,71 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T09:28:28+00:00"
+      "time": "2022-02-21T11:14:54+00:00"
     },
     {
       "name": "symplify/coding-standard",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/coding-standard.git",
-        "reference": "3ce70069790d35e6d6377675778157b573f3a2dd"
+        "reference": "752145634b0e6f9924be3093b3669cca4f759dc0"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/coding-standard/zipball/3ce70069790d35e6d6377675778157b573f3a2dd",
-        "reference": "3ce70069790d35e6d6377675778157b573f3a2dd",
+        "url": "https://api.github.com/repos/symplify/coding-standard/zipball/752145634b0e6f9924be3093b3669cca4f759dc0",
+        "reference": "752145634b0e6f9924be3093b3669cca4f759dc0",
         "shasum": ""
       },
       "require": {
-        "friendsofphp/php-cs-fixer": "^3.0",
+        "friendsofphp/php-cs-fixer": "^3.6",
         "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "symplify/autowire-array-parameter": "^9.3.22",
-        "symplify/package-builder": "^9.3.22",
-        "symplify/rule-doc-generator-contracts": "^9.3.22",
-        "symplify/symplify-kernel": "^9.3.22"
+        "php": ">=8.0",
+        "symplify/autowire-array-parameter": "^10.1",
+        "symplify/package-builder": "^10.1",
+        "symplify/rule-doc-generator-contracts": "^10.1",
+        "symplify/symplify-kernel": "^10.1"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/composer-json-manipulator": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/easy-testing": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/smart-file-system": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
-        "doctrine/orm": "^2.7",
+        "doctrine/orm": "^2.10",
         "nette/application": "^3.1",
         "nette/bootstrap": "^3.1",
         "phpunit/phpunit": "^9.5",
-        "symfony/framework-bundle": "^4.4|^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/easy-coding-standard": "^9.3.22",
-        "symplify/rule-doc-generator": "^9.3.22",
-        "symplify/smart-file-system": "^9.3.22"
+        "symfony/framework-bundle": "^5.4|^6.0",
+        "symplify/easy-coding-standard": "^10.1",
+        "symplify/rule-doc-generator": "^10.1",
+        "symplify/smart-file-system": "^10.1",
+        "symplify/symplify-kernel": "^10.1"
       },
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7051,7 +6391,7 @@
       "license": ["MIT"],
       "description": "Set of Symplify rules for PHP_CodeSniffer and PHP CS Fixer.",
       "support": {
-        "source": "https://github.com/symplify/coding-standard/tree/v9.3.22"
+        "source": "https://github.com/symplify/coding-standard/tree/10.1.0"
       },
       "funding": [
         {
@@ -7063,31 +6403,58 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T09:28:27+00:00"
+      "time": "2022-02-21T11:15:00+00:00"
     },
     {
       "name": "symplify/composer-json-manipulator",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/composer-json-manipulator.git",
-        "reference": "a3d711ec0928cf8ddf3e4c16dad335318d588679"
+        "reference": "73fcdc1153dbe9d12a5d4fb1ddae07d600eff1c3"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/composer-json-manipulator/zipball/a3d711ec0928cf8ddf3e4c16dad335318d588679",
-        "reference": "a3d711ec0928cf8ddf3e4c16dad335318d588679",
+        "url": "https://api.github.com/repos/symplify/composer-json-manipulator/zipball/73fcdc1153dbe9d12a5d4fb1ddae07d600eff1c3",
+        "reference": "73fcdc1153dbe9d12a5d4fb1ddae07d600eff1c3",
         "shasum": ""
       },
       "require": {
         "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "symfony/config": "^4.4|^5.2",
-        "symfony/dependency-injection": "^5.2",
-        "symfony/filesystem": "^4.4|^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/package-builder": "^9.3.22",
-        "symplify/smart-file-system": "^9.3.22"
+        "php": ">=8.0",
+        "symfony/config": "^5.4|^6.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symfony/filesystem": "^5.4|^6.0",
+        "symplify/package-builder": "^10.1",
+        "symplify/smart-file-system": "^10.1",
+        "symplify/symplify-kernel": "^10.1"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/autowire-array-parameter": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/easy-testing": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/rule-doc-generator-contracts": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/symplify-kernel": "<9.4.70",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
         "phpunit/phpunit": "^9.5"
@@ -7095,7 +6462,7 @@
       "type": "symfony-bundle",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7107,7 +6474,7 @@
       "license": ["MIT"],
       "description": "Package to load, merge and save composer.json file(s)",
       "support": {
-        "source": "https://github.com/symplify/composer-json-manipulator/tree/v9.3.22"
+        "source": "https://github.com/symplify/composer-json-manipulator/tree/10.1.0"
       },
       "funding": [
         {
@@ -7119,64 +6486,20 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T09:28:23+00:00"
-    },
-    {
-      "name": "symplify/console-package-builder",
-      "version": "v9.3.22",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symplify/console-package-builder.git",
-        "reference": "14a0eeaed45b850e579ddd16913a5d74ec856f16"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symplify/console-package-builder/zipball/14a0eeaed45b850e579ddd16913a5d74ec856f16",
-        "reference": "14a0eeaed45b850e579ddd16913a5d74ec856f16",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.3",
-        "symfony/console": "^4.4|^5.2",
-        "symfony/dependency-injection": "^5.2",
-        "symplify/symplify-kernel": "^9.3.22"
-      },
-      "require-dev": {
-        "phpunit/phpunit": "^9.5",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/package-builder": "^9.3.22"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "9.4-dev"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symplify\\ConsolePackageBuilder\\": "src"
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "Package to speed up building command line applications",
-      "support": {
-        "source": "https://github.com/symplify/console-package-builder/tree/v9.3.22"
-      },
-      "time": "2021-06-10T09:28:40+00:00"
+      "time": "2022-02-21T11:15:03+00:00"
     },
     {
       "name": "symplify/easy-coding-standard",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/easy-coding-standard.git",
-        "reference": "7ada08f221241f513531588585e55f423100705d"
+        "reference": "dcad0cff507fc3e56bf345dcd634dbea3ce0917e"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/7ada08f221241f513531588585e55f423100705d",
-        "reference": "7ada08f221241f513531588585e55f423100705d",
+        "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/dcad0cff507fc3e56bf345dcd634dbea3ce0917e",
+        "reference": "dcad0cff507fc3e56bf345dcd634dbea3ce0917e",
         "shasum": ""
       },
       "require": {
@@ -7188,6 +6511,11 @@
       },
       "bin": ["bin/ecs"],
       "type": "library",
+      "extra": {
+        "branch-alias": {
+          "dev-main": "9.5-dev"
+        }
+      },
       "autoload": {
         "files": ["bootstrap.php"]
       },
@@ -7195,7 +6523,7 @@
       "license": ["MIT"],
       "description": "Prefixed scoped version of ECS package",
       "support": {
-        "source": "https://github.com/symplify/easy-coding-standard/tree/v9.3.22"
+        "source": "https://github.com/symplify/easy-coding-standard/tree/10.1.0"
       },
       "funding": [
         {
@@ -7207,33 +6535,57 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T09:29:11+00:00"
+      "time": "2022-02-21T11:18:44+00:00"
     },
     {
       "name": "symplify/easy-testing",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/easy-testing.git",
-        "reference": "6d5543190c9d578b61d9181d77d7255340743929"
+        "reference": "1fcd31f2542a705858eac77bc36ddf43fa799c0e"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/easy-testing/zipball/6d5543190c9d578b61d9181d77d7255340743929",
-        "reference": "6d5543190c9d578b61d9181d77d7255340743929",
+        "url": "https://api.github.com/repos/symplify/easy-testing/zipball/1fcd31f2542a705858eac77bc36ddf43fa799c0e",
+        "reference": "1fcd31f2542a705858eac77bc36ddf43fa799c0e",
         "shasum": ""
       },
       "require": {
         "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "symfony/console": "^4.4|^5.2",
-        "symfony/dependency-injection": "^5.2",
-        "symfony/finder": "^4.4|^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/console-package-builder": "^9.3.22",
-        "symplify/package-builder": "^9.3.22",
-        "symplify/smart-file-system": "^9.3.22",
-        "symplify/symplify-kernel": "^9.3.22"
+        "php": ">=8.0",
+        "symfony/console": "^5.4|^6.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symfony/finder": "^5.4|^6.0",
+        "symplify/package-builder": "^10.1",
+        "symplify/smart-file-system": "^10.1",
+        "symplify/symplify-kernel": "^10.1"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/autowire-array-parameter": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/composer-json-manipulator": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/rule-doc-generator-contracts": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
         "phpunit/phpunit": "^9.5"
@@ -7242,7 +6594,7 @@
       "type": "symfony-bundle",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7254,7 +6606,7 @@
       "license": ["MIT"],
       "description": "Testing made easy",
       "support": {
-        "source": "https://github.com/symplify/easy-testing/tree/v9.3.22"
+        "source": "https://github.com/symplify/easy-testing/tree/10.1.0"
       },
       "funding": [
         {
@@ -7266,42 +6618,68 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T09:28:48+00:00"
+      "time": "2022-02-21T11:15:10+00:00"
     },
     {
       "name": "symplify/package-builder",
-      "version": "dev-main",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/package-builder.git",
-        "reference": "a86c7bd0307ba0b368510851e86082f773e64138"
+        "reference": "3a83129159832622fbb4317def676337301d8300"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/package-builder/zipball/a86c7bd0307ba0b368510851e86082f773e64138",
-        "reference": "a86c7bd0307ba0b368510851e86082f773e64138",
+        "url": "https://api.github.com/repos/symplify/package-builder/zipball/3a83129159832622fbb4317def676337301d8300",
+        "reference": "3a83129159832622fbb4317def676337301d8300",
         "shasum": ""
       },
       "require": {
-        "nette/neon": "^3.2",
+        "nette/neon": "^3.3.2",
         "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "symfony/config": "^4.4|^5.2",
-        "symfony/console": "^4.4|^5.2",
-        "symfony/dependency-injection": "^5.2",
-        "symfony/finder": "^4.4|^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/easy-testing": "^9.3.22",
-        "symplify/symplify-kernel": "^9.3.22"
+        "php": ">=8.0",
+        "sebastian/diff": "^4.0",
+        "symfony/config": "^5.4|^6.0",
+        "symfony/console": "^5.4|^6.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symfony/finder": "^5.4|^6.0",
+        "symplify/easy-testing": "^10.1",
+        "symplify/symplify-kernel": "^10.1"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/autowire-array-parameter": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/composer-json-manipulator": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/rule-doc-generator-contracts": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/smart-file-system": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
         "phpunit/phpunit": "^9.5"
       },
-      "default-branch": true,
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7313,138 +6691,7 @@
       "license": ["MIT"],
       "description": "Dependency Injection, Console and Kernel toolkit for Symplify packages.",
       "support": {
-        "source": "https://github.com/symplify/package-builder/tree/main"
-      },
-      "funding": [
-        {
-          "url": "https://www.paypal.me/rectorphp",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/tomasvotruba",
-          "type": "github"
-        }
-      ],
-      "time": "2021-06-10T09:30:06+00:00"
-    },
-    {
-      "name": "symplify/phpstan-extensions",
-      "version": "v9.3.21",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symplify/phpstan-extensions.git",
-        "reference": "e9c83ac50fe205f28bece8013d92f5a9130dc3d6"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symplify/phpstan-extensions/zipball/e9c83ac50fe205f28bece8013d92f5a9130dc3d6",
-        "reference": "e9c83ac50fe205f28bece8013d92f5a9130dc3d6",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.3",
-        "phpstan/phpstan": "^0.12.88",
-        "symplify/astral": "^9.3.21",
-        "symplify/package-builder": "^9.3.21",
-        "symplify/smart-file-system": "^9.3.21"
-      },
-      "require-dev": {
-        "phpunit/phpunit": "^9.5"
-      },
-      "type": "phpstan-extension",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "9.4-dev"
-        },
-        "phpstan": {
-          "includes": ["config/config.neon"]
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symplify\\PHPStanExtensions\\": "src"
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "Pre-escaped error messages in 'symplify' error format, container aware test case and other useful extensions for PHPStan",
-      "support": {
-        "source": "https://github.com/symplify/phpstan-extensions/tree/v9.3.21"
-      },
-      "funding": [
-        {
-          "url": "https://www.paypal.me/rectorphp",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/tomasvotruba",
-          "type": "github"
-        }
-      ],
-      "time": "2021-06-10T08:50:09+00:00"
-    },
-    {
-      "name": "symplify/phpstan-rules",
-      "version": "v9.3.21",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symplify/phpstan-rules.git",
-        "reference": "1fac85aa8621e29af083b49c71d8ce793ca4dd46"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symplify/phpstan-rules/zipball/1fac85aa8621e29af083b49c71d8ce793ca4dd46",
-        "reference": "1fac85aa8621e29af083b49c71d8ce793ca4dd46",
-        "shasum": ""
-      },
-      "require": {
-        "nette/utils": "^3.2",
-        "nikic/php-parser": "4.10.5",
-        "php": ">=7.3",
-        "phpstan/phpdoc-parser": "^0.5",
-        "phpstan/phpstan": "^0.12.88",
-        "symplify/astral": "^9.3.21",
-        "symplify/composer-json-manipulator": "^9.3.21",
-        "symplify/package-builder": "^9.3.21",
-        "symplify/rule-doc-generator-contracts": "^9.3.21",
-        "symplify/simple-php-doc-parser": "^9.3.21",
-        "symplify/smart-file-system": "^9.3.21",
-        "webmozart/assert": "^1.9"
-      },
-      "require-dev": {
-        "nette/application": "^3.1",
-        "nette/forms": "^3.1",
-        "phpunit/phpunit": "^9.5",
-        "symfony/framework-bundle": "^4.4|^5.2",
-        "symplify/easy-testing": "^9.3.21",
-        "symplify/phpstan-extensions": "^9.3.21",
-        "symplify/rule-doc-generator": "^9.3.21"
-      },
-      "type": "phpstan-extension",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "9.4-dev"
-        },
-        "phpstan": {
-          "includes": [
-            "config/services/services.neon",
-            "packages/cognitive-complexity/config/cognitive-complexity-services.neon",
-            "packages/object-calisthenics/config/object-calisthenics-services.neon"
-          ]
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symplify\\PHPStanRules\\": "src",
-          "Symplify\\PHPStanRules\\CognitiveComplexity\\": "packages/cognitive-complexity/src",
-          "Symplify\\PHPStanRules\\ObjectCalisthenics\\": "packages/object-calisthenics/src"
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "Set of Symplify rules for PHPStan",
-      "support": {
-        "source": "https://github.com/symplify/phpstan-rules/tree/v9.3.21"
+        "source": "https://github.com/symplify/package-builder/tree/10.1.0"
       },
       "funding": [
         {
@@ -7456,31 +6703,59 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T08:50:10+00:00"
+      "time": "2022-02-21T11:15:34+00:00"
     },
     {
       "name": "symplify/rule-doc-generator-contracts",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/rule-doc-generator-contracts.git",
-        "reference": "a6f944a49198ed3260bc941533629e917137e476"
+        "reference": "351303b0b0f277af30a7e9c588fdc8411e0f5500"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/rule-doc-generator-contracts/zipball/a6f944a49198ed3260bc941533629e917137e476",
-        "reference": "a6f944a49198ed3260bc941533629e917137e476",
+        "url": "https://api.github.com/repos/symplify/rule-doc-generator-contracts/zipball/351303b0b0f277af30a7e9c588fdc8411e0f5500",
+        "reference": "351303b0b0f277af30a7e9c588fdc8411e0f5500",
         "shasum": ""
       },
       "require": {
-        "danielstjules/stringy": "^3.1",
         "nette/utils": "^3.2",
-        "php": ">=7.3"
+        "php": ">=8.0"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/autowire-array-parameter": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/composer-json-manipulator": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/easy-testing": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/package-builder": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/smart-file-system": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/symplify-kernel": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7492,62 +6767,7 @@
       "license": ["MIT"],
       "description": "Contracts for production code of RuleDocGenerator",
       "support": {
-        "source": "https://github.com/symplify/rule-doc-generator-contracts/tree/v9.3.22"
-      },
-      "funding": [
-        {
-          "url": "https://www.paypal.me/rectorphp",
-          "type": "custom"
-        },
-        {
-          "url": "https://github.com/tomasvotruba",
-          "type": "github"
-        }
-      ],
-      "time": "2021-06-06T16:17:29+00:00"
-    },
-    {
-      "name": "symplify/simple-php-doc-parser",
-      "version": "v9.3.21",
-      "source": {
-        "type": "git",
-        "url": "https://github.com/symplify/simple-php-doc-parser.git",
-        "reference": "5668608067a6ee4f0513348bdb46319617288ce1"
-      },
-      "dist": {
-        "type": "zip",
-        "url": "https://api.github.com/repos/symplify/simple-php-doc-parser/zipball/5668608067a6ee4f0513348bdb46319617288ce1",
-        "reference": "5668608067a6ee4f0513348bdb46319617288ce1",
-        "shasum": ""
-      },
-      "require": {
-        "php": ">=7.3",
-        "phpstan/phpdoc-parser": "^0.5",
-        "symfony/config": "^4.4|^5.2",
-        "symfony/dependency-injection": "^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/package-builder": "^9.3.21"
-      },
-      "require-dev": {
-        "phpunit/phpunit": "^9.5",
-        "symplify/easy-testing": "^9.3.21"
-      },
-      "type": "library",
-      "extra": {
-        "branch-alias": {
-          "dev-main": "9.4-dev"
-        }
-      },
-      "autoload": {
-        "psr-4": {
-          "Symplify\\SimplePhpDocParser\\": "src"
-        }
-      },
-      "notification-url": "https://packagist.org/downloads/",
-      "license": ["MIT"],
-      "description": "Service integration of phpstan/phpdoc-parser, with few extra goodies for practical simple use",
-      "support": {
-        "source": "https://github.com/symplify/simple-php-doc-parser/tree/v9.3.21"
+        "source": "https://github.com/symplify/rule-doc-generator-contracts/tree/10.1.0"
       },
       "funding": [
         {
@@ -7559,27 +6779,56 @@
           "type": "github"
         }
       ],
-      "time": "2021-06-10T08:50:34+00:00"
+      "time": "2022-02-21T11:16:12+00:00"
     },
     {
       "name": "symplify/smart-file-system",
-      "version": "v9.3.22",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/smart-file-system.git",
-        "reference": "a2a8d39fe46b01ead8d2af7368b0b36b68fac979"
+        "reference": "c676b278b95646700424952fc6d6aaa9e6fbfa8e"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/smart-file-system/zipball/a2a8d39fe46b01ead8d2af7368b0b36b68fac979",
-        "reference": "a2a8d39fe46b01ead8d2af7368b0b36b68fac979",
+        "url": "https://api.github.com/repos/symplify/smart-file-system/zipball/c676b278b95646700424952fc6d6aaa9e6fbfa8e",
+        "reference": "c676b278b95646700424952fc6d6aaa9e6fbfa8e",
         "shasum": ""
       },
       "require": {
         "nette/utils": "^3.2",
-        "php": ">=7.3",
-        "symfony/filesystem": "^4.4|^5.2",
-        "symfony/finder": "^4.4|^5.2"
+        "php": ">=8.0",
+        "symfony/filesystem": "^5.4|^6.0",
+        "symfony/finder": "^5.4|^6.0"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/autowire-array-parameter": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/composer-json-manipulator": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/easy-testing": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/package-builder": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/rule-doc-generator-contracts": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/symplify-kernel": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
         "nette/finder": "^2.5",
@@ -7588,7 +6837,7 @@
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7600,7 +6849,7 @@
       "license": ["MIT"],
       "description": "Sanitized FileInfo with safe getRealPath() and other handy methods",
       "support": {
-        "source": "https://github.com/symplify/smart-file-system/tree/v9.3.22"
+        "source": "https://github.com/symplify/smart-file-system/tree/10.1.0"
       },
       "funding": [
         {
@@ -7612,40 +6861,64 @@
           "type": "github"
         }
       ],
-      "time": "2021-05-20T20:16:49+00:00"
+      "time": "2022-02-21T11:16:15+00:00"
     },
     {
       "name": "symplify/symplify-kernel",
-      "version": "dev-main",
+      "version": "10.1.0",
       "source": {
         "type": "git",
         "url": "https://github.com/symplify/symplify-kernel.git",
-        "reference": "966602555962ef929214be2459bfeef3d0ceb114"
+        "reference": "6c1c0710cea728427d8fdfc461a40d7c35daad82"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/symplify/symplify-kernel/zipball/966602555962ef929214be2459bfeef3d0ceb114",
-        "reference": "966602555962ef929214be2459bfeef3d0ceb114",
+        "url": "https://api.github.com/repos/symplify/symplify-kernel/zipball/6c1c0710cea728427d8fdfc461a40d7c35daad82",
+        "reference": "6c1c0710cea728427d8fdfc461a40d7c35daad82",
         "shasum": ""
       },
       "require": {
-        "php": ">=7.3",
-        "symfony/console": "^4.4|^5.2",
-        "symfony/dependency-injection": "^5.2",
-        "symfony/http-kernel": "^4.4|^5.2",
-        "symplify/autowire-array-parameter": "^9.3.22",
-        "symplify/composer-json-manipulator": "^9.3.22",
-        "symplify/package-builder": "^9.3.22",
-        "symplify/smart-file-system": "^9.3.22"
+        "php": ">=8.0",
+        "symfony/console": "^5.4|^6.0",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symplify/autowire-array-parameter": "^10.1",
+        "symplify/composer-json-manipulator": "^10.1",
+        "symplify/package-builder": "^10.1",
+        "symplify/smart-file-system": "^10.1",
+        "webmozart/assert": "^1.10"
+      },
+      "conflict": {
+        "symplify/amnesia": "<10.1.0",
+        "symplify/astral": "<10.1.0",
+        "symplify/coding-standard": "<10.1.0",
+        "symplify/config-transformer": "<10.1.0",
+        "symplify/easy-ci": "<10.1.0",
+        "symplify/easy-coding-standard": "<10.1.0",
+        "symplify/easy-parallel": "<10.1.0",
+        "symplify/easy-testing": "<10.1.0",
+        "symplify/git-wrapper": "<10.1.0",
+        "symplify/latte-phpstan-compiler": "<10.1.0",
+        "symplify/markdown-diff": "<10.1.0",
+        "symplify/monorepo-builder": "<10.1.0",
+        "symplify/neon-config-dumper": "<10.1.0",
+        "symplify/php-config-printer": "<10.1.0",
+        "symplify/phpstan-extensions": "<10.1.0",
+        "symplify/phpstan-latte-rules": "<10.1.0",
+        "symplify/phpstan-rules": "<10.1.0",
+        "symplify/rule-doc-generator": "<10.1.0",
+        "symplify/rule-doc-generator-contracts": "<10.1.0",
+        "symplify/skipper": "<10.1.0",
+        "symplify/symfony-static-dumper": "<10.1.0",
+        "symplify/template-phpstan-compiler": "<10.1.0",
+        "symplify/vendor-patches": "<10.1.0"
       },
       "require-dev": {
         "phpunit/phpunit": "^9.5"
       },
-      "default-branch": true,
       "type": "library",
       "extra": {
         "branch-alias": {
-          "dev-main": "9.4-dev"
+          "dev-main": "10.1-dev"
         }
       },
       "autoload": {
@@ -7657,22 +6930,22 @@
       "license": ["MIT"],
       "description": "Internal Kernel for Symplify packages",
       "support": {
-        "source": "https://github.com/symplify/symplify-kernel/tree/main"
+        "source": "https://github.com/symplify/symplify-kernel/tree/10.1.0"
       },
-      "time": "2021-06-10T09:29:50+00:00"
+      "time": "2022-02-21T11:16:21+00:00"
     },
     {
       "name": "theseer/tokenizer",
-      "version": "1.2.0",
+      "version": "1.2.1",
       "source": {
         "type": "git",
         "url": "https://github.com/theseer/tokenizer.git",
-        "reference": "75a63c33a8577608444246075ea0af0d052e452a"
+        "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
-        "reference": "75a63c33a8577608444246075ea0af0d052e452a",
+        "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+        "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
         "shasum": ""
       },
       "require": {
@@ -7697,7 +6970,7 @@
       "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
       "support": {
         "issues": "https://github.com/theseer/tokenizer/issues",
-        "source": "https://github.com/theseer/tokenizer/tree/master"
+        "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
       },
       "funding": [
         {
@@ -7705,7 +6978,7 @@
           "type": "github"
         }
       ],
-      "time": "2020-07-12T23:59:07+00:00"
+      "time": "2021-07-28T10:34:58+00:00"
     },
     {
       "name": "webmozart/assert",
@@ -7761,13 +7034,11 @@
     }
   ],
   "aliases": [],
-  "minimum-stability": "dev",
+  "minimum-stability": "stable",
   "stability-flags": {
     "james-heinrich/getid3": 20,
     "myth/auth": 20,
-    "codeigniter4/codeigniter4": 20,
-    "michalsn/codeigniter4-uuid": 20,
-    "codeigniter4/settings": 20
+    "michalsn/codeigniter4-uuid": 20
   },
   "prefer-stable": true,
   "prefer-lowest": false,
diff --git a/ecs.php b/ecs.php
index a7d4071516..a96e00df49 100644
--- a/ecs.php
+++ b/ecs.php
@@ -6,6 +6,7 @@ use Symplify\CodingStandard\Fixer\Naming\StandardizeHereNowDocKeywordFixer;
 use Symplify\EasyCodingStandard\ValueObject\Option;
 use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
 use Symplify\CodingStandard\Fixer\LineLength\LineLengthFixer;
+use PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis\AssignmentInConditionSniff;
 
 return static function (ContainerConfigurator $containerConfigurator): void {
     $parameters = $containerConfigurator->parameters();
@@ -19,7 +20,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
         __DIR__ . '/public',
     ]);
 
-    $parameters->set(Option::SKIP, [
+    $parameters->set(Option::SKIP, [        
         // skip specific generated files
         __DIR__ . '/modules/Admin/Language/*/PersonsTaxonomy.php',
 
@@ -39,7 +40,9 @@ return static function (ContainerConfigurator $containerConfigurator): void {
             __DIR__ . '/app/Views/*',
             __DIR__ . '/modules/**/Views/*',
             __DIR__ . '/themes/*',
-        ]
+        ],
+
+        AssignmentInConditionSniff::class,
     ]);
 
     $containerConfigurator->import(SetList::PSR_12);
diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php
index a91139c169..58beff9793 100644
--- a/modules/Admin/Controllers/EpisodeController.php
+++ b/modules/Admin/Controllers/EpisodeController.php
@@ -294,6 +294,7 @@ class EpisodeController extends BaseController
             ) {
                 (new MediaModel())->deleteMedia($this->episode->transcript);
             }
+
             $this->episode->transcript_remote_url = $transcriptRemoteUrl === '' ? null : $transcriptRemoteUrl;
         }
 
@@ -311,6 +312,7 @@ class EpisodeController extends BaseController
             ) {
                 (new MediaModel())->deleteMedia($this->episode->chapters);
             }
+
             $this->episode->chapters_remote_url = $chaptersRemoteUrl === '' ? null : $chaptersRemoteUrl;
         }
 
diff --git a/modules/Admin/Controllers/PodcastController.php b/modules/Admin/Controllers/PodcastController.php
index 9c27a603a2..ce649a9b46 100644
--- a/modules/Admin/Controllers/PodcastController.php
+++ b/modules/Admin/Controllers/PodcastController.php
@@ -384,6 +384,7 @@ class PodcastController extends BaseController
                 ->withInput()
                 ->with('errors', $mediaModel->errors());
         }
+
         (new PodcastModel())->clearCache([
             'id' => $this->podcast->id,
         ]);
diff --git a/modules/Admin/Controllers/PodcastImportController.php b/modules/Admin/Controllers/PodcastImportController.php
index 3b0dba7648..ba53eea3e9 100644
--- a/modules/Admin/Controllers/PodcastImportController.php
+++ b/modules/Admin/Controllers/PodcastImportController.php
@@ -77,6 +77,7 @@ class PodcastImportController extends BaseController
                 ->withInput()
                 ->with('errors', $this->validator->getErrors());
         }
+
         try {
             ini_set('user_agent', 'Castopod/' . CP_VERSION);
             $feed = simplexml_load_file($this->request->getPost('imported_feed_url'));
@@ -93,6 +94,7 @@ class PodcastImportController extends BaseController
                         ' ⎋</a>',
                 ]);
         }
+
         $nsItunes = $feed->channel[0]->children('http://www.itunes.com/dtds/podcast-1.0.dtd');
         $nsPodcast = $feed->channel[0]->children(
             'https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md',
@@ -128,6 +130,7 @@ class PodcastImportController extends BaseController
                     $nsPodcast->location->attributes()['osm'] === null ? null : (string) $nsPodcast->location->attributes()['osm'],
                 );
             }
+
             $guid = null;
             if (property_exists($nsPodcast, 'guid') && $nsPodcast->guid !== null) {
                 $guid = (string) $nsPodcast->guid;
@@ -313,8 +316,10 @@ class PodcastImportController extends BaseController
                 while (in_array($slug . '-' . $slugNumber, $slugs, true)) {
                     ++$slugNumber;
                 }
+
                 $slug = $slug . '-' . $slugNumber;
             }
+
             $slugs[] = $slug;
             $itemDescriptionHtml = match ($this->request->getPost('description_field')) {
                 'content' => (string) $nsContent->encoded,
diff --git a/modules/Admin/Controllers/PodcastPlatformController.php b/modules/Admin/Controllers/PodcastPlatformController.php
index 0bdc4db5b5..08b8f96165 100644
--- a/modules/Admin/Controllers/PodcastPlatformController.php
+++ b/modules/Admin/Controllers/PodcastPlatformController.php
@@ -74,9 +74,11 @@ class PodcastPlatformController extends BaseController
             if ($podcastPlatformUrl === null) {
                 continue;
             }
+
             if (! $validation->check($podcastPlatformUrl, 'validate_url')) {
                 continue;
             }
+
             $podcastsPlatformsData[] = [
                 'platform_slug' => $platformSlug,
                 'podcast_id' => $this->podcast->id,
diff --git a/modules/Admin/Controllers/SchedulerController.php b/modules/Admin/Controllers/SchedulerController.php
index 209979da9c..d13a29e457 100644
--- a/modules/Admin/Controllers/SchedulerController.php
+++ b/modules/Admin/Controllers/SchedulerController.php
@@ -81,6 +81,7 @@ class SchedulerController extends Controller
                         'job_ended_at' => Time::now(),
                     ]);
                 }
+
                 $clipModel->clearVideoClipCache($scheduledClip->id);
             } catch (Exception $exception) {
                 (new ClipModel())->update($scheduledClip->id, [
diff --git a/modules/Admin/Controllers/SettingsController.php b/modules/Admin/Controllers/SettingsController.php
index 348d0c7511..7562546038 100644
--- a/modules/Admin/Controllers/SettingsController.php
+++ b/modules/Admin/Controllers/SettingsController.php
@@ -179,6 +179,7 @@ class SettingsController extends BaseController
             (new EpisodeCommentModel())->resetLikesCount();
             (new EpisodeCommentModel())->resetRepliesCount();
         }
+
         helper('media');
 
         if ($this->request->getPost('rewrite_media') === 'yes') {
diff --git a/modules/Admin/Controllers/SoundbiteController.php b/modules/Admin/Controllers/SoundbiteController.php
index 9d8e8a376e..0016de24df 100644
--- a/modules/Admin/Controllers/SoundbiteController.php
+++ b/modules/Admin/Controllers/SoundbiteController.php
@@ -144,7 +144,7 @@ class SoundbiteController extends BaseController
     {
         $soundbite = (new ClipModel())->getSoundbiteById((int) $soundbiteId);
 
-        if ($soundbite === null) {
+        if (! $soundbite instanceof Soundbite) {
             throw PageNotFoundException::forPageNotFound();
         }
 
diff --git a/modules/Admin/Controllers/VideoClipsController.php b/modules/Admin/Controllers/VideoClipsController.php
index 267845cbd6..71eb4596e4 100644
--- a/modules/Admin/Controllers/VideoClipsController.php
+++ b/modules/Admin/Controllers/VideoClipsController.php
@@ -197,7 +197,7 @@ class VideoClipsController extends BaseController
     {
         $videoClip = (new ClipModel())->getVideoClipById((int) $videoClipId);
 
-        if ($videoClip === null) {
+        if (! $videoClip instanceof VideoClip) {
             throw PageNotFoundException::forPageNotFound();
         }
 
@@ -214,7 +214,7 @@ class VideoClipsController extends BaseController
     {
         $videoClip = (new ClipModel())->getVideoClipById((int) $videoClipId);
 
-        if ($videoClip === null) {
+        if (! $videoClip instanceof VideoClip) {
             throw PageNotFoundException::forPageNotFound();
         }
 
diff --git a/modules/Analytics/Helpers/analytics_helper.php b/modules/Analytics/Helpers/analytics_helper.php
index c9b582a763..c2dd24d8ed 100644
--- a/modules/Analytics/Helpers/analytics_helper.php
+++ b/modules/Analytics/Helpers/analytics_helper.php
@@ -9,7 +9,6 @@ declare(strict_types=1);
  */
 
 use AdAures\Ipcat\IpDb;
-use CodeIgniter\Router\Exceptions\RouterException;
 use Config\Services;
 use GeoIp2\Database\Reader;
 use Opawg\UserAgentsPhp\UserAgents;
@@ -38,8 +37,6 @@ if (! function_exists('base64_url_decode')) {
 if (! function_exists('generate_episode_analytics_url')) {
     /**
      * Builds the episode analytics url that redirects to the audio file url after analytics hit.
-     *
-     * @throws RouterException
      */
     function generate_episode_analytics_url(
         int $podcastId,
@@ -124,6 +121,7 @@ if (! function_exists('set_user_session_location')) {
                 // If things go wrong the show must go on and the user must be able to download the file
             } catch (Exception) {
             }
+
             $session->set('location', $location);
         }
     }
@@ -147,6 +145,7 @@ if (! function_exists('set_user_session_player')) {
                 // If things go wrong the show must go on and the user must be able to download the file
             } catch (Exception) {
             }
+
             if ($playerFound) {
                 $session->set('player', $playerFound);
             } else {
@@ -188,9 +187,11 @@ if (! function_exists('set_user_session_browser')) {
             } catch (Exception) {
                 $browserName = '- Could not get browser name -';
             }
+
             if ($browserName === '') {
                 $browserName = '- Could not get browser name -';
             }
+
             $session->set('browser', $browserName);
         }
     }
@@ -273,6 +274,7 @@ if (! function_exists('podcast_hit')) {
             if ($session->get('denyListIp')) {
                 $session->get('player')['bot'] = true;
             }
+
             //We get the HTTP header field `Range`:
             $httpRange = isset($_SERVER['HTTP_RANGE'])
                 ? $_SERVER['HTTP_RANGE']
@@ -295,6 +297,7 @@ if (! function_exists('podcast_hit')) {
                 // If it was never downloaded that means that zero byte were downloaded:
                 $downloadedBytes = 0;
             }
+
             // If the number of downloaded bytes was previously below the 1mn threshold we go on:
             // (Otherwise it means that this was already counted, therefore we don't do anything)
             if ($downloadedBytes < $bytesThreshold) {
@@ -314,6 +317,7 @@ if (! function_exists('podcast_hit')) {
                                 (array_key_exists(0, $parts) ? 0 : (int) $parts[0]);
                     }
                 }
+
                 // We save the number of downloaded bytes for this user and this episode:
                 cache()
                     ->save($episodeHashId, $downloadedBytes, $rollingTTL);
@@ -339,6 +343,7 @@ if (! function_exists('podcast_hit')) {
                     } else {
                         $downloadsByUser = 1;
                     }
+
                     // Listener count is calculated from 00h00 to 23h59:
                     $midnightTTL = strtotime('tomorrow') - time();
                     // We save the download count for this user until midnight:
diff --git a/modules/Analytics/Models/AnalyticsPodcastByCountryModel.php b/modules/Analytics/Models/AnalyticsPodcastByCountryModel.php
index 110706912e..cc96c4154e 100644
--- a/modules/Analytics/Models/AnalyticsPodcastByCountryModel.php
+++ b/modules/Analytics/Models/AnalyticsPodcastByCountryModel.php
@@ -89,6 +89,7 @@ class AnalyticsPodcastByCountryModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_by_country_yearly", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsPodcastByPlayerModel.php b/modules/Analytics/Models/AnalyticsPodcastByPlayerModel.php
index 84e385c0e5..d30e348847 100644
--- a/modules/Analytics/Models/AnalyticsPodcastByPlayerModel.php
+++ b/modules/Analytics/Models/AnalyticsPodcastByPlayerModel.php
@@ -62,6 +62,7 @@ class AnalyticsPodcastByPlayerModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_player_by_app_weekly", $found, 600);
         }
+
         return $found;
     }
 
@@ -90,6 +91,7 @@ class AnalyticsPodcastByPlayerModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_player_by_app_yearly", $found, 600);
         }
+
         return $found;
     }
 
@@ -119,6 +121,7 @@ class AnalyticsPodcastByPlayerModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_player_by_os_weekly", $found, 600);
         }
+
         return $found;
     }
 
@@ -147,6 +150,7 @@ class AnalyticsPodcastByPlayerModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_player_by_device_weekly", $found, 600);
         }
+
         return $found;
     }
 
@@ -175,6 +179,7 @@ class AnalyticsPodcastByPlayerModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_player_bots", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsPodcastByRegionModel.php b/modules/Analytics/Models/AnalyticsPodcastByRegionModel.php
index 1258d7ec87..7b04fd8afa 100644
--- a/modules/Analytics/Models/AnalyticsPodcastByRegionModel.php
+++ b/modules/Analytics/Models/AnalyticsPodcastByRegionModel.php
@@ -64,6 +64,7 @@ class AnalyticsPodcastByRegionModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_by_region_{$locale}", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsPodcastByServiceModel.php b/modules/Analytics/Models/AnalyticsPodcastByServiceModel.php
index 0742319c29..2e1e9eda7e 100644
--- a/modules/Analytics/Models/AnalyticsPodcastByServiceModel.php
+++ b/modules/Analytics/Models/AnalyticsPodcastByServiceModel.php
@@ -62,6 +62,7 @@ class AnalyticsPodcastByServiceModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_service_weekly", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsPodcastModel.php b/modules/Analytics/Models/AnalyticsPodcastModel.php
index 7bc0c782b2..493dd5da31 100644
--- a/modules/Analytics/Models/AnalyticsPodcastModel.php
+++ b/modules/Analytics/Models/AnalyticsPodcastModel.php
@@ -56,6 +56,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_by_day", $found, 600);
         }
+
         return $found;
     }
 
@@ -80,6 +81,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcasts_by_weekday", $found, 600);
         }
+
         return $found;
     }
 
@@ -102,6 +104,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_by_bandwidth", $found, 600);
         }
+
         return $found;
     }
 
@@ -125,6 +128,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_by_month", $found, 600);
         }
+
         return $found;
     }
 
@@ -149,6 +153,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_unique_listeners_by_day", $found, 600);
         }
+
         return $found;
     }
 
@@ -174,6 +179,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_unique_listeners_by_month", $found, 600);
         }
+
         return $found;
     }
 
@@ -200,6 +206,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_listening_time_by_day", $found, 600);
         }
+
         return $found;
     }
 
@@ -225,6 +232,7 @@ class AnalyticsPodcastModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_podcast_listening_time_by_month", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsWebsiteByBrowserModel.php b/modules/Analytics/Models/AnalyticsWebsiteByBrowserModel.php
index bd4ee34c49..ebb446d670 100644
--- a/modules/Analytics/Models/AnalyticsWebsiteByBrowserModel.php
+++ b/modules/Analytics/Models/AnalyticsWebsiteByBrowserModel.php
@@ -59,6 +59,7 @@ class AnalyticsWebsiteByBrowserModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_website_by_browser", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsWebsiteByEntryPageModel.php b/modules/Analytics/Models/AnalyticsWebsiteByEntryPageModel.php
index 25b569eb5f..0ef9d84225 100644
--- a/modules/Analytics/Models/AnalyticsWebsiteByEntryPageModel.php
+++ b/modules/Analytics/Models/AnalyticsWebsiteByEntryPageModel.php
@@ -58,6 +58,7 @@ class AnalyticsWebsiteByEntryPageModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_website_by_entry_page", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Analytics/Models/AnalyticsWebsiteByRefererModel.php b/modules/Analytics/Models/AnalyticsWebsiteByRefererModel.php
index f7a165d83e..b5973d2c4f 100644
--- a/modules/Analytics/Models/AnalyticsWebsiteByRefererModel.php
+++ b/modules/Analytics/Models/AnalyticsWebsiteByRefererModel.php
@@ -58,6 +58,7 @@ class AnalyticsWebsiteByRefererModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_website_by_referer", $found, 600);
         }
+
         return $found;
     }
 
@@ -84,6 +85,7 @@ class AnalyticsWebsiteByRefererModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_website_by_domain_weekly", $found, 600);
         }
+
         return $found;
     }
 
@@ -110,6 +112,7 @@ class AnalyticsWebsiteByRefererModel extends Model
             cache()
                 ->save("{$podcastId}_analytics_website_by_domain_yearly", $found, 600);
         }
+
         return $found;
     }
 }
diff --git a/modules/Auth/Filters/PermissionFilter.php b/modules/Auth/Filters/PermissionFilter.php
index 6f26e20b98..198247987a 100644
--- a/modules/Auth/Filters/PermissionFilter.php
+++ b/modules/Auth/Filters/PermissionFilter.php
@@ -78,6 +78,7 @@ class PermissionFilter implements FilterInterface
                     ->to($redirectURL)
                     ->with('error', lang('Auth.notEnoughPrivilege'));
             }
+
             throw new PermissionException(lang('Auth.notEnoughPrivilege'));
         }
     }
diff --git a/modules/Fediverse/Controllers/ActorController.php b/modules/Fediverse/Controllers/ActorController.php
index 9e14a7a0a5..7962a39676 100644
--- a/modules/Fediverse/Controllers/ActorController.php
+++ b/modules/Fediverse/Controllers/ActorController.php
@@ -132,6 +132,7 @@ class ActorController extends Controller
                     return $this->response->setStatusCode(200)
                         ->setJSON([]);
                 }
+
                 // return not handled undo error (501 = not implemented)
                 return $this->response->setStatusCode(501)
                     ->setJSON([]);
@@ -286,6 +287,7 @@ class ActorController extends Controller
             foreach ($paginatedActivity as $activity) {
                 $orderedItems[] = $activity->payload;
             }
+
             $collection = new OrderedCollectionPage($pager, $orderedItems);
         }
 
@@ -322,6 +324,7 @@ class ActorController extends Controller
             foreach ($paginatedFollowers as $follower) {
                 $orderedItems[] = $follower->uri;
             }
+
             $followersCollection = new OrderedCollectionPage($pager, $orderedItems);
         }
 
diff --git a/modules/Fediverse/Helpers/fediverse_helper.php b/modules/Fediverse/Helpers/fediverse_helper.php
index 7ef5608939..5f243f99d0 100644
--- a/modules/Fediverse/Helpers/fediverse_helper.php
+++ b/modules/Fediverse/Helpers/fediverse_helper.php
@@ -108,6 +108,7 @@ if (! function_exists('send_activity_to_actor')) {
             if ($actor->private_key !== null) {
                 $acceptRequest->sign($actor->public_key_id, $actor->private_key);
             }
+
             $acceptRequest->post();
         } catch (Exception $exception) {
             // log error
@@ -283,6 +284,7 @@ if (! function_exists('create_actor_from_uri')) {
             $newActor->cover_image_url = $actorPayload->image->url;
             $newActor->cover_image_mimetype = $actorPayload->image->mediaType;
         }
+
         $newActor->inbox_url = $actorPayload->inbox;
         $newActor->outbox_url = property_exists($actorPayload, 'outbox') ? $actorPayload->outbox : null;
         $newActor->followers_url = property_exists($actorPayload, 'followers') ? $actorPayload->followers : null;
@@ -299,8 +301,6 @@ if (! function_exists('create_actor_from_uri')) {
 if (! function_exists('get_current_domain')) {
     /**
      * Returns instance's domain name
-     *
-     * @throws HTTPException
      */
     function get_current_domain(): string
     {
@@ -324,8 +324,6 @@ if (! function_exists('get_message_from_object')) {
      * Gets the message from content, if no content key is present, checks for content in contentMap
      *
      * TODO: store multiple languages, convert markdown
-     *
-     * @return string|false
      */
     function get_message_from_object(stdClass $object): string | false
     {
@@ -365,9 +363,10 @@ if (! function_exists('linkify')) {
                 'http', 'https' => preg_replace_callback(
                     '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i',
                     function (array $match) use ($protocol, &$links) {
-                        if ($match[1]) {
+                        if ($match[1] !== '' && $match[1] !== '0') {
                             $protocol = $match[1];
                         }
+
                         $link = $match[2] ?: $match[3];
 
                         helper('text');
diff --git a/modules/Fediverse/Models/BlockedDomainModel.php b/modules/Fediverse/Models/BlockedDomainModel.php
index 34e2915ef7..933f6e522f 100644
--- a/modules/Fediverse/Models/BlockedDomainModel.php
+++ b/modules/Fediverse/Models/BlockedDomainModel.php
@@ -12,7 +12,6 @@ namespace Modules\Fediverse\Models;
 
 use CodeIgniter\Database\BaseResult;
 use CodeIgniter\Events\Events;
-use CodeIgniter\Model;
 use Modules\Fediverse\Entities\BlockedDomain;
 
 class BlockedDomainModel extends BaseModel
@@ -64,6 +63,7 @@ class BlockedDomainModel extends BaseModel
             cache()
                 ->save($cacheName, $found, DECADE);
         }
+
         return $found;
     }
 
diff --git a/modules/Fediverse/Models/FollowModel.php b/modules/Fediverse/Models/FollowModel.php
index 4a2bdf8f8f..f1e764507c 100644
--- a/modules/Fediverse/Models/FollowModel.php
+++ b/modules/Fediverse/Models/FollowModel.php
@@ -10,12 +10,9 @@ declare(strict_types=1);
 
 namespace Modules\Fediverse\Models;
 
-use CodeIgniter\Database\Exceptions\DatabaseException;
 use CodeIgniter\Events\Events;
 use CodeIgniter\I18n\Time;
-use CodeIgniter\Model;
 use Exception;
-use InvalidArgumentException;
 use Modules\Fediverse\Activities\FollowActivity;
 use Modules\Fediverse\Activities\UndoActivity;
 use Modules\Fediverse\Entities\Actor;
@@ -48,7 +45,6 @@ class FollowModel extends BaseModel
     /**
      * @param Actor $actor Actor that is following
      * @param Actor $targetActor Actor that is being followed
-     * @throws DatabaseException
      */
     public function addFollower(Actor $actor, Actor $targetActor, bool $registerActivity = true): void
     {
@@ -105,8 +101,6 @@ class FollowModel extends BaseModel
     /**
      * @param Actor $actor Actor that is unfollowing
      * @param Actor $targetActor Actor that is being unfollowed
-     * @throws InvalidArgumentException
-     * @throws DatabaseException
      */
     public function removeFollower(Actor $actor, Actor $targetActor, bool $registerActivity = true): void
     {
diff --git a/modules/Fediverse/Objects/OrderedCollectionPage.php b/modules/Fediverse/Objects/OrderedCollectionPage.php
index c9774d1745..afa6835cdc 100644
--- a/modules/Fediverse/Objects/OrderedCollectionPage.php
+++ b/modules/Fediverse/Objects/OrderedCollectionPage.php
@@ -33,6 +33,7 @@ class OrderedCollectionPage extends OrderedCollectionObject
         if ($isFirstPage) {
             $this->first = null;
         }
+
         if ($isLastPage) {
             $this->last = null;
         }
diff --git a/modules/Install/Controllers/InstallController.php b/modules/Install/Controllers/InstallController.php
index 2068ef5661..49ca718359 100644
--- a/modules/Install/Controllers/InstallController.php
+++ b/modules/Install/Controllers/InstallController.php
@@ -356,6 +356,7 @@ class InstallController extends Controller
                         $replaced = true;
                         return $keyVal;
                     }
+
                     return $line;
                 },
                 $envData
diff --git a/package-lock.json b/package-lock.json
index bf6722c26e..daec42f5b6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,76 +9,77 @@
       "version": "1.0.0-beta.8",
       "license": "AGPL-3.0-or-later",
       "dependencies": {
-        "@amcharts/amcharts4": "^4.10.23",
+        "@amcharts/amcharts4": "^4.10.24",
         "@amcharts/amcharts4-geodata": "^4.1.22",
         "@codemirror/basic-setup": "^0.19.1",
-        "@codemirror/commands": "^0.19.7",
+        "@codemirror/commands": "^0.19.8",
         "@codemirror/lang-xml": "^0.19.2",
-        "@codemirror/state": "^0.19.6",
-        "@codemirror/view": "^0.19.39",
-        "@floating-ui/dom": "^0.1.10",
+        "@codemirror/state": "^0.19.9",
+        "@codemirror/view": "^0.19.45",
+        "@floating-ui/dom": "^0.3.1",
         "@github/clipboard-copy-element": "^1.1.2",
-        "@github/hotkey": "^1.6.1",
+        "@github/hotkey": "^2.0.0",
         "@github/markdown-toolbar-element": "^2.1.0",
         "@github/time-elements": "^3.1.2",
         "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
         "@vime/core": "^5.3.1",
-        "choices.js": "^10.0.0",
+        "choices.js": "^10.1.0",
         "flatpickr": "^4.6.9",
         "leaflet": "^1.7.1",
         "leaflet.markercluster": "^1.5.3",
-        "lit": "^2.1.1",
-        "marked": "^4.0.10",
-        "wavesurfer.js": "^5.2.0",
-        "xml-formatter": "^2.6.0"
+        "lit": "^2.2.0",
+        "marked": "^4.0.12",
+        "wavesurfer.js": "^6.0.2",
+        "xml-formatter": "^2.6.1"
       },
       "devDependencies": {
-        "@commitlint/cli": "^16.0.2",
-        "@commitlint/config-conventional": "^16.0.0",
+        "@commitlint/cli": "^16.2.1",
+        "@commitlint/config-conventional": "^16.2.1",
         "@semantic-release/changelog": "^6.0.1",
         "@semantic-release/exec": "^6.0.3",
         "@semantic-release/git": "^10.0.1",
         "@semantic-release/gitlab": "^7.0.4",
         "@tailwindcss/forms": "^0.4.0-alpha.2",
         "@tailwindcss/line-clamp": "^0.3.1",
-        "@tailwindcss/typography": "^0.5.0",
-        "@types/leaflet": "^1.7.8",
-        "@types/marked": "^4.0.1",
-        "@types/wavesurfer.js": "^5.2.2",
-        "@typescript-eslint/eslint-plugin": "^5.10.0",
-        "@typescript-eslint/parser": "^5.10.0",
+        "@tailwindcss/typography": "^0.5.2",
+        "@types/leaflet": "^1.7.9",
+        "@types/marked": "^4.0.2",
+        "@types/wavesurfer.js": "^6.0.1",
+        "@typescript-eslint/eslint-plugin": "^5.12.1",
+        "@typescript-eslint/parser": "^5.12.1",
         "cross-env": "^7.0.3",
-        "cssnano": "^5.0.15",
+        "cssnano": "^5.0.17",
         "cz-conventional-changelog": "^3.3.0",
-        "eslint": "^8.7.0",
-        "eslint-config-prettier": "^8.3.0",
+        "eslint": "^8.10.0",
+        "eslint-config-prettier": "^8.4.0",
         "eslint-plugin-prettier": "^4.0.0",
         "husky": "^7.0.4",
         "is-ci": "^3.0.1",
-        "lint-staged": "^12.2.0",
+        "lint-staged": "^12.3.4",
         "postcss-import": "^14.0.2",
         "postcss-nesting": "^10.1.2",
-        "postcss-preset-env": "^7.2.3",
+        "postcss-preset-env": "^7.4.1",
         "postcss-reporter": "^7.0.5",
         "prettier": "2.5.1",
         "prettier-plugin-organize-imports": "^2.3.4",
         "semantic-release": "^19.0.2",
-        "stylelint": "^14.2.0",
-        "stylelint-config-standard": "^24.0.0",
+        "stylelint": "^14.5.3",
+        "stylelint-config-standard": "^25.0.0",
         "svgo": "^2.8.0",
-        "tailwindcss": "^3.0.15",
-        "typescript": "^4.5.4",
-        "vite": "^2.7.13",
+        "tailwindcss": "^3.0.23",
+        "typescript": "^4.5.5",
+        "vite": "^2.8.4",
         "vite-plugin-pwa": "^0.11.13",
-        "workbox-build": "^6.4.2",
-        "workbox-core": "^6.4.2",
-        "workbox-routing": "^6.4.2",
-        "workbox-strategies": "^6.4.2"
+        "workbox-build": "^6.5.0",
+        "workbox-core": "^6.5.0",
+        "workbox-routing": "^6.5.0",
+        "workbox-strategies": "^6.5.0"
       }
     },
     "node_modules/@amcharts/amcharts4": {
-      "version": "4.10.23",
-      "license": "SEE LICENSE IN LICENSE",
+      "version": "4.10.24",
+      "resolved": "https://registry.npmjs.org/@amcharts/amcharts4/-/amcharts4-4.10.24.tgz",
+      "integrity": "sha512-Yq7Ynn9XAENDHPuGyZpDiK8xBa223/8yxpt9R2FJ0by4pHruxu+SCJ7L8S/0CDWy/ABMVVObVsnYwNBm8GFJPQ==",
       "dependencies": {
         "@babel/runtime": "^7.6.3",
         "core-js": "^3.0.0",
@@ -1728,14 +1729,14 @@
       }
     },
     "node_modules/@codemirror/commands": {
-      "version": "0.19.7",
-      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.19.7.tgz",
-      "integrity": "sha512-Mwh064xnuDbFw+9KJAi2Hmg8Va+YqQzgn6e/94/bSJavY3uuIBPr4vJp6pFEa1qPp40qs5/XJ01ty/0G3uLewA==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.19.8.tgz",
+      "integrity": "sha512-65LIMSGUGGpY3oH6mzV46YWRrgao6NmfJ+AuC7jNz3K5NPnH6GCV1H5I6SwOFyVbkiygGyd0EFwrWqywTBD1aw==",
       "dependencies": {
         "@codemirror/language": "^0.19.0",
         "@codemirror/matchbrackets": "^0.19.0",
         "@codemirror/state": "^0.19.2",
-        "@codemirror/text": "^0.19.0",
+        "@codemirror/text": "^0.19.6",
         "@codemirror/view": "^0.19.22",
         "@lezer/common": "^0.15.0"
       }
@@ -1872,15 +1873,17 @@
       }
     },
     "node_modules/@codemirror/state": {
-      "version": "0.19.6",
-      "license": "MIT",
+      "version": "0.19.9",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz",
+      "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==",
       "dependencies": {
         "@codemirror/text": "^0.19.0"
       }
     },
     "node_modules/@codemirror/text": {
-      "version": "0.19.5",
-      "license": "MIT"
+      "version": "0.19.6",
+      "resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz",
+      "integrity": "sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA=="
     },
     "node_modules/@codemirror/tooltip": {
       "version": "0.19.10",
@@ -1891,9 +1894,9 @@
       }
     },
     "node_modules/@codemirror/view": {
-      "version": "0.19.39",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.39.tgz",
-      "integrity": "sha512-ol4smHAwhWkW8p1diPZiZkLZVmKybKhQigwyrgdF7k1UFNY+/KDH4w2xic8JQXxX+v0ppMsoNf11C+afKJze5g==",
+      "version": "0.19.45",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.45.tgz",
+      "integrity": "sha512-wR19UBYvJMeV9axa5Xo6ATbAP1jl30BPFZ5buu3cJjYXwlRhJDjzw2wUbxk1zsR1LtAe5jrRNeWEtGA+IPacxw==",
       "dependencies": {
         "@codemirror/rangeset": "^0.19.5",
         "@codemirror/state": "^0.19.3",
@@ -1903,16 +1906,16 @@
       }
     },
     "node_modules/@commitlint/cli": {
-      "version": "16.0.2",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.0.2.tgz",
-      "integrity": "sha512-Jt7iaBjoLGC5Nq4dHPTvTYnqPGkElFPBtTXTvBpTgatZApczyjI2plE0oG4GYWPp1suHIS/VdVDOMpPZjGVusg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.2.1.tgz",
+      "integrity": "sha512-zfKf+B9osuiDbxGMJ7bWFv7XFCW8wlQYPtCffNp7Ukdb7mdrep5R9e03vPUZysnwp8NX6hg05kPEvnD/wRIGWw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/format": "^16.0.0",
-        "@commitlint/lint": "^16.0.0",
-        "@commitlint/load": "^16.0.0",
-        "@commitlint/read": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/format": "^16.2.1",
+        "@commitlint/lint": "^16.2.1",
+        "@commitlint/load": "^16.2.1",
+        "@commitlint/read": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19",
         "resolve-from": "5.0.0",
         "resolve-global": "1.0.0",
@@ -1991,9 +1994,9 @@
       }
     },
     "node_modules/@commitlint/config-conventional": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.0.0.tgz",
-      "integrity": "sha512-mN7J8KlKFn0kROd+q9PB01sfDx/8K/R25yITspL1No8PB4oj9M1p77xWjP80hPydqZG9OvQq+anXK3ZWeR7s3g==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.1.tgz",
+      "integrity": "sha512-cP9gArx7gnaj4IqmtCIcHdRjTYdRUi6lmGE+lOzGGjGe45qGOS8nyQQNvkNy2Ey2VqoSWuXXkD8zCUh6EHf1Ww==",
       "dev": true,
       "dependencies": {
         "conventional-changelog-conventionalcommits": "^4.3.1"
@@ -2003,12 +2006,12 @@
       }
     },
     "node_modules/@commitlint/config-validator": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.0.0.tgz",
-      "integrity": "sha512-i80DGlo1FeC5jZpuoNV9NIjQN/m2dDV3jYGWg+1Wr+KldptkUHXj+6GY1Akll66lJ3D8s6aUGi3comPLHPtWHg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz",
+      "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "ajv": "^6.12.6"
       },
       "engines": {
@@ -2016,12 +2019,12 @@
       }
     },
     "node_modules/@commitlint/ensure": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.0.0.tgz",
-      "integrity": "sha512-WdMySU8DCTaq3JPf0tZFCKIUhqxaL54mjduNhu8v4D2AMUVIIQKYMGyvXn94k8begeW6iJkTf9cXBArayskE7Q==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz",
+      "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19"
       },
       "engines": {
@@ -2029,21 +2032,21 @@
       }
     },
     "node_modules/@commitlint/execute-rule": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.0.0.tgz",
-      "integrity": "sha512-8edcCibmBb386x5JTHSPHINwA5L0xPkHQFY8TAuDEt5QyRZY/o5DF8OPHSa5Hx2xJvGaxxuIz4UtAT6IiRDYkw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz",
+      "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==",
       "dev": true,
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/format": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.0.0.tgz",
-      "integrity": "sha512-9yp5NCquXL1jVMKL0ZkRwJf/UHdebvCcMvICuZV00NQGYSAL89O398nhqrqxlbjBhM5EZVq0VGcV5+7r3D4zAA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz",
+      "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "chalk": "^4.0.0"
       },
       "engines": {
@@ -2051,12 +2054,12 @@
       }
     },
     "node_modules/@commitlint/is-ignored": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.0.0.tgz",
-      "integrity": "sha512-gmAQcwIGC/R/Lp0CEb2b5bfGC7MT5rPe09N8kOGjO/NcdNmfFSZMquwrvNJsq9hnAP0skRdHIsqwlkENkN4Lag==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.1.tgz",
+      "integrity": "sha512-exl8HRzTIfb1YvDJp2b2HU5z1BT+9tmgxR2XF0YEzkMiCIuEKh+XLeocPr1VcvAKXv3Cmv5X/OfNRp+i+/HIhQ==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "semver": "7.3.5"
       },
       "engines": {
@@ -2079,30 +2082,31 @@
       }
     },
     "node_modules/@commitlint/lint": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.0.0.tgz",
-      "integrity": "sha512-HNl15bRC0h+pLzbMzQC3tM0j1aESXsLYhElqKnXcf5mnCBkBkHzu6WwJW8rZbfxX+YwJmNljN62cPhmdBo8x0A==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.1.tgz",
+      "integrity": "sha512-fNINQ3X2ZqsCkNB3Z0Z8ElmhewqrS3gy2wgBTx97BkcjOWiyPAGwDJ752hwrsUnWAVBRztgw826n37xPzxsOgg==",
       "dev": true,
       "dependencies": {
-        "@commitlint/is-ignored": "^16.0.0",
-        "@commitlint/parse": "^16.0.0",
-        "@commitlint/rules": "^16.0.0",
-        "@commitlint/types": "^16.0.0"
+        "@commitlint/is-ignored": "^16.2.1",
+        "@commitlint/parse": "^16.2.1",
+        "@commitlint/rules": "^16.2.1",
+        "@commitlint/types": "^16.2.1"
       },
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/load": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.0.0.tgz",
-      "integrity": "sha512-7WhrGCkP6K/XfjBBguLkkI2XUdiiIyMGlNsSoSqgRNiD352EiffhFEApMy1/XOU+viwBBm/On0n5p0NC7e9/4A==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.2.1.tgz",
+      "integrity": "sha512-oSpz0jTyVI/A1AIImxJINTLDOMB8YF7lWGm+Jg5wVWM0r7ucpuhyViVvpSRTgvL0z09oIxlctyFGWUQQpI42uw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/config-validator": "^16.0.0",
-        "@commitlint/execute-rule": "^16.0.0",
-        "@commitlint/resolve-extends": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/execute-rule": "^16.2.1",
+        "@commitlint/resolve-extends": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
+        "@types/node": ">=12",
         "chalk": "^4.0.0",
         "cosmiconfig": "^7.0.0",
         "cosmiconfig-typescript-loader": "^1.0.0",
@@ -2115,21 +2119,21 @@
       }
     },
     "node_modules/@commitlint/message": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.0.0.tgz",
-      "integrity": "sha512-CmK2074SH1Ws6kFMEKOKH/7hMekGVbOD6vb4alCOo2+33ZSLUIX8iNkDYyrw38Jwg6yWUhLjyQLUxREeV+QIUA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz",
+      "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==",
       "dev": true,
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/parse": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.0.0.tgz",
-      "integrity": "sha512-F9EjFlMw4MYgBEqoRrWZZKQBzdiJzPBI0qFDFqwUvfQsMmXEREZ242T4R5bFwLINWaALFLHEIa/FXEPa6QxCag==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz",
+      "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==",
       "dev": true,
       "dependencies": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "conventional-changelog-angular": "^5.0.11",
         "conventional-commits-parser": "^3.2.2"
       },
@@ -2138,13 +2142,13 @@
       }
     },
     "node_modules/@commitlint/read": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.0.0.tgz",
-      "integrity": "sha512-H4T2zsfmYQK9B+JtoQaCXWBHUhgIJyOzWZjSfuIV9Ce69/OgHoffNpLZPF2lX6yKuDrS1SQFhI/kUCjVc/e4ew==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz",
+      "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/top-level": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/top-level": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "fs-extra": "^10.0.0",
         "git-raw-commits": "^2.0.0"
       },
@@ -2153,9 +2157,9 @@
       }
     },
     "node_modules/@commitlint/read/node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
+      "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -2188,13 +2192,13 @@
       }
     },
     "node_modules/@commitlint/resolve-extends": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.0.0.tgz",
-      "integrity": "sha512-Z/w9MAQUcxeawpCLtjmkVNXAXOmB2nhW+LYmHEZcx9O6UTauF/1+uuZ2/r0MtzTe1qw2JD+1QHVhEWYHVPlkdA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz",
+      "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==",
       "dev": true,
       "dependencies": {
-        "@commitlint/config-validator": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "import-fresh": "^3.0.0",
         "lodash": "^4.17.19",
         "resolve-from": "^5.0.0",
@@ -2205,15 +2209,15 @@
       }
     },
     "node_modules/@commitlint/rules": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.0.0.tgz",
-      "integrity": "sha512-AOl0y2SBTdJ1bvIv8nwHvQKRT/jC1xb09C5VZwzHoT8sE8F54KDeEzPCwHQFgUcWdGLyS10kkOTAH2MyA8EIlg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.1.tgz",
+      "integrity": "sha512-ZFezJXQaBBso+BOTre/+1dGCuCzlWVaeLiVRGypI53qVgPMzQqZhkCcrxBFeqB87qeyzr4A4EoG++IvITwwpIw==",
       "dev": true,
       "dependencies": {
-        "@commitlint/ensure": "^16.0.0",
-        "@commitlint/message": "^16.0.0",
-        "@commitlint/to-lines": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/ensure": "^16.2.1",
+        "@commitlint/message": "^16.2.1",
+        "@commitlint/to-lines": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "execa": "^5.0.0"
       },
       "engines": {
@@ -2221,18 +2225,18 @@
       }
     },
     "node_modules/@commitlint/to-lines": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.0.0.tgz",
-      "integrity": "sha512-iN/qU38TCKU7uKOg6RXLpD49wNiuI0TqMqybHbjefUeP/Jmzxa8ishryj0uLyVdrAl1ZjGeD1ukXGMTtvqz8iA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz",
+      "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==",
       "dev": true,
       "engines": {
         "node": ">=v12"
       }
     },
     "node_modules/@commitlint/top-level": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.0.0.tgz",
-      "integrity": "sha512-/Jt6NLxyFkpjL5O0jxurZPCHURZAm7cQCqikgPCwqPAH0TLgwqdHjnYipl8J+AGnAMGDip4FNLoYrtgIpZGBYw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz",
+      "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==",
       "dev": true,
       "dependencies": {
         "find-up": "^5.0.0"
@@ -2303,9 +2307,9 @@
       }
     },
     "node_modules/@commitlint/types": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.0.0.tgz",
-      "integrity": "sha512-+0FvYOAS39bJ4aKjnYn/7FD4DfWkmQ6G/06I4F0Gvu4KS5twirEg8mIcLhmeRDOOKn4Tp8PwpLwBiSA6npEMQA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz",
+      "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==",
       "dev": true,
       "dependencies": {
         "chalk": "^4.0.0"
@@ -2335,15 +2339,138 @@
         "node": ">=12"
       }
     },
+    "node_modules/@csstools/postcss-color-function": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.0.2.tgz",
+      "integrity": "sha512-uayvFqfa0hITPwVduxRYNL9YBD/anTqula0tu2llalaxblEd7QPuETSN3gB5PvTYxSfd0d8kS4Fypgo5JaUJ6A==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/@csstools/postcss-font-format-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.0.tgz",
+      "integrity": "sha512-oO0cZt8do8FdVBX8INftvIA4lUrKUSCcWUf9IwH9IPWOgKT22oAZFXeHLoDK7nhB2SmkNycp5brxfNMRLIhd6Q==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/@csstools/postcss-hwb-function": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.0.tgz",
+      "integrity": "sha512-VSTd7hGjmde4rTj1rR30sokY3ONJph1reCBTUXqeW1fKwETPy1x4t/XIeaaqbMbC5Xg4SM/lyXZ2S8NELT2TaA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/@csstools/postcss-ic-unit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.0.tgz",
+      "integrity": "sha512-i4yps1mBp2ijrx7E96RXrQXQQHm6F4ym1TOD0D69/sjDjZvQ22tqiEvaNw7pFZTUO5b9vWRHzbHzP9+UKuw+bA==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/@csstools/postcss-is-pseudo-class": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.0.tgz",
+      "integrity": "sha512-WnfZlyuh/CW4oS530HBbrKq0G8BKl/bsNr5NMFoubBFzJfvFRGJhplCgIJYWUidLuL3WJ/zhMtDIyNFTqhx63Q==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.9"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/@csstools/postcss-normalize-display-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.0.tgz",
+      "integrity": "sha512-bX+nx5V8XTJEmGtpWTO6kywdS725t71YSLlxWt78XoHUbELWgoCXeOFymRJmL3SU1TLlKSIi7v52EWqe60vJTQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/@csstools/postcss-oklab-function": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.0.1.tgz",
+      "integrity": "sha512-Bnly2FWWSTZX20hDJLYHpurhp1ot+ZGvojLOsrHa9frzOVruOv4oPYMZ6wQomi9KsbZZ+Af/CuRYaGReTyGtEg==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/@csstools/postcss-progressive-custom-properties": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.2.0.tgz",
+      "integrity": "sha512-YLpFPK5OaLIRKZhUfnrZPT9s9cmtqltIOg7W6jPcxmiDpnZ4lk+odfufZttOAgcg6IHWvNLgcITSLpJxIQB/qQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
-      "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
+      "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
       "dev": true,
       "dependencies": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.2.0",
+        "espree": "^9.3.1",
         "globals": "^13.9.0",
         "ignore": "^4.0.6",
         "import-fresh": "^3.2.1",
@@ -2377,16 +2504,16 @@
       }
     },
     "node_modules/@floating-ui/core": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.3.1.tgz",
-      "integrity": "sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g=="
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.5.1.tgz",
+      "integrity": "sha512-LOFg65vdU4o4eZjVKNhu7VXbjdnY0amMw9sydLtKZiCNwj0eMD06rmktbWp9L/f6w6s9Qqe22lkks8PbwYwy4Q=="
     },
     "node_modules/@floating-ui/dom": {
-      "version": "0.1.10",
-      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.1.10.tgz",
-      "integrity": "sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==",
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.3.1.tgz",
+      "integrity": "sha512-HJX/2xgGPt01YHQNAya2taqg5HDnY6ipF0B0Bk/Th2s4FD9R89Ecw3TEegLLO+VrQnPEGbuHOGJ6Fr3BPM0DYg==",
       "dependencies": {
-        "@floating-ui/core": "^0.3.0"
+        "@floating-ui/core": "^0.5.0"
       }
     },
     "node_modules/@foliojs-fork/fontkit": {
@@ -2433,9 +2560,9 @@
       "license": "MIT"
     },
     "node_modules/@github/hotkey": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/@github/hotkey/-/hotkey-1.6.1.tgz",
-      "integrity": "sha512-vwxqOREwldnk5wD460LPB5wUVpiVECPupi+9fKx5TFXUiRLLz4sw8QbF1FqQsV+puwsjUBhzXPa4Crj/7MGPhw=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@github/hotkey/-/hotkey-2.0.0.tgz",
+      "integrity": "sha512-KRw695msYYRIeFWvADV2PJa58+88NvYmHl+RJZLAlCtvbzjlkYwDf6yLC0xSLGcoYB5bKHQzudqYgPgpYnVbLw=="
     },
     "node_modules/@github/markdown-toolbar-element": {
       "version": "2.1.0",
@@ -2485,9 +2612,9 @@
       }
     },
     "node_modules/@lit/reactive-element": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.2.0.tgz",
-      "integrity": "sha512-7i/Fz8enAQ2AN5DyJ2i2AFERufjP6x1NjuHoNgDyJkjjHxEoo8kVyyHxu1A9YyeShlksjt5FvpvENBDuivQHLA=="
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.0.tgz",
+      "integrity": "sha512-0TKSIuJHXNLM0k98fi0AdMIdUoHIYlDHTP+0Vruc2SOs4T6vU1FinXgSvYd8mSrkt+8R+qdRAXvjpqrMXMyBgw=="
     },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.3",
@@ -3237,15 +3364,14 @@
       }
     },
     "node_modules/@tailwindcss/typography": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.0.tgz",
-      "integrity": "sha512-1p/3C6C+JJziS/ghtG8ACYalbA2SyLJY27Pm33cVTlAoY6VQ7zfm2H64cPxUMBkVIlWXTtWHhZcZJPobMRmQAA==",
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
+      "integrity": "sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==",
       "dev": true,
       "dependencies": {
         "lodash.castarray": "^4.4.0",
         "lodash.isplainobject": "^4.0.6",
-        "lodash.merge": "^4.6.2",
-        "lodash.uniq": "^4.5.0"
+        "lodash.merge": "^4.6.2"
       },
       "peerDependencies": {
         "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders"
@@ -3347,18 +3473,18 @@
       }
     },
     "node_modules/@types/leaflet": {
-      "version": "1.7.8",
-      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.8.tgz",
-      "integrity": "sha512-prZwhmUznkwTYCTZVGTR4U1GzgPP3PAWYYQ3wDgVkIoiuQTheWoycsXx4Rz9ARYhlDTl0Ycd8lvhH2/rNSkqIg==",
+      "version": "1.7.9",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.9.tgz",
+      "integrity": "sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA==",
       "dev": true,
       "dependencies": {
         "@types/geojson": "*"
       }
     },
     "node_modules/@types/marked": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.1.tgz",
-      "integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.2.tgz",
+      "integrity": "sha512-auNrZ/c0w6wsM9DccwVxWHssrMDezHUAXNesdp2RQrCVCyrQbOiSq7yqdJKrUQQpw9VTm7CGYJH2A/YG7jjrjQ==",
       "dev": true
     },
     "node_modules/@types/minimist": {
@@ -3408,23 +3534,23 @@
       "license": "MIT"
     },
     "node_modules/@types/wavesurfer.js": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/@types/wavesurfer.js/-/wavesurfer.js-5.2.2.tgz",
-      "integrity": "sha512-/vjpf81co0SK3z4F5V79fZrFPQ8pw9/fEpgkzcgNVkBa9sY0gAaYzKuaQyCX/yjVf6kc73uPtWABQuVgvpguDQ==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@types/wavesurfer.js/-/wavesurfer.js-6.0.1.tgz",
+      "integrity": "sha512-WkHu4SgMdqWsR1fHVrkgNXrgcJBPUgMzI8YaZW86aemNSdnWijSkJQ1hEk8jgpeMKJx9oxu7I1x0pIHIlVPr2w==",
       "dev": true,
       "dependencies": {
         "@types/debounce": "*"
       }
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.0.tgz",
-      "integrity": "sha512-XXVKnMsq2fuu9K2KsIxPUGqb6xAImz8MEChClbXmE3VbveFtBUU5bzM6IPVWqzyADIgdkS2Ws/6Xo7W2TeZWjQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.12.1.tgz",
+      "integrity": "sha512-M499lqa8rnNK7mUv74lSFFttuUsubIRdAbHcVaP93oFcKkEmHmLqy2n7jM9C8DVmFMYK61ExrZU6dLYhQZmUpw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.10.0",
-        "@typescript-eslint/type-utils": "5.10.0",
-        "@typescript-eslint/utils": "5.10.0",
+        "@typescript-eslint/scope-manager": "5.12.1",
+        "@typescript-eslint/type-utils": "5.12.1",
+        "@typescript-eslint/utils": "5.12.1",
         "debug": "^4.3.2",
         "functional-red-black-tree": "^1.0.1",
         "ignore": "^5.1.8",
@@ -3464,14 +3590,14 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.0.tgz",
-      "integrity": "sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.12.1.tgz",
+      "integrity": "sha512-6LuVUbe7oSdHxUWoX/m40Ni8gsZMKCi31rlawBHt7VtW15iHzjbpj2WLiToG2758KjtCCiLRKZqfrOdl3cNKuw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.10.0",
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/typescript-estree": "5.10.0",
+        "@typescript-eslint/scope-manager": "5.12.1",
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/typescript-estree": "5.12.1",
         "debug": "^4.3.2"
       },
       "engines": {
@@ -3491,13 +3617,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz",
-      "integrity": "sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.12.1.tgz",
+      "integrity": "sha512-J0Wrh5xS6XNkd4TkOosxdpObzlYfXjAFIm9QxYLCPOcHVv1FyyFCPom66uIh8uBr0sZCrtS+n19tzufhwab8ZQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/visitor-keys": "5.10.0"
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/visitor-keys": "5.12.1"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3508,12 +3634,12 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.0.tgz",
-      "integrity": "sha512-TzlyTmufJO5V886N+hTJBGIfnjQDQ32rJYxPaeiyWKdjsv2Ld5l8cbS7pxim4DeNs62fKzRSt8Q14Evs4JnZyQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.12.1.tgz",
+      "integrity": "sha512-Gh8feEhsNLeCz6aYqynh61Vsdy+tiNNkQtc+bN3IvQvRqHkXGUhYkUi+ePKzP0Mb42se7FDb+y2SypTbpbR/Sg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/utils": "5.10.0",
+        "@typescript-eslint/utils": "5.12.1",
         "debug": "^4.3.2",
         "tsutils": "^3.21.0"
       },
@@ -3534,9 +3660,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.0.tgz",
-      "integrity": "sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.12.1.tgz",
+      "integrity": "sha512-hfcbq4qVOHV1YRdhkDldhV9NpmmAu2vp6wuFODL71Y0Ixak+FLeEU4rnPxgmZMnGreGEghlEucs9UZn5KOfHJA==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3547,13 +3673,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz",
-      "integrity": "sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.12.1.tgz",
+      "integrity": "sha512-ahOdkIY9Mgbza7L9sIi205Pe1inCkZWAHE1TV1bpxlU4RZNPtXaDZfiiFWcL9jdxvW1hDYZJXrFm+vlMkXRbBw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/visitor-keys": "5.10.0",
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/visitor-keys": "5.12.1",
         "debug": "^4.3.2",
         "globby": "^11.0.4",
         "is-glob": "^4.0.3",
@@ -3589,15 +3715,15 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.0.tgz",
-      "integrity": "sha512-IGYwlt1CVcFoE2ueW4/ioEwybR60RAdGeiJX/iDAw0t5w0wK3S7QncDwpmsM70nKgGTuVchEWB8lwZwHqPAWRg==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.12.1.tgz",
+      "integrity": "sha512-Qq9FIuU0EVEsi8fS6pG+uurbhNTtoYr4fq8tKjBupsK5Bgbk2I32UGm0Sh+WOyjOPgo/5URbxxSNV6HYsxV4MQ==",
       "dev": true,
       "dependencies": {
         "@types/json-schema": "^7.0.9",
-        "@typescript-eslint/scope-manager": "5.10.0",
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/typescript-estree": "5.10.0",
+        "@typescript-eslint/scope-manager": "5.12.1",
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/typescript-estree": "5.12.1",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       },
@@ -3613,12 +3739,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz",
-      "integrity": "sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.12.1.tgz",
+      "integrity": "sha512-l1KSLfupuwrXx6wc0AuOmC7Ko5g14ZOQ86wJJqRbdLbXLK02pK/DPiDDqCc7BqqiiA04/eAA6ayL0bgOrAkH7A==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.10.0",
+        "@typescript-eslint/types": "5.12.1",
         "eslint-visitor-keys": "^3.0.0"
       },
       "engines": {
@@ -3740,12 +3866,6 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "node_modules/alphanum-sort": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
-      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
-      "dev": true
-    },
     "node_modules/amdefine": {
       "version": "1.0.1",
       "license": "BSD-3-Clause OR MIT",
@@ -3754,16 +3874,6 @@
         "node": ">=0.4.2"
       }
     },
-    "node_modules/ansi-colors": {
-      "version": "4.1.1",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/ansi-escapes": {
       "version": "3.2.0",
       "dev": true,
@@ -3799,8 +3909,9 @@
     },
     "node_modules/anymatch": {
       "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
       "dev": true,
-      "license": "ISC",
       "dependencies": {
         "normalize-path": "^3.0.0",
         "picomatch": "^2.0.4"
@@ -3878,8 +3989,9 @@
     },
     "node_modules/astral-regex": {
       "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
@@ -4009,9 +4121,10 @@
       "license": "Apache-2.0"
     },
     "node_modules/binary-extensions": {
-      "version": "2.1.0",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
@@ -4368,9 +4481,9 @@
       "license": "MIT"
     },
     "node_modules/choices.js": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-10.0.0.tgz",
-      "integrity": "sha512-I/p92v2Oqbgf/ugThrD2E5nVqtVv6QouiURC7izFr6Mqn5NNUX8VZO64Rur0gh4GWKovj32WcxONzgqJJr5vdA==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-10.1.0.tgz",
+      "integrity": "sha512-NtrFt7c7ZQEGmkWsAV+EHynJhADWoZ82JEfg1+vQ9MMKJD4Ax2rzYPxXe+Q64i0HgUgWG/XTN3gN2pB8UFFFlA==",
       "dependencies": {
         "deepmerge": "^4.2.2",
         "fuse.js": "^6.5.3",
@@ -4378,9 +4491,16 @@
       }
     },
     "node_modules/chokidar": {
-      "version": "3.5.2",
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
       "dev": true,
-      "license": "MIT",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
       "dependencies": {
         "anymatch": "~3.1.2",
         "braces": "~3.0.2",
@@ -4482,8 +4602,9 @@
     },
     "node_modules/cli-truncate": {
       "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "slice-ansi": "^3.0.0",
         "string-width": "^4.2.0"
@@ -4497,67 +4618,27 @@
     },
     "node_modules/cli-truncate/node_modules/ansi-regex": {
       "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
       "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cli-truncate/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
       "engines": {
         "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/cli-truncate/node_modules/color-convert": {
-      "version": "2.0.1",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
       }
     },
-    "node_modules/cli-truncate/node_modules/color-name": {
-      "version": "1.1.4",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cli-truncate/node_modules/slice-ansi": {
-      "version": "3.0.0",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/cli-truncate/node_modules/string-width": {
       "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -4569,8 +4650,9 @@
     },
     "node_modules/cli-truncate/node_modules/strip-ansi": {
       "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1"
       },
@@ -4695,8 +4777,9 @@
     },
     "node_modules/colorette": {
       "version": "2.0.16",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz",
+      "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
+      "dev": true
     },
     "node_modules/colors": {
       "version": "1.4.0",
@@ -5124,12 +5207,12 @@
       }
     },
     "node_modules/css-blank-pseudo": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.2.tgz",
-      "integrity": "sha512-hOb1LFjRR+8ocA071xUSmg5VslJ8NGo/I2qpUpdeAYyBVCgupS5O8SEVo4SxEMYyFBNodBkzG3T1iqW9HCXxew==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz",
+      "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       },
       "bin": {
         "css-blank-pseudo": "dist/cli.cjs"
@@ -5138,7 +5221,7 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/css-declaration-sorter": {
@@ -5156,13 +5239,22 @@
         "postcss": "^8.0.9"
       }
     },
+    "node_modules/css-functions-list": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz",
+      "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      }
+    },
     "node_modules/css-has-pseudo": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.3.tgz",
-      "integrity": "sha512-0gDYWEKaGacwxCqvQ3Ypg6wGdD1AztbMm5h1JsactG2hP2eiflj808QITmuWBpE7sjSEVrAlZhPTVd/nNMj/hQ==",
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz",
+      "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       },
       "bin": {
         "css-has-pseudo": "dist/cli.cjs"
@@ -5171,13 +5263,13 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/css-prefers-color-scheme": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.2.tgz",
-      "integrity": "sha512-gv0KQBEM+q/XdoKyznovq3KW7ocO7k+FhPP+hQR1MenJdu0uPGS6IZa9PzlbqBeS6XcZJNAoqoFxlAUW461CrA==",
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
+      "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
       "dev": true,
       "bin": {
         "css-prefers-color-scheme": "dist/cli.cjs"
@@ -5186,7 +5278,7 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/css-tree": {
@@ -5210,9 +5302,9 @@
       }
     },
     "node_modules/cssdb": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-5.0.0.tgz",
-      "integrity": "sha512-Q7982SynYCtcLUBCPgUPFy2TZmDiFyimpdln8K2v4w2c07W4rXL7q5F1ksVAqOAQfxKyyUGCKSsioezKT5bU1Q==",
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-6.4.0.tgz",
+      "integrity": "sha512-8NMWrur/ewSNrRNZndbtOTXc2Xb2b+NCTPHj8VErFYvJUlgsMAiBGaFaxG6hjy9zbCjj2ZLwSQrMM+tormO8qA==",
       "dev": true
     },
     "node_modules/cssesc": {
@@ -5226,12 +5318,12 @@
       }
     },
     "node_modules/cssnano": {
-      "version": "5.0.15",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.15.tgz",
-      "integrity": "sha512-ppZsS7oPpi2sfiyV5+i+NbB/3GtQ+ab2Vs1azrZaXWujUSN4o+WdTxlCZIMcT9yLW3VO/5yX3vpyDaQ1nIn8CQ==",
+      "version": "5.0.17",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.17.tgz",
+      "integrity": "sha512-fmjLP7k8kL18xSspeXTzRhaFtRI7DL9b8IcXR80JgtnWBpvAzHT7sCR/6qdn0tnxIaINUN6OEQu83wF57Gs3Xw==",
       "dev": true,
       "dependencies": {
-        "cssnano-preset-default": "^5.1.10",
+        "cssnano-preset-default": "^5.1.12",
         "lilconfig": "^2.0.3",
         "yaml": "^1.10.2"
       },
@@ -5247,40 +5339,40 @@
       }
     },
     "node_modules/cssnano-preset-default": {
-      "version": "5.1.10",
-      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.10.tgz",
-      "integrity": "sha512-BcpSzUVygHMOnp9uG5rfPzTOCb0GAHQkqtUQx8j1oMNF9A1Q8hziOOhiM4bdICpmrBIU85BE64RD5XGYsVQZNA==",
+      "version": "5.1.12",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.12.tgz",
+      "integrity": "sha512-rO/JZYyjW1QNkWBxMGV28DW7d98UDLaF759frhli58QFehZ+D/LSmwQ2z/ylBAe2hUlsIWTq6NYGfQPq65EF9w==",
       "dev": true,
       "dependencies": {
         "css-declaration-sorter": "^6.0.3",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-calc": "^8.2.0",
-        "postcss-colormin": "^5.2.3",
-        "postcss-convert-values": "^5.0.2",
-        "postcss-discard-comments": "^5.0.1",
-        "postcss-discard-duplicates": "^5.0.1",
-        "postcss-discard-empty": "^5.0.1",
-        "postcss-discard-overridden": "^5.0.2",
-        "postcss-merge-longhand": "^5.0.4",
-        "postcss-merge-rules": "^5.0.4",
-        "postcss-minify-font-values": "^5.0.2",
-        "postcss-minify-gradients": "^5.0.4",
-        "postcss-minify-params": "^5.0.3",
-        "postcss-minify-selectors": "^5.1.1",
-        "postcss-normalize-charset": "^5.0.1",
-        "postcss-normalize-display-values": "^5.0.2",
-        "postcss-normalize-positions": "^5.0.2",
-        "postcss-normalize-repeat-style": "^5.0.2",
-        "postcss-normalize-string": "^5.0.2",
-        "postcss-normalize-timing-functions": "^5.0.2",
-        "postcss-normalize-unicode": "^5.0.2",
-        "postcss-normalize-url": "^5.0.4",
-        "postcss-normalize-whitespace": "^5.0.2",
-        "postcss-ordered-values": "^5.0.3",
-        "postcss-reduce-initial": "^5.0.2",
-        "postcss-reduce-transforms": "^5.0.2",
-        "postcss-svgo": "^5.0.3",
-        "postcss-unique-selectors": "^5.0.2"
+        "postcss-colormin": "^5.2.5",
+        "postcss-convert-values": "^5.0.4",
+        "postcss-discard-comments": "^5.0.3",
+        "postcss-discard-duplicates": "^5.0.3",
+        "postcss-discard-empty": "^5.0.3",
+        "postcss-discard-overridden": "^5.0.4",
+        "postcss-merge-longhand": "^5.0.6",
+        "postcss-merge-rules": "^5.0.6",
+        "postcss-minify-font-values": "^5.0.4",
+        "postcss-minify-gradients": "^5.0.6",
+        "postcss-minify-params": "^5.0.5",
+        "postcss-minify-selectors": "^5.1.3",
+        "postcss-normalize-charset": "^5.0.3",
+        "postcss-normalize-display-values": "^5.0.3",
+        "postcss-normalize-positions": "^5.0.4",
+        "postcss-normalize-repeat-style": "^5.0.4",
+        "postcss-normalize-string": "^5.0.4",
+        "postcss-normalize-timing-functions": "^5.0.3",
+        "postcss-normalize-unicode": "^5.0.4",
+        "postcss-normalize-url": "^5.0.5",
+        "postcss-normalize-whitespace": "^5.0.4",
+        "postcss-ordered-values": "^5.0.5",
+        "postcss-reduce-initial": "^5.0.3",
+        "postcss-reduce-transforms": "^5.0.4",
+        "postcss-svgo": "^5.0.4",
+        "postcss-unique-selectors": "^5.0.4"
       },
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -5290,9 +5382,9 @@
       }
     },
     "node_modules/cssnano-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.0.tgz",
-      "integrity": "sha512-Pzs7/BZ6OgT+tXXuF12DKR8SmSbzUeVYCtMBbS8lI0uAm3mrYmkyqCXXPsQESI6kmLfEVBppbdVY/el3hg3nAA==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.2.tgz",
+      "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==",
       "dev": true,
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -5819,19 +5911,6 @@
         "once": "^1.4.0"
       }
     },
-    "node_modules/enquirer": {
-      "version": "2.3.6",
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "ansi-colors": "^4.1.1"
-      },
-      "engines": {
-        "node": ">=8.6"
-      }
-    },
     "node_modules/entities": {
       "version": "2.2.0",
       "dev": true,
@@ -5966,53 +6045,351 @@
         "es5-ext": "~0.10.14"
       }
     },
-    "node_modules/es6-symbol": {
-      "version": "3.1.3",
-      "license": "ISC",
-      "dependencies": {
-        "d": "^1.0.1",
-        "ext": "^1.1.2"
+    "node_modules/es6-symbol": {
+      "version": "3.1.3",
+      "license": "ISC",
+      "dependencies": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.23.tgz",
+      "integrity": "sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==",
+      "dev": true,
+      "hasInstallScript": true,
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "optionalDependencies": {
+        "esbuild-android-arm64": "0.14.23",
+        "esbuild-darwin-64": "0.14.23",
+        "esbuild-darwin-arm64": "0.14.23",
+        "esbuild-freebsd-64": "0.14.23",
+        "esbuild-freebsd-arm64": "0.14.23",
+        "esbuild-linux-32": "0.14.23",
+        "esbuild-linux-64": "0.14.23",
+        "esbuild-linux-arm": "0.14.23",
+        "esbuild-linux-arm64": "0.14.23",
+        "esbuild-linux-mips64le": "0.14.23",
+        "esbuild-linux-ppc64le": "0.14.23",
+        "esbuild-linux-riscv64": "0.14.23",
+        "esbuild-linux-s390x": "0.14.23",
+        "esbuild-netbsd-64": "0.14.23",
+        "esbuild-openbsd-64": "0.14.23",
+        "esbuild-sunos-64": "0.14.23",
+        "esbuild-windows-32": "0.14.23",
+        "esbuild-windows-64": "0.14.23",
+        "esbuild-windows-arm64": "0.14.23"
+      }
+    },
+    "node_modules/esbuild-android-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz",
+      "integrity": "sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz",
+      "integrity": "sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-darwin-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz",
+      "integrity": "sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz",
+      "integrity": "sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-freebsd-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz",
+      "integrity": "sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-32": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz",
+      "integrity": "sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz",
+      "integrity": "sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz",
+      "integrity": "sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz",
+      "integrity": "sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-mips64le": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz",
+      "integrity": "sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==",
+      "cpu": [
+        "mips64el"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-ppc64le": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz",
+      "integrity": "sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==",
+      "cpu": [
+        "ppc64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-riscv64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz",
+      "integrity": "sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==",
+      "cpu": [
+        "riscv64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-linux-s390x": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz",
+      "integrity": "sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==",
+      "cpu": [
+        "s390x"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-netbsd-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz",
+      "integrity": "sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-openbsd-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz",
+      "integrity": "sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-sunos-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz",
+      "integrity": "sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/esbuild": {
-      "version": "0.13.15",
+    "node_modules/esbuild-windows-32": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz",
+      "integrity": "sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==",
+      "cpu": [
+        "ia32"
+      ],
       "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "bin": {
-        "esbuild": "bin/esbuild"
-      },
-      "optionalDependencies": {
-        "esbuild-android-arm64": "0.13.15",
-        "esbuild-darwin-64": "0.13.15",
-        "esbuild-darwin-arm64": "0.13.15",
-        "esbuild-freebsd-64": "0.13.15",
-        "esbuild-freebsd-arm64": "0.13.15",
-        "esbuild-linux-32": "0.13.15",
-        "esbuild-linux-64": "0.13.15",
-        "esbuild-linux-arm": "0.13.15",
-        "esbuild-linux-arm64": "0.13.15",
-        "esbuild-linux-mips64le": "0.13.15",
-        "esbuild-linux-ppc64le": "0.13.15",
-        "esbuild-netbsd-64": "0.13.15",
-        "esbuild-openbsd-64": "0.13.15",
-        "esbuild-sunos-64": "0.13.15",
-        "esbuild-windows-32": "0.13.15",
-        "esbuild-windows-64": "0.13.15",
-        "esbuild-windows-arm64": "0.13.15"
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
       }
     },
-    "node_modules/esbuild-linux-64": {
-      "version": "0.13.15",
+    "node_modules/esbuild-windows-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz",
+      "integrity": "sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==",
       "cpu": [
         "x64"
       ],
       "dev": true,
-      "license": "MIT",
       "optional": true,
       "os": [
-        "linux"
-      ]
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/esbuild-windows-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz",
+      "integrity": "sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=12"
+      }
     },
     "node_modules/escalade": {
       "version": "3.1.1",
@@ -6081,12 +6458,12 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.7.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz",
-      "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==",
+      "version": "8.10.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
+      "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
       "dev": true,
       "dependencies": {
-        "@eslint/eslintrc": "^1.0.5",
+        "@eslint/eslintrc": "^1.2.0",
         "@humanwhocodes/config-array": "^0.9.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
@@ -6094,10 +6471,10 @@
         "debug": "^4.3.2",
         "doctrine": "^3.0.0",
         "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.1.0",
+        "eslint-scope": "^7.1.1",
         "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.2.0",
-        "espree": "^9.3.0",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.3.1",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
@@ -6133,9 +6510,10 @@
       }
     },
     "node_modules/eslint-config-prettier": {
-      "version": "8.3.0",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.4.0.tgz",
+      "integrity": "sha512-CFotdUcMY18nGRo5KGsnNxpznzhkopOcOo0InID+sgQssPrzjvsyKZPvOgymTFeHrFuC3Tzdf2YndhXtULK9Iw==",
       "dev": true,
-      "license": "MIT",
       "bin": {
         "eslint-config-prettier": "bin/cli.js"
       },
@@ -6204,9 +6582,9 @@
       }
     },
     "node_modules/eslint-visitor-keys": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz",
-      "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6232,9 +6610,9 @@
       }
     },
     "node_modules/eslint/node_modules/eslint-scope": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz",
-      "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+      "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
       "dev": true,
       "dependencies": {
         "esrecurse": "^4.3.0",
@@ -6288,14 +6666,14 @@
       }
     },
     "node_modules/espree": {
-      "version": "9.3.0",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz",
-      "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==",
+      "version": "9.3.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
+      "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
       "dev": true,
       "dependencies": {
         "acorn": "^8.7.0",
         "acorn-jsx": "^5.3.1",
-        "eslint-visitor-keys": "^3.1.0"
+        "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6515,9 +6893,10 @@
       "license": "Apache-2.0"
     },
     "node_modules/fast-glob": {
-      "version": "3.2.7",
+      "version": "3.2.11",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "@nodelib/fs.stat": "^2.0.2",
         "@nodelib/fs.walk": "^1.2.3",
@@ -6526,7 +6905,7 @@
         "micromatch": "^4.0.4"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=8.6.0"
       }
     },
     "node_modules/fast-json-stable-stringify": {
@@ -6987,9 +7366,9 @@
       }
     },
     "node_modules/globals": {
-      "version": "13.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
-      "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+      "version": "13.12.1",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
+      "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
       "dev": true,
       "dependencies": {
         "type-fest": "^0.20.2"
@@ -7014,15 +7393,16 @@
       }
     },
     "node_modules/globby": {
-      "version": "11.0.4",
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "array-union": "^2.1.0",
         "dir-glob": "^3.0.1",
-        "fast-glob": "^3.1.1",
-        "ignore": "^5.1.4",
-        "merge2": "^1.3.0",
+        "fast-glob": "^3.2.9",
+        "ignore": "^5.2.0",
+        "merge2": "^1.4.1",
         "slash": "^3.0.0"
       },
       "engines": {
@@ -7473,8 +7853,9 @@
     },
     "node_modules/is-binary-path": {
       "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "binary-extensions": "^2.0.0"
       },
@@ -7745,11 +8126,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/is-typedarray": {
-      "version": "1.0.0",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/is-utf8": {
       "version": "0.2.1",
       "dev": true,
@@ -8218,9 +8594,9 @@
       "license": "MIT"
     },
     "node_modules/lint-staged": {
-      "version": "12.2.0",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.2.0.tgz",
-      "integrity": "sha512-TnNciMBhmEqzqM+RvzqqdvrG4TsI8wCDMX1Vg9+rj2Y9uY70Nq84Mb1WOIiwxW9l5tUlCOqtY5La71RM2fSgfA==",
+      "version": "12.3.4",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.4.tgz",
+      "integrity": "sha512-yv/iK4WwZ7/v0GtVkNb3R82pdL9M+ScpIbJLJNyCXkJ1FGaXvRCOg/SeL59SZtPpqZhE7BD6kPKFLIDUhDx2/w==",
       "dev": true,
       "dependencies": {
         "cli-truncate": "^3.1.0",
@@ -8229,10 +8605,10 @@
         "debug": "^4.3.3",
         "execa": "^5.1.1",
         "lilconfig": "2.0.4",
-        "listr2": "^3.13.5",
+        "listr2": "^4.0.1",
         "micromatch": "^4.0.4",
         "normalize-path": "^3.0.0",
-        "object-inspect": "^1.11.1",
+        "object-inspect": "^1.12.0",
         "string-argv": "^0.3.1",
         "supports-color": "^9.2.1",
         "yaml": "^1.10.2"
@@ -8366,21 +8742,22 @@
       }
     },
     "node_modules/listr2": {
-      "version": "3.13.5",
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.4.tgz",
+      "integrity": "sha512-vJOm5KD6uZXjSsrwajr+mNacIjf87gWvlBEltPWLbTkslUscWAzquyK4xfe9Zd4RDgO5nnwFyV06FC+uVR+5mg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "cli-truncate": "^2.1.0",
         "colorette": "^2.0.16",
         "log-update": "^4.0.0",
         "p-map": "^4.0.0",
         "rfdc": "^1.3.0",
-        "rxjs": "^7.4.0",
+        "rxjs": "^7.5.4",
         "through": "^2.3.8",
         "wrap-ansi": "^7.0.0"
       },
       "engines": {
-        "node": ">=10.0.0"
+        "node": ">=12"
       },
       "peerDependencies": {
         "enquirer": ">= 2.3.0 < 3"
@@ -8392,41 +8769,43 @@
       }
     },
     "node_modules/listr2/node_modules/rxjs": {
-      "version": "7.4.0",
+      "version": "7.5.4",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz",
+      "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==",
       "dev": true,
-      "license": "Apache-2.0",
       "dependencies": {
-        "tslib": "~2.1.0"
+        "tslib": "^2.1.0"
       }
     },
     "node_modules/listr2/node_modules/tslib": {
-      "version": "2.1.0",
-      "dev": true,
-      "license": "0BSD"
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+      "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+      "dev": true
     },
     "node_modules/lit": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.1.1.tgz",
-      "integrity": "sha512-yqDqf36IhXwOxIQSFqCMgpfvDCRdxLCLZl7m/+tO5C9W/OBHUj17qZpiMBT35v97QMVKcKEi1KZ3hZRyTwBNsQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.0.tgz",
+      "integrity": "sha512-FDyxUuczo6cJJY/2Bkgfh1872U4ikUvmK1Cb6+lYC1CW+QOo8CaWXCpvPKFzYsz0ojUxoruBLVrECc7VI2f1dQ==",
       "dependencies": {
-        "@lit/reactive-element": "^1.1.0",
-        "lit-element": "^3.1.0",
-        "lit-html": "^2.1.0"
+        "@lit/reactive-element": "^1.3.0",
+        "lit-element": "^3.2.0",
+        "lit-html": "^2.2.0"
       }
     },
     "node_modules/lit-element": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.1.1.tgz",
-      "integrity": "sha512-14ClnMAU8EXnzC+M2/KDd3SFmNUn1QUw1+GxWkEMwGV3iaH8ObunMlO5svzvaWlkSV0WlxJCi40NGnDVJ2XZKQ==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
+      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
       "dependencies": {
-        "@lit/reactive-element": "^1.1.0",
-        "lit-html": "^2.1.0"
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.2.0"
       }
     },
     "node_modules/lit-html": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.1.1.tgz",
-      "integrity": "sha512-E4BImK6lopAYanJpvcGaAG8kQFF1ccIulPu2BRNZI7acFB6i4ujjjsnaPVFT1j/4lD9r8GKih0Y8d7/LH8SeyQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.0.tgz",
+      "integrity": "sha512-dJnevgV8VkCuOXLWrjQopDE8nSy8CzipZ/ATfYQv7z7Dct4abblcKecf50gkIScuwCTzKvRLgvTgV0zzagW4gA==",
       "dependencies": {
         "@types/trusted-types": "^2.0.2"
       }
@@ -8536,13 +8915,15 @@
     },
     "node_modules/lodash.truncate": {
       "version": "4.4.2",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+      "dev": true
     },
     "node_modules/lodash.uniq": {
       "version": "4.5.0",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+      "dev": true
     },
     "node_modules/lodash.uniqby": {
       "version": "4.7.0",
@@ -8551,8 +8932,9 @@
     },
     "node_modules/log-update": {
       "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+      "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-escapes": "^4.3.0",
         "cli-cursor": "^3.1.0",
@@ -8568,8 +8950,9 @@
     },
     "node_modules/log-update/node_modules/ansi-escapes": {
       "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "type-fest": "^0.21.3"
       },
@@ -8582,16 +8965,18 @@
     },
     "node_modules/log-update/node_modules/ansi-regex": {
       "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/log-update/node_modules/ansi-styles": {
       "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "color-convert": "^2.0.1"
       },
@@ -8604,8 +8989,9 @@
     },
     "node_modules/log-update/node_modules/cli-cursor": {
       "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "restore-cursor": "^3.1.0"
       },
@@ -8615,8 +9001,9 @@
     },
     "node_modules/log-update/node_modules/color-convert": {
       "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "color-name": "~1.1.4"
       },
@@ -8626,21 +9013,24 @@
     },
     "node_modules/log-update/node_modules/color-name": {
       "version": "1.1.4",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
     },
     "node_modules/log-update/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/log-update/node_modules/onetime": {
       "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "mimic-fn": "^2.1.0"
       },
@@ -8653,8 +9043,9 @@
     },
     "node_modules/log-update/node_modules/restore-cursor": {
       "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "onetime": "^5.1.0",
         "signal-exit": "^3.0.2"
@@ -8663,10 +9054,28 @@
         "node": ">=8"
       }
     },
+    "node_modules/log-update/node_modules/slice-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+      }
+    },
     "node_modules/log-update/node_modules/string-width": {
       "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -8678,8 +9087,9 @@
     },
     "node_modules/log-update/node_modules/strip-ansi": {
       "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1"
       },
@@ -8689,8 +9099,9 @@
     },
     "node_modules/log-update/node_modules/type-fest": {
       "version": "0.21.3",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
       "dev": true,
-      "license": "(MIT OR CC0-1.0)",
       "engines": {
         "node": ">=10"
       },
@@ -8700,8 +9111,9 @@
     },
     "node_modules/log-update/node_modules/wrap-ansi": {
       "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
@@ -8762,9 +9174,9 @@
       }
     },
     "node_modules/marked": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
-      "integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw==",
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
+      "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==",
       "bin": {
         "marked": "bin/marked.js"
       },
@@ -9008,9 +9420,9 @@
       "license": "ISC"
     },
     "node_modules/nanoid": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+      "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
       "bin": {
         "nanoid": "bin/nanoid.cjs"
       },
@@ -11664,8 +12076,9 @@
       }
     },
     "node_modules/object-inspect": {
-      "version": "1.11.1",
-      "license": "MIT",
+      "version": "1.12.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
+      "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -12112,12 +12525,13 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.5",
-      "license": "MIT",
+      "version": "8.4.7",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz",
+      "integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==",
       "dependencies": {
-        "nanoid": "^3.1.30",
+        "nanoid": "^3.3.1",
         "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.1"
+        "source-map-js": "^1.0.2"
       },
       "engines": {
         "node": "^10 || ^12 || >=14"
@@ -12140,22 +12554,37 @@
       }
     },
     "node_modules/postcss-calc": {
-      "version": "8.2.2",
-      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.2.tgz",
-      "integrity": "sha512-B5R0UeB4zLJvxNt1FVCaDZULdzsKLPc6FhjFJ+xwFiq7VG4i9cuaJLxVjNtExNK8ocm3n2o4unXXLiVX1SCqxA==",
+      "version": "8.2.4",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
+      "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.2",
-        "postcss-value-parser": "^4.0.2"
+        "postcss-selector-parser": "^6.0.9",
+        "postcss-value-parser": "^4.2.0"
       },
       "peerDependencies": {
         "postcss": "^8.2.2"
       }
     },
+    "node_modules/postcss-clamp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.0.0.tgz",
+      "integrity": "sha512-FsMmeBZtymFN7Jtlnw9is8I4nB+qEEb/qS0ZLTIqcKiwZyHBq44Yhv29Q+VQsTGHYFqIr/s/9tqvNM7j+j1d+g==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=7.6.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4.6"
+      }
+    },
     "node_modules/postcss-color-functional-notation": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.1.tgz",
-      "integrity": "sha512-62OBIXCjRXpQZcFOYIXwXBlpAVWrYk8ek1rcjvMING4Q2cf0ipyN9qT+BhHA6HmftGSEnFQu2qgKO3gMscl3Rw==",
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.2.tgz",
+      "integrity": "sha512-DXVtwUhIk4f49KK5EGuEdgx4Gnyj6+t2jBSEmxvpIK9QI40tWrpS2Pua8Q7iIZWBrki2QOaeUdEaLPPa91K0RQ==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12164,13 +12593,13 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-color-hex-alpha": {
-      "version": "8.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.2.tgz",
-      "integrity": "sha512-gyx8RgqSmGVK156NAdKcsfkY3KPGHhKqvHTL3hhveFrBBToguKFzhyiuk3cljH6L4fJ0Kv+JENuPXs1Wij27Zw==",
+      "version": "8.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz",
+      "integrity": "sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12179,7 +12608,7 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-color-rebeccapurple": {
@@ -12198,9 +12627,9 @@
       }
     },
     "node_modules/postcss-colormin": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.3.tgz",
-      "integrity": "sha512-dra4xoAjub2wha6RUXAgadHEn2lGxbj8drhFcIGLOMn914Eu7DkPUurugDXgstwttCYkJtZ/+PkWRWdp3UHRIA==",
+      "version": "5.2.5",
+      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.5.tgz",
+      "integrity": "sha512-+X30aDaGYq81mFqwyPpnYInsZQnNpdxMX0ajlY7AExCexEFkPVV+KrO7kXwayqEWL2xwEbNQ4nUO0ZsRWGnevg==",
       "dev": true,
       "dependencies": {
         "browserslist": "^4.16.6",
@@ -12216,12 +12645,12 @@
       }
     },
     "node_modules/postcss-convert-values": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz",
-      "integrity": "sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.4.tgz",
+      "integrity": "sha512-bugzSAyjIexdObovsPZu/sBCTHccImJxLyFgeV0MmNBm/Lw5h5XnjfML6gzEmJ3A6nyfCW7hb1JXzcsA4Zfbdw==",
       "dev": true,
       "dependencies": {
-        "postcss-value-parser": "^4.1.0"
+        "postcss-value-parser": "^4.2.0"
       },
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12243,9 +12672,9 @@
       }
     },
     "node_modules/postcss-custom-properties": {
-      "version": "12.1.3",
-      "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.3.tgz",
-      "integrity": "sha512-rtu3otIeY532PnEuuBrIIe+N+pcdbX/7JMZfrcL09wc78YayrHw5E8UkDfvnlOhEUrI4ptCuzXQfj+Or6spbGA==",
+      "version": "12.1.4",
+      "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.4.tgz",
+      "integrity": "sha512-i6AytuTCoDLJkWN/MtAIGriJz3j7UX6bV7Z5t+KgFz+dwZS15/mlTJY1S0kRizlk6ba0V8u8hN50Fz5Nm7tdZw==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12254,7 +12683,7 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-custom-selectors": {
@@ -12273,24 +12702,24 @@
       }
     },
     "node_modules/postcss-dir-pseudo-class": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.3.tgz",
-      "integrity": "sha512-qiPm+CNAlgXiMf0J5IbBBEXA9l/Q5HGsNGkL3znIwT2ZFRLGY9U2fTUpa4lqCUXQOxaLimpacHeQC80BD2qbDw==",
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz",
+      "integrity": "sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       },
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-discard-comments": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz",
-      "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.3.tgz",
+      "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==",
       "dev": true,
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12300,9 +12729,9 @@
       }
     },
     "node_modules/postcss-discard-duplicates": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz",
-      "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.3.tgz",
+      "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==",
       "dev": true,
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12312,9 +12741,9 @@
       }
     },
     "node_modules/postcss-discard-empty": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz",
-      "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.3.tgz",
+      "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==",
       "dev": true,
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12324,9 +12753,9 @@
       }
     },
     "node_modules/postcss-discard-overridden": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.2.tgz",
-      "integrity": "sha512-+56BLP6NSSUuWUXjRgAQuho1p5xs/hU5Sw7+xt9S3JSg+7R6+WMGnJW7Hre/6tTuZ2xiXMB42ObkiZJ2hy/Pew==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.4.tgz",
+      "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==",
       "dev": true,
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12336,24 +12765,25 @@
       }
     },
     "node_modules/postcss-double-position-gradients": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.4.tgz",
-      "integrity": "sha512-qz+s5vhKJlsHw8HjSs+HVk2QGFdRyC68KGRQGX3i+GcnUjhWhXQEmCXW6siOJkZ1giu0ddPwSO6I6JdVVVPoog==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.0.tgz",
+      "integrity": "sha512-oz73I08yMN3oxjj0s8mED1rG+uOYoK3H8N9RjQofyg52KBRNmePJKg3fVwTpL2U5ZFbCzXoZBsUD/CvZdlqE4Q==",
       "dev": true,
       "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
         "postcss-value-parser": "^4.2.0"
       },
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-env-function": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.4.tgz",
-      "integrity": "sha512-0ltahRTPtXSIlEZFv7zIvdEib7HN0ZbUQxrxIKn8KbiRyhALo854I/CggU5lyZe6ZBvSTJ6Al2vkZecI2OhneQ==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.5.tgz",
+      "integrity": "sha512-gPUJc71ji9XKyl0WSzAalBeEA/89kU+XpffpPxSaaaZ1c48OL36r1Ep5R6+9XAPkIiDlSvVAwP4io12q/vTcvA==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12362,37 +12792,37 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-focus-visible": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.3.tgz",
-      "integrity": "sha512-ozOsg+L1U8S+rxSHnJJiET6dNLyADcPHhEarhhtCI9DBLGOPG/2i4ddVoFch9LzrBgb8uDaaRI4nuid2OM82ZA==",
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz",
+      "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       },
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-focus-within": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.3.tgz",
-      "integrity": "sha512-fk9y2uFS6/Kpp7/A9Hz9Z4rlFQ8+tzgBcQCXAFSrXFGAbKx+4ZZOmmfHuYjCOMegPWoz0pnC6fNzi8j7Xyqp5Q==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz",
+      "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       },
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-font-variant": {
@@ -12405,21 +12835,21 @@
       }
     },
     "node_modules/postcss-gap-properties": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.2.tgz",
-      "integrity": "sha512-EaMy/pbxtQnKDsnbEjdqlkCkROTQZzolcLKgIE+3b7EuJfJydH55cZeHfm+MtIezXRqhR80VKgaztO/vHq94Fw==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz",
+      "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==",
       "dev": true,
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-image-set-function": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.4.tgz",
-      "integrity": "sha512-BlEo9gSTj66lXjRNByvkMK9dEdEGFXRfGjKRi9fo8s0/P3oEk74cAoonl/utiM50E2OPVb/XSu+lWvdW4KtE/Q==",
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz",
+      "integrity": "sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12428,7 +12858,7 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-import": {
@@ -12476,18 +12906,19 @@
       }
     },
     "node_modules/postcss-lab-function": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.0.3.tgz",
-      "integrity": "sha512-MH4tymWmefdZQ7uVG/4icfLjAQmH6o2NRYyVh2mKoB4RXJp9PjsyhZwhH4ouaCQHvg+qJVj3RzeAR1EQpIlXZA==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.1.1.tgz",
+      "integrity": "sha512-j3Z0WQCimY2tMle++YcmygnnVbt6XdnrCV1FO2IpzaCSmtTF2oO8h4ZYUA1Q+QHYroIiaWPvNHt9uBR4riCksQ==",
       "dev": true,
       "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
         "postcss-value-parser": "^4.2.0"
       },
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-load-config": {
@@ -12516,15 +12947,15 @@
       }
     },
     "node_modules/postcss-logical": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.3.tgz",
-      "integrity": "sha512-P5NcHWYrif0vK8rgOy/T87vg0WRIj3HSknrvp1wzDbiBeoDPVmiVRmkown2eSQdpPveat/MC1ess5uhzZFVnqQ==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
+      "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
       "dev": true,
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-media-minmax": {
@@ -12545,13 +12976,13 @@
       "license": "MIT"
     },
     "node_modules/postcss-merge-longhand": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz",
-      "integrity": "sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==",
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.6.tgz",
+      "integrity": "sha512-rkmoPwQO6ymJSmWsX6l2hHeEBQa7C4kJb9jyi5fZB1sE8nSCv7sqchoYPixRwX/yvLoZP2y6FA5kcjiByeJqDg==",
       "dev": true,
       "dependencies": {
-        "postcss-value-parser": "^4.1.0",
-        "stylehacks": "^5.0.1"
+        "postcss-value-parser": "^4.2.0",
+        "stylehacks": "^5.0.3"
       },
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12561,14 +12992,14 @@
       }
     },
     "node_modules/postcss-merge-rules": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.4.tgz",
-      "integrity": "sha512-yOj7bW3NxlQxaERBB0lEY1sH5y+RzevjbdH4DBJurjKERNpknRByFNdNe+V72i5pIZL12woM9uGdS5xbSB+kDQ==",
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.6.tgz",
+      "integrity": "sha512-nzJWJ9yXWp8AOEpn/HFAW72WKVGD2bsLiAmgw4hDchSij27bt6TF+sIK0cJUBAYT3SGcjtGGsOR89bwkkMuMgQ==",
       "dev": true,
       "dependencies": {
         "browserslist": "^4.16.6",
         "caniuse-api": "^3.0.0",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-selector-parser": "^6.0.5"
       },
       "engines": {
@@ -12579,9 +13010,9 @@
       }
     },
     "node_modules/postcss-minify-font-values": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.2.tgz",
-      "integrity": "sha512-R6MJZryq28Cw0AmnyhXrM7naqJZZLoa1paBltIzh2wM7yb4D45TLur+eubTQ4jCmZU9SGeZdWsc5KcSoqTMeTg==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.4.tgz",
+      "integrity": "sha512-RN6q3tyuEesvyCYYFCRGJ41J1XFvgV+dvYGHr0CeHv8F00yILlN8Slf4t8XW4IghlfZYCeyRrANO6HpJ948ieA==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12594,13 +13025,13 @@
       }
     },
     "node_modules/postcss-minify-gradients": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.4.tgz",
-      "integrity": "sha512-RVwZA7NC4R4J76u8X0Q0j+J7ItKUWAeBUJ8oEEZWmtv3Xoh19uNJaJwzNpsydQjk6PkuhRrK+YwwMf+c+68EYg==",
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.6.tgz",
+      "integrity": "sha512-E/dT6oVxB9nLGUTiY/rG5dX9taugv9cbLNTFad3dKxOO+BQg25Q/xo2z2ddG+ZB1CbkZYaVwx5blY8VC7R/43A==",
       "dev": true,
       "dependencies": {
         "colord": "^2.9.1",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-value-parser": "^4.2.0"
       },
       "engines": {
@@ -12611,14 +13042,13 @@
       }
     },
     "node_modules/postcss-minify-params": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.3.tgz",
-      "integrity": "sha512-NY92FUikE+wralaiVexFd5gwb7oJTIDhgTNeIw89i1Ymsgt4RWiPXfz3bg7hDy4NL6gepcThJwOYNtZO/eNi7Q==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.5.tgz",
+      "integrity": "sha512-YBNuq3Rz5LfLFNHb9wrvm6t859b8qIqfXsWeK7wROm3jSKNpO1Y5e8cOyBv6Acji15TgSrAwb3JkVNCqNyLvBg==",
       "dev": true,
       "dependencies": {
-        "alphanum-sort": "^1.0.2",
         "browserslist": "^4.16.6",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-value-parser": "^4.2.0"
       },
       "engines": {
@@ -12629,12 +13059,11 @@
       }
     },
     "node_modules/postcss-minify-selectors": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.1.tgz",
-      "integrity": "sha512-TOzqOPXt91O2luJInaVPiivh90a2SIK5Nf1Ea7yEIM/5w+XA5BGrZGUSW8aEx9pJ/oNj7ZJBhjvigSiBV+bC1Q==",
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.3.tgz",
+      "integrity": "sha512-9RJfTiQEKA/kZhMaEXND893nBqmYQ8qYa/G+uPdVnXF6D/FzpfI6kwBtWEcHx5FqDbA79O9n6fQJfrIj6M8jvQ==",
       "dev": true,
       "dependencies": {
-        "alphanum-sort": "^1.0.2",
         "postcss-selector-parser": "^6.0.5"
       },
       "engines": {
@@ -12677,9 +13106,9 @@
       }
     },
     "node_modules/postcss-normalize-charset": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz",
-      "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.3.tgz",
+      "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==",
       "dev": true,
       "engines": {
         "node": "^10 || ^12 || >=14.0"
@@ -12689,9 +13118,9 @@
       }
     },
     "node_modules/postcss-normalize-display-values": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.2.tgz",
-      "integrity": "sha512-RxXoJPUR0shSjkMMzgEZDjGPrgXUVYyWA/YwQRicb48H15OClPuaDR7tYokLAlGZ2tCSENEN5WxjgxSD5m4cUw==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.3.tgz",
+      "integrity": "sha512-FIV5FY/qs4Ja32jiDb5mVj5iWBlS3N8tFcw2yg98+8MkRgyhtnBgSC0lxU+16AMHbjX5fbSJgw5AXLMolonuRQ==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12704,9 +13133,9 @@
       }
     },
     "node_modules/postcss-normalize-positions": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.2.tgz",
-      "integrity": "sha512-tqghWFVDp2btqFg1gYob1etPNxXLNh3uVeWgZE2AQGh6b2F8AK2Gj36v5Vhyh+APwIzNjmt6jwZ9pTBP+/OM8g==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.4.tgz",
+      "integrity": "sha512-qynirjBX0Lc73ROomZE3lzzmXXTu48/QiEzKgMeqh28+MfuHLsuqC9po4kj84igZqqFGovz8F8hf44hA3dPYmQ==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12719,9 +13148,9 @@
       }
     },
     "node_modules/postcss-normalize-repeat-style": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.2.tgz",
-      "integrity": "sha512-/rIZn8X9bBzC7KvY4iKUhXUGW3MmbXwfPF23jC9wT9xTi7kAvgj8sEgwxjixBmoL6MVa4WOgxNz2hAR6wTK8tw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.4.tgz",
+      "integrity": "sha512-Innt+wctD7YpfeDR7r5Ik6krdyppyAg2HBRpX88fo5AYzC1Ut/l3xaxACG0KsbX49cO2n5EB13clPwuYVt8cMA==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12734,9 +13163,9 @@
       }
     },
     "node_modules/postcss-normalize-string": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.2.tgz",
-      "integrity": "sha512-zaI1yzwL+a/FkIzUWMQoH25YwCYxi917J4pYm1nRXtdgiCdnlTkx5eRzqWEC64HtRa06WCJ9TIutpb6GmW4gFw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.4.tgz",
+      "integrity": "sha512-Dfk42l0+A1CDnVpgE606ENvdmksttLynEqTQf5FL3XGQOyqxjbo25+pglCUvziicTxjtI2NLUR6KkxyUWEVubQ==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12749,9 +13178,9 @@
       }
     },
     "node_modules/postcss-normalize-timing-functions": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.2.tgz",
-      "integrity": "sha512-Ao0PP6MoYsRU1LxeVUW740ioknvdIUmfr6uAA3xWlQJ9s69/Tupy8qwhuKG3xWfl+KvLMAP9p2WXF9cwuk/7Bg==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.3.tgz",
+      "integrity": "sha512-QRfjvFh11moN4PYnJ7hia4uJXeFotyK3t2jjg8lM9mswleGsNw2Lm3I5wO+l4k1FzK96EFwEVn8X8Ojrp2gP4g==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12764,9 +13193,9 @@
       }
     },
     "node_modules/postcss-normalize-unicode": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.2.tgz",
-      "integrity": "sha512-3y/V+vjZ19HNcTizeqwrbZSUsE69ZMRHfiiyLAJb7C7hJtYmM4Gsbajy7gKagu97E8q5rlS9k8FhojA8cpGhWw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.4.tgz",
+      "integrity": "sha512-W79Regn+a+eXTzB+oV/8XJ33s3pDyFTND2yDuUCo0Xa3QSy1HtNIfRVPXNubHxjhlqmMFADr3FSCHT84ITW3ig==",
       "dev": true,
       "dependencies": {
         "browserslist": "^4.16.6",
@@ -12780,9 +13209,9 @@
       }
     },
     "node_modules/postcss-normalize-url": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.4.tgz",
-      "integrity": "sha512-cNj3RzK2pgQQyNp7dzq0dqpUpQ/wYtdDZM3DepPmFjCmYIfceuD9VIAcOdvrNetjIU65g1B4uwdP/Krf6AFdXg==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.5.tgz",
+      "integrity": "sha512-Ws3tX+PcekYlXh+ycAt0wyzqGthkvVtZ9SZLutMVvHARxcpu4o7vvXcNoiNKyjKuWecnjS6HDI3fjBuDr5MQxQ==",
       "dev": true,
       "dependencies": {
         "normalize-url": "^6.0.1",
@@ -12796,9 +13225,9 @@
       }
     },
     "node_modules/postcss-normalize-whitespace": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.2.tgz",
-      "integrity": "sha512-CXBx+9fVlzSgbk0IXA/dcZn9lXixnQRndnsPC5ht3HxlQ1bVh77KQDL1GffJx1LTzzfae8ftMulsjYmO2yegxA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.4.tgz",
+      "integrity": "sha512-wsnuHolYZjMwWZJoTC9jeI2AcjA67v4UuidDrPN9RnX8KIZfE+r2Nd6XZRwHVwUiHmRvKQtxiqo64K+h8/imaw==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12810,13 +13239,32 @@
         "postcss": "^8.2.15"
       }
     },
+    "node_modules/postcss-opacity-percentage": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz",
+      "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "kofi",
+          "url": "https://ko-fi.com/mrcgrtz"
+        },
+        {
+          "type": "liberapay",
+          "url": "https://liberapay.com/mrcgrtz"
+        }
+      ],
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      }
+    },
     "node_modules/postcss-ordered-values": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.3.tgz",
-      "integrity": "sha512-T9pDS+P9bWeFvqivXd5ACzQmrCmHjv3ZP+djn8E1UZY7iK79pFSm7i3WbKw2VSmFmdbMm8sQ12OPcNpzBo3Z2w==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.5.tgz",
+      "integrity": "sha512-mfY7lXpq+8bDEHfP+muqibDPhZ5eP9zgBEF9XRvoQgXcQe2Db3G1wcvjbnfjXG6wYsl+0UIjikqq4ym1V2jGMQ==",
       "dev": true,
       "dependencies": {
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-value-parser": "^4.2.0"
       },
       "engines": {
@@ -12827,15 +13275,15 @@
       }
     },
     "node_modules/postcss-overflow-shorthand": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.2.tgz",
-      "integrity": "sha512-odBMVt6PTX7jOE9UNvmnLrFzA9pXS44Jd5shFGGtSHY80QCuJF+14McSy0iavZggRZ9Oj//C9vOKQmexvyEJMg==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz",
+      "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==",
       "dev": true,
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-page-break": {
@@ -12848,9 +13296,9 @@
       }
     },
     "node_modules/postcss-place": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.3.tgz",
-      "integrity": "sha512-tDQ3m+GYoOar+KoQgj+pwPAvGHAp/Sby6vrFiyrELrMKQJ4AejL0NcS0mm296OKKYA2SRg9ism/hlT/OLhBrdQ==",
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.4.tgz",
+      "integrity": "sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -12859,46 +13307,55 @@
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-preset-env": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.2.3.tgz",
-      "integrity": "sha512-Ok0DhLfwrcNGrBn8sNdy1uZqWRk/9FId0GiQ39W4ILop5GHtjJs8bu1MY9isPwHInpVEPWjb4CEcEaSbBLpfwA==",
-      "dev": true,
-      "dependencies": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.4.1.tgz",
+      "integrity": "sha512-UvBVvPJ2vb4odAtckSbryndyBz+Me1q8wawqq0qznpDXy188I+8W5Sa929sCPqw2/NSYnqpHJbo41BKso3+I9A==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-color-function": "^1.0.2",
+        "@csstools/postcss-font-format-keywords": "^1.0.0",
+        "@csstools/postcss-hwb-function": "^1.0.0",
+        "@csstools/postcss-ic-unit": "^1.0.0",
+        "@csstools/postcss-is-pseudo-class": "^2.0.0",
+        "@csstools/postcss-normalize-display-values": "^1.0.0",
+        "@csstools/postcss-oklab-function": "^1.0.1",
+        "@csstools/postcss-progressive-custom-properties": "^1.2.0",
         "autoprefixer": "^10.4.2",
         "browserslist": "^4.19.1",
-        "caniuse-lite": "^1.0.30001299",
-        "css-blank-pseudo": "^3.0.2",
-        "css-has-pseudo": "^3.0.3",
-        "css-prefers-color-scheme": "^6.0.2",
-        "cssdb": "^5.0.0",
+        "css-blank-pseudo": "^3.0.3",
+        "css-has-pseudo": "^3.0.4",
+        "css-prefers-color-scheme": "^6.0.3",
+        "cssdb": "^6.3.1",
         "postcss-attribute-case-insensitive": "^5.0.0",
-        "postcss-color-functional-notation": "^4.2.1",
-        "postcss-color-hex-alpha": "^8.0.2",
+        "postcss-clamp": "^4.0.0",
+        "postcss-color-functional-notation": "^4.2.2",
+        "postcss-color-hex-alpha": "^8.0.3",
         "postcss-color-rebeccapurple": "^7.0.2",
         "postcss-custom-media": "^8.0.0",
-        "postcss-custom-properties": "^12.1.2",
+        "postcss-custom-properties": "^12.1.4",
         "postcss-custom-selectors": "^6.0.0",
-        "postcss-dir-pseudo-class": "^6.0.3",
-        "postcss-double-position-gradients": "^3.0.4",
-        "postcss-env-function": "^4.0.4",
-        "postcss-focus-visible": "^6.0.3",
-        "postcss-focus-within": "^5.0.3",
+        "postcss-dir-pseudo-class": "^6.0.4",
+        "postcss-double-position-gradients": "^3.1.0",
+        "postcss-env-function": "^4.0.5",
+        "postcss-focus-visible": "^6.0.4",
+        "postcss-focus-within": "^5.0.4",
         "postcss-font-variant": "^5.0.0",
-        "postcss-gap-properties": "^3.0.2",
-        "postcss-image-set-function": "^4.0.4",
+        "postcss-gap-properties": "^3.0.3",
+        "postcss-image-set-function": "^4.0.6",
         "postcss-initial": "^4.0.1",
-        "postcss-lab-function": "^4.0.3",
-        "postcss-logical": "^5.0.3",
+        "postcss-lab-function": "^4.1.1",
+        "postcss-logical": "^5.0.4",
         "postcss-media-minmax": "^5.0.0",
         "postcss-nesting": "^10.1.2",
-        "postcss-overflow-shorthand": "^3.0.2",
+        "postcss-opacity-percentage": "^1.1.2",
+        "postcss-overflow-shorthand": "^3.0.3",
         "postcss-page-break": "^3.0.4",
-        "postcss-place": "^7.0.3",
-        "postcss-pseudo-class-any-link": "^7.0.2",
+        "postcss-place": "^7.0.4",
+        "postcss-pseudo-class-any-link": "^7.1.1",
         "postcss-replace-overflow-wrap": "^4.0.0",
         "postcss-selector-not": "^5.0.0"
       },
@@ -12910,24 +13367,24 @@
       }
     },
     "node_modules/postcss-pseudo-class-any-link": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.0.2.tgz",
-      "integrity": "sha512-CG35J1COUH7OOBgpw5O+0koOLUd5N4vUGKUqSAuIe4GiuLHWU96Pqp+UPC8QITTd12zYAFx76pV7qWT/0Aj/TA==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.1.tgz",
+      "integrity": "sha512-JRoLFvPEX/1YTPxRxp1JO4WxBVXJYrSY7NHeak5LImwJ+VobFMwYDQHvfTXEpcn+7fYIeGkC29zYFhFWIZD8fg==",
       "dev": true,
       "dependencies": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       },
       "engines": {
         "node": "^12 || ^14 || >=16"
       },
       "peerDependencies": {
-        "postcss": "^8.3"
+        "postcss": "^8.4"
       }
     },
     "node_modules/postcss-reduce-initial": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz",
-      "integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.3.tgz",
+      "integrity": "sha512-c88TkSnQ/Dnwgb4OZbKPOBbCaauwEjbECP5uAuFPOzQ+XdjNjRH7SG0dteXrpp1LlIFEKK76iUGgmw2V0xeieA==",
       "dev": true,
       "dependencies": {
         "browserslist": "^4.16.6",
@@ -12941,9 +13398,9 @@
       }
     },
     "node_modules/postcss-reduce-transforms": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.2.tgz",
-      "integrity": "sha512-25HeDeFsgiPSUx69jJXZn8I06tMxLQJJNF5h7i9gsUg8iP4KOOJ8EX8fj3seeoLt3SLU2YDD6UPnDYVGUO7DEA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.4.tgz",
+      "integrity": "sha512-VIJB9SFSaL8B/B7AXb7KHL6/GNNbbCHslgdzS9UDfBZYIA2nx8NLY7iD/BXFSO/1sRUILzBTfHCoW5inP37C5g==",
       "dev": true,
       "dependencies": {
         "postcss-value-parser": "^4.2.0"
@@ -13017,9 +13474,9 @@
       }
     },
     "node_modules/postcss-selector-parser": {
-      "version": "6.0.8",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz",
-      "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==",
+      "version": "6.0.9",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz",
+      "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==",
       "dependencies": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
@@ -13029,12 +13486,12 @@
       }
     },
     "node_modules/postcss-svgo": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.3.tgz",
-      "integrity": "sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.4.tgz",
+      "integrity": "sha512-yDKHvULbnZtIrRqhZoA+rxreWpee28JSRH/gy9727u0UCgtpv1M/9WEWY3xySlFa0zQJcqf6oCBJPR5NwkmYpg==",
       "dev": true,
       "dependencies": {
-        "postcss-value-parser": "^4.1.0",
+        "postcss-value-parser": "^4.2.0",
         "svgo": "^2.7.0"
       },
       "engines": {
@@ -13045,12 +13502,11 @@
       }
     },
     "node_modules/postcss-unique-selectors": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz",
-      "integrity": "sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.4.tgz",
+      "integrity": "sha512-5ampwoSDJCxDPoANBIlMgoBcYUHnhaiuLYJR5pj1DLnYQvMRVyFuTA5C3Bvt+aHtiqWpJkD/lXT50Vo1D0ZsAQ==",
       "dev": true,
       "dependencies": {
-        "alphanum-sort": "^1.0.2",
         "postcss-selector-parser": "^6.0.5"
       },
       "engines": {
@@ -13370,8 +13826,9 @@
     },
     "node_modules/readdirp": {
       "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "picomatch": "^2.2.1"
       },
@@ -13541,11 +13998,11 @@
       }
     },
     "node_modules/resolve": {
-      "version": "1.21.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz",
-      "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==",
+      "version": "1.22.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
+      "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
       "dependencies": {
-        "is-core-module": "^2.8.0",
+        "is-core-module": "^2.8.1",
         "path-parse": "^1.0.7",
         "supports-preserve-symlinks-flag": "^1.0.0"
       },
@@ -13637,9 +14094,10 @@
       }
     },
     "node_modules/rfdc": {
-      "version": "1.3.0",
-      "dev": true,
-      "license": "MIT"
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
+      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
+      "dev": true
     },
     "node_modules/rgbcolor": {
       "version": "1.0.1",
@@ -13962,9 +14420,10 @@
       }
     },
     "node_modules/signal-exit": {
-      "version": "3.0.3",
-      "dev": true,
-      "license": "ISC"
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+      "dev": true
     },
     "node_modules/signale": {
       "version": "1.4.0",
@@ -14001,25 +14460,24 @@
       }
     },
     "node_modules/slice-ansi": {
-      "version": "4.0.0",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-styles": "^4.0.0",
         "astral-regex": "^2.0.0",
         "is-fullwidth-code-point": "^3.0.0"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+        "node": ">=8"
       }
     },
     "node_modules/slice-ansi/node_modules/ansi-styles": {
       "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "color-convert": "^2.0.1"
       },
@@ -14032,8 +14490,9 @@
     },
     "node_modules/slice-ansi/node_modules/color-convert": {
       "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "color-name": "~1.1.4"
       },
@@ -14043,13 +14502,15 @@
     },
     "node_modules/slice-ansi/node_modules/color-name": {
       "version": "1.1.4",
-      "dev": true,
-      "license": "MIT"
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
     },
     "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
@@ -14062,8 +14523,9 @@
       }
     },
     "node_modules/source-map-js": {
-      "version": "1.0.1",
-      "license": "BSD-3-Clause",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
       "engines": {
         "node": ">=0.10.0"
       }
@@ -14085,12 +14547,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/source-map-url": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
-      "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
-      "dev": true
-    },
     "node_modules/sourcemap-codec": {
       "version": "1.4.8",
       "license": "MIT"
@@ -14573,12 +15029,12 @@
       "license": "ISC"
     },
     "node_modules/stylehacks": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz",
-      "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.3.tgz",
+      "integrity": "sha512-ENcUdpf4yO0E1rubu8rkxI+JGQk4CgjchynZ4bDBJDfqdy+uhTRSWb8/F3Jtu+Bw5MW45Po3/aQGeIyyxgQtxg==",
       "dev": true,
       "dependencies": {
-        "browserslist": "^4.16.0",
+        "browserslist": "^4.16.6",
         "postcss-selector-parser": "^6.0.4"
       },
       "engines": {
@@ -14589,22 +15045,23 @@
       }
     },
     "node_modules/stylelint": {
-      "version": "14.2.0",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.2.0.tgz",
-      "integrity": "sha512-i0DrmDXFNpDsWiwx6SPRs4/pyw4kvZgqpDGvsTslQMY7hpUl6r33aQvNSn6cnTg2wtZ9rreFElI7XAKpOWi1vQ==",
+      "version": "14.5.3",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.5.3.tgz",
+      "integrity": "sha512-omHETL+kGHR+fCXFK1SkZD/A+emCP9esggAdWEl8GPjTNeyRYj+H6uetRDcU+7E451zwWiUYGVAX+lApsAZgsQ==",
       "dev": true,
       "dependencies": {
         "balanced-match": "^2.0.0",
         "colord": "^2.9.2",
         "cosmiconfig": "^7.0.1",
+        "css-functions-list": "^3.0.1",
         "debug": "^4.3.3",
         "execall": "^2.0.0",
-        "fast-glob": "^3.2.7",
+        "fast-glob": "^3.2.11",
         "fastest-levenshtein": "^1.0.12",
         "file-entry-cache": "^6.0.1",
         "get-stdin": "^8.0.0",
         "global-modules": "^2.0.0",
-        "globby": "^11.0.4",
+        "globby": "^11.1.0",
         "globjoin": "^0.1.4",
         "html-tags": "^3.1.0",
         "ignore": "^5.2.0",
@@ -14618,21 +15075,22 @@
         "normalize-path": "^3.0.0",
         "normalize-selector": "^0.2.0",
         "picocolors": "^1.0.0",
-        "postcss": "^8.3.11",
+        "postcss": "^8.4.6",
         "postcss-media-query-parser": "^0.2.3",
         "postcss-resolve-nested-selector": "^0.1.1",
         "postcss-safe-parser": "^6.0.0",
-        "postcss-selector-parser": "^6.0.7",
-        "postcss-value-parser": "^4.1.0",
+        "postcss-selector-parser": "^6.0.9",
+        "postcss-value-parser": "^4.2.0",
         "resolve-from": "^5.0.0",
         "specificity": "^0.4.1",
         "string-width": "^4.2.3",
         "strip-ansi": "^6.0.1",
         "style-search": "^0.1.0",
+        "supports-hyperlinks": "^2.2.0",
         "svg-tags": "^1.0.0",
-        "table": "^6.7.5",
+        "table": "^6.8.0",
         "v8-compile-cache": "^2.3.0",
-        "write-file-atomic": "^3.0.3"
+        "write-file-atomic": "^4.0.1"
       },
       "bin": {
         "stylelint": "bin/stylelint.js"
@@ -14646,24 +15104,24 @@
       }
     },
     "node_modules/stylelint-config-recommended": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz",
-      "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz",
+      "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==",
       "dev": true,
       "peerDependencies": {
-        "stylelint": "^14.0.0"
+        "stylelint": "^14.4.0"
       }
     },
     "node_modules/stylelint-config-standard": {
-      "version": "24.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-24.0.0.tgz",
-      "integrity": "sha512-+RtU7fbNT+VlNbdXJvnjc3USNPZRiRVp/d2DxOF/vBDDTi0kH5RX2Ny6errdtZJH3boO+bmqIYEllEmok4jiuw==",
+      "version": "25.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz",
+      "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==",
       "dev": true,
       "dependencies": {
-        "stylelint-config-recommended": "^6.0.0"
+        "stylelint-config-recommended": "^7.0.0"
       },
       "peerDependencies": {
-        "stylelint": "^14.0.0"
+        "stylelint": "^14.4.0"
       }
     },
     "node_modules/stylelint/node_modules/ansi-regex": {
@@ -14948,9 +15406,10 @@
       "license": "MIT"
     },
     "node_modules/table": {
-      "version": "6.7.5",
+      "version": "6.8.0",
+      "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz",
+      "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==",
       "dev": true,
-      "license": "BSD-3-Clause",
       "dependencies": {
         "ajv": "^8.0.1",
         "lodash.truncate": "^4.4.2",
@@ -14963,9 +15422,10 @@
       }
     },
     "node_modules/table/node_modules/ajv": {
-      "version": "8.8.2",
+      "version": "8.10.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz",
+      "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "fast-deep-equal": "^3.1.1",
         "json-schema-traverse": "^1.0.0",
@@ -14979,29 +15439,83 @@
     },
     "node_modules/table/node_modules/ansi-regex": {
       "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
+    "node_modules/table/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/table/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/table/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
     "node_modules/table/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
-      "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/table/node_modules/json-schema-traverse": {
       "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/table/node_modules/slice-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
       "dev": true,
-      "license": "MIT"
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+      }
     },
     "node_modules/table/node_modules/string-width": {
       "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
@@ -15013,8 +15527,9 @@
     },
     "node_modules/table/node_modules/strip-ansi": {
       "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1"
       },
@@ -15023,31 +15538,32 @@
       }
     },
     "node_modules/tailwindcss": {
-      "version": "3.0.15",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.15.tgz",
-      "integrity": "sha512-bT2iy7FtjwgsXik4ZoJnHXR+SRCiGR1W95fVqpLZebr64m4ahwUwRbIAc5w5+2fzr1YF4Ct2eI7dojMRRl8sVQ==",
+      "version": "3.0.23",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.23.tgz",
+      "integrity": "sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA==",
       "dev": true,
       "dependencies": {
         "arg": "^5.0.1",
         "chalk": "^4.1.2",
-        "chokidar": "^3.5.2",
+        "chokidar": "^3.5.3",
         "color-name": "^1.1.4",
         "cosmiconfig": "^7.0.1",
         "detective": "^5.2.0",
         "didyoumean": "^1.2.2",
         "dlv": "^1.1.3",
-        "fast-glob": "^3.2.7",
+        "fast-glob": "^3.2.11",
         "glob-parent": "^6.0.2",
         "is-glob": "^4.0.3",
         "normalize-path": "^3.0.0",
         "object-hash": "^2.2.0",
+        "postcss": "^8.4.6",
         "postcss-js": "^4.0.0",
         "postcss-load-config": "^3.1.0",
         "postcss-nested": "5.0.6",
-        "postcss-selector-parser": "^6.0.8",
+        "postcss-selector-parser": "^6.0.9",
         "postcss-value-parser": "^4.2.0",
         "quick-lru": "^5.1.1",
-        "resolve": "^1.21.0"
+        "resolve": "^1.22.0"
       },
       "bin": {
         "tailwind": "lib/cli.js",
@@ -15368,18 +15884,11 @@
       "version": "0.0.6",
       "license": "MIT"
     },
-    "node_modules/typedarray-to-buffer": {
-      "version": "3.1.5",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
     "node_modules/typescript": {
-      "version": "4.5.4",
+      "version": "4.5.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
+      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
       "dev": true,
-      "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -15536,14 +16045,14 @@
       }
     },
     "node_modules/vite": {
-      "version": "2.7.13",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-2.7.13.tgz",
-      "integrity": "sha512-Mq8et7f3aK0SgSxjDNfOAimZGW9XryfHRa/uV0jseQSilg+KhYDSoNb9h1rknOy6SuMkvNDLKCYAYYUMCE+IgQ==",
+      "version": "2.8.4",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-2.8.4.tgz",
+      "integrity": "sha512-GwtOkkaT2LDI82uWZKcrpRQxP5tymLnC7hVHHqNkhFNknYr0hJUlDLfhVRgngJvAy3RwypkDCWtTKn1BjO96Dw==",
       "dev": true,
       "dependencies": {
-        "esbuild": "^0.13.12",
-        "postcss": "^8.4.5",
-        "resolve": "^1.20.0",
+        "esbuild": "^0.14.14",
+        "postcss": "^8.4.6",
+        "resolve": "^1.22.0",
         "rollup": "^2.59.0"
       },
       "bin": {
@@ -15616,9 +16125,9 @@
       }
     },
     "node_modules/wavesurfer.js": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-5.2.0.tgz",
-      "integrity": "sha512-SkPlTXfvKy+ZnEA7f7g7jn6iQg5/8mAvWpVV5vRbIS/FF9TB2ak9J7VayQfzfshOLW/CqccTiN6DDR/fZA902g=="
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-6.0.2.tgz",
+      "integrity": "sha512-dd1ZwsgobELehtrzdKiQ9Im+m0F1Dbe39bJeo7ZQjkW8KTwdTNVg3ymURwif3pYsHo8ikKWjD5QDvIu/O0mRSA=="
     },
     "node_modules/webidl-conversions": {
       "version": "6.1.0",
@@ -15708,28 +16217,28 @@
       "license": "MIT"
     },
     "node_modules/workbox-background-sync": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.4.2.tgz",
-      "integrity": "sha512-P7c8uG5X2k+DMICH9xeSA9eUlCOjHHYoB42Rq+RtUpuwBxUOflAXR1zdsMWj81LopE4gjKXlTw7BFd1BDAHo7g==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.0.tgz",
+      "integrity": "sha512-rrekt/gt6qOIZsisj6QZfmAFPAnocq1Z603zAjt+qHmeXY8DLPOklVtvrXSaHoHH3qIjUq3SQY5s2x240iTIKw==",
       "dev": true,
       "dependencies": {
         "idb": "^6.1.4",
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-broadcast-update": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.4.2.tgz",
-      "integrity": "sha512-qnBwQyE0+PWFFc/n4ISXINE49m44gbEreJUYt2ldGH3+CNrLmJ1egJOOyUqqu9R4Eb7QrXcmB34ClXG7S37LbA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.0.tgz",
+      "integrity": "sha512-JC97c7tYqoGWcCfbKO9KHG6lkU+WhXCnDB2j1oFWEiv53nUHy3yjPpzMmAGNLD9oV5lInO15n6V18HfwgkhISw==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-build": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.4.2.tgz",
-      "integrity": "sha512-WMdYLhDIsuzViOTXDH+tJ1GijkFp5khSYolnxR/11zmfhNDtuo7jof72xPGFy+KRpsz6tug39RhivCj77qqO0w==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.0.tgz",
+      "integrity": "sha512-da0/1b6//P9+ts7ofcIKcMVPyN6suJvjJASXokF7DsqvUmgRBPcCVV4KCy8QWjgfcz7mzuTpkSbdVHcPFJ/p0A==",
       "dev": true,
       "dependencies": {
         "@apideck/better-ajv-errors": "^0.3.1",
@@ -15750,26 +16259,25 @@
         "rollup": "^2.43.1",
         "rollup-plugin-terser": "^7.0.0",
         "source-map": "^0.8.0-beta.0",
-        "source-map-url": "^0.4.0",
         "stringify-object": "^3.3.0",
         "strip-comments": "^2.0.1",
         "tempy": "^0.6.0",
         "upath": "^1.2.0",
-        "workbox-background-sync": "6.4.2",
-        "workbox-broadcast-update": "6.4.2",
-        "workbox-cacheable-response": "6.4.2",
-        "workbox-core": "6.4.2",
-        "workbox-expiration": "6.4.2",
-        "workbox-google-analytics": "6.4.2",
-        "workbox-navigation-preload": "6.4.2",
-        "workbox-precaching": "6.4.2",
-        "workbox-range-requests": "6.4.2",
-        "workbox-recipes": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2",
-        "workbox-streams": "6.4.2",
-        "workbox-sw": "6.4.2",
-        "workbox-window": "6.4.2"
+        "workbox-background-sync": "6.5.0",
+        "workbox-broadcast-update": "6.5.0",
+        "workbox-cacheable-response": "6.5.0",
+        "workbox-core": "6.5.0",
+        "workbox-expiration": "6.5.0",
+        "workbox-google-analytics": "6.5.0",
+        "workbox-navigation-preload": "6.5.0",
+        "workbox-precaching": "6.5.0",
+        "workbox-range-requests": "6.5.0",
+        "workbox-recipes": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0",
+        "workbox-streams": "6.5.0",
+        "workbox-sw": "6.5.0",
+        "workbox-window": "6.5.0"
       },
       "engines": {
         "node": ">=10.0.0"
@@ -15919,127 +16427,127 @@
       }
     },
     "node_modules/workbox-cacheable-response": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.4.2.tgz",
-      "integrity": "sha512-9FE1W/cKffk1AJzImxgEN0ceWpyz1tqNjZVtA3/LAvYL3AC5SbIkhc7ZCO82WmO9IjTfu8Vut2X/C7ViMSF7TA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.0.tgz",
+      "integrity": "sha512-sqAtWAiBwWvI8HG/2Do7BeKPhHuUczt22ORkAjkH9DfTq9LuWRFd6T4HAMqX5G8F1gM9XA2UPlxRrEeSpFIz/A==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-core": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.4.2.tgz",
-      "integrity": "sha512-1U6cdEYPcajRXiboSlpJx6U7TvhIKbxRRerfepAJu2hniKwJ3DHILjpU/zx3yvzSBCWcNJDoFalf7Vgd7ey/rw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.0.tgz",
+      "integrity": "sha512-5SPwNipUzYBhrneLVT02JFA0fw3LG82jFAN/G2NzxkIW10t4MVZuML2nU94bbkgjq25u0fkY8+4JXzMfHgxEWQ==",
       "dev": true
     },
     "node_modules/workbox-expiration": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.4.2.tgz",
-      "integrity": "sha512-0hbpBj0tDnW+DZOUmwZqntB/8xrXOgO34i7s00Si/VlFJvvpRKg1leXdHHU8ykoSBd6+F2KDcMP3swoCi5guLw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.0.tgz",
+      "integrity": "sha512-y3WRkKRy/gMuZZNkrLFahjY0QZtLoq+QfhTbVAsOGHVg1CCtnNbeFAnEidQs7UisI2BK76VqQPvM7hEOFyZ92A==",
       "dev": true,
       "dependencies": {
         "idb": "^6.1.4",
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-google-analytics": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.4.2.tgz",
-      "integrity": "sha512-u+gxs3jXovPb1oul4CTBOb+T9fS1oZG+ZE6AzS7l40vnyfJV79DaLBvlpEZfXGv3CjMdV1sT/ltdOrKzo7HcGw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.0.tgz",
+      "integrity": "sha512-CHHh55wMNCc/BV1URrzEM2Zjgf6g2CV6QpAAc1pBRqaLY5755PeQZbp3o8KbJEM7YsC9mIBeQVsOkSKkGS30bg==",
       "dev": true,
       "dependencies": {
-        "workbox-background-sync": "6.4.2",
-        "workbox-core": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2"
+        "workbox-background-sync": "6.5.0",
+        "workbox-core": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0"
       }
     },
     "node_modules/workbox-navigation-preload": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.4.2.tgz",
-      "integrity": "sha512-viyejlCtlKsbJCBHwhSBbWc57MwPXvUrc8P7d+87AxBGPU+JuWkT6nvBANgVgFz6FUhCvRC8aYt+B1helo166g==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.0.tgz",
+      "integrity": "sha512-ktrRQzXJ0zFy0puOtCa49wE3BSBGUB8KRMot3tEieikCkSO0wMLmiCb9GwTVvNMJLl0THRlsdFoI93si04nTxA==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-precaching": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.4.2.tgz",
-      "integrity": "sha512-CZ6uwFN/2wb4noHVlALL7UqPFbLfez/9S2GAzGAb0Sk876ul9ukRKPJJ6gtsxfE2HSTwqwuyNVa6xWyeyJ1XSA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.0.tgz",
+      "integrity": "sha512-IVLzgHx38T6LphJyEOltd7XAvpDi73p85uCT2ZtT1HHg9FAYC49a+5iHUVOnqye73fLW20eiAMFcnehGxz9RWg==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2"
+        "workbox-core": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0"
       }
     },
     "node_modules/workbox-range-requests": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.4.2.tgz",
-      "integrity": "sha512-SowF3z69hr3Po/w7+xarWfzxJX/3Fo0uSG72Zg4g5FWWnHpq2zPvgbWerBZIa81zpJVUdYpMa3akJJsv+LaO1Q==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.0.tgz",
+      "integrity": "sha512-+qTELdGZE5rOjuv+ifFrfRDN8Uvzpbm5Fal7qSUqB1V1DLCMxPwHCj6mWwQBRKBpW7G09kAwewH7zA3Asjkf/Q==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-recipes": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.4.2.tgz",
-      "integrity": "sha512-/oVxlZFpAjFVbY+3PoGEXe8qyvtmqMrTdWhbOfbwokNFtUZ/JCtanDKgwDv9x3AebqGAoJRvQNSru0F4nG+gWA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.0.tgz",
+      "integrity": "sha512-7hWZAIcXmvr31NwYSWaQIrnThCH/Dx9+eYv/YdkpUeWIXRiHRkYvP1FdiHItbLSjL4Y6K7cy2Y9y5lGCkgaE4w==",
       "dev": true,
       "dependencies": {
-        "workbox-cacheable-response": "6.4.2",
-        "workbox-core": "6.4.2",
-        "workbox-expiration": "6.4.2",
-        "workbox-precaching": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2"
+        "workbox-cacheable-response": "6.5.0",
+        "workbox-core": "6.5.0",
+        "workbox-expiration": "6.5.0",
+        "workbox-precaching": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0"
       }
     },
     "node_modules/workbox-routing": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.4.2.tgz",
-      "integrity": "sha512-0ss/n9PAcHjTy4Ad7l2puuod4WtsnRYu9BrmHcu6Dk4PgWeJo1t5VnGufPxNtcuyPGQ3OdnMdlmhMJ57sSrrSw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.0.tgz",
+      "integrity": "sha512-w1A9OVa/yYStu9ds0Dj+TC6zOAoskKlczf+wZI5mrM9nFCt/KOMQiFp1/41DMFPrrN/8KlZTS3Cel/Ttutw93Q==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-strategies": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.4.2.tgz",
-      "integrity": "sha512-YXh9E9dZGEO1EiPC3jPe2CbztO5WT8Ruj8wiYZM56XqEJp5YlGTtqRjghV+JovWOqkWdR+amJpV31KPWQUvn1Q==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.0.tgz",
+      "integrity": "sha512-Ngnwo+tfGw4uKSlTz3h1fYKb/lCV7SDI/dtTb8VaJzRl0N9XssloDGYERBmF6BN/DV/x3bnRsshfobnKI/3z0g==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/workbox-streams": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.4.2.tgz",
-      "integrity": "sha512-ROEGlZHGVEgpa5bOZefiJEVsi5PsFjJG9Xd+wnDbApsCO9xq9rYFopF+IRq9tChyYzhBnyk2hJxbQVWphz3sog==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.0.tgz",
+      "integrity": "sha512-ZbeaZINkju4x45P9DFyRbOYInE+dyNAJIelflz4f9AOAdm+zZUJCooU4MdfsedVhHiTIA6pCD/3jCmW1XbvlbA==",
       "dev": true,
       "dependencies": {
-        "workbox-core": "6.4.2",
-        "workbox-routing": "6.4.2"
+        "workbox-core": "6.5.0",
+        "workbox-routing": "6.5.0"
       }
     },
     "node_modules/workbox-sw": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.4.2.tgz",
-      "integrity": "sha512-A2qdu9TLktfIM5NE/8+yYwfWu+JgDaCkbo5ikrky2c7r9v2X6DcJ+zSLphNHHLwM/0eVk5XVf1mC5HGhYpMhhg==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.0.tgz",
+      "integrity": "sha512-uPGJ9Yost4yabnCko/IuhouquoQKrWOEqLq7L/xVYtltWe4+J8Hw8iPCVtxvXQ26hffd7MaFWUAN83j2ZWbxRg==",
       "dev": true
     },
     "node_modules/workbox-window": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.4.2.tgz",
-      "integrity": "sha512-KVyRKmrJg7iB+uym/B/CnEUEFG9CvnTU1Bq5xpXHbtgD9l+ShDekSl1wYpqw/O0JfeeQVOFb8CiNfvnwWwqnWQ==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.0.tgz",
+      "integrity": "sha512-DOrhiTnWup/CsNstO2uvfdKM4kdStgHd31xGGvBcoCE3Are3DRcy5s3zz3PedcAR1AKskQj3BXz0UhzQiOq8nA==",
       "dev": true,
       "dependencies": {
         "@types/trusted-types": "^2.0.2",
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "node_modules/wrap-ansi": {
@@ -16134,14 +16642,16 @@
       "license": "ISC"
     },
     "node_modules/write-file-atomic": {
-      "version": "3.0.3",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz",
+      "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==",
       "dev": true,
-      "license": "ISC",
       "dependencies": {
         "imurmurhash": "^0.1.4",
-        "is-typedarray": "^1.0.0",
-        "signal-exit": "^3.0.2",
-        "typedarray-to-buffer": "^3.1.5"
+        "signal-exit": "^3.0.7"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || >=16"
       }
     },
     "node_modules/ws": {
@@ -16190,9 +16700,9 @@
       "license": "MIT"
     },
     "node_modules/xml-formatter": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.0.tgz",
-      "integrity": "sha512-+bQeoiE5W3CJdDCHTlveYSWFfQWnYB3uHGeRJ6LlEsL5kT++mWy9iN1cMeEDfBbgOnXO2DNUbmQ6elkR/mCcjg==",
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz",
+      "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==",
       "dependencies": {
         "xml-parser-xo": "^3.2.0"
       },
@@ -16339,7 +16849,9 @@
   },
   "dependencies": {
     "@amcharts/amcharts4": {
-      "version": "4.10.23",
+      "version": "4.10.24",
+      "resolved": "https://registry.npmjs.org/@amcharts/amcharts4/-/amcharts4-4.10.24.tgz",
+      "integrity": "sha512-Yq7Ynn9XAENDHPuGyZpDiK8xBa223/8yxpt9R2FJ0by4pHruxu+SCJ7L8S/0CDWy/ABMVVObVsnYwNBm8GFJPQ==",
       "requires": {
         "@babel/runtime": "^7.6.3",
         "core-js": "^3.0.0",
@@ -17506,14 +18018,14 @@
       }
     },
     "@codemirror/commands": {
-      "version": "0.19.7",
-      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.19.7.tgz",
-      "integrity": "sha512-Mwh064xnuDbFw+9KJAi2Hmg8Va+YqQzgn6e/94/bSJavY3uuIBPr4vJp6pFEa1qPp40qs5/XJ01ty/0G3uLewA==",
+      "version": "0.19.8",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.19.8.tgz",
+      "integrity": "sha512-65LIMSGUGGpY3oH6mzV46YWRrgao6NmfJ+AuC7jNz3K5NPnH6GCV1H5I6SwOFyVbkiygGyd0EFwrWqywTBD1aw==",
       "requires": {
         "@codemirror/language": "^0.19.0",
         "@codemirror/matchbrackets": "^0.19.0",
         "@codemirror/state": "^0.19.2",
-        "@codemirror/text": "^0.19.0",
+        "@codemirror/text": "^0.19.6",
         "@codemirror/view": "^0.19.22",
         "@lezer/common": "^0.15.0"
       }
@@ -17637,13 +18149,17 @@
       }
     },
     "@codemirror/state": {
-      "version": "0.19.6",
+      "version": "0.19.9",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz",
+      "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==",
       "requires": {
         "@codemirror/text": "^0.19.0"
       }
     },
     "@codemirror/text": {
-      "version": "0.19.5"
+      "version": "0.19.6",
+      "resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz",
+      "integrity": "sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA=="
     },
     "@codemirror/tooltip": {
       "version": "0.19.10",
@@ -17653,9 +18169,9 @@
       }
     },
     "@codemirror/view": {
-      "version": "0.19.39",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.39.tgz",
-      "integrity": "sha512-ol4smHAwhWkW8p1diPZiZkLZVmKybKhQigwyrgdF7k1UFNY+/KDH4w2xic8JQXxX+v0ppMsoNf11C+afKJze5g==",
+      "version": "0.19.45",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.45.tgz",
+      "integrity": "sha512-wR19UBYvJMeV9axa5Xo6ATbAP1jl30BPFZ5buu3cJjYXwlRhJDjzw2wUbxk1zsR1LtAe5jrRNeWEtGA+IPacxw==",
       "requires": {
         "@codemirror/rangeset": "^0.19.5",
         "@codemirror/state": "^0.19.3",
@@ -17665,16 +18181,16 @@
       }
     },
     "@commitlint/cli": {
-      "version": "16.0.2",
-      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.0.2.tgz",
-      "integrity": "sha512-Jt7iaBjoLGC5Nq4dHPTvTYnqPGkElFPBtTXTvBpTgatZApczyjI2plE0oG4GYWPp1suHIS/VdVDOMpPZjGVusg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-16.2.1.tgz",
+      "integrity": "sha512-zfKf+B9osuiDbxGMJ7bWFv7XFCW8wlQYPtCffNp7Ukdb7mdrep5R9e03vPUZysnwp8NX6hg05kPEvnD/wRIGWw==",
       "dev": true,
       "requires": {
-        "@commitlint/format": "^16.0.0",
-        "@commitlint/lint": "^16.0.0",
-        "@commitlint/load": "^16.0.0",
-        "@commitlint/read": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/format": "^16.2.1",
+        "@commitlint/lint": "^16.2.1",
+        "@commitlint/load": "^16.2.1",
+        "@commitlint/read": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19",
         "resolve-from": "5.0.0",
         "resolve-global": "1.0.0",
@@ -17725,57 +18241,57 @@
       }
     },
     "@commitlint/config-conventional": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.0.0.tgz",
-      "integrity": "sha512-mN7J8KlKFn0kROd+q9PB01sfDx/8K/R25yITspL1No8PB4oj9M1p77xWjP80hPydqZG9OvQq+anXK3ZWeR7s3g==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-16.2.1.tgz",
+      "integrity": "sha512-cP9gArx7gnaj4IqmtCIcHdRjTYdRUi6lmGE+lOzGGjGe45qGOS8nyQQNvkNy2Ey2VqoSWuXXkD8zCUh6EHf1Ww==",
       "dev": true,
       "requires": {
         "conventional-changelog-conventionalcommits": "^4.3.1"
       }
     },
     "@commitlint/config-validator": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.0.0.tgz",
-      "integrity": "sha512-i80DGlo1FeC5jZpuoNV9NIjQN/m2dDV3jYGWg+1Wr+KldptkUHXj+6GY1Akll66lJ3D8s6aUGi3comPLHPtWHg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-16.2.1.tgz",
+      "integrity": "sha512-hogSe0WGg7CKmp4IfNbdNES3Rq3UEI4XRPB8JL4EPgo/ORq5nrGTVzxJh78omibNuB8Ho4501Czb1Er1MoDWpw==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "ajv": "^6.12.6"
       }
     },
     "@commitlint/ensure": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.0.0.tgz",
-      "integrity": "sha512-WdMySU8DCTaq3JPf0tZFCKIUhqxaL54mjduNhu8v4D2AMUVIIQKYMGyvXn94k8begeW6iJkTf9cXBArayskE7Q==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-16.2.1.tgz",
+      "integrity": "sha512-/h+lBTgf1r5fhbDNHOViLuej38i3rZqTQnBTk+xEg+ehOwQDXUuissQ5GsYXXqI5uGy+261ew++sT4EA3uBJ+A==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "lodash": "^4.17.19"
       }
     },
     "@commitlint/execute-rule": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.0.0.tgz",
-      "integrity": "sha512-8edcCibmBb386x5JTHSPHINwA5L0xPkHQFY8TAuDEt5QyRZY/o5DF8OPHSa5Hx2xJvGaxxuIz4UtAT6IiRDYkw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-16.2.1.tgz",
+      "integrity": "sha512-oSls82fmUTLM6cl5V3epdVo4gHhbmBFvCvQGHBRdQ50H/690Uq1Dyd7hXMuKITCIdcnr9umyDkr8r5C6HZDF3g==",
       "dev": true
     },
     "@commitlint/format": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.0.0.tgz",
-      "integrity": "sha512-9yp5NCquXL1jVMKL0ZkRwJf/UHdebvCcMvICuZV00NQGYSAL89O398nhqrqxlbjBhM5EZVq0VGcV5+7r3D4zAA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-16.2.1.tgz",
+      "integrity": "sha512-Yyio9bdHWmNDRlEJrxHKglamIk3d6hC0NkEUW6Ti6ipEh2g0BAhy8Od6t4vLhdZRa1I2n+gY13foy+tUgk0i1Q==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "chalk": "^4.0.0"
       }
     },
     "@commitlint/is-ignored": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.0.0.tgz",
-      "integrity": "sha512-gmAQcwIGC/R/Lp0CEb2b5bfGC7MT5rPe09N8kOGjO/NcdNmfFSZMquwrvNJsq9hnAP0skRdHIsqwlkENkN4Lag==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-16.2.1.tgz",
+      "integrity": "sha512-exl8HRzTIfb1YvDJp2b2HU5z1BT+9tmgxR2XF0YEzkMiCIuEKh+XLeocPr1VcvAKXv3Cmv5X/OfNRp+i+/HIhQ==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "semver": "7.3.5"
       },
       "dependencies": {
@@ -17791,27 +18307,28 @@
       }
     },
     "@commitlint/lint": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.0.0.tgz",
-      "integrity": "sha512-HNl15bRC0h+pLzbMzQC3tM0j1aESXsLYhElqKnXcf5mnCBkBkHzu6WwJW8rZbfxX+YwJmNljN62cPhmdBo8x0A==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-16.2.1.tgz",
+      "integrity": "sha512-fNINQ3X2ZqsCkNB3Z0Z8ElmhewqrS3gy2wgBTx97BkcjOWiyPAGwDJ752hwrsUnWAVBRztgw826n37xPzxsOgg==",
       "dev": true,
       "requires": {
-        "@commitlint/is-ignored": "^16.0.0",
-        "@commitlint/parse": "^16.0.0",
-        "@commitlint/rules": "^16.0.0",
-        "@commitlint/types": "^16.0.0"
+        "@commitlint/is-ignored": "^16.2.1",
+        "@commitlint/parse": "^16.2.1",
+        "@commitlint/rules": "^16.2.1",
+        "@commitlint/types": "^16.2.1"
       }
     },
     "@commitlint/load": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.0.0.tgz",
-      "integrity": "sha512-7WhrGCkP6K/XfjBBguLkkI2XUdiiIyMGlNsSoSqgRNiD352EiffhFEApMy1/XOU+viwBBm/On0n5p0NC7e9/4A==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-16.2.1.tgz",
+      "integrity": "sha512-oSpz0jTyVI/A1AIImxJINTLDOMB8YF7lWGm+Jg5wVWM0r7ucpuhyViVvpSRTgvL0z09oIxlctyFGWUQQpI42uw==",
       "dev": true,
       "requires": {
-        "@commitlint/config-validator": "^16.0.0",
-        "@commitlint/execute-rule": "^16.0.0",
-        "@commitlint/resolve-extends": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/execute-rule": "^16.2.1",
+        "@commitlint/resolve-extends": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
+        "@types/node": ">=12",
         "chalk": "^4.0.0",
         "cosmiconfig": "^7.0.0",
         "cosmiconfig-typescript-loader": "^1.0.0",
@@ -17821,38 +18338,38 @@
       }
     },
     "@commitlint/message": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.0.0.tgz",
-      "integrity": "sha512-CmK2074SH1Ws6kFMEKOKH/7hMekGVbOD6vb4alCOo2+33ZSLUIX8iNkDYyrw38Jwg6yWUhLjyQLUxREeV+QIUA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-16.2.1.tgz",
+      "integrity": "sha512-2eWX/47rftViYg7a3axYDdrgwKv32mxbycBJT6OQY/MJM7SUfYNYYvbMFOQFaA4xIVZt7t2Alyqslbl6blVwWw==",
       "dev": true
     },
     "@commitlint/parse": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.0.0.tgz",
-      "integrity": "sha512-F9EjFlMw4MYgBEqoRrWZZKQBzdiJzPBI0qFDFqwUvfQsMmXEREZ242T4R5bFwLINWaALFLHEIa/FXEPa6QxCag==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-16.2.1.tgz",
+      "integrity": "sha512-2NP2dDQNL378VZYioLrgGVZhWdnJO4nAxQl5LXwYb08nEcN+cgxHN1dJV8OLJ5uxlGJtDeR8UZZ1mnQ1gSAD/g==",
       "dev": true,
       "requires": {
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/types": "^16.2.1",
         "conventional-changelog-angular": "^5.0.11",
         "conventional-commits-parser": "^3.2.2"
       }
     },
     "@commitlint/read": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.0.0.tgz",
-      "integrity": "sha512-H4T2zsfmYQK9B+JtoQaCXWBHUhgIJyOzWZjSfuIV9Ce69/OgHoffNpLZPF2lX6yKuDrS1SQFhI/kUCjVc/e4ew==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-16.2.1.tgz",
+      "integrity": "sha512-tViXGuaxLTrw2r7PiYMQOFA2fueZxnnt0lkOWqKyxT+n2XdEMGYcI9ID5ndJKXnfPGPppD0w/IItKsIXlZ+alw==",
       "dev": true,
       "requires": {
-        "@commitlint/top-level": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/top-level": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "fs-extra": "^10.0.0",
         "git-raw-commits": "^2.0.0"
       },
       "dependencies": {
         "fs-extra": {
-          "version": "10.0.0",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-          "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+          "version": "10.0.1",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
+          "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
           "dev": true,
           "requires": {
             "graceful-fs": "^4.2.0",
@@ -17879,13 +18396,13 @@
       }
     },
     "@commitlint/resolve-extends": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.0.0.tgz",
-      "integrity": "sha512-Z/w9MAQUcxeawpCLtjmkVNXAXOmB2nhW+LYmHEZcx9O6UTauF/1+uuZ2/r0MtzTe1qw2JD+1QHVhEWYHVPlkdA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-16.2.1.tgz",
+      "integrity": "sha512-NbbCMPKTFf2J805kwfP9EO+vV+XvnaHRcBy6ud5dF35dxMsvdJqke54W3XazXF1ZAxC4a3LBy4i/GNVBAthsEg==",
       "dev": true,
       "requires": {
-        "@commitlint/config-validator": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/config-validator": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "import-fresh": "^3.0.0",
         "lodash": "^4.17.19",
         "resolve-from": "^5.0.0",
@@ -17893,28 +18410,28 @@
       }
     },
     "@commitlint/rules": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.0.0.tgz",
-      "integrity": "sha512-AOl0y2SBTdJ1bvIv8nwHvQKRT/jC1xb09C5VZwzHoT8sE8F54KDeEzPCwHQFgUcWdGLyS10kkOTAH2MyA8EIlg==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-16.2.1.tgz",
+      "integrity": "sha512-ZFezJXQaBBso+BOTre/+1dGCuCzlWVaeLiVRGypI53qVgPMzQqZhkCcrxBFeqB87qeyzr4A4EoG++IvITwwpIw==",
       "dev": true,
       "requires": {
-        "@commitlint/ensure": "^16.0.0",
-        "@commitlint/message": "^16.0.0",
-        "@commitlint/to-lines": "^16.0.0",
-        "@commitlint/types": "^16.0.0",
+        "@commitlint/ensure": "^16.2.1",
+        "@commitlint/message": "^16.2.1",
+        "@commitlint/to-lines": "^16.2.1",
+        "@commitlint/types": "^16.2.1",
         "execa": "^5.0.0"
       }
     },
     "@commitlint/to-lines": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.0.0.tgz",
-      "integrity": "sha512-iN/qU38TCKU7uKOg6RXLpD49wNiuI0TqMqybHbjefUeP/Jmzxa8ishryj0uLyVdrAl1ZjGeD1ukXGMTtvqz8iA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-16.2.1.tgz",
+      "integrity": "sha512-9/VjpYj5j1QeY3eiog1zQWY6axsdWAc0AonUUfyZ7B0MVcRI0R56YsHAfzF6uK/g/WwPZaoe4Lb1QCyDVnpVaQ==",
       "dev": true
     },
     "@commitlint/top-level": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.0.0.tgz",
-      "integrity": "sha512-/Jt6NLxyFkpjL5O0jxurZPCHURZAm7cQCqikgPCwqPAH0TLgwqdHjnYipl8J+AGnAMGDip4FNLoYrtgIpZGBYw==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-16.2.1.tgz",
+      "integrity": "sha512-lS6GSieHW9y6ePL73ied71Z9bOKyK+Ib9hTkRsB8oZFAyQZcyRwq2w6nIa6Fngir1QW51oKzzaXfJL94qwImyw==",
       "dev": true,
       "requires": {
         "find-up": "^5.0.0"
@@ -17960,9 +18477,9 @@
       }
     },
     "@commitlint/types": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.0.0.tgz",
-      "integrity": "sha512-+0FvYOAS39bJ4aKjnYn/7FD4DfWkmQ6G/06I4F0Gvu4KS5twirEg8mIcLhmeRDOOKn4Tp8PwpLwBiSA6npEMQA==",
+      "version": "16.2.1",
+      "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-16.2.1.tgz",
+      "integrity": "sha512-7/z7pA7BM0i8XvMSBynO7xsB3mVQPUZbVn6zMIlp/a091XJ3qAXRXc+HwLYhiIdzzS5fuxxNIHZMGHVD4HJxdA==",
       "dev": true,
       "requires": {
         "chalk": "^4.0.0"
@@ -17983,15 +18500,90 @@
         "@cspotcode/source-map-consumer": "0.8.0"
       }
     },
+    "@csstools/postcss-color-function": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.0.2.tgz",
+      "integrity": "sha512-uayvFqfa0hITPwVduxRYNL9YBD/anTqula0tu2llalaxblEd7QPuETSN3gB5PvTYxSfd0d8kS4Fypgo5JaUJ6A==",
+      "dev": true,
+      "requires": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "@csstools/postcss-font-format-keywords": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.0.tgz",
+      "integrity": "sha512-oO0cZt8do8FdVBX8INftvIA4lUrKUSCcWUf9IwH9IPWOgKT22oAZFXeHLoDK7nhB2SmkNycp5brxfNMRLIhd6Q==",
+      "dev": true,
+      "requires": {
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "@csstools/postcss-hwb-function": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.0.tgz",
+      "integrity": "sha512-VSTd7hGjmde4rTj1rR30sokY3ONJph1reCBTUXqeW1fKwETPy1x4t/XIeaaqbMbC5Xg4SM/lyXZ2S8NELT2TaA==",
+      "dev": true,
+      "requires": {
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "@csstools/postcss-ic-unit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.0.tgz",
+      "integrity": "sha512-i4yps1mBp2ijrx7E96RXrQXQQHm6F4ym1TOD0D69/sjDjZvQ22tqiEvaNw7pFZTUO5b9vWRHzbHzP9+UKuw+bA==",
+      "dev": true,
+      "requires": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "@csstools/postcss-is-pseudo-class": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.0.tgz",
+      "integrity": "sha512-WnfZlyuh/CW4oS530HBbrKq0G8BKl/bsNr5NMFoubBFzJfvFRGJhplCgIJYWUidLuL3WJ/zhMtDIyNFTqhx63Q==",
+      "dev": true,
+      "requires": {
+        "postcss-selector-parser": "^6.0.9"
+      }
+    },
+    "@csstools/postcss-normalize-display-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.0.tgz",
+      "integrity": "sha512-bX+nx5V8XTJEmGtpWTO6kywdS725t71YSLlxWt78XoHUbELWgoCXeOFymRJmL3SU1TLlKSIi7v52EWqe60vJTQ==",
+      "dev": true,
+      "requires": {
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "@csstools/postcss-oklab-function": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.0.1.tgz",
+      "integrity": "sha512-Bnly2FWWSTZX20hDJLYHpurhp1ot+ZGvojLOsrHa9frzOVruOv4oPYMZ6wQomi9KsbZZ+Af/CuRYaGReTyGtEg==",
+      "dev": true,
+      "requires": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "@csstools/postcss-progressive-custom-properties": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.2.0.tgz",
+      "integrity": "sha512-YLpFPK5OaLIRKZhUfnrZPT9s9cmtqltIOg7W6jPcxmiDpnZ4lk+odfufZttOAgcg6IHWvNLgcITSLpJxIQB/qQ==",
+      "dev": true,
+      "requires": {
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
     "@eslint/eslintrc": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz",
-      "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==",
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
+      "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
-        "espree": "^9.2.0",
+        "espree": "^9.3.1",
         "globals": "^13.9.0",
         "ignore": "^4.0.6",
         "import-fresh": "^3.2.1",
@@ -18015,16 +18607,16 @@
       }
     },
     "@floating-ui/core": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.3.1.tgz",
-      "integrity": "sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g=="
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.5.1.tgz",
+      "integrity": "sha512-LOFg65vdU4o4eZjVKNhu7VXbjdnY0amMw9sydLtKZiCNwj0eMD06rmktbWp9L/f6w6s9Qqe22lkks8PbwYwy4Q=="
     },
     "@floating-ui/dom": {
-      "version": "0.1.10",
-      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.1.10.tgz",
-      "integrity": "sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==",
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.3.1.tgz",
+      "integrity": "sha512-HJX/2xgGPt01YHQNAya2taqg5HDnY6ipF0B0Bk/Th2s4FD9R89Ecw3TEegLLO+VrQnPEGbuHOGJ6Fr3BPM0DYg==",
       "requires": {
-        "@floating-ui/core": "^0.3.0"
+        "@floating-ui/core": "^0.5.0"
       }
     },
     "@foliojs-fork/fontkit": {
@@ -18066,9 +18658,9 @@
       "version": "1.1.2"
     },
     "@github/hotkey": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/@github/hotkey/-/hotkey-1.6.1.tgz",
-      "integrity": "sha512-vwxqOREwldnk5wD460LPB5wUVpiVECPupi+9fKx5TFXUiRLLz4sw8QbF1FqQsV+puwsjUBhzXPa4Crj/7MGPhw=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@github/hotkey/-/hotkey-2.0.0.tgz",
+      "integrity": "sha512-KRw695msYYRIeFWvADV2PJa58+88NvYmHl+RJZLAlCtvbzjlkYwDf6yLC0xSLGcoYB5bKHQzudqYgPgpYnVbLw=="
     },
     "@github/markdown-toolbar-element": {
       "version": "2.1.0",
@@ -18111,9 +18703,9 @@
       }
     },
     "@lit/reactive-element": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.2.0.tgz",
-      "integrity": "sha512-7i/Fz8enAQ2AN5DyJ2i2AFERufjP6x1NjuHoNgDyJkjjHxEoo8kVyyHxu1A9YyeShlksjt5FvpvENBDuivQHLA=="
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.3.0.tgz",
+      "integrity": "sha512-0TKSIuJHXNLM0k98fi0AdMIdUoHIYlDHTP+0Vruc2SOs4T6vU1FinXgSvYd8mSrkt+8R+qdRAXvjpqrMXMyBgw=="
     },
     "@nodelib/fs.scandir": {
       "version": "2.1.3",
@@ -18638,15 +19230,14 @@
       }
     },
     "@tailwindcss/typography": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.0.tgz",
-      "integrity": "sha512-1p/3C6C+JJziS/ghtG8ACYalbA2SyLJY27Pm33cVTlAoY6VQ7zfm2H64cPxUMBkVIlWXTtWHhZcZJPobMRmQAA==",
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz",
+      "integrity": "sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==",
       "dev": true,
       "requires": {
         "lodash.castarray": "^4.4.0",
         "lodash.isplainobject": "^4.0.6",
-        "lodash.merge": "^4.6.2",
-        "lodash.uniq": "^4.5.0"
+        "lodash.merge": "^4.6.2"
       }
     },
     "@tootallnate/once": {
@@ -18731,18 +19322,18 @@
       }
     },
     "@types/leaflet": {
-      "version": "1.7.8",
-      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.8.tgz",
-      "integrity": "sha512-prZwhmUznkwTYCTZVGTR4U1GzgPP3PAWYYQ3wDgVkIoiuQTheWoycsXx4Rz9ARYhlDTl0Ycd8lvhH2/rNSkqIg==",
+      "version": "1.7.9",
+      "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.9.tgz",
+      "integrity": "sha512-H8vPgD49HKzqM41ArHGZM70g/tfhp8W+JcPxfnF+5H/Xvp+xiP+KQOUNWU8U89fqS1Jj3cpRY/+nbnaHFzwnFA==",
       "dev": true,
       "requires": {
         "@types/geojson": "*"
       }
     },
     "@types/marked": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.1.tgz",
-      "integrity": "sha512-ZigEmCWdNUU7IjZEuQ/iaimYdDHWHfTe3kg8ORfKjyGYd9RWumPoOJRQXB0bO+XLkNwzCthW3wUIQtANaEZ1ag==",
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.0.2.tgz",
+      "integrity": "sha512-auNrZ/c0w6wsM9DccwVxWHssrMDezHUAXNesdp2RQrCVCyrQbOiSq7yqdJKrUQQpw9VTm7CGYJH2A/YG7jjrjQ==",
       "dev": true
     },
     "@types/minimist": {
@@ -18785,23 +19376,23 @@
       "version": "2.0.2"
     },
     "@types/wavesurfer.js": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/@types/wavesurfer.js/-/wavesurfer.js-5.2.2.tgz",
-      "integrity": "sha512-/vjpf81co0SK3z4F5V79fZrFPQ8pw9/fEpgkzcgNVkBa9sY0gAaYzKuaQyCX/yjVf6kc73uPtWABQuVgvpguDQ==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@types/wavesurfer.js/-/wavesurfer.js-6.0.1.tgz",
+      "integrity": "sha512-WkHu4SgMdqWsR1fHVrkgNXrgcJBPUgMzI8YaZW86aemNSdnWijSkJQ1hEk8jgpeMKJx9oxu7I1x0pIHIlVPr2w==",
       "dev": true,
       "requires": {
         "@types/debounce": "*"
       }
     },
     "@typescript-eslint/eslint-plugin": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.0.tgz",
-      "integrity": "sha512-XXVKnMsq2fuu9K2KsIxPUGqb6xAImz8MEChClbXmE3VbveFtBUU5bzM6IPVWqzyADIgdkS2Ws/6Xo7W2TeZWjQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.12.1.tgz",
+      "integrity": "sha512-M499lqa8rnNK7mUv74lSFFttuUsubIRdAbHcVaP93oFcKkEmHmLqy2n7jM9C8DVmFMYK61ExrZU6dLYhQZmUpw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.10.0",
-        "@typescript-eslint/type-utils": "5.10.0",
-        "@typescript-eslint/utils": "5.10.0",
+        "@typescript-eslint/scope-manager": "5.12.1",
+        "@typescript-eslint/type-utils": "5.12.1",
+        "@typescript-eslint/utils": "5.12.1",
         "debug": "^4.3.2",
         "functional-red-black-tree": "^1.0.1",
         "ignore": "^5.1.8",
@@ -18820,52 +19411,52 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.0.tgz",
-      "integrity": "sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.12.1.tgz",
+      "integrity": "sha512-6LuVUbe7oSdHxUWoX/m40Ni8gsZMKCi31rlawBHt7VtW15iHzjbpj2WLiToG2758KjtCCiLRKZqfrOdl3cNKuw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.10.0",
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/typescript-estree": "5.10.0",
+        "@typescript-eslint/scope-manager": "5.12.1",
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/typescript-estree": "5.12.1",
         "debug": "^4.3.2"
       }
     },
     "@typescript-eslint/scope-manager": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz",
-      "integrity": "sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.12.1.tgz",
+      "integrity": "sha512-J0Wrh5xS6XNkd4TkOosxdpObzlYfXjAFIm9QxYLCPOcHVv1FyyFCPom66uIh8uBr0sZCrtS+n19tzufhwab8ZQ==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/visitor-keys": "5.10.0"
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/visitor-keys": "5.12.1"
       }
     },
     "@typescript-eslint/type-utils": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.0.tgz",
-      "integrity": "sha512-TzlyTmufJO5V886N+hTJBGIfnjQDQ32rJYxPaeiyWKdjsv2Ld5l8cbS7pxim4DeNs62fKzRSt8Q14Evs4JnZyQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.12.1.tgz",
+      "integrity": "sha512-Gh8feEhsNLeCz6aYqynh61Vsdy+tiNNkQtc+bN3IvQvRqHkXGUhYkUi+ePKzP0Mb42se7FDb+y2SypTbpbR/Sg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/utils": "5.10.0",
+        "@typescript-eslint/utils": "5.12.1",
         "debug": "^4.3.2",
         "tsutils": "^3.21.0"
       }
     },
     "@typescript-eslint/types": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.0.tgz",
-      "integrity": "sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.12.1.tgz",
+      "integrity": "sha512-hfcbq4qVOHV1YRdhkDldhV9NpmmAu2vp6wuFODL71Y0Ixak+FLeEU4rnPxgmZMnGreGEghlEucs9UZn5KOfHJA==",
       "dev": true
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz",
-      "integrity": "sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.12.1.tgz",
+      "integrity": "sha512-ahOdkIY9Mgbza7L9sIi205Pe1inCkZWAHE1TV1bpxlU4RZNPtXaDZfiiFWcL9jdxvW1hDYZJXrFm+vlMkXRbBw==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/visitor-keys": "5.10.0",
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/visitor-keys": "5.12.1",
         "debug": "^4.3.2",
         "globby": "^11.0.4",
         "is-glob": "^4.0.3",
@@ -18885,26 +19476,26 @@
       }
     },
     "@typescript-eslint/utils": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.0.tgz",
-      "integrity": "sha512-IGYwlt1CVcFoE2ueW4/ioEwybR60RAdGeiJX/iDAw0t5w0wK3S7QncDwpmsM70nKgGTuVchEWB8lwZwHqPAWRg==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.12.1.tgz",
+      "integrity": "sha512-Qq9FIuU0EVEsi8fS6pG+uurbhNTtoYr4fq8tKjBupsK5Bgbk2I32UGm0Sh+WOyjOPgo/5URbxxSNV6HYsxV4MQ==",
       "dev": true,
       "requires": {
         "@types/json-schema": "^7.0.9",
-        "@typescript-eslint/scope-manager": "5.10.0",
-        "@typescript-eslint/types": "5.10.0",
-        "@typescript-eslint/typescript-estree": "5.10.0",
+        "@typescript-eslint/scope-manager": "5.12.1",
+        "@typescript-eslint/types": "5.12.1",
+        "@typescript-eslint/typescript-estree": "5.12.1",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       }
     },
     "@typescript-eslint/visitor-keys": {
-      "version": "5.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz",
-      "integrity": "sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.12.1.tgz",
+      "integrity": "sha512-l1KSLfupuwrXx6wc0AuOmC7Ko5g14ZOQ86wJJqRbdLbXLK02pK/DPiDDqCc7BqqiiA04/eAA6ayL0bgOrAkH7A==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.10.0",
+        "@typescript-eslint/types": "5.12.1",
         "eslint-visitor-keys": "^3.0.0"
       }
     },
@@ -18984,22 +19575,10 @@
         "uri-js": "^4.2.2"
       }
     },
-    "alphanum-sort": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
-      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
-      "dev": true
-    },
     "amdefine": {
       "version": "1.0.1",
       "optional": true
     },
-    "ansi-colors": {
-      "version": "4.1.1",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "ansi-escapes": {
       "version": "3.2.0",
       "dev": true
@@ -19023,6 +19602,8 @@
     },
     "anymatch": {
       "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
       "dev": true,
       "requires": {
         "normalize-path": "^3.0.0",
@@ -19076,6 +19657,8 @@
     },
     "astral-regex": {
       "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
       "dev": true
     },
     "async": {
@@ -19171,7 +19754,9 @@
       "dev": true
     },
     "binary-extensions": {
-      "version": "2.1.0",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+      "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
       "dev": true
     },
     "boolbase": {
@@ -19410,9 +19995,9 @@
       "dev": true
     },
     "choices.js": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-10.0.0.tgz",
-      "integrity": "sha512-I/p92v2Oqbgf/ugThrD2E5nVqtVv6QouiURC7izFr6Mqn5NNUX8VZO64Rur0gh4GWKovj32WcxONzgqJJr5vdA==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-10.1.0.tgz",
+      "integrity": "sha512-NtrFt7c7ZQEGmkWsAV+EHynJhADWoZ82JEfg1+vQ9MMKJD4Ax2rzYPxXe+Q64i0HgUgWG/XTN3gN2pB8UFFFlA==",
       "requires": {
         "deepmerge": "^4.2.2",
         "fuse.js": "^6.5.3",
@@ -19420,7 +20005,9 @@
       }
     },
     "chokidar": {
-      "version": "3.5.2",
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
       "dev": true,
       "requires": {
         "anymatch": "~3.1.2",
@@ -19494,6 +20081,8 @@
     },
     "cli-truncate": {
       "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
       "dev": true,
       "requires": {
         "slice-ansi": "^3.0.0",
@@ -19502,41 +20091,20 @@
       "dependencies": {
         "ansi-regex": {
           "version": "5.0.1",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true
         },
-        "slice-ansi": {
-          "version": "3.0.0",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "astral-regex": "^2.0.0",
-            "is-fullwidth-code-point": "^3.0.0"
-          }
-        },
         "string-width": {
           "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
@@ -19546,6 +20114,8 @@
         },
         "strip-ansi": {
           "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
           "dev": true,
           "requires": {
             "ansi-regex": "^5.0.1"
@@ -19637,6 +20207,8 @@
     },
     "colorette": {
       "version": "2.0.16",
+      "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz",
+      "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
       "dev": true
     },
     "colors": {
@@ -19927,12 +20499,12 @@
       "dev": true
     },
     "css-blank-pseudo": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.2.tgz",
-      "integrity": "sha512-hOb1LFjRR+8ocA071xUSmg5VslJ8NGo/I2qpUpdeAYyBVCgupS5O8SEVo4SxEMYyFBNodBkzG3T1iqW9HCXxew==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz",
+      "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       }
     },
     "css-declaration-sorter": {
@@ -19944,19 +20516,25 @@
         "timsort": "^0.3.0"
       }
     },
+    "css-functions-list": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.0.1.tgz",
+      "integrity": "sha512-PriDuifDt4u4rkDgnqRCLnjfMatufLmWNfQnGCq34xZwpY3oabwhB9SqRBmuvWUgndbemCFlKqg+nO7C2q0SBw==",
+      "dev": true
+    },
     "css-has-pseudo": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.3.tgz",
-      "integrity": "sha512-0gDYWEKaGacwxCqvQ3Ypg6wGdD1AztbMm5h1JsactG2hP2eiflj808QITmuWBpE7sjSEVrAlZhPTVd/nNMj/hQ==",
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz",
+      "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       }
     },
     "css-prefers-color-scheme": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.2.tgz",
-      "integrity": "sha512-gv0KQBEM+q/XdoKyznovq3KW7ocO7k+FhPP+hQR1MenJdu0uPGS6IZa9PzlbqBeS6XcZJNAoqoFxlAUW461CrA==",
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
+      "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
       "dev": true,
       "requires": {}
     },
@@ -19975,66 +20553,66 @@
       }
     },
     "cssdb": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-5.0.0.tgz",
-      "integrity": "sha512-Q7982SynYCtcLUBCPgUPFy2TZmDiFyimpdln8K2v4w2c07W4rXL7q5F1ksVAqOAQfxKyyUGCKSsioezKT5bU1Q==",
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-6.4.0.tgz",
+      "integrity": "sha512-8NMWrur/ewSNrRNZndbtOTXc2Xb2b+NCTPHj8VErFYvJUlgsMAiBGaFaxG6hjy9zbCjj2ZLwSQrMM+tormO8qA==",
       "dev": true
     },
     "cssesc": {
       "version": "3.0.0"
     },
     "cssnano": {
-      "version": "5.0.15",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.15.tgz",
-      "integrity": "sha512-ppZsS7oPpi2sfiyV5+i+NbB/3GtQ+ab2Vs1azrZaXWujUSN4o+WdTxlCZIMcT9yLW3VO/5yX3vpyDaQ1nIn8CQ==",
+      "version": "5.0.17",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.17.tgz",
+      "integrity": "sha512-fmjLP7k8kL18xSspeXTzRhaFtRI7DL9b8IcXR80JgtnWBpvAzHT7sCR/6qdn0tnxIaINUN6OEQu83wF57Gs3Xw==",
       "dev": true,
       "requires": {
-        "cssnano-preset-default": "^5.1.10",
+        "cssnano-preset-default": "^5.1.12",
         "lilconfig": "^2.0.3",
         "yaml": "^1.10.2"
       }
     },
     "cssnano-preset-default": {
-      "version": "5.1.10",
-      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.10.tgz",
-      "integrity": "sha512-BcpSzUVygHMOnp9uG5rfPzTOCb0GAHQkqtUQx8j1oMNF9A1Q8hziOOhiM4bdICpmrBIU85BE64RD5XGYsVQZNA==",
+      "version": "5.1.12",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.12.tgz",
+      "integrity": "sha512-rO/JZYyjW1QNkWBxMGV28DW7d98UDLaF759frhli58QFehZ+D/LSmwQ2z/ylBAe2hUlsIWTq6NYGfQPq65EF9w==",
       "dev": true,
       "requires": {
         "css-declaration-sorter": "^6.0.3",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-calc": "^8.2.0",
-        "postcss-colormin": "^5.2.3",
-        "postcss-convert-values": "^5.0.2",
-        "postcss-discard-comments": "^5.0.1",
-        "postcss-discard-duplicates": "^5.0.1",
-        "postcss-discard-empty": "^5.0.1",
-        "postcss-discard-overridden": "^5.0.2",
-        "postcss-merge-longhand": "^5.0.4",
-        "postcss-merge-rules": "^5.0.4",
-        "postcss-minify-font-values": "^5.0.2",
-        "postcss-minify-gradients": "^5.0.4",
-        "postcss-minify-params": "^5.0.3",
-        "postcss-minify-selectors": "^5.1.1",
-        "postcss-normalize-charset": "^5.0.1",
-        "postcss-normalize-display-values": "^5.0.2",
-        "postcss-normalize-positions": "^5.0.2",
-        "postcss-normalize-repeat-style": "^5.0.2",
-        "postcss-normalize-string": "^5.0.2",
-        "postcss-normalize-timing-functions": "^5.0.2",
-        "postcss-normalize-unicode": "^5.0.2",
-        "postcss-normalize-url": "^5.0.4",
-        "postcss-normalize-whitespace": "^5.0.2",
-        "postcss-ordered-values": "^5.0.3",
-        "postcss-reduce-initial": "^5.0.2",
-        "postcss-reduce-transforms": "^5.0.2",
-        "postcss-svgo": "^5.0.3",
-        "postcss-unique-selectors": "^5.0.2"
+        "postcss-colormin": "^5.2.5",
+        "postcss-convert-values": "^5.0.4",
+        "postcss-discard-comments": "^5.0.3",
+        "postcss-discard-duplicates": "^5.0.3",
+        "postcss-discard-empty": "^5.0.3",
+        "postcss-discard-overridden": "^5.0.4",
+        "postcss-merge-longhand": "^5.0.6",
+        "postcss-merge-rules": "^5.0.6",
+        "postcss-minify-font-values": "^5.0.4",
+        "postcss-minify-gradients": "^5.0.6",
+        "postcss-minify-params": "^5.0.5",
+        "postcss-minify-selectors": "^5.1.3",
+        "postcss-normalize-charset": "^5.0.3",
+        "postcss-normalize-display-values": "^5.0.3",
+        "postcss-normalize-positions": "^5.0.4",
+        "postcss-normalize-repeat-style": "^5.0.4",
+        "postcss-normalize-string": "^5.0.4",
+        "postcss-normalize-timing-functions": "^5.0.3",
+        "postcss-normalize-unicode": "^5.0.4",
+        "postcss-normalize-url": "^5.0.5",
+        "postcss-normalize-whitespace": "^5.0.4",
+        "postcss-ordered-values": "^5.0.5",
+        "postcss-reduce-initial": "^5.0.3",
+        "postcss-reduce-transforms": "^5.0.4",
+        "postcss-svgo": "^5.0.4",
+        "postcss-unique-selectors": "^5.0.4"
       }
     },
     "cssnano-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.0.tgz",
-      "integrity": "sha512-Pzs7/BZ6OgT+tXXuF12DKR8SmSbzUeVYCtMBbS8lI0uAm3mrYmkyqCXXPsQESI6kmLfEVBppbdVY/el3hg3nAA==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.0.2.tgz",
+      "integrity": "sha512-KhprijuQv2sP4kT92sSQwhlK3SJTbDIsxcfIEySB0O+3m9esFOai7dP9bMx5enHAh2MwarVIcnwiWoOm01RIbQ==",
       "dev": true,
       "requires": {}
     },
@@ -20390,15 +20968,6 @@
         "once": "^1.4.0"
       }
     },
-    "enquirer": {
-      "version": "2.3.6",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "ansi-colors": "^4.1.1"
-      }
-    },
     "entities": {
       "version": "2.2.0",
       "dev": true
@@ -20518,30 +21087,162 @@
       }
     },
     "esbuild": {
-      "version": "0.13.15",
-      "dev": true,
-      "requires": {
-        "esbuild-android-arm64": "0.13.15",
-        "esbuild-darwin-64": "0.13.15",
-        "esbuild-darwin-arm64": "0.13.15",
-        "esbuild-freebsd-64": "0.13.15",
-        "esbuild-freebsd-arm64": "0.13.15",
-        "esbuild-linux-32": "0.13.15",
-        "esbuild-linux-64": "0.13.15",
-        "esbuild-linux-arm": "0.13.15",
-        "esbuild-linux-arm64": "0.13.15",
-        "esbuild-linux-mips64le": "0.13.15",
-        "esbuild-linux-ppc64le": "0.13.15",
-        "esbuild-netbsd-64": "0.13.15",
-        "esbuild-openbsd-64": "0.13.15",
-        "esbuild-sunos-64": "0.13.15",
-        "esbuild-windows-32": "0.13.15",
-        "esbuild-windows-64": "0.13.15",
-        "esbuild-windows-arm64": "0.13.15"
-      }
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.23.tgz",
+      "integrity": "sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==",
+      "dev": true,
+      "requires": {
+        "esbuild-android-arm64": "0.14.23",
+        "esbuild-darwin-64": "0.14.23",
+        "esbuild-darwin-arm64": "0.14.23",
+        "esbuild-freebsd-64": "0.14.23",
+        "esbuild-freebsd-arm64": "0.14.23",
+        "esbuild-linux-32": "0.14.23",
+        "esbuild-linux-64": "0.14.23",
+        "esbuild-linux-arm": "0.14.23",
+        "esbuild-linux-arm64": "0.14.23",
+        "esbuild-linux-mips64le": "0.14.23",
+        "esbuild-linux-ppc64le": "0.14.23",
+        "esbuild-linux-riscv64": "0.14.23",
+        "esbuild-linux-s390x": "0.14.23",
+        "esbuild-netbsd-64": "0.14.23",
+        "esbuild-openbsd-64": "0.14.23",
+        "esbuild-sunos-64": "0.14.23",
+        "esbuild-windows-32": "0.14.23",
+        "esbuild-windows-64": "0.14.23",
+        "esbuild-windows-arm64": "0.14.23"
+      }
+    },
+    "esbuild-android-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz",
+      "integrity": "sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-darwin-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz",
+      "integrity": "sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-darwin-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz",
+      "integrity": "sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-freebsd-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz",
+      "integrity": "sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-freebsd-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz",
+      "integrity": "sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-32": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz",
+      "integrity": "sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==",
+      "dev": true,
+      "optional": true
     },
     "esbuild-linux-64": {
-      "version": "0.13.15",
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz",
+      "integrity": "sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-arm": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz",
+      "integrity": "sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz",
+      "integrity": "sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-mips64le": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz",
+      "integrity": "sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-ppc64le": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz",
+      "integrity": "sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-riscv64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz",
+      "integrity": "sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-linux-s390x": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz",
+      "integrity": "sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-netbsd-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz",
+      "integrity": "sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-openbsd-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz",
+      "integrity": "sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-sunos-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz",
+      "integrity": "sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-windows-32": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz",
+      "integrity": "sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-windows-64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz",
+      "integrity": "sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==",
+      "dev": true,
+      "optional": true
+    },
+    "esbuild-windows-arm64": {
+      "version": "0.14.23",
+      "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz",
+      "integrity": "sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==",
       "dev": true,
       "optional": true
     },
@@ -20581,12 +21282,12 @@
       }
     },
     "eslint": {
-      "version": "8.7.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz",
-      "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==",
+      "version": "8.10.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
+      "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
       "dev": true,
       "requires": {
-        "@eslint/eslintrc": "^1.0.5",
+        "@eslint/eslintrc": "^1.2.0",
         "@humanwhocodes/config-array": "^0.9.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
@@ -20594,10 +21295,10 @@
         "debug": "^4.3.2",
         "doctrine": "^3.0.0",
         "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.1.0",
+        "eslint-scope": "^7.1.1",
         "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.2.0",
-        "espree": "^9.3.0",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.3.1",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
@@ -20632,9 +21333,9 @@
           "dev": true
         },
         "eslint-scope": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz",
-          "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==",
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+          "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
           "dev": true,
           "requires": {
             "esrecurse": "^4.3.0",
@@ -20670,7 +21371,9 @@
       }
     },
     "eslint-config-prettier": {
-      "version": "8.3.0",
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.4.0.tgz",
+      "integrity": "sha512-CFotdUcMY18nGRo5KGsnNxpznzhkopOcOo0InID+sgQssPrzjvsyKZPvOgymTFeHrFuC3Tzdf2YndhXtULK9Iw==",
       "dev": true,
       "requires": {}
     },
@@ -20709,20 +21412,20 @@
       }
     },
     "eslint-visitor-keys": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz",
-      "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
       "dev": true
     },
     "espree": {
-      "version": "9.3.0",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz",
-      "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==",
+      "version": "9.3.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz",
+      "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==",
       "dev": true,
       "requires": {
         "acorn": "^8.7.0",
         "acorn-jsx": "^5.3.1",
-        "eslint-visitor-keys": "^3.1.0"
+        "eslint-visitor-keys": "^3.3.0"
       },
       "dependencies": {
         "acorn": {
@@ -20866,7 +21569,9 @@
       "dev": true
     },
     "fast-glob": {
-      "version": "3.2.7",
+      "version": "3.2.11",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+      "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
       "dev": true,
       "requires": {
         "@nodelib/fs.stat": "^2.0.2",
@@ -21189,9 +21894,9 @@
       }
     },
     "globals": {
-      "version": "13.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
-      "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+      "version": "13.12.1",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
+      "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
       "dev": true,
       "requires": {
         "type-fest": "^0.20.2"
@@ -21206,14 +21911,16 @@
       }
     },
     "globby": {
-      "version": "11.0.4",
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
       "dev": true,
       "requires": {
         "array-union": "^2.1.0",
         "dir-glob": "^3.0.1",
-        "fast-glob": "^3.1.1",
-        "ignore": "^5.1.4",
-        "merge2": "^1.3.0",
+        "fast-glob": "^3.2.9",
+        "ignore": "^5.2.0",
+        "merge2": "^1.4.1",
         "slash": "^3.0.0"
       }
     },
@@ -21495,6 +22202,8 @@
     },
     "is-binary-path": {
       "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
       "dev": true,
       "requires": {
         "binary-extensions": "^2.0.0"
@@ -21656,10 +22365,6 @@
         "text-extensions": "^1.0.0"
       }
     },
-    "is-typedarray": {
-      "version": "1.0.0",
-      "dev": true
-    },
     "is-utf8": {
       "version": "0.2.1",
       "dev": true
@@ -21985,9 +22690,9 @@
       "dev": true
     },
     "lint-staged": {
-      "version": "12.2.0",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.2.0.tgz",
-      "integrity": "sha512-TnNciMBhmEqzqM+RvzqqdvrG4TsI8wCDMX1Vg9+rj2Y9uY70Nq84Mb1WOIiwxW9l5tUlCOqtY5La71RM2fSgfA==",
+      "version": "12.3.4",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.4.tgz",
+      "integrity": "sha512-yv/iK4WwZ7/v0GtVkNb3R82pdL9M+ScpIbJLJNyCXkJ1FGaXvRCOg/SeL59SZtPpqZhE7BD6kPKFLIDUhDx2/w==",
       "dev": true,
       "requires": {
         "cli-truncate": "^3.1.0",
@@ -21996,10 +22701,10 @@
         "debug": "^4.3.3",
         "execa": "^5.1.1",
         "lilconfig": "2.0.4",
-        "listr2": "^3.13.5",
+        "listr2": "^4.0.1",
         "micromatch": "^4.0.4",
         "normalize-path": "^3.0.0",
-        "object-inspect": "^1.11.1",
+        "object-inspect": "^1.12.0",
         "string-argv": "^0.3.1",
         "supports-color": "^9.2.1",
         "yaml": "^1.10.2"
@@ -22078,7 +22783,9 @@
       }
     },
     "listr2": {
-      "version": "3.13.5",
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.4.tgz",
+      "integrity": "sha512-vJOm5KD6uZXjSsrwajr+mNacIjf87gWvlBEltPWLbTkslUscWAzquyK4xfe9Zd4RDgO5nnwFyV06FC+uVR+5mg==",
       "dev": true,
       "requires": {
         "cli-truncate": "^2.1.0",
@@ -22086,47 +22793,51 @@
         "log-update": "^4.0.0",
         "p-map": "^4.0.0",
         "rfdc": "^1.3.0",
-        "rxjs": "^7.4.0",
+        "rxjs": "^7.5.4",
         "through": "^2.3.8",
         "wrap-ansi": "^7.0.0"
       },
       "dependencies": {
         "rxjs": {
-          "version": "7.4.0",
+          "version": "7.5.4",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz",
+          "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==",
           "dev": true,
           "requires": {
-            "tslib": "~2.1.0"
+            "tslib": "^2.1.0"
           }
         },
         "tslib": {
-          "version": "2.1.0",
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+          "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
           "dev": true
         }
       }
     },
     "lit": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/lit/-/lit-2.1.1.tgz",
-      "integrity": "sha512-yqDqf36IhXwOxIQSFqCMgpfvDCRdxLCLZl7m/+tO5C9W/OBHUj17qZpiMBT35v97QMVKcKEi1KZ3hZRyTwBNsQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.0.tgz",
+      "integrity": "sha512-FDyxUuczo6cJJY/2Bkgfh1872U4ikUvmK1Cb6+lYC1CW+QOo8CaWXCpvPKFzYsz0ojUxoruBLVrECc7VI2f1dQ==",
       "requires": {
-        "@lit/reactive-element": "^1.1.0",
-        "lit-element": "^3.1.0",
-        "lit-html": "^2.1.0"
+        "@lit/reactive-element": "^1.3.0",
+        "lit-element": "^3.2.0",
+        "lit-html": "^2.2.0"
       }
     },
     "lit-element": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.1.1.tgz",
-      "integrity": "sha512-14ClnMAU8EXnzC+M2/KDd3SFmNUn1QUw1+GxWkEMwGV3iaH8ObunMlO5svzvaWlkSV0WlxJCi40NGnDVJ2XZKQ==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
+      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
       "requires": {
-        "@lit/reactive-element": "^1.1.0",
-        "lit-html": "^2.1.0"
+        "@lit/reactive-element": "^1.3.0",
+        "lit-html": "^2.2.0"
       }
     },
     "lit-html": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.1.1.tgz",
-      "integrity": "sha512-E4BImK6lopAYanJpvcGaAG8kQFF1ccIulPu2BRNZI7acFB6i4ujjjsnaPVFT1j/4lD9r8GKih0Y8d7/LH8SeyQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.2.0.tgz",
+      "integrity": "sha512-dJnevgV8VkCuOXLWrjQopDE8nSy8CzipZ/ATfYQv7z7Dct4abblcKecf50gkIScuwCTzKvRLgvTgV0zzagW4gA==",
       "requires": {
         "@types/trusted-types": "^2.0.2"
       }
@@ -22213,10 +22924,14 @@
     },
     "lodash.truncate": {
       "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
       "dev": true
     },
     "lodash.uniq": {
       "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
       "dev": true
     },
     "lodash.uniqby": {
@@ -22225,6 +22940,8 @@
     },
     "log-update": {
       "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+      "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
       "dev": true,
       "requires": {
         "ansi-escapes": "^4.3.0",
@@ -22235,6 +22952,8 @@
       "dependencies": {
         "ansi-escapes": {
           "version": "4.3.2",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+          "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
           "dev": true,
           "requires": {
             "type-fest": "^0.21.3"
@@ -22242,10 +22961,14 @@
         },
         "ansi-regex": {
           "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
           "dev": true
         },
         "ansi-styles": {
           "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
           "dev": true,
           "requires": {
             "color-convert": "^2.0.1"
@@ -22253,6 +22976,8 @@
         },
         "cli-cursor": {
           "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
           "dev": true,
           "requires": {
             "restore-cursor": "^3.1.0"
@@ -22260,6 +22985,8 @@
         },
         "color-convert": {
           "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dev": true,
           "requires": {
             "color-name": "~1.1.4"
@@ -22267,14 +22994,20 @@
         },
         "color-name": {
           "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true
         },
         "onetime": {
           "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+          "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
           "dev": true,
           "requires": {
             "mimic-fn": "^2.1.0"
@@ -22282,14 +23015,29 @@
         },
         "restore-cursor": {
           "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
           "dev": true,
           "requires": {
             "onetime": "^5.1.0",
             "signal-exit": "^3.0.2"
           }
         },
+        "slice-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+          "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "astral-regex": "^2.0.0",
+            "is-fullwidth-code-point": "^3.0.0"
+          }
+        },
         "string-width": {
           "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
@@ -22299,6 +23047,8 @@
         },
         "strip-ansi": {
           "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
           "dev": true,
           "requires": {
             "ansi-regex": "^5.0.1"
@@ -22306,10 +23056,14 @@
         },
         "type-fest": {
           "version": "0.21.3",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+          "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
           "dev": true
         },
         "wrap-ansi": {
           "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
           "dev": true,
           "requires": {
             "ansi-styles": "^4.0.0",
@@ -22349,9 +23103,9 @@
       "dev": true
     },
     "marked": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.10.tgz",
-      "integrity": "sha512-+QvuFj0nGgO970fySghXGmuw+Fd0gD2x3+MqCWLIPf5oxdv1Ka6b2q+z9RP01P/IaKPMEramy+7cNy/Lw8c3hw=="
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
+      "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ=="
     },
     "marked-terminal": {
       "version": "5.0.0",
@@ -22500,9 +23254,9 @@
       "dev": true
     },
     "nanoid": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA=="
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+      "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw=="
     },
     "natural-compare": {
       "version": "1.4.0",
@@ -24372,7 +25126,9 @@
       "dev": true
     },
     "object-inspect": {
-      "version": "1.11.1"
+      "version": "1.12.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
+      "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
     },
     "object-is": {
       "version": "1.1.5",
@@ -24652,11 +25408,13 @@
       }
     },
     "postcss": {
-      "version": "8.4.5",
+      "version": "8.4.7",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz",
+      "integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==",
       "requires": {
-        "nanoid": "^3.1.30",
+        "nanoid": "^3.3.1",
         "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.1"
+        "source-map-js": "^1.0.2"
       }
     },
     "postcss-attribute-case-insensitive": {
@@ -24669,28 +25427,37 @@
       }
     },
     "postcss-calc": {
-      "version": "8.2.2",
-      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.2.tgz",
-      "integrity": "sha512-B5R0UeB4zLJvxNt1FVCaDZULdzsKLPc6FhjFJ+xwFiq7VG4i9cuaJLxVjNtExNK8ocm3n2o4unXXLiVX1SCqxA==",
+      "version": "8.2.4",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
+      "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
+      "dev": true,
+      "requires": {
+        "postcss-selector-parser": "^6.0.9",
+        "postcss-value-parser": "^4.2.0"
+      }
+    },
+    "postcss-clamp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.0.0.tgz",
+      "integrity": "sha512-FsMmeBZtymFN7Jtlnw9is8I4nB+qEEb/qS0ZLTIqcKiwZyHBq44Yhv29Q+VQsTGHYFqIr/s/9tqvNM7j+j1d+g==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.2",
-        "postcss-value-parser": "^4.0.2"
+        "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-color-functional-notation": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.1.tgz",
-      "integrity": "sha512-62OBIXCjRXpQZcFOYIXwXBlpAVWrYk8ek1rcjvMING4Q2cf0ipyN9qT+BhHA6HmftGSEnFQu2qgKO3gMscl3Rw==",
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.2.tgz",
+      "integrity": "sha512-DXVtwUhIk4f49KK5EGuEdgx4Gnyj6+t2jBSEmxvpIK9QI40tWrpS2Pua8Q7iIZWBrki2QOaeUdEaLPPa91K0RQ==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-color-hex-alpha": {
-      "version": "8.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.2.tgz",
-      "integrity": "sha512-gyx8RgqSmGVK156NAdKcsfkY3KPGHhKqvHTL3hhveFrBBToguKFzhyiuk3cljH6L4fJ0Kv+JENuPXs1Wij27Zw==",
+      "version": "8.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz",
+      "integrity": "sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
@@ -24706,9 +25473,9 @@
       }
     },
     "postcss-colormin": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.3.tgz",
-      "integrity": "sha512-dra4xoAjub2wha6RUXAgadHEn2lGxbj8drhFcIGLOMn914Eu7DkPUurugDXgstwttCYkJtZ/+PkWRWdp3UHRIA==",
+      "version": "5.2.5",
+      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.2.5.tgz",
+      "integrity": "sha512-+X30aDaGYq81mFqwyPpnYInsZQnNpdxMX0ajlY7AExCexEFkPVV+KrO7kXwayqEWL2xwEbNQ4nUO0ZsRWGnevg==",
       "dev": true,
       "requires": {
         "browserslist": "^4.16.6",
@@ -24718,12 +25485,12 @@
       }
     },
     "postcss-convert-values": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz",
-      "integrity": "sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.0.4.tgz",
+      "integrity": "sha512-bugzSAyjIexdObovsPZu/sBCTHccImJxLyFgeV0MmNBm/Lw5h5XnjfML6gzEmJ3A6nyfCW7hb1JXzcsA4Zfbdw==",
       "dev": true,
       "requires": {
-        "postcss-value-parser": "^4.1.0"
+        "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-custom-media": {
@@ -24734,9 +25501,9 @@
       "requires": {}
     },
     "postcss-custom-properties": {
-      "version": "12.1.3",
-      "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.3.tgz",
-      "integrity": "sha512-rtu3otIeY532PnEuuBrIIe+N+pcdbX/7JMZfrcL09wc78YayrHw5E8UkDfvnlOhEUrI4ptCuzXQfj+Or6spbGA==",
+      "version": "12.1.4",
+      "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.4.tgz",
+      "integrity": "sha512-i6AytuTCoDLJkWN/MtAIGriJz3j7UX6bV7Z5t+KgFz+dwZS15/mlTJY1S0kRizlk6ba0V8u8hN50Fz5Nm7tdZw==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
@@ -24752,76 +25519,77 @@
       }
     },
     "postcss-dir-pseudo-class": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.3.tgz",
-      "integrity": "sha512-qiPm+CNAlgXiMf0J5IbBBEXA9l/Q5HGsNGkL3znIwT2ZFRLGY9U2fTUpa4lqCUXQOxaLimpacHeQC80BD2qbDw==",
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz",
+      "integrity": "sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       }
     },
     "postcss-discard-comments": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz",
-      "integrity": "sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.0.3.tgz",
+      "integrity": "sha512-6W5BemziRoqIdAKT+1QjM4bNcJAQ7z7zk073730NHg4cUXh3/rQHHj7pmYxUB9aGhuRhBiUf0pXvIHkRwhQP0Q==",
       "dev": true,
       "requires": {}
     },
     "postcss-discard-duplicates": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz",
-      "integrity": "sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.3.tgz",
+      "integrity": "sha512-vPtm1Mf+kp7iAENTG7jI1MN1lk+fBqL5y+qxyi4v3H+lzsXEdfS3dwUZD45KVhgzDEgduur8ycB4hMegyMTeRw==",
       "dev": true,
       "requires": {}
     },
     "postcss-discard-empty": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz",
-      "integrity": "sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.0.3.tgz",
+      "integrity": "sha512-xGJugpaXKakwKI7sSdZjUuN4V3zSzb2Y0LOlmTajFbNinEjTfVs9PFW2lmKBaC/E64WwYppfqLD03P8l9BuueA==",
       "dev": true,
       "requires": {}
     },
     "postcss-discard-overridden": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.2.tgz",
-      "integrity": "sha512-+56BLP6NSSUuWUXjRgAQuho1p5xs/hU5Sw7+xt9S3JSg+7R6+WMGnJW7Hre/6tTuZ2xiXMB42ObkiZJ2hy/Pew==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.0.4.tgz",
+      "integrity": "sha512-3j9QH0Qh1KkdxwiZOW82cId7zdwXVQv/gRXYDnwx5pBtR1sTkU4cXRK9lp5dSdiM0r0OICO/L8J6sV1/7m0kHg==",
       "dev": true,
       "requires": {}
     },
     "postcss-double-position-gradients": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.4.tgz",
-      "integrity": "sha512-qz+s5vhKJlsHw8HjSs+HVk2QGFdRyC68KGRQGX3i+GcnUjhWhXQEmCXW6siOJkZ1giu0ddPwSO6I6JdVVVPoog==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.0.tgz",
+      "integrity": "sha512-oz73I08yMN3oxjj0s8mED1rG+uOYoK3H8N9RjQofyg52KBRNmePJKg3fVwTpL2U5ZFbCzXoZBsUD/CvZdlqE4Q==",
       "dev": true,
       "requires": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-env-function": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.4.tgz",
-      "integrity": "sha512-0ltahRTPtXSIlEZFv7zIvdEib7HN0ZbUQxrxIKn8KbiRyhALo854I/CggU5lyZe6ZBvSTJ6Al2vkZecI2OhneQ==",
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.5.tgz",
+      "integrity": "sha512-gPUJc71ji9XKyl0WSzAalBeEA/89kU+XpffpPxSaaaZ1c48OL36r1Ep5R6+9XAPkIiDlSvVAwP4io12q/vTcvA==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-focus-visible": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.3.tgz",
-      "integrity": "sha512-ozOsg+L1U8S+rxSHnJJiET6dNLyADcPHhEarhhtCI9DBLGOPG/2i4ddVoFch9LzrBgb8uDaaRI4nuid2OM82ZA==",
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz",
+      "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       }
     },
     "postcss-focus-within": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.3.tgz",
-      "integrity": "sha512-fk9y2uFS6/Kpp7/A9Hz9Z4rlFQ8+tzgBcQCXAFSrXFGAbKx+4ZZOmmfHuYjCOMegPWoz0pnC6fNzi8j7Xyqp5Q==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz",
+      "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       }
     },
     "postcss-font-variant": {
@@ -24832,16 +25600,16 @@
       "requires": {}
     },
     "postcss-gap-properties": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.2.tgz",
-      "integrity": "sha512-EaMy/pbxtQnKDsnbEjdqlkCkROTQZzolcLKgIE+3b7EuJfJydH55cZeHfm+MtIezXRqhR80VKgaztO/vHq94Fw==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz",
+      "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==",
       "dev": true,
       "requires": {}
     },
     "postcss-image-set-function": {
-      "version": "4.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.4.tgz",
-      "integrity": "sha512-BlEo9gSTj66lXjRNByvkMK9dEdEGFXRfGjKRi9fo8s0/P3oEk74cAoonl/utiM50E2OPVb/XSu+lWvdW4KtE/Q==",
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz",
+      "integrity": "sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
@@ -24873,11 +25641,12 @@
       }
     },
     "postcss-lab-function": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.0.3.tgz",
-      "integrity": "sha512-MH4tymWmefdZQ7uVG/4icfLjAQmH6o2NRYyVh2mKoB4RXJp9PjsyhZwhH4ouaCQHvg+qJVj3RzeAR1EQpIlXZA==",
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.1.1.tgz",
+      "integrity": "sha512-j3Z0WQCimY2tMle++YcmygnnVbt6XdnrCV1FO2IpzaCSmtTF2oO8h4ZYUA1Q+QHYroIiaWPvNHt9uBR4riCksQ==",
       "dev": true,
       "requires": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
         "postcss-value-parser": "^4.2.0"
       }
     },
@@ -24891,9 +25660,9 @@
       }
     },
     "postcss-logical": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.3.tgz",
-      "integrity": "sha512-P5NcHWYrif0vK8rgOy/T87vg0WRIj3HSknrvp1wzDbiBeoDPVmiVRmkown2eSQdpPveat/MC1ess5uhzZFVnqQ==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz",
+      "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
       "dev": true,
       "requires": {}
     },
@@ -24909,66 +25678,64 @@
       "dev": true
     },
     "postcss-merge-longhand": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz",
-      "integrity": "sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==",
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.0.6.tgz",
+      "integrity": "sha512-rkmoPwQO6ymJSmWsX6l2hHeEBQa7C4kJb9jyi5fZB1sE8nSCv7sqchoYPixRwX/yvLoZP2y6FA5kcjiByeJqDg==",
       "dev": true,
       "requires": {
-        "postcss-value-parser": "^4.1.0",
-        "stylehacks": "^5.0.1"
+        "postcss-value-parser": "^4.2.0",
+        "stylehacks": "^5.0.3"
       }
     },
     "postcss-merge-rules": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.4.tgz",
-      "integrity": "sha512-yOj7bW3NxlQxaERBB0lEY1sH5y+RzevjbdH4DBJurjKERNpknRByFNdNe+V72i5pIZL12woM9uGdS5xbSB+kDQ==",
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.0.6.tgz",
+      "integrity": "sha512-nzJWJ9yXWp8AOEpn/HFAW72WKVGD2bsLiAmgw4hDchSij27bt6TF+sIK0cJUBAYT3SGcjtGGsOR89bwkkMuMgQ==",
       "dev": true,
       "requires": {
         "browserslist": "^4.16.6",
         "caniuse-api": "^3.0.0",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-selector-parser": "^6.0.5"
       }
     },
     "postcss-minify-font-values": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.2.tgz",
-      "integrity": "sha512-R6MJZryq28Cw0AmnyhXrM7naqJZZLoa1paBltIzh2wM7yb4D45TLur+eubTQ4jCmZU9SGeZdWsc5KcSoqTMeTg==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.0.4.tgz",
+      "integrity": "sha512-RN6q3tyuEesvyCYYFCRGJ41J1XFvgV+dvYGHr0CeHv8F00yILlN8Slf4t8XW4IghlfZYCeyRrANO6HpJ948ieA==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-minify-gradients": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.4.tgz",
-      "integrity": "sha512-RVwZA7NC4R4J76u8X0Q0j+J7ItKUWAeBUJ8oEEZWmtv3Xoh19uNJaJwzNpsydQjk6PkuhRrK+YwwMf+c+68EYg==",
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.0.6.tgz",
+      "integrity": "sha512-E/dT6oVxB9nLGUTiY/rG5dX9taugv9cbLNTFad3dKxOO+BQg25Q/xo2z2ddG+ZB1CbkZYaVwx5blY8VC7R/43A==",
       "dev": true,
       "requires": {
         "colord": "^2.9.1",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-minify-params": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.3.tgz",
-      "integrity": "sha512-NY92FUikE+wralaiVexFd5gwb7oJTIDhgTNeIw89i1Ymsgt4RWiPXfz3bg7hDy4NL6gepcThJwOYNtZO/eNi7Q==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.0.5.tgz",
+      "integrity": "sha512-YBNuq3Rz5LfLFNHb9wrvm6t859b8qIqfXsWeK7wROm3jSKNpO1Y5e8cOyBv6Acji15TgSrAwb3JkVNCqNyLvBg==",
       "dev": true,
       "requires": {
-        "alphanum-sort": "^1.0.2",
         "browserslist": "^4.16.6",
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-minify-selectors": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.1.tgz",
-      "integrity": "sha512-TOzqOPXt91O2luJInaVPiivh90a2SIK5Nf1Ea7yEIM/5w+XA5BGrZGUSW8aEx9pJ/oNj7ZJBhjvigSiBV+bC1Q==",
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.1.3.tgz",
+      "integrity": "sha512-9RJfTiQEKA/kZhMaEXND893nBqmYQ8qYa/G+uPdVnXF6D/FzpfI6kwBtWEcHx5FqDbA79O9n6fQJfrIj6M8jvQ==",
       "dev": true,
       "requires": {
-        "alphanum-sort": "^1.0.2",
         "postcss-selector-parser": "^6.0.5"
       }
     },
@@ -24988,61 +25755,61 @@
       }
     },
     "postcss-normalize-charset": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz",
-      "integrity": "sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.0.3.tgz",
+      "integrity": "sha512-iKEplDBco9EfH7sx4ut7R2r/dwTnUqyfACf62Unc9UiyFuI7uUqZZtY+u+qp7g8Qszl/U28HIfcsI3pEABWFfA==",
       "dev": true,
       "requires": {}
     },
     "postcss-normalize-display-values": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.2.tgz",
-      "integrity": "sha512-RxXoJPUR0shSjkMMzgEZDjGPrgXUVYyWA/YwQRicb48H15OClPuaDR7tYokLAlGZ2tCSENEN5WxjgxSD5m4cUw==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.3.tgz",
+      "integrity": "sha512-FIV5FY/qs4Ja32jiDb5mVj5iWBlS3N8tFcw2yg98+8MkRgyhtnBgSC0lxU+16AMHbjX5fbSJgw5AXLMolonuRQ==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-normalize-positions": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.2.tgz",
-      "integrity": "sha512-tqghWFVDp2btqFg1gYob1etPNxXLNh3uVeWgZE2AQGh6b2F8AK2Gj36v5Vhyh+APwIzNjmt6jwZ9pTBP+/OM8g==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.0.4.tgz",
+      "integrity": "sha512-qynirjBX0Lc73ROomZE3lzzmXXTu48/QiEzKgMeqh28+MfuHLsuqC9po4kj84igZqqFGovz8F8hf44hA3dPYmQ==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-normalize-repeat-style": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.2.tgz",
-      "integrity": "sha512-/rIZn8X9bBzC7KvY4iKUhXUGW3MmbXwfPF23jC9wT9xTi7kAvgj8sEgwxjixBmoL6MVa4WOgxNz2hAR6wTK8tw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.4.tgz",
+      "integrity": "sha512-Innt+wctD7YpfeDR7r5Ik6krdyppyAg2HBRpX88fo5AYzC1Ut/l3xaxACG0KsbX49cO2n5EB13clPwuYVt8cMA==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-normalize-string": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.2.tgz",
-      "integrity": "sha512-zaI1yzwL+a/FkIzUWMQoH25YwCYxi917J4pYm1nRXtdgiCdnlTkx5eRzqWEC64HtRa06WCJ9TIutpb6GmW4gFw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.0.4.tgz",
+      "integrity": "sha512-Dfk42l0+A1CDnVpgE606ENvdmksttLynEqTQf5FL3XGQOyqxjbo25+pglCUvziicTxjtI2NLUR6KkxyUWEVubQ==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-normalize-timing-functions": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.2.tgz",
-      "integrity": "sha512-Ao0PP6MoYsRU1LxeVUW740ioknvdIUmfr6uAA3xWlQJ9s69/Tupy8qwhuKG3xWfl+KvLMAP9p2WXF9cwuk/7Bg==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.3.tgz",
+      "integrity": "sha512-QRfjvFh11moN4PYnJ7hia4uJXeFotyK3t2jjg8lM9mswleGsNw2Lm3I5wO+l4k1FzK96EFwEVn8X8Ojrp2gP4g==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-normalize-unicode": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.2.tgz",
-      "integrity": "sha512-3y/V+vjZ19HNcTizeqwrbZSUsE69ZMRHfiiyLAJb7C7hJtYmM4Gsbajy7gKagu97E8q5rlS9k8FhojA8cpGhWw==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.4.tgz",
+      "integrity": "sha512-W79Regn+a+eXTzB+oV/8XJ33s3pDyFTND2yDuUCo0Xa3QSy1HtNIfRVPXNubHxjhlqmMFADr3FSCHT84ITW3ig==",
       "dev": true,
       "requires": {
         "browserslist": "^4.16.6",
@@ -25050,9 +25817,9 @@
       }
     },
     "postcss-normalize-url": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.4.tgz",
-      "integrity": "sha512-cNj3RzK2pgQQyNp7dzq0dqpUpQ/wYtdDZM3DepPmFjCmYIfceuD9VIAcOdvrNetjIU65g1B4uwdP/Krf6AFdXg==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.0.5.tgz",
+      "integrity": "sha512-Ws3tX+PcekYlXh+ycAt0wyzqGthkvVtZ9SZLutMVvHARxcpu4o7vvXcNoiNKyjKuWecnjS6HDI3fjBuDr5MQxQ==",
       "dev": true,
       "requires": {
         "normalize-url": "^6.0.1",
@@ -25060,28 +25827,34 @@
       }
     },
     "postcss-normalize-whitespace": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.2.tgz",
-      "integrity": "sha512-CXBx+9fVlzSgbk0IXA/dcZn9lXixnQRndnsPC5ht3HxlQ1bVh77KQDL1GffJx1LTzzfae8ftMulsjYmO2yegxA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.4.tgz",
+      "integrity": "sha512-wsnuHolYZjMwWZJoTC9jeI2AcjA67v4UuidDrPN9RnX8KIZfE+r2Nd6XZRwHVwUiHmRvKQtxiqo64K+h8/imaw==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
+    "postcss-opacity-percentage": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz",
+      "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==",
+      "dev": true
+    },
     "postcss-ordered-values": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.3.tgz",
-      "integrity": "sha512-T9pDS+P9bWeFvqivXd5ACzQmrCmHjv3ZP+djn8E1UZY7iK79pFSm7i3WbKw2VSmFmdbMm8sQ12OPcNpzBo3Z2w==",
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.0.5.tgz",
+      "integrity": "sha512-mfY7lXpq+8bDEHfP+muqibDPhZ5eP9zgBEF9XRvoQgXcQe2Db3G1wcvjbnfjXG6wYsl+0UIjikqq4ym1V2jGMQ==",
       "dev": true,
       "requires": {
-        "cssnano-utils": "^3.0.0",
+        "cssnano-utils": "^3.0.2",
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-overflow-shorthand": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.2.tgz",
-      "integrity": "sha512-odBMVt6PTX7jOE9UNvmnLrFzA9pXS44Jd5shFGGtSHY80QCuJF+14McSy0iavZggRZ9Oj//C9vOKQmexvyEJMg==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz",
+      "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==",
       "dev": true,
       "requires": {}
     },
@@ -25093,68 +25866,77 @@
       "requires": {}
     },
     "postcss-place": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.3.tgz",
-      "integrity": "sha512-tDQ3m+GYoOar+KoQgj+pwPAvGHAp/Sby6vrFiyrELrMKQJ4AejL0NcS0mm296OKKYA2SRg9ism/hlT/OLhBrdQ==",
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.4.tgz",
+      "integrity": "sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
       }
     },
     "postcss-preset-env": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.2.3.tgz",
-      "integrity": "sha512-Ok0DhLfwrcNGrBn8sNdy1uZqWRk/9FId0GiQ39W4ILop5GHtjJs8bu1MY9isPwHInpVEPWjb4CEcEaSbBLpfwA==",
-      "dev": true,
-      "requires": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.4.1.tgz",
+      "integrity": "sha512-UvBVvPJ2vb4odAtckSbryndyBz+Me1q8wawqq0qznpDXy188I+8W5Sa929sCPqw2/NSYnqpHJbo41BKso3+I9A==",
+      "dev": true,
+      "requires": {
+        "@csstools/postcss-color-function": "^1.0.2",
+        "@csstools/postcss-font-format-keywords": "^1.0.0",
+        "@csstools/postcss-hwb-function": "^1.0.0",
+        "@csstools/postcss-ic-unit": "^1.0.0",
+        "@csstools/postcss-is-pseudo-class": "^2.0.0",
+        "@csstools/postcss-normalize-display-values": "^1.0.0",
+        "@csstools/postcss-oklab-function": "^1.0.1",
+        "@csstools/postcss-progressive-custom-properties": "^1.2.0",
         "autoprefixer": "^10.4.2",
         "browserslist": "^4.19.1",
-        "caniuse-lite": "^1.0.30001299",
-        "css-blank-pseudo": "^3.0.2",
-        "css-has-pseudo": "^3.0.3",
-        "css-prefers-color-scheme": "^6.0.2",
-        "cssdb": "^5.0.0",
+        "css-blank-pseudo": "^3.0.3",
+        "css-has-pseudo": "^3.0.4",
+        "css-prefers-color-scheme": "^6.0.3",
+        "cssdb": "^6.3.1",
         "postcss-attribute-case-insensitive": "^5.0.0",
-        "postcss-color-functional-notation": "^4.2.1",
-        "postcss-color-hex-alpha": "^8.0.2",
+        "postcss-clamp": "^4.0.0",
+        "postcss-color-functional-notation": "^4.2.2",
+        "postcss-color-hex-alpha": "^8.0.3",
         "postcss-color-rebeccapurple": "^7.0.2",
         "postcss-custom-media": "^8.0.0",
-        "postcss-custom-properties": "^12.1.2",
+        "postcss-custom-properties": "^12.1.4",
         "postcss-custom-selectors": "^6.0.0",
-        "postcss-dir-pseudo-class": "^6.0.3",
-        "postcss-double-position-gradients": "^3.0.4",
-        "postcss-env-function": "^4.0.4",
-        "postcss-focus-visible": "^6.0.3",
-        "postcss-focus-within": "^5.0.3",
+        "postcss-dir-pseudo-class": "^6.0.4",
+        "postcss-double-position-gradients": "^3.1.0",
+        "postcss-env-function": "^4.0.5",
+        "postcss-focus-visible": "^6.0.4",
+        "postcss-focus-within": "^5.0.4",
         "postcss-font-variant": "^5.0.0",
-        "postcss-gap-properties": "^3.0.2",
-        "postcss-image-set-function": "^4.0.4",
+        "postcss-gap-properties": "^3.0.3",
+        "postcss-image-set-function": "^4.0.6",
         "postcss-initial": "^4.0.1",
-        "postcss-lab-function": "^4.0.3",
-        "postcss-logical": "^5.0.3",
+        "postcss-lab-function": "^4.1.1",
+        "postcss-logical": "^5.0.4",
         "postcss-media-minmax": "^5.0.0",
         "postcss-nesting": "^10.1.2",
-        "postcss-overflow-shorthand": "^3.0.2",
+        "postcss-opacity-percentage": "^1.1.2",
+        "postcss-overflow-shorthand": "^3.0.3",
         "postcss-page-break": "^3.0.4",
-        "postcss-place": "^7.0.3",
-        "postcss-pseudo-class-any-link": "^7.0.2",
+        "postcss-place": "^7.0.4",
+        "postcss-pseudo-class-any-link": "^7.1.1",
         "postcss-replace-overflow-wrap": "^4.0.0",
         "postcss-selector-not": "^5.0.0"
       }
     },
     "postcss-pseudo-class-any-link": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.0.2.tgz",
-      "integrity": "sha512-CG35J1COUH7OOBgpw5O+0koOLUd5N4vUGKUqSAuIe4GiuLHWU96Pqp+UPC8QITTd12zYAFx76pV7qWT/0Aj/TA==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.1.tgz",
+      "integrity": "sha512-JRoLFvPEX/1YTPxRxp1JO4WxBVXJYrSY7NHeak5LImwJ+VobFMwYDQHvfTXEpcn+7fYIeGkC29zYFhFWIZD8fg==",
       "dev": true,
       "requires": {
-        "postcss-selector-parser": "^6.0.8"
+        "postcss-selector-parser": "^6.0.9"
       }
     },
     "postcss-reduce-initial": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz",
-      "integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.3.tgz",
+      "integrity": "sha512-c88TkSnQ/Dnwgb4OZbKPOBbCaauwEjbECP5uAuFPOzQ+XdjNjRH7SG0dteXrpp1LlIFEKK76iUGgmw2V0xeieA==",
       "dev": true,
       "requires": {
         "browserslist": "^4.16.6",
@@ -25162,9 +25944,9 @@
       }
     },
     "postcss-reduce-transforms": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.2.tgz",
-      "integrity": "sha512-25HeDeFsgiPSUx69jJXZn8I06tMxLQJJNF5h7i9gsUg8iP4KOOJ8EX8fj3seeoLt3SLU2YDD6UPnDYVGUO7DEA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.4.tgz",
+      "integrity": "sha512-VIJB9SFSaL8B/B7AXb7KHL6/GNNbbCHslgdzS9UDfBZYIA2nx8NLY7iD/BXFSO/1sRUILzBTfHCoW5inP37C5g==",
       "dev": true,
       "requires": {
         "postcss-value-parser": "^4.2.0"
@@ -25206,31 +25988,30 @@
       }
     },
     "postcss-selector-parser": {
-      "version": "6.0.8",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz",
-      "integrity": "sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==",
+      "version": "6.0.9",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz",
+      "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==",
       "requires": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
       }
     },
     "postcss-svgo": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.3.tgz",
-      "integrity": "sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.0.4.tgz",
+      "integrity": "sha512-yDKHvULbnZtIrRqhZoA+rxreWpee28JSRH/gy9727u0UCgtpv1M/9WEWY3xySlFa0zQJcqf6oCBJPR5NwkmYpg==",
       "dev": true,
       "requires": {
-        "postcss-value-parser": "^4.1.0",
+        "postcss-value-parser": "^4.2.0",
         "svgo": "^2.7.0"
       }
     },
     "postcss-unique-selectors": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz",
-      "integrity": "sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==",
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.0.4.tgz",
+      "integrity": "sha512-5ampwoSDJCxDPoANBIlMgoBcYUHnhaiuLYJR5pj1DLnYQvMRVyFuTA5C3Bvt+aHtiqWpJkD/lXT50Vo1D0ZsAQ==",
       "dev": true,
       "requires": {
-        "alphanum-sort": "^1.0.2",
         "postcss-selector-parser": "^6.0.5"
       }
     },
@@ -25443,6 +26224,8 @@
     },
     "readdirp": {
       "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
       "dev": true,
       "requires": {
         "picomatch": "^2.2.1"
@@ -25569,11 +26352,11 @@
       "dev": true
     },
     "resolve": {
-      "version": "1.21.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz",
-      "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==",
+      "version": "1.22.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz",
+      "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==",
       "requires": {
-        "is-core-module": "^2.8.0",
+        "is-core-module": "^2.8.1",
         "path-parse": "^1.0.7",
         "supports-preserve-symlinks-flag": "^1.0.0"
       }
@@ -25632,6 +26415,8 @@
     },
     "rfdc": {
       "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
+      "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
       "dev": true
     },
     "rgbcolor": {
@@ -25844,7 +26629,9 @@
       }
     },
     "signal-exit": {
-      "version": "3.0.3",
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
       "dev": true
     },
     "signale": {
@@ -25872,7 +26659,9 @@
       "dev": true
     },
     "slice-ansi": {
-      "version": "4.0.0",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
       "dev": true,
       "requires": {
         "ansi-styles": "^4.0.0",
@@ -25882,6 +26671,8 @@
       "dependencies": {
         "ansi-styles": {
           "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
           "dev": true,
           "requires": {
             "color-convert": "^2.0.1"
@@ -25889,6 +26680,8 @@
         },
         "color-convert": {
           "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dev": true,
           "requires": {
             "color-name": "~1.1.4"
@@ -25896,10 +26689,14 @@
         },
         "color-name": {
           "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true
         }
       }
@@ -25908,7 +26705,9 @@
       "version": "0.5.7"
     },
     "source-map-js": {
-      "version": "1.0.1"
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
     },
     "source-map-support": {
       "version": "0.5.21",
@@ -25924,12 +26723,6 @@
         }
       }
     },
-    "source-map-url": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
-      "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
-      "dev": true
-    },
     "sourcemap-codec": {
       "version": "1.4.8"
     },
@@ -26268,32 +27061,33 @@
       "dev": true
     },
     "stylehacks": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.1.tgz",
-      "integrity": "sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.0.3.tgz",
+      "integrity": "sha512-ENcUdpf4yO0E1rubu8rkxI+JGQk4CgjchynZ4bDBJDfqdy+uhTRSWb8/F3Jtu+Bw5MW45Po3/aQGeIyyxgQtxg==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.16.0",
+        "browserslist": "^4.16.6",
         "postcss-selector-parser": "^6.0.4"
       }
     },
     "stylelint": {
-      "version": "14.2.0",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.2.0.tgz",
-      "integrity": "sha512-i0DrmDXFNpDsWiwx6SPRs4/pyw4kvZgqpDGvsTslQMY7hpUl6r33aQvNSn6cnTg2wtZ9rreFElI7XAKpOWi1vQ==",
+      "version": "14.5.3",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.5.3.tgz",
+      "integrity": "sha512-omHETL+kGHR+fCXFK1SkZD/A+emCP9esggAdWEl8GPjTNeyRYj+H6uetRDcU+7E451zwWiUYGVAX+lApsAZgsQ==",
       "dev": true,
       "requires": {
         "balanced-match": "^2.0.0",
         "colord": "^2.9.2",
         "cosmiconfig": "^7.0.1",
+        "css-functions-list": "^3.0.1",
         "debug": "^4.3.3",
         "execall": "^2.0.0",
-        "fast-glob": "^3.2.7",
+        "fast-glob": "^3.2.11",
         "fastest-levenshtein": "^1.0.12",
         "file-entry-cache": "^6.0.1",
         "get-stdin": "^8.0.0",
         "global-modules": "^2.0.0",
-        "globby": "^11.0.4",
+        "globby": "^11.1.0",
         "globjoin": "^0.1.4",
         "html-tags": "^3.1.0",
         "ignore": "^5.2.0",
@@ -26307,21 +27101,22 @@
         "normalize-path": "^3.0.0",
         "normalize-selector": "^0.2.0",
         "picocolors": "^1.0.0",
-        "postcss": "^8.3.11",
+        "postcss": "^8.4.6",
         "postcss-media-query-parser": "^0.2.3",
         "postcss-resolve-nested-selector": "^0.1.1",
         "postcss-safe-parser": "^6.0.0",
-        "postcss-selector-parser": "^6.0.7",
-        "postcss-value-parser": "^4.1.0",
+        "postcss-selector-parser": "^6.0.9",
+        "postcss-value-parser": "^4.2.0",
         "resolve-from": "^5.0.0",
         "specificity": "^0.4.1",
         "string-width": "^4.2.3",
         "strip-ansi": "^6.0.1",
         "style-search": "^0.1.0",
+        "supports-hyperlinks": "^2.2.0",
         "svg-tags": "^1.0.0",
-        "table": "^6.7.5",
+        "table": "^6.8.0",
         "v8-compile-cache": "^2.3.0",
-        "write-file-atomic": "^3.0.3"
+        "write-file-atomic": "^4.0.1"
       },
       "dependencies": {
         "ansi-regex": {
@@ -26389,19 +27184,19 @@
       }
     },
     "stylelint-config-recommended": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz",
-      "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz",
+      "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==",
       "dev": true,
       "requires": {}
     },
     "stylelint-config-standard": {
-      "version": "24.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-24.0.0.tgz",
-      "integrity": "sha512-+RtU7fbNT+VlNbdXJvnjc3USNPZRiRVp/d2DxOF/vBDDTi0kH5RX2Ny6errdtZJH3boO+bmqIYEllEmok4jiuw==",
+      "version": "25.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz",
+      "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==",
       "dev": true,
       "requires": {
-        "stylelint-config-recommended": "^6.0.0"
+        "stylelint-config-recommended": "^7.0.0"
       }
     },
     "supports-color": {
@@ -26527,7 +27322,9 @@
       "version": "3.2.4"
     },
     "table": {
-      "version": "6.7.5",
+      "version": "6.8.0",
+      "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz",
+      "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==",
       "dev": true,
       "requires": {
         "ajv": "^8.0.1",
@@ -26538,7 +27335,9 @@
       },
       "dependencies": {
         "ajv": {
-          "version": "8.8.2",
+          "version": "8.10.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz",
+          "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==",
           "dev": true,
           "requires": {
             "fast-deep-equal": "^3.1.1",
@@ -26549,18 +27348,61 @@
         },
         "ansi-regex": {
           "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+          "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
           "dev": true
         },
         "is-fullwidth-code-point": {
           "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true
         },
         "json-schema-traverse": {
           "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
           "dev": true
         },
+        "slice-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+          "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "astral-regex": "^2.0.0",
+            "is-fullwidth-code-point": "^3.0.0"
+          }
+        },
         "string-width": {
           "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
           "dev": true,
           "requires": {
             "emoji-regex": "^8.0.0",
@@ -26570,6 +27412,8 @@
         },
         "strip-ansi": {
           "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+          "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
           "dev": true,
           "requires": {
             "ansi-regex": "^5.0.1"
@@ -26578,31 +27422,32 @@
       }
     },
     "tailwindcss": {
-      "version": "3.0.15",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.15.tgz",
-      "integrity": "sha512-bT2iy7FtjwgsXik4ZoJnHXR+SRCiGR1W95fVqpLZebr64m4ahwUwRbIAc5w5+2fzr1YF4Ct2eI7dojMRRl8sVQ==",
+      "version": "3.0.23",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.23.tgz",
+      "integrity": "sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA==",
       "dev": true,
       "requires": {
         "arg": "^5.0.1",
         "chalk": "^4.1.2",
-        "chokidar": "^3.5.2",
+        "chokidar": "^3.5.3",
         "color-name": "^1.1.4",
         "cosmiconfig": "^7.0.1",
         "detective": "^5.2.0",
         "didyoumean": "^1.2.2",
         "dlv": "^1.1.3",
-        "fast-glob": "^3.2.7",
+        "fast-glob": "^3.2.11",
         "glob-parent": "^6.0.2",
         "is-glob": "^4.0.3",
         "normalize-path": "^3.0.0",
         "object-hash": "^2.2.0",
+        "postcss": "^8.4.6",
         "postcss-js": "^4.0.0",
         "postcss-load-config": "^3.1.0",
         "postcss-nested": "5.0.6",
-        "postcss-selector-parser": "^6.0.8",
+        "postcss-selector-parser": "^6.0.9",
         "postcss-value-parser": "^4.2.0",
         "quick-lru": "^5.1.1",
-        "resolve": "^1.21.0"
+        "resolve": "^1.22.0"
       },
       "dependencies": {
         "color-name": {
@@ -26804,15 +27649,10 @@
     "typedarray": {
       "version": "0.0.6"
     },
-    "typedarray-to-buffer": {
-      "version": "3.1.5",
-      "dev": true,
-      "requires": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
     "typescript": {
-      "version": "4.5.4",
+      "version": "4.5.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
+      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
       "dev": true
     },
     "uglify-js": {
@@ -26921,15 +27761,15 @@
       }
     },
     "vite": {
-      "version": "2.7.13",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-2.7.13.tgz",
-      "integrity": "sha512-Mq8et7f3aK0SgSxjDNfOAimZGW9XryfHRa/uV0jseQSilg+KhYDSoNb9h1rknOy6SuMkvNDLKCYAYYUMCE+IgQ==",
+      "version": "2.8.4",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-2.8.4.tgz",
+      "integrity": "sha512-GwtOkkaT2LDI82uWZKcrpRQxP5tymLnC7hVHHqNkhFNknYr0hJUlDLfhVRgngJvAy3RwypkDCWtTKn1BjO96Dw==",
       "dev": true,
       "requires": {
-        "esbuild": "^0.13.12",
+        "esbuild": "^0.14.14",
         "fsevents": "~2.3.2",
-        "postcss": "^8.4.5",
-        "resolve": "^1.20.0",
+        "postcss": "^8.4.6",
+        "resolve": "^1.22.0",
         "rollup": "^2.59.0"
       }
     },
@@ -26963,9 +27803,9 @@
       }
     },
     "wavesurfer.js": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-5.2.0.tgz",
-      "integrity": "sha512-SkPlTXfvKy+ZnEA7f7g7jn6iQg5/8mAvWpVV5vRbIS/FF9TB2ak9J7VayQfzfshOLW/CqccTiN6DDR/fZA902g=="
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-6.0.2.tgz",
+      "integrity": "sha512-dd1ZwsgobELehtrzdKiQ9Im+m0F1Dbe39bJeo7ZQjkW8KTwdTNVg3ymURwif3pYsHo8ikKWjD5QDvIu/O0mRSA=="
     },
     "webidl-conversions": {
       "version": "6.1.0"
@@ -27025,28 +27865,28 @@
       "dev": true
     },
     "workbox-background-sync": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.4.2.tgz",
-      "integrity": "sha512-P7c8uG5X2k+DMICH9xeSA9eUlCOjHHYoB42Rq+RtUpuwBxUOflAXR1zdsMWj81LopE4gjKXlTw7BFd1BDAHo7g==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.0.tgz",
+      "integrity": "sha512-rrekt/gt6qOIZsisj6QZfmAFPAnocq1Z603zAjt+qHmeXY8DLPOklVtvrXSaHoHH3qIjUq3SQY5s2x240iTIKw==",
       "dev": true,
       "requires": {
         "idb": "^6.1.4",
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-broadcast-update": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.4.2.tgz",
-      "integrity": "sha512-qnBwQyE0+PWFFc/n4ISXINE49m44gbEreJUYt2ldGH3+CNrLmJ1egJOOyUqqu9R4Eb7QrXcmB34ClXG7S37LbA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.0.tgz",
+      "integrity": "sha512-JC97c7tYqoGWcCfbKO9KHG6lkU+WhXCnDB2j1oFWEiv53nUHy3yjPpzMmAGNLD9oV5lInO15n6V18HfwgkhISw==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-build": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.4.2.tgz",
-      "integrity": "sha512-WMdYLhDIsuzViOTXDH+tJ1GijkFp5khSYolnxR/11zmfhNDtuo7jof72xPGFy+KRpsz6tug39RhivCj77qqO0w==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.0.tgz",
+      "integrity": "sha512-da0/1b6//P9+ts7ofcIKcMVPyN6suJvjJASXokF7DsqvUmgRBPcCVV4KCy8QWjgfcz7mzuTpkSbdVHcPFJ/p0A==",
       "dev": true,
       "requires": {
         "@apideck/better-ajv-errors": "^0.3.1",
@@ -27067,26 +27907,25 @@
         "rollup": "^2.43.1",
         "rollup-plugin-terser": "^7.0.0",
         "source-map": "^0.8.0-beta.0",
-        "source-map-url": "^0.4.0",
         "stringify-object": "^3.3.0",
         "strip-comments": "^2.0.1",
         "tempy": "^0.6.0",
         "upath": "^1.2.0",
-        "workbox-background-sync": "6.4.2",
-        "workbox-broadcast-update": "6.4.2",
-        "workbox-cacheable-response": "6.4.2",
-        "workbox-core": "6.4.2",
-        "workbox-expiration": "6.4.2",
-        "workbox-google-analytics": "6.4.2",
-        "workbox-navigation-preload": "6.4.2",
-        "workbox-precaching": "6.4.2",
-        "workbox-range-requests": "6.4.2",
-        "workbox-recipes": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2",
-        "workbox-streams": "6.4.2",
-        "workbox-sw": "6.4.2",
-        "workbox-window": "6.4.2"
+        "workbox-background-sync": "6.5.0",
+        "workbox-broadcast-update": "6.5.0",
+        "workbox-cacheable-response": "6.5.0",
+        "workbox-core": "6.5.0",
+        "workbox-expiration": "6.5.0",
+        "workbox-google-analytics": "6.5.0",
+        "workbox-navigation-preload": "6.5.0",
+        "workbox-precaching": "6.5.0",
+        "workbox-range-requests": "6.5.0",
+        "workbox-recipes": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0",
+        "workbox-streams": "6.5.0",
+        "workbox-sw": "6.5.0",
+        "workbox-window": "6.5.0"
       },
       "dependencies": {
         "@apideck/better-ajv-errors": {
@@ -27202,127 +28041,127 @@
       }
     },
     "workbox-cacheable-response": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.4.2.tgz",
-      "integrity": "sha512-9FE1W/cKffk1AJzImxgEN0ceWpyz1tqNjZVtA3/LAvYL3AC5SbIkhc7ZCO82WmO9IjTfu8Vut2X/C7ViMSF7TA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.0.tgz",
+      "integrity": "sha512-sqAtWAiBwWvI8HG/2Do7BeKPhHuUczt22ORkAjkH9DfTq9LuWRFd6T4HAMqX5G8F1gM9XA2UPlxRrEeSpFIz/A==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-core": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.4.2.tgz",
-      "integrity": "sha512-1U6cdEYPcajRXiboSlpJx6U7TvhIKbxRRerfepAJu2hniKwJ3DHILjpU/zx3yvzSBCWcNJDoFalf7Vgd7ey/rw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.0.tgz",
+      "integrity": "sha512-5SPwNipUzYBhrneLVT02JFA0fw3LG82jFAN/G2NzxkIW10t4MVZuML2nU94bbkgjq25u0fkY8+4JXzMfHgxEWQ==",
       "dev": true
     },
     "workbox-expiration": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.4.2.tgz",
-      "integrity": "sha512-0hbpBj0tDnW+DZOUmwZqntB/8xrXOgO34i7s00Si/VlFJvvpRKg1leXdHHU8ykoSBd6+F2KDcMP3swoCi5guLw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.0.tgz",
+      "integrity": "sha512-y3WRkKRy/gMuZZNkrLFahjY0QZtLoq+QfhTbVAsOGHVg1CCtnNbeFAnEidQs7UisI2BK76VqQPvM7hEOFyZ92A==",
       "dev": true,
       "requires": {
         "idb": "^6.1.4",
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-google-analytics": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.4.2.tgz",
-      "integrity": "sha512-u+gxs3jXovPb1oul4CTBOb+T9fS1oZG+ZE6AzS7l40vnyfJV79DaLBvlpEZfXGv3CjMdV1sT/ltdOrKzo7HcGw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.0.tgz",
+      "integrity": "sha512-CHHh55wMNCc/BV1URrzEM2Zjgf6g2CV6QpAAc1pBRqaLY5755PeQZbp3o8KbJEM7YsC9mIBeQVsOkSKkGS30bg==",
       "dev": true,
       "requires": {
-        "workbox-background-sync": "6.4.2",
-        "workbox-core": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2"
+        "workbox-background-sync": "6.5.0",
+        "workbox-core": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0"
       }
     },
     "workbox-navigation-preload": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.4.2.tgz",
-      "integrity": "sha512-viyejlCtlKsbJCBHwhSBbWc57MwPXvUrc8P7d+87AxBGPU+JuWkT6nvBANgVgFz6FUhCvRC8aYt+B1helo166g==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.0.tgz",
+      "integrity": "sha512-ktrRQzXJ0zFy0puOtCa49wE3BSBGUB8KRMot3tEieikCkSO0wMLmiCb9GwTVvNMJLl0THRlsdFoI93si04nTxA==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-precaching": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.4.2.tgz",
-      "integrity": "sha512-CZ6uwFN/2wb4noHVlALL7UqPFbLfez/9S2GAzGAb0Sk876ul9ukRKPJJ6gtsxfE2HSTwqwuyNVa6xWyeyJ1XSA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.0.tgz",
+      "integrity": "sha512-IVLzgHx38T6LphJyEOltd7XAvpDi73p85uCT2ZtT1HHg9FAYC49a+5iHUVOnqye73fLW20eiAMFcnehGxz9RWg==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2"
+        "workbox-core": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0"
       }
     },
     "workbox-range-requests": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.4.2.tgz",
-      "integrity": "sha512-SowF3z69hr3Po/w7+xarWfzxJX/3Fo0uSG72Zg4g5FWWnHpq2zPvgbWerBZIa81zpJVUdYpMa3akJJsv+LaO1Q==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.0.tgz",
+      "integrity": "sha512-+qTELdGZE5rOjuv+ifFrfRDN8Uvzpbm5Fal7qSUqB1V1DLCMxPwHCj6mWwQBRKBpW7G09kAwewH7zA3Asjkf/Q==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-recipes": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.4.2.tgz",
-      "integrity": "sha512-/oVxlZFpAjFVbY+3PoGEXe8qyvtmqMrTdWhbOfbwokNFtUZ/JCtanDKgwDv9x3AebqGAoJRvQNSru0F4nG+gWA==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.0.tgz",
+      "integrity": "sha512-7hWZAIcXmvr31NwYSWaQIrnThCH/Dx9+eYv/YdkpUeWIXRiHRkYvP1FdiHItbLSjL4Y6K7cy2Y9y5lGCkgaE4w==",
       "dev": true,
       "requires": {
-        "workbox-cacheable-response": "6.4.2",
-        "workbox-core": "6.4.2",
-        "workbox-expiration": "6.4.2",
-        "workbox-precaching": "6.4.2",
-        "workbox-routing": "6.4.2",
-        "workbox-strategies": "6.4.2"
+        "workbox-cacheable-response": "6.5.0",
+        "workbox-core": "6.5.0",
+        "workbox-expiration": "6.5.0",
+        "workbox-precaching": "6.5.0",
+        "workbox-routing": "6.5.0",
+        "workbox-strategies": "6.5.0"
       }
     },
     "workbox-routing": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.4.2.tgz",
-      "integrity": "sha512-0ss/n9PAcHjTy4Ad7l2puuod4WtsnRYu9BrmHcu6Dk4PgWeJo1t5VnGufPxNtcuyPGQ3OdnMdlmhMJ57sSrrSw==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.0.tgz",
+      "integrity": "sha512-w1A9OVa/yYStu9ds0Dj+TC6zOAoskKlczf+wZI5mrM9nFCt/KOMQiFp1/41DMFPrrN/8KlZTS3Cel/Ttutw93Q==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-strategies": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.4.2.tgz",
-      "integrity": "sha512-YXh9E9dZGEO1EiPC3jPe2CbztO5WT8Ruj8wiYZM56XqEJp5YlGTtqRjghV+JovWOqkWdR+amJpV31KPWQUvn1Q==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.0.tgz",
+      "integrity": "sha512-Ngnwo+tfGw4uKSlTz3h1fYKb/lCV7SDI/dtTb8VaJzRl0N9XssloDGYERBmF6BN/DV/x3bnRsshfobnKI/3z0g==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "workbox-streams": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.4.2.tgz",
-      "integrity": "sha512-ROEGlZHGVEgpa5bOZefiJEVsi5PsFjJG9Xd+wnDbApsCO9xq9rYFopF+IRq9tChyYzhBnyk2hJxbQVWphz3sog==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.0.tgz",
+      "integrity": "sha512-ZbeaZINkju4x45P9DFyRbOYInE+dyNAJIelflz4f9AOAdm+zZUJCooU4MdfsedVhHiTIA6pCD/3jCmW1XbvlbA==",
       "dev": true,
       "requires": {
-        "workbox-core": "6.4.2",
-        "workbox-routing": "6.4.2"
+        "workbox-core": "6.5.0",
+        "workbox-routing": "6.5.0"
       }
     },
     "workbox-sw": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.4.2.tgz",
-      "integrity": "sha512-A2qdu9TLktfIM5NE/8+yYwfWu+JgDaCkbo5ikrky2c7r9v2X6DcJ+zSLphNHHLwM/0eVk5XVf1mC5HGhYpMhhg==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.0.tgz",
+      "integrity": "sha512-uPGJ9Yost4yabnCko/IuhouquoQKrWOEqLq7L/xVYtltWe4+J8Hw8iPCVtxvXQ26hffd7MaFWUAN83j2ZWbxRg==",
       "dev": true
     },
     "workbox-window": {
-      "version": "6.4.2",
-      "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.4.2.tgz",
-      "integrity": "sha512-KVyRKmrJg7iB+uym/B/CnEUEFG9CvnTU1Bq5xpXHbtgD9l+ShDekSl1wYpqw/O0JfeeQVOFb8CiNfvnwWwqnWQ==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.0.tgz",
+      "integrity": "sha512-DOrhiTnWup/CsNstO2uvfdKM4kdStgHd31xGGvBcoCE3Are3DRcy5s3zz3PedcAR1AKskQj3BXz0UhzQiOq8nA==",
       "dev": true,
       "requires": {
         "@types/trusted-types": "^2.0.2",
-        "workbox-core": "6.4.2"
+        "workbox-core": "6.5.0"
       }
     },
     "wrap-ansi": {
@@ -27383,13 +28222,13 @@
       "dev": true
     },
     "write-file-atomic": {
-      "version": "3.0.3",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz",
+      "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==",
       "dev": true,
       "requires": {
         "imurmurhash": "^0.1.4",
-        "is-typedarray": "^1.0.0",
-        "signal-exit": "^3.0.2",
-        "typedarray-to-buffer": "^3.1.5"
+        "signal-exit": "^3.0.7"
       }
     },
     "ws": {
@@ -27417,9 +28256,9 @@
       }
     },
     "xml-formatter": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.0.tgz",
-      "integrity": "sha512-+bQeoiE5W3CJdDCHTlveYSWFfQWnYB3uHGeRJ6LlEsL5kT++mWy9iN1cMeEDfBbgOnXO2DNUbmQ6elkR/mCcjg==",
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz",
+      "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==",
       "requires": {
         "xml-parser-xo": "^3.2.0"
       }
diff --git a/package.json b/package.json
index 10891f1a67..28323e6c9b 100644
--- a/package.json
+++ b/package.json
@@ -27,71 +27,71 @@
     "prepare": "is-ci || husky install"
   },
   "dependencies": {
-    "@amcharts/amcharts4": "^4.10.23",
+    "@amcharts/amcharts4": "^4.10.24",
     "@amcharts/amcharts4-geodata": "^4.1.22",
     "@codemirror/basic-setup": "^0.19.1",
-    "@codemirror/commands": "^0.19.7",
+    "@codemirror/commands": "^0.19.8",
     "@codemirror/lang-xml": "^0.19.2",
-    "@codemirror/state": "^0.19.6",
-    "@codemirror/view": "^0.19.39",
-    "@floating-ui/dom": "^0.1.10",
+    "@codemirror/state": "^0.19.9",
+    "@codemirror/view": "^0.19.45",
+    "@floating-ui/dom": "^0.3.1",
     "@github/clipboard-copy-element": "^1.1.2",
-    "@github/hotkey": "^1.6.1",
+    "@github/hotkey": "^2.0.0",
     "@github/markdown-toolbar-element": "^2.1.0",
     "@github/time-elements": "^3.1.2",
     "@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
     "@vime/core": "^5.3.1",
-    "choices.js": "^10.0.0",
+    "choices.js": "^10.1.0",
     "flatpickr": "^4.6.9",
     "leaflet": "^1.7.1",
     "leaflet.markercluster": "^1.5.3",
-    "lit": "^2.1.1",
-    "marked": "^4.0.10",
-    "wavesurfer.js": "^5.2.0",
-    "xml-formatter": "^2.6.0"
+    "lit": "^2.2.0",
+    "marked": "^4.0.12",
+    "wavesurfer.js": "^6.0.2",
+    "xml-formatter": "^2.6.1"
   },
   "devDependencies": {
-    "@commitlint/cli": "^16.0.2",
-    "@commitlint/config-conventional": "^16.0.0",
+    "@commitlint/cli": "^16.2.1",
+    "@commitlint/config-conventional": "^16.2.1",
     "@semantic-release/changelog": "^6.0.1",
     "@semantic-release/exec": "^6.0.3",
     "@semantic-release/git": "^10.0.1",
     "@semantic-release/gitlab": "^7.0.4",
     "@tailwindcss/forms": "^0.4.0-alpha.2",
     "@tailwindcss/line-clamp": "^0.3.1",
-    "@tailwindcss/typography": "^0.5.0",
-    "@types/leaflet": "^1.7.8",
-    "@types/marked": "^4.0.1",
-    "@types/wavesurfer.js": "^5.2.2",
-    "@typescript-eslint/eslint-plugin": "^5.10.0",
-    "@typescript-eslint/parser": "^5.10.0",
+    "@tailwindcss/typography": "^0.5.2",
+    "@types/leaflet": "^1.7.9",
+    "@types/marked": "^4.0.2",
+    "@types/wavesurfer.js": "^6.0.1",
+    "@typescript-eslint/eslint-plugin": "^5.12.1",
+    "@typescript-eslint/parser": "^5.12.1",
     "cross-env": "^7.0.3",
-    "cssnano": "^5.0.15",
+    "cssnano": "^5.0.17",
     "cz-conventional-changelog": "^3.3.0",
-    "eslint": "^8.7.0",
-    "eslint-config-prettier": "^8.3.0",
+    "eslint": "^8.10.0",
+    "eslint-config-prettier": "^8.4.0",
     "eslint-plugin-prettier": "^4.0.0",
     "husky": "^7.0.4",
     "is-ci": "^3.0.1",
-    "lint-staged": "^12.2.0",
+    "lint-staged": "^12.3.4",
     "postcss-import": "^14.0.2",
     "postcss-nesting": "^10.1.2",
-    "postcss-preset-env": "^7.2.3",
+    "postcss-preset-env": "^7.4.1",
     "postcss-reporter": "^7.0.5",
     "prettier": "2.5.1",
     "prettier-plugin-organize-imports": "^2.3.4",
     "semantic-release": "^19.0.2",
-    "stylelint": "^14.2.0",
-    "stylelint-config-standard": "^24.0.0",
+    "stylelint": "^14.5.3",
+    "stylelint-config-standard": "^25.0.0",
     "svgo": "^2.8.0",
-    "tailwindcss": "^3.0.15",
-    "typescript": "^4.5.4",
-    "vite": "^2.7.13",
+    "tailwindcss": "^3.0.23",
+    "typescript": "^4.5.5",
+    "vite": "^2.8.4",
     "vite-plugin-pwa": "^0.11.13",
-    "workbox-build": "^6.4.2",
-    "workbox-core": "^6.4.2",
-    "workbox-routing": "^6.4.2",
-    "workbox-strategies": "^6.4.2"
+    "workbox-build": "^6.5.0",
+    "workbox-core": "^6.5.0",
+    "workbox-routing": "^6.5.0",
+    "workbox-strategies": "^6.5.0"
   },
   "lint-staged": {
     "*.{js,ts,css,md,json}": "prettier --write",
diff --git a/phpstan.neon b/phpstan.neon
index 88db3cf6a5..c32c499c4a 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -5,35 +5,22 @@ parameters:
         - app
         - tests
     bootstrapFiles:
-        - vendor/codeigniter4/codeigniter4/system/Test/bootstrap.php
+        - vendor/codeigniter4/framework/system/Test/bootstrap.php
     scanDirectories:
         - app/Helpers
         - modules/Analytics/Helpers
         - modules/Fediverse/Helpers
-        - vendor/codeigniter4/codeigniter4/system/Helpers
+        - vendor/codeigniter4/framework/system/Helpers
         - vendor/myth/auth/src/Helpers
-    excludes_analyse:
+    excludePaths:
         - app/Libraries/Router.php
         - app/Views/*
         - modules/*/Views/*
         - themes/*
     ignoreErrors:
-        - '#This property type might be inlined to PHP. Do you have confidence it is correct\? Put it here#'
-        - '#^Cognitive complexity for#'
-        - '#^Class cognitive complexity#'
-        - '#Do not use chained method calls. Put each on separated lines.#'
-        - '#Do not inherit from abstract class, better use composition#'
         - '#Cannot access property [\$a-z_]+ on ((array\|)?object)#'
         - '#^Call to an undefined method CodeIgniter\\Database\\BaseBuilder#'
         - '#^Call to an undefined method CodeIgniter\\Database\\ConnectionInterface#'
-        - '#Function \"preg_.*\(\)\" cannot be used/left in the code#'
-        - '#Function "property_exists\(\)" cannot be used/left in the code#'
-        - '#Instead of "instanceof/is_a\(\)" use ReflectionProvider service or "\(new ObjectType\(<desired_type\>\)\)\-\>isSuperTypeOf\(<element_type\>\)" for static reflection to work#'
+        - '#^Call to an undefined method CodeIgniter\\Model#'
         - '#^Access to an undefined property App\\Entities\\Media\\Image#'
-        - '#^Access to an undefined property CodeIgniter\\Database\\BaseBuilder#'
-        -
-            message: '#Function "function_exists\(\)" cannot be used/left in the code#'
-            paths:
-                - app/Helpers
-                - app/Common.php
-                - app/Libraries/ViewComponents/Helpers
+        - '#^Access to an undefined property CodeIgniter\\Database\\BaseBuilder#'
\ No newline at end of file
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 8040502639..c05e50146f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-		bootstrap="vendor/codeigniter4/codeigniter4/system/Test/bootstrap.php"
+		bootstrap="vendor/codeigniter4/framework/system/Test/bootstrap.php"
 		backupGlobals="false"
 		colors="true"
 		convertErrorsToExceptions="true"
diff --git a/rector.php b/rector.php
index c173dbd552..8041d3c1cf 100644
--- a/rector.php
+++ b/rector.php
@@ -2,12 +2,11 @@
 
 declare(strict_types=1);
 
+use Rector\CodeQuality\Rector\PropertyFetch\ExplicitMethodCallOverMagicGetSetRector;
 use Rector\CodingStyle\Rector\ClassMethod\UnSpreadOperatorRector;
 use Rector\CodingStyle\Rector\Encapsed\EncapsedStringsToSprintfRector;
-use Rector\CodingStyle\Rector\FuncCall\CallUserFuncArrayToVariadicRector;
 use Rector\CodingStyle\Rector\FuncCall\ConsistentPregDelimiterRector;
-use Rector\CodingStyle\Rector\FuncCall\VersionCompareFuncCallToConstantRector;
-use Rector\CodingStyle\Rector\String_\SplitStringClassConstantToClassConstFetchRector;
+use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
 use Rector\Core\Configuration\Option;
 use Rector\Core\ValueObject\PhpVersion;
 use Rector\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector;
@@ -15,7 +14,6 @@ use Rector\EarlyReturn\Rector\If_\ChangeOrIfReturnToEarlyReturnRector;
 use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
 use Rector\Php80\Rector\ClassMethod\OptionalParametersAfterRequiredRector;
 use Rector\Set\ValueObject\SetList;
-use Rector\Transform\Rector\FuncCall\FuncCallToConstFetchRector;
 use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
 
 return static function (ContainerConfigurator $containerConfigurator): void {
@@ -24,14 +22,14 @@ return static function (ContainerConfigurator $containerConfigurator): void {
 
     $parameters->set(Option::PATHS, [
         __DIR__ . '/app',
-        __DIR__ . '/modules',
-        __DIR__ . '/tests',
-        __DIR__ . '/public',
+        // __DIR__ . '/modules',
+        // __DIR__ . '/tests',
+        // __DIR__ . '/public',
     ]);
 
     // do you need to include constants, class aliases or custom autoloader? files listed will be executed
     $parameters->set(Option::BOOTSTRAP_FILES, [
-        __DIR__ . '/vendor/codeigniter4/codeigniter4/system/Test/bootstrap.php',
+        __DIR__ . '/vendor/codeigniter4/framework/system/Test/bootstrap.php',
     ]);
 
     // Define what rule sets will be applied
@@ -46,10 +44,13 @@ return static function (ContainerConfigurator $containerConfigurator): void {
 
     // auto import fully qualified class names
     $parameters->set(Option::AUTO_IMPORT_NAMES, true);
-    // $parameters->set(Option::ENABLE_CACHE, true);
+    // TODO: add parallel
+    // $parameters->set(Option::PARALLEL, true);
     $parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_80);
 
     $parameters->set(Option::SKIP, [
+        __DIR__ . '/app/Views/errors/*',
+
         // skip specific generated files
         __DIR__ . '/modules/Admin/Language/*/PersonsTaxonomy.php',
 
@@ -57,8 +58,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
         ChangeOrIfReturnToEarlyReturnRector::class,
         ChangeOrIfContinueToMultiContinueRector::class,
         EncapsedStringsToSprintfRector::class,
-        SplitStringClassConstantToClassConstFetchRector::class,
         UnSpreadOperatorRector::class,
+        ExplicitMethodCallOverMagicGetSetRector::class,
 
         // skip rule in specific directory
         StringClassNameToClassConstantRector::class => [
@@ -68,6 +69,10 @@ return static function (ContainerConfigurator $containerConfigurator): void {
         OptionalParametersAfterRequiredRector::class => [
             __DIR__ . '/app/Validation',
         ],
+
+        NewlineAfterStatementRector::class => [
+            __DIR__ . '/app/Views',
+        ]
     ]);
 
     // Path to phpstan with extensions, that PHPStan in Rector uses to determine types
diff --git a/tests/_support/Libraries/ConfigReader.php b/tests/_support/Libraries/ConfigReader.php
index b6b85d4536..19a02db0e9 100644
--- a/tests/_support/Libraries/ConfigReader.php
+++ b/tests/_support/Libraries/ConfigReader.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
- * @package    CodeIgniter
- * @author     CodeIgniter Dev Team
  * @copyright  2019-2020 CodeIgniter Foundation
  * @license    https://opensource.org/licenses/MIT	MIT License
  * @link       https://codeigniter.com
diff --git a/themes/cp_admin/episode/video_clips_new.php b/themes/cp_admin/episode/video_clips_new.php
index 8819a41f6f..7b7f2839d0 100644
--- a/themes/cp_admin/episode/video_clips_new.php
+++ b/themes/cp_admin/episode/video_clips_new.php
@@ -11,6 +11,7 @@
 <?= $this->section('content') ?>
 
 <form id="new-video-clip-form" action="<?= route_to('video-clips-create', $podcast->id, $episode->id) ?>" method="POST" class="flex flex-col items-center gap-4 xl:items-start xl:flex-row">
+<?= csrf_field() ?>
 
 <div class="flex-1 w-full rounded-xl border-3 border-subtle">
     <video-clip-previewer duration="<?= old('duration', 30) ?>">
-- 
GitLab


From 47a927d3d7875be06447f0388a1b5787eed9e55e Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Wed, 2 Mar 2022 16:16:02 +0000
Subject: [PATCH 5/7] fix(security): escape user input to prevent XSS attacks

---
 app/Controllers/MapController.php             |  6 +-
 app/Controllers/PostController.php            |  2 +-
 app/Controllers/WebmanifestController.php     | 12 ++--
 app/Entities/Episode.php                      | 10 ++-
 app/Helpers/breadcrumb_helper.php             |  2 +-
 app/Helpers/components_helper.php             |  4 +-
 app/Helpers/id3_helper.php                    |  8 +--
 app/Helpers/page_helper.php                   |  2 +-
 app/Helpers/rss_helper.php                    | 28 ++------
 app/Helpers/seo_helper.php                    | 64 ++++++++++---------
 app/Libraries/CommentObject.php               |  2 +-
 app/Libraries/PodcastActor.php                |  2 +-
 app/Libraries/PodcastEpisode.php              |  2 +-
 app/Models/EpisodeCommentModel.php            | 11 +++-
 app/Models/EpisodeModel.php                   |  4 +-
 app/Models/LikeModel.php                      |  6 +-
 app/Models/PodcastModel.php                   |  2 +-
 app/Views/_message_block.php                  | 23 +++----
 .../Controllers/ContributorController.php     |  1 +
 modules/Admin/Language/en/Fediverse.php       |  1 +
 modules/Admin/Language/fr/Fediverse.php       |  1 +
 .../Fediverse/Controllers/BlockController.php | 11 ++--
 .../Controllers/NodeInfo2Controller.php       |  3 +-
 .../Fediverse/Helpers/fediverse_helper.php    |  2 +-
 modules/Fediverse/Models/FavouriteModel.php   |  6 +-
 modules/Fediverse/Models/FollowModel.php      |  4 +-
 modules/Fediverse/Models/PostModel.php        | 10 +--
 modules/Fediverse/Objects/NoteObject.php      |  2 +-
 tests/unit/HealthTest.php                     |  4 +-
 themes/cp_admin/_message_block.php            |  9 ++-
 themes/cp_admin/_partials/_nav_header.php     |  5 +-
 themes/cp_admin/_partials/_user_info.php      |  2 +-
 themes/cp_admin/contributor/add.php           |  4 +-
 themes/cp_admin/contributor/edit.php          |  4 +-
 themes/cp_admin/contributor/list.php          |  2 +-
 themes/cp_admin/contributor/view.php          | 16 +++--
 themes/cp_admin/episode/_card.php             |  6 +-
 themes/cp_admin/episode/_sidebar.php          | 12 ++--
 themes/cp_admin/episode/create.php            |  2 +-
 themes/cp_admin/episode/edit.php              | 12 ++--
 themes/cp_admin/episode/list.php              |  6 +-
 themes/cp_admin/episode/persons.php           |  8 +--
 themes/cp_admin/episode/publish.php           | 10 +--
 themes/cp_admin/episode/publish_edit.php      | 10 +--
 themes/cp_admin/episode/soundbites_list.php   |  2 +-
 themes/cp_admin/episode/video_clip.php        |  6 +-
 themes/cp_admin/episode/video_clips_list.php  |  2 +-
 themes/cp_admin/episode/view.php              |  4 +-
 themes/cp_admin/fediverse/blocked_actors.php  |  4 +-
 themes/cp_admin/fediverse/blocked_domains.php |  6 +-
 themes/cp_admin/page/edit.php                 |  4 +-
 themes/cp_admin/page/list.php                 |  6 +-
 themes/cp_admin/page/view.php                 |  4 +-
 themes/cp_admin/person/_card.php              |  4 +-
 themes/cp_admin/person/edit.php               |  6 +-
 themes/cp_admin/person/view.php               | 10 +--
 themes/cp_admin/podcast/_card.php             |  6 +-
 themes/cp_admin/podcast/_sidebar.php          |  8 +--
 themes/cp_admin/podcast/analytics/index.php   |  4 +-
 .../podcast/analytics/listening_time.php      |  4 +-
 .../cp_admin/podcast/analytics/locations.php  |  4 +-
 themes/cp_admin/podcast/analytics/players.php |  4 +-
 .../podcast/analytics/time_periods.php        |  4 +-
 .../podcast/analytics/unique_listeners.php    |  4 +-
 .../cp_admin/podcast/analytics/webpages.php   |  4 +-
 themes/cp_admin/podcast/edit.php              | 28 ++++----
 themes/cp_admin/podcast/persons.php           |  8 +--
 themes/cp_admin/podcast/platforms.php         | 20 +++---
 themes/cp_admin/podcast/view.php              |  4 +-
 themes/cp_admin/settings/general.php          | 10 +--
 themes/cp_admin/user/edit.php                 |  4 +-
 themes/cp_admin/user/list.php                 |  4 +-
 themes/cp_admin/user/view.php                 |  2 +-
 themes/cp_app/_admin_navbar.php               |  5 +-
 themes/cp_app/_persons_modal.php              |  6 +-
 themes/cp_app/embed.php                       |  8 +--
 themes/cp_app/episode/_layout.php             | 41 ++++++------
 themes/cp_app/episode/_partials/card.php      |  8 +--
 themes/cp_app/episode/_partials/comment.php   | 12 ++--
 .../episode/_partials/comment_actions.php     |  8 +--
 .../_partials/comment_actions_from_post.php   | 10 +--
 .../cp_app/episode/_partials/comment_card.php | 12 ++--
 .../episode/_partials/comment_reply.php       | 12 ++--
 .../_partials/comment_reply_actions.php       |  6 +-
 .../_partials/comment_with_replies.php        |  6 +-
 .../cp_app/episode/_partials/navigation.php   |  4 +-
 .../cp_app/episode/_partials/preview_card.php |  8 +--
 themes/cp_app/episode/activity.php            |  6 +-
 themes/cp_app/episode/comment.php             |  2 +-
 themes/cp_app/episode/comments.php            |  4 +-
 themes/cp_app/home.php                        | 10 +--
 themes/cp_app/pages/_layout.php               |  2 +-
 themes/cp_app/pages/credits.php               | 16 ++---
 themes/cp_app/pages/map.php                   |  6 +-
 themes/cp_app/podcast/_layout.php             |  8 +--
 .../podcast/_partials/funding_links_modal.php | 10 +--
 .../cp_app/podcast/_partials/navigation.php   |  6 +-
 themes/cp_app/podcast/_partials/sidebar.php   | 16 ++---
 themes/cp_app/podcast/about.php               |  6 +-
 themes/cp_app/podcast/activity.php            |  6 +-
 themes/cp_app/podcast/follow.php              | 10 +--
 themes/cp_app/post/_partials/actions.php      | 26 ++++----
 themes/cp_app/post/_partials/card.php         | 14 ++--
 .../post/_partials/post_with_replies.php      | 12 ++--
 themes/cp_app/post/_partials/preview_card.php | 19 +++---
 themes/cp_app/post/_partials/reblog.php       | 14 ++--
 themes/cp_app/post/_partials/reply.php        | 12 ++--
 .../cp_app/post/_partials/reply_actions.php   | 26 ++++----
 themes/cp_app/post/post.php                   |  4 +-
 themes/cp_app/post/remote_action.php          |  2 +-
 themes/cp_auth/_message_block.php             |  9 ++-
 themes/cp_install/_message_block.php          | 11 ++--
 112 files changed, 458 insertions(+), 468 deletions(-)

diff --git a/app/Controllers/MapController.php b/app/Controllers/MapController.php
index a0a390b2fe..79fa7d5261 100644
--- a/app/Controllers/MapController.php
+++ b/app/Controllers/MapController.php
@@ -51,13 +51,13 @@ class MapController extends BaseController
                 $found[] = [
                     'latitude' => $episode->location->latitude,
                     'longitude' => $episode->location->longitude,
-                    'location_name' => $episode->location->name,
+                    'location_name' => esc($episode->location->name),
                     'location_url' => $episode->location->url,
                     'episode_link' => $episode->link,
                     'podcast_link' => $episode->podcast->link,
                     'cover_url' => $episode->cover->thumbnail_url,
-                    'podcast_title' => $episode->podcast->title,
-                    'episode_title' => $episode->title,
+                    'podcast_title' => esc($episode->podcast->title),
+                    'episode_title' => esc($episode->title),
                 ];
             }
 
diff --git a/app/Controllers/PostController.php b/app/Controllers/PostController.php
index 0104015e3a..78510e23a2 100644
--- a/app/Controllers/PostController.php
+++ b/app/Controllers/PostController.php
@@ -111,7 +111,7 @@ class PostController extends FediversePostController
     {
         $rules = [
             'message' => 'required|max_length[500]',
-            'episode_url' => 'valid_url|permit_empty',
+            'episode_url' => 'valid_url_strict|permit_empty',
         ];
 
         if (! $this->validate($rules)) {
diff --git a/app/Controllers/WebmanifestController.php b/app/Controllers/WebmanifestController.php
index 5ac61f929f..8a1bd83eb0 100644
--- a/app/Controllers/WebmanifestController.php
+++ b/app/Controllers/WebmanifestController.php
@@ -50,10 +50,8 @@ class WebmanifestController extends Controller
     public function index(): ResponseInterface
     {
         $webmanifest = [
-            'name' => service('settings')
-                ->get('App.siteName'),
-            'description' => service('settings')
-                ->get('App.siteDescription'),
+            'name' => esc(service('settings') ->get('App.siteName')),
+            'description' => esc(service('settings') ->get('App.siteDescription')),
             'lang' => service('request')
                 ->getLocale(),
             'start_url' => base_url(),
@@ -89,12 +87,12 @@ class WebmanifestController extends Controller
         }
 
         $webmanifest = [
-            'name' => $podcast->title,
-            'short_name' => '@' . $podcast->handle,
+            'name' => esc($podcast->title),
+            'short_name' => '@' . esc($podcast->handle),
             'description' => $podcast->description,
             'lang' => $podcast->language_code,
             'start_url' => $podcast->link,
-            'scope' => '/@' . $podcast->handle,
+            'scope' => '/@' . esc($podcast->handle),
             'display' => 'standalone',
             'orientation' => 'portrait',
             'theme_color' => self::THEME_COLORS[service('settings')->get('App.theme')]['theme'],
diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index 3dceb5b5f8..87a3d71761 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -453,16 +453,14 @@ class Episode extends Entity
 
     public function getLink(): string
     {
-        return url_to('episode', $this->getPodcast()->handle, $this->attributes['slug']);
+        return url_to('episode', esc($this->getPodcast()->handle), esc($this->attributes['slug']));
     }
 
     public function getEmbedUrl(string $theme = null): string
     {
-        return base_url(
-            $theme
-                ? route_to('embed-theme', $this->getPodcast() ->handle, $this->attributes['slug'], $theme,)
-                : route_to('embed', $this->getPodcast()->handle, $this->attributes['slug']),
-        );
+        return $theme
+                ? url_to('embed-theme', esc($this->getPodcast()->handle), esc($this->attributes['slug']), $theme,)
+                : url_to('embed', esc($this->getPodcast()->handle), esc($this->attributes['slug']));
     }
 
     public function setGuid(?string $guid = null): static
diff --git a/app/Helpers/breadcrumb_helper.php b/app/Helpers/breadcrumb_helper.php
index 718f831009..bb3187ae0d 100644
--- a/app/Helpers/breadcrumb_helper.php
+++ b/app/Helpers/breadcrumb_helper.php
@@ -31,6 +31,6 @@ if (! function_exists('replace_breadcrumb_params')) {
     function replace_breadcrumb_params(array $newParams): void
     {
         $breadcrumb = Services::breadcrumb();
-        $breadcrumb->replaceParams($newParams);
+        $breadcrumb->replaceParams(esc($newParams));
     }
 }
diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php
index f17c71944b..0c27ab9aa8 100644
--- a/app/Helpers/components_helper.php
+++ b/app/Helpers/components_helper.php
@@ -243,10 +243,10 @@ if (! function_exists('location_link')) {
 
         return anchor(
             $location->url,
-            icon('map-pin', 'mr-2') . $location->name,
+            icon('map-pin', 'mr-2 flex-shrink-0') . '<span class="truncate">' . esc($location->name) . '</span>',
             [
                 'class' =>
-                    'inline-flex items-baseline hover:underline focus:ring-accent' .
+                    'w-full overflow-hidden inline-flex items-baseline hover:underline focus:ring-accent' .
                     ($class === '' ? '' : " {$class}"),
                 'target' => '_blank',
                 'rel' => 'noreferrer noopener',
diff --git a/app/Helpers/id3_helper.php b/app/Helpers/id3_helper.php
index 1d8b107e01..e8051c9b2d 100644
--- a/app/Helpers/id3_helper.php
+++ b/app/Helpers/id3_helper.php
@@ -38,13 +38,13 @@ if (! function_exists('write_audio_file_tags')) {
 
         // populate data array
         $TagData = [
-            'title' => [$episode->title],
+            'title' => [esc($episode->title)],
             'artist' => [
                 $episode->podcast->publisher === null
-                    ? $episode->podcast->owner_name
+                    ? esc($episode->podcast->owner_name)
                     : $episode->podcast->publisher,
             ],
-            'album' => [$episode->podcast->title],
+            'album' => [esc($episode->podcast->title)],
             'year' => [$episode->published_at !== null ? $episode->published_at->format('Y') : ''],
             'genre' => ['Podcast'],
             'comment' => [$episode->description],
@@ -52,7 +52,7 @@ if (! function_exists('write_audio_file_tags')) {
             'copyright_message' => [$episode->podcast->copyright],
             'publisher' => [
                 $episode->podcast->publisher === null
-                    ? $episode->podcast->owner_name
+                    ? esc($episode->podcast->owner_name)
                     : $episode->podcast->publisher,
             ],
             'encoded_by' => ['Castopod'],
diff --git a/app/Helpers/page_helper.php b/app/Helpers/page_helper.php
index 41f082063e..b0c20929cb 100644
--- a/app/Helpers/page_helper.php
+++ b/app/Helpers/page_helper.php
@@ -29,7 +29,7 @@ if (! function_exists('render_page_links')) {
             'class' => 'px-2 py-1 underline hover:no-underline focus:ring-accent',
         ]);
         foreach ($pages as $page) {
-            $links .= anchor($page->link, $page->title, [
+            $links .= anchor($page->link, esc($page->title), [
                 'class' => 'px-2  py-1 underline hover:no-underline focus:ring-accent',
             ]);
         }
diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php
index 6359256b44..43e866c5f9 100644
--- a/app/Helpers/rss_helper.php
+++ b/app/Helpers/rss_helper.php
@@ -60,11 +60,7 @@ if (! function_exists('get_rss_feed')) {
 
         $channel->addChild('language', $podcast->language_code);
         if ($podcast->location !== null) {
-            $locationElement = $channel->addChild(
-                'location',
-                htmlspecialchars($podcast->location->name),
-                $podcastNamespace,
-            );
+            $locationElement = $channel->addChild('location', $podcast->location->name, $podcastNamespace);
             if ($podcast->location->geo !== null) {
                 $locationElement->addAttribute('geo', $podcast->location->geo);
             }
@@ -101,7 +97,7 @@ if (! function_exists('get_rss_feed')) {
             }
 
             if ($podcastingPlatform->link_url !== null) {
-                $podcastingPlatformElement->addAttribute('url', htmlspecialchars($podcastingPlatform->link_url));
+                $podcastingPlatformElement->addAttribute('url', $podcastingPlatform->link_url);
             }
         }
 
@@ -183,17 +179,13 @@ if (! function_exists('get_rss_feed')) {
             );
             $fundingPlatformElement->addAttribute('platform', $fundingPlatform->slug);
             if ($fundingPlatform->link_url !== null) {
-                $fundingPlatformElement->addAttribute('url', htmlspecialchars($fundingPlatform->link_url));
+                $fundingPlatformElement->addAttribute('url', $fundingPlatform->link_url);
             }
         }
 
         foreach ($podcast->persons as $person) {
             foreach ($person->roles as $role) {
-                $personElement = $channel->addChild(
-                    'person',
-                    htmlspecialchars($person->full_name),
-                    $podcastNamespace,
-                );
+                $personElement = $channel->addChild('person', $person->full_name, $podcastNamespace,);
 
                 $personElement->addAttribute('img', $person->avatar->medium_url);
 
@@ -203,14 +195,12 @@ if (! function_exists('get_rss_feed')) {
 
                 $personElement->addAttribute(
                     'role',
-                    htmlspecialchars(
-                        lang("PersonsTaxonomy.persons.{$role->group}.roles.{$role->role}.label", [], 'en'),
-                    ),
+                    lang("PersonsTaxonomy.persons.{$role->group}.roles.{$role->role}.label", [], 'en'),
                 );
 
                 $personElement->addAttribute(
                     'group',
-                    htmlspecialchars(lang("PersonsTaxonomy.persons.{$role->group}.label", [], 'en')),
+                    lang("PersonsTaxonomy.persons.{$role->group}.label", [], 'en'),
                 );
             }
         }
@@ -280,11 +270,7 @@ if (! function_exists('get_rss_feed')) {
             $item->addChild('guid', $episode->guid);
             $item->addChild('pubDate', $episode->published_at->format(DATE_RFC1123));
             if ($episode->location !== null) {
-                $locationElement = $item->addChild(
-                    'location',
-                    htmlspecialchars($episode->location->name),
-                    $podcastNamespace,
-                );
+                $locationElement = $item->addChild('location', $episode->location->name, $podcastNamespace,);
                 if ($episode->location->geo !== null) {
                     $locationElement->addAttribute('geo', $episode->location->geo);
                 }
diff --git a/app/Helpers/seo_helper.php b/app/Helpers/seo_helper.php
index 436c64d426..284af09398 100644
--- a/app/Helpers/seo_helper.php
+++ b/app/Helpers/seo_helper.php
@@ -30,8 +30,8 @@ if (! function_exists('get_podcast_metatags')) {
 
         $schema = new Schema(
             new Thing('PodcastSeries', [
-                'name' => $podcast->title,
-                'headline' => $podcast->title,
+                'name' => esc($podcast->title),
+                'headline' => esc($podcast->title),
                 'url' => current_url(),
                 'sameAs' => $podcast->link,
                 'identifier' => $podcast->guid,
@@ -39,8 +39,8 @@ if (! function_exists('get_podcast_metatags')) {
                 'description' => $podcast->description,
                 'webFeed' => $podcast->feed_url,
                 'accessMode' => 'auditory',
-                'author' => $podcast->owner_name,
-                'creator' => $podcast->owner_name,
+                'author' => esc($podcast->owner_name),
+                'creator' => esc($podcast->owner_name),
                 'publisher' => $podcast->publisher,
                 'inLanguage' => $podcast->language_code,
                 'genre' => $category,
@@ -50,25 +50,27 @@ if (! function_exists('get_podcast_metatags')) {
         $metatags = new MetaTags();
 
         $metatags
-            ->title('  ' . $podcast->title . " (@{$podcast->handle})" . ' • ' . lang('Podcast.' . $page))
+            ->title(esc($podcast->title) . ' (@' . esc($podcast->handle) . ') • ' . lang('Podcast.' . $page))
             ->description(htmlspecialchars($podcast->description))
             ->image((string) $podcast->cover->og_url)
             ->canonical((string) current_url())
             ->og('image:width', (string) config('Images')->podcastCoverSizes['og']['width'])
             ->og('image:height', (string) config('Images')->podcastCoverSizes['og']['height'])
             ->og('locale', $podcast->language_code)
-            ->og('site_name', service('settings')->get('App.siteName'))
+            ->og('site_name', esc(service('settings')->get('App.siteName')))
             ->push('link', [
                 'rel' => 'alternate',
                 'type' => 'application/activity+json',
-                'href' => url_to('podcast-activity', $podcast->handle),
+                'href' => url_to('podcast-activity', esc($podcast->handle)),
             ]);
 
         if ($podcast->payment_pointer) {
             $metatags->meta('monetization', $podcast->payment_pointer);
         }
 
-        return '<link type="application/rss+xml" rel="alternate" title="' . $podcast->title . '" href="' . $podcast->feed_url . '" />' . PHP_EOL . $metatags->__toString() . PHP_EOL . $schema->__toString();
+        return '<link type="application/rss+xml" rel="alternate" title="' . esc(
+            $podcast->title
+        ) . '" href="' . $podcast->feed_url . '" />' . PHP_EOL . $metatags->__toString() . PHP_EOL . $schema->__toString();
     }
 }
 
@@ -77,8 +79,8 @@ if (! function_exists('get_episode_metatags')) {
     {
         $schema = new Schema(
             new Thing('PodcastEpisode', [
-                'url' => url_to('episode', $episode->podcast->handle, $episode->slug),
-                'name' => $episode->title,
+                'url' => url_to('episode', esc($episode->podcast->handle), $episode->slug),
+                'name' => esc($episode->title),
                 'image' => $episode->cover->feed_url,
                 'description' => $episode->description,
                 'datePublished' => $episode->published_at->format(DATE_ISO8601),
@@ -88,7 +90,7 @@ if (! function_exists('get_episode_metatags')) {
                     'contentUrl' => $episode->audio->file_url,
                 ]),
                 'partOfSeries' => new Thing('PodcastSeries', [
-                    'name' => $episode->podcast->title,
+                    'name' => esc($episode->podcast->title),
                     'url' => $episode->podcast->link,
                 ]),
             ])
@@ -98,10 +100,10 @@ if (! function_exists('get_episode_metatags')) {
 
         $metatags
             ->title($episode->title)
-            ->description(htmlspecialchars($episode->description))
+            ->description(esc($episode->description))
             ->image((string) $episode->cover->og_url, 'player')
             ->canonical($episode->link)
-            ->og('site_name', service('settings')->get('App.siteName'))
+            ->og('site_name', esc(service('settings')->get('App.siteName')))
             ->og('image:width', (string) config('Images')->podcastCoverSizes['og']['width'])
             ->og('image:height', (string) config('Images')->podcastCoverSizes['og']['height'])
             ->og('locale', $episode->podcast->language_code)
@@ -110,7 +112,7 @@ if (! function_exists('get_episode_metatags')) {
             ->meta('article:published_time', $episode->published_at->format(DATE_ISO8601))
             ->meta('article:modified_time', $episode->updated_at->format(DATE_ISO8601))
             ->twitter('audio:partner', $episode->podcast->publisher ?? '')
-            ->twitter('audio:artist_name', $episode->podcast->owner_name)
+            ->twitter('audio:artist_name', esc($episode->podcast->owner_name))
             ->twitter('player', $episode->getEmbedUrl('light'))
             ->twitter('player:width', (string) config('Embed')->width)
             ->twitter('player:height', (string) config('Embed')->height)
@@ -126,9 +128,11 @@ if (! function_exists('get_episode_metatags')) {
 
         return $metatags->__toString() . PHP_EOL . '<link rel="alternate" type="application/json+oembed" href="' . base_url(
             route_to('episode-oembed-json', $episode->podcast->handle, $episode->slug)
-        ) . '" title="' . $episode->title . ' oEmbed json" />' . PHP_EOL . '<link rel="alternate" type="text/xml+oembed" href="' . base_url(
+        ) . '" title="' . esc(
+            $episode->title
+        ) . ' oEmbed json" />' . PHP_EOL . '<link rel="alternate" type="text/xml+oembed" href="' . base_url(
             route_to('episode-oembed-xml', $episode->podcast->handle, $episode->slug)
-        ) . '" title="' . $episode->title . ' oEmbed xml" />' . PHP_EOL . $schema->__toString();
+        ) . '" title="' . esc($episode->title) . ' oEmbed xml" />' . PHP_EOL . $schema->__toString();
     }
 }
 
@@ -136,7 +140,7 @@ if (! function_exists('get_post_metatags')) {
     function get_post_metatags(Post $post): string
     {
         $socialMediaPosting = new Thing('SocialMediaPosting', [
-            '@id' => url_to('post', $post->actor->username, $post->id),
+            '@id' => url_to('post', esc($post->actor->username), $post->id),
             'datePublished' => $post->published_at->format(DATE_ISO8601),
             'author' => new Thing('Person', [
                 'name' => $post->actor->display_name,
@@ -173,11 +177,11 @@ if (! function_exists('get_post_metatags')) {
             ->description($post->message)
             ->image($post->actor->avatar_image_url)
             ->canonical((string) current_url())
-            ->og('site_name', service('settings')->get('App.siteName'))
+            ->og('site_name', esc(service('settings')->get('App.siteName')))
             ->push('link', [
                 'rel' => 'alternate',
                 'type' => 'application/activity+json',
-                'href' => url_to('post', $post->actor->username, $post->id),
+                'href' => url_to('post', esc($post->actor->username), $post->id),
             ]);
 
         return $metatags->__toString() . PHP_EOL . $schema->__toString();
@@ -190,7 +194,7 @@ if (! function_exists('get_episode_comment_metatags')) {
         $schema = new Schema(new Thing('SocialMediaPosting', [
             '@id' => url_to(
                 'episode-comment',
-                $episodeComment->actor->username,
+                esc($episodeComment->actor->username),
                 $episodeComment->episode->slug,
                 $episodeComment->id
             ),
@@ -212,7 +216,7 @@ if (! function_exists('get_episode_comment_metatags')) {
             ->description($episodeComment->message)
             ->image($episodeComment->actor->avatar_image_url)
             ->canonical((string) current_url())
-            ->og('site_name', service('settings')->get('App.siteName'))
+            ->og('site_name', esc(service('settings')->get('App.siteName')))
             ->push('link', [
                 'rel' => 'alternate',
                 'type' => 'application/activity+json',
@@ -239,7 +243,7 @@ if (! function_exists('get_follow_metatags')) {
             ->description($actor->summary)
             ->image($actor->avatar_image_url)
             ->canonical((string) current_url())
-            ->og('site_name', service('settings')->get('App.siteName'));
+            ->og('site_name', esc(service('settings')->get('App.siteName')));
 
         return $metatags->__toString();
     }
@@ -256,7 +260,7 @@ if (! function_exists('get_remote_actions_metatags')) {
             ->description($post->message)
             ->image($post->actor->avatar_image_url)
             ->canonical((string) current_url())
-            ->og('site_name', service('settings')->get('App.siteName'));
+            ->og('site_name', esc(service('settings')->get('App.siteName')));
 
         return $metatags->__toString();
     }
@@ -267,11 +271,11 @@ if (! function_exists('get_home_metatags')) {
     {
         $metatags = new MetaTags();
         $metatags
-            ->title(service('settings')->get('App.siteName'))
-            ->description(service('settings')->get('App.siteDescription'))
+            ->title(esc(service('settings')->get('App.siteName')))
+            ->description(esc(service('settings')->get('App.siteDescription')))
             ->image(service('settings')->get('App.siteIcon')['512'])
             ->canonical((string) current_url())
-            ->og('site_name', service('settings')->get('App.siteName'));
+            ->og('site_name', esc(service('settings')->get('App.siteName')));
 
         return $metatags->__toString();
     }
@@ -283,14 +287,14 @@ if (! function_exists('get_page_metatags')) {
         $metatags = new MetaTags();
         $metatags
             ->title(
-                $page->title . service('settings')->get('App.siteTitleSeparator') . service(
+                esc($page->title) . service('settings')->get('App.siteTitleSeparator') . esc(service(
                     'settings'
-                )->get('App.siteName')
+                )->get('App.siteName'))
             )
-            ->description(service('settings')->get('App.siteDescription'))
+            ->description(esc(service('settings')->get('App.siteDescription')))
             ->image(service('settings')->get('App.siteIcon')['512'])
             ->canonical((string) current_url())
-            ->og('site_name', service('settings')->get('App.siteName'));
+            ->og('site_name', esc(service('settings')->get('App.siteName')));
 
         return $metatags->__toString();
     }
diff --git a/app/Libraries/CommentObject.php b/app/Libraries/CommentObject.php
index 20ca892e6b..4d8c75d777 100644
--- a/app/Libraries/CommentObject.php
+++ b/app/Libraries/CommentObject.php
@@ -37,7 +37,7 @@ class CommentObject extends ObjectType
 
         $this->replies = url_to(
             'episode-comment-replies',
-            $comment->actor->username,
+            esc($comment->actor->username),
             $comment->episode->slug,
             $comment->id
         );
diff --git a/app/Libraries/PodcastActor.php b/app/Libraries/PodcastActor.php
index 61b188b53d..f07a23118f 100644
--- a/app/Libraries/PodcastActor.php
+++ b/app/Libraries/PodcastActor.php
@@ -44,6 +44,6 @@ class PodcastActor extends ActorObject
 
         $this->category = $category;
 
-        $this->episodes = url_to('podcast-episodes', $podcast->handle);
+        $this->episodes = url_to('podcast-episodes', esc($podcast->handle));
     }
 }
diff --git a/app/Libraries/PodcastEpisode.php b/app/Libraries/PodcastEpisode.php
index 8e7dc09884..9b2bf169b6 100644
--- a/app/Libraries/PodcastEpisode.php
+++ b/app/Libraries/PodcastEpisode.php
@@ -60,7 +60,7 @@ class PodcastEpisode extends ObjectType
         $this->audio = [
             'id' => $episode->audio->file_url,
             'type' => 'Audio',
-            'name' => $episode->title,
+            'name' => esc($episode->title),
             'size' => $episode->audio->file_size,
             'duration' => $episode->audio->duration,
             'url' => [
diff --git a/app/Models/EpisodeCommentModel.php b/app/Models/EpisodeCommentModel.php
index d3bb982c7d..7ac93b0b68 100644
--- a/app/Models/EpisodeCommentModel.php
+++ b/app/Models/EpisodeCommentModel.php
@@ -94,7 +94,12 @@ class EpisodeCommentModel extends UuidModel
         if ($registerActivity) {
             // set post id and uri to construct NoteObject
             $comment->id = $newCommentId;
-            $comment->uri = url_to('episode-comment', $comment->actor->username, $comment->episode->slug, $comment->id);
+            $comment->uri = url_to(
+                'episode-comment',
+                esc($comment->actor->username),
+                $comment->episode->slug,
+                $comment->id
+            );
 
             $createActivity = new CreateActivity();
             $createActivity
@@ -112,7 +117,7 @@ class EpisodeCommentModel extends UuidModel
                     'queued',
                 );
 
-            $createActivity->set('id', url_to('activity', $comment->actor->username, $activityId));
+            $createActivity->set('id', url_to('activity', esc($comment->actor->username), $activityId));
 
             model(ActivityModel::class, false)
                 ->update($activityId, [
@@ -235,7 +240,7 @@ class EpisodeCommentModel extends UuidModel
             $episode = model(EpisodeModel::class, false)
                 ->find((int) $data['data']['episode_id']);
 
-            $data['data']['uri'] = url_to('episode-comment', $actor->username, $episode->slug, $uuid4->toString());
+            $data['data']['uri'] = url_to('episode-comment', esc($actor->username), $episode->slug, $uuid4->toString());
         }
 
         return $data;
diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php
index 3d2eb63825..64fdc7e563 100644
--- a/app/Models/EpisodeModel.php
+++ b/app/Models/EpisodeModel.php
@@ -115,8 +115,8 @@ class EpisodeModel extends Model
         'number' => 'is_natural_no_zero|permit_empty',
         'season_number' => 'is_natural_no_zero|permit_empty',
         'type' => 'required',
-        'transcript_remote_url' => 'valid_url|permit_empty',
-        'chapters_remote_url' => 'valid_url|permit_empty',
+        'transcript_remote_url' => 'valid_url_strict|permit_empty',
+        'chapters_remote_url' => 'valid_url_strict|permit_empty',
         'published_at' => 'valid_date|permit_empty',
         'created_by' => 'required',
         'updated_by' => 'required',
diff --git a/app/Models/LikeModel.php b/app/Models/LikeModel.php
index 0c763ce0a7..8462d4c33e 100644
--- a/app/Models/LikeModel.php
+++ b/app/Models/LikeModel.php
@@ -76,7 +76,7 @@ class LikeModel extends UuidModel
                     'queued',
                 );
 
-            $likeActivity->set('id', url_to('activity', $actor->username, $activityId));
+            $likeActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
             model(ActivityModel::class)
                 ->update($activityId, [
@@ -115,7 +115,7 @@ class LikeModel extends UuidModel
 
             $likeActivity = new LikeActivity();
             $likeActivity
-                ->set('id', url_to('activity', $actor->username, $activity->id))
+                ->set('id', url_to('activity', esc($actor->username), $activity->id))
                 ->set('actor', $actor->uri)
                 ->set('object', $comment->uri);
 
@@ -134,7 +134,7 @@ class LikeModel extends UuidModel
                     'queued',
                 );
 
-            $undoActivity->set('id', url_to('activity', $actor->username, $activityId));
+            $undoActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
             model(ActivityModel::class)
                 ->update($activityId, [
diff --git a/app/Models/PodcastModel.php b/app/Models/PodcastModel.php
index aa2d018aa5..1a5be2b68a 100644
--- a/app/Models/PodcastModel.php
+++ b/app/Models/PodcastModel.php
@@ -94,7 +94,7 @@ class PodcastModel extends Model
         'language_code' => 'required',
         'category_id' => 'required',
         'owner_email' => 'required|valid_email',
-        'new_feed_url' => 'valid_url|permit_empty',
+        'new_feed_url' => 'valid_url_strict|permit_empty',
         'type' => 'required',
         'created_by' => 'required',
         'updated_by' => 'required',
diff --git a/app/Views/_message_block.php b/app/Views/_message_block.php
index 1c6fd67b8e..1504aa372c 100644
--- a/app/Views/_message_block.php
+++ b/app/Views/_message_block.php
@@ -1,22 +1,19 @@
 <?php declare(strict_types=1);
 
 if (session()->has('message')): ?>
-    <div class="px-4 py-2 mb-4 font-semibold text-green-900 bg-green-200 border border-green-700">
-        <?= session('message') ?>
-    </div>
+    <Alert variant="success" class="mb-4"><?= esc(session('message')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('error')): ?>
-    <div class="px-4 py-2 mb-4 font-semibold text-red-900 bg-red-200 border border-red-700">
-        <?= session('error') ?>
-    </div>
+    <Alert variant="danger" class="mb-4"><?= esc(session('error')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('errors')): ?>
-    <ul class="px-4 py-2 mb-4 font-semibold text-red-900 bg-red-200 border border-red-700">
-    <?php foreach (session('errors') as $error): ?>
-        <li><?= $error ?></li>
-    <?php endforeach; ?>
-    </ul>
-<?php endif;
-?>
+    <Alert variant="danger" class="mb-4">
+        <ul>
+            <?php foreach (session('errors') as $error): ?>
+                <li><?= esc($error) ?></li>
+            <?php endforeach; ?>
+        </ul>
+    </Alert>
+<?php endif; ?>
diff --git a/modules/Admin/Controllers/ContributorController.php b/modules/Admin/Controllers/ContributorController.php
index c5d09fd5e0..a5a0268be6 100644
--- a/modules/Admin/Controllers/ContributorController.php
+++ b/modules/Admin/Controllers/ContributorController.php
@@ -63,6 +63,7 @@ class ContributorController extends BaseController
     public function view(): string
     {
         $data = [
+            'podcast' => $this->podcast,
             'contributor' => (new UserModel())->getPodcastContributor($this->user->id, $this->podcast->id),
         ];
 
diff --git a/modules/Admin/Language/en/Fediverse.php b/modules/Admin/Language/en/Fediverse.php
index 3718c8e93a..0e4ca66d89 100644
--- a/modules/Admin/Language/en/Fediverse.php
+++ b/modules/Admin/Language/en/Fediverse.php
@@ -10,6 +10,7 @@ declare(strict_types=1);
 
 return [
     'messages' => [
+        'actorNotFound' => 'The account could not be found!',
         'blockActorSuccess' => '{actor} has been blocked!',
         'unblockActorSuccess' => 'Actor has been unblocked!',
         'blockDomainSuccess' => '{domain} has been blocked!',
diff --git a/modules/Admin/Language/fr/Fediverse.php b/modules/Admin/Language/fr/Fediverse.php
index c7d34bbabf..87d20cc678 100644
--- a/modules/Admin/Language/fr/Fediverse.php
+++ b/modules/Admin/Language/fr/Fediverse.php
@@ -10,6 +10,7 @@ declare(strict_types=1);
 
 return [
     'messages' => [
+        'actorNotFound' => 'L’utilisateur n’a pu être trouvé !',
         'blockActorSuccess' => '{actor} a été bloqué !',
         'unblockActorSuccess' => 'L’utilisateur a été débloqué !',
         'blockDomainSuccess' => '{domain} a été bloqué !',
diff --git a/modules/Fediverse/Controllers/BlockController.php b/modules/Fediverse/Controllers/BlockController.php
index 088d270e2e..abf6a7c49b 100644
--- a/modules/Fediverse/Controllers/BlockController.php
+++ b/modules/Fediverse/Controllers/BlockController.php
@@ -12,6 +12,7 @@ namespace Modules\Fediverse\Controllers;
 
 use CodeIgniter\Controller;
 use CodeIgniter\HTTP\RedirectResponse;
+use Exception;
 
 class BlockController extends Controller
 {
@@ -23,7 +24,7 @@ class BlockController extends Controller
     public function attemptBlockActor(): RedirectResponse
     {
         $rules = [
-            'handle' => 'required',
+            'handle' => 'required|regex_match[/^@?([\w\.\-]+)@([\w\.\-]+)(:[\d]+)?$/]',
         ];
 
         if (! $this->validate($rules)) {
@@ -36,9 +37,9 @@ class BlockController extends Controller
         $handle = $this->request->getPost('handle');
 
         if ($parts = split_handle($handle)) {
-            if (
-                ($actor = get_or_create_actor($parts['username'], $parts['domain'])) === null
-            ) {
+            try {
+                $actor = get_or_create_actor($parts['username'], $parts['domain']);
+            } catch (Exception) {
                 return redirect()
                     ->back()
                     ->withInput()
@@ -78,7 +79,7 @@ class BlockController extends Controller
     public function attemptBlockDomain(): RedirectResponse
     {
         $rules = [
-            'domain' => 'required',
+            'domain' => 'required|regex_match[/^[\w\-\.]+[\w]+(:[\d]+)?/]',
         ];
 
         if (! $this->validate($rules)) {
diff --git a/modules/Fediverse/Controllers/NodeInfo2Controller.php b/modules/Fediverse/Controllers/NodeInfo2Controller.php
index f5fbf00ed7..60ef6cb2fa 100644
--- a/modules/Fediverse/Controllers/NodeInfo2Controller.php
+++ b/modules/Fediverse/Controllers/NodeInfo2Controller.php
@@ -30,8 +30,7 @@ class NodeInfo2Controller extends Controller
             'version' => '1.0',
             'server' => [
                 'baseUrl' => base_url(),
-                'name' => service('settings')
-                    ->get('App.siteName'),
+                'name' => esc(service('settings') ->get('App.siteName')),
                 'software' => 'Castopod',
                 'version' => CP_VERSION,
             ],
diff --git a/modules/Fediverse/Helpers/fediverse_helper.php b/modules/Fediverse/Helpers/fediverse_helper.php
index 5f243f99d0..2a0e14920c 100644
--- a/modules/Fediverse/Helpers/fediverse_helper.php
+++ b/modules/Fediverse/Helpers/fediverse_helper.php
@@ -79,7 +79,7 @@ if (! function_exists('accept_follow')) {
             $acceptActivity->toJSON(),
         );
 
-        $acceptActivity->set('id', url_to('activity', $actor->username, $activityId));
+        $acceptActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
         $activityModel->update($activityId, [
             'payload' => $acceptActivity->toJSON(),
diff --git a/modules/Fediverse/Models/FavouriteModel.php b/modules/Fediverse/Models/FavouriteModel.php
index d8ef76de3c..3ca5aa62b8 100644
--- a/modules/Fediverse/Models/FavouriteModel.php
+++ b/modules/Fediverse/Models/FavouriteModel.php
@@ -75,7 +75,7 @@ class FavouriteModel extends BaseUuidModel
                     'queued',
                 );
 
-            $likeActivity->set('id', url_to('activity', $actor->username, $activityId));
+            $likeActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
             model('ActivityModel', false)
                 ->update($activityId, [
@@ -122,7 +122,7 @@ class FavouriteModel extends BaseUuidModel
 
             $likeActivity = new LikeActivity();
             $likeActivity
-                ->set('id', url_to('activity', $actor->username, $activity->id))
+                ->set('id', url_to('activity', esc($actor->username), $activity->id))
                 ->set('actor', $actor->uri)
                 ->set('object', $post->uri);
 
@@ -141,7 +141,7 @@ class FavouriteModel extends BaseUuidModel
                     'queued',
                 );
 
-            $undoActivity->set('id', url_to('activity', $actor->username, $activityId));
+            $undoActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
             model('ActivityModel', false)
                 ->update($activityId, [
diff --git a/modules/Fediverse/Models/FollowModel.php b/modules/Fediverse/Models/FollowModel.php
index f1e764507c..5a49b0a804 100644
--- a/modules/Fediverse/Models/FollowModel.php
+++ b/modules/Fediverse/Models/FollowModel.php
@@ -79,7 +79,7 @@ class FollowModel extends BaseModel
                         'queued',
                     );
 
-                $followActivity->set('id', url_to('activity', $actor->username, $activityId));
+                $followActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
                 model('ActivityModel', false)
                     ->update($activityId, [
@@ -142,7 +142,7 @@ class FollowModel extends BaseModel
                     'queued',
                 );
 
-            $undoActivity->set('id', url_to('activity', $actor->username, $activityId));
+            $undoActivity->set('id', url_to('activity', esc($actor->username), $activityId));
 
             model('ActivityModel', false)
                 ->update($activityId, [
diff --git a/modules/Fediverse/Models/PostModel.php b/modules/Fediverse/Models/PostModel.php
index 4d2e9840e3..4b6d0a3601 100644
--- a/modules/Fediverse/Models/PostModel.php
+++ b/modules/Fediverse/Models/PostModel.php
@@ -286,7 +286,7 @@ class PostModel extends BaseUuidModel
         if ($registerActivity) {
             // set post id and uri to construct NoteObject
             $post->id = $newPostId;
-            $post->uri = url_to('post', $post->actor->username, $newPostId);
+            $post->uri = url_to('post', esc($post->actor->username), $newPostId);
 
             $createActivity = new CreateActivity();
             $noteObjectClass = config('Fediverse')
@@ -306,7 +306,7 @@ class PostModel extends BaseUuidModel
                     'queued',
                 );
 
-            $createActivity->set('id', url_to('activity', $post->actor->username, $activityId));
+            $createActivity->set('id', url_to('activity', esc($post->actor->username), $activityId));
 
             model('ActivityModel', false)
                 ->update($activityId, [
@@ -419,7 +419,7 @@ class PostModel extends BaseUuidModel
                     'queued',
                 );
 
-            $deleteActivity->set('id', url_to('activity', $post->actor->username, $activityId));
+            $deleteActivity->set('id', url_to('activity', esc($post->actor->username), $activityId));
 
             model('ActivityModel', false)
                 ->update($activityId, [
@@ -506,7 +506,7 @@ class PostModel extends BaseUuidModel
                     'queued',
                 );
 
-            $announceActivity->set('id', url_to('activity', $post->actor->username, $activityId));
+            $announceActivity->set('id', url_to('activity', esc($post->actor->username), $activityId));
 
             model('ActivityModel', false)
                 ->update($activityId, [
@@ -721,7 +721,7 @@ class PostModel extends BaseUuidModel
             $actor = model('ActorModel', false)
                 ->getActorById((int) $data['data']['actor_id']);
 
-            $data['data']['uri'] = url_to('post', $actor->username, $uuid4->toString());
+            $data['data']['uri'] = url_to('post', esc($actor->username), $uuid4->toString());
         }
 
         return $data;
diff --git a/modules/Fediverse/Objects/NoteObject.php b/modules/Fediverse/Objects/NoteObject.php
index 70c56f3eb3..561ce89b50 100644
--- a/modules/Fediverse/Objects/NoteObject.php
+++ b/modules/Fediverse/Objects/NoteObject.php
@@ -44,7 +44,7 @@ class NoteObject extends ObjectType
             $this->inReplyTo = $post->reply_to_post->uri;
         }
 
-        $this->replies = url_to('post-replies', $post->actor->username, $post->id);
+        $this->replies = url_to('post-replies', esc($post->actor->username), $post->id);
 
         $this->cc = [$post->actor->followers_url];
     }
diff --git a/tests/unit/HealthTest.php b/tests/unit/HealthTest.php
index 06ea8eccfb..b3b5dbcec2 100644
--- a/tests/unit/HealthTest.php
+++ b/tests/unit/HealthTest.php
@@ -34,7 +34,7 @@ final class HealthTest extends CIUnitTestCase
             // So if you set app.baseURL in .env, it takes precedence
             $config = new App();
             $this->assertTrue(
-                $validation->check($config->baseURL, 'valid_url'),
+                $validation->check($config->baseURL, 'valid_url_strict'),
                 'baseURL "' . $config->baseURL . '" in .env is not valid URL'
             );
         }
@@ -45,7 +45,7 @@ final class HealthTest extends CIUnitTestCase
 
         // BaseURL in app/Config/App.php is a valid URL?
         $this->assertTrue(
-            $validation->check($reader->baseURL, 'valid_url'),
+            $validation->check($reader->baseURL, 'valid_url_strict'),
             'baseURL "' . $reader->baseURL . '" in app/Config/App.php is not valid URL'
         );
     }
diff --git a/themes/cp_admin/_message_block.php b/themes/cp_admin/_message_block.php
index ffe70e09c7..1504aa372c 100644
--- a/themes/cp_admin/_message_block.php
+++ b/themes/cp_admin/_message_block.php
@@ -1,20 +1,19 @@
 <?php declare(strict_types=1);
 
 if (session()->has('message')): ?>
-    <Alert variant="success" class="mb-4"><?= session('message') ?></Alert>
+    <Alert variant="success" class="mb-4"><?= esc(session('message')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('error')): ?>
-    <Alert variant="danger" class="mb-4"><?= session('error') ?></Alert>
+    <Alert variant="danger" class="mb-4"><?= esc(session('error')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('errors')): ?>
     <Alert variant="danger" class="mb-4">
         <ul>
             <?php foreach (session('errors') as $error): ?>
-                <li><?= $error ?></li>
+                <li><?= esc($error) ?></li>
             <?php endforeach; ?>
         </ul>
     </Alert>
-<?php endif;
-?>
+<?php endif; ?>
diff --git a/themes/cp_admin/_partials/_nav_header.php b/themes/cp_admin/_partials/_nav_header.php
index 03a8ec0acb..8280862898 100644
--- a/themes/cp_admin/_partials/_nav_header.php
+++ b/themes/cp_admin/_partials/_nav_header.php
@@ -27,16 +27,17 @@
             <?= user()
                 ->podcasts === [] ? '' : '<img src="' . interact_as_actor()->avatar_image_url . '" class="absolute bottom-0 w-4 h-4 border rounded-full -right-1 border-navigation-bg" loading="lazy" />' ?>
         </div>
-        <?= user()->username ?>
+        <?= esc(user()->username) ?>
         <?= icon('caret-down', 'ml-auto text-2xl') ?></button>
     <?php
         $interactButtons = '';
         foreach (user()->podcasts as $userPodcast) {
             $checkMark = interact_as_actor_id() === $userPodcast->actor_id ? icon('check', 'ml-2 bg-accent-base text-accent-contrast rounded-full') : '';
+            $userPodcastTitle = esc($userPodcast->title);
 
             $interactButtons .= <<<CODE_SAMPLE
                 <button class="inline-flex items-center w-full px-4 py-1 hover:bg-highlight" id="interact-as-actor-{$userPodcast->id}" name="actor_id" value="{$userPodcast->actor_id}">
-                    <div class="inline-flex items-center flex-1 text-sm"><img src="{$userPodcast->cover->tiny_url}" class="w-6 h-6 mr-2 rounded-full" loading="lazy" /><span class="truncate">{$userPodcast->title}</span>{$checkMark}</div>
+                    <div class="inline-flex items-center flex-1 text-sm"><img src="{$userPodcast->cover->tiny_url}" class="w-6 h-6 mr-2 rounded-full" loading="lazy" /><span class="max-w-xs truncate">{$userPodcastTitle}</span>{$checkMark}</div>
                 </button>
             CODE_SAMPLE;
         }
diff --git a/themes/cp_admin/_partials/_user_info.php b/themes/cp_admin/_partials/_user_info.php
index 613aea146c..61871f6a9e 100644
--- a/themes/cp_admin/_partials/_user_info.php
+++ b/themes/cp_admin/_partials/_user_info.php
@@ -11,7 +11,7 @@
     <?= lang('User.form.username') ?>
     </dt>
     <dd class="mt-1 text-sm leading-5">
-    <?= $user->username ?>
+    <?= esc($user->username) ?>
     </dd>
 </div>
 <div class="px-4 py-5">
diff --git a/themes/cp_admin/contributor/add.php b/themes/cp_admin/contributor/add.php
index e272466db8..ef2325bb4f 100644
--- a/themes/cp_admin/contributor/add.php
+++ b/themes/cp_admin/contributor/add.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= lang('Contributor.add_contributor', [$podcast->title]) ?>
+<?= lang('Contributor.add_contributor', [esc($podcast->title)]) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= lang('Contributor.add_contributor', [$podcast->title]) ?>
+<?= lang('Contributor.add_contributor', [esc($podcast->title)]) ?>
 <?= $this->endSection() ?>
 
 
diff --git a/themes/cp_admin/contributor/edit.php b/themes/cp_admin/contributor/edit.php
index 2baa789e13..edfed8412f 100644
--- a/themes/cp_admin/contributor/edit.php
+++ b/themes/cp_admin/contributor/edit.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= lang('Contributor.edit_role', [$user->username]) ?>
+<?= lang('Contributor.edit_role', [esc($user->username)]) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= lang('Contributor.edit_role', [$user->username]) ?>
+<?= lang('Contributor.edit_role', [esc($user->username)]) ?>
 <?= $this->endSection() ?>
 
 
diff --git a/themes/cp_admin/contributor/list.php b/themes/cp_admin/contributor/list.php
index ea6c4750c3..6ad44137e2 100644
--- a/themes/cp_admin/contributor/list.php
+++ b/themes/cp_admin/contributor/list.php
@@ -20,7 +20,7 @@
         [
             'header' => lang('Contributor.list.username'),
             'cell' => function ($contributor) {
-                return $contributor->username;
+                return esc($contributor->username);
             },
         ],
         [
diff --git a/themes/cp_admin/contributor/view.php b/themes/cp_admin/contributor/view.php
index d7388bb597..71bd3b1e13 100644
--- a/themes/cp_admin/contributor/view.php
+++ b/themes/cp_admin/contributor/view.php
@@ -2,24 +2,30 @@
 
 <?= $this->section('title') ?>
 <?= lang('Contributor.view', [
-    'username' => $contributor->username,
-    'podcastTitle' => $contributor->podcast->title,
+    'username' => esc($contributor->username),
+    'podcastTitle' => esc($podcast->title),
 ]) ?>
 <?= $this->endSection() ?>
 
+<?= $this->section('pageTitle') ?>
+<?= lang('Contributor.view', [
+    'username' => esc($contributor->username),
+    'podcastTitle' => esc($podcast->title),
+]) ?>
+<?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
 <div class="px-4 py-5 bg-base sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
     <dt class="text-sm font-medium leading-5 text-skin-muted">
-    Username
+    <?= lang('Contributor.list.username') ?>
     </dt>
     <dd class="mt-1 text-sm leading-5 sm:mt-0 sm:col-span-2">
-    <?= $contributor->username ?>
+    <?= esc($contributor->username) ?>
     </dd>
 </div>
 <div class="px-4 py-5 bg-base sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
     <dt class="text-sm font-medium leading-5 text-skin-muted">
-    Role
+    <?= lang('Contributor.list.role') ?>
     </dt>
     <dd class="mt-1 text-sm leading-5 sm:mt-0 sm:col-span-2">
     <?= $contributor->podcast_role ?>
diff --git a/themes/cp_admin/episode/_card.php b/themes/cp_admin/episode/_card.php
index 6cde92c17c..543d45e0f2 100644
--- a/themes/cp_admin/episode/_card.php
+++ b/themes/cp_admin/episode/_card.php
@@ -2,12 +2,12 @@
     <a href="<?= route_to('episode-view', $episode->podcast->id, $episode->id) ?>" class="flex flex-col justify-end w-full h-full text-white group">
         <div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient mix-blend-multiply"></div>
         <div class="w-full h-full overflow-hidden bg-header">
-            <img src="<?= $episode->cover->medium_url ?>" alt="<?= $episode->title ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform group-focus:scale-105 group-hover:scale-105 aspect-square" loading="lazy" />
+            <img src="<?= $episode->cover->medium_url ?>" alt="<?= esc($episode->title) ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform group-focus:scale-105 group-hover:scale-105 aspect-square" loading="lazy" />
         </div>
         <?= publication_pill($episode->published_at, $episode->publication_status, 'absolute top-0 left-0 ml-2 mt-2 text-sm'); ?>
         <div class="absolute z-20 flex flex-col items-start px-4 py-2">
             <?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold !no-underline px-1 bg-black/50 mr-1', true) ?>
-            <span class="font-semibold leading-tight line-clamp-2"><?= $episode->title ?></span>
+            <span class="font-semibold leading-tight line-clamp-2"><?= esc($episode->title) ?></span>
         </div>
     </a>
     <button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $episode->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $episode->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
@@ -15,7 +15,7 @@
         [
             'type' => 'link',
             'title' => lang('Episode.go_to_page'),
-            'uri' => route_to('episode', $episode->podcast->handle, $episode->slug),
+            'uri' => route_to('episode', esc($episode->podcast->handle), esc($episode->slug)),
         ],
         [
             'type' => 'link',
diff --git a/themes/cp_admin/episode/_sidebar.php b/themes/cp_admin/episode/_sidebar.php
index f6dea48616..0993601b69 100644
--- a/themes/cp_admin/episode/_sidebar.php
+++ b/themes/cp_admin/episode/_sidebar.php
@@ -15,25 +15,25 @@ $podcastNavigation = [
     <?= icon('arrow-left', 'mr-2') ?>
     <img
     src="<?= $podcast->cover->tiny_url ?>"
-    alt="<?= $podcast->title ?>"
+    alt="<?= esc($podcast->title) ?>"
     class="object-cover w-6 h-6 rounded aspect-square"
     loading="lazy"
     />
-    <span class="flex-1 w-full px-2 text-xs font-semibold truncate" title="<?= $podcast->title ?>"><?= $podcast->title ?></span>
+    <span class="flex-1 w-full px-2 text-xs font-semibold truncate" title="<?= esc($podcast->title) ?>"><?= esc($podcast->title) ?></span>
 </a>
 <div class="flex items-center px-4 py-2 border-y border-navigation">
     <img
     src="<?= $episode->cover->thumbnail_url ?>"
-    alt="<?= $episode->title ?>"
+    alt="<?= esc($episode->title) ?>"
     class="object-cover w-16 h-16 rounded aspect-square"
     loading="lazy"
     />
     <div class="flex flex-col items-start flex-1 w-48 px-2">
-        <span class="w-full font-semibold truncate" title="<?= $episode->title ?>"><?= $episode->title ?></span>
+        <span class="w-full font-semibold truncate" title="<?= esc($episode->title) ?>"><?= esc($episode->title) ?></span>
         <a href="<?= route_to(
     'episode',
-    $podcast->handle,
-    $episode->slug,
+    esc($podcast->handle),
+    esc($episode->slug),
 ) ?>" class="inline-flex items-center text-xs hover:underline focus:ring-accent"><?= lang(
     'EpisodeNavigation.go_to_page',
 ) ?>
diff --git a/themes/cp_admin/episode/create.php b/themes/cp_admin/episode/create.php
index 4bb1b89c23..86bdfecefc 100644
--- a/themes/cp_admin/episode/create.php
+++ b/themes/cp_admin/episode/create.php
@@ -46,7 +46,7 @@
 <div>
     <Forms.Label for="slug"><?= lang('Episode.form.permalink') ?></Forms.Label>
     <permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
-        <span slot="domain"><?= base_url('/@' . $podcast->handle . '/episodes') . '/' ?></span>
+        <span slot="domain"><?= base_url('/@' . esc($podcast->handle) . '/episodes') . '/' ?></span>
         <Forms.Input name="slug" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" />
     </permalink-edit>
 </div>
diff --git a/themes/cp_admin/episode/edit.php b/themes/cp_admin/episode/edit.php
index 2ea9988d64..70453ca31a 100644
--- a/themes/cp_admin/episode/edit.php
+++ b/themes/cp_admin/episode/edit.php
@@ -43,15 +43,15 @@
     name="title"
     label="<?= lang('Episode.form.title') ?>"
     hint="<?= lang('Episode.form.title_hint') ?>"
-    value="<?= $episode->title ?>"
+    value="<?= esc($episode->title) ?>"
     required="true"
     data-slugify="title" />
 
 <div>
     <Forms.Label for="slug"><?= lang('Episode.form.permalink') ?></Forms.Label>
     <permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
-        <span slot="domain"><?= base_url('/@' . $podcast->handle . '/episodes') . '/' ?></span>
-        <Forms.Input name="slug" value="<?= $episode->slug ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" />
+        <span slot="domain"><?= base_url('/@' . esc($podcast->handle) . '/episodes') . '/' ?></span>
+        <Forms.Input name="slug" value="<?= esc($episode->slug) ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" />
     </permalink-edit>
 </div>
 
@@ -144,7 +144,7 @@
     name="location_name"
     label="<?= lang('Episode.form.location_name') ?>"
     hint="<?= lang('Episode.form.location_name_hint') ?>"
-    value="<?= $episode->location_name ?>" />
+    value="<?= esc($episode->location_name) ?>" />
 </Forms.Section>
 
 <Forms.Section
@@ -198,7 +198,7 @@
         </section>
         <section id="transcript-file-remote-url" class="tab-panel">
             <Forms.Label class="sr-only" for="transcript_remote_url" isOptional="true"><?= lang('Episode.form.transcript_remote_url') ?></Forms.Label>
-            <Forms.Input class="w-full" placeholder="https://…" name="transcript_remote_url" value="<?= $episode->transcript_remote_url ?>" />
+            <Forms.Input class="w-full" placeholder="https://…" name="transcript_remote_url" value="<?= esc($episode->transcript_remote_url) ?>" />
         </section>
     </div>
 </div>
@@ -253,7 +253,7 @@
         </section>
         <section id="chapters-file-remote-url" class="tab-panel">
             <Forms.Label class="sr-only" for="chapters_remote_url" isOptional="true"><?= lang('Episode.form.chapters_remote_url') ?></Forms.Label>
-            <Forms.Input class="w-full" placeholder="https://…" name="chapters_remote_url" value="<?= $episode->chapters_remote_url ?>" />
+            <Forms.Input class="w-full" placeholder="https://…" name="chapters_remote_url" value="<?= esc($episode->chapters_remote_url) ?>" />
         </section>
     </div>
 </div>
diff --git a/themes/cp_admin/episode/list.php b/themes/cp_admin/episode/list.php
index b240931c7b..6ffd2214aa 100644
--- a/themes/cp_admin/episode/list.php
+++ b/themes/cp_admin/episode/list.php
@@ -34,7 +34,7 @@
                                     $episode->audio->duration,
                                 ) .
                             '</time>' .
-                            '<img src="' . $episode->cover->thumbnail_url . '" alt="' . $episode->title . '" class="object-cover w-20 rounded-lg shadow-inner aspect-square" loading="lazy" />' .
+                            '<img src="' . $episode->cover->thumbnail_url . '" alt="' . esc($episode->title) . '" class="object-cover w-20 rounded-lg shadow-inner aspect-square" loading="lazy" />' .
                         '</div>' .
                         '<a class="overflow-x-hidden text-sm hover:underline" href="' . route_to(
                             'episode-view',
@@ -48,7 +48,7 @@
                             'text-xs font-semibold text-skin-muted !no-underline border px-1 border-gray-500',
                             true,
                         ) .
-                        '<span class="mr-1 truncate group-hover:underline">' . $episode->title . '</span>' .
+                        '<span class="mr-1 truncate group-hover:underline">' . esc($episode->title) . '</span>' .
                         '</h2>' .
                         '<p class="max-w-sm text-xs text-skin-muted line-clamp-2">' . $episode->description . '</p>' .
                         '</a>' .
@@ -80,7 +80,7 @@
                             [
                                 'type' => 'link',
                                 'title' => lang('Episode.go_to_page'),
-                                'uri' => route_to('episode', $podcast->handle, $episode->slug),
+                                'uri' => route_to('episode', esc($podcast->handle), esc($episode->slug)),
                             ],
                             [
                                 'type' => 'link',
diff --git a/themes/cp_admin/episode/persons.php b/themes/cp_admin/episode/persons.php
index 0f5e637369..05e0a619ca 100644
--- a/themes/cp_admin/episode/persons.php
+++ b/themes/cp_admin/episode/persons.php
@@ -58,9 +58,9 @@
                 return '<div class="flex">' .
                     '<a href="' .
                     route_to('person-view', $person->id) .
-                    "\"><img src=\"{$person->avatar->thumbnail_url}\" alt=\"{$person->full_name}\" class=\"object-cover w-16 rounded-full aspect-square\" loading=\"lazy\" /></a>" .
+                    '"><img src="' . $person->avatar->thumbnail_url . '" alt="' . esc($person->full_name) . '" class="object-cover w-16 rounded-full aspect-square" loading="lazy" /></a>' .
                     '<div class="flex flex-col ml-3">' .
-                    $person->full_name .
+                    esc($person->full_name) .
                     implode(
                         '',
                         array_map(function ($role) {
@@ -77,8 +77,8 @@
                     ) .
                     ($person->information_url === null
                         ? ''
-                        : "<a href=\"{$person->information_url}\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"font-semibold text-sm text-accent-base hover:text-accent-hover\">" .
-                        $person->information_url .
+                        : '<a href="' . esc($person->information_url) . '" target="_blank" rel="noreferrer noopener" class="text-sm font-semibold text-accent-base hover:text-accent-hover">' .
+                        esc($person->information_url) .
                         '</a>') .
                     '</div></div>';
             },
diff --git a/themes/cp_admin/episode/publish.php b/themes/cp_admin/episode/publish.php
index 09c3212d2a..3c3c105414 100644
--- a/themes/cp_admin/episode/publish.php
+++ b/themes/cp_admin/episode/publish.php
@@ -28,11 +28,11 @@
 <small class="max-w-md mb-2 text-skin-muted"><?= lang('Episode.publish_form.post_hint') ?></small>
 <div class="mb-8 overflow-hidden shadow-md bg-elevated rounded-xl">
     <div class="flex px-4 py-3 gap-x-2">
-        <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+        <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= esc($podcast->actor->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
         <div class="flex flex-col min-w-0">
             <p class="flex items-baseline min-w-0">
-                <span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span>
-                <span class="text-sm truncate text-skin-muted">@<?= $podcast->actor->username ?></span>
+                <span class="mr-2 font-semibold truncate"><?= esc($podcast->actor->display_name) ?></span>
+                <span class="text-sm truncate text-skin-muted">@<?= esc($podcast->actor->username) ?></span>
             </p>
         </div>
     </div>
@@ -41,11 +41,11 @@
     </div>
     <div class="flex border-y">
         <img src="<?= $episode->cover
-    ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="w-24 h-24 aspect-square" loading="lazy" />
+    ->thumbnail_url ?>" alt="<?= esc($episode->title) ?>" class="w-24 h-24 aspect-square" loading="lazy" />
         <div class="flex flex-col flex-1">
             <a href="<?= $episode->link ?>" class="flex-1 px-4 py-2">
                 <div class="flex items-baseline">
-                    <span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= $episode->title ?></span>
+                    <span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= esc($episode->title) ?></span>
                     <?= episode_numbering(
         $episode->number,
         $episode->season_number,
diff --git a/themes/cp_admin/episode/publish_edit.php b/themes/cp_admin/episode/publish_edit.php
index efe4d586f9..79a9a461ef 100644
--- a/themes/cp_admin/episode/publish_edit.php
+++ b/themes/cp_admin/episode/publish_edit.php
@@ -29,11 +29,11 @@
 <small class="max-w-md mb-2 text-skin-muted"><?= lang('Episode.publish_form.post_hint') ?></small>
 <div class="mb-8 overflow-hidden shadow-md bg-elevated rounded-xl">
     <div class="flex px-4 py-3 gap-x-2">
-        <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+        <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= esc($podcast->actor->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
         <div class="flex flex-col min-w-0">
             <p class="flex items-baseline min-w-0">
-                <span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span>
-                <span class="text-sm truncate text-skin-muted">@<?= $podcast->actor->username ?></span>
+                <span class="mr-2 font-semibold truncate"><?= esc($podcast->actor->display_name) ?></span>
+                <span class="text-sm truncate text-skin-muted">@<?= esc($podcast->actor->username) ?></span>
             </p>
             <?= relative_time($post->published_at, 'text-xs text-skin-muted') ?>
         </div>
@@ -43,11 +43,11 @@
     </div>
     <div class="flex border-y">
         <img src="<?= $episode->cover
-                ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="w-24 h-24 aspect-square" loading="lazy" />
+                ->thumbnail_url ?>" alt="<?= esc($episode->title) ?>" class="w-24 h-24 aspect-square" loading="lazy" />
         <div class="flex flex-col flex-1">
             <a href="<?= $episode->link ?>" class="flex-1 px-4 py-2">
                 <div class="flex items-baseline">
-                    <span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= $episode->title ?></span>
+                    <span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= esc($episode->title) ?></span>
                     <?= episode_numbering(
                     $episode->number,
                     $episode->season_number,
diff --git a/themes/cp_admin/episode/soundbites_list.php b/themes/cp_admin/episode/soundbites_list.php
index d6ee8af171..8a7c090f74 100644
--- a/themes/cp_admin/episode/soundbites_list.php
+++ b/themes/cp_admin/episode/soundbites_list.php
@@ -19,7 +19,7 @@
         [
             'header' => lang('Soundbite.list.soundbite'),
             'cell' => function ($soundbite): string {
-                return '<div class="flex gap-x-2"><play-soundbite audio-src="' . $soundbite->episode->audio->file_url . '" start-time="' . $soundbite->start_time . '" duration="' . $soundbite->duration . '" play-label="' . lang('Soundbite.play') . '" playing-label="' . lang('Soundbite.stop') . '"></play-soundbite><div class="flex flex-col"><span class="text-sm font-semibold">' . $soundbite->title . '</span><span class="text-xs">' . format_duration((int) $soundbite->duration) . '</span></div></div>';
+                return '<div class="flex gap-x-2"><play-soundbite audio-src="' . $soundbite->episode->audio->file_url . '" start-time="' . $soundbite->start_time . '" duration="' . $soundbite->duration . '" play-label="' . lang('Soundbite.play') . '" playing-label="' . lang('Soundbite.stop') . '"></play-soundbite><div class="flex flex-col"><span class="text-sm font-semibold">' . esc($soundbite->title) . '</span><span class="text-xs">' . format_duration((int) $soundbite->duration) . '</span></div></div>';
             },
         ],
         [
diff --git a/themes/cp_admin/episode/video_clip.php b/themes/cp_admin/episode/video_clip.php
index 46f51a1501..cc536f20ad 100644
--- a/themes/cp_admin/episode/video_clip.php
+++ b/themes/cp_admin/episode/video_clip.php
@@ -2,13 +2,13 @@
 
 <?= $this->section('title') ?>
 <?= lang('VideoClip.title', [
-    'videoClipLabel' => $videoClip->title,
+    'videoClipLabel' => esc($videoClip->title),
 ]) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
 <?= lang('VideoClip.title', [
-    'videoClipLabel' => $videoClip->title,
+    'videoClipLabel' => esc($videoClip->title),
 ]) ?>
 <?= $this->endSection() ?>
 
@@ -17,7 +17,7 @@
 <?php if ($videoClip->media): ?>
     <video controls class="bg-black h-80 aspect-video">
     <source src="<?= $videoClip->media->file_url ?>" type="<?= $videoClip->media->file_mimetype ?>">
-    Your browser does not support the video tag.
+        Your browser does not support the video tag.
     </video>
 <?php endif; ?>
 
diff --git a/themes/cp_admin/episode/video_clips_list.php b/themes/cp_admin/episode/video_clips_list.php
index 5af00a750b..474233b160 100644
--- a/themes/cp_admin/episode/video_clips_list.php
+++ b/themes/cp_admin/episode/video_clips_list.php
@@ -62,7 +62,7 @@ use CodeIgniter\I18n\Time;
                     'portrait' => 'aspect-[9/16]',
                     'squared' => 'aspect-square',
                 ];
-                return '<a href="' . route_to('video-clip', $videoClip->podcast_id, $videoClip->episode_id, $videoClip->id) . '" class="inline-flex items-center w-full group gap-x-2 focus:ring-accent"><div class="relative"><span class="absolute block w-3 h-3 rounded-full ring-2 ring-white -bottom-1 -left-1" data-tooltip="bottom" title="' . lang('Settings.theme.' . $videoClip->theme['name']) . '" style="background-color:hsl(' . $videoClip->theme['preview'] . ')"></span><div class="flex items-center justify-center h-6 overflow-hidden bg-black rounded-sm aspect-video" data-tooltip="bottom" title="' . lang('VideoClip.format.' . $videoClip->format) . '"><span class="flex items-center justify-center h-full text-white bg-gray-400 ' . $formatClass[$videoClip->format] . '"><Icon glyph="play"/></span></div></div><div class="flex flex-col"><div class="text-sm">#' . $videoClip->id . ' – <span class="font-semibold group-hover:underline">' . $videoClip->title . '</span><span class="ml-1 text-sm">by ' . $videoClip->user->username . '</span></div><span class="text-xs">' . format_duration((int) $videoClip->duration) . '</span></div></a>';
+                return '<a href="' . route_to('video-clip', $videoClip->podcast_id, $videoClip->episode_id, $videoClip->id) . '" class="inline-flex items-center w-full group gap-x-2 focus:ring-accent"><div class="relative"><span class="absolute block w-3 h-3 rounded-full ring-2 ring-white -bottom-1 -left-1" data-tooltip="bottom" title="' . lang('Settings.theme.' . $videoClip->theme['name']) . '" style="background-color:hsl(' . $videoClip->theme['preview'] . ')"></span><div class="flex items-center justify-center h-6 overflow-hidden bg-black rounded-sm aspect-video" data-tooltip="bottom" title="' . lang('VideoClip.format.' . $videoClip->format) . '"><span class="flex items-center justify-center h-full text-white bg-gray-400 ' . $formatClass[$videoClip->format] . '"><Icon glyph="play"/></span></div></div><div class="flex flex-col"><div class="text-sm">#' . $videoClip->id . ' – <span class="font-semibold group-hover:underline">' . esc($videoClip->title) . '</span><span class="ml-1 text-sm">by ' . esc($videoClip->user->username) . '</span></div><span class="text-xs">' . format_duration((int) $videoClip->duration) . '</span></div></a>';
             },
         ],
         [
diff --git a/themes/cp_admin/episode/view.php b/themes/cp_admin/episode/view.php
index f9a9e5e84b..0d42adf5c4 100644
--- a/themes/cp_admin/episode/view.php
+++ b/themes/cp_admin/episode/view.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $episode->title ?>
+<?= esc($episode->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $episode->title ?>    
+<?= esc($episode->title) ?>    
 <?= $this->endSection() ?>
 
 <?= $this->section('headerLeft') ?>
diff --git a/themes/cp_admin/fediverse/blocked_actors.php b/themes/cp_admin/fediverse/blocked_actors.php
index e60865cb5a..f8ddb35079 100644
--- a/themes/cp_admin/fediverse/blocked_actors.php
+++ b/themes/cp_admin/fediverse/blocked_actors.php
@@ -23,7 +23,7 @@
         [
             'header' => lang('Fediverse.list.actor'),
             'cell' => function ($blockedActor) {
-                return $blockedActor->username;
+                return esc($blockedActor->username);
             },
         ],
         [
@@ -36,7 +36,7 @@
                     $blockedActor->id .
                     '" />' .
                     csrf_field() .
-                    '<Button uri="' . route_to('fediverse-unblock-actor', $blockedActor->username) . '" variant="info" size="small" type="submit">' . lang('Fediverse.list.unblock') . '</Button>' .
+                    '<Button uri="' . route_to('fediverse-unblock-actor', esc($blockedActor->username)) . '" variant="info" size="small" type="submit">' . lang('Fediverse.list.unblock') . '</Button>' .
                     '</form>';
             },
         ],
diff --git a/themes/cp_admin/fediverse/blocked_domains.php b/themes/cp_admin/fediverse/blocked_domains.php
index c3b701f720..2a80d81ea3 100644
--- a/themes/cp_admin/fediverse/blocked_domains.php
+++ b/themes/cp_admin/fediverse/blocked_domains.php
@@ -23,7 +23,7 @@
         [
             'header' => lang('Fediverse.list.actor'),
             'cell' => function ($blockedDomain) {
-                return $blockedDomain->name;
+                return esc($blockedDomain->name);
             },
         ],
         [
@@ -33,10 +33,10 @@
                     route_to('fediverse-attempt-unblock-domain') .
                     '" method="POST">' .
                     '<input name="domain" type="hidden" value="' .
-                    $blockedDomain->name .
+                    esc($blockedDomain->name) .
                     '" />' .
                     csrf_field() .
-                    '<Button uri="' . route_to('fediverse-unblock-domain', $blockedDomain->name) . '" variant="info" size="small" type="submit">' . lang('Fediverse.list.unblock') . '</Button>' .
+                    '<Button uri="' . route_to('fediverse-unblock-domain', esc($blockedDomain->name)) . '" variant="info" size="small" type="submit">' . lang('Fediverse.list.unblock') . '</Button>' .
                     '</form>';
             },
         ],
diff --git a/themes/cp_admin/page/edit.php b/themes/cp_admin/page/edit.php
index fc9a8254b9..9e051f75c5 100644
--- a/themes/cp_admin/page/edit.php
+++ b/themes/cp_admin/page/edit.php
@@ -19,7 +19,7 @@
     label="<?= lang('Page.form.title') ?>"
     required="true"
     data-slugify="title"
-    value="<?= $page->title ?>"
+    value="<?= esc($page->title) ?>"
     slot="slug-input"
     class="max-w-sm" />
 
@@ -27,7 +27,7 @@
     <Forms.Label for="slug"><?= lang('Page.form.permalink') ?></Forms.Label>
     <permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
         <span slot="domain" class="flex-shrink-0"><?= base_url('pages') . '/' ?></span>
-        <Forms.Input name="slug" value="<?= $page->slug ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" value="<?= $page->slug ?>"/>
+        <Forms.Input name="slug" value="<?= esc($page->slug) ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" value="<?= esc($page->slug) ?>"/>
     </permalink-edit>
 </div>
 
diff --git a/themes/cp_admin/page/list.php b/themes/cp_admin/page/list.php
index b77b5af023..3d5d1ec0c2 100644
--- a/themes/cp_admin/page/list.php
+++ b/themes/cp_admin/page/list.php
@@ -21,16 +21,16 @@
             'header' => lang('Page.page'),
             'cell' => function ($page) {
                 return '<div class="flex flex-col">' .
-                    $page->title .
+                    esc($page->title) .
                     '<span class="text-sm text-skin-muted">/' .
-                    $page->slug .
+                    esc($page->slug) .
                     '</span></div>';
             },
         ],
         [
             'header' => lang('Common.actions'),
             'cell' => function ($page) {
-                return '<Button uri="' . route_to('page', $page->slug) . '" variant="secondary" size="small">' . lang('Page.go_to_page') . '</Button>' .
+                return '<Button uri="' . route_to('page', esc($page->slug)) . '" variant="secondary" size="small">' . lang('Page.go_to_page') . '</Button>' .
                 '<Button uri="' . route_to('page-edit', $page->id) . '" variant="info" size="small">' . lang('Page.edit') . '</Button>' .
                 '<Button uri="' . route_to('page-delete', $page->id) . '" variant="danger" size="small">' . lang('Page.delete') . '</Button>';
             },
diff --git a/themes/cp_admin/page/view.php b/themes/cp_admin/page/view.php
index fde36892c7..abc918ae4d 100644
--- a/themes/cp_admin/page/view.php
+++ b/themes/cp_admin/page/view.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $page->title ?>
+<?= esc($page->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $page->title ?>
+<?= esc($page->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('headerRight') ?>
diff --git a/themes/cp_admin/person/_card.php b/themes/cp_admin/person/_card.php
index 747598c5a2..20408bb517 100644
--- a/themes/cp_admin/person/_card.php
+++ b/themes/cp_admin/person/_card.php
@@ -2,10 +2,10 @@
     <a href="<?= route_to('person-view', $person->id) ?>" class="flex flex-col justify-end w-full h-full text-white group">
         <div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient mix-blend-multiply"></div>
         <div class="w-full h-full overflow-hidden bg-header">
-            <img alt="<?= $person->full_name ?>" src="<?= $person->avatar->medium_url ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform aspect-square group-focus:scale-105 group-hover:scale-105" loading="lazy" />
+            <img alt="<?= esc($person->full_name) ?>" src="<?= $person->avatar->medium_url ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform aspect-square group-focus:scale-105 group-hover:scale-105" loading="lazy" />
         </div>
         <div class="absolute z-20">
-            <h2 class="px-4 py-2 font-semibold leading-tight"><?= $person->full_name ?></h2>
+            <h2 class="px-4 py-2 font-semibold leading-tight"><?= esc($person->full_name) ?></h2>
         </div>
     </a>
     <button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $person->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $person->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
diff --git a/themes/cp_admin/person/edit.php b/themes/cp_admin/person/edit.php
index 2c23a2eaf5..b31504ed7b 100644
--- a/themes/cp_admin/person/edit.php
+++ b/themes/cp_admin/person/edit.php
@@ -23,7 +23,7 @@
 
 <Forms.Field
     name="full_name"
-    value="<?= $person->full_name ?>"
+    value="<?= esc($person->full_name) ?>"
     label="<?= lang('Person.form.full_name') ?>"
     hint="<?= lang('Person.form.full_name_hint') ?>"
     required="true"
@@ -31,7 +31,7 @@
 
 <Forms.Field
     name="unique_name"
-    value="<?= $person->unique_name ?>"
+    value="<?= esc($person->unique_name) ?>"
     label="<?= lang('Person.form.unique_name') ?>"
     hint="<?= lang('Person.form.unique_name_hint') ?>"
     required="true"
@@ -41,7 +41,7 @@
     name="information_url"
     label="<?= lang('Person.form.information_url') ?>"
     hint="<?= lang('Person.form.information_url_hint') ?>"
-    value="<?= $person->information_url ?>" />
+    value="<?= esc($person->information_url) ?>" />
 
 <Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_edit') ?></Button>
 
diff --git a/themes/cp_admin/person/view.php b/themes/cp_admin/person/view.php
index 87c2c3a92c..4956b3cca3 100644
--- a/themes/cp_admin/person/view.php
+++ b/themes/cp_admin/person/view.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $person->full_name ?>
+<?= esc($person->full_name) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $person->full_name ?>
+<?= esc($person->full_name) ?>
 
 <?= $this->endSection() ?>
 
@@ -18,13 +18,13 @@
 <div class="flex flex-wrap gap-2">
     <img
         src="<?= $person->avatar->medium_url ?>"
-        alt="<?= $person->full_name ?>"
+        alt="<?= esc($person->full_name) ?>"
         class="object-cover w-full max-w-xs rounded aspect-square"
         loading="lazy"
     />
     <div class="flex flex-col">
-        <?= $person->full_name ?>
-        <a class="font-semibold no-underline text-accent-base hover:underline" href="<?= $person->information_url ?>"><?= $person->information_url ?></a>
+        <?= esc($person->full_name) ?>
+        <a class="font-semibold no-underline text-accent-base hover:underline" href="<?= esc($person->information_url) ?>"><?= esc($person->information_url) ?></a>
     </div>
 </div>
 
diff --git a/themes/cp_admin/podcast/_card.php b/themes/cp_admin/podcast/_card.php
index 9fc16545da..61a60330fd 100644
--- a/themes/cp_admin/podcast/_card.php
+++ b/themes/cp_admin/podcast/_card.php
@@ -3,12 +3,12 @@
         <div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient mix-blend-multiply"></div>
         <div class="w-full h-full overflow-hidden bg-header">
             <img
-            alt="<?= $podcast->title ?>"
+            alt="<?= esc($podcast->title) ?>"
             src="<?= $podcast->cover->medium_url ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform aspect-square group-focus:scale-105 group-hover:scale-105" loading="lazy" />
         </div>
         <div class="absolute z-20 w-full px-4 pb-4 transition duration-75 ease-out translate-y-6 group-focus:translate-y-0 group-hover:translate-y-0">
-            <h2 class="font-bold leading-none truncate font-display"><?= $podcast->title ?></h2>
-            <p class="text-sm transition duration-150 opacity-0 group-focus:opacity-100 group-hover:opacity-100">@<?= $podcast->handle ?></p>
+            <h2 class="font-bold leading-none truncate font-display"><?= esc($podcast->title) ?></h2>
+            <p class="text-sm transition duration-150 opacity-0 group-focus:opacity-100 group-hover:opacity-100">@<?= esc($podcast->handle) ?></p>
         </div>
     </a>
     <button class="absolute top-0 right-0 z-10 p-2 mt-2 mr-2 text-white transition -translate-y-12 rounded-full opacity-0 focus:ring-accent focus:opacity-100 focus:-translate-y-0 group-hover:translate-y-0 bg-black/50 group-hover:opacity-100" id="more-dropdown-<?= $podcast->id ?>" data-dropdown="button" data-dropdown-target="more-dropdown-<?= $podcast->id ?>-menu" aria-haspopup="true" aria-expanded="false" title="<?= lang('Common.more') ?>"><?= icon('more') ?></button>
diff --git a/themes/cp_admin/podcast/_sidebar.php b/themes/cp_admin/podcast/_sidebar.php
index 574fd9e526..dadafde874 100644
--- a/themes/cp_admin/podcast/_sidebar.php
+++ b/themes/cp_admin/podcast/_sidebar.php
@@ -38,19 +38,19 @@ $podcastNavigation = [
 <div class="flex items-center px-4 py-2 border-b border-navigation">
     <img
     src="<?= $podcast->cover->thumbnail_url ?>"
-    alt="<?= $podcast->title ?>"
+    alt="<?= esc($podcast->title) ?>"
     class="object-cover w-16 h-16 rounded aspect-square"
     loading="lazy"
     />
     <div class="flex flex-col items-start flex-1 w-48 px-2">
-        <span class="w-full font-semibold truncate" title="<?= $podcast->title ?>"><?= $podcast->title ?></span>
+        <span class="w-full font-semibold truncate" title="<?= esc($podcast->title) ?>"><?= esc($podcast->title) ?></span>
         <a href="<?= route_to(
     'podcast-activity',
-    $podcast->handle,
+    esc($podcast->handle),
 ) ?>" class="inline-flex items-center text-sm hover:underline focus:ring-accent"
         data-tooltip="bottom" title="<?= lang(
     'PodcastNavigation.go_to_page',
-) ?>">@<?= $podcast->handle ?>
+) ?>">@<?= esc($podcast->handle) ?>
         <?= icon('external-link', 'ml-1 opacity-60') ?>
         </a>
     </div>
diff --git a/themes/cp_admin/podcast/analytics/index.php b/themes/cp_admin/podcast/analytics/index.php
index cf207790c2..f9740c3c08 100644
--- a/themes/cp_admin/podcast/analytics/index.php
+++ b/themes/cp_admin/podcast/analytics/index.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/analytics/listening_time.php b/themes/cp_admin/podcast/analytics/listening_time.php
index 6a6e45c636..a835497acc 100644
--- a/themes/cp_admin/podcast/analytics/listening_time.php
+++ b/themes/cp_admin/podcast/analytics/listening_time.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/analytics/locations.php b/themes/cp_admin/podcast/analytics/locations.php
index 76ddd8bf05..2e00943061 100644
--- a/themes/cp_admin/podcast/analytics/locations.php
+++ b/themes/cp_admin/podcast/analytics/locations.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/analytics/players.php b/themes/cp_admin/podcast/analytics/players.php
index d3eba7843b..38be6fa087 100644
--- a/themes/cp_admin/podcast/analytics/players.php
+++ b/themes/cp_admin/podcast/analytics/players.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/analytics/time_periods.php b/themes/cp_admin/podcast/analytics/time_periods.php
index 00d37795ab..46a4db2f8a 100644
--- a/themes/cp_admin/podcast/analytics/time_periods.php
+++ b/themes/cp_admin/podcast/analytics/time_periods.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/analytics/unique_listeners.php b/themes/cp_admin/podcast/analytics/unique_listeners.php
index 088c396f62..d4de1c72af 100644
--- a/themes/cp_admin/podcast/analytics/unique_listeners.php
+++ b/themes/cp_admin/podcast/analytics/unique_listeners.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/analytics/webpages.php b/themes/cp_admin/podcast/analytics/webpages.php
index 3f2033576a..9ede392b1a 100644
--- a/themes/cp_admin/podcast/analytics/webpages.php
+++ b/themes/cp_admin/podcast/analytics/webpages.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('content') ?>
diff --git a/themes/cp_admin/podcast/edit.php b/themes/cp_admin/podcast/edit.php
index 10e32c3354..661c111148 100644
--- a/themes/cp_admin/podcast/edit.php
+++ b/themes/cp_admin/podcast/edit.php
@@ -27,11 +27,11 @@
     <?php endif; ?>
     <img src="<?= $podcast->banner->small_url ?>" alt="" class="w-full aspect-[3/1] bg-header" loading="lazy" />
     <div class="flex px-4 py-2">
-        <img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= $podcast->title ?>"
+        <img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= esc($podcast->title) ?>"
             class="w-16 h-16 mr-4 -mt-8 rounded-full ring-2 ring-background-elevated aspect-square" loading="lazy" />
         <div class="flex flex-col">
-            <p class="font-semibold leading-none"><?= $podcast->title ?></p>
-            <p class="text-sm text-skin-muted">@<?= $podcast->handle ?></p>
+            <p class="font-semibold leading-none"><?= esc($podcast->title) ?></p>
+            <p class="text-sm text-skin-muted">@<?= esc($podcast->handle) ?></p>
         </div>
     </div>
 </div>
@@ -60,7 +60,7 @@
     name="title"
     label="<?= lang('Podcast.form.title') ?>"
     helper="<?= $podcast->link ?>"
-    value="<?= $podcast->title ?>"
+    value="<?= esc($podcast->title) ?>"
     required="true" />
 
 <Forms.Field
@@ -144,7 +144,7 @@
 <Forms.Field
     name="owner_name"
     label="<?= lang('Podcast.form.owner_name') ?>"
-    value="<?= $podcast->owner_name ?>"
+    value="<?= esc($podcast->owner_name) ?>"
     hint="<?= lang('Podcast.form.owner_name_hint') ?>"
     required="true" />
 
@@ -152,20 +152,20 @@
     name="owner_email"
     type="email"
     label="<?= lang('Podcast.form.owner_email') ?>"
-    value="<?= $podcast->owner_email ?>"
+    value="<?= esc($podcast->owner_email) ?>"
     hint="<?= lang('Podcast.form.owner_email_hint') ?>"
     required="true" />
 
 <Forms.Field
     name="publisher"
     label="<?= lang('Podcast.form.publisher') ?>"
-    value="<?= $podcast->publisher ?>"
+    value="<?= esc($podcast->publisher) ?>"
     hint="<?= lang('Podcast.form.publisher_hint') ?>" />
 
 <Forms.Field
     name="copyright"
     label="<?= lang('Podcast.form.copyright') ?>"
-    value="<?= $podcast->copyright ?>" />
+    value="<?= esc($podcast->copyright) ?>" />
 
 </Forms.Section>
 
@@ -176,7 +176,7 @@
 <Forms.Field
     name="location_name"
     label="<?= lang('Podcast.form.location_name') ?>"
-    value="<?= $podcast->location_name ?>"
+    value="<?= esc($podcast->location_name) ?>"
     hint="<?= lang('Podcast.form.location_name_hint') ?>" />
 
 </Forms.Section>
@@ -188,7 +188,7 @@
 <Forms.Field
     name="payment_pointer"
     label="<?= lang('Podcast.form.payment_pointer') ?>"
-    value="<?= $podcast->payment_pointer ?>"
+    value="<?= esc($podcast->payment_pointer) ?>"
     hint="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
 
 <fieldset class="flex flex-col items-start p-4 rounded bg-base">
@@ -196,16 +196,16 @@
     <div class="flex flex-col w-full clear-left gap-x-2 gap-y-4 md:flex-row">
         <div class="flex flex-col flex-shrink w-32">
             <Forms.Label for="partner_id" hint="<?= lang('Podcast.form.partner_id_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_id') ?></Forms.Label>
-            <Forms.Input name="partner_id" value="<?= $podcast->partner_id ?>" />
+            <Forms.Input name="partner_id" value="<?= esc($podcast->partner_id) ?>" />
         </div>
         <div class="flex flex-col flex-1">
             <Forms.Label for="partner_link_url" hint="<?= lang('Podcast.form.partner_link_url_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_link_url') ?></Forms.Label>
-            <Forms.Input name="partner_link_url" value="<?= $podcast->partner_link_url ?>" />
+            <Forms.Input name="partner_link_url" value="<?= esc($podcast->partner_link_url) ?>" />
         </div>
     </div>
     <div class="flex flex-col w-full mt-2">
         <Forms.Label for="partner_image_url" hint="<?= lang('Podcast.form.partner_image_url_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_image_url') ?></Forms.Label>
-        <Forms.Input name="partner_image_url" value="<?= $podcast->partner_image_url ?>" />
+        <Forms.Input name="partner_image_url" value="<?= esc($podcast->partner_image_url) ?>" />
     </div>
 </fieldset>
 </Forms.Section>
@@ -226,7 +226,7 @@
     type="url"
     label="<?= lang('Podcast.form.new_feed_url') ?>"
     hint="<?= lang('Podcast.form.new_feed_url_hint') ?>"
-    value="<?= $podcast->new_feed_url ?>"
+    value="<?= esc($podcast->new_feed_url) ?>"
 />
 
 </Forms.Section>
diff --git a/themes/cp_admin/podcast/persons.php b/themes/cp_admin/podcast/persons.php
index 542642babb..7b127d630b 100644
--- a/themes/cp_admin/podcast/persons.php
+++ b/themes/cp_admin/podcast/persons.php
@@ -55,9 +55,9 @@
                 return '<div class="flex">' .
                     '<a href="' .
                     route_to('person-view', $person->id) .
-                    "\"><img src=\"{$person->avatar->thumbnail_url}\" alt=\"{$person->full_name}\" class=\"object-cover aspect-square w-16 h-16 rounded-full\" loading=\"lazy\" /></a>" .
+                    '"><img src="' . $person->avatar->thumbnail_url . '" alt="' . esc($person->full_name) . '" class="object-cover w-16 h-16 rounded-full aspect-square" loading="lazy" /></a>' .
                     '<div class="flex flex-col ml-3">' .
-                    $person->full_name .
+                    esc($person->full_name) .
                     implode(
                         '',
                         array_map(function ($role) {
@@ -74,8 +74,8 @@
                     ) .
                     ($person->information_url === null
                         ? ''
-                        : "<a href=\"{$person->information_url}\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"font-semibold text-sm text-accent-base hover:text-accent-hover\">" .
-                            $person->information_url .
+                        : '<a href="' . esc($person->information_url) . '" target="_blank" rel="noreferrer noopener" class="text-sm font-semibold text-accent-base hover:text-accent-hover">' .
+                            esc($person->information_url) .
                             '</a>') .
                     '</div></div>';
             },
diff --git a/themes/cp_admin/podcast/platforms.php b/themes/cp_admin/podcast/platforms.php
index 8bb37fd188..45771d39b8 100644
--- a/themes/cp_admin/podcast/platforms.php
+++ b/themes/cp_admin/podcast/platforms.php
@@ -23,7 +23,7 @@
     <div class="flex flex-col items-center w-12 mr-4">
         <?php if ($platform->submit_url === ''): ?>
             <?= icon(
-    $platform->slug,
+    esc($platform->slug),
     'text-skin-muted text-4xl',
     $platform->type
 ) ?>
@@ -31,7 +31,7 @@
             <?= anchor(
     $platform->submit_url,
     icon(
-        $platform->slug,
+        esc($platform->slug),
         'text-skin-muted text-4xl',
         $platform->type
     ),
@@ -75,7 +75,7 @@
                 route_to(
                     'podcast-platform-remove',
                     $podcast->id,
-                    $platform->slug,
+                    esc($platform->slug),
                 ),
                 icon('delete-bin', 'mx-auto'),
                 [
@@ -92,18 +92,18 @@
             <legend class="mb-2 font-semibold"><?= $platform->label ?></legend>
             <Forms.Input
                 class="w-full mb-1"
-                id="<?= $platform->slug . '_link_url' ?>"
-                name="<?= 'platforms[' . $platform->slug . '][url]' ?>"
-                value="<?= $platform->link_url ?>"
+                id="<?= esc($platform->slug) . '_link_url' ?>"
+                name="<?= 'platforms[' . esc($platform->slug) . '][url]' ?>"
+                value="<?= esc($platform->link_url) ?>"
                 type="url"
                 placeholder="https://…" />
             <Forms.Input
                 class="w-full mb-1"
-                id="<?= $platform->slug . '_account_id' ?>"
-                name="<?= 'platforms[' . $platform->slug . '][account_id]' ?>"
-                value="<?= $platform->account_id ?>"
+                id="<?= esc($platform->slug) . '_account_id' ?>"
+                name="<?= 'platforms[' . esc($platform->slug) . '][account_id]' ?>"
+                value="<?= esc($platform->account_id) ?>"
                 placeholder="<?= lang("Platforms.description.{$platform->type}") ?>" />
-            <Forms.Toggler size="small" class="text-sm" id="<?= $platform->slug . '_visible' ?>" name="<?= 'platforms[' . $platform->slug . '][visible]'?>" value="yes" checked="<?= old($platform->slug . '_visible', $platform->is_visible ? 'true' : 'false') ?>"><?= lang('Platforms.visible') ?></Forms.Toggler>
+            <Forms.Toggler size="small" class="text-sm" id="<?= esc($platform->slug) . '_visible' ?>" name="<?= 'platforms[' . esc($platform->slug) . '][visible]'?>" value="yes" checked="<?= old(esc($platform->slug) . '_visible', $platform->is_visible ? 'true' : 'false') ?>"><?= lang('Platforms.visible') ?></Forms.Toggler>
         </fieldset>
     </div>
 </div>
diff --git a/themes/cp_admin/podcast/view.php b/themes/cp_admin/podcast/view.php
index 0595700821..45f564e0bb 100644
--- a/themes/cp_admin/podcast/view.php
+++ b/themes/cp_admin/podcast/view.php
@@ -1,11 +1,11 @@
 <?= $this->extend('_layout') ?>
 
 <?= $this->section('title') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
-<?= $podcast->title ?>
+<?= esc($podcast->title) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('headerRight') ?>
diff --git a/themes/cp_admin/settings/general.php b/themes/cp_admin/settings/general.php
index b6d2b19df1..1bafc54608 100644
--- a/themes/cp_admin/settings/general.php
+++ b/themes/cp_admin/settings/general.php
@@ -20,16 +20,16 @@
     <Forms.Field
         name="site_name"
         label="<?= lang('Settings.instance.site_name') ?>"
-        value="<?= service('settings')
-    ->get('App.siteName') ?>"
+        value="<?= esc(service('settings')
+    ->get('App.siteName')) ?>"
         required="true" />
 
     <Forms.Field
         as="Textarea"
         name="site_description"
         label="<?= lang('Settings.instance.site_description') ?>"
-        value="<?= service('settings')
-    ->get('App.siteDescription') ?>"
+        value="<?= esc(service('settings')
+    ->get('App.siteDescription')) ?>"
         required="true"
         rows="4" />
 
@@ -46,7 +46,7 @@
         <?php if (config('App')->siteIcon['ico'] !== service('settings')->get('App.siteIcon')['ico']): ?>
         <div class="relative ml-2">
             <a href="<?= route_to('settings-instance-delete-icon') ?>" class="absolute p-1 text-red-700 bg-red-100 border-2 rounded-full hover:text-red-900 border-contrast -top-3 -right-3 focus:ring-accent" title="<?= lang('Settings.instance.site_icon_delete') ?>" data-tooltip="top"><?= icon('delete-bin') ?></a>
-            <img src="<?= service('settings')->get('App.siteIcon')['64'] ?>" alt="<?= service('settings')->get('App.siteName') ?> Favicon" class="w-10 h-10 aspect-square" loading="lazy" />
+            <img src="<?= service('settings')->get('App.siteIcon')['64'] ?>" alt="<?= esc(service('settings')->get('App.siteName')) ?> Favicon" class="w-10 h-10 aspect-square" loading="lazy" />
         </div>
         <?php endif; ?>
     </div>
diff --git a/themes/cp_admin/user/edit.php b/themes/cp_admin/user/edit.php
index 3fdd98bc61..88c641d866 100644
--- a/themes/cp_admin/user/edit.php
+++ b/themes/cp_admin/user/edit.php
@@ -2,13 +2,13 @@
 
 <?= $this->section('title') ?>
 <?= lang('User.edit_roles', [
-    'username' => $user->username,
+    'username' => esc($user->username),
 ]) ?>
 <?= $this->endSection() ?>
 
 <?= $this->section('pageTitle') ?>
 <?= lang('User.edit_roles', [
-    'username' => $user->username,
+    'username' => esc($user->username),
 ]) ?>
 <?= $this->endSection() ?>
 
diff --git a/themes/cp_admin/user/list.php b/themes/cp_admin/user/list.php
index d5fa1445a2..54c7bdb654 100644
--- a/themes/cp_admin/user/list.php
+++ b/themes/cp_admin/user/list.php
@@ -21,7 +21,7 @@
             'header' => lang('User.list.user'),
             'cell' => function ($user) {
                 return '<div class="flex flex-col">' .
-                    $user->username .
+                    esc($user->username) .
                     '<span class="text-sm text-skin-muted">' .
                     $user->email .
                     '</span></div>';
@@ -32,7 +32,7 @@
             'cell' => function ($user) {
                 return implode(',', $user->roles) .
                     '<IconButton uri="' . route_to('user-edit', $user->id) . '" glyph="edit" variant="info">' . lang('User.edit_roles', [
-                        'username' => $user->username,
+                        'username' => esc($user->username),
                     ]) . '</IconButton>';
             },
         ],
diff --git a/themes/cp_admin/user/view.php b/themes/cp_admin/user/view.php
index 402fe327e7..5213a16a7e 100644
--- a/themes/cp_admin/user/view.php
+++ b/themes/cp_admin/user/view.php
@@ -2,7 +2,7 @@
 
 <?= $this->section('title') ?>
 <?= lang('User.view', [
-    'username' => $user->username,
+    'username' => esc($user->username),
 ]) ?>
 <?= $this->endSection() ?>
 
diff --git a/themes/cp_app/_admin_navbar.php b/themes/cp_app/_admin_navbar.php
index f2aaa7c06e..f2a4100426 100644
--- a/themes/cp_app/_admin_navbar.php
+++ b/themes/cp_app/_admin_navbar.php
@@ -22,16 +22,17 @@
                 <?= user()
                     ->podcasts === [] ? '' : '<img src="' . interact_as_actor()->avatar_image_url . '" class="absolute bottom-0 w-4 h-4 border rounded-full -right-1 border-navigation-bg" loading="lazy" />' ?>
             </div>
-            <?= user()->username ?>
+            <?= esc(user()->username) ?>
             <?= icon('caret-down', 'ml-auto text-2xl') ?></button>
         <?php
             $interactButtons = '';
             foreach (user()->podcasts as $userPodcast) {
                 $checkMark = interact_as_actor_id() === $userPodcast->actor_id ? icon('check', 'ml-2 bg-accent-base text-accent-contrast rounded-full') : '';
+                $userPodcastTitle = esc($userPodcast->title);
 
                 $interactButtons .= <<<CODE_SAMPLE
                     <button class="inline-flex items-center w-full px-4 py-1 hover:bg-highlight" id="interact-as-actor-{$userPodcast->id}" name="actor_id" value="{$userPodcast->actor_id}">
-                        <div class="inline-flex items-center flex-1 text-sm"><img src="{$userPodcast->cover->tiny_url}" class="w-6 h-6 mr-2 rounded-full" loading="lazy" /><span class="truncate">{$userPodcast->title}</span>{$checkMark}</div>
+                        <div class="inline-flex items-center flex-1 text-sm"><img src="{$userPodcast->cover->tiny_url}" class="w-6 h-6 mr-2 rounded-full" loading="lazy" /><span class="max-w-xs truncate">{$userPodcastTitle}</span>{$checkMark}</div>
                     </button>
                 CODE_SAMPLE;
             }
diff --git a/themes/cp_app/_persons_modal.php b/themes/cp_app/_persons_modal.php
index f2be55dc8c..6294fe90c7 100644
--- a/themes/cp_app/_persons_modal.php
+++ b/themes/cp_app/_persons_modal.php
@@ -17,13 +17,13 @@
         <div class="flex flex-col items-start p-4 gap-y-4">
             <?php foreach ($persons as $person): ?>
                 <div class="flex gap-x-2">
-                    <img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-10 rounded-full bg-header aspect-square" loading="lazy" />
+                    <img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= esc($person->full_name) ?>" class="object-cover w-10 rounded-full bg-header aspect-square" loading="lazy" />
                     <div class="flex flex-col">
                         <h4 class="text-sm font-semibold">
                             <?php if ($person->information_url): ?>
-                                <a href="<?= $person->information_url ?>" class="hover:underline focus:ring-accent" target="_blank" rel="noopener noreferrer"><?= $person->full_name ?></a>
+                                <a href="<?= esc($person->information_url) ?>" class="hover:underline focus:ring-accent" target="_blank" rel="noopener noreferrer"><?= esc($person->full_name) ?></a>
                             <?php else: ?>
-                                <?= $person->full_name ?>
+                                <?= esc($person->full_name) ?>
                             <?php endif; ?>
                         </h4>
                         <p class="text-xs text-skin-muted"><?= implode(
diff --git a/themes/cp_app/embed.php b/themes/cp_app/embed.php
index 175129240c..8e858f0bc9 100644
--- a/themes/cp_app/embed.php
+++ b/themes/cp_app/embed.php
@@ -5,7 +5,7 @@
 <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-    <title><?= $episode->title ?></title>
+    <title><?= esc($episode->title) ?></title>
     <meta name="description" content="<?= htmlspecialchars(
         $episode->description,
     ) ?>" />
@@ -20,17 +20,17 @@
 </head>
 
 <body class="flex" style="background: <?= $themeData['background'] ?>; color: <?= $themeData['text'] ?>;">
-    <img src="<?= $episode->cover->thumbnail_url ?>" alt="<?= $episode->title ?>" class="flex-shrink w-28 h-28 aspect-square" loading="lazy" />
+    <img src="<?= $episode->cover->thumbnail_url ?>" alt="<?= esc($episode->title) ?>" class="flex-shrink w-28 h-28 aspect-square" loading="lazy" />
     <div class="flex flex-col items-start flex-1 min-w-0 px-4 pt-4 h-28">
         <a href="https://castopod.org/" class="absolute top-0 right-0 mt-1 mr-2 text-2xl text-pine-500 hover:opacity-75" title="<?= lang('Common.powered_by', [
             'castopod' => 'Castopod',
         ]) ?>" target="_blank" rel="noopener noreferrer"><?= icon('castopod', '', 'podcasting') ?></a>
         <div class="flex gap-x-2">
             <?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold !no-underline border px-1 border-gray-500', true) ?>
-            <a href="<?= route_to('podcast-activity', $podcast->handle) ?>" style="color: <?= $themeData['text'] ?>;" class="text-xs truncate opacity-75 hover:opacity-100" target="_blank" rel="noopener noreferrer"><?= $podcast->title ?></a>
+            <a href="<?= route_to('podcast-activity', esc($podcast->handle)) ?>" style="color: <?= $themeData['text'] ?>;" class="text-xs truncate opacity-75 hover:opacity-100" target="_blank" rel="noopener noreferrer"><?= esc($podcast->title) ?></a>
         </div>
         <a href="<?= $episode->link ?>" class="flex flex-col items-start text-sm" style="color: <?= $themeData['text'] ?>;" target="_blank" rel="noopener noreferrer">
-            <h1 class="font-semibold leading-tight opacity-100 line-clamp-2 hover:opacity-75"><?= $episode->title ?></h1>
+            <h1 class="font-semibold leading-tight opacity-100 line-clamp-2 hover:opacity-75"><?= esc($episode->title) ?></h1>
         </a>
         <vm-player
                 id="castopod-vm-player"
diff --git a/themes/cp_app/episode/_layout.php b/themes/cp_app/episode/_layout.php
index ddbfd16e56..aa047ddb3f 100644
--- a/themes/cp_app/episode/_layout.php
+++ b/themes/cp_app/episode/_layout.php
@@ -10,7 +10,7 @@
     <link rel="icon" type="image/x-icon" href="<?= service('settings')
     ->get('App.siteIcon')['ico'] ?>" />
     <link rel="apple-touch-icon" href="<?= service('settings')->get('App.siteIcon')['180'] ?>">
-    <link rel="manifest" href="<?= route_to('podcast-webmanifest', $podcast->handle) ?>">
+    <link rel="manifest" href="<?= route_to('podcast-webmanifest', esc($podcast->handle)) ?>">
     <meta name="theme-color" content="<?= \App\Controllers\WebmanifestController::THEME_COLORS[service('settings')->get('App.theme')]['theme'] ?>">
     <script>
     // Check that service workers are supported
@@ -44,14 +44,14 @@
     <?php endif; ?>
 
     <nav class="flex items-center justify-between h-10 col-start-2 text-white bg-header">
-        <a href="<?= route_to('podcast-episodes', $podcast->handle) ?>" class="inline-flex items-center h-full px-2 focus:ring-accent focus:ring-inset" title="<?= lang('Episode.back_to_episodes', [
-            'podcast' => $podcast->title,
+        <a href="<?= route_to('podcast-episodes', esc($podcast->handle)) ?>" class="flex items-center flex-1 h-full min-w-0 px-2 gap-x-2 focus:ring-accent focus:ring-inset" title="<?= lang('Episode.back_to_episodes', [
+            'podcast' => esc($podcast->title),
         ]) ?>">
-            <?= icon('arrow-left', 'mr-2 text-lg') ?>
-            <div class="inline-flex items-center gap-x-2">
-                <img class="w-8 h-8 rounded-full" src="<?= $episode->podcast->cover->tiny_url ?>" alt="<?= $episode->podcast->title ?>" loading="lazy" />
-                <div class="flex flex-col">
-                    <span class="text-sm font-semibold leading-none"><?= $episode->podcast->title ?></span>
+            <?= icon('arrow-left', 'text-lg') ?>
+            <div class="flex items-center flex-1 min-w-0 gap-x-2">
+                <img class="w-8 h-8 rounded-full" src="<?= $episode->podcast->cover->tiny_url ?>" alt="<?= esc($episode->podcast->title) ?>" loading="lazy" />
+                <div class="flex flex-col flex-1 overflow-hidden">
+                    <span class="text-sm font-semibold leading-none truncate"><?= esc($episode->podcast->title) ?></span>
                     <span class="text-xs"><?= lang('Podcast.followers', [
                         'numberOfFollowers' => $podcast->actor->followers_count,
                     ]) ?></span>
@@ -63,7 +63,7 @@
                 <button class="p-2 text-red-600 bg-white rounded-full shadow hover:text-red-500 focus:ring-accent" data-toggle="funding-links" data-toggle-class="hidden" title="<?= lang('Podcast.sponsor') ?>"><Icon glyph="heart"></Icon></button>
             <?php endif; ?>
             <?= anchor_popup(
-                        route_to('follow', $podcast->handle),
+                        route_to('follow', esc($podcast->handle)),
                         icon(
                             'social/castopod',
                             'mr-2 text-xl text-black/75 group-hover:text-black',
@@ -81,20 +81,20 @@
         <div class="absolute top-0 left-0 w-full h-full bg-center bg-no-repeat bg-cover blur-lg mix-blend-overlay filter grayscale" style="background-image: url('<?= $episode->podcast->banner->small_url ?>');"></div>
         <div class="absolute top-0 left-0 w-full h-full bg-gradient-to-t from-background-header to-transparent"></div>
         <div class="z-10 flex flex-col items-start gap-y-2 gap-x-4 sm:flex-row">
-            <div class="relative">
+            <div class="relative flex-shrink-0">
                 <?= explicit_badge($episode->parental_advisory === 'explicit', 'rounded absolute left-0 bottom-0 ml-2 mb-2 bg-black/75 text-accent-contrast') ?>
-                <img src="<?= $episode->cover->medium_url ?>" alt="<?= $episode->title ?>" class="rounded-md shadow-xl h-36 aspect-square" loading="lazy" />
+                <img src="<?= $episode->cover->medium_url ?>" alt="<?= esc($episode->title) ?>" class="flex-shrink-0 rounded-md shadow-xl h-36 aspect-square" loading="lazy" />
             </div>
-            <div class="flex flex-col items-start text-white">
+            <div class="flex flex-col items-start w-full min-w-0 text-white">
                 <?= episode_numbering($episode->number, $episode->season_number, 'text-sm leading-none font-semibold px-1 py-1 text-white/90 border !no-underline border-subtle', true) ?>
-                <h1 class="inline-flex items-baseline max-w-md mt-2 text-2xl font-bold sm:leading-none sm:text-3xl font-display line-clamp-2"><?= $episode->title ?></h1>
-                <div class="flex items-center mt-4 gap-x-8">
+                <h1 class="inline-flex items-baseline max-w-lg mt-2 text-2xl font-bold sm:leading-none sm:text-3xl font-display line-clamp-2" title="<?= esc($episode->title) ?>"><?= esc($episode->title) ?></h1>
+                <div class="flex items-center w-full mt-4 gap-x-8">
                 <?php if ($episode->persons !== []): ?>
-                    <button class="flex items-center text-xs font-semibold gap-x-2 hover:underline focus:ring-accent" data-toggle="persons-list" data-toggle-class="hidden">
+                    <button class="flex items-center flex-shrink-0 text-xs font-semibold gap-x-2 hover:underline focus:ring-accent" data-toggle="persons-list" data-toggle-class="hidden">
                         <span class="inline-flex flex-row-reverse">
                             <?php $i = 0; ?>
                             <?php foreach ($episode->persons as $person): ?>
-                                <img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-8 h-8 -ml-4 border-2 rounded-full aspect-square border-background-header last:ml-0" loading="lazy" />
+                                <img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= esc($person->full_name) ?>" class="object-cover w-8 h-8 -ml-4 border-2 rounded-full aspect-square border-background-header last:ml-0" loading="lazy" />
                                 <?php $i++; if ($i === 3) {
                         break;
                     }?>
@@ -115,8 +115,8 @@
             <play-episode-button
                 id="<?= $episode->id ?>"
                 imageSrc="<?= $episode->cover->thumbnail_url ?>"
-                title="<?= $episode->title ?>"
-                podcast="<?= $episode->podcast->title ?>"
+                title="<?= esc($episode->title) ?>"
+                podcast="<?= esc($episode->podcast->title) ?>"
                 src="<?= $episode->audio_web_url ?>"
                 mediaType="<?= $episode->audio->file_mimetype ?>"
                 playLabel="<?= lang('Common.play_episode_button.play') ?>"
@@ -148,10 +148,9 @@
     </div>
     <?= view('_persons_modal', [
         'title' => lang('Episode.persons_list', [
-            'episodeTitle' => $episode->title,
+            'episodeTitle' => esc($episode->title),
         ]),
-        'persons' => $episode->
-persons,
+        'persons' => $episode->persons,
     ]) ?>
     <?php if (in_array(true, array_column($podcast->fundingPlatforms, 'is_visible'), true)): ?>
         <?= $this->include('podcast/_partials/funding_links_modal') ?>
diff --git a/themes/cp_app/episode/_partials/card.php b/themes/cp_app/episode/_partials/card.php
index 9b53fdb1d4..00a26425b7 100644
--- a/themes/cp_app/episode/_partials/card.php
+++ b/themes/cp_app/episode/_partials/card.php
@@ -4,7 +4,7 @@
             <?= format_duration($episode->audio->duration) ?>
         </time>
         <img src="<?= $episode->cover
-                ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="object-cover w-20 rounded-lg shadow-inner aspect-square" loading="lazy" />
+                ->thumbnail_url ?>" alt="<?= esc($episode->title) ?>" class="object-cover w-20 rounded-lg shadow-inner aspect-square" loading="lazy" />
     </div>
     <div class="flex items-center flex-1 gap-x-4">
         <div class="flex flex-col flex-1">
@@ -12,13 +12,13 @@
                 <?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold border-subtle text-skin-muted px-1 border mr-2 !no-underline', true) ?>
                 <?= relative_time($episode->published_at, 'text-xs whitespace-nowrap text-skin-muted') ?>
             </div>
-            <h2 class="flex-1 mt-1 font-semibold leading-tight line-clamp-2"><a class="hover:underline" href="<?= $episode->link ?>"><?= $episode->title ?></a></h2>
+            <h2 class="flex-1 mt-1 font-semibold leading-tight line-clamp-2"><a class="hover:underline" href="<?= $episode->link ?>"><?= esc($episode->title) ?></a></h2>
         </div>
         <play-episode-button
             id="<?= $episode->id ?>"
             imageSrc="<?= $episode->cover->thumbnail_url ?>"
-            title="<?= $episode->title ?>"
-            podcast="<?= $episode->podcast->title ?>"
+            title="<?= esc($episode->title) ?>"
+            podcast="<?= esc($episode->podcast->title) ?>"
             src="<?= $episode->audio_web_url ?>"
             mediaType="<?= $episode->audio->file_mimetype ?>"
             playLabel="<?= lang('Common.play_episode_button.play') ?>"
diff --git a/themes/cp_app/episode/_partials/comment.php b/themes/cp_app/episode/_partials/comment.php
index 665396c865..22d3da6409 100644
--- a/themes/cp_app/episode/_partials/comment.php
+++ b/themes/cp_app/episode/_partials/comment.php
@@ -1,18 +1,18 @@
 <article class="relative z-10 flex w-full px-4 py-2 rounded-conditional-2xl gap-x-2">
-    <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= $comment->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+    <img src="<?= $comment->actor->avatar_image_url ?>" alt="<?= esc($comment->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
     <div class="flex-1">
         <header class="w-full mb-2 text-sm">
             <a href="<?= $comment->actor
     ->uri ?>" class="flex items-baseline hover:underline" <?= $comment->actor->is_local
                 ? ''
                 : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $comment->actor
-                    ->display_name ?></span>
-                <span class="text-sm truncate text-skin-muted">@<?= $comment->actor
-                    ->username .
+                <span class="mr-2 font-semibold truncate"><?= esc($comment->actor
+                    ->display_name) ?></span>
+                <span class="text-sm truncate text-skin-muted">@<?= esc($comment->actor
+                    ->username) .
                     ($comment->actor->is_local
                         ? ''
-                        : '@' . $comment->actor->domain) ?></span>
+                        : '@' . esc($comment->actor->domain)) ?></span>
                 <?= relative_time($comment->created_at, 'text-xs text-skin-muted ml-auto flex-shrink-0') ?>
             </a>
         </header>
diff --git a/themes/cp_app/episode/_partials/comment_actions.php b/themes/cp_app/episode/_partials/comment_actions.php
index c1fe1244a0..01d062a4ea 100644
--- a/themes/cp_app/episode/_partials/comment_actions.php
+++ b/themes/cp_app/episode/_partials/comment_actions.php
@@ -1,6 +1,6 @@
 <footer>
     <?php if (can_user_interact()): ?>
-        <form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $comment->episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+        <form action="<?= route_to('episode-comment-attempt-like', esc(interact_as_actor()->username), esc($comment->episode->slug), $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
             <?= csrf_field() ?>
             <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
     'Comment.likes',
@@ -8,11 +8,11 @@
         'numberOfLikes' => $comment->likes_count,
     ],
 ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
-            <Button uri="<?= route_to('episode-comment', $comment->episode->podcast->handle, $comment->episode->slug, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
+            <Button uri="<?= route_to('episode-comment', esc($comment->episode->podcast->handle), esc($comment->episode->slug), $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
         </form>
         <?php if ($comment->replies_count): ?>
             <?= anchor(
-    route_to('episode-comment', $comment->episode->podcast->handle, $comment->episode->slug, $comment->id),
+    route_to('episode-comment', esc($comment->episode->podcast->handle), esc($comment->episode->slug), $comment->id),
     icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', [
         'numberOfReplies' => $comment->replies_count,
     ]),
@@ -30,7 +30,7 @@
 ) ?>"><?= icon('heart', 'text-xl mr-1 text-skin-muted') . $comment->likes_count ?></button>
         <?php if ($comment->replies_count): ?>
             <?= anchor(
-    route_to('episode-comment', $comment->episode->podcast->handle, $comment->episode->slug, $comment->id),
+    route_to('episode-comment', esc($comment->episode->podcast->handle), esc($comment->episode->slug), $comment->id),
     icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', [
         'numberOfReplies' => $comment->replies_count,
     ]),
diff --git a/themes/cp_app/episode/_partials/comment_actions_from_post.php b/themes/cp_app/episode/_partials/comment_actions_from_post.php
index fbbb08c246..803b53b688 100644
--- a/themes/cp_app/episode/_partials/comment_actions_from_post.php
+++ b/themes/cp_app/episode/_partials/comment_actions_from_post.php
@@ -1,6 +1,6 @@
 <footer>
     <?php if (can_user_interact()): ?>
-        <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+        <form action="<?= route_to('post-attempt-action', esc(interact_as_actor()->username), $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
         <?= csrf_field() ?>
         <button type="submit" name="action" value="favourite" class="inline-flex items-center hover:underline group" title="<?= lang(
     'Comment.likes',
@@ -8,11 +8,11 @@
         'numberOfLikes' => $comment->likes_count,
     ],
 ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
-            <Button uri="<?= route_to('post', $podcast->handle, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
+            <Button uri="<?= route_to('post', esc($podcast->handle), $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
         </form>
         <?php if ($comment->replies_count): ?>
             <?= anchor(
-    route_to('post', $podcast->handle, $comment->id),
+    route_to('post', esc($podcast->handle), $comment->id),
     icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', [
         'numberOfReplies' => $comment->replies_count,
     ]),
@@ -23,7 +23,7 @@
         <?php endif; ?>
     <?php else: ?>
         <?= anchor_popup(
-    route_to('post-remote-action', $podcast->handle, $comment->id, 'favourite'),
+    route_to('post-remote-action', esc($podcast->handle), $comment->id, 'favourite'),
     icon('heart', 'text-xl mr-1 opacity-40') . $comment->likes_count,
     [
         'class' => 'inline-flex items-center hover:underline',
@@ -36,7 +36,7 @@
 ) ?>
         <?php if ($comment->replies_count): ?>
             <?= anchor(
-    route_to('post', $podcast->handle, $comment->id),
+    route_to('post', esc($podcast->handle), $comment->id),
     icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', [
         'numberOfReplies' => $comment->replies_count,
     ]),
diff --git a/themes/cp_app/episode/_partials/comment_card.php b/themes/cp_app/episode/_partials/comment_card.php
index a54c51c157..bb93771586 100644
--- a/themes/cp_app/episode/_partials/comment_card.php
+++ b/themes/cp_app/episode/_partials/comment_card.php
@@ -5,13 +5,13 @@
             <a href="<?= $comment->actor->uri ?>" class="flex items-baseline hover:underline" <?= $comment->actor->is_local
                 ? ''
                 : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $comment->actor
-                    ->display_name ?></span>
-                <span class="text-sm truncate text-skin-muted">@<?= $comment->actor
-                    ->username .
+                <span class="mr-2 font-semibold truncate"><?= esc($comment->actor
+                    ->display_name) ?></span>
+                <span class="text-sm truncate text-skin-muted">@<?= esc($comment->actor
+                    ->username) .
                     ($comment->actor->is_local
                         ? ''
-                        : '@' . $comment->actor->domain) ?></span>
+                        : '@' . esc($comment->actor->domain)) ?></span>
                 <?= relative_time($comment->created_at, 'text-xs text-skin-muted ml-auto') ?>
             </a>
         </header>
@@ -21,7 +21,7 @@
         <?php else: ?>
             <footer>
                 <?php if (can_user_interact()): ?>
-                    <form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
+                    <form action="<?= route_to('episode-comment-attempt-like', esc(interact_as_actor()->username), esc($episode->slug), $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
                     <?= csrf_field() ?>
 
                     <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
diff --git a/themes/cp_app/episode/_partials/comment_reply.php b/themes/cp_app/episode/_partials/comment_reply.php
index 4fabdde008..d4ac193acb 100644
--- a/themes/cp_app/episode/_partials/comment_reply.php
+++ b/themes/cp_app/episode/_partials/comment_reply.php
@@ -1,16 +1,16 @@
 <article class="flex px-6 py-4 bg-base gap-x-2">
-    <img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor
-    ->display_name ?>" class="z-10 w-10 h-10 rounded-full ring-gray-50 ring-2 aspect-square" loading="lazy" />
+    <img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= esc($reply->actor
+    ->display_name) ?>" class="z-10 w-10 h-10 rounded-full ring-gray-50 ring-2 aspect-square" loading="lazy" />
     <div class="flex flex-col flex-1 min-w-0">
         <header class="flex items-center mb-2">
             <a href="<?= $reply->actor
     ->uri ?>" class="mr-2 text-base font-semibold truncate hover:underline" <?= $reply
     ->actor->is_local
     ? ''
-    : 'target="_blank" rel="noopener noreferrer"' ?>><?= $reply->actor
-        ->display_name ?><span class="ml-1 text-sm font-normal text-skin-muted">@<?= $reply
-        ->actor->username .
-    ($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
+    : 'target="_blank" rel="noopener noreferrer"' ?>><?= esc($reply->actor
+        ->display_name) ?><span class="ml-1 text-sm font-normal text-skin-muted">@<?= esc($reply
+        ->actor->username) .
+    ($reply->actor->is_local ? '' : '@' . esc($reply->actor->domain)) ?></span></a>
             <?= relative_time($reply->created_at, 'flex-shrink-0 ml-auto text-xs text-skin-muted') ?>
         </header>
         <p class="mb-2 post-content"><?= $reply->message_html ?></p>
diff --git a/themes/cp_app/episode/_partials/comment_reply_actions.php b/themes/cp_app/episode/_partials/comment_reply_actions.php
index 2f4be594ea..c906279698 100644
--- a/themes/cp_app/episode/_partials/comment_reply_actions.php
+++ b/themes/cp_app/episode/_partials/comment_reply_actions.php
@@ -1,6 +1,6 @@
 <footer>
     <?php if (can_user_interact()): ?>
-        <form action="<?= route_to('episode-comment-attempt-like', interact_as_actor()->username, $reply->episode->slug, $reply->id) ?>" method="POST" class="flex items-center gap-x-4">
+        <form action="<?= route_to('episode-comment-attempt-like', esc(interact_as_actor()->username), esc($reply->episode->slug), $reply->id) ?>" method="POST" class="flex items-center gap-x-4">
             <?= csrf_field() ?>
 
             <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
@@ -9,7 +9,7 @@
         'numberOfLikes' => $reply->likes_count,
     ],
 ) ?>"><?= icon('heart', 'text-lg mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button>
-            <Button uri="<?= route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
+            <Button uri="<?= route_to('episode-comment', esc($reply->episode->podcast->handle), esc($reply->episode->slug), $reply->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
         </form>
     <?php else: ?>
         <button type="submit" name="action" class="inline-flex items-center opacity-50 cursor-not-allowed" disabled="disabled" title="<?= lang(
@@ -20,7 +20,7 @@
 ) ?>"><?= icon('heart', 'text-lg mr-1 text-skin-muted') . $reply->likes_count ?></button>
             <?php if ($reply->replies_count): ?>
                     <?= anchor(
-    route_to('episode-comment', $reply->episode->podcast->handle, $reply->episode->slug, $reply->id),
+    route_to('episode-comment', esc($reply->episode->podcast->handle), esc($reply->episode->slug), $reply->id),
     icon('chat', 'text-2xl mr-1 opacity-40') . $reply->replies_count,
     [
         'class' => 'inline-flex items-center hover:underline',
diff --git a/themes/cp_app/episode/_partials/comment_with_replies.php b/themes/cp_app/episode/_partials/comment_with_replies.php
index 17c291fb3f..58a3f96c6f 100644
--- a/themes/cp_app/episode/_partials/comment_with_replies.php
+++ b/themes/cp_app/episode/_partials/comment_with_replies.php
@@ -16,15 +16,15 @@ if ($comment->in_reply_to_id): ?>
     <?= csrf_field() ?>
 
     <img src="<?= interact_as_actor()
-        ->avatar_image_url ?>" alt="<?= interact_as_actor()
-        ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+        ->avatar_image_url ?>" alt="<?= esc(interact_as_actor()
+        ->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
     <div class="flex flex-col flex-1">
         <Forms.Textarea
             name="message"
             required="true"
             class="w-full mb-4"
             placeholder="<?= lang('Comment.form.reply_to_placeholder', [
-                'actorUsername' => $comment->actor->username,
+                'actorUsername' => esc($comment->actor->username),
             ]) ?>"
             rows="1" />
         <Button variant="primary" size="small" type="submit" name="action" value="reply" class="self-end" iconRight="send-plane"><?= lang('Comment.form.submit_reply') ?></Button>
diff --git a/themes/cp_app/episode/_partials/navigation.php b/themes/cp_app/episode/_partials/navigation.php
index b88ca10e2e..7f346f9eee 100644
--- a/themes/cp_app/episode/_partials/navigation.php
+++ b/themes/cp_app/episode/_partials/navigation.php
@@ -2,12 +2,12 @@
 
 $navigationItems = [
     [
-        'uri' => route_to('episode', $podcast->handle, $episode->slug),
+        'uri' => route_to('episode', esc($podcast->handle), esc($episode->slug)),
         'label' => lang('Episode.comments'),
         'labelInfo' => $episode->comments_count,
     ],
     [
-        'uri' => route_to('episode-activity', $podcast->handle, $episode->slug),
+        'uri' => route_to('episode-activity', esc($podcast->handle), esc($episode->slug)),
         'label' => lang('Episode.activity'),
         'labelInfo' => $episode->posts_count,
     ],
diff --git a/themes/cp_app/episode/_partials/preview_card.php b/themes/cp_app/episode/_partials/preview_card.php
index 0507fc1513..da0943d520 100644
--- a/themes/cp_app/episode/_partials/preview_card.php
+++ b/themes/cp_app/episode/_partials/preview_card.php
@@ -5,21 +5,21 @@
         </time>
         <img
         src="<?= $episode->cover->thumbnail_url ?>"
-        alt="<?= $episode->title ?>" class="w-24 h-24 aspect-square" loading="lazy" />
+        alt="<?= esc($episode->title) ?>" class="w-24 h-24 aspect-square" loading="lazy" />
     </div>
     <div class="flex flex-col flex-1 px-4 py-2">
         <div class="inline-flex">
             <?= episode_numbering($episode->number, $episode->season_number, 'text-xs font-semibold text-skin-muted px-1 border border-subtle mr-2 !no-underline', true) ?>
             <?= relative_time($episode->published_at, 'text-xs whitespace-nowrap text-skin-muted') ?>
         </div>
-        <a href="<?= $episode->link ?>" class="flex items-baseline font-semibold line-clamp-2" title="<?= $episode->title ?>"><?= $episode->title ?></a>
+        <a href="<?= $episode->link ?>" class="flex items-baseline font-semibold line-clamp-2" title="<?= esc($episode->title) ?>"><?= esc($episode->title) ?></a>
     </div>
     <play-episode-button
         class="mr-4"
         id="<?= $index . '_' . $episode->id ?>"
         imageSrc="<?= $episode->cover->thumbnail_url ?>"
-        title="<?= $episode->title ?>"
-        podcast="<?= $episode->podcast->title ?>"
+        title="<?= esc($episode->title) ?>"
+        podcast="<?= esc($episode->podcast->title) ?>"
         src="<?= $episode->audio_web_url ?>"
         mediaType="<?= $episode->audio->file_mimetype ?>"
         playLabel="<?= lang('Common.play_episode_button.play') ?>"
diff --git a/themes/cp_app/episode/activity.php b/themes/cp_app/episode/activity.php
index 93c0d9043a..293a8c73e7 100644
--- a/themes/cp_app/episode/activity.php
+++ b/themes/cp_app/episode/activity.php
@@ -4,12 +4,12 @@
 
 <?php if (can_user_interact()): ?>
     <?= view('_message_block') ?>
-    <form action="<?= route_to('post-attempt-create', $podcast->handle) ?>" method="POST" class="flex p-4 shadow bg-elevated gap-x-2 rounded-conditional-2xl">
+    <form action="<?= route_to('post-attempt-create', esc($podcast->handle)) ?>" method="POST" class="flex p-4 shadow bg-elevated gap-x-2 rounded-conditional-2xl">
         <?= csrf_field() ?>
 
         <img src="<?= interact_as_actor()
-            ->avatar_image_url ?>" alt="<?= interact_as_actor()
-            ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+            ->avatar_image_url ?>" alt="<?= esc(interact_as_actor()
+            ->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
         <div class="flex flex-col flex-1 min-w-0 gap-y-2">
             <input name="episode_url" value="<?= $episode->link ?>" type="hidden" />
             <Forms.Textarea
diff --git a/themes/cp_app/episode/comment.php b/themes/cp_app/episode/comment.php
index 446bfb143f..18d26a1193 100644
--- a/themes/cp_app/episode/comment.php
+++ b/themes/cp_app/episode/comment.php
@@ -3,7 +3,7 @@
 <?= $this->section('content') ?>
 <div class="max-w-2xl px-6 mx-auto">
     <nav class="mb-2">
-        <a href="<?= route_to('episode', $podcast->handle, $episode->slug) ?>"
+        <a href="<?= route_to('episode', esc($podcast->handle), esc($episode->slug)) ?>"
         class="inline-flex items-center px-4 py-2 text-sm focus:ring-accent"><?= icon(
     'arrow-left',
     'mr-2 text-lg',
diff --git a/themes/cp_app/episode/comments.php b/themes/cp_app/episode/comments.php
index dc6ee95a42..e9242a3139 100644
--- a/themes/cp_app/episode/comments.php
+++ b/themes/cp_app/episode/comments.php
@@ -8,8 +8,8 @@
         <?= csrf_field() ?>
 
         <img src="<?= interact_as_actor()
-            ->avatar_image_url ?>" alt="<?= interact_as_actor()
-            ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+            ->avatar_image_url ?>" alt="<?= esc(interact_as_actor()
+            ->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
         <div class="flex flex-col flex-1 min-w-0 gap-y-2">
             <Forms.Textarea
                 name="message"
diff --git a/themes/cp_app/home.php b/themes/cp_app/home.php
index bb7d725577..eeebcb9c1e 100644
--- a/themes/cp_app/home.php
+++ b/themes/cp_app/home.php
@@ -42,8 +42,8 @@
             'home',
         ) ?>" class="inline-flex items-baseline text-3xl font-semibold font-display"><?= service('settings')
         ->get('App.siteName') === 'Castopod' ? 'castopod' .
-    svg('castopod-logo-base', 'h-6 ml-2') : service('settings')
-        ->get('App.siteName') ?></a>
+    svg('castopod-logo-base', 'h-6 ml-2') : esc(service('settings')
+        ->get('App.siteName')) ?></a>
         </h1>
     </header>
     <main class="container flex-1 px-4 py-10 mx-auto">
@@ -81,11 +81,11 @@
                             <div class="absolute bottom-0 left-0 z-10 w-full h-full backdrop-gradient mix-blend-multiply"></div>
                             <div class="w-full h-full overflow-hidden bg-header">
                                 <?= explicit_badge($podcast->parental_advisory === 'explicit', 'absolute top-0 left-0 z-10 rounded bg-black/75 ml-2 mt-2') ?>
-                                <img alt="<?= $podcast->title ?>" src="<?= $podcast->cover->medium_url ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform bg-header aspect-square group-focus:scale-105 group-hover:scale-105" loading="lazy" />
+                                <img alt="<?= esc($podcast->title) ?>" src="<?= $podcast->cover->medium_url ?>" class="object-cover w-full h-full transition duration-200 ease-in-out transform bg-header aspect-square group-focus:scale-105 group-hover:scale-105" loading="lazy" />
                             </div>
                             <div class="absolute bottom-0 left-0 z-20 w-full px-4 pb-2">
-                                <h3 class="font-bold leading-none truncate font-display"><?= $podcast->title ?></h3>
-                                <p class="text-sm opacity-75">@<?= $podcast->handle ?></p>
+                                <h3 class="font-bold leading-none truncate font-display"><?= esc($podcast->title) ?></h3>
+                                <p class="text-sm opacity-75">@<?= esc($podcast->handle) ?></p>
                             </div>
                         </article>
                     </a>
diff --git a/themes/cp_app/pages/_layout.php b/themes/cp_app/pages/_layout.php
index 839f577f22..ecdb5bcc6f 100644
--- a/themes/cp_app/pages/_layout.php
+++ b/themes/cp_app/pages/_layout.php
@@ -45,7 +45,7 @@
             'arrow-left',
             'mr-2',
         ) . lang('Page.back_to_home') ?></a>
-            <Heading tagName="h1" size="large"><?= $page->title ?></Heading>
+            <Heading tagName="h1" size="large"><?= esc($page->title) ?></Heading>
         </div>
     </header>
     <main class="container flex-1 px-4 py-6 mx-auto">
diff --git a/themes/cp_app/pages/credits.php b/themes/cp_app/pages/credits.php
index fc961cff76..3207d5d6cf 100644
--- a/themes/cp_app/pages/credits.php
+++ b/themes/cp_app/pages/credits.php
@@ -15,17 +15,17 @@
         <?php endif; ?>
         <?php foreach ($groups['persons'] as $persons): ?>
             <div class="flex mt-2 mb-2">
-                <img src="<?= $persons['thumbnail_url'] ?>" alt="<?= $persons[
+                <img src="<?= $persons['thumbnail_url'] ?>" alt="<?= esc($persons[
     'full_name'
-] ?>" class="object-cover w-16 rounded-full aspect-square md:h-24 md:w-24 border-gray" loading="lazy" />
+]) ?>" class="object-cover w-16 rounded-full aspect-square md:h-24 md:w-24 border-gray" loading="lazy" />
                 <div class="flex flex-col ml-3 mr-4">
                     <span class="text-lg font-semibold text-skin-muted md:text-xl">
-                        <?= $persons['full_name'] ?>
+                        <?= esc($persons['full_name']) ?>
                     </span>
                     <?php if ($persons['information_url'] !== null): ?>
-                        <a href="<?= $persons[
+                        <a href="<?= esc($persons[
                             'information_url'
-                        ] ?>" class="text-sm font-semibold text-accent-base hover:underline" target="_blank" rel="noreferrer noopener"><?= $persons[
+                        ]) ?>" class="text-sm font-semibold text-accent-base hover:underline" target="_blank" rel="noreferrer noopener"><?= $persons[
     'information_url'
 ] ?></a>
                     <?php endif; ?>
@@ -36,11 +36,9 @@
                     <?= $role['role_label'] ?>
 
                     <?php foreach ($role['is_in'] as $in): ?>
-                        <a href="<?= $in[
+                        <a href="<?= esc($in[
                             'link'
-                        ] ?>" class="text-sm text-skin-muted hover:underline"><?= $in[
-    'title'
-] ?></a>
+                        ]) ?>" class="text-sm text-skin-muted hover:underline"><?= esc($in['title']) ?></a>
                     <?php endforeach; ?>
                 <?php endforeach; ?>
             </div>
diff --git a/themes/cp_app/pages/map.php b/themes/cp_app/pages/map.php
index 25efdbacd4..44a933ef8b 100644
--- a/themes/cp_app/pages/map.php
+++ b/themes/cp_app/pages/map.php
@@ -5,10 +5,10 @@
 
 <head>
     <meta charset="UTF-8"/>
-    <title><?= lang('Page.map.title') . service('settings')->get('App.siteTitleSeparator') . service('settings')->get('App.siteName') ?></title>
+    <title><?= lang('Page.map.title') . service('settings')->get('App.siteTitleSeparator') . esc(service('settings')->get('App.siteName')) ?></title>
     <meta name="description" content="<?= lang('Page.map.description', [
-        'siteName' => service('settings')
-            ->get('App.siteName'),
+        'siteName' => esc(service('settings')
+            ->get('App.siteName')),
     ]) ?>"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
     <link rel="icon" type="image/x-icon" href="<?= service('settings')
diff --git a/themes/cp_app/podcast/_layout.php b/themes/cp_app/podcast/_layout.php
index 417f39531f..f35f9136b4 100644
--- a/themes/cp_app/podcast/_layout.php
+++ b/themes/cp_app/podcast/_layout.php
@@ -10,7 +10,7 @@
     <link rel="icon" type="image/x-icon" href="<?= service('settings')
     ->get('App.siteIcon')['ico'] ?>" />
     <link rel="apple-touch-icon" href="<?= service('settings')->get('App.siteIcon')['180'] ?>">
-    <link rel="manifest" href="<?= route_to('podcast-webmanifest', $podcast->handle) ?>">
+    <link rel="manifest" href="<?= route_to('podcast-webmanifest', esc($podcast->handle)) ?>">
     <meta name="theme-color" content="<?= \App\Controllers\WebmanifestController::THEME_COLORS[service('settings')->get('App.theme')]['theme'] ?>">
     <script>
     // Check that service workers are supported
@@ -46,9 +46,9 @@
     <header class="relative z-50 flex flex-col-reverse justify-between w-full col-start-2 bg-top bg-no-repeat bg-cover sm:flex-row sm:items-end bg-header aspect-[3/1]" style="background-image: url('<?= $podcast->banner->medium_url ?>');">
         <div class="absolute bottom-0 left-0 w-full h-full backdrop-gradient mix-blend-multiply"></div>
         <div class="z-10 flex items-center pl-4 -mb-6 md:pl-8 md:-mb-8 gap-x-4">
-            <img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= $podcast->title ?>" class="h-24 rounded-full sm:h-28 md:h-36 ring-3 ring-background-elevated aspect-square" loading="lazy" />
+            <img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= esc($podcast->title) ?>" class="h-24 rounded-full sm:h-28 md:h-36 ring-3 ring-background-elevated aspect-square" loading="lazy" />
             <div class="relative flex flex-col text-white -top-3 sm:top-0 md:top-2">
-                <h1 class="text-lg font-bold leading-none line-clamp-2 md:leading-none md:text-2xl font-display"><?= $podcast->title ?><span class="ml-1 font-sans text-base font-normal">@<?= $podcast->handle ?></span></h1>
+                <h1 class="text-lg font-bold leading-none line-clamp-2 md:leading-none md:text-2xl font-display"><?= esc($podcast->title) ?><span class="ml-1 font-sans text-base font-normal">@<?= esc($podcast->handle) ?></span></h1>
                 <div class="">
                     <?= explicit_badge($podcast->parental_advisory === 'explicit', 'mr-1') ?>
                     <span class="text-xs"><?= lang('Podcast.followers', [
@@ -62,7 +62,7 @@
                 <button class="p-2 text-red-600 bg-white rounded-full shadow hover:text-red-500 focus:ring-accent" data-toggle="funding-links" data-toggle-class="hidden" data-tooltip="bottom" title="<?= lang('Podcast.sponsor') ?>"><Icon glyph="heart"></Icon></button>
             <?php endif; ?>
             <?= anchor_popup(
-                        route_to('follow', $podcast->handle),
+                        route_to('follow', esc($podcast->handle)),
                         icon(
                             'social/castopod',
                             'mr-2 text-xl text-black/75 group-hover:text-black',
diff --git a/themes/cp_app/podcast/_partials/funding_links_modal.php b/themes/cp_app/podcast/_partials/funding_links_modal.php
index add8203160..25bfcbce30 100644
--- a/themes/cp_app/podcast/_partials/funding_links_modal.php
+++ b/themes/cp_app/podcast/_partials/funding_links_modal.php
@@ -8,7 +8,7 @@
     <div class="z-10 w-full max-w-xl rounded-lg shadow-2xl bg-elevated">
         <div class="flex justify-between px-4 py-2 border-b border-subtle">
             <h3 class="self-center text-lg"><?= lang('Podcast.funding_links', [
-                'podcastTitle' => $podcast->title,
+                'podcastTitle' => esc($podcast->title),
             ]) ?></h3>
             <button
             data-toggle="funding-links"
@@ -20,16 +20,16 @@
             <?php foreach ($podcast->fundingPlatforms as $fundingPlatform): ?>
                 <?php if ($fundingPlatform->is_visible): ?>
                     <a
-                    href="<?= $fundingPlatform->link_url ?>"
-                    title="<?= $fundingPlatform->account_id ?>"
+                    href="<?= esc($fundingPlatform->link_url) ?>"
+                    title="<?= esc($fundingPlatform->account_id) ?>"
                     target="_blank"
                     rel="noopener noreferrer"
                     class="inline-flex items-center w-full font-semibold text-accent-base hover:text-accent-hover focus:ring-accent">
                     <?= icon(
-                $fundingPlatform->slug,
+                esc($fundingPlatform->slug),
                 'mr-2 flex-shrink-0',
                 $fundingPlatform->type
-            ) . '<span class="truncate">' . $fundingPlatform->link_url . '</span>' ?>
+            ) . '<span class="truncate">' . esc($fundingPlatform->link_url) . '</span>' ?>
                     </a>
                 <?php endif; ?>
             <?php endforeach; ?>
diff --git a/themes/cp_app/podcast/_partials/navigation.php b/themes/cp_app/podcast/_partials/navigation.php
index 458f1d9f11..fb7b7cacf7 100644
--- a/themes/cp_app/podcast/_partials/navigation.php
+++ b/themes/cp_app/podcast/_partials/navigation.php
@@ -2,15 +2,15 @@
 
 $navigationItems = [
     [
-        'uri' => route_to('podcast-activity', $podcast->handle),
+        'uri' => route_to('podcast-activity', esc($podcast->handle)),
         'label' => lang('Podcast.activity'),
     ],
     [
-        'uri' => route_to('podcast-episodes', $podcast->handle),
+        'uri' => route_to('podcast-episodes', esc($podcast->handle)),
         'label' => lang('Podcast.episodes'),
     ],
     [
-        'uri' => route_to('podcast-about', $podcast->handle),
+        'uri' => route_to('podcast-about', esc($podcast->handle)),
         'label' => lang('Podcast.about'),
     ],
 ]
diff --git a/themes/cp_app/podcast/_partials/sidebar.php b/themes/cp_app/podcast/_partials/sidebar.php
index 94b3fa7314..67aae12e29 100644
--- a/themes/cp_app/podcast/_partials/sidebar.php
+++ b/themes/cp_app/podcast/_partials/sidebar.php
@@ -1,21 +1,21 @@
 <div data-sidebar-toggler="backdrop" class="absolute top-0 left-0 z-10 hidden w-full h-full bg-backdrop/75 md:hidden" role="button" tabIndex="0" aria-label="Close"></div>
 <aside id="podcast-sidebar" data-sidebar-toggler="sidebar" data-toggle-class="hidden" data-hide-class="hidden" class="z-20 hidden h-full col-span-1 col-start-2 row-start-1 p-4 py-6 shadow-2xl md:shadow-none md:block bg-base">
     <div class="sticky z-10 bg-base top-12">
-        <a href="<?= route_to('podcast_feed', $podcast->handle) ?>" class="inline-flex items-center mb-6 text-sm font-semibold focus:ring-accent text-skin-muted hover:text-skin-base group" target="_blank" rel="noopener noreferrer">
+        <a href="<?= route_to('podcast_feed', esc($podcast->handle)) ?>" class="inline-flex items-center mb-6 text-sm font-semibold focus:ring-accent text-skin-muted hover:text-skin-base group" target="_blank" rel="noopener noreferrer">
             <?= icon('rss', ' mr-2 bg-orange-500 text-xl text-white group-hover:bg-orange-700 p-1 w-6 h-6 inline-flex items-center justify-center rounded-lg') . lang('Podcast.feed') ?>
         </a>
         <?php if (
             in_array(true, array_column($podcast->socialPlatforms, 'is_visible'), true)
         ): ?>
         <h2 class="text-sm font-bold font-display text-accent-muted"> <?= lang('Podcast.find_on', [
-            'podcastTitle' => $podcast->title,
+            'podcastTitle' => esc($podcast->title),
         ]) ?></h2>
         <div class="grid items-center justify-center grid-cols-6 gap-3 mb-6">
         <?php foreach ($podcast->socialPlatforms as $socialPlatform): ?>
             <?php if ($socialPlatform->is_visible): ?>
                 <?= anchor(
-            $socialPlatform->link_url,
-            icon("{$socialPlatform->type}/{$socialPlatform->slug}"),
+            esc($socialPlatform->link_url),
+            icon($socialPlatform->type . '/' . esc($socialPlatform->slug)),
             [
                 'class' => 'text-2xl text-skin-muted hover:text-skin-base w-8 h-8 items-center inline-flex justify-center',
                 'target' => '_blank',
@@ -37,10 +37,8 @@
             <?php foreach ($podcast->podcastingPlatforms as $podcastingPlatform): ?>
                 <?php if ($podcastingPlatform->is_visible): ?>
                     <?= anchor(
-            $podcastingPlatform->link_url,
-            icon(
-                "{$podcastingPlatform->type}/{$podcastingPlatform->slug}",
-            ),
+            esc($podcastingPlatform->link_url),
+            icon($podcastingPlatform->type . '/' . $podcastingPlatform->slug),
             [
                 'class' => 'text-2xl text-skin-muted hover:text-skin-base w-8 h-8 items-center inline-flex justify-center',
                 'target' => '_blank',
@@ -56,7 +54,7 @@
         <footer class="flex flex-col items-center py-2 text-xs text-center border-t border-subtle text-skin-muted">
             <?= render_page_links('inline-flex mb-2 flex-wrap gap-y-1 justify-center') ?>
             <div class="flex flex-col">
-                <p><?= $podcast->copyright ?></p>
+                <p><?= esc($podcast->copyright) ?></p>
                 <p><?= lang('Common.powered_by', [
                     'castopod' =>
                         '<a class="inline-flex font-semibold text-skin-muted hover:underline focus:ring-accent" href="https://castopod.org" target="_blank" rel="noreferrer noopener">Castopod' . icon('castopod', 'ml-1 text-lg', 'social') . '</a>',
diff --git a/themes/cp_app/podcast/about.php b/themes/cp_app/podcast/about.php
index 8907f91d7e..4a721c983c 100644
--- a/themes/cp_app/podcast/about.php
+++ b/themes/cp_app/podcast/about.php
@@ -17,11 +17,11 @@
 
     <div class="flex items-center mt-4 gap-x-8">
         <?php if ($podcast->persons !== []): ?>
-            <button class="flex items-center text-xs font-semibold gap-x-2 hover:underline focus:ring-accent" data-toggle="persons-list" data-toggle-class="hidden">
+            <button class="flex items-center flex-shrink-0 text-xs font-semibold gap-x-2 hover:underline focus:ring-accent" data-toggle="persons-list" data-toggle-class="hidden">
                 <span class="inline-flex flex-row-reverse">
                     <?php $i = 0; ?>
                     <?php foreach ($podcast->persons as $person): ?>
-                        <img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-8 -ml-4 border-2 rounded-full aspect-square bg-header border-background-base last:ml-0" loading="lazy" />
+                        <img src="<?= $person->avatar->thumbnail_url ?>" alt="<?= esc($person->full_name) ?>" class="object-cover w-8 -ml-4 border-2 rounded-full aspect-square bg-header border-background-base last:ml-0" loading="lazy" />
                         <?php $i++; if ($i === 3) {
     break;
 }?>
@@ -51,7 +51,7 @@
 
 <?= view('_persons_modal', [
     'title' => lang('Podcast.persons_list', [
-        'podcastTitle' => $podcast->title,
+        'podcastTitle' => esc($podcast->title),
     ]),
     'persons' => $podcast->persons,
 ]) ?>
diff --git a/themes/cp_app/podcast/activity.php b/themes/cp_app/podcast/activity.php
index bc5b42d375..dcca1117b2 100644
--- a/themes/cp_app/podcast/activity.php
+++ b/themes/cp_app/podcast/activity.php
@@ -3,14 +3,14 @@
 <?= $this->section('content') ?>
 
 <?php if (can_user_interact()): ?>
-    <form action="<?= route_to('post-attempt-create', interact_as_actor()->username) ?>" method="POST" class="flex p-4 shadow bg-elevated gap-x-2 rounded-conditional-2xl">
+    <form action="<?= route_to('post-attempt-create', esc(interact_as_actor()->username)) ?>" method="POST" class="flex p-4 shadow bg-elevated gap-x-2 rounded-conditional-2xl">
     <?= csrf_field() ?>
 
     <?= view('_message_block') ?>
 
     <img src="<?= interact_as_actor()
-        ->avatar_image_url ?>" alt="<?= interact_as_actor()
-        ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+        ->avatar_image_url ?>" alt="<?= esc(interact_as_actor()
+        ->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
     <div class="flex flex-col flex-1 min-w-0 gap-y-2">
         <Forms.Textarea
             name="message"
diff --git a/themes/cp_app/podcast/follow.php b/themes/cp_app/podcast/follow.php
index b2d3ad3733..5b6fa1ba0a 100644
--- a/themes/cp_app/podcast/follow.php
+++ b/themes/cp_app/podcast/follow.php
@@ -10,7 +10,7 @@
     <link rel="icon" type="image/x-icon" href="<?= service('settings')
     ->get('App.siteIcon')['ico'] ?>" />
     <link rel="apple-touch-icon" href="<?= service('settings')->get('App.siteIcon')['180'] ?>">
-    <link rel="manifest" href="<?= route_to('podcast-webmanifest', $actor->podcast->handle) ?>">
+    <link rel="manifest" href="<?= route_to('podcast-webmanifest', esc($actor->podcast->handle)) ?>">
     <meta name="theme-color" content="<?= \App\Controllers\WebmanifestController::THEME_COLORS[service('settings')->get('App.theme')]['theme'] ?>">
     <script>
     // Check that service workers are supported
@@ -40,18 +40,18 @@
         <div class="flex flex-col w-full max-w-xs -mt-24 overflow-hidden shadow bg-elevated rounded-xl">
             <img src="<?= $actor->podcast->banner->small_url ?>" alt="" class="w-full aspect-[3/1] bg-header" loading="lazy" />
             <div class="flex px-4 py-2">
-                <img src="<?= $actor->avatar_image_url ?>" alt="<?= $actor->display_name ?>"
+                <img src="<?= $actor->avatar_image_url ?>" alt="<?= esc($actor->display_name) ?>"
                     class="w-16 h-16 mr-4 -mt-8 rounded-full ring-2 ring-background-elevated aspect-square" loading="lazy" />
                 <div class="flex flex-col">
-                    <p class="font-semibold"><?= $actor->display_name ?></p>
-                    <p class="text-sm text-skin-muted">@<?= $actor->username ?></p>
+                    <p class="font-semibold"><?= esc($actor->display_name) ?></p>
+                    <p class="text-sm text-skin-muted">@<?= esc($actor->username) ?></p>
                 </div>
             </div>
         </div>
     </header>
 
     <main class="w-full max-w-md px-4 mx-auto">
-        <form action="<?= route_to('attempt-follow', $actor->username) ?>" method="POST" class="flex flex-col gap-y-2">
+        <form action="<?= route_to('attempt-follow', esc($actor->username)) ?>" method="POST" class="flex flex-col gap-y-2">
             <?= csrf_field() ?>
             <?= view('_message_block') ?>
 
diff --git a/themes/cp_app/post/_partials/actions.php b/themes/cp_app/post/_partials/actions.php
index 0f75de4174..721ef7b0e2 100644
--- a/themes/cp_app/post/_partials/actions.php
+++ b/themes/cp_app/post/_partials/actions.php
@@ -1,9 +1,9 @@
 <footer class="flex justify-around px-6 py-3">
     <?php if (can_user_interact()): ?>
-        <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $post->id) ?>" method="POST" class="flex justify-around w-full">
+        <form action="<?= route_to('post-attempt-action', esc(interact_as_actor()->username), $post->id) ?>" method="POST" class="flex justify-around w-full">
             <?= csrf_field() ?>
             <?= anchor(
-    route_to('post', $podcast->handle, $post->id),
+    route_to('post', esc($podcast->handle), $post->id),
     icon('chat', 'text-2xl mr-1 opacity-40') . $post->replies_count,
     [
         'class' => 'inline-flex items-center hover:underline',
@@ -37,7 +37,7 @@
             '-more-dropdown-menu' ?>" class="flex flex-col py-2 text-sm rounded-lg shadow border-3 border-subtle bg-elevated" aria-labelledby="<?= $post->id .
         '-more-dropdown' ?>" data-dropdown="menu" data-dropdown-placement="bottom">
             <?= anchor(
-            route_to('post', $podcast->handle, $post->id),
+            route_to('post', esc($podcast->handle), $post->id),
             lang('Post.expand'),
             [
                 'class' => 'px-4 py-1 hover:bg-highlight',
@@ -45,29 +45,29 @@
         ) ?>
             <form action="<?= route_to(
             'post-attempt-block-actor',
-            interact_as_actor()
-                ->username,
+            esc(interact_as_actor()
+                ->username),
             $post->id,
         ) ?>" method="POST">
                 <?= csrf_field() ?>
                 <button class="w-full px-4 py-1 text-left hover:bg-highlight"><?= lang(
             'Post.block_actor',
             [
-                'actorUsername' => $post->actor->username,
+                'actorUsername' => esc($post->actor->username),
             ],
         ) ?></button>
             </form>
             <form action="<?= route_to(
             'post-attempt-block-domain',
-            interact_as_actor()
-                ->username,
+            esc(interact_as_actor()
+                ->username),
             $post->id,
         ) ?>" method="POST">
                 <?= csrf_field() ?>
                 <button class="w-full px-4 py-1 text-left hover:bg-highlight"><?= lang(
             'Post.block_domain',
             [
-                'actorDomain' => $post->actor->domain,
+                'actorDomain' => esc($post->actor->domain),
             ],
         ) ?></button>
             </form>
@@ -75,7 +75,7 @@
                 <hr class="my-2 border-subtle" />
                 <form action="<?= route_to(
             'post-attempt-delete',
-            $post->actor->username,
+            esc($post->actor->username),
             $post->id,
         ) ?>" method="POST">
                     <?= csrf_field() ?>
@@ -87,7 +87,7 @@
         </nav>
     <?php else: ?>
     <?= anchor(
-            route_to('post', $podcast->handle, $post->id),
+            route_to('post', esc($podcast->handle), $post->id),
             icon('chat', 'text-2xl mr-1 opacity-40') . $post->replies_count,
             [
                 'class' => 'inline-flex items-center hover:underline',
@@ -97,7 +97,7 @@
             ],
         ) ?>
     <?= anchor_popup(
-            route_to('post-remote-action', $podcast->handle, $post->id, 'reblog'),
+            route_to('post-remote-action', esc($podcast->handle), $post->id, 'reblog'),
             icon('repeat', 'text-2xl mr-1 opacity-40') . $post->reblogs_count,
             [
                 'class' => 'inline-flex items-center hover:underline',
@@ -109,7 +109,7 @@
             ],
         ) ?>
     <?= anchor_popup(
-            route_to('post-remote-action', $podcast->handle, $post->id, 'favourite'),
+            route_to('post-remote-action', esc($podcast->handle), $post->id, 'favourite'),
             icon('heart', 'text-2xl mr-1 opacity-40') . $post->favourites_count,
             [
                 'class' => 'inline-flex items-center hover:underline',
diff --git a/themes/cp_app/post/_partials/card.php b/themes/cp_app/post/_partials/card.php
index eaef1e8ca3..1b72212d43 100644
--- a/themes/cp_app/post/_partials/card.php
+++ b/themes/cp_app/post/_partials/card.php
@@ -1,22 +1,22 @@
 <article class="relative z-10 w-full shadow bg-elevated sm:rounded-conditional-2xl">
     <header class="flex px-6 py-4 gap-x-2">
         <img src="<?= $post->actor
-    ->avatar_image_url ?>" alt="<?= $post->actor->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+    ->avatar_image_url ?>" alt="<?= esc($post->actor->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
         <div class="flex flex-col min-w-0">
             <a href="<?= $post->actor
     ->uri ?>" class="flex items-baseline hover:underline" <?= $post
     ->actor->is_local
     ? ''
     : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $post->actor
-        ->display_name ?></span>
-                <span class="text-sm truncate text-skin-muted">@<?= $post->actor
-        ->username .
+                <span class="mr-2 font-semibold truncate"><?= esc($post->actor
+        ->display_name) ?></span>
+                <span class="text-sm truncate text-skin-muted">@<?= esc($post->actor
+        ->username) .
                     ($post->actor->is_local
                         ? ''
-                        : '@' . $post->actor->domain) ?></span>
+                        : '@' . esc($post->actor->domain)) ?></span>
             </a>
-            <a href="<?= route_to('post', $podcast->handle, $post->id) ?>"
+            <a href="<?= route_to('post', esc($podcast->handle), $post->id) ?>"
             class="text-xs text-skin-muted">
                 <?= relative_time($post->published_at) ?>
             </a>
diff --git a/themes/cp_app/post/_partials/post_with_replies.php b/themes/cp_app/post/_partials/post_with_replies.php
index 245fe09784..21ed54dd11 100644
--- a/themes/cp_app/post/_partials/post_with_replies.php
+++ b/themes/cp_app/post/_partials/post_with_replies.php
@@ -17,19 +17,19 @@ if ($post->in_reply_to_id): ?>
 <div class="-mt-2 overflow-hidden border-b border-l border-r border-subtle post-replies rounded-b-xl">
     <div class="px-6 pt-8 pb-4 bg-base">
         <?php if (can_user_interact()): ?>
-            <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $post->id) ?>" method="POST" class="flex gap-x-2" >
+            <form action="<?= route_to('post-attempt-action', esc(interact_as_actor()->username), $post->id) ?>" method="POST" class="flex gap-x-2" >
                 <?= csrf_field() ?>
 
                 <img src="<?= interact_as_actor()
-                    ->avatar_image_url ?>" alt="<?= interact_as_actor()
-                    ->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+                    ->avatar_image_url ?>" alt="<?= esc(interact_as_actor()
+                    ->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
                 <div class="flex flex-col flex-1">
                     <Forms.Textarea
                         name="message"
                         class="w-full mb-4"
                         required="true"
                         placeholder="<?= lang('Post.form.reply_to_placeholder', [
-                            'actorUsername' => $post->actor->username,
+                            'actorUsername' => esc($post->actor->username),
                         ]) ?>"
                         rows="1" />
                     <Button variant="primary" size="small" type="submit" name="action" value="reply" class="self-end" iconRight="send-plane"><?= lang('Post.form.submit_reply') ?></Button>
@@ -37,9 +37,9 @@ if ($post->in_reply_to_id): ?>
             </form>
         <?php else: ?>
             <?= anchor_popup(
-                            route_to('post-remote-action', $podcast->handle, $post->id, 'reply'),
+                            route_to('post-remote-action', esc($podcast->handle), $post->id, 'reply'),
                             lang('Post.reply_to', [
-                                'actorUsername' => $post->actor->username,
+                                'actorUsername' => esc($post->actor->username),
                             ]),
                             [
                                 'class' =>
diff --git a/themes/cp_app/post/_partials/preview_card.php b/themes/cp_app/post/_partials/preview_card.php
index 54c013cc19..552331ce88 100644
--- a/themes/cp_app/post/_partials/preview_card.php
+++ b/themes/cp_app/post/_partials/preview_card.php
@@ -8,12 +8,12 @@ if ($preview_card->type === 'image'): ?>
     'external-link',
     'absolute inset-0 m-auto text-6xl bg-accent-base bg-opacity-50 group-hover:bg-opacity-100 text-accent-contrast rounded-full p-2',
 ) ?>
-        <img src="<?= $preview_card->image ?>" alt="<?= $preview_card->title ?>" class="object-cover w-full aspect-video" loading="lazy" />
+        <img src="<?= $preview_card->image ?>" alt="<?= esc($preview_card->title) ?>" class="object-cover w-full aspect-video" loading="lazy" />
     </div>
     <?php endif; ?>
 
     <div class="flex flex-col flex-1 px-4 py-2">
-        <span class="text-xs tracking-wider uppercase text-skin-muted"><?= $preview_card->provider_name ?></span>
+        <span class="text-xs tracking-wider uppercase text-skin-muted"><?= esc($preview_card->provider_name) ?></span>
     </div>
 </a>
 <?php elseif ($preview_card->type === 'video'): ?>
@@ -24,24 +24,23 @@ if ($preview_card->type === 'image'): ?>
     'play',
     'absolute inset-0 m-auto text-6xl bg-accent-base bg-opacity-50 group-hover:bg-opacity-100 text-accent-contrast rounded-full p-2',
 ) ?>
-        <img class="object-cover w-full aspect-video" src="<?= $preview_card->image ?>" alt="<?= $preview_card->title ?>" loading="lazy" />
+        <img class="object-cover w-full aspect-video" src="<?= $preview_card->image ?>" alt="<?= esc($preview_card->title) ?>" loading="lazy" />
     </div>
     <?php endif; ?>
 
     <div class="flex flex-col flex-1 px-4 py-2">
-        <span class="text-xs tracking-wider uppercase text-skin-muted"><?= $preview_card->provider_name ?></span>
-        <span class="mb-2 font-semibold truncate"><?= $preview_card->title ?></span>
+        <span class="text-xs tracking-wider uppercase text-skin-muted"><?= esc($preview_card->provider_name) ?></span>
+        <span class="mb-2 font-semibold truncate"><?= esc($preview_card->title) ?></span>
     </div>
 </a>
 <?php else: ?>
 <a href="<?= $preview_card->url ?>" class="flex items-center bg-highlight">
     <?php if ($preview_card->image): ?>
-    <img src="<?= $preview_card->image ?>" alt="<?= $preview_card->title ?>" class="object-cover w-20 aspect-square" loading="lazy" />
+    <img src="<?= $preview_card->image ?>" alt="<?= esc($preview_card->title) ?>" class="object-cover w-20 aspect-square" loading="lazy" />
     <?php endif; ?>
     <p class="flex flex-col flex-1 px-4 py-2">
-        <span class="text-xs tracking-wider uppercase text-skin-muted"><?= $preview_card->provider_name ?></span>
-        <span class="mb-2 font-semibold truncate"><?= $preview_card->title ?></span>
+        <span class="text-xs tracking-wider uppercase text-skin-muted"><?= esc($preview_card->provider_name) ?></span>
+        <span class="mb-2 font-semibold truncate"><?= esc($preview_card->title) ?></span>
     </p>
 </a>
-<?php endif;
-?>
+<?php endif; ?>
diff --git a/themes/cp_app/post/_partials/reblog.php b/themes/cp_app/post/_partials/reblog.php
index 1e4227e8cc..70d6c0032b 100644
--- a/themes/cp_app/post/_partials/reblog.php
+++ b/themes/cp_app/post/_partials/reblog.php
@@ -4,26 +4,26 @@
     'text-lg mr-2 opacity-40',
 ) .
         lang('Post.actor_shared', [
-            'actor' => $post->actor->display_name,
+            'actor' => esc($post->actor->display_name),
         ]) ?></p>
     <header class="flex px-6 py-4 gap-x-2">
         <img src="<?= $post->actor
-            ->avatar_image_url ?>" alt="<?= $post->display_name ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
+            ->avatar_image_url ?>" alt="<?= esc($post->actor->display_name) ?>" class="w-10 h-10 rounded-full aspect-square" loading="lazy" />
         <div class="flex flex-col min-w-0">
             <a href="<?= $post->actor
             ->uri ?>" class="flex items-baseline hover:underline" <?= $post
             ->actor->is_local
     ? ''
     : 'target="_blank" rel="noopener noreferrer"' ?>>
-                <span class="mr-2 font-semibold truncate"><?= $post->actor
-        ->display_name ?></span>
-                <span class="text-sm truncate text-skin-muted">@<?= $post->actor
-        ->username .
+                <span class="mr-2 font-semibold truncate"><?= esc($post->actor
+        ->display_name) ?></span>
+                <span class="text-sm truncate text-skin-muted">@<?= esc($post->actor
+        ->username) .
                     ($post->actor->is_local
                         ? ''
                         : '@' . $post->actor->domain) ?></span>
             </a>
-            <a href="<?= route_to('post', $podcast->handle, $post->id) ?>"
+            <a href="<?= route_to('post', esc($podcast->handle), $post->id) ?>"
             class="text-xs text-skin-muted">
                 <?= relative_time($post->published_at) ?>
             </a>
diff --git a/themes/cp_app/post/_partials/reply.php b/themes/cp_app/post/_partials/reply.php
index fcef3b417d..fecee07a18 100644
--- a/themes/cp_app/post/_partials/reply.php
+++ b/themes/cp_app/post/_partials/reply.php
@@ -1,16 +1,16 @@
 <article class="flex px-6 py-4 bg-base gap-x-2">
-    <img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= $reply->actor
-    ->display_name ?>" class="z-10 w-10 h-10 rounded-full ring-background-base ring-2 aspect-square" loading="lazy" />
+    <img src="<?= $reply->actor->avatar_image_url ?>" alt="<?= esc($reply->actor
+    ->display_name) ?>" class="z-10 w-10 h-10 rounded-full ring-background-base ring-2 aspect-square" loading="lazy" />
     <div class="flex flex-col flex-1 min-w-0">
         <header class="flex items-center mb-2">
             <a href="<?= $reply->actor
     ->uri ?>" class="mr-2 text-base font-semibold truncate hover:underline" <?= $reply
     ->actor->is_local
     ? ''
-    : 'target="_blank" rel="noopener noreferrer"' ?>><?= $reply->actor
-        ->display_name ?><span class="ml-1 text-sm font-normal text-skin-muted">@<?= $reply
-        ->actor->username .
-    ($reply->actor->is_local ? '' : '@' . $reply->actor->domain) ?></span></a>
+    : 'target="_blank" rel="noopener noreferrer"' ?>><?= esc($reply->actor
+        ->display_name) ?><span class="ml-1 text-sm font-normal text-skin-muted">@<?= esc($reply
+        ->actor->username) .
+    ($reply->actor->is_local ? '' : '@' . esc($reply->actor->domain)) ?></span></a>
             <?= relative_time($reply->published_at, 'flex-shrink-0 ml-auto text-xs text-skin-muted') ?>
         </header>
         <p class="mb-2 post-content"><?= $reply->message_html ?></p>
diff --git a/themes/cp_app/post/_partials/reply_actions.php b/themes/cp_app/post/_partials/reply_actions.php
index eadb30f7c5..0e2b853f45 100644
--- a/themes/cp_app/post/_partials/reply_actions.php
+++ b/themes/cp_app/post/_partials/reply_actions.php
@@ -2,10 +2,10 @@
 
 if (can_user_interact()): ?>
     <footer>
-        <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $reply->id) ?>" method="POST" class="flex items-start gap-x-6">
+        <form action="<?= route_to('post-attempt-action', esc(interact_as_actor()->username), $reply->id) ?>" method="POST" class="flex items-start gap-x-6">
             <?= csrf_field() ?>
             <?= anchor(
-    route_to('post', $podcast->handle, $reply->id),
+    route_to('post', esc($podcast->handle), $reply->id),
     icon('chat', 'text-lg mr-1 opacity-40') . $reply->replies_count,
     [
         'class' => 'inline-flex items-center hover:underline text-sm',
@@ -39,7 +39,7 @@ if (can_user_interact()): ?>
             '-more-dropdown-menu' ?>" class="flex flex-col py-2 text-sm rounded-lg shadow border-3 border-subtle bg-elevated" aria-labelledby="<?= $reply->id .
         '-more-dropdown' ?>" data-dropdown="menu" data-dropdown-placement="bottom">
             <?= anchor(
-            route_to('post', $podcast->handle, $reply->id),
+            route_to('post', esc($podcast->handle), $reply->id),
             lang('Post.expand'),
             [
                 'class' => 'px-4 py-1 hover:bg-highlight',
@@ -47,29 +47,29 @@ if (can_user_interact()): ?>
         ) ?>
             <form action="<?= route_to(
             'post-attempt-block-actor',
-            interact_as_actor()
-                ->username,
+            esc(interact_as_actor()
+                ->username),
             $reply->id,
         ) ?>" method="POST">
                 <?= csrf_field() ?>
                 <button class="w-full px-4 py-1 text-left hover:bg-highlight"><?= lang(
             'Post.block_actor',
             [
-                'actorUsername' => $reply->actor->username,
+                'actorUsername' => esc($reply->actor->username),
             ],
         ) ?></button>
             </form>
             <form action="<?= route_to(
             'post-attempt-block-domain',
-            interact_as_actor()
-                ->username,
+            esc(interact_as_actor()
+                ->username),
             $reply->id,
         ) ?>" method="POST">
                 <?= csrf_field() ?>
                 <button class="w-full px-4 py-1 text-left hover:bg-highlight"><?= lang(
             'Post.block_domain',
             [
-                'actorDomain' => $reply->actor->domain,
+                'actorDomain' => esc($reply->actor->domain),
             ],
         ) ?></button>
             </form>
@@ -77,7 +77,7 @@ if (can_user_interact()): ?>
                 <hr class="my-2 border-subtle" />
                 <form action="<?= route_to(
             'post-attempt-delete',
-            $reply->actor->username,
+            esc($reply->actor->username),
             $reply->id,
         ) ?>" method="POST">
                     <?= csrf_field() ?>
@@ -91,7 +91,7 @@ if (can_user_interact()): ?>
 <?php else: ?>
     <footer class="flex gap-x-6">
         <?= anchor(
-            route_to('post', $podcast->handle, $reply->id),
+            route_to('post', esc($podcast->handle), $reply->id),
             icon('chat', 'text-lg mr-1 opacity-40') . $reply->replies_count,
             [
                 'class' => 'inline-flex items-center hover:underline text-sm',
@@ -101,7 +101,7 @@ if (can_user_interact()): ?>
             ],
         ) ?>
         <?= anchor_popup(
-            route_to('post-remote-action', $podcast->handle, $reply->id, 'reblog'),
+            route_to('post-remote-action', esc($podcast->handle), $reply->id, 'reblog'),
             icon('repeat', 'text-lg mr-1 opacity-40') . $reply->reblogs_count,
             [
                 'class' => 'inline-flex items-center hover:underline text-sm',
@@ -113,7 +113,7 @@ if (can_user_interact()): ?>
             ],
         ) ?>
         <?= anchor_popup(
-            route_to('post-remote-action', $podcast->handle, $reply->id, 'favourite'),
+            route_to('post-remote-action', esc($podcast->handle), $reply->id, 'favourite'),
             icon('heart', 'text-lg mr-1 opacity-40') . $reply->favourites_count,
             [
                 'class' => 'inline-flex items-center hover:underline text-sm',
diff --git a/themes/cp_app/post/post.php b/themes/cp_app/post/post.php
index 02c168bf73..47a09e6a96 100644
--- a/themes/cp_app/post/post.php
+++ b/themes/cp_app/post/post.php
@@ -2,13 +2,13 @@
 
 <?= $this->section('content') ?>
 <nav class="py-2">
-    <a href="<?= route_to('podcast-activity', $podcast->handle) ?>"
+    <a href="<?= route_to('podcast-activity', esc($podcast->handle)) ?>"
     class="inline-flex items-center px-4 py-2 text-sm focus:ring-accent"><?= icon(
     'arrow-left',
     'mr-2 text-lg',
 ) .
         lang('Post.back_to_actor_posts', [
-            'actor' => $post->actor->display_name,
+            'actor' => esc($post->actor->display_name),
         ]) ?></a>
 </nav>
 <div class="pb-12">
diff --git a/themes/cp_app/post/remote_action.php b/themes/cp_app/post/remote_action.php
index ba251e4962..26747cb761 100644
--- a/themes/cp_app/post/remote_action.php
+++ b/themes/cp_app/post/remote_action.php
@@ -8,7 +8,7 @@
     <link rel="icon" type="image/x-icon" href="<?= service('settings')
     ->get('App.siteIcon')['ico'] ?>" />
     <link rel="apple-touch-icon" href="<?= service('settings')->get('App.siteIcon')['180'] ?>">
-    <link rel="manifest" href="<?= route_to('podcast-webmanifest', $post->actor->podcast->handle) ?>">
+    <link rel="manifest" href="<?= route_to('podcast-webmanifest', esc($post->actor->podcast->handle)) ?>">
     <meta name="theme-color" content="<?= \App\Controllers\WebmanifestController::THEME_COLORS[service('settings')->get('App.theme')]['theme'] ?>">
     <script>
     // Check that service workers are supported
diff --git a/themes/cp_auth/_message_block.php b/themes/cp_auth/_message_block.php
index ffe70e09c7..1504aa372c 100644
--- a/themes/cp_auth/_message_block.php
+++ b/themes/cp_auth/_message_block.php
@@ -1,20 +1,19 @@
 <?php declare(strict_types=1);
 
 if (session()->has('message')): ?>
-    <Alert variant="success" class="mb-4"><?= session('message') ?></Alert>
+    <Alert variant="success" class="mb-4"><?= esc(session('message')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('error')): ?>
-    <Alert variant="danger" class="mb-4"><?= session('error') ?></Alert>
+    <Alert variant="danger" class="mb-4"><?= esc(session('error')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('errors')): ?>
     <Alert variant="danger" class="mb-4">
         <ul>
             <?php foreach (session('errors') as $error): ?>
-                <li><?= $error ?></li>
+                <li><?= esc($error) ?></li>
             <?php endforeach; ?>
         </ul>
     </Alert>
-<?php endif;
-?>
+<?php endif; ?>
diff --git a/themes/cp_install/_message_block.php b/themes/cp_install/_message_block.php
index b52a79f6cf..1504aa372c 100644
--- a/themes/cp_install/_message_block.php
+++ b/themes/cp_install/_message_block.php
@@ -1,20 +1,19 @@
 <?php declare(strict_types=1);
 
 if (session()->has('message')): ?>
-    <Alert variant="success" class="max-w-sm mb-4"><?= session('message') ?></Alert>
+    <Alert variant="success" class="mb-4"><?= esc(session('message')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('error')): ?>
-    <Alert variant="danger" class="max-w-sm mb-4"><?= session('error') ?></Alert>
+    <Alert variant="danger" class="mb-4"><?= esc(session('error')) ?></Alert>
 <?php endif; ?>
 
 <?php if (session()->has('errors')): ?>
-    <Alert variant="danger" class="max-w-sm mb-4">
+    <Alert variant="danger" class="mb-4">
         <ul>
             <?php foreach (session('errors') as $error): ?>
-                <li><?= $error ?></li>
+                <li><?= esc($error) ?></li>
             <?php endforeach; ?>
         </ul>
     </Alert>
-<?php endif;
-?>
+<?php endif; ?>
-- 
GitLab


From c2f2291ba66d15b49cf4645e92abc02d1eede1cd Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Fri, 4 Mar 2022 10:21:21 +0000
Subject: [PATCH 6/7] fix(csrf): remove csrf for federation inbox posting

---
 app/Config/Filters.php     | 6 ++++--
 app/Helpers/rss_helper.php | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/app/Config/Filters.php b/app/Config/Filters.php
index 7a505b477d..fdc14d7957 100644
--- a/app/Config/Filters.php
+++ b/app/Config/Filters.php
@@ -39,12 +39,14 @@ class Filters extends BaseConfig
     /**
      * List of filter aliases that are always applied before and after every request.
      *
-     * @var array<string, string[]>
+     * @var array<string, mixed>
      */
     public array $globals = [
         'before' => [
             // 'honeypot',
-            'csrf',
+            'csrf' => [
+                'except' => ['@[a-zA-Z0-9\_]{1,32}/inbox'],
+            ],
             // 'invalidchars',
         ],
         'after' => [
diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php
index 43e866c5f9..51297b7371 100644
--- a/app/Helpers/rss_helper.php
+++ b/app/Helpers/rss_helper.php
@@ -127,6 +127,7 @@ if (! function_exists('get_rss_feed')) {
             if ($socialPlatform->account_id !== null) {
                 $socialElement->addAttribute('accountId', esc($socialPlatform->account_id));
             }
+
             if ($socialPlatform->link_url !== null) {
                 $socialElement->addAttribute('accountUrl', esc($socialPlatform->link_url));
             }
-- 
GitLab


From 66b1afa8a67e4f57c7027c02854e4485b161fad3 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Fri, 4 Mar 2022 12:14:42 +0000
Subject: [PATCH 7/7] build(vite): update rollup input paths in config

---
 package-lock.json | 28 ++++++++++++++--------------
 package.json      |  4 ++--
 vite.config.ts    | 20 ++++++++++----------
 3 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index daec42f5b6..ffa8240a17 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -67,8 +67,8 @@
         "stylelint-config-standard": "^25.0.0",
         "svgo": "^2.8.0",
         "tailwindcss": "^3.0.23",
-        "typescript": "^4.5.5",
-        "vite": "^2.8.4",
+        "typescript": "^4.6.2",
+        "vite": "^2.8.6",
         "vite-plugin-pwa": "^0.11.13",
         "workbox-build": "^6.5.0",
         "workbox-core": "^6.5.0",
@@ -15885,9 +15885,9 @@
       "license": "MIT"
     },
     "node_modules/typescript": {
-      "version": "4.5.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
-      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -16045,9 +16045,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "2.8.4",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-2.8.4.tgz",
-      "integrity": "sha512-GwtOkkaT2LDI82uWZKcrpRQxP5tymLnC7hVHHqNkhFNknYr0hJUlDLfhVRgngJvAy3RwypkDCWtTKn1BjO96Dw==",
+      "version": "2.8.6",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-2.8.6.tgz",
+      "integrity": "sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==",
       "dev": true,
       "dependencies": {
         "esbuild": "^0.14.14",
@@ -27650,9 +27650,9 @@
       "version": "0.0.6"
     },
     "typescript": {
-      "version": "4.5.5",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
-      "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
       "dev": true
     },
     "uglify-js": {
@@ -27761,9 +27761,9 @@
       }
     },
     "vite": {
-      "version": "2.8.4",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-2.8.4.tgz",
-      "integrity": "sha512-GwtOkkaT2LDI82uWZKcrpRQxP5tymLnC7hVHHqNkhFNknYr0hJUlDLfhVRgngJvAy3RwypkDCWtTKn1BjO96Dw==",
+      "version": "2.8.6",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-2.8.6.tgz",
+      "integrity": "sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==",
       "dev": true,
       "requires": {
         "esbuild": "^0.14.14",
diff --git a/package.json b/package.json
index 28323e6c9b..4b76fe3cc0 100644
--- a/package.json
+++ b/package.json
@@ -85,8 +85,8 @@
     "stylelint-config-standard": "^25.0.0",
     "svgo": "^2.8.0",
     "tailwindcss": "^3.0.23",
-    "typescript": "^4.5.5",
-    "vite": "^2.8.4",
+    "typescript": "^4.6.2",
+    "vite": "^2.8.6",
     "vite-plugin-pwa": "^0.11.13",
     "workbox-build": "^6.5.0",
     "workbox-core": "^6.5.0",
diff --git a/vite.config.ts b/vite.config.ts
index f43f05bf18..6b293f3052 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -13,16 +13,16 @@ export default defineConfig({
     sourcemap: true,
     rollupOptions: {
       input: {
-        "admin-audio-player.ts": "js/admin-audio-player.ts",
-        "admin.ts": "js/admin.ts",
-        "app.ts": "js/app.ts",
-        "audio-player.ts": "js/audio-player.ts",
-        "charts.ts": "js/charts.ts",
-        "embed.ts": "js/embed.ts",
-        "install.ts": "js/install.ts",
-        "map.ts": "js/map.ts",
-        "podcast.ts": "js/podcast.ts",
-        "styles/index.css": "styles/index.css",
+        "admin-audio-player.ts": "app/Resources/js/admin-audio-player.ts",
+        "admin.ts": "app/Resources/js/admin.ts",
+        "app.ts": "app/Resources/js/app.ts",
+        "audio-player.ts": "app/Resources/js/audio-player.ts",
+        "charts.ts": "app/Resources/js/charts.ts",
+        "embed.ts": "app/Resources/js/embed.ts",
+        "install.ts": "app/Resources/js/install.ts",
+        "map.ts": "app/Resources/js/map.ts",
+        "podcast.ts": "app/Resources/js/podcast.ts",
+        "styles/index.css": "app/Resources/styles/index.css",
       },
     },
   },
-- 
GitLab