diff --git a/composer.json b/composer.json
index 3e4e665acc274f09f080323ff80c446aea7ed11d..ac03753767b1af33f95d056cd28a8e7e2a35d42c 100644
--- a/composer.json
+++ b/composer.json
@@ -106,8 +106,8 @@
         "drupal/ckeditor": "^1.0",
         "drupal/ckeditor_indentblock": "^1.0",
         "drupal/config_ignore": "^3.0",
-        "drupal/core-composer-scaffold": "^10",
-        "drupal/core-recommended": "^10",
+        "drupal/core-composer-scaffold": "^10.1",
+        "drupal/core-recommended": "^10.1",
         "drupal/crop": "2.3",
         "drupal/ctools": "^4.0",
         "drupal/decorative_image_widget": "^1.0",
diff --git a/composer.lock b/composer.lock
index 749218a732c441c87e28a087adb760910f74bb91..372dffe7c717ac9902bfb0fa6d736c67d445e940 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": "83bb2cb6d9a59f12abaeb091ee6e9204",
+    "content-hash": "2a02d0e2e8242ba7416066e2ff6e0150",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -2192,16 +2192,16 @@
         },
         {
             "name": "drupal/core",
-            "version": "10.1.5",
+            "version": "10.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core.git",
-                "reference": "1272c35d547e844e7ebf3fe5513542291cda8cec"
+                "reference": "33695caf467e3e1e8c75d42215df57bee31be9ec"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/drupal/core/zipball/1272c35d547e844e7ebf3fe5513542291cda8cec",
-                "reference": "1272c35d547e844e7ebf3fe5513542291cda8cec",
+                "url": "https://api.github.com/repos/drupal/core/zipball/33695caf467e3e1e8c75d42215df57bee31be9ec",
+                "reference": "33695caf467e3e1e8c75d42215df57bee31be9ec",
                 "shasum": ""
             },
             "require": {
@@ -2346,13 +2346,13 @@
             ],
             "description": "Drupal is an open source content management platform powering millions of websites and applications.",
             "support": {
-                "source": "https://github.com/drupal/core/tree/10.1.5"
+                "source": "https://github.com/drupal/core/tree/10.1.6"
             },
-            "time": "2023-10-04T21:37:59+00:00"
+            "time": "2023-11-01T11:59:20+00:00"
         },
         {
             "name": "drupal/core-composer-scaffold",
-            "version": "10.1.5",
+            "version": "10.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core-composer-scaffold.git",
@@ -2396,22 +2396,22 @@
                 "drupal"
             ],
             "support": {
-                "source": "https://github.com/drupal/core-composer-scaffold/tree/10.1.5"
+                "source": "https://github.com/drupal/core-composer-scaffold/tree/10.1.6"
             },
             "time": "2023-04-30T16:15:32+00:00"
         },
         {
             "name": "drupal/core-recommended",
-            "version": "10.1.5",
+            "version": "10.1.6",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core-recommended.git",
-                "reference": "2c5cf420ddb06f3e9b624d168b724ca1c7c326e2"
+                "reference": "13f5968854fe8bc02e659d8a4facc04a1a576ce5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/drupal/core-recommended/zipball/2c5cf420ddb06f3e9b624d168b724ca1c7c326e2",
-                "reference": "2c5cf420ddb06f3e9b624d168b724ca1c7c326e2",
+                "url": "https://api.github.com/repos/drupal/core-recommended/zipball/13f5968854fe8bc02e659d8a4facc04a1a576ce5",
+                "reference": "13f5968854fe8bc02e659d8a4facc04a1a576ce5",
                 "shasum": ""
             },
             "require": {
@@ -2420,7 +2420,7 @@
                 "doctrine/annotations": "~1.14.3",
                 "doctrine/deprecations": "~v1.1.1",
                 "doctrine/lexer": "~2.1.0",
-                "drupal/core": "10.1.5",
+                "drupal/core": "10.1.6",
                 "egulias/email-validator": "~4.0.1",
                 "guzzlehttp/guzzle": "~7.7.0",
                 "guzzlehttp/psr7": "~2.5.0",
@@ -2477,9 +2477,9 @@
             ],
             "description": "Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.",
             "support": {
-                "source": "https://github.com/drupal/core-recommended/tree/10.1.5"
+                "source": "https://github.com/drupal/core-recommended/tree/10.1.6"
             },
-            "time": "2023-10-04T21:37:59+00:00"
+            "time": "2023-11-01T11:59:20+00:00"
         },
         {
             "name": "drupal/crop",
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index a728fa13cf91104fc2fde16d34accc2592597bb2..610b100d50501a113f8070c27ea5db958f60fdf4 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -2295,17 +2295,17 @@
         },
         {
             "name": "drupal/core",
-            "version": "10.1.5",
-            "version_normalized": "10.1.5.0",
+            "version": "10.1.6",
+            "version_normalized": "10.1.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core.git",
-                "reference": "1272c35d547e844e7ebf3fe5513542291cda8cec"
+                "reference": "33695caf467e3e1e8c75d42215df57bee31be9ec"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/drupal/core/zipball/1272c35d547e844e7ebf3fe5513542291cda8cec",
-                "reference": "1272c35d547e844e7ebf3fe5513542291cda8cec",
+                "url": "https://api.github.com/repos/drupal/core/zipball/33695caf467e3e1e8c75d42215df57bee31be9ec",
+                "reference": "33695caf467e3e1e8c75d42215df57bee31be9ec",
                 "shasum": ""
             },
             "require": {
@@ -2382,7 +2382,7 @@
             "suggest": {
                 "ext-zip": "Needed to extend the plugin.manager.archiver service capability with the handling of files in the ZIP format."
             },
-            "time": "2023-10-04T21:37:59+00:00",
+            "time": "2023-11-01T11:59:20+00:00",
             "type": "drupal-core",
             "extra": {
                 "drupal-scaffold": {
@@ -2455,14 +2455,14 @@
             ],
             "description": "Drupal is an open source content management platform powering millions of websites and applications.",
             "support": {
-                "source": "https://github.com/drupal/core/tree/10.1.5"
+                "source": "https://github.com/drupal/core/tree/10.1.6"
             },
             "install-path": "../../web/core"
         },
         {
             "name": "drupal/core-composer-scaffold",
-            "version": "10.1.5",
-            "version_normalized": "10.1.5.0",
+            "version": "10.1.6",
+            "version_normalized": "10.1.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core-composer-scaffold.git",
@@ -2508,23 +2508,23 @@
                 "drupal"
             ],
             "support": {
-                "source": "https://github.com/drupal/core-composer-scaffold/tree/10.1.5"
+                "source": "https://github.com/drupal/core-composer-scaffold/tree/10.1.6"
             },
             "install-path": "../drupal/core-composer-scaffold"
         },
         {
             "name": "drupal/core-recommended",
-            "version": "10.1.5",
-            "version_normalized": "10.1.5.0",
+            "version": "10.1.6",
+            "version_normalized": "10.1.6.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/drupal/core-recommended.git",
-                "reference": "2c5cf420ddb06f3e9b624d168b724ca1c7c326e2"
+                "reference": "13f5968854fe8bc02e659d8a4facc04a1a576ce5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/drupal/core-recommended/zipball/2c5cf420ddb06f3e9b624d168b724ca1c7c326e2",
-                "reference": "2c5cf420ddb06f3e9b624d168b724ca1c7c326e2",
+                "url": "https://api.github.com/repos/drupal/core-recommended/zipball/13f5968854fe8bc02e659d8a4facc04a1a576ce5",
+                "reference": "13f5968854fe8bc02e659d8a4facc04a1a576ce5",
                 "shasum": ""
             },
             "require": {
@@ -2533,7 +2533,7 @@
                 "doctrine/annotations": "~1.14.3",
                 "doctrine/deprecations": "~v1.1.1",
                 "doctrine/lexer": "~2.1.0",
-                "drupal/core": "10.1.5",
+                "drupal/core": "10.1.6",
                 "egulias/email-validator": "~4.0.1",
                 "guzzlehttp/guzzle": "~7.7.0",
                 "guzzlehttp/psr7": "~2.5.0",
@@ -2583,7 +2583,7 @@
             "conflict": {
                 "webflo/drupal-core-strict": "*"
             },
-            "time": "2023-10-04T21:37:59+00:00",
+            "time": "2023-11-01T11:59:20+00:00",
             "type": "metapackage",
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -2591,7 +2591,7 @@
             ],
             "description": "Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.",
             "support": {
-                "source": "https://github.com/drupal/core-recommended/tree/10.1.5"
+                "source": "https://github.com/drupal/core-recommended/tree/10.1.6"
             },
             "install-path": null
         },
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index d0a63856e6447d391eb1b15523c44dcb65d5785f..ce3011d089f1e05ae7f82ac5b887397336a5b463 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -3,7 +3,7 @@
         'name' => 'osu-asc-webservices/d8-upstream',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
-        'reference' => 'ee2cb1c3540cb7e67140dd667e6828b9b59e5c9a',
+        'reference' => '6d88cd620aad5c039922728fc2c186268a052911',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
@@ -359,9 +359,9 @@
             'dev_requirement' => false,
         ),
         'drupal/core' => array(
-            'pretty_version' => '10.1.5',
-            'version' => '10.1.5.0',
-            'reference' => '1272c35d547e844e7ebf3fe5513542291cda8cec',
+            'pretty_version' => '10.1.6',
+            'version' => '10.1.6.0',
+            'reference' => '33695caf467e3e1e8c75d42215df57bee31be9ec',
             'type' => 'drupal-core',
             'install_path' => __DIR__ . '/../../web/core',
             'aliases' => array(),
@@ -370,24 +370,24 @@
         'drupal/core-annotation' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-assertion' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-class-finder' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-composer-scaffold' => array(
-            'pretty_version' => '10.1.5',
-            'version' => '10.1.5.0',
+            'pretty_version' => '10.1.6',
+            'version' => '10.1.6.0',
             'reference' => '1ccd7db5ff8a5425b5bbba9b9a05e366363c0a51',
             'type' => 'composer-plugin',
             'install_path' => __DIR__ . '/../drupal/core-composer-scaffold',
@@ -397,97 +397,97 @@
         'drupal/core-datetime' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-dependency-injection' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-diff' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-discovery' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-event-dispatcher' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-file-cache' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-file-security' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-filesystem' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-front-matter' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-gettext' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-graph' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-http-foundation' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-php-storage' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-plugin' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-proxy-builder' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-recommended' => array(
-            'pretty_version' => '10.1.5',
-            'version' => '10.1.5.0',
-            'reference' => '2c5cf420ddb06f3e9b624d168b724ca1c7c326e2',
+            'pretty_version' => '10.1.6',
+            'version' => '10.1.6.0',
+            'reference' => '13f5968854fe8bc02e659d8a4facc04a1a576ce5',
             'type' => 'metapackage',
             'install_path' => NULL,
             'aliases' => array(),
@@ -496,37 +496,37 @@
         'drupal/core-render' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-serialization' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-transliteration' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-utility' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-uuid' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/core-version' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                0 => '10.1.5',
+                0 => '10.1.6',
             ),
         ),
         'drupal/crop' => array(
@@ -1393,7 +1393,7 @@
         'osu-asc-webservices/d8-upstream' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
-            'reference' => 'ee2cb1c3540cb7e67140dd667e6828b9b59e5c9a',
+            'reference' => '6d88cd620aad5c039922728fc2c186268a052911',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
diff --git a/web/core/assets/scaffold/files/modules.README.txt b/web/core/assets/scaffold/files/modules.README.txt
index 529c31b2ba23f2281d9276e05dfb48ecda265395..249e8177ac230814f80fd44ea0acfadf2e6a2bb1 100644
--- a/web/core/assets/scaffold/files/modules.README.txt
+++ b/web/core/assets/scaffold/files/modules.README.txt
@@ -38,5 +38,5 @@ pattern may be used to restrict modules to a specific site instance.
 MORE INFORMATION
 ----------------
 
-Refer to the “Developing for Drupal” section of the README.txt in the Drupal
+Refer to the “Developing for Drupal” section of the README.md in the Drupal
 root directory for further information on extending Drupal with custom modules.
diff --git a/web/core/assets/scaffold/files/profiles.README.txt b/web/core/assets/scaffold/files/profiles.README.txt
index b0f0c0bac99138cd636c0e865eaa2354cc6531a3..6d11a51114c4598e66501df0864ace82c2576950 100644
--- a/web/core/assets/scaffold/files/profiles.README.txt
+++ b/web/core/assets/scaffold/files/profiles.README.txt
@@ -24,5 +24,5 @@ available to all sites during their initial site installation.
 MORE INFORMATION
 ----------------
 
-Refer to the "Installation profiles" section of the README.txt in the Drupal
+Refer to the "Installation profiles" section of the README.md in the Drupal
 root directory for further information on extending Drupal with custom profiles.
diff --git a/web/core/assets/scaffold/files/themes.README.txt b/web/core/assets/scaffold/files/themes.README.txt
index 039aaaf83a06ad33744027fa4ec95e8cc852e765..1e00ead6d85b3624bb7f3c5280c5a551c6ef84b7 100644
--- a/web/core/assets/scaffold/files/themes.README.txt
+++ b/web/core/assets/scaffold/files/themes.README.txt
@@ -26,6 +26,6 @@ pattern may be used to restrict themes to a specific site instance.
 MORE INFORMATION
 -----------------
 
-Refer to the "Appearance" section of the README.txt in the Drupal root directory
+Refer to the "Appearance" section of the README.md in the Drupal root directory
 for further information on customizing the appearance of Drupal with custom
 themes.
diff --git a/web/core/lib/Drupal.php b/web/core/lib/Drupal.php
index dd4bd657f55c8aa1f466498d7f3531186c95b6de..0dfbd6316d62bf70c9db379879176db6280e11b0 100644
--- a/web/core/lib/Drupal.php
+++ b/web/core/lib/Drupal.php
@@ -75,7 +75,7 @@ class Drupal {
   /**
    * The current system version.
    */
-  const VERSION = '10.1.5';
+  const VERSION = '10.1.6';
 
   /**
    * Core API compatibility.
diff --git a/web/core/lib/Drupal/Core/Asset/AssetResolver.php b/web/core/lib/Drupal/Core/Asset/AssetResolver.php
index 04a5186368b3e3c678491437d6b545a8a73b4896..e92102d4e385370350033ddc646ccf2c00d021ea 100644
--- a/web/core/lib/Drupal/Core/Asset/AssetResolver.php
+++ b/web/core/lib/Drupal/Core/Asset/AssetResolver.php
@@ -170,11 +170,13 @@ public function getCssAssets(AttachedAssetsInterface $assets, $optimize, Languag
     $this->moduleHandler->alter('css', $css, $assets, $language);
     $this->themeManager->alter('css', $css, $assets, $language);
 
-    // Sort CSS items, so that they appear in the correct order.
-    uasort($css, [static::class, 'sort']);
+    if (!empty($css)) {
+      // Sort CSS items, so that they appear in the correct order.
+      uasort($css, [static::class, 'sort']);
 
-    if ($optimize) {
-      $css = \Drupal::service('asset.css.collection_optimizer')->optimize($css, $libraries_to_load, $language);
+      if ($optimize) {
+        $css = \Drupal::service('asset.css.collection_optimizer')->optimize($css, $libraries_to_load, $language);
+      }
     }
     $this->cache->set($cid, $css, CacheBackendInterface::CACHE_PERMANENT, ['library_info']);
 
diff --git a/web/core/lib/Drupal/Core/Condition/ConditionPluginCollection.php b/web/core/lib/Drupal/Core/Condition/ConditionPluginCollection.php
index ec15926c65ad296188b681dd7dc566dc4412f713..4717cd997afd409239eaa402b42149d09698c7a0 100644
--- a/web/core/lib/Drupal/Core/Condition/ConditionPluginCollection.php
+++ b/web/core/lib/Drupal/Core/Condition/ConditionPluginCollection.php
@@ -44,7 +44,12 @@ public function getConfiguration() {
       unset($instance_config['context_mapping']);
       ksort($default_config);
       ksort($instance_config);
-      if ($default_config === $instance_config) {
+      // With PHP 8 type juggling, there should not be an issue using equal
+      // operator instead of identical operator. Allowing looser comparison here
+      // will prevent configuration from being erroneously exported when values
+      // are updated via form elements that return values of the wrong type, for
+      // example, '0'/'1' vs FALSE/TRUE.
+      if ($default_config == $instance_config) {
         unset($configuration[$instance_id]);
       }
     }
diff --git a/web/core/lib/Drupal/Core/Config/ConfigBase.php b/web/core/lib/Drupal/Core/Config/ConfigBase.php
index e4d298511599eeabfab91f6c8c71dccf964f7708..744af363b157b633f7063004207b4f5aa14c499d 100644
--- a/web/core/lib/Drupal/Core/Config/ConfigBase.php
+++ b/web/core/lib/Drupal/Core/Config/ConfigBase.php
@@ -200,8 +200,6 @@ public function set($key, $value) {
    * @param array $data
    *   Configuration array structure.
    *
-   * @return null
-   *
    * @throws \Drupal\Core\Config\ConfigValueException
    *   If any key in $data in any depth contains a dot.
    */
diff --git a/web/core/lib/Drupal/Core/Config/ConfigImporter.php b/web/core/lib/Drupal/Core/Config/ConfigImporter.php
index b6c6c7f9aa1b43d8d32eb8f4ba18d10dc4e2aaf7..3be2b32273e520803ebce610db70f4b62423f150 100644
--- a/web/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/web/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -996,6 +996,9 @@ protected function importConfig($collection, $op, $name) {
       $config->delete();
     }
     else {
+      if ($old_data = $this->storageComparer->getTargetStorage($collection)->read($name)) {
+        $config->initWithData($old_data);
+      }
       $data = $this->storageComparer->getSourceStorage($collection)->read($name);
       $config->setData($data ? $data : []);
       $config->save();
diff --git a/web/core/lib/Drupal/Core/Config/ImmutableConfig.php b/web/core/lib/Drupal/Core/Config/ImmutableConfig.php
index b0d4e8d8dcd6bcd9199b34d057e13133cdeab321..806c6b98cd6d0bbaac1083426280f62d4625a337 100644
--- a/web/core/lib/Drupal/Core/Config/ImmutableConfig.php
+++ b/web/core/lib/Drupal/Core/Config/ImmutableConfig.php
@@ -42,10 +42,7 @@ public function save($has_trusted_data = FALSE) {
   }
 
   /**
-   * Deletes the configuration object.
-   *
-   * @return \Drupal\Core\Config\Config
-   *   The configuration object.
+   * {@inheritdoc}
    */
   public function delete() {
     throw new ImmutableConfigException("Can not delete immutable configuration {$this->getName()}. Use \\Drupal\\Core\\Config\\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object");
diff --git a/web/core/lib/Drupal/Core/Config/StorableConfigBase.php b/web/core/lib/Drupal/Core/Config/StorableConfigBase.php
index f3202a764441f6e0f23af3c445b40bccea454f45..ae521919d00a507200e9de28a39371907ef1a622 100644
--- a/web/core/lib/Drupal/Core/Config/StorableConfigBase.php
+++ b/web/core/lib/Drupal/Core/Config/StorableConfigBase.php
@@ -145,8 +145,6 @@ protected function getSchemaWrapper() {
    * @param mixed $value
    *   Value to associate with the key.
    *
-   * @return null
-   *
    * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
    *   If the value is unsupported in configuration.
    */
diff --git a/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index 48adc9772a3d54b97411fc527a290c2f854bffae..b2eb730adadf39860ddbc0a0953fc7b8f6465327 100644
--- a/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -1455,9 +1455,6 @@ protected function addTableDefaults(&$schema) {
    *   The entity type.
    * @param array $schema
    *   The table schema, passed by reference.
-   *
-   * @return array
-   *   A partial schema array for the base table.
    */
   protected function processDataTable(ContentEntityTypeInterface $entity_type, array &$schema) {
     // Marking the respective fields as NOT NULL makes the indexes more
@@ -1470,11 +1467,8 @@ protected function processDataTable(ContentEntityTypeInterface $entity_type, arr
    *
    * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type
    *   The entity type.
-   * @param array $schema
+   * @param array &$schema
    *   The table schema, passed by reference.
-   *
-   * @return array
-   *   A partial schema array for the base table.
    */
   protected function processRevisionDataTable(ContentEntityTypeInterface $entity_type, array &$schema) {
     // Marking the respective fields as NOT NULL makes the indexes more
diff --git a/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php b/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
index 526cb42d69ae6f8d5023281626ba0034f5ed2596..8adc67a6c969b4e512e3e29b8d25bd77ef81c572 100644
--- a/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
+++ b/web/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
@@ -75,6 +75,22 @@ public function onError(ExceptionEvent $event) {
     }
   }
 
+  /**
+   * Log 4xx errors that are not 403 or 404.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
+   *   The event to process.
+   */
+  public function onClientError(ExceptionEvent $event) {
+    $exception = $event->getThrowable();
+    $error = Error::decodeException($exception);
+    $error += [
+      'status_code' => $exception->getStatusCode(),
+    ];
+    $this->logger->get('client error')
+      ->log($error['severity_level'], Error::DEFAULT_ERROR_MESSAGE, $error);
+  }
+
   /**
    * Log all exceptions.
    *
@@ -88,10 +104,14 @@ public function onException(ExceptionEvent $event) {
 
     // Treat any non-HTTP exception as if it were one, so we log it the same.
     if ($exception instanceof HttpExceptionInterface) {
-      $possible_method = 'on' . $exception->getStatusCode();
+      $status_code = $exception->getStatusCode();
+      $possible_method = 'on' . $status_code;
       if (method_exists($this, $possible_method)) {
         $method = $possible_method;
       }
+      elseif ($status_code >= 400 && $status_code < 500) {
+        $method = 'onClientError';
+      }
     }
 
     $this->$method($event);
diff --git a/web/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php b/web/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php
index 54c08284f4e1ec92e5f0c287a400205dd606d60b..2fb62c010762a1bac91cc85f81b5776c1faf1343 100644
--- a/web/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php
+++ b/web/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php
@@ -145,6 +145,13 @@ public function isComputed() {
     return $this->getBaseFieldDefinition()->isComputed();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isInternal(): bool {
+    return $this->getBaseFieldDefinition()->isInternal();
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php b/web/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php
index d75eb2295b2f4ba43f7e11dd149f6da31684785d..ead716800865c4d101c951eee233a00fca827d6a 100644
--- a/web/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php
+++ b/web/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php
@@ -74,7 +74,7 @@ public function getSettings();
    *   The setting name.
    *
    * @return mixed
-   *   The setting value.
+   *   The setting value or NULL if the setting name doesn't exist.
    */
   public function getSetting($setting_name);
 
diff --git a/web/core/lib/Drupal/Core/Form/EnforcedResponseException.php b/web/core/lib/Drupal/Core/Form/EnforcedResponseException.php
index 73649845eb467558e39688acf3278c79bf1e5f3b..ca3b8b8688e14f6687e446e9fd2122e3b4b571c3 100644
--- a/web/core/lib/Drupal/Core/Form/EnforcedResponseException.php
+++ b/web/core/lib/Drupal/Core/Form/EnforcedResponseException.php
@@ -37,7 +37,7 @@ public function __construct(Response $response, $message = "", $code = 0, \Excep
   /**
    * Return the response to be enforced.
    *
-   * @returns \Symfony\Component\HttpFoundation\Response $response
+   * @return \Symfony\Component\HttpFoundation\Response
    *   The response to be enforced.
    */
   public function getResponse() {
diff --git a/web/core/lib/Drupal/Core/Menu/menu.api.php b/web/core/lib/Drupal/Core/Menu/menu.api.php
index 10a3793b46c0467445facb6d2274e2b1fa121c56..4d775978c22590538f6c6b5a0642b4ca5fd732e4 100644
--- a/web/core/lib/Drupal/Core/Menu/menu.api.php
+++ b/web/core/lib/Drupal/Core/Menu/menu.api.php
@@ -221,11 +221,8 @@
 /**
  * Alters all the menu links discovered by the menu link plugin manager.
  *
- * @param array $links
- *   The link definitions to be altered.
- *
- * @return array
- *   An array of discovered menu links. Each link has a key that is the machine
+ * @param array &$links
+ *   The link definitions to be altered. Each link has a key that is the machine
  *   name, which must be unique. By default, use the route name as the
  *   machine name. In cases where multiple links use the same route name, such
  *   as two links to the same page in different menus, or two links using the
diff --git a/web/core/lib/Drupal/Core/Password/PasswordInterface.php b/web/core/lib/Drupal/Core/Password/PasswordInterface.php
index c514b840feb5c57ac3b664a47cab037e915ee83f..84aa11f3c59dee6b92edbfb306be55c90baab40e 100644
--- a/web/core/lib/Drupal/Core/Password/PasswordInterface.php
+++ b/web/core/lib/Drupal/Core/Password/PasswordInterface.php
@@ -27,8 +27,8 @@ public function hash(#[\SensitiveParameter] $password);
    * Check whether a plain text password matches a hashed password.
    *
    * @param string $password
-   *   A plain-text password
-   * @param string $hash
+   *   A plain-text password.
+   * @param string|null $hash
    *   A hashed password.
    *
    * @return bool
@@ -46,7 +46,7 @@ public function check(#[\SensitiveParameter] $password, #[\SensitiveParameter] $
    * This method returns TRUE if the password was hashed with an older
    * algorithm.
    *
-   * @param string $hash
+   * @param string|null $hash
    *   The hash to be checked.
    *
    * @return bool
diff --git a/web/core/lib/Drupal/Core/Password/PhpPassword.php b/web/core/lib/Drupal/Core/Password/PhpPassword.php
index f16eeb200cab3e254fc09d758ce1c914ee2674f9..c199de8fd8b7af65ebc5687c889dbc96e57e1322 100644
--- a/web/core/lib/Drupal/Core/Password/PhpPassword.php
+++ b/web/core/lib/Drupal/Core/Password/PhpPassword.php
@@ -45,6 +45,10 @@ public function check(#[\SensitiveParameter] $password, #[\SensitiveParameter] $
     if (strlen($password) > static::PASSWORD_MAX_LENGTH) {
       return FALSE;
     }
+    // Newly created accounts may have empty passwords.
+    if ($hash === NULL || $hash === '') {
+      return FALSE;
+    }
 
     return password_verify($password, $hash);
   }
diff --git a/web/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php b/web/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php
index 052c2be81ee3ed86be160356609000c64eb23349..7be8e393801f79071cf74430b636b401fc417952 100644
--- a/web/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php
+++ b/web/core/lib/Drupal/Core/Password/PhpassHashedPasswordBase.php
@@ -242,6 +242,10 @@ public function hash(#[\SensitiveParameter] $password) {
    * {@inheritdoc}
    */
   public function check(#[\SensitiveParameter] $password, #[\SensitiveParameter] $hash) {
+    // Newly created accounts may have empty passwords.
+    if ($hash === NULL || $hash === '') {
+      return FALSE;
+    }
     if (substr($hash, 0, 2) == 'U$') {
       // This may be an updated password from user_update_7000(). Such hashes
       // have 'U' added as the first character and need an extra md5() (see the
diff --git a/web/core/lib/Drupal/Core/Queue/QueueInterface.php b/web/core/lib/Drupal/Core/Queue/QueueInterface.php
index 8b9ff654c068bed674ed92d54e7fc2f2bcfd1118..5305a26be02a3cc94565f5a5e89d2274f2bec92f 100644
--- a/web/core/lib/Drupal/Core/Queue/QueueInterface.php
+++ b/web/core/lib/Drupal/Core/Queue/QueueInterface.php
@@ -18,7 +18,7 @@ interface QueueInterface {
    * @param $data
    *   Arbitrary data to be associated with the new task in the queue.
    *
-   * @return bool|int|string
+   * @return false|int|string
    *   A unique ID if the item was successfully created and was (best effort)
    *   added to the queue, otherwise FALSE. We don't guarantee the item was
    *   committed to disk etc, but as far as we know, the item is now in the
diff --git a/web/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php b/web/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php
index 3438d0fd27c792e66b7d2d4a94b65adcf477ad77..6468e02d17e71aa1bbe3015e2c109bded32ae49d 100644
--- a/web/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php
+++ b/web/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php
@@ -61,7 +61,7 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
     $title = $main_content['#title'] ?? $this->titleResolver->getTitle($request, $route_match->getRouteObject());
 
     // Determine the dialog options and the target for the OpenDialogCommand.
-    $options = $request->request->all('dialogOptions');
+    $options = $this->getDialogOptions($request);
     $target = $this->determineTargetSelector($options, $route_match);
 
     $response->addCommand(new OpenDialogCommand($target, $title, $content, $options));
@@ -100,4 +100,20 @@ protected function determineTargetSelector(array &$options, RouteMatchInterface
     return $target;
   }
 
+  /**
+   * Returns the dialog options from request.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The HTTP request.
+   *
+   * @return array
+   *   The dialog options used for OpenDialogCommand.
+   */
+  protected function getDialogOptions(Request $request): array {
+    if ($request->getMethod() === 'GET') {
+      return $request->query->all('dialogOptions');
+    }
+    return $request->request->all('dialogOptions');
+  }
+
 }
diff --git a/web/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php b/web/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php
index df80b7dce00ccc5237f8264a09b452ce86587900..6e344ce6397abede1d77932d7bd32e9ec61bb080 100644
--- a/web/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php
+++ b/web/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php
@@ -29,9 +29,8 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
     // If the main content doesn't provide a title, use the title resolver.
     $title = $main_content['#title'] ?? $this->titleResolver->getTitle($request, $route_match->getRouteObject());
 
-    // Determine the title: use the title provided by the main content if any,
-    // otherwise get it from the routing information.
-    $options = $request->request->all('dialogOptions');
+    // Determine the dialog options for the OpenDialogCommand.
+    $options = $this->getDialogOptions($request);
 
     $response->addCommand(new OpenModalDialogCommand($title, $content, $options));
     return $response;
diff --git a/web/core/lib/Drupal/Core/Render/Renderer.php b/web/core/lib/Drupal/Core/Render/Renderer.php
index 5d794f4517876ebd370cebf3bb027a658a1974f1..8097d84d7479daaa5c242a25bc707c3c0e537461 100644
--- a/web/core/lib/Drupal/Core/Render/Renderer.php
+++ b/web/core/lib/Drupal/Core/Render/Renderer.php
@@ -641,7 +641,7 @@ protected function setCurrentRenderContext(RenderContext $context = NULL) {
    *   bubbleable metadata associated with the markup that replaced the
    *   placeholders.
    *
-   * @returns bool
+   * @return bool
    *   Whether placeholders were replaced.
    *
    * @see \Drupal\Core\Render\Renderer::renderPlaceholder()
diff --git a/web/core/lib/Drupal/Core/Render/theme.api.php b/web/core/lib/Drupal/Core/Render/theme.api.php
index aba99058bca30e074062ac25765a5b255d2b4c91..36f1c096987366221c962e51395be162b9dd0502 100644
--- a/web/core/lib/Drupal/Core/Render/theme.api.php
+++ b/web/core/lib/Drupal/Core/Render/theme.api.php
@@ -688,9 +688,6 @@ function hook_theme_suggestions_HOOK(array $variables) {
  *   (in this case 'node__article') is available in
  *   $variables['theme_hook_original'].
  *
- * @return array
- *   An array of theme suggestions.
- *
  * @see hook_theme_suggestions_HOOK_alter()
  */
 function hook_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
diff --git a/web/core/lib/Drupal/Core/Session/SessionConfiguration.php b/web/core/lib/Drupal/Core/Session/SessionConfiguration.php
index 2687ac94b614dcd916f5c89b3797cf636b37fc9b..d1e5de1d934e40f9760c84d16def656cccab1d79 100644
--- a/web/core/lib/Drupal/Core/Session/SessionConfiguration.php
+++ b/web/core/lib/Drupal/Core/Session/SessionConfiguration.php
@@ -82,7 +82,7 @@ protected function getName(Request $request) {
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The request.
    *
-   * @returns string
+   * @return string
    *   The session name without the prefix (SESS/SSESS).
    */
   protected function getUnprefixedName(Request $request) {
@@ -118,7 +118,7 @@ protected function getUnprefixedName(Request $request) {
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The request.
    *
-   * @returns string|null
+   * @return string|null
    *   The session cookie domain, or NULL if the calculated value is invalid.
    */
   protected function getCookieDomain(Request $request) {
diff --git a/web/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php b/web/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php
index e5614d3d462e85e092f7fad8a2f43654463b4a6f..3b9c64f4337aa5c0460e31b20f761fb0a60aaa79 100644
--- a/web/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php
+++ b/web/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php
@@ -143,7 +143,7 @@ public function getSettings();
    *   The setting name.
    *
    * @return mixed
-   *   The setting value.
+   *   The setting value or NULL if the setting name doesn't exist.
    */
   public function getSetting($setting_name);
 
diff --git a/web/core/modules/big_pipe/js/big_pipe.js b/web/core/modules/big_pipe/js/big_pipe.js
index d20331de05673c7dfe5e390f7971e30caeec8cdc..fbfc7b26c12a5b088c6791aee8bf4439d82f05ee 100644
--- a/web/core/modules/big_pipe/js/big_pipe.js
+++ b/web/core/modules/big_pipe/js/big_pipe.js
@@ -59,8 +59,9 @@
    */
   function processReplacement(replacement) {
     const id = replacement.dataset.bigPipeReplacementForPlaceholderWithId;
-    // Because we use a mutation observer the content is guaranteed to be
-    // complete at this point.
+    // The content is not guaranteed to be complete at this point, but trimming
+    // it will not make a big change, since json will not be valid if it was
+    // not fully loaded anyway.
     const content = replacement.textContent.trim();
 
     // Ignore any placeholders that are not in the known placeholder list. Used
@@ -69,20 +70,32 @@
       return;
     }
 
-    // Immediately remove the replacement to prevent it being processed twice.
-    delete drupalSettings.bigPipePlaceholderIds[id];
-
     const response = mapTextContentToAjaxResponse(content);
 
     if (response === false) {
       return;
     }
 
+    // Immediately remove the replacement to prevent it being processed twice.
+    delete drupalSettings.bigPipePlaceholderIds[id];
+
     // Then, simulate an AJAX response having arrived, and let the Ajax system
     // handle it.
     ajaxObject.success(response, 'success');
   }
 
+  /**
+   * Checks if node is valid big pipe replacement.
+   */
+  function checkMutation(node) {
+    return Boolean(
+      node.nodeType === Node.ELEMENT_NODE &&
+        node.nodeName === 'SCRIPT' &&
+        node.dataset &&
+        node.dataset.bigPipeReplacementForPlaceholderWithId,
+    );
+  }
+
   /**
    * Check that the element is valid to process and process it.
    *
@@ -90,12 +103,7 @@
    *  The node added to the body element.
    */
   function checkMutationAndProcess(node) {
-    if (
-      node.nodeType === Node.ELEMENT_NODE &&
-      node.nodeName === 'SCRIPT' &&
-      node.dataset &&
-      node.dataset.bigPipeReplacementForPlaceholderWithId
-    ) {
+    if (checkMutation(node)) {
       processReplacement(node);
     }
   }
@@ -107,8 +115,20 @@
    *  The list of mutations registered by the browser.
    */
   function processMutations(mutations) {
-    mutations.forEach(({ addedNodes }) => {
+    mutations.forEach(({ addedNodes, type, target }) => {
       addedNodes.forEach(checkMutationAndProcess);
+
+      // Checks if parent node of target node has not been processed.
+      // @see `@ingroup large_chunk` for more information.
+      if (
+        type === 'characterData' &&
+        checkMutation(target.parentNode) &&
+        drupalSettings.bigPipePlaceholderIds[
+          target.parentNode.dataset.bigPipeReplacementForPlaceholderWithId
+        ] === true
+      ) {
+        processReplacement(target.parentNode);
+      }
     });
   }
 
@@ -121,8 +141,19 @@
   // in the DOM before the mutation observer is started.
   document.querySelectorAll(replacementsSelector).forEach(processReplacement);
 
-  // Start observing the body element for new children.
-  observer.observe(document.body, { childList: true });
+  // Start observing the body element for new children and for new changes in
+  // Text nodes of elements. We need to track Text nodes because content
+  // of the node can be too large, browser will receive not fully loaded chunk
+  // and render it as is. At this moment json inside script will be invalid and
+  // we need to track new changes to that json (Text node), once it will be
+  // fully loaded it will be processed.
+  // @ingroup large_chunk
+  observer.observe(document.body, {
+    childList: true,
+    // Without this options characterData will not be triggered inside child nodes.
+    subtree: true,
+    characterData: true,
+  });
 
   // As soon as the document is loaded, no more replacements will be added.
   // Immediately fetch and process all pending mutations and stop the observer.
diff --git a/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.module b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.module
new file mode 100644
index 0000000000000000000000000000000000000000..c56a6bd86b4323522547867131f53bee217b11aa
--- /dev/null
+++ b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.module
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Support module for BigPipe testing.
+ */
+
+/**
+ * Implements hook_theme().
+ *
+ * @see \Drupal\Tests\big_pipe\FunctionalJavascript\BigPipeRegressionTest::testBigPipeLargeContent
+ */
+function big_pipe_regression_test_theme() {
+  return [
+    'big_pipe_test_large_content' => [
+      'variables' => [],
+    ],
+  ];
+}
diff --git a/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.routing.yml b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.routing.yml
index bd0543b0e7a567a8d6b915bafd358d4d6ae1e812..82a53d6e2f6018bb194f0d601d0ad2ffc70954b3 100644
--- a/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.routing.yml
+++ b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/big_pipe_regression_test.routing.yml
@@ -11,3 +11,11 @@ big_pipe_regression_test.2802923:
     _controller: '\Drupal\big_pipe_regression_test\BigPipeRegressionTestController::regression2802923'
   requirements:
     _access: 'TRUE'
+
+big_pipe_test_large_content:
+  path: '/big_pipe_test_large_content'
+  defaults:
+    _controller: '\Drupal\big_pipe_regression_test\BigPipeRegressionTestController::largeContent'
+    _title: 'BigPipe test large content'
+  requirements:
+    _access: 'TRUE'
diff --git a/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
index 6c1fde73319e62fa8eb78df65443c588a0d43b50..f612330e0292675985991768f53f6e1ae28a7317 100644
--- a/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
+++ b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
@@ -32,6 +32,32 @@ public function regression2802923() {
     ];
   }
 
+  /**
+   * A page with large content.
+   *
+   * @see \Drupal\Tests\big_pipe\FunctionalJavascript\BigPipeRegressionTest::testBigPipeLargeContent
+   */
+  public function largeContent() {
+    return [
+      'item1' => [
+        '#lazy_builder' => [static::class . '::largeContentBuilder', []],
+        '#create_placeholder' => TRUE,
+      ],
+    ];
+  }
+
+  /**
+   * Renders large content.
+   *
+   * @see \Drupal\Tests\big_pipe\FunctionalJavascript\BigPipeRegressionTest::testBigPipeLargeContent
+   */
+  public static function largeContentBuilder() {
+    return [
+      '#theme' => 'big_pipe_test_large_content',
+      '#cache' => ['max-age' => 0],
+    ];
+  }
+
   /**
    * #lazy_builder callback; builds <time> markup with current time.
    *
@@ -48,7 +74,7 @@ public static function currentTime() {
    * {@inheritdoc}
    */
   public static function trustedCallbacks() {
-    return ['currentTime'];
+    return ['currentTime', 'largeContentBuilder'];
   }
 
 }
diff --git a/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/templates/big-pipe-test-large-content.html.twig b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/templates/big-pipe-test-large-content.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..86a5291cc6535d4fac8bfa944f9a42caffaf9bf9
--- /dev/null
+++ b/web/core/modules/big_pipe/tests/modules/big_pipe_regression_test/templates/big-pipe-test-large-content.html.twig
@@ -0,0 +1,6 @@
+<div id="big-pipe-large-content">
+    {% for i in 0..130000 %}
+        boing
+    {% endfor %}
+</div>
+
diff --git a/web/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php b/web/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php
index 0cfeb11875e58ab3ada6fc1094776be0f009ba17..a06f39e9c7208867b96572fdc8b579d5c690d975 100644
--- a/web/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php
+++ b/web/core/modules/big_pipe/tests/src/FunctionalJavascript/BigPipeRegressionTest.php
@@ -124,4 +124,28 @@ public function testPlaceholderInParagraph_2802923() {
     $this->assertJsCondition('document.querySelectorAll(\'p\').length === 1');
   }
 
+  /**
+   * Tests BigPipe large content.
+   *
+   * Repeat loading of same page for two times, after second time the page is
+   * cached and the bug consistently reproducible.
+   */
+  public function testBigPipeLargeContent() {
+    $user = $this->drupalCreateUser();
+    $this->drupalLogin($user);
+    $assert_session = $this->assertSession();
+
+    $this->drupalGet(Url::fromRoute('big_pipe_test_large_content'));
+    $this->assertNotNull($assert_session->waitForElement('css', 'script[data-big-pipe-event="stop"]'));
+    $this->assertCount(0, $this->getDrupalSettings()['bigPipePlaceholderIds']);
+    $this->assertCount(2, $this->getSession()->getPage()->findAll('css', 'script[data-big-pipe-replacement-for-placeholder-with-id]'));
+    $assert_session->elementExists('css', '#big-pipe-large-content');
+
+    $this->drupalGet(Url::fromRoute('big_pipe_test_large_content'));
+    $this->assertNotNull($assert_session->waitForElement('css', 'script[data-big-pipe-event="stop"]'));
+    $this->assertCount(0, $this->getDrupalSettings()['bigPipePlaceholderIds']);
+    $this->assertCount(2, $this->getSession()->getPage()->findAll('css', 'script[data-big-pipe-replacement-for-placeholder-with-id]'));
+    $assert_session->elementExists('css', '#big-pipe-large-content');
+  }
+
 }
diff --git a/web/core/modules/block/migrations/d7_block.yml b/web/core/modules/block/migrations/d7_block.yml
index c6b8dffbca3112d48d87d62f5bb296c52e3f2394..184eee2f81ba7c4b198f29a143fdb0481e29bafa 100644
--- a/web/core/modules/block/migrations/d7_block.yml
+++ b/web/core/modules/block/migrations/d7_block.yml
@@ -1,4 +1,4 @@
-# cspell: ignore firstcolumn secondcolumn thirdcolumn fourthcolumn
+# cspell:ignore firstcolumn secondcolumn thirdcolumn fourthcolumn
 id: d7_block
 label: Blocks
 # This configuration migration depends on the d7_custom_block content migration.
diff --git a/web/core/modules/block/src/BlockForm.php b/web/core/modules/block/src/BlockForm.php
index 90cd6823ffb4881561f2d1e4fd7136f7245b19f9..7bbf1b8654b6c8ae3eceb16f936fb087aab6be3e 100644
--- a/web/core/modules/block/src/BlockForm.php
+++ b/web/core/modules/block/src/BlockForm.php
@@ -309,13 +309,6 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
   protected function validateVisibility(array $form, FormStateInterface $form_state) {
     // Validate visibility condition settings.
     foreach ($form_state->getValue('visibility') as $condition_id => $values) {
-      // All condition plugins use 'negate' as a Boolean in their schema.
-      // However, certain form elements may return it as 0/1. Cast here to
-      // ensure the data is in the expected type.
-      if (array_key_exists('negate', $values)) {
-        $form_state->setValue(['visibility', $condition_id, 'negate'], (bool) $values['negate']);
-      }
-
       // Allow the condition to validate the form.
       $condition = $form_state->get(['conditions', $condition_id]);
       $condition->validateConfigurationForm($form['visibility'][$condition_id], SubformState::createForSubform($form['visibility'][$condition_id], $form, $form_state));
@@ -342,9 +335,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
 
     $this->submitVisibility($form, $form_state);
+  }
 
-    // Save the settings of the plugin.
-    $entity->save();
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, FormStateInterface $form_state) {
+    $value = parent::save($form, $form_state);
 
     $this->messenger()->addStatus($this->t('The block configuration has been saved.'));
     $form_state->setRedirect(
@@ -354,6 +351,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       ],
       ['query' => ['block-placement' => Html::getClass($this->entity->id())]]
     );
+
+    return $value;
   }
 
   /**
diff --git a/web/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php b/web/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php
index 73444dfab1fd2c7d99ed2ec1ea138ac15f55f869..8f7f9f6e36a0c1f9de4aed6a5a40c68118054628 100644
--- a/web/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php
+++ b/web/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php
@@ -28,7 +28,7 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI
   /**
    * The block_content entity storage handler.
    *
-   * @var \Drupal\Core\Entity\EntityStorageInterface
+   * @var \Drupal\Core\Entity\EntityStorageInterface|null
    */
   protected $blockContentStorage;
 
@@ -41,12 +41,13 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI
    *   The plugin ID.
    * @param array $plugin_definition
    *   The plugin definition.
-   * @param \Drupal\Core\Entity\EntityStorageInterface $storage
-   *   The block content storage object.
+   * @param \Drupal\Core\Entity\EntityStorageInterface|null $storage
+   *   The block content storage object. NULL if the block_content module is
+   *   not installed.
    * @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
    *   The migrate lookup service.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityStorageInterface $storage, MigrateLookupInterface $migrate_lookup) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ?EntityStorageInterface $storage, MigrateLookupInterface $migrate_lookup) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->blockContentStorage = $storage;
     $this->migrateLookup = $migrate_lookup;
@@ -61,7 +62,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $entity_type_manager->getDefinition('block_content') ? $entity_type_manager->getStorage('block_content') : NULL,
+      $entity_type_manager->hasDefinition('block_content') ? $entity_type_manager->getStorage('block_content') : NULL,
       $container->get('migrate.lookup')
     );
   }
diff --git a/web/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockNoBlockContentTest.php b/web/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockNoBlockContentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c7b92dc9ee1daaa27e865948364f262a94f037d
--- /dev/null
+++ b/web/core/modules/block/tests/src/Kernel/Migrate/d7/MigrateBlockNoBlockContentTest.php
@@ -0,0 +1,161 @@
+<?php
+
+namespace Drupal\Tests\block\Kernel\Migrate\d7;
+
+use Drupal\block\Entity\Block;
+use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
+
+/**
+ * Tests the migration of blocks without Block Content installed.
+ *
+ * @group block
+ */
+class MigrateBlockNoBlockContentTest extends MigrateDrupal7TestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'block',
+    'views',
+    'comment',
+    'menu_ui',
+    'node',
+    'text',
+    'filter',
+    'path_alias',
+    'user',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    // Install the themes used for this test.
+    $this->container->get('theme_installer')->install(['olivero', 'claro']);
+
+    $this->installConfig(static::$modules);
+
+    // Set Olivero and Claro as the default public and admin theme.
+    $config = $this->config('system.theme');
+    $config->set('default', 'olivero');
+    $config->set('admin', 'claro');
+    $config->save();
+
+    $this->executeMigrations([
+      'd7_filter_format',
+      'd7_user_role',
+      'd7_block',
+    ]);
+    block_rebuild();
+  }
+
+  /**
+   * Asserts various aspects of a block.
+   *
+   * @param string $id
+   *   The block ID.
+   * @param string $plugin_id
+   *   The block's plugin ID.
+   * @param array $roles
+   *   Role IDs the block is expected to have.
+   * @param string $pages
+   *   The list of pages on which the block should appear.
+   * @param string $region
+   *   The display region.
+   * @param string $theme
+   *   The theme.
+   * @param int $weight
+   *   The block weight.
+   * @param string $label
+   *   The block label.
+   * @param string $label_display
+   *   The block label display setting.
+   * @param bool $status
+   *   Whether the block is expected to be enabled or disabled.
+   *
+   * @internal
+   */
+  public function assertEntity(string $id, string $plugin_id, array $roles, string $pages, string $region, string $theme, int $weight, string $label, string $label_display, bool $status = TRUE): void {
+    $block = Block::load($id);
+    $this->assertInstanceOf(Block::class, $block);
+    /** @var \Drupal\block\BlockInterface $block */
+    $this->assertSame($plugin_id, $block->getPluginId());
+
+    $visibility = $block->getVisibility();
+    if ($roles) {
+      $this->assertSame($roles, array_values($visibility['user_role']['roles']));
+      $this->assertSame('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']);
+    }
+    if ($pages) {
+      $this->assertSame($pages, $visibility['request_path']['pages']);
+    }
+
+    $this->assertSame($region, $block->getRegion());
+    $this->assertSame($theme, $block->getTheme());
+    $this->assertSame($weight, $block->getWeight());
+    $this->assertSame($status, $block->status());
+
+    $config = $this->config('block.block.' . $id);
+    $this->assertSame($label, $config->get('settings.label'));
+    $this->assertSame($label_display, $config->get('settings.label_display'));
+  }
+
+  /**
+   * Tests the block migration.
+   */
+  public function testBlockMigration(): void {
+    $this->assertEntity('bartik_system_main', 'system_main_block', [], '', 'content', 'olivero', 0, '', '0');
+    $this->assertEntity('bartik_search_form', 'search_form_block', [], '', 'content', 'olivero', -1, '', '0');
+    $this->assertEntity('bartik_user_login', 'user_login_block', [], '', 'content', 'olivero', 0, 'User login title', 'visible');
+    $this->assertEntity('bartik_system_powered_by', 'system_powered_by_block', [], '', 'footer_bottom', 'olivero', 10, '', '0');
+    $this->assertEntity('seven_system_main', 'system_main_block', [], '', 'content', 'claro', 0, '', '0');
+    $this->assertEntity('seven_user_login', 'user_login_block', [], '', 'content', 'claro', 10, 'User login title', 'visible');
+
+    // Assert that disabled blocks (or enabled blocks whose plugin IDs could
+    // be resolved) did not migrate.
+    $non_existent_blocks = [
+      'bartik_system_navigation',
+      'bartik_system_help',
+      'seven_user_new',
+      'seven_search_form',
+      'bartik_comment_recent',
+      'bartik_node_syndicate',
+      'bartik_node_recent',
+      'bartik_shortcut_shortcuts',
+      'bartik_system_management',
+      'bartik_system_user-menu',
+      'bartik_system_main-menu',
+      'bartik_user_new',
+      'bartik_user_online',
+      'seven_comment_recent',
+      'seven_node_syndicate',
+      'seven_shortcut_shortcuts',
+      'seven_system_powered-by',
+      'seven_system_navigation',
+      'seven_system_management',
+      'seven_system_user-menu',
+      'seven_system_main-menu',
+      'seven_user_online',
+      'bartik_blog_recent',
+      'bartik_book_navigation',
+      'bartik_locale_language',
+      'bartik_forum_active',
+      'bartik_forum_new',
+      'seven_blog_recent',
+      'seven_book_navigation',
+      'seven_locale_language',
+      'seven_forum_active',
+      'seven_forum_new',
+      'bartik_menu_menu-test-menu',
+      'bartik_statistics_popular',
+      'seven_menu_menu-test-menu',
+      'seven_statistics_popular',
+      'seven_block_1',
+    ];
+    $this->assertEmpty(Block::loadMultiple($non_existent_blocks));
+  }
+
+}
diff --git a/web/core/modules/ckeditor5/js/ckeditor5.dialog.fix.js b/web/core/modules/ckeditor5/js/ckeditor5.dialog.fix.js
index 1f4ed1d7feb523cffee35f245b7dab06da4f38fa..41449dcf693fab7ff15220fd4b57bd89a71cab8d 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5.dialog.fix.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5.dialog.fix.js
@@ -12,6 +12,12 @@
     // CKEditor 5 in modals can work as expected.
     // @see https://api.jqueryui.com/dialog/#method-_allowInteraction
     _allowInteraction(event) {
+      // Fixes "Uncaught TypeError: event.target.classList is undefined"
+      // in Firefox (only).
+      // @see https://www.drupal.org/project/drupal/issues/3351600
+      if (event.target.classList === undefined) {
+        return this._super(event);
+      }
       return event.target.classList.contains('ck') || this._super(event);
     },
   });
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlbuilder.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlbuilder.js
index fb5846b3b4a384511550b0722295686712e76820..48178378d5de70cf916cc90d7da4e69c4deb8cbb 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlbuilder.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlbuilder.js
@@ -1,4 +1,4 @@
-// cSpell:words apos
+// cspell:ignore apos
 
 /**
  * HTML builder that converts document fragments into strings.
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlengine.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlengine.js
index e365d42d4955fbcc45f9b0f15307f3ec60d0bd41..1bbb1514aa538741e698dfe0cbe9c03f53f54e1b 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlengine.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlengine.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-// cSpell:words drupalhtmlwriter
+// cspell:ignore drupalhtmlwriter
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalHtmlWriter from './drupalhtmlwriter';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlwriter.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlwriter.js
index 4851ebdc720a4a9615ec0b06e86fcd80139a9110..5201504dd160cfa792eb59b15924e8e17de91ba2 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlwriter.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalHtmlEngine/src/drupalhtmlwriter.js
@@ -1,4 +1,4 @@
-// cSpell:words drupalhtmlbuilder dataprocessor basichtmlwriter htmlwriter
+// cspell:ignore drupalhtmlbuilder dataprocessor basichtmlwriter htmlwriter
 import DrupalHtmlBuilder from './drupalhtmlbuilder';
 
 /**
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimage.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimage.js
index 5b67bd18d09168f548567c861cf2726a636a7388..53b405468e8b281c6644da6cf0297ede67e22e38 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimage.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimage.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalimageediting drupalimagealternativetext */
+/* cspell:ignore drupalimageediting drupalimagealternativetext */
 
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalImageEditing from './drupalimageediting';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimagealternativetext.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimagealternativetext.js
index e82ab82527434cb261028234abeb0b5f1b45109f..18059d9d5ad39dc6c60a12887ad6b89abc088c85 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimagealternativetext.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimagealternativetext.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words imagealternativetext imagetextalternativeediting drupalimagealternativetextediting drupalimagealternativetextui */
+/* cspell:ignore imagealternativetext imagetextalternativeediting drupalimagealternativetextediting drupalimagealternativetextui */
 
 /**
  * @module drupalImage/imagealternativetext
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimageediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimageediting.js
index f1a5be865d95cef94d93b576c435d8aa2f921ea2..b594e2a1f9989ddbe60afd2d69bcb1d0ab8d9689 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimageediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/drupalimageediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-// cSpell:words datafilter downcasted linkimageediting emptyelement downcastdispatcher
+// cspell:ignore datafilter downcasted linkimageediting emptyelement downcastdispatcher
 import { Plugin } from 'ckeditor5/src/core';
 import { setViewAttributes } from '@ckeditor/ckeditor5-html-support/src/utils';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextediting.js
index f931c874fe43938b373b4273eb33f8a45c32200e..ce35fa5a225160450c6cdfb3c39198b1a138fb59 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words imagealternativetext drupalimagealternativetextediting drupalimagetextalternativecommand textalternativemissingview imagetextalternativecommand */
+/* cspell:ignore imagealternativetext drupalimagealternativetextediting drupalimagetextalternativecommand textalternativemissingview imagetextalternativecommand */
 
 /**
  * @module drupalImage/imagealternativetext/drupalimagealternativetextediting
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextui.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextui.js
index 597ebda91e0b6d3397bb48b42982fac510e290a1..ed10936a9fa5518dd8dc04ca94900ae6c56fe74b 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextui.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/drupalimagealternativetextui.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalimagealternativetextui contextualballoon componentfactory imagealternativetextformview missingalternativetextview imagetextalternativeui imagealternativetext */
+/* cspell:ignore drupalimagealternativetextui contextualballoon componentfactory imagealternativetextformview missingalternativetextview imagetextalternativeui imagealternativetext */
 
 /**
  * @module drupalImage/imagealternativetext/drupalimagealternativetextui
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/imagealternativetextformview.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/imagealternativetextformview.js
index df231866fe49250ed156cb8b65568bca2ffbc52d..e87c06521d527f55e01165d1abb656680bbe7932 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/imagealternativetextformview.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/imagealternativetextformview.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words focustracker keystrokehandler labeledfield labeledfieldview buttonview viewcollection focusables focuscycler switchbuttonview imagealternativetextformview imagealternativetext */
+/* cspell:ignore focustracker keystrokehandler labeledfield labeledfieldview buttonview viewcollection focusables focuscycler switchbuttonview imagealternativetextformview imagealternativetext */
 
 /**
  * @module drupalImage/imagealternativetext/ui/imagealternativetextformview
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/missingalternativetextview.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/missingalternativetextview.js
index ddd8f6e3b77783b3800c56e5d99045e3786794fa..a1bb44567ae63592d8ce913a67f6a93b42c377d3 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/missingalternativetextview.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imagealternativetext/ui/missingalternativetextview.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words imagetextalternative missingalternativetextview imagealternativetext */
+/* cspell:ignore imagetextalternative missingalternativetextview imagealternativetext */
 
 import { View, ButtonView } from 'ckeditor5/src/ui';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalfilerepository.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalfilerepository.js
index a851e38efee188d63b0e92510b525141d9c7d31a..4604b9e12c9f6f68d39da0ab3dbfb17b6096d11c 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalfilerepository.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalfilerepository.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words uploadurl drupalimageuploadadapter  */
+/* cspell:ignore uploadurl drupalimageuploadadapter  */
 
 import { Plugin } from 'ckeditor5/src/core';
 import { FileRepository } from 'ckeditor5/src/upload';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageupload.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageupload.js
index 629f086cc92fb76e1c420fe48383708d98965521..fc37adb824dcd1c93ade199b0d3d5f31e4c9c5e0 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageupload.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageupload.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalimageuploadediting drupalfilerepository */
+/* cspell:ignore drupalimageuploadediting drupalfilerepository */
 
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalImageUploadEditing from './drupalimageuploadediting';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageuploadadapter.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageuploadadapter.js
index 50969fb00c3078fc518a284104098d044f5167cf..13abca90afa69e0f81e096f92e385613780d6f32 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageuploadadapter.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalImage/src/imageupload/drupalimageuploadadapter.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words simpleuploadadapter filerepository */
+/* cspell:ignore simpleuploadadapter filerepository */
 
 /**
  * Upload adapter.
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle.js
index 52d120693fe7ed09143c549fe5d1024ffa210609..ea61869a8c2f75ab3236421d2e5c96a0250ab987 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalelementstyle drupalelementstyleui drupalelementstyleediting imagestyle drupalmediatoolbar drupalmediaediting */
+/* cspell:ignore drupalelementstyle drupalelementstyleui drupalelementstyleediting imagestyle drupalmediatoolbar drupalmediaediting */
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalElementStyleUi from './drupalelementstyle/drupalelementstyleui';
 import DrupalElementStyleEditing from './drupalelementstyle/drupalelementstyleediting';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleediting.js
index dd8eba70dd3989cdd5ce38f9e63bcf1b9a1c88e6..c2e0922a7112aa7e51cfb01c2acd740c7622e5c4 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalelementstylecommand */
+/* cspell:ignore drupalelementstylecommand */
 import { Plugin, icons } from 'ckeditor5/src/core';
 import { first } from 'ckeditor5/src/utils';
 import DrupalElementStyleCommand from './drupalelementstylecommand';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleui.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleui.js
index 21869fe57f5d4d57e5c54afdfcc106077a506358..3dbb39553800dabb7bedf6705334326104b995c6 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleui.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/drupalelementstyleui.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalelementstyleediting splitbutton imagestyle componentfactory buttonview */
+/* cspell:ignore drupalelementstyleediting splitbutton imagestyle componentfactory buttonview */
 import { Plugin } from 'ckeditor5/src/core';
 import { Collection, toMap } from 'ckeditor5/src/utils';
 import utils from '@ckeditor/ckeditor5-image/src/imagestyle/utils';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/utils.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/utils.js
index 4db1f8ee409408a02b1eb765c6fb64919799bf3b..7de86e4c58db5cd5745c1ae8930d6629d2ab0bfc 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/utils.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalelementstyle/utils.js
@@ -1,4 +1,4 @@
-/* cspell:words documentselection */
+/* cspell:ignore documentselection */
 /**
  * Checks the schema to see if drupalElementStyle is supported on the element.
  *
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmedia.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmedia.js
index 847f762b55fe6d0e83c6e31fd0dcd63dcd2f7b08..fbb37e8eb11289e8425898edcc4c095fb9357c61 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmedia.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmedia.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupallinkmediaediting drupallinkmediaui */
+/* cspell:ignore drupallinkmediaediting drupallinkmediaui */
 
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalLinkMediaEditing from './drupallinkmediaediting';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaediting.js
index 658e6ee66b9f952e7e37ee25f3d684a7247c8d59..67f7f303d12944e5b4809458250347d5e115ff5c 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupallinkmediaediting linkediting linkimageediting linkcommand */
+/* cspell:ignore drupallinkmediaediting linkediting linkimageediting linkcommand */
 import { Plugin } from 'ckeditor5/src/core';
 import { Matcher } from 'ckeditor5/src/engine';
 import { toMap } from 'ckeditor5/src/utils';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaui.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaui.js
index c366ec21025cd0d935039bc6e6699519d18f001e..cb4685e49f23bed535c2f512f6d1f349ef57e910 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaui.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupallinkmedia/drupallinkmediaui.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-// cSpell:words linkui
+// cspell:ignore linkui
 import { Plugin } from 'ckeditor5/src/core';
 import { LINK_KEYSTROKE } from '@ckeditor/ckeditor5-link/src/utils';
 import { ButtonView } from 'ckeditor5/src/ui';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmedia.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmedia.js
index 74167436c3f19a4db113ce170a802b9bd9e69e95..c7271d361467b34e1033f892f16d70d8a9763a1f 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmedia.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmedia.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalmediaediting drupalmediageneralhtmlsupport drupalmediaui drupalmediatoolbar mediaimagetextalternative */
+/* cspell:ignore drupalmediaediting drupalmediageneralhtmlsupport drupalmediaui drupalmediatoolbar mediaimagetextalternative */
 
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalMediaEditing from './drupalmediaediting';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption.js
index 3abd8b45af4941033d2cb1646a9e86c01ab77655..c5a1a62dd222cab77ae9ceea824554eed27b362f 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalmediacaption drupalmediacaptionediting drupalmediacaptionui */
+/* cspell:ignore drupalmediacaption drupalmediacaptionediting drupalmediacaptionui */
 import { Plugin } from 'ckeditor5/src/core';
 import DrupalMediaCaptionEditing from './drupalmediacaption/drupalmediacaptionediting';
 import DrupalMediaCaptionUI from './drupalmediacaption/drupalmediacaptionui';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptioncommand.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptioncommand.js
index c17a9e1beff66deda310c92c26686a5ebaac6c4b..f1268afdab03696d93b1c76fc450f0699a8f8b13 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptioncommand.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptioncommand.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words imagecaption */
+/* cspell:ignore imagecaption */
 import { Command } from 'ckeditor5/src/core';
 import { getClosestSelectedDrupalMediaElement, isDrupalMedia } from '../utils';
 import { getMediaCaptionFromModelSelection } from './utils';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptionediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptionediting.js
index d22100c4761b37bbcf339a44e46f51de64c2e8c1..f0d5faa5efbeb99f5a8a8e0012aa4cd5f2dbbae6 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptionediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediacaption/drupalmediacaptionediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words insertdrupalmedia JSONified drupalmediacaptioncommand downcasted */
+/* cspell:ignore insertdrupalmedia JSONified drupalmediacaptioncommand downcasted */
 import { Plugin } from 'ckeditor5/src/core';
 import { Element, enablePlaceholder } from 'ckeditor5/src/engine';
 import { toWidgetEditable } from 'ckeditor5/src/widget';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediaediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediaediting.js
index d31db61f7a472f5fcc43eb45511334ed6c08d8ea..d4f227f01c97b63f6c233ced921ddd888580fc44 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediaediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediaediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words insertdrupalmedia drupalmediaediting insertdrupalmediacommand drupalmediametadatarepository */
+/* cspell:ignore insertdrupalmedia drupalmediaediting insertdrupalmediacommand drupalmediametadatarepository */
 
 import { Plugin } from 'ckeditor5/src/core';
 import { toWidget, Widget } from 'ckeditor5/src/widget';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediageneralhtmlsupport.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediageneralhtmlsupport.js
index c770a53169eac81474783d2de163b831e96df2cf..66ca7dbee62ee9bb97f9bed0f95a2ec718903f18 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediageneralhtmlsupport.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediageneralhtmlsupport.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-// cSpell:words datafilter eventinfo downcastdispatcher generalhtmlsupport
+// cspell:ignore datafilter eventinfo downcastdispatcher generalhtmlsupport
 import { Plugin } from 'ckeditor5/src/core';
 import { setViewAttributes } from '@ckeditor/ckeditor5-html-support/src/utils';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediametadatarepository.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediametadatarepository.js
index a6ebd11a1b7b603edc43c263974687296ed95dfc..81e2f79d6b20bfd5981f97e33dddc36df1b82f2d 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediametadatarepository.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediametadatarepository.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalmediametadatarepository */
+/* cspell:ignore drupalmediametadatarepository */
 
 import { Plugin } from 'ckeditor5/src/core';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediatoolbar.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediatoolbar.js
index de4dc9e177f0d11d9aa3fe837558dea288968395..e79f82282f0531207fce03dbe07b4bf525ed8a10 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediatoolbar.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/drupalmediatoolbar.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words drupalmediatoolbar */
+/* cspell:ignore drupalmediatoolbar */
 import { Plugin } from 'ckeditor5/src/core';
 import { WidgetToolbarRepository } from 'ckeditor5/src/widget';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/insertdrupalmedia.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/insertdrupalmedia.js
index be47f38c313c040005618fd84d3cfd1f912172b1..df600cd3d0af8e1093379037a4158e2dfa48f436 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/insertdrupalmedia.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/insertdrupalmedia.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-// cSpell:words insertdrupalmediacommand
+// cspell:ignore insertdrupalmediacommand
 import { Command } from 'ckeditor5/src/core';
 import { groupNameToModelAttributeKey } from './utils';
 
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeediting.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeediting.js
index 994c6b83fc40566bf11d7dc4186fb0566e1ac404..984058ccf108f1897f0ad99ce4ccc488926d4aaa 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeediting.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeediting.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words mediaimagetextalternativecommand drupalmediametadatarepository insertdrupalmediacommand */
+/* cspell:ignore mediaimagetextalternativecommand drupalmediametadatarepository insertdrupalmediacommand */
 
 import { Plugin } from 'ckeditor5/src/core';
 import { Template } from 'ckeditor5/src/ui';
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeui.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeui.js
index 4972715ebc591b2ff52071431bc46b493aa40e3b..b6a313efa447755a6c9add342bf9113ff7ddcbb3 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeui.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/mediaimagetextalternative/mediaimagetextalternativeui.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-/* cspell:words textalternativeformview */
+/* cspell:ignore textalternativeformview */
 
 import { Plugin, icons } from 'ckeditor5/src/core';
 import {
diff --git a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/utils.js b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/utils.js
index 1095686ee8bb4f4a0373eea03d165016be750d02..afd77f4cd9828c77c226ddda92437775f3cd8686 100644
--- a/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/utils.js
+++ b/web/core/modules/ckeditor5/js/ckeditor5_plugins/drupalMedia/src/utils.js
@@ -1,5 +1,5 @@
 /* eslint-disable import/no-extraneous-dependencies */
-// cSpell:words documentselection
+// cspell:ignore documentselection
 import { isWidget } from 'ckeditor5/src/widget';
 
 /**
diff --git a/web/core/modules/content_translation/src/ContentTranslationManagerInterface.php b/web/core/modules/content_translation/src/ContentTranslationManagerInterface.php
index 1852026126cdab26d104a0ce274111f37a61dec6..1b36b077342b9c4f1af40b09b2e52820d7ddd3d9 100644
--- a/web/core/modules/content_translation/src/ContentTranslationManagerInterface.php
+++ b/web/core/modules/content_translation/src/ContentTranslationManagerInterface.php
@@ -71,7 +71,7 @@ public function setEnabled($entity_type_id, $bundle, $value);
    *   (optional) The bundle of the entity. If no bundle is provided, all the
    *   available bundles are checked.
    *
-   * @returns bool
+   * @return bool
    *   TRUE if the specified bundle is translatable. If no bundle is provided
    *   returns TRUE if at least one of the entity bundles is translatable.
    */
diff --git a/web/core/modules/content_translation/src/FieldTranslationSynchronizer.php b/web/core/modules/content_translation/src/FieldTranslationSynchronizer.php
index 336909d2a7e89d6f00cdd95a2746ff6189429501..0bd8e2c6d833209ea214e3834d53c7e41a0f5daf 100644
--- a/web/core/modules/content_translation/src/FieldTranslationSynchronizer.php
+++ b/web/core/modules/content_translation/src/FieldTranslationSynchronizer.php
@@ -327,7 +327,7 @@ protected function createMergedItem(array $source_item, array $target_item, arra
    * @param array $properties
    *   An array of column names to be synchronized.
    *
-   * @returns string
+   * @return string
    *   A hash code that can be used to identify the item.
    */
   protected function itemHash(array $items, $delta, array $properties) {
diff --git a/web/core/modules/jsonapi/jsonapi.module b/web/core/modules/jsonapi/jsonapi.module
index 804e78fd643749229202121bca760e8fba21fc3c..fa21b18d960e45e3e6e25d35bda833af7644c6f9 100644
--- a/web/core/modules/jsonapi/jsonapi.module
+++ b/web/core/modules/jsonapi/jsonapi.module
@@ -183,6 +183,7 @@ function jsonapi_jsonapi_block_content_filter_access(EntityTypeInterface $entity
   // \Drupal\jsonapi\Access\TemporaryQueryGuard adds the condition for
   // (isReusable()), so this does not have to.
   return ([
+    JSONAPI_FILTER_AMONG_ALL => AccessResult::allowedIfHasPermission($account, 'access block library'),
     JSONAPI_FILTER_AMONG_PUBLISHED => AccessResult::allowed(),
   ]);
 }
diff --git a/web/core/modules/jsonapi/src/Normalizer/Value/TemporaryArrayObjectThrowingExceptions.php b/web/core/modules/jsonapi/src/Normalizer/Value/TemporaryArrayObjectThrowingExceptions.php
index 63b7ada5d3edc176dc195d1311ba2ec46adc8259..397dd2c624e7fd073f545fc295d58e6f5480ceb5 100644
--- a/web/core/modules/jsonapi/src/Normalizer/Value/TemporaryArrayObjectThrowingExceptions.php
+++ b/web/core/modules/jsonapi/src/Normalizer/Value/TemporaryArrayObjectThrowingExceptions.php
@@ -30,9 +30,6 @@ public function append($value): void {
    * @param int $flags
    *   The flags to sort the ArrayObject by.
    *
-   * @return bool
-   *   This method always returns TRUE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -45,9 +42,6 @@ public function asort($flags = SORT_REGULAR): bool {
   /**
    * Count the ArrayObject.
    *
-   * @return int
-   *   The number of public properties in the \ArrayObject.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -62,9 +56,6 @@ public function count(): int {
    * @param array|object $array
    *   The array to replace for the current array.
    *
-   * @return array
-   *   The new array or object to exchange with the current array.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -76,9 +67,6 @@ public function exchangeArray($array): array {
   /**
    * Exports the \ArrayObject to an array.
    *
-   * @return array
-   *   Returns a copy of the array.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -90,9 +78,6 @@ public function getArrayCopy(): array {
   /**
    * Gets the behavior flags of the \ArrayObject.
    *
-   * @return int
-   *   Returns the behavior flags of the \ArrayObject.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -104,9 +89,6 @@ public function getFlags(): int {
   /**
    * Create a new iterator from an ArrayObject instance.
    *
-   * @return \Iterator
-   *   An iterator from the ArrayObject.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -118,9 +100,6 @@ public function getIterator(): \Iterator {
   /**
    * Gets the class name of the array iterator that is used by \ArrayObject::getIterator().
    *
-   * @return string
-   *   Returns the iterator class name that is used to iterate over this object.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -135,9 +114,6 @@ public function getIteratorClass(): string {
    * @param int $flags
    *   The flags to sort the ArrayObject by.
    *
-   * @return bool
-   *   This method always returns TRUE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -150,9 +126,6 @@ public function ksort($flags = SORT_REGULAR): bool {
   /**
    * Sort an array using a case insensitive "natural order" algorithm.
    *
-   * @return bool
-   *   This method always returns TRUE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -165,9 +138,6 @@ public function natcasesort(): bool {
   /**
    * Sort entries using a "natural order" algorithm.
    *
-   * @return bool
-   *   This method always returns TRUE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -183,9 +153,6 @@ public function natsort(): bool {
    * @param mixed $key
    *   The index being checked.
    *
-   * @return bool
-   *   Return TRUE if the requested index exists, otherwise FALSE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -279,9 +246,6 @@ public function setIteratorClass($iteratorClass): void {
    *   greater than zero if the first argument is considered to be respectively
    *   less than, equal to, or greater than the second.
    *
-   * @return bool
-   *   This method always returns TRUE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
@@ -299,9 +263,6 @@ public function uasort($callback): bool {
    *   greater than zero if the first argument is considered to be respectively
    *   less than, equal to, or greater than the second.
    *
-   * @return bool
-   *   This method always returns TRUE.
-   *
    * @throws \Exception
    *   This class does not support this action but it must implement it, because
    *   it is extending \ArrayObject.
diff --git a/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php b/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php
index a0d689169c12e3d880429c97d4370209b8bffede..2e5308890e10aec4a773f08f19b764ea7bd12042 100644
--- a/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php
+++ b/web/core/modules/jsonapi/tests/src/Functional/BlockContentTest.php
@@ -68,6 +68,11 @@ class BlockContentTest extends ResourceTestBase {
   protected function setUpAuthorization($method) {
     switch ($method) {
       case 'GET':
+        $this->grantPermissionsToTestedRole([
+          'access block library',
+        ]);
+        break;
+
       case 'PATCH':
         $this->grantPermissionsToTestedRole([
           'access block library',
@@ -86,6 +91,14 @@ protected function setUpAuthorization($method) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpRevisionAuthorization($method) {
+    parent::setUpRevisionAuthorization($method);
+    $this->grantPermissionsToTestedRole(['view any basic block content history']);
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/core/modules/jsonapi/tests/src/Kernel/ResourceType/ResourceTypeRepositoryTest.php b/web/core/modules/jsonapi/tests/src/Kernel/ResourceType/ResourceTypeRepositoryTest.php
index e7d5216e5c5eb7823a589d1d4ef1a4aedbc19b1d..88c60f7203cf11813a423e1b79b529f6b78d6cf5 100644
--- a/web/core/modules/jsonapi/tests/src/Kernel/ResourceType/ResourceTypeRepositoryTest.php
+++ b/web/core/modules/jsonapi/tests/src/Kernel/ResourceType/ResourceTypeRepositoryTest.php
@@ -90,7 +90,7 @@ public function testGet($entity_type_id, $bundle, $entity_class) {
   /**
    * Data provider for testGet.
    *
-   * @returns array
+   * @return array
    *   The data for the test method.
    */
   public function getProvider() {
@@ -137,7 +137,7 @@ public function testMappingNameConflictCheck($field_name_list) {
    * mapping: the special-cased names "type" or "id", and the name
    * "{$entity_type_id}_type" or "{$entity_type_id}_id", respectively.
    *
-   * @returns array
+   * @return array
    *   The data for the test method.
    */
   public function getFieldsProvider() {
diff --git a/web/core/modules/locale/locale.compare.inc b/web/core/modules/locale/locale.compare.inc
index b07c5360c70bcd0d624d0817c2ae3f4c759c3de2..5a5a9c165ad5f657cc988a723cad784626f678d6 100644
--- a/web/core/modules/locale/locale.compare.inc
+++ b/web/core/modules/locale/locale.compare.inc
@@ -177,9 +177,6 @@ function locale_translation_default_translation_server() {
  * @param array $langcodes
  *   Array of language codes. Defaults to all translatable languages.
  *
- * @return array
- *   Available sources indexed by project and language.
- *
  * @todo Return batch or NULL.
  */
 function locale_translation_check_projects($projects = [], $langcodes = []) {
diff --git a/web/core/modules/locale/src/PluralFormula.php b/web/core/modules/locale/src/PluralFormula.php
index fc7fd88519faf1bc91a9870e24c5ded4afae5ef4..398fc0f2340cc2efa6c273f435938655f2dba657 100644
--- a/web/core/modules/locale/src/PluralFormula.php
+++ b/web/core/modules/locale/src/PluralFormula.php
@@ -93,8 +93,6 @@ public function getFormula($langcode) {
 
   /**
    * Loads the formulae and stores them on the PluralFormula object if not set.
-   *
-   * @return array
    */
   protected function loadFormulae() {
     if (!isset($this->formulae)) {
diff --git a/web/core/modules/migrate/src/Plugin/MigrationInterface.php b/web/core/modules/migrate/src/Plugin/MigrationInterface.php
index 7936485997b76cdc555d9dbe9e9343c27980541c..132582852d7c153af4a3df34fb2ffef001fee640 100644
--- a/web/core/modules/migrate/src/Plugin/MigrationInterface.php
+++ b/web/core/modules/migrate/src/Plugin/MigrationInterface.php
@@ -106,7 +106,7 @@ public function label();
   /**
    * Get a list of required plugin IDs.
    *
-   * @returns string[]
+   * @return string[]
    */
   public function getRequirements(): array;
 
diff --git a/web/core/modules/page_cache/src/StackMiddleware/PageCache.php b/web/core/modules/page_cache/src/StackMiddleware/PageCache.php
index 05a70187e1ad03d82187afdd8a982b25fa7ff48c..07456a40976dadc56d1987efa2b8e72d5c83a9e5 100644
--- a/web/core/modules/page_cache/src/StackMiddleware/PageCache.php
+++ b/web/core/modules/page_cache/src/StackMiddleware/PageCache.php
@@ -99,7 +99,7 @@ public function handle(Request $request, $type = self::MAIN_REQUEST, $catch = TR
    * @param bool $catch
    *   Whether to catch exceptions or not
    *
-   * @returns \Symfony\Component\HttpFoundation\Response $response
+   * @return \Symfony\Component\HttpFoundation\Response
    *   A response object.
    */
   protected function pass(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE) {
@@ -117,7 +117,7 @@ protected function pass(Request $request, $type = self::MAIN_REQUEST, $catch = T
    * @param bool $catch
    *   Whether to catch exceptions or not
    *
-   * @returns \Symfony\Component\HttpFoundation\Response $response
+   * @return \Symfony\Component\HttpFoundation\Response
    *   A response object.
    */
   protected function lookup(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE) {
@@ -183,7 +183,7 @@ protected function lookup(Request $request, $type = self::MAIN_REQUEST, $catch =
    * @param bool $catch
    *   Whether to catch exceptions or not
    *
-   * @returns \Symfony\Component\HttpFoundation\Response $response
+   * @return \Symfony\Component\HttpFoundation\Response
    *   A response object.
    */
   protected function fetch(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE) {
@@ -207,7 +207,8 @@ protected function fetch(Request $request, $type = self::MAIN_REQUEST, $catch =
    * @param \Symfony\Component\HttpFoundation\Response $response
    *   A response object that should be stored in the page cache.
    *
-   * @returns bool
+   * @return bool
+   *   TRUE if the response has been stored successfully, FALSE otherwise.
    */
   protected function storeResponse(Request $request, Response $response) {
     // Drupal's primary cache invalidation architecture is cache tags: any
diff --git a/web/core/modules/phpass/tests/src/Tests/LegacyPasswordHashingTest.php b/web/core/modules/phpass/tests/src/Unit/LegacyPasswordHashingTest.php
similarity index 93%
rename from web/core/modules/phpass/tests/src/Tests/LegacyPasswordHashingTest.php
rename to web/core/modules/phpass/tests/src/Unit/LegacyPasswordHashingTest.php
index b8064d84a3ad5d965163c932d84e199ccddb8240..586d20818ce9e2e67f65447667675f4e988b8ea5 100644
--- a/web/core/modules/phpass/tests/src/Tests/LegacyPasswordHashingTest.php
+++ b/web/core/modules/phpass/tests/src/Unit/LegacyPasswordHashingTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\Tests\phpass\Password;
+namespace Drupal\Tests\phpass\Unit;
 
 use Drupal\phpass\Password\PhpassHashedPassword;
 use Drupal\Tests\UnitTestCase;
@@ -60,14 +60,6 @@ protected function setUp(): void {
     $this->md5HashedPassword = 'U' . $this->passwordHasher->hash(md5($this->password));
   }
 
-  /**
-   * Tests invalid constructor arguments.
-   */
-  public function testInvalidArguments() {
-    $this->expectException(\InvalidArgumentException::class);
-    new PhpassHashedPassword('not a number');
-  }
-
   /**
    * Tests a password needs update.
    *
@@ -122,4 +114,14 @@ public function testPasswordRehashing() {
     $this->assertTrue($this->passwordHasher->check($this->password, $rehashed_password), 'Password check succeeds with re-hashed password with original hasher.');
   }
 
+  /**
+   * Tests password validation when the hash is NULL.
+   *
+   * @covers ::check
+   */
+  public function testEmptyHash(): void {
+    $this->assertFalse($this->passwordHasher->check($this->password, NULL));
+    $this->assertFalse($this->passwordHasher->check($this->password, ''));
+  }
+
 }
diff --git a/web/core/modules/phpass/tests/src/Tests/PasswordVerifyTest.php b/web/core/modules/phpass/tests/src/Unit/PasswordVerifyTest.php
similarity index 99%
rename from web/core/modules/phpass/tests/src/Tests/PasswordVerifyTest.php
rename to web/core/modules/phpass/tests/src/Unit/PasswordVerifyTest.php
index 828eae0e9c10081725163c7dab23b0d9f4546cad..f080bd2396deff3b6516a04f6bdb86d703218ddc 100644
--- a/web/core/modules/phpass/tests/src/Tests/PasswordVerifyTest.php
+++ b/web/core/modules/phpass/tests/src/Unit/PasswordVerifyTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\Tests\phpass\Password;
+namespace Drupal\Tests\phpass\Unit;
 
 use Drupal\phpass\Password\PhpassHashedPassword;
 use Drupal\Core\Password\PasswordInterface;
diff --git a/web/core/modules/rest/src/Routing/ResourceRoutes.php b/web/core/modules/rest/src/Routing/ResourceRoutes.php
index a3cfe746057d253aa7a2ac0e5b6c0faa08482610..21fc270caa49ba77d41b9b91fc23c7ba51593ad5 100644
--- a/web/core/modules/rest/src/Routing/ResourceRoutes.php
+++ b/web/core/modules/rest/src/Routing/ResourceRoutes.php
@@ -58,8 +58,6 @@ public function __construct(ResourcePluginManager $manager, EntityTypeManagerInt
    *
    * @param \Drupal\Core\Routing\RouteBuildEvent $event
    *   The route build event.
-   *
-   * @return array
    */
   public function onDynamicRouteEvent(RouteBuildEvent $event) {
     // Iterate over all enabled REST resource config entities.
diff --git a/web/core/modules/rest/tests/src/Functional/ResourceTestBase.php b/web/core/modules/rest/tests/src/Functional/ResourceTestBase.php
index 5d32aa20bf43a40131eda444e74cf6a9ec66c0df..3b5fe5ec7d7fce0e057db133642721a0625da404 100644
--- a/web/core/modules/rest/tests/src/Functional/ResourceTestBase.php
+++ b/web/core/modules/rest/tests/src/Functional/ResourceTestBase.php
@@ -487,9 +487,6 @@ protected function decorateWithXdebugCookie(array $request_options) {
    *
    * @param array $array
    *   An array to sort.
-   *
-   * @return array
-   *   The sorted array.
    */
   protected static function recursiveKSort(array &$array) {
     // First, sort the main array.
@@ -501,8 +498,6 @@ protected static function recursiveKSort(array &$array) {
         static::recursiveKSort($value);
       }
     }
-
-    return $array;
   }
 
 }
diff --git a/web/core/modules/sdc/src/Element/ComponentElement.php b/web/core/modules/sdc/src/Element/ComponentElement.php
index de540ae24d6351249ca573ffbebbf77aa81cb461..b7e259d762aee00611dab6ee9afcf9520a3a5d87 100644
--- a/web/core/modules/sdc/src/Element/ComponentElement.php
+++ b/web/core/modules/sdc/src/Element/ComponentElement.php
@@ -105,9 +105,14 @@ private function generateComponentTemplate(
     $template .= sprintf('{%% embed \'%s\' %%}', $id);
     $template .= PHP_EOL;
     foreach ($slots as $slot_name => $slot_value) {
+      if (\is_scalar($slot_value)) {
+        $slot_value = [
+          "#plain_text" => (string) $slot_value,
+        ];
+      }
       if (!Utilities::isRenderArray($slot_value)) {
         $message = sprintf(
-          'Unable to render component "%s". A render array is expected for the slot "%s" when using the render element with the "#slots" property',
+          'Unable to render component "%s". A render array or a scalar is expected for the slot "%s" when using the render element with the "#slots" property',
           $id,
           $slot_name
         );
diff --git a/web/core/modules/sdc/src/Twig/ComponentNodeVisitor.php b/web/core/modules/sdc/src/Twig/ComponentNodeVisitor.php
index e7f2a928a5c56b1ca9d21bf545425bda99a0a1e8..5fdffa5c1e4069da52905db23ba255ad8707baeb 100644
--- a/web/core/modules/sdc/src/Twig/ComponentNodeVisitor.php
+++ b/web/core/modules/sdc/src/Twig/ComponentNodeVisitor.php
@@ -71,15 +71,25 @@ public function leaveNode(Node $node, Environment $env): ?Node {
       new Node([new ConstantExpression($component_id, $line)]),
       $line
     ), $line);
-    foreach ($print_nodes as $index => $print_node) {
-      $node->getNode('display_start')->setNode((string) $index, $print_node);
-    }
+
+    // Append the print nodes to the display_start node.
+    $node->setNode(
+      'display_start',
+      new Node([
+        $node->getNode('display_start'),
+        ...$print_nodes,
+      ]),
+    );
+
     if ($env->isDebug()) {
-      $node->getNode('display_end')
-        ->setNode(
-          '0',
-          new PrintNode(new ConstantExpression(sprintf('<!-- %s Component end: %s -->', $emoji, $component_id), $line), $line)
-        );
+      // Append the closing comment to the display_end node.
+      $node->setNode(
+        'display_end',
+        new Node([
+          new PrintNode(new ConstantExpression(sprintf('<!-- %s Component end: %s -->', $emoji, $component_id), $line), $line),
+          $node->getNode('display_end'),
+        ])
+      );
     }
     // Slots can be validated at compile time, we don't need to add nodes to
     // execute functions during display with the actual data.
diff --git a/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ba20067f05346b92727c656cc4e4816d50f7bda7
--- /dev/null
+++ b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.info.yml
@@ -0,0 +1,5 @@
+name: 'Add another node visitor'
+type: module
+dependencies:
+  - sdc:sdc
+package: Testing
diff --git a/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml
new file mode 100644
index 0000000000000000000000000000000000000000..38b78f5aced4cd216e5d36b1cdfafbf96c159c81
--- /dev/null
+++ b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/sdc_other_node_visitor.services.yml
@@ -0,0 +1,5 @@
+services:
+  sdc_other_node_visitor.twig.extension.profiler:
+    class: Drupal\sdc_other_node_visitor\Twig\Extension\TestProfilerExtension
+    tags:
+      - { name: twig.extension, priority: 100 }
diff --git a/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php
new file mode 100644
index 0000000000000000000000000000000000000000..78b19f319f94a747af22225aa0642476142b826e
--- /dev/null
+++ b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Extension/TestProfilerExtension.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\sdc_other_node_visitor\Twig\Extension;
+
+use Drupal\sdc_other_node_visitor\Twig\NodeVisitor\TestNodeVisitor;
+use Twig\Extension\AbstractExtension;
+
+/**
+ * Twig extension to add a test node visitor.
+ */
+class TestProfilerExtension extends AbstractExtension {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getNodeVisitors(): array {
+    return [new TestNodeVisitor(static::class)];
+  }
+
+  /**
+   * Dummy function called when a Twig template is entered.
+   */
+  public function enter() {
+    // NOOP.
+  }
+
+  /**
+   * Dummy function called when a Twig template is left.
+   */
+  public function leave() {
+    // NOOP.
+  }
+
+}
diff --git a/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e3305b83315e7bf724d7665c7ea9632d1b6c1cc
--- /dev/null
+++ b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/NodeVisitor/TestNodeVisitor.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\sdc_other_node_visitor\Twig\NodeVisitor;
+
+use Drupal\sdc_other_node_visitor\Twig\Profiler\EnterProfileNode;
+use Drupal\sdc_other_node_visitor\Twig\Profiler\LeaveProfileNode;
+use Twig\Environment;
+use Twig\Node\ModuleNode;
+use Twig\Node\Node;
+use Twig\NodeVisitor\NodeVisitorInterface;
+
+/**
+ * A node visitor that adds nodes to the Twig template.
+ *
+ * Most of this code is copied from
+ * Twig\Profiler\NodeVisitor\ProfilerNodeVisitor.
+ */
+final class TestNodeVisitor implements NodeVisitorInterface {
+
+  private string $extensionName;
+
+  private string $varName;
+
+  /**
+   * TestNodeVisitor constructor.
+   *
+   * @param string $extensionName
+   *   The name of the extension.
+   */
+  public function __construct(string $extensionName) {
+    $this->extensionName = $extensionName;
+    $this->varName = sprintf('__internal_%s', hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $extensionName));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function enterNode(Node $node, Environment $env): Node {
+    return $node;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function leaveNode(Node $node, Environment $env): ?Node {
+    if ($node instanceof ModuleNode) {
+      $node->setNode('display_start', new Node([
+        new EnterProfileNode($this->extensionName, $this->varName),
+        $node->getNode('display_start'),
+      ]));
+      $node->setNode('display_end', new Node([
+        new LeaveProfileNode($this->varName),
+        $node->getNode('display_end'),
+      ]));
+    }
+
+    return $node;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPriority(): int {
+    return 0;
+  }
+
+}
diff --git a/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e55b192682f59264288a56546a848232ae0d40e
--- /dev/null
+++ b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/EnterProfileNode.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\sdc_other_node_visitor\Twig\Profiler;
+
+use Twig\Compiler;
+use Twig\Node\Node;
+
+/**
+ * Represents a profile enter node.
+ */
+class EnterProfileNode extends Node {
+
+  public function __construct(string $extensionName, string $varName) {
+    parent::__construct([], [
+      'extension_name' => $extensionName,
+      'var_name' => $varName,
+    ]);
+  }
+
+  public function compile(Compiler $compiler): void {
+    $compiler
+      ->write(sprintf('$%s = $this->extensions[', $this->getAttribute('var_name')))
+      /* cspell:disable-next-line */
+      ->repr($this->getAttribute('extension_name'))
+      ->raw("];\n")
+      ->write(sprintf('$%s->enter();', $this->getAttribute('var_name')))
+      ->raw("\n\n");
+  }
+
+}
diff --git a/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php
new file mode 100644
index 0000000000000000000000000000000000000000..52e86a4c9c939abef2d8f2fe79341658185c3fb4
--- /dev/null
+++ b/web/core/modules/sdc/tests/modules/sdc_other_node_visitor/src/Twig/Profiler/LeaveProfileNode.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\sdc_other_node_visitor\Twig\Profiler;
+
+use Twig\Compiler;
+use Twig\Node\Node;
+
+/**
+ * Represents a profile leave node.
+ */
+class LeaveProfileNode extends Node {
+
+  public function __construct(string $varName) {
+    parent::__construct([], ['var_name' => $varName]);
+  }
+
+  public function compile(Compiler $compiler): void {
+    $compiler
+      ->write("\n")
+      ->write(sprintf("\$%s->leave();\n\n", $this->getAttribute('var_name')));
+  }
+
+}
diff --git a/web/core/modules/sdc/tests/src/Kernel/ComponentNodeVisitorTest.php b/web/core/modules/sdc/tests/src/Kernel/ComponentNodeVisitorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef541d0aa532c7dbd0ec910e163a3d17a8331be6
--- /dev/null
+++ b/web/core/modules/sdc/tests/src/Kernel/ComponentNodeVisitorTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\Tests\sdc\Kernel;
+
+/**
+ * Tests the node visitor.
+ *
+ * @coversDefaultClass \Drupal\sdc\Twig\ComponentNodeVisitor
+ * @group sdc
+ *
+ * @internal
+ */
+final class ComponentNodeVisitorTest extends ComponentKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['sdc', 'sdc_other_node_visitor'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $themes = ['sdc_theme_test'];
+
+  /**
+   * Test that other visitors can modify Twig nodes.
+   */
+  public function testOtherVisitorsCanModifyTwigNodes(): void {
+    $build = [
+      '#type' => 'inline_template',
+      '#template' => "{% embed('sdc_theme_test_base:my-card-no-schema') %}{% block card_body %}Foo bar{% endblock %}{% endembed %}",
+    ];
+    $this->renderComponentRenderArray($build);
+
+    // If this is reached, the test passed.
+    $this->assertTrue(TRUE);
+  }
+
+}
diff --git a/web/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php b/web/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
index 174a2dcbbe4d83f5a498da41f486c44669c08115..d4ea6194ebe8226afda0f6833e1edef697784caf 100644
--- a/web/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
+++ b/web/core/modules/sdc/tests/src/Kernel/ComponentRenderTest.php
@@ -42,6 +42,7 @@ public function testRender(): void {
     $this->checkLibraryOverrides();
     $this->checkAttributeMerging();
     $this->checkRenderElementAlters();
+    $this->checkSlots();
     $this->checkInvalidSlot();
   }
 
@@ -284,7 +285,36 @@ public function checkRenderElementAlters(): void {
   }
 
   /**
-   * Ensure that the slots receive a render array when using the render element.
+   * Ensure that the slots allow a render array or a scalar when using the render element.
+   */
+  public function checkSlots(): void {
+    $slots = [
+      'This is the contents of the banner body.',
+      [
+        '#plain_text' => 'This is the contents of the banner body.',
+      ],
+    ];
+    foreach ($slots as $slot) {
+      $build = [
+        '#type' => 'component',
+        '#component' => 'sdc_test:my-banner',
+        '#props' => [
+          'heading' => $this->t('I am a banner'),
+          'ctaText' => $this->t('Click me'),
+          'ctaHref' => 'https://www.example.org',
+          'ctaTarget' => '',
+        ],
+        '#slots' => [
+          'banner_body' => $slot,
+        ],
+      ];
+      $crawler = $this->renderComponentRenderArray($build);
+      $this->assertNotEmpty($crawler->filter('#sdc-wrapper [data-component-id="sdc_test:my-banner"] .component--my-banner--body:contains("This is the contents of the banner body.")'));
+    }
+  }
+
+  /**
+   * Ensure that the slots throw an error for invalid slots.
    */
   public function checkInvalidSlot(): void {
     $build = [
@@ -297,11 +327,11 @@ public function checkInvalidSlot(): void {
         'ctaTarget' => '',
       ],
       '#slots' => [
-        'banner_body' => 'I am an invalid render array.',
+        'banner_body' => new \stdClass(),
       ],
     ];
     $this->expectException(InvalidComponentDataException::class);
-    $this->expectExceptionMessage('Unable to render component "sdc_test:my-banner". A render array is expected for the slot "banner_body" when using the render element with the "#slots" property');
+    $this->expectExceptionMessage('Unable to render component "sdc_test:my-banner". A render array or a scalar is expected for the slot "banner_body" when using the render element with the "#slots" property');
     $this->renderComponentRenderArray($build);
   }
 
diff --git a/web/core/modules/serialization/src/Normalizer/DateTimeNormalizer.php b/web/core/modules/serialization/src/Normalizer/DateTimeNormalizer.php
index c1fdf1fb1834ed9f4ddbbbb8ba8c003e90baee4c..83ffe156fe6e6ebaa5ae5c09016dcc4c19697286 100644
--- a/web/core/modules/serialization/src/Normalizer/DateTimeNormalizer.php
+++ b/web/core/modules/serialization/src/Normalizer/DateTimeNormalizer.php
@@ -69,7 +69,7 @@ public function normalize($datetime, $format = NULL, array $context = []): array
    * @see ::normalize
    * @see \Drupal\Core\Datetime\DrupalDateTime::prepareTimezone()
    *
-   * @returns \DateTimeZone
+   * @return \DateTimeZone
    *   The timezone to use.
    */
   protected function getNormalizationTimezone() {
diff --git a/web/core/modules/system/src/Controller/AssetControllerBase.php b/web/core/modules/system/src/Controller/AssetControllerBase.php
index 7a161a5d7e47aa08fea81bec61abed680425757c..3c662294a2e49cc18bbbd579a00de0d49696e931 100644
--- a/web/core/modules/system/src/Controller/AssetControllerBase.php
+++ b/web/core/modules/system/src/Controller/AssetControllerBase.php
@@ -195,11 +195,7 @@ public function deliver(Request $request, string $file_name) {
     // from filling the disk, while still serving aggregates that may be
     // referenced in cached HTML.
     if (hash_equals($generated_hash, $received_hash)) {
-      $uri = $this->dumper->dumpToUri($data, $this->assetType, $uri);
-      $state_key = 'drupal_' . $this->assetType . '_cache_files';
-      $files = $this->state()->get($state_key, []);
-      $files[] = $uri;
-      $this->state()->set($state_key, $files);
+      $this->dumper->dumpToUri($data, $this->assetType, $uri);
     }
     return new Response($data, 200, [
       'Cache-control' => static::CACHE_CONTROL,
diff --git a/web/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml b/web/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml
index 12e65477897736f2e4e97b6ea89c8b13a134e5c4..b846939a6e076f80c7e38f90fa21ef034b5d917b 100644
--- a/web/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml
+++ b/web/core/modules/system/tests/modules/ajax_test/ajax_test.routing.yml
@@ -129,3 +129,19 @@ ajax_test.throw_exception:
     _controller: '\Drupal\ajax_test\Controller\AjaxTestController::throwException'
   requirements:
     _access: 'TRUE'
+
+ajax_test.http_methods:
+  path: '/ajax-test/http-methods'
+  defaults:
+    _controller: Drupal\ajax_test\Controller\AjaxTestController::httpMethods
+  requirements:
+    _access: 'TRUE'
+  options:
+    no_cache: TRUE
+
+ajax_test.http_methods.dialog:
+  path: '/ajax-test/http-methods-dialog'
+  defaults:
+    _controller: Drupal\ajax_test\Controller\AjaxTestController::httpMethodsDialog
+  requirements:
+    _access: 'TRUE'
diff --git a/web/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php b/web/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
index ad883b145e7f9d4c387a396e001a14081098c6b2..b91b37d038e7d9b005cb3e757f133c58ce6eda75 100644
--- a/web/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
+++ b/web/core/modules/system/tests/modules/ajax_test/src/Controller/AjaxTestController.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\ajax_test\Controller;
 
+use Drupal\Component\Serialization\Json;
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\AlertCommand;
 use Drupal\Core\Ajax\CloseDialogCommand;
@@ -419,4 +420,41 @@ public function exceptionLink() {
     ];
   }
 
+  /**
+   * Provides an Ajax link used with different HTTP methods.
+   *
+   * @return array
+   *   The AJAX link.
+   */
+  public function httpMethods(): array {
+    return [
+      '#type' => 'link',
+      '#title' => 'Link',
+      '#url' => Url::fromRoute('ajax_test.http_methods.dialog'),
+      '#attributes' => [
+        'class' => ['use-ajax'],
+        'data-dialog-type' => 'modal',
+        'data-dialog-options' => Json::encode(['width' => 800]),
+        // Use this state var to change the HTTP method in tests.
+        // @see \Drupal\FunctionalJavascriptTests\Ajax\DialogTest::testHttpMethod()
+        'data-ajax-http-method' => \Drupal::state()->get('ajax_test.http_method', 'POST'),
+      ],
+      '#attached' => [
+        'library' => [
+          'core/drupal.dialog.ajax',
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * Provides a modal dialog to test links with different HTTP methods.
+   *
+   * @return array
+   *   The render array.
+   */
+  public function httpMethodsDialog(): array {
+    return ['#markup' => 'Modal dialog contents'];
+  }
+
 }
diff --git a/web/core/modules/system/tests/modules/decoupled_menus_test/decoupled_menus_test.info.yml b/web/core/modules/system/tests/modules/decoupled_menus_test/decoupled_menus_test.info.yml
index 40b4a30052762a0d8821a817784e617a9fe2a303..3d3cf4403e54551ea7df609d452a9ac89006eec0 100644
--- a/web/core/modules/system/tests/modules/decoupled_menus_test/decoupled_menus_test.info.yml
+++ b/web/core/modules/system/tests/modules/decoupled_menus_test/decoupled_menus_test.info.yml
@@ -4,5 +4,5 @@ description: 'Support module for decoupled_menus endpoint.'
 package: Testing
 version: VERSION
 dependencies:
-  drupal:rest
-  drupal:user
+  - drupal:rest
+  - drupal:user
diff --git a/web/core/modules/system/tests/modules/router_test_directory/src/TestContent.php b/web/core/modules/system/tests/modules/router_test_directory/src/TestContent.php
index 7f4166078b0eaaf0d2b637cb55f5e6ac66938faf..38ec6982ed12e60cf97a0bd767a1be6e4485c710 100644
--- a/web/core/modules/system/tests/modules/router_test_directory/src/TestContent.php
+++ b/web/core/modules/system/tests/modules/router_test_directory/src/TestContent.php
@@ -44,7 +44,7 @@ public function test1() {
   /**
    * Provides example content for route specific authentication.
    *
-   * @returns string
+   * @return string
    *   The user name of the current logged in user.
    */
   public function test11() {
diff --git a/web/core/modules/views/src/Plugin/views/field/EntityLink.php b/web/core/modules/views/src/Plugin/views/field/EntityLink.php
index 3ebe91a109cbda23758690d4ef290a59c79b1209..b96d1d445cc5bc3730cba74d71a06ad5a567193f 100644
--- a/web/core/modules/views/src/Plugin/views/field/EntityLink.php
+++ b/web/core/modules/views/src/Plugin/views/field/EntityLink.php
@@ -50,7 +50,7 @@ protected function getUrlInfo(ResultRow $row) {
   /**
    * Returns the entity link template name identifying the link route.
    *
-   * @returns string
+   * @return string
    *   The link template name.
    */
   protected function getEntityLinkTemplate() {
diff --git a/web/core/package.json b/web/core/package.json
index 2450d4d499257fd3cf87f26489eaffb89a9f6a4b..7196bd4c00205f9b2f5296a41d14d37afab7264d 100644
--- a/web/core/package.json
+++ b/web/core/package.json
@@ -78,7 +78,7 @@
     "mkdirp": "^3.0.1",
     "nightwatch": "^2.3.9",
     "normalize.css": "8.0.x",
-    "postcss": "^8.4.24",
+    "postcss": "^8.4.31",
     "postcss-header": "^3.0.2",
     "postcss-import": "^15.0.0",
     "postcss-preset-env": "^8.4.2",
diff --git a/web/core/phpstan-baseline.neon b/web/core/phpstan-baseline.neon
index 113f73abdc042d40f84370498d2c54f371342439..8b902e8e670c0c10f60037a270353f63098c8226 100644
--- a/web/core/phpstan-baseline.neon
+++ b/web/core/phpstan-baseline.neon
@@ -425,16 +425,6 @@ parameters:
 			count: 2
 			path: lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
 
-		-
-			message: "#^Method Drupal\\\\Core\\\\Entity\\\\Sql\\\\SqlContentEntityStorageSchema\\:\\:processDataTable\\(\\) should return array but return statement is missing\\.$#"
-			count: 1
-			path: lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
-
-		-
-			message: "#^Method Drupal\\\\Core\\\\Entity\\\\Sql\\\\SqlContentEntityStorageSchema\\:\\:processRevisionDataTable\\(\\) should return array but return statement is missing\\.$#"
-			count: 1
-			path: lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
-
 		-
 			message: "#^Variable \\$initial_storage_value in empty\\(\\) always exists and is not falsy\\.$#"
 			count: 1
@@ -1370,11 +1360,6 @@ parameters:
 			count: 1
 			path: modules/locale/locale.bulk.inc
 
-		-
-			message: "#^Function locale_translation_check_projects\\(\\) should return array but return statement is missing\\.$#"
-			count: 1
-			path: modules/locale/locale.compare.inc
-
 		-
 			message: "#^Variable \\$item in empty\\(\\) always exists and is not falsy\\.$#"
 			count: 1
@@ -1400,11 +1385,6 @@ parameters:
 			count: 1
 			path: modules/locale/src/LocaleProjectStorage.php
 
-		-
-			message: "#^Method Drupal\\\\locale\\\\PluralFormula\\:\\:loadFormulae\\(\\) should return array but return statement is missing\\.$#"
-			count: 1
-			path: modules/locale/src/PluralFormula.php
-
 		-
 			message: "#^Method Drupal\\\\locale\\\\PoDatabaseReader\\:\\:readItem\\(\\) should return Drupal\\\\Component\\\\Gettext\\\\PoItem but return statement is missing\\.$#"
 			count: 1
@@ -1820,11 +1800,6 @@ parameters:
 			count: 1
 			path: modules/responsive_image/src/ResponsiveImageStyleForm.php
 
-		-
-			message: "#^Method Drupal\\\\rest\\\\Routing\\\\ResourceRoutes\\:\\:onDynamicRouteEvent\\(\\) should return array but return statement is missing\\.$#"
-			count: 1
-			path: modules/rest/src/Routing/ResourceRoutes.php
-
 		-
 			message: "#^Variable \\$created_entity might not be defined\\.$#"
 			count: 4
diff --git a/web/core/profiles/demo_umami/themes/umami/css/classy/components/form.css b/web/core/profiles/demo_umami/themes/umami/css/components/forms/form.css
similarity index 96%
rename from web/core/profiles/demo_umami/themes/umami/css/classy/components/form.css
rename to web/core/profiles/demo_umami/themes/umami/css/components/forms/form.css
index 302e279771ff909863db3a05923ef40e5c6fd874..a07557d3449c9e776ece7c8ac7ab225ae3c044d7 100644
--- a/web/core/profiles/demo_umami/themes/umami/css/classy/components/form.css
+++ b/web/core/profiles/demo_umami/themes/umami/css/components/forms/form.css
@@ -78,7 +78,7 @@ label.option {
   content: "";
   vertical-align: super;
   /* Use a background image to prevent screen readers from announcing the text. */
-  background-image: url(../../../../../../../misc/icons/ee0000/required.svg);
+  background-image: url(../../../images/svg/e40000/required.svg);
   background-repeat: no-repeat;
   background-size: 6px 6px;
 }
diff --git a/web/core/profiles/demo_umami/themes/umami/images/svg/e40000/required.svg b/web/core/profiles/demo_umami/themes/umami/images/svg/e40000/required.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d837dbccc0ba7397b3b3f52e2172830d0938274e
--- /dev/null
+++ b/web/core/profiles/demo_umami/themes/umami/images/svg/e40000/required.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path fill="#E40000"  d="M0,7.562l1.114-3.438c2.565,0.906,4.43,1.688,5.59,2.35C6.398,3.553,6.237,1.544,6.22,0.447h3.511 c-0.05,1.597-0.234,3.6-0.558,6.003c1.664-0.838,3.566-1.613,5.714-2.325L16,7.562c-2.05,0.678-4.06,1.131-6.028,1.356 c0.984,0.856,2.372,2.381,4.166,4.575l-2.906,2.059c-0.935-1.274-2.041-3.009-3.316-5.206c-1.194,2.275-2.244,4.013-3.147,5.206 l-2.856-2.059c1.872-2.307,3.211-3.832,4.017-4.575C3.849,8.516,1.872,8.062,0,7.562"/></svg>
diff --git a/web/core/profiles/demo_umami/themes/umami/umami.libraries.yml b/web/core/profiles/demo_umami/themes/umami/umami.libraries.yml
index 800006c1be10d5f2707d9a463daebc08daa5995a..fec00e792c1b718bf60803b0713ec6b4dbb9b8d5 100644
--- a/web/core/profiles/demo_umami/themes/umami/umami.libraries.yml
+++ b/web/core/profiles/demo_umami/themes/umami/umami.libraries.yml
@@ -13,6 +13,7 @@ global:
       css/components/blocks/search/search-results.css: {}
       css/components/blocks/articles-aside/articles-aside.css: {}
       css/components/forms/contact.css: {}
+      css/components/forms/form.css: { weight: -10 }
       css/components/forms/content-moderation.css: {}
       css/components/content/node.css: {}
       css/components/content/full/node-full.css: {}
@@ -137,7 +138,6 @@ classy.base:
       css/classy/components/details.css: { weight: -10 }
       css/classy/components/exposed-filters.css: { weight: -10 }
       css/classy/components/field.css: { weight: -10 }
-      css/classy/components/form.css: { weight: -10 }
       css/classy/components/icons.css: { weight: -10 }
       css/classy/components/inline-form.css: { weight: -10 }
       css/classy/components/item-list.css: { weight: -10 }
diff --git a/web/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php b/web/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php
index d700a13f4b0d8d5775d3bdf8c0ddf847bf274687..f9ca183233a207ad73726ea66428ec05a1ed8f17 100644
--- a/web/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php
+++ b/web/core/tests/Drupal/BuildTests/Framework/BuildTestBase.php
@@ -546,9 +546,8 @@ protected function getPortNumber() {
    * Use this method to copy the current codebase, including any patched
    * changes, into the workspace.
    *
-   * By default, the copy will exclude sites/default/settings.php,
-   * sites/default/files, and vendor/. Use the $iterator parameter to override
-   * this behavior.
+   * By default, the copy will exclude site-specific and build-related files and
+   * directories. Use the $iterator parameter to override this behavior.
    *
    * @param \Iterator|null $iterator
    *   (optional) An iterator of all the files to copy. Default behavior is to
@@ -589,6 +588,7 @@ public function getCodebaseFinder() {
       ->notPath('#^sites/default/files#')
       ->notPath('#^sites/simpletest#')
       ->notPath('#^vendor#')
+      ->notPath('#^core/node_modules#')
       ->notPath('#^sites/default/settings\..*php#')
       ->ignoreDotFiles(FALSE)
       ->ignoreVCS(FALSE);
diff --git a/web/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php b/web/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
index 5ea74a35078a06a22c3b66bffb1813a829cc232e..1a537175db5c43fb991f68a57bec3a97592cb664 100644
--- a/web/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
+++ b/web/core/tests/Drupal/FunctionalJavascriptTests/Ajax/DialogTest.php
@@ -188,4 +188,38 @@ public function testDialog() {
     $this->assertNotNull($form_title, 'The add form title is as expected.');
   }
 
+  /**
+   * Tests dialog link opener with different HTTP methods.
+   */
+  public function testHttpMethod(): void {
+    $assert = $this->assertSession();
+    $script = <<<SCRIPT
+      (function() {
+        return document.querySelector('div[aria-describedby="drupal-modal"]').offsetWidth;
+      }())
+      SCRIPT;
+
+    // Open the modal dialog with POST HTTP method.
+    $this->drupalGet('/ajax-test/http-methods');
+    $this->clickLink('Link');
+    $assert->assertWaitOnAjaxRequest();
+    $assert->pageTextContains('Modal dialog contents');
+    $width = $this->getSession()->getDriver()->evaluateScript($script);
+    // The theme is adding 4px as padding and border on each side.
+    $this->assertSame(808, $width);
+
+    // Switch to GET HTTP method.
+    // @see \Drupal\ajax_test\Controller\AjaxTestController::httpMethods()
+    \Drupal::state()->set('ajax_test.http_method', 'GET');
+
+    // Open the modal dialog with GET HTTP method.
+    $this->drupalGet('/ajax-test/http-methods');
+    $this->clickLink('Link');
+    $assert->assertWaitOnAjaxRequest();
+    $assert->pageTextContains('Modal dialog contents');
+    $width = $this->getSession()->getDriver()->evaluateScript($script);
+    // The theme is adding 4px as padding and border on each side.
+    $this->assertSame(808, $width);
+  }
+
 }
diff --git a/web/core/tests/Drupal/KernelTests/Core/Condition/ConditionPluginCollectionTest.php b/web/core/tests/Drupal/KernelTests/Core/Condition/ConditionPluginCollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0f1c9ebafe8d7df61a50080d85e5586239f436d
--- /dev/null
+++ b/web/core/tests/Drupal/KernelTests/Core/Condition/ConditionPluginCollectionTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Condition;
+
+use Drupal\Core\Condition\ConditionPluginCollection;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Condition\ConditionPluginCollection
+ *
+ * @group Condition
+ */
+class ConditionPluginCollectionTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'system',
+    'user',
+    'path_alias',
+  ];
+
+  /**
+   * @covers ::getConfiguration
+   */
+  public function testGetConfiguration(): void {
+    // Include a condition that has custom configuration and a type mismatch on
+    // 'negate' by using 0 instead of FALSE.
+    $configuration['request_path'] = [
+      'id' => 'request_path',
+      'negate' => 0,
+      'context_mapping' => [],
+      'pages' => '/user/*',
+    ];
+    // Include a condition that matches default values but with a type mismatch
+    // on 'negate' by using 0 instead of FALSE. This condition will be removed,
+    // because condition configurations that match default values with "=="
+    // comparison are not saved or exported.
+    $configuration['user_role'] = [
+      'id' => 'user_role',
+      'negate' => '0',
+      'context_mapping' => [],
+      'roles' => [],
+    ];
+    $collection = new ConditionPluginCollection(\Drupal::service('plugin.manager.condition'), $configuration);
+
+    $expected['request_path'] = [
+      'id' => 'request_path',
+      'negate' => 0,
+      'context_mapping' => [],
+      'pages' => '/user/*',
+    ];
+    // NB: The 'user_role' property should not exist in expected set.
+    $this->assertSame($expected, $collection->getConfiguration());
+  }
+
+}
diff --git a/web/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php b/web/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
index 2ab3c547fdbe36fc9fb7f1f5c881cf12e61a74c6..e7f13b762552961e0ecf07b8d79d02009f6ce504 100644
--- a/web/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
+++ b/web/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\Config\ConfigEvents;
 use Drupal\Core\Config\ConfigImporter;
 use Drupal\Core\Config\ConfigImporterException;
 use Drupal\KernelTests\KernelTestBase;
@@ -25,7 +26,7 @@ class ConfigImporterTest extends KernelTestBase {
    *
    * @var array
    */
-  protected static $modules = ['config_test', 'system', 'config_import_test'];
+  protected static $modules = ['config_test', 'system', 'config_import_test', 'config_events_test'];
 
   /**
    * {@inheritdoc}
@@ -899,6 +900,26 @@ public function testUninstallThemeIncrementsCount(): void {
     $this->assertEquals(0, $this->config($cronName)->get('logging'));
   }
 
+  /**
+   * Tests config events during config import.
+   */
+  public function testConfigEvents(): void {
+    $this->installConfig(['config_events_test']);
+    $this->config('config_events_test.test')->set('key', 'bar')->save();
+    $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.sync'));
+    $this->config('config_events_test.test')->set('key', 'foo')->save();
+    \Drupal::state()->set('config_events_test.event', []);
+
+    // Import the configuration. This results in a save event with the value
+    // changing from foo to bar.
+    $this->configImporter()->import();
+    $event = \Drupal::state()->get('config_events_test.event', []);
+    $this->assertSame(ConfigEvents::SAVE, $event['event_name']);
+    $this->assertSame(['key' => 'bar'], $event['current_config_data']);
+    $this->assertSame(['key' => 'bar'], $event['raw_config_data']);
+    $this->assertSame(['key' => 'foo'], $event['original_config_data']);
+  }
+
   /**
    * Helper method to test custom config installer steps.
    *
diff --git a/web/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php b/web/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php
index ac8246c8ef86fdb0c4bdb90db943925c15d02bb8..4e405fd908b196855f84be642e80107084a20f22 100644
--- a/web/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php
+++ b/web/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php
@@ -101,7 +101,9 @@ public function testCoreServiceAliases(): void {
       }
     }
 
-    $this->assertSame($expected, array_intersect($expected, $aliases));
+    $missing = array_diff($expected, $aliases);
+    $formatted = Yaml::encode(array_map(fn ($alias) => sprintf('@%s', $alias), $missing));
+    $this->assertSame($expected, array_intersect($expected, $aliases), sprintf('The following core services do not have map the class name to an alias. Add the following to core.services.yml in the appropriate place: %s%s%s', \PHP_EOL, \PHP_EOL, $formatted));
   }
 
 }
diff --git a/web/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeTest.php b/web/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeTest.php
index 6b47489844f6656492d57de02d05adf90eb10146..789b38caceaa7ff4561caee9bf8faab62add8dbe 100644
--- a/web/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeTest.php
+++ b/web/core/tests/Drupal/KernelTests/Core/Entity/EntityTypeTest.php
@@ -43,7 +43,7 @@ public function __construct() {
       }
 
       /**
-       * @return array
+       * Always throw an exception.
        */
       public function __serialize(): array {
         throw new \Exception();
diff --git a/web/core/tests/Drupal/KernelTests/Core/EventSubscriber/ExceptionLoggingSubscriberTest.php b/web/core/tests/Drupal/KernelTests/Core/EventSubscriber/ExceptionLoggingSubscriberTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b15ecff3f0fee6678689f2519ed90e357583bf57
--- /dev/null
+++ b/web/core/tests/Drupal/KernelTests/Core/EventSubscriber/ExceptionLoggingSubscriberTest.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\KernelTests\Core\EventSubscriber;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\KernelTests\KernelTestBase;
+use Symfony\Component\ErrorHandler\BufferingLogger;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Tests that HTTP exceptions are logged correctly.
+ *
+ * @group system
+ */
+class ExceptionLoggingSubscriberTest extends KernelTestBase {
+
+  /**
+   * The service name for a logger implementation that collects anything logged.
+   *
+   * @var string
+   */
+  protected $testLogServiceName = 'exception_logging_subscriber_test.logger';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['system', 'test_page_test'];
+
+  /**
+   * Tests \Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber::onException().
+   */
+  public function testExceptionLogging() {
+    $http_kernel = \Drupal::service('http_kernel');
+
+    $channel_map = [
+      400 => 'client error',
+      401 => 'client error',
+      403 => 'access denied',
+      404 => 'page not found',
+      405 => 'client error',
+      408 => 'client error',
+      // Do not check the 500 status code here because it would be caught by
+      // Drupal\Core\EventSubscriberExceptionTestSiteSubscriber which has lower
+      // priority.
+      501 => 'php',
+      502 => 'php',
+      503 => 'php',
+    ];
+
+    // Ensure that noting is logged.
+    $this->assertEmpty($this->container->get($this->testLogServiceName)->cleanLogs());
+
+    // Temporarily disable error log as the ExceptionLoggingSubscriber logs 5xx
+    // HTTP errors using error_log().
+    $error_log = ini_set('error_log', '/dev/null');
+    foreach ($channel_map as $code => $channel) {
+      $request = Request::create('/test-http-response-exception/' . $code);
+      $http_kernel->handle($request);
+    }
+    ini_set('error_log', $error_log);
+
+    $expected_channels = array_values($channel_map);
+
+    $logs = $this->container->get($this->testLogServiceName)->cleanLogs();
+    foreach ($expected_channels as $key => $expected_channel) {
+      $log_message = $logs[$key][2]['channel'];
+      $this->assertEquals($expected_channel, $log_message);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function register(ContainerBuilder $container) {
+    parent::register($container);
+    $container
+      ->register($this->testLogServiceName, BufferingLogger::class)
+      ->addTag('logger');
+  }
+
+}
diff --git a/web/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php b/web/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php
index 9ddfa59acc143e3eef489c4a2b3a10161af5cba7..92c1b98cc047137499100fb9b53a612983896a9d 100644
--- a/web/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php
+++ b/web/core/tests/Drupal/KernelTests/Core/Field/Entity/BaseFieldOverrideTest.php
@@ -82,6 +82,38 @@ public function testDefaultValueCallback() {
     $this->assertEquals([['target_id' => 99]], $base_field_override->getDefaultValue($entity));
   }
 
+  /**
+   * Tests that some properties are inherited from the BaseFieldDefinition.
+   *
+   * @covers ::isReadOnly
+   * @covers ::isComputed
+   * @covers ::isInternal
+   * @covers ::getUniqueIdentifier
+   */
+  public function testInheritedProperties() {
+    $base_field = BaseFieldDefinition::create('string')
+      ->setName('Test Field')
+      ->setTargetEntityTypeId('entity_test')
+      ->setReadOnly(TRUE)
+      /** Ensure that the internal property is inherited from the base field and not the parent class. @see FieldConfigBase::isInternal */
+      ->setInternal(TRUE)
+      ->setComputed(FALSE);
+
+    // Getters of the properties to check.
+    $methods = [
+      'getUniqueIdentifier',
+      'getClass',
+      'isComputed',
+      'isReadOnly',
+      'isInternal',
+    ];
+
+    $override = BaseFieldOverride::createFromBaseFieldDefinition($base_field, 'test_bundle');
+    foreach ($methods as $method) {
+      $this->assertEquals($base_field->$method(), $override->$method());
+    }
+  }
+
   /**
    * A default value callback which returns a primitive value.
    *
diff --git a/web/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php b/web/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php
index 98dc0e6b53d836733501aa4409a048eecb5754cd..83c5a3e86ad236a86778a3469e4400538edb6e9b 100644
--- a/web/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php
+++ b/web/core/tests/Drupal/Tests/Component/Datetime/TimeTest.php
@@ -128,7 +128,7 @@ public function testGetCurrentMicroTime() {
 /**
  * Shadow time() system call.
  *
- * @returns int
+ * @return int
  */
 function time() {
   return 12345678;
@@ -137,7 +137,7 @@ function time() {
 /**
  * Shadow microtime system call.
  *
- * @returns float
+ * @return float
  */
 function microtime() {
   return 1234567.89;
diff --git a/web/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php b/web/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
index 3c4623ab228fdb1c3df9573a041dce6b8a046296..cc2596566c770ad2652c8ce074beb8ca87a718e5 100644
--- a/web/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
+++ b/web/core/tests/Drupal/Tests/Core/Asset/JsOptimizerUnitTest.php
@@ -33,7 +33,7 @@ protected function setUp(): void {
    *
    * @see \Drupal\Core\Asset\JsOptimizer::clean()
    *
-   * @returns array
+   * @return array
    *   An array of test data.
    */
   public function providerTestClean() {
@@ -80,7 +80,7 @@ public function testClean($js_asset, $expected) {
    *
    * @see \Drupal\Core\Asset\JsOptimizer::optimize()
    *
-   * @returns array
+   * @return array
    *   An array of test data.
    */
   public function providerTestOptimize() {
diff --git a/web/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php b/web/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php
index 4efda0785bfc33bb289b8fc1e7839cdf91d9d533..cb04af7ff54405ba7b4e0fa36671f5202a2d61b5 100644
--- a/web/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php
+++ b/web/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php
@@ -177,8 +177,7 @@ public function unregister() {
   /**
    * Loads the given class or interface.
    *
-   * @return null
-   *   This class never loads.
+   * This class never loads.
    */
   public function loadClass() {
     return NULL;
@@ -187,8 +186,7 @@ public function loadClass() {
   /**
    * Finds a file by class name while caching lookups to APC.
    *
-   * @return null
-   *   This class never finds.
+   * This class never finds.
    */
   public function findFile() {
     return NULL;
diff --git a/web/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/web/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
index 5da25e326fb61ea95d26528083c2908100d7e304..8b75f404e7155aea16d364994288bb58b7dfbc85 100644
--- a/web/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
+++ b/web/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
@@ -526,7 +526,7 @@ public function testAccess() {
   /**
    * Data provider for testGet().
    *
-   * @returns
+   * @return array
    *   - Expected output from get().
    *   - Field name parameter to get().
    *   - Language code for $activeLanguage.
@@ -586,7 +586,7 @@ public function testGet($expected, $field_name, $active_langcode, $fields) {
   /**
    * Data provider for testGetFields().
    *
-   * @returns array
+   * @return array
    *   - Expected output from getFields().
    *   - $include_computed value to pass to getFields().
    *   - Value to mock from all field definitions for isComputed().
diff --git a/web/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php b/web/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
index 470a2cd69573252d58152a5535afe5ea5a871149..08d8540889cc4c5ebd9687c549a4a397f1d740c0 100644
--- a/web/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
+++ b/web/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
 use Drupal\Core\Routing\RedirectDestinationInterface;
+use Drupal\Core\Url;
 use Drupal\entity_test\EntityTestListBuilder;
 use Drupal\Tests\UnitTestCase;
 
@@ -120,12 +121,7 @@ public function testGetOperations() {
     $this->role->expects($this->any())
       ->method('hasLinkTemplate')
       ->willReturn(TRUE);
-    $url = $this->getMockBuilder('\Drupal\Core\Url')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $url->expects($this->atLeastOnce())
-      ->method('mergeOptions')
-      ->with(['query' => ['destination' => '/foo/bar']]);
+    $url = Url::fromRoute('entity.user_role.collection');
     $this->role->expects($this->any())
       ->method('toUrl')
       ->willReturn($url);
diff --git a/web/core/tests/Drupal/Tests/Core/Password/PhpPasswordTest.php b/web/core/tests/Drupal/Tests/Core/Password/PhpPasswordTest.php
index 7d429ca3d533d5c907099498faffe820318ec534..21f7266d019ca5230b23d3f5dfa34cb6109aacdc 100644
--- a/web/core/tests/Drupal/Tests/Core/Password/PhpPasswordTest.php
+++ b/web/core/tests/Drupal/Tests/Core/Password/PhpPasswordTest.php
@@ -124,4 +124,14 @@ public function providerLongPasswords() {
     return $passwords;
   }
 
+  /**
+   * Tests password check in case provided hash is NULL.
+   *
+   * @covers ::check
+   */
+  public function testEmptyHash(): void {
+    $this->assertFalse($this->passwordHasher->check($this->password, NULL));
+    $this->assertFalse($this->passwordHasher->check($this->password, ''));
+  }
+
 }
diff --git a/web/core/tests/Drupal/Tests/Core/Session/SessionConfigurationTest.php b/web/core/tests/Drupal/Tests/Core/Session/SessionConfigurationTest.php
index 55282c05483c3e945a50b4e84c8ce4ee28ecacec..3c6508806ca0fd40d4c2de462a26c97506f54f0b 100644
--- a/web/core/tests/Drupal/Tests/Core/Session/SessionConfigurationTest.php
+++ b/web/core/tests/Drupal/Tests/Core/Session/SessionConfigurationTest.php
@@ -14,7 +14,7 @@ class SessionConfigurationTest extends UnitTestCase {
   /**
    * Constructs a partially mocked SUT.
    *
-   * @returns \Drupal\Core\Session\SessionConfiguration|\PHPUnit\Framework\MockObject\MockObject
+   * @return \Drupal\Core\Session\SessionConfiguration|\PHPUnit\Framework\MockObject\MockObject
    */
   protected function createSessionConfiguration($options = []) {
     return $this->getMockBuilder('Drupal\Core\Session\SessionConfiguration')
@@ -42,7 +42,7 @@ public function testGeneratedCookieDomain($uri, $expected_domain) {
   /**
    * Data provider for the cookie domain test.
    *
-   * @returns array
+   * @return array
    *   Test data
    */
   public function providerTestGeneratedCookieDomain() {
@@ -81,7 +81,7 @@ public function testEnforcedCookieDomain($uri, $expected_domain) {
   /**
    * Data provider for the cookie domain test.
    *
-   * @returns array
+   * @return array
    *   Test data
    */
   public function providerTestEnforcedCookieDomain() {
@@ -147,7 +147,7 @@ public function testCookieSecureNotOverridable($uri, $expected_secure) {
   /**
    * Data provider for the cookie secure test.
    *
-   * @returns array
+   * @return array
    *   Test data
    */
   public function providerTestCookieSecure() {
@@ -180,7 +180,7 @@ public function testGeneratedSessionName($uri, $expected_name) {
   /**
    * Data provider for the cookie name test.
    *
-   * @returns array
+   * @return array
    *   Test data
    */
   public function providerTestGeneratedSessionName() {
@@ -228,7 +228,7 @@ public function testEnforcedSessionNameViaCookieDomain($uri, $expected_name) {
   /**
    * Data provider for the cookie name test.
    *
-   * @returns array
+   * @return array
    *   Test data
    */
   public function providerTestEnforcedSessionName() {
@@ -274,7 +274,7 @@ public function testConstructorDefaultSettings(array $options, int $expected_sid
   /**
    * Data provider for the constructor test.
    *
-   * @returns array
+   * @return array
    *   Test data
    */
   public function providerTestConstructorDefaultSettings() {
diff --git a/web/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php b/web/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php
index bffe8fa0a6ce0746de703852e4f325e764f12f2d..13833a2897d43347eac2c2c57556a58280208273 100644
--- a/web/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php
+++ b/web/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php
@@ -379,9 +379,9 @@ public function testSerialization() {
 class UnserializableRequest extends Request {
 
   /**
-   * @return array
+   * Always throw an exception.
    */
-  public function __serialize(): array {
+  public function __serialize() {
     throw new \LogicException('Oops!');
   }
 
diff --git a/web/core/themes/olivero/templates/content/comment.html.twig b/web/core/themes/olivero/templates/content/comment.html.twig
index dca937fff0a542f8e257b08823f9532768068683..1306e56d72862d4e2336c78c0eaf8c0824bd4a22 100644
--- a/web/core/themes/olivero/templates/content/comment.html.twig
+++ b/web/core/themes/olivero/templates/content/comment.html.twig
@@ -4,7 +4,7 @@
  * Olivero's theme implementation for comments.
  *
  * Available variables:
- * - author: Comment author. Can be a link or plain text.
+ * - author: (optional) Comment author. Can be a link or plain text.
  * - content: The content-related items for the comment display. Use
  *   {{ content }} to print them all, or print a subset such as
  *   {{ content.field_example }}. Use the following code to temporarily suppress
@@ -12,22 +12,24 @@
  *   @code
  *   {{ content|without('field_example') }}
  *   @endcode
- * - created: Formatted date and time for when the comment was created.
- *   Preprocess functions can reformat it by calling DateFormatter::format()
- *   with the desired parameters on the 'comment.created' variable.
- * - changed: Formatted date and time for when the comment was last changed.
- *   Preprocess functions can reformat it by calling DateFormatter::format()
- *   with the desired parameters on the 'comment.changed' variable.
+ * - created: (optional) Formatted date and time for when the comment was
+ *   created. Preprocess functions can reformat it by calling
+ *   DateFormatter::format() with the desired parameters on the
+ *   'comment.created' variable.
+ * - changed: (optional) Formatted date and time for when the comment was last
+ *   changed. Preprocess functions can reformat it by calling
+ *   DateFormatter::format() with the desired parameters on the
+ *   'comment.changed' variable.
  * - permalink: Comment permalink.
- * - submitted: Submission information created from author and created
- *   during template_preprocess_comment().
- * - user_picture: The comment author's profile picture.
+ * - submitted: (optional) Submission information created from author and
+ *   created during template_preprocess_comment().
+ * - user_picture: (optional) The comment author's profile picture.
  * - status: Comment status. Possible values are:
  *   unpublished, published, or preview.
- * - title: Comment title, linked to the comment.
+ * - title: (optional) Comment title, linked to the comment.
  * - attributes: HTML attributes for the containing element.
  *   The attributes.class may contain one or more of the following classes:
- *   - comment: The current template type; e.g., 'theming hook'.
+ *   - comment: The current template type; for instance, 'theming hook'.
  *   - by-anonymous: Comment by an unregistered user.
  *   - by-{entity-type}-author: Comment by the author of the parent entity,
  *     eg. by-node-author.
@@ -38,13 +40,13 @@
  *   displayed in front of the main title tag that appears in the template.
  * - title_suffix: Additional output populated by modules, intended to be
  *   displayed after the main title tag that appears in the template.
+ * - content_attributes: List of classes for the styling of the comment content.
  * - title_attributes: Same as attributes, except applied to the main title
  *   tag that appears in the template.
- * - content_attributes: List of classes for the styling of the comment content.
  * - threaded: A flag indicating whether the comments are threaded or not.
  *
  * These variables are provided to give context about the parent comment (if
- * any):
+ * any, optional):
  * - parent_comment: Full parent comment entity (if any).
  * - parent_author: Equivalent to author for the parent comment.
  * - parent_created: Equivalent to created for the parent comment.
@@ -83,24 +85,28 @@
   #}
   <span class="hidden" data-comment-timestamp="{{ new_indicator_timestamp }}"></span>
 
-  <div class="comment__picture-wrapper">
-    <div class="comment__picture">
-      {{ user_picture }}
+  {% if submitted %}
+    <div class="comment__picture-wrapper">
+      <div class="comment__picture">
+        {{ user_picture }}
+      </div>
     </div>
-  </div>
+  {% endif %}
   <div class="comment__text-wrapper">
-    <footer class="comment__meta">
-      <p class="comment__author">{{ author }}</p>
-      <p class="comment__time">{{ created }}</p>
-      {#
-        Indicate the semantic relationship between parent and child comments
-        for accessibility. The list is difficult to navigate in a screen
-        reader without this information.
-       #}
-      {% if parent %}
-        <p class="visually-hidden">{{ parent }}</p>
-      {% endif %}
-    </footer>
+    {% if submitted %}
+      <footer class="comment__meta">
+        <p class="comment__author">{{ author }}</p>
+        <p class="comment__time">{{ created }}</p>
+        {#
+          Indicate the semantic relationship between parent and child comments
+          for accessibility. The list is difficult to navigate in a screen
+          reader without this information.
+         #}
+        {% if parent %}
+          <p class="visually-hidden">{{ parent }}</p>
+        {% endif %}
+      </footer>
+    {% endif %}
     <div{{ content_attributes.addClass('comment__content') }}>
       {% if title %}
         {{ title_prefix }}
diff --git a/web/core/themes/starterkit_theme/templates/content/comment.html.twig b/web/core/themes/starterkit_theme/templates/content/comment.html.twig
index 5838c62915961753be6a55d227afe8ca499619d9..41c64901a3884823d87ea6ff926d8038860993c9 100644
--- a/web/core/themes/starterkit_theme/templates/content/comment.html.twig
+++ b/web/core/themes/starterkit_theme/templates/content/comment.html.twig
@@ -4,7 +4,7 @@
  * Theme override for comments.
  *
  * Available variables:
- * - author: Comment author. Can be a link or plain text.
+ * - author: (optional) Comment author. Can be a link or plain text.
  * - content: The content-related items for the comment display. Use
  *   {{ content }} to print them all, or print a subset such as
  *   {{ content.field_example }}. Use the following code to temporarily suppress
@@ -12,22 +12,24 @@
  *   @code
  *   {{ content|without('field_example') }}
  *   @endcode
- * - created: Formatted date and time for when the comment was created.
- *   Preprocess functions can reformat it by calling DateFormatter::format()
- *   with the desired parameters on the 'comment.created' variable.
- * - changed: Formatted date and time for when the comment was last changed.
- *   Preprocess functions can reformat it by calling DateFormatter::format()
- *   with the desired parameters on the 'comment.changed' variable.
+ * - created: (optional) Formatted date and time for when the comment was
+ *   created. Preprocess functions can reformat it by calling
+ *   DateFormatter::format() with the desired parameters on the
+ *   'comment.created' variable.
+ * - changed: (optional) Formatted date and time for when the comment was last
+ *   changed. Preprocess functions can reformat it by calling
+ *   DateFormatter::format() with the desired parameters on the
+ *   'comment.changed' variable.
  * - permalink: Comment permalink.
- * - submitted: Submission information created from author and created
- *   during template_preprocess_comment().
- * - user_picture: The comment author's profile picture.
+ * - submitted: (optional) Submission information created from author and
+ *   created during template_preprocess_comment().
+ * - user_picture: (optional) The comment author's profile picture.
  * - status: Comment status. Possible values are:
  *   unpublished, published, or preview.
- * - title: Comment title, linked to the comment.
+ * - title: (optional) Comment title, linked to the comment.
  * - attributes: HTML attributes for the containing element.
  *   The attributes.class may contain one or more of the following classes:
- *   - comment: The current template type; e.g., 'theming hook'.
+ *   - comment: The current template type; for instance, 'theming hook'.
  *   - by-anonymous: Comment by an unregistered user.
  *   - by-{entity-type}-author: Comment by the author of the parent entity,
  *     eg. by-node-author.
@@ -44,7 +46,7 @@
  * - threaded: A flag indicating whether the comments are threaded or not.
  *
  * These variables are provided to give context about the parent comment (if
- * any):
+ * any, optional):
  * - parent_comment: Full parent comment entity (if any).
  * - parent_author: Equivalent to author for the parent comment.
  * - parent_created: Equivalent to created for the parent comment.
@@ -84,21 +86,23 @@
   #}
   <mark class="hidden" data-comment-timestamp="{{ new_indicator_timestamp }}"></mark>
 
-  <footer class="comment__meta">
-    {{ user_picture }}
-    <p class="comment__submitted">{{ submitted }}</p>
+  {% if submitted %}
+    <footer class="comment__meta">
+      {{ user_picture }}
+      <p class="comment__submitted">{{ submitted }}</p>
 
-    {#
-      Indicate the semantic relationship between parent and child comments for
-      accessibility. The list is difficult to navigate in a screen reader
-      without this information.
-    #}
-    {% if parent %}
-      <p class="parent visually-hidden">{{ parent }}</p>
-    {% endif %}
+      {#
+        Indicate the semantic relationship between parent and child comments for
+        accessibility. The list is difficult to navigate in a screen reader
+        without this information.
+      #}
+      {% if parent %}
+        <p class="parent visually-hidden">{{ parent }}</p>
+      {% endif %}
 
-    {{ permalink }}
-  </footer>
+      {{ permalink }}
+    </footer>
+  {% endif %}
 
   <div{{ content_attributes.addClass('content') }}>
     {% if title %}
diff --git a/web/core/yarn.lock b/web/core/yarn.lock
index 47e62c1ba3a4b51c5cc7e996a44304e0b17ffe37..fbc6229283b265f526464eb71dddc724cb51ae5d 100644
--- a/web/core/yarn.lock
+++ b/web/core/yarn.lock
@@ -4395,19 +4395,10 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
   resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
   integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
 
-postcss@^8.4.21:
-  version "8.4.23"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
-  integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==
-  dependencies:
-    nanoid "^3.3.6"
-    picocolors "^1.0.0"
-    source-map-js "^1.0.2"
-
-postcss@^8.4.24:
-  version "8.4.24"
-  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df"
-  integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==
+postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.31:
+  version "8.4.31"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
+  integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
   dependencies:
     nanoid "^3.3.6"
     picocolors "^1.0.0"