diff --git a/DEPS b/DEPS
index f0f9cd28..a704e27 100644
--- a/DEPS
+++ b/DEPS
@@ -234,15 +234,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': 'aef2b63743e2d7634191afb90091fae303b7228a',
+  'skia_revision': 'dfe33f49f5cf19174533028af307cfb972a25163',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '5e4118803eaf493e9c0ef6cb617b608032386c40',
+  'v8_revision': '66b18e0e5168b5c7c2e21af5ae8003e19a677413',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '9d91064d6c8beb7679502d4e92942c325065adea',
+  'angle_revision': '8f6f5a4bb28d4f9cef8b747c9cd384ebcebb2a6a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -309,7 +309,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '8f098d33cda3dd94b53e9506cd3883d0dccc339e',
+  'devtools_frontend_revision': 'd8bbc76a3ffac4835cc1d4e4c7dcd22a062750cd',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -349,7 +349,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '2294cf44802b25f9ec81134613dd8156351f4a76',
+  'dawn_revision': 'e7efad03259a6cc1643d9bc545c16bb9f3ddc1e4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -393,11 +393,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'libcxxabi_revision':    '665b74f7d1b3bb295cd6ba7d8fcec1acd3d2ac84',
+  'libcxxabi_revision':    '89f2e82120461d34098edd216e57aa743f441107',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'libunwind_revision':    'c936d73ff70ebf755c8fee3f3420dd16805e377a',
+  'libunwind_revision':    'a281fd3d4c50174af1dd2d88bb15b168b73883d0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -922,7 +922,7 @@
 
   'src/third_party/barhopper': {
       'url': 'https://chrome-internal.googlesource.com/chrome/deps/barhopper.git' + '@' + 'b619dfad3ef48aa15d3a647442c3c40f3a967146',
-      'condition': 'checkout_src_internal',
+      'condition': 'checkout_src_internal and checkout_chromeos',
   },
 
   'src/third_party/cast_core/prebuilts': {
@@ -1010,7 +1010,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '1979aadbf44f3f3101e51415a93463e8641f0628',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6badd12fdf7c0eeb8ff5cfe31758962f3e784209',
       'condition': 'checkout_chromeos',
   },
 
@@ -1413,7 +1413,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '9296f1edfee55523164a8c3cae7458b21a36dc2d',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '4a9b683ccbbb7f1d3d16645671e960dae6a8a352',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1631,10 +1631,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '9ec0bd5501c6a35eb365dc49be7618a763135a10',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'c531d83e7869a8265a62892db877fc56c20ca4c4',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '6dd2ea962ece11eef2e2dfebc55e60aa05b18488',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '59b8a46d3f6a072ae3eba8ab86fdd91c39821ec6',
+    Var('webrtc_git') + '/src.git' + '@' + '794cc227dc9110fa89e36c5e6e9827d40d3046f0',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1692,7 +1692,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@bc3e343a93269629bde5439433d4a35ee381d461',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d94dad4e25791568b6d15d321ac121e62d363aa6',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/ash_prefs.cc b/ash/ash_prefs.cc
index 5ea13a1e..3105900 100644
--- a/ash/ash_prefs.cc
+++ b/ash/ash_prefs.cc
@@ -127,6 +127,7 @@
   PowerPrefs::RegisterLocalStatePrefs(registry);
   DisplayPrefs::RegisterLocalStatePrefs(registry);
   LoginExpandedPublicAccountView::RegisterLocalStatePrefs(registry);
+  quick_pair::Mediator::RegisterLocalStatePrefs(registry);
   TopShortcutsView::RegisterLocalStatePrefs(registry);
 }
 
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.cc b/ash/quick_pair/keyed_service/quick_pair_mediator.cc
index 8461a9a..5bd59cb 100644
--- a/ash/quick_pair/keyed_service/quick_pair_mediator.cc
+++ b/ash/quick_pair/keyed_service/quick_pair_mediator.cc
@@ -111,6 +111,12 @@
   PendingWriteStore::RegisterProfilePrefs(registry);
 }
 
+// static
+void Mediator::RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
+  // TODO(dclasson): register future local state prefs here.
+  return;
+}
+
 chromeos::bluetooth_config::FastPairDelegate* Mediator::GetFastPairDelegate() {
   return fast_pair_bluetooth_config_delegate_.get();
 }
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.h b/ash/quick_pair/keyed_service/quick_pair_mediator.h
index 5cc2cac9..e37d3d3 100644
--- a/ash/quick_pair/keyed_service/quick_pair_mediator.h
+++ b/ash/quick_pair/keyed_service/quick_pair_mediator.h
@@ -66,6 +66,7 @@
   ~Mediator() override;
 
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
+  static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
 
   chromeos::bluetooth_config::FastPairDelegate* GetFastPairDelegate();
 
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc
index 5af7aadf..5ea2158 100644
--- a/ash/style/ash_color_provider.cc
+++ b/ash/style/ash_color_provider.cc
@@ -54,10 +54,6 @@
 constexpr int kDarkBackgroundBlendAlpha = 127;   // 50%
 constexpr int kLightBackgroundBlendAlpha = 127;  // 50%
 
-// The default background color that can be applied on any layer.
-constexpr SkColor kBackgroundColorDefaultLight = SK_ColorWHITE;
-constexpr SkColor kBackgroundColorDefaultDark = gfx::kGoogleGrey900;
-
 // Get the corresponding ColorName for |type|. ColorName is an enum in
 // cros_styles.h file that is generated from cros_colors.json5, which
 // includes the color IDs and colors that will be used by ChromeOS WebUI.
@@ -234,6 +230,13 @@
                     : GetInvertedBackgroundDefaultColor();
 }
 
+SkColor AshColorProvider::GetBackgroundColorInMode(bool use_dark_color) const {
+  return cros_styles::ResolveColor(
+      cros_styles::ColorName::kBgColor, use_dark_color,
+      base::FeatureList::IsEnabled(
+          ash::features::kSemanticColorsDebugOverride));
+}
+
 void AshColorProvider::AddObserver(ColorModeObserver* observer) {
   observers_.AddObserver(observer);
 }
@@ -403,13 +406,11 @@
 }
 
 SkColor AshColorProvider::GetBackgroundDefaultColor() const {
-  return IsDarkModeEnabled() ? kBackgroundColorDefaultDark
-                             : kBackgroundColorDefaultLight;
+  return GetBackgroundColorInMode(IsDarkModeEnabled());
 }
 
 SkColor AshColorProvider::GetInvertedBackgroundDefaultColor() const {
-  return !IsDarkModeEnabled() ? kBackgroundColorDefaultDark
-                              : kBackgroundColorDefaultLight;
+  return GetBackgroundColorInMode(!IsDarkModeEnabled());
 }
 
 SkColor AshColorProvider::GetBackgroundThemedColor() const {
diff --git a/ash/style/ash_color_provider.h b/ash/style/ash_color_provider.h
index 57490352..21b27ec 100644
--- a/ash/style/ash_color_provider.h
+++ b/ash/style/ash_color_provider.h
@@ -80,6 +80,8 @@
   // Same as above, but returns the color based on the current inverted color
   // mode and color theme.
   SkColor GetInvertedBackgroundColor() const;
+  // Gets the background color in the desired color mode dark/light.
+  SkColor GetBackgroundColorInMode(bool use_dark_color) const;
 
   // Whether the system color mode is themed, by default is true. If true, the
   // background color will be calculated based on extracted wallpaper color.
diff --git a/ash/system/bluetooth/bluetooth_device_list_item_view.cc b/ash/system/bluetooth/bluetooth_device_list_item_view.cc
index b88a236..032304d 100644
--- a/ash/system/bluetooth/bluetooth_device_list_item_view.cc
+++ b/ash/system/bluetooth/bluetooth_device_list_item_view.cc
@@ -11,7 +11,9 @@
 #include "ash/system/tray/tray_utils.h"
 #include "base/check.h"
 #include "chromeos/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h"
+#include "chromeos/ui/vector_icons/vector_icons.h"
 #include "mojo/public/cpp/bindings/clone_traits.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/gfx/vector_icon_types.h"
@@ -26,6 +28,8 @@
 using chromeos::bluetooth_config::mojom::DeviceType;
 using chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr;
 
+constexpr int kEnterpriseManagedIconSizeDip = 20;
+
 // Returns the icon corresponding to the provided |device_type| and
 // |connection_state|.
 const gfx::VectorIcon& GetDeviceIcon(const DeviceType device_type) {
@@ -82,6 +86,15 @@
               AshColorProvider::ContentLayerType::kIconColorPrimary)),
       GetPairedDeviceName(device_properties_.get()));
 
+  // Adds an icon to indicate that the device supports profiles or services that
+  // are disabled or blocked by enterprise policy.
+  if (device_properties->device_properties->is_blocked_by_policy) {
+    AddRightIcon(
+        CreateVectorIcon(chromeos::kEnterpriseIcon,
+                         kEnterpriseManagedIconSizeDip, gfx::kGoogleGrey100),
+        /*icon_size=*/kEnterpriseManagedIconSizeDip);
+  }
+
   const DeviceConnectionState& connection_state =
       device_properties_->device_properties->connection_state;
 
diff --git a/ash/system/bluetooth/bluetooth_device_list_item_view_unittest.cc b/ash/system/bluetooth/bluetooth_device_list_item_view_unittest.cc
index f8f7cf6c..8f9099f 100644
--- a/ash/system/bluetooth/bluetooth_device_list_item_view_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_device_list_item_view_unittest.cc
@@ -19,7 +19,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
+#include "chromeos/ui/vector_icons/vector_icons.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_unittest_util.h"
@@ -213,6 +215,39 @@
   }
 }
 
+TEST_F(BluetoothDeviceListItemViewTest,
+       HasEnterpriseIconWhenDeviceIsBlockedByPolicy) {
+  PairedBluetoothDevicePropertiesPtr paired_device_properties =
+      CreatePairedDeviceProperties();
+
+  paired_device_properties->device_properties->is_blocked_by_policy = false;
+  bluetooth_device_list_item()->UpdateDeviceProperties(
+      paired_device_properties);
+  EXPECT_FALSE(bluetooth_device_list_item()->right_view());
+
+  paired_device_properties->device_properties->is_blocked_by_policy = true;
+  bluetooth_device_list_item()->UpdateDeviceProperties(
+      paired_device_properties);
+  ASSERT_TRUE(bluetooth_device_list_item()->right_view());
+  EXPECT_TRUE(bluetooth_device_list_item()->right_view()->GetVisible());
+
+  const gfx::Image expected_image(CreateVectorIcon(
+      chromeos::kEnterpriseIcon, /*dip_size=*/20, gfx::kGoogleGrey100));
+
+  ASSERT_TRUE(views::IsViewClass<views::ImageView>(
+      bluetooth_device_list_item()->right_view()));
+  const gfx::Image actual_image(
+      static_cast<views::ImageView*>(bluetooth_device_list_item()->right_view())
+          ->GetImage());
+
+  EXPECT_TRUE(gfx::test::AreImagesEqual(expected_image, actual_image));
+
+  paired_device_properties->device_properties->is_blocked_by_policy = false;
+  bluetooth_device_list_item()->UpdateDeviceProperties(
+      paired_device_properties);
+  ASSERT_FALSE(bluetooth_device_list_item()->right_view());
+}
+
 TEST_F(BluetoothDeviceListItemViewTest, NotifiesListenerWhenClicked) {
   EXPECT_FALSE(last_clicked_device_list_item());
   SimulateMouseClickAt(GetEventGenerator(), bluetooth_device_list_item());
diff --git a/ash/system/phonehub/bluetooth_disabled_view.cc b/ash/system/phonehub/bluetooth_disabled_view.cc
index 78c88e8e..6b3f84ce 100644
--- a/ash/system/phonehub/bluetooth_disabled_view.cc
+++ b/ash/system/phonehub/bluetooth_disabled_view.cc
@@ -68,7 +68,7 @@
 
 void BluetoothDisabledView::LearnMoreButtonPressed() {
   LogInterstitialScreenEvent(InterstitialScreenEvent::kLearnMore);
-  NewWindowDelegate::GetInstance()->OpenUrl(
+  NewWindowDelegate::GetPrimary()->OpenUrl(
       GURL(phonehub::kPhoneHubLearnMoreLink),
       /*from_user_interaction=*/true);
 }
diff --git a/ash/system/phonehub/continue_browsing_chip.cc b/ash/system/phonehub/continue_browsing_chip.cc
index 9db3fa5..01e5603 100644
--- a/ash/system/phonehub/continue_browsing_chip.cc
+++ b/ash/system/phonehub/continue_browsing_chip.cc
@@ -141,8 +141,8 @@
   phone_hub_metrics::LogTabContinuationChipClicked(index_);
   user_action_recorder_->RecordBrowserTabOpened();
 
-  NewWindowDelegate::GetInstance()->OpenUrl(url_,
-                                            /*from_user_interaction=*/true);
+  NewWindowDelegate::GetPrimary()->OpenUrl(url_,
+                                           /*from_user_interaction=*/true);
 
   // Close Phone Hub bubble in current display.
   views::Widget* const widget = GetWidget();
diff --git a/ash/system/phonehub/notification_opt_in_view.cc b/ash/system/phonehub/notification_opt_in_view.cc
index b7362bc7..f38ebfa 100644
--- a/ash/system/phonehub/notification_opt_in_view.cc
+++ b/ash/system/phonehub/notification_opt_in_view.cc
@@ -49,8 +49,8 @@
 void NotificationOptInView::SetUpButtonPressed() {
   // Opens the notification set up dialog in settings to start the opt in flow.
   LogNotificationOptInEvent(InterstitialScreenEvent::kConfirm);
-  NewWindowDelegate::GetInstance()->OpenUrl(GURL(kMultideviceSettingsUrl),
-                                            /*from_user_interaction=*/true);
+  NewWindowDelegate::GetPrimary()->OpenUrl(GURL(kMultideviceSettingsUrl),
+                                           /*from_user_interaction=*/true);
 }
 
 void NotificationOptInView::DismissButtonPressed() {
diff --git a/ash/system/phonehub/phone_disconnected_view.cc b/ash/system/phonehub/phone_disconnected_view.cc
index b9775b2..bf541013 100644
--- a/ash/system/phonehub/phone_disconnected_view.cc
+++ b/ash/system/phonehub/phone_disconnected_view.cc
@@ -51,11 +51,10 @@
       base::BindRepeating(
           &PhoneDisconnectedView::ButtonPressed, base::Unretained(this),
           InterstitialScreenEvent::kLearnMore,
-          base::BindRepeating(
-              &NewWindowDelegate::OpenUrl,
-              base::Unretained(NewWindowDelegate::GetInstance()),
-              GURL(phonehub::kPhoneHubLearnMoreLink),
-              /*from_user_interaction=*/true)),
+          base::BindRepeating(&NewWindowDelegate::OpenUrl,
+                              base::Unretained(NewWindowDelegate::GetPrimary()),
+                              GURL(phonehub::kPhoneHubLearnMoreLink),
+                              /*from_user_interaction=*/true)),
       l10n_util::GetStringUTF16(
           IDS_ASH_PHONE_HUB_PHONE_DISCONNECTED_DIALOG_LEARN_MORE_BUTTON),
       PillButton::Type::kIconlessFloating, /*icon=*/nullptr);
diff --git a/ash/wallpaper/test_wallpaper_controller_client.cc b/ash/wallpaper/test_wallpaper_controller_client.cc
index fbe3b93..4cf62b3 100644
--- a/ash/wallpaper/test_wallpaper_controller_client.cc
+++ b/ash/wallpaper/test_wallpaper_controller_client.cc
@@ -52,7 +52,7 @@
   if (fetch_daily_refresh_info_fails_) {
     std::move(callback).Run(absl::nullopt, std::string());
   } else {
-    std::move(callback).Run(1, "fun_image_url");
+    std::move(callback).Run(1, "http://example.com");
   }
 }
 
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index 779d0091..364636a 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -34,13 +34,17 @@
 #include "ash/wallpaper/wallpaper_view.h"
 #include "ash/wallpaper/wallpaper_widget_controller.h"
 #include "ash/wallpaper/wallpaper_window_state_manager.h"
+#include "ash/webui/personalization_app/proto/backdrop_wallpaper.pb.h"
 #include "ash/wm/overview/overview_constants.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
+#include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/check.h"
 #include "base/command_line.h"
 #include "base/files/file_enumerator.h"
+#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
@@ -411,6 +415,33 @@
   return base::FilePath();
 }
 
+// Checks the file paths for the given online wallpaper variants. Return empty
+// map if not all paths are available.
+base::flat_map<std::string, base::FilePath> GetOnlineWallpaperVariantPaths(
+    const std::vector<OnlineWallpaperVariant>& variants) {
+  base::flat_map<std::string, base::FilePath> url_to_file_path_map;
+  WallpaperControllerImpl::WallpaperResolution resolution =
+      GetAppropriateResolution();
+
+  for (const auto& variant : variants) {
+    const std::string& url = variant.url.spec();
+    base::FilePath variant_path = GetOnlineWallpaperPath(url, resolution);
+    base::FilePath large_variant_path = GetOnlineWallpaperPath(
+        url, WallpaperControllerImpl::WALLPAPER_RESOLUTION_LARGE);
+    if (base::PathExists(variant_path)) {
+      url_to_file_path_map[url] = variant_path;
+    } else if (resolution ==
+                   WallpaperControllerImpl::WALLPAPER_RESOLUTION_SMALL &&
+               base::PathExists(large_variant_path)) {
+      // Falls back to the large wallpaper if the small one doesn't exist.
+      url_to_file_path_map[url] = large_variant_path;
+    } else {
+      return base::flat_map<std::string, base::FilePath>();
+    }
+  }
+  return url_to_file_path_map;
+}
+
 // Saves the online wallpaper with both large and small sizes to local file
 // system.
 void SaveOnlineWallpaper(const std::string& url,
@@ -1082,12 +1113,24 @@
     }
   }
 
-  base::PostTaskAndReplyWithResult(
-      sequenced_task_runner_.get(), FROM_HERE,
-      base::BindOnce(&GetExistingOnlineWallpaperPath, params.url.spec()),
-      base::BindOnce(&WallpaperControllerImpl::SetOnlineWallpaperFromPath,
-                     set_wallpaper_weak_factory_.GetWeakPtr(),
-                     std::move(callback), params));
+  if (params.variants.empty()) {
+    // |params.variants| can be empty for users who use the old wallpaper
+    // picker. If that's the case, just follow the old flow.
+    base::PostTaskAndReplyWithResult(
+        sequenced_task_runner_.get(), FROM_HERE,
+        base::BindOnce(&GetExistingOnlineWallpaperPath, params.url.spec()),
+        base::BindOnce(&WallpaperControllerImpl::SetOnlineWallpaperFromPath,
+                       set_wallpaper_weak_factory_.GetWeakPtr(),
+                       std::move(callback), params));
+  } else {
+    base::PostTaskAndReplyWithResult(
+        sequenced_task_runner_.get(), FROM_HERE,
+        base::BindOnce(&GetOnlineWallpaperVariantPaths, params.variants),
+        base::BindOnce(
+            &WallpaperControllerImpl::SetOnlineWallpaperFromVariantPaths,
+            set_wallpaper_weak_factory_.GetWeakPtr(), std::move(callback),
+            params));
+  }
 }
 
 void WallpaperControllerImpl::SetOnlineWallpaperFromData(
@@ -1947,6 +1990,22 @@
       sequenced_task_runner_, file_path);
 }
 
+void WallpaperControllerImpl::SetOnlineWallpaperFromVariantPaths(
+    SetOnlineWallpaperCallback callback,
+    const OnlineWallpaperParams& params,
+    const base::flat_map<std::string, base::FilePath>& url_to_file_path_map) {
+  if (url_to_file_path_map.empty()) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  ReadAndDecodeWallpaper(
+      base::BindOnce(&WallpaperControllerImpl::OnOnlineWallpaperDecoded,
+                     set_wallpaper_weak_factory_.GetWeakPtr(), params,
+                     /*save_file=*/false, std::move(callback)),
+      sequenced_task_runner_, url_to_file_path_map.at(params.url.spec()));
+}
+
 void WallpaperControllerImpl::OnOnlineWallpaperDecoded(
     const OnlineWallpaperParams& params,
     bool save_file,
@@ -2505,12 +2564,74 @@
     std::move(callback).Run(true);
     return;
   }
-  std::string url = params.url.spec() + GetBackdropWallpaperSuffix();
-  ImageDownloader::Get()->Download(
-      GURL(url), NO_TRAFFIC_ANNOTATION_YET,
-      base::BindOnce(&WallpaperControllerImpl::OnOnlineWallpaperDecoded,
-                     set_wallpaper_weak_factory_.GetWeakPtr(), params,
-                     /*save_file=*/true, std::move(callback)));
+
+  const std::vector<OnlineWallpaperVariant>& variants = params.variants;
+  if (variants.empty()) {
+    // |variants| can be empty for users who have just migrated from the old
+    // wallpaper picker to the new one.
+    std::string url = params.url.spec() + GetBackdropWallpaperSuffix();
+    ImageDownloader::Get()->Download(
+        GURL(url), NO_TRAFFIC_ANNOTATION_YET,
+        base::BindOnce(&WallpaperControllerImpl::OnOnlineWallpaperDecoded,
+                       set_wallpaper_weak_factory_.GetWeakPtr(), params,
+                       /*save_file=*/true, std::move(callback)));
+  } else {
+    // Start fetching the wallpaper variants.
+    url_to_image_map_.clear();
+    auto on_done = base::BarrierClosure(
+        variants.size(),
+        base::BindOnce(
+            &WallpaperControllerImpl::OnAllOnlineWallpaperVariantsDownloaded,
+            weak_factory_.GetWeakPtr(), params, std::move(callback)));
+
+    for (size_t i = 0; i < variants.size(); i++) {
+      ImageDownloader::Get()->Download(
+          GURL(variants.at(i).url), NO_TRAFFIC_ANNOTATION_YET,
+          base::BindOnce(
+              &WallpaperControllerImpl::OnOnlineWallpaperVariantDownloaded,
+              set_wallpaper_weak_factory_.GetWeakPtr(), params, on_done,
+              /*current_index=*/i));
+    }
+  }
+}
+
+void WallpaperControllerImpl::OnOnlineWallpaperVariantDownloaded(
+    const OnlineWallpaperParams& params,
+    base::RepeatingClosure on_done,
+    size_t current_index,
+    const gfx::ImageSkia& image) {
+  if (image.isNull()) {
+    std::move(on_done).Run();
+    return;
+  }
+
+  const std::vector<OnlineWallpaperVariant>& variants = params.variants;
+  const OnlineWallpaperVariant& current_variant = variants.at(current_index);
+  // Keep track of each downloaded image.
+  url_to_image_map_.insert({current_variant.url.spec(), image});
+
+  // Save the image to disk.
+  image.EnsureRepsForSupportedScales();
+  gfx::ImageSkia deep_copy(image.DeepCopy());
+  sequenced_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(&SaveOnlineWallpaper, current_variant.url.spec(),
+                     params.layout, deep_copy));
+  std::move(on_done).Run();
+}
+
+void WallpaperControllerImpl::OnAllOnlineWallpaperVariantsDownloaded(
+    const OnlineWallpaperParams& params,
+    SetOnlineWallpaperCallback callback) {
+  bool success = url_to_image_map_.size() == params.variants.size() &&
+                 !url_to_image_map_.at(params.url.spec()).isNull();
+  if (!success) {
+    std::move(callback).Run(success);
+    return;
+  }
+
+  OnOnlineWallpaperDecoded(params, /*save_file=*/false, std::move(callback),
+                           url_to_image_map_.at(params.url.spec()));
 }
 
 constexpr bool WallpaperControllerImpl::IsWallpaperTypeSyncable(
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h
index 4c361c7..67a307589 100644
--- a/ash/wallpaper/wallpaper_controller_impl.h
+++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -26,6 +26,7 @@
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer_observer.h"
 #include "ash/wm/overview/overview_observer.h"
 #include "base/callback_helpers.h"
+#include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
 #include "base/files/file_path_watcher.h"
 #include "base/gtest_prod_util.h"
@@ -41,6 +42,7 @@
 #include "ui/gfx/image/image_skia.h"
 #include "ui/native_theme/native_theme.h"
 #include "ui/native_theme/native_theme_observer.h"
+#include "url/gurl.h"
 
 class PrefRegistrySimple;
 
@@ -445,6 +447,13 @@
                                   const OnlineWallpaperParams& params,
                                   const base::FilePath& file_path);
 
+  // Used as the callback of checking that all the wallpaper variants' paths
+  // exist. If they do, set the online wallpaper from the given |params.url|.
+  void SetOnlineWallpaperFromVariantPaths(
+      SetOnlineWallpaperCallback callback,
+      const OnlineWallpaperParams& params,
+      const base::flat_map<std::string, base::FilePath>& url_to_file_path_map);
+
   // Used as the callback of decoding wallpapers of type
   // `WallpaperType::kOnline`. Saves the image to local file if `save_file` is
   // true, and shows the wallpaper immediately if `params.account_id` is the
@@ -524,13 +533,13 @@
                           bool show_wallpaper,
                           const gfx::ImageSkia& image);
 
-  // Reloads the current wallpaper. It may change the wallpaper size based on
-  // the current display's resolution. If |clear_cache| is true, all wallpaper
-  // cache should be cleared. This is required when the display's native
-  // resolution changes to a larger resolution (e.g. when hooked up a large
-  // external display) and we need to load a larger resolution wallpaper for the
-  // display. All the previous small resolution wallpaper cache should be
-  // cleared.
+  // Reloads the current wallpaper. It may change the wallpaper size based
+  // on the current display's resolution. If |clear_cache| is true, all
+  // wallpaper cache should be cleared. This is required when the display's
+  // native resolution changes to a larger resolution (e.g. when hooked up a
+  // large external display) and we need to load a larger resolution
+  // wallpaper for the display. All the previous small resolution wallpaper
+  // cache should be cleared.
   void ReloadWallpaper(bool clear_cache);
 
   // Sets |prominent_colors_| and notifies the observers if there is a change.
@@ -604,6 +613,19 @@
   void OnAttemptSetOnlineWallpaper(const OnlineWallpaperParams& params,
                                    SetOnlineWallpaperCallback callback,
                                    bool success);
+
+  // Save the downloaded |params.variants| at |current_index|.
+  void OnOnlineWallpaperVariantDownloaded(const OnlineWallpaperParams& params,
+                                          base::RepeatingClosure on_done,
+                                          size_t current_index,
+                                          const gfx::ImageSkia& image);
+
+  // Check that all variants are downloaded successfully and set the wallpaper
+  // from |params.url|.
+  void OnAllOnlineWallpaperVariantsDownloaded(
+      const OnlineWallpaperParams& params,
+      SetOnlineWallpaperCallback callback);
+
   constexpr bool IsWallpaperTypeSyncable(WallpaperType type);
 
   // If daily refresh wallpapers is enabled by the user.
@@ -742,6 +764,10 @@
 
   base::FilePathWatcher drive_fs_wallpaper_watcher_;
 
+  // Used to capture wallpaper variants' url to their corresponding image.
+  // Cleared every time downloading wallpapers is initiated.
+  base::flat_map<std::string, gfx::ImageSkia> url_to_image_map_;
+
   // If true, use a solid color wallpaper as if it is the decoded image.
   bool bypass_decode_for_testing_ = false;
 
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index 6002158..18d4934e 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -16,6 +16,7 @@
 #include "ash/public/cpp/test/shell_test_api.h"
 #include "ash/public/cpp/test/test_image_downloader.h"
 #include "ash/public/cpp/wallpaper/online_wallpaper_params.h"
+#include "ash/public/cpp/wallpaper/online_wallpaper_variant.h"
 #include "ash/public/cpp/wallpaper/wallpaper_controller_client.h"
 #include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h"
 #include "ash/public/cpp/wallpaper/wallpaper_types.h"
@@ -28,6 +29,7 @@
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer.h"
 #include "ash/wallpaper/wallpaper_view.h"
 #include "ash/wallpaper/wallpaper_widget_controller.h"
+#include "ash/webui/personalization_app/proto/backdrop_wallpaper.pb.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/window_cycle/window_cycle_controller.h"
 #include "ash/wm/window_state.h"
@@ -3225,7 +3227,9 @@
 
   void SetUp() override {
     scoped_feature_list_.InitWithFeatures(
-        {features::kWallpaperWebUI, features::kWallpaperFullScreenPreview}, {});
+        {features::kWallpaperWebUI, features::kWallpaperFullScreenPreview,
+         features::kDarkLightMode},
+        {});
     WallpaperControllerTestBase::SetUp();
   }
 
@@ -3817,12 +3821,14 @@
 
   auto run_loop = std::make_unique<base::RunLoop>();
   ClearWallpaperCount();
+  std::vector<OnlineWallpaperVariant> variants;
+  variants.emplace_back(OnlineWallpaperVariant(
+      kAssetId.value(), GURL(kDummyUrl), backdrop::Image::IMAGE_TYPE_UNKNOWN));
   controller_->SetOnlineWallpaper(
       OnlineWallpaperParams(account_id_1, kAssetId, GURL(kDummyUrl),
                             kDummyCollectionId, WALLPAPER_LAYOUT_CENTER_CROPPED,
                             /*preview_mode=*/false, /*from_user=*/true,
-                            /*daily_refresh_enabled=*/false,
-                            /*variants=*/std::vector<OnlineWallpaperVariant>()),
+                            /*daily_refresh_enabled=*/false, variants),
       base::BindLambdaForTesting([&run_loop](bool success) {
         EXPECT_TRUE(success);
         run_loop->Quit();
@@ -3835,4 +3841,81 @@
   RunAllTasksUntilIdle();
   EXPECT_EQ(2, GetWallpaperCount());
 }
+
+TEST_F(WallpaperControllerWallpaperWebUiTest, SetOnlineWallpaperIfExists) {
+  SetBypassDecode();
+  gfx::ImageSkia image = CreateImage(640, 480, kWallpaperColor);
+  WallpaperLayout layout = WALLPAPER_LAYOUT_CENTER_CROPPED;
+  std::vector<OnlineWallpaperVariant> variants;
+  variants.emplace_back(OnlineWallpaperVariant(
+      kAssetId.value(), GURL(kDummyUrl), backdrop::Image::IMAGE_TYPE_UNKNOWN));
+  SimulateUserLogin(account_id_1);
+
+  // Verify that calling |SetOnlineWallpaperIfExists| without providing image
+  // data fails.
+  std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
+  ClearWallpaperCount();
+  controller_->SetOnlineWallpaperIfExists(
+      OnlineWallpaperParams(account_id_1, kAssetId, GURL(kDummyUrl),
+                            kDummyCollectionId, layout,
+                            /*preview_mode=*/false, /*from_user=*/true,
+                            /*daily_refresh_enabled=*/false, variants),
+      base::BindLambdaForTesting([&run_loop](bool file_exists) {
+        EXPECT_FALSE(file_exists);
+        run_loop->Quit();
+      }));
+  run_loop->Run();
+  EXPECT_EQ(0, GetWallpaperCount());
+
+  // Set an online wallpaper with image data. Verify that the wallpaper is set
+  // successfully.
+  ClearWallpaperCount();
+  controller_->SetOnlineWallpaperFromData(
+      OnlineWallpaperParams(account_id_1, /*asset_id=*/absl::nullopt,
+                            GURL(kDummyUrl),
+                            /*collection_id=*/std::string(), layout,
+                            /*preview_mode=*/false, /*from_user=*/false,
+                            /*daily_refresh_enabled=*/false, variants),
+      /*image_data=*/std::string(),
+      WallpaperControllerImpl::SetOnlineWallpaperCallback());
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kOnline);
+  // Verify that the user wallpaper info is updated.
+  WallpaperInfo wallpaper_info;
+  EXPECT_TRUE(controller_->GetUserWallpaperInfo(account_id_1, &wallpaper_info));
+  WallpaperInfo expected_wallpaper_info(kDummyUrl, layout,
+                                        WallpaperType::kOnline,
+                                        base::Time::Now().LocalMidnight());
+  EXPECT_EQ(wallpaper_info, expected_wallpaper_info);
+
+  // Change the on-screen wallpaper to a different one. (Otherwise the
+  // subsequent calls will be no-op since we intentionally prevent reloading the
+  // same wallpaper.)
+  ClearWallpaperCount();
+  controller_->SetCustomWallpaper(account_id_1, file_name_1, layout,
+                                  CreateImage(640, 480, kWallpaperColor),
+                                  /*preview_mode=*/false);
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kCustomized);
+
+  // Attempt to set an online wallpaper via |SetOnlineWallpaperIfExists| without
+  // providing the image data. Verify it succeeds this time because
+  // |SetOnlineWallpaperFromData| has saved the file.
+  ClearWallpaperCount();
+  run_loop = std::make_unique<base::RunLoop>();
+  controller_->SetOnlineWallpaperIfExists(
+      OnlineWallpaperParams(account_id_1, kAssetId, GURL(kDummyUrl),
+                            kDummyCollectionId, layout,
+                            /*preview_mode=*/false, /*from_user=*/true,
+                            /*daily_refresh_enabled=*/false, variants),
+      base::BindLambdaForTesting([&run_loop](bool file_exists) {
+        EXPECT_TRUE(file_exists);
+        run_loop->Quit();
+      }));
+  run_loop->Run();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), WallpaperType::kOnline);
+}
 }  // namespace ash
diff --git a/ash/webui/shimless_rma/resources/BUILD.gn b/ash/webui/shimless_rma/resources/BUILD.gn
index f9eeec9..49bb48c4 100644
--- a/ash/webui/shimless_rma/resources/BUILD.gn
+++ b/ash/webui/shimless_rma/resources/BUILD.gn
@@ -19,7 +19,6 @@
   "base_page.js",
   "calibration_component_chip.js",
   "icons.js",
-  "critical_error_page.js",
   "onboarding_choose_destination_page.js",
   "onboarding_choose_wp_disable_method_page.js",
   "onboarding_enter_rsu_wp_disable_code_page.js",
@@ -76,7 +75,6 @@
   deps = [
     ":base_page",
     ":calibration_component_chip",
-    ":critical_error_page",
     ":fake_shimless_rma_service",
     ":mojo_interface_provider",
     ":onboarding_choose_destination_page",
@@ -107,7 +105,6 @@
 
 js_library("shimless_rma") {
   deps = [
-    ":critical_error_page",
     ":mojo_interface_provider",
     ":onboarding_choose_destination_page",
     ":onboarding_choose_wp_disable_method_page",
@@ -147,16 +144,6 @@
   ]
 }
 
-js_library("critical_error_page") {
-  deps = [
-    ":base_page",
-    ":mojo_interface_provider",
-    ":shimless_rma_types",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-    "//ui/webui/resources/js:i18n_behavior.m",
-  ]
-}
-
 js_library("data") {
   deps = [
     ":shimless_rma_types",
diff --git a/ash/webui/shimless_rma/resources/critical_error_page.html b/ash/webui/shimless_rma/resources/critical_error_page.html
deleted file mode 100644
index ac68857..0000000
--- a/ash/webui/shimless_rma/resources/critical_error_page.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<style include="cr-shared-style shimless-rma-shared">
-  .large-icon {
-    height: 200px;
-    width: 300px;
-  }
-
-  .small-icon {
-    height: 20px;
-    width: 20px;
-  }
-</style>
-<base-page orientation="column">
-  <div slot="header">
-    <h1>[[i18n('criticalErrorTitleText')]]</h1>
-    <div id="writeProtectStatus">[[statusString_]]</div>
-    <cr-button id="exitToLoginButton" on-click="onExitToLoginButtonClicked_">
-        [[i18n('criticalErrorExitToLoginText')]]
-    </cr-button>
-    <cr-button id="performUpdateButton" on-click="onRebootButtonClicked_">
-        [[i18n('criticalErrorRebootText')]]
-      <iron-icon id="restartIcon" icon="shimless-icon:update"
-          class="small-icon">
-      </iron-icon>
-    </cr-button>
-  </div>
-  <div slot="body">
-    <!-- TODO(gavindodd): Replace with correct graphic -->
-    <iron-icon icon="shimless:shimless-placeholder" class="large-icon">
-    </iron-icon>
-  </div>
-</base-page>
diff --git a/ash/webui/shimless_rma/resources/critical_error_page.js b/ash/webui/shimless_rma/resources/critical_error_page.js
deleted file mode 100644
index dabe91fa6..0000000
--- a/ash/webui/shimless_rma/resources/critical_error_page.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import './base_page.js';
-import './shimless_rma_shared_css.js';
-import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {getShimlessRmaService} from './mojo_interface_provider.js';
-import {ShimlessRmaServiceInterface} from './shimless_rma_types.js';
-
-/**
- * @fileoverview
- * 'critical-error-page' is displayed when an unexpected error blocks RMA from
- * continuing.
- */
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- */
-const CriticalErrorPageBase = mixinBehaviors([I18nBehavior], PolymerElement);
-
-/** @polymer */
-export class CriticalErrorPage extends CriticalErrorPageBase {
-  static get is() {
-    return 'critical-error-page';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  constructor() {
-    super();
-    /** @private {ShimlessRmaServiceInterface} */
-    this.shimlessRmaService_ = getShimlessRmaService();
-  }
-
-  /** @protected */
-  onExitToLoginButtonClicked_() {
-    this.shimlessRmaService_.criticalErrorExitToLogin();
-  }
-
-  /** @protected */
-  onRebootButtonClicked_() {
-    this.shimlessRmaService_.criticalErrorReboot();
-  }
-}
-
-customElements.define(CriticalErrorPage.is, CriticalErrorPage);
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js
index 7686851..47113f4 100644
--- a/ash/webui/shimless_rma/resources/shimless_rma.js
+++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import './critical_error_page.js';
 import './onboarding_choose_destination_page.js';
 import './onboarding_choose_wp_disable_method_page.js';
 import './onboarding_enter_rsu_wp_disable_code_page.js';
@@ -59,9 +58,8 @@
  * @type {!Object<!State, !PageInfo>}
  */
 const StateComponentMapping = {
-  // It is assumed that if state is kUnknown the error is kRmaNotRequired.
   [State.kUnknown]: {
-    componentIs: 'critical-error-page',
+    componentIs: 'badcomponent',
     requiresReloadWhenShown: false,
     buttonNext: ButtonState.HIDDEN,
     buttonCancel: ButtonState.HIDDEN,
@@ -366,34 +364,23 @@
    * @param {!StateResult} stateResult
    */
   processStateResult_(stateResult) {
-    // Do not show the state screen if the critical error screen was shown.
-    if (this.handleStandardAndCriticalError_(stateResult.error)) {
-      return;
-    }
+    this.handleError_(stateResult.error);
     this.showState_(
         stateResult.state, stateResult.canCancel, stateResult.canGoBack);
   }
 
   /** @param {!RmadErrorCode} error */
   onError(error) {
-    this.handleStandardAndCriticalError_(error);
+    this.handleError_(error);
   }
 
   /**
    * @private
    * @param {!RmadErrorCode} error
-   * @return {boolean}
-   * Returns true if the critical error screen was displayed.
    */
-  handleStandardAndCriticalError_(error) {
-    // Critical error - expected to be in RMA.
-    if (error === RmadErrorCode.kRmaNotRequired) {
-      this.showState_(State.kUnknown, false, false);
-      return true;
-    }
+  handleError_(error) {
     // TODO(gavindodd): Handle error appropriately
     this.errorMessage_ = rmadErrorString(error);
-    return false;
   }
 
   /**
@@ -520,7 +507,7 @@
   onCancelButtonClicked_() {
     this.allButtonsDisabled_ = true;
     this.shimlessRmaService_.abortRma().then(
-        (result) => this.handleStandardAndCriticalError_(result.error));
+        (result) => this.handleError_(result.error));
   }
 
   /**
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc
index 82ddb0f6..29f293e 100644
--- a/ash/webui/shimless_rma/shimless_rma.cc
+++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -289,12 +289,6 @@
       {"onboardingUpdateDisabled", IDS_SHIMLESS_RMA_ONBOARDING_UPDATE_DISABLED},
       {"onboardingUpdatePermission",
        IDS_SHIMLESS_RMA_ONBOARDING_UPDATE_PERMISSION},
-      // Critical error
-      {"criticalErrorTitleText", IDS_SHIMLESS_RMA_CRITICAL_ERROR_TITLE},
-      {"criticalErrorMessageText", IDS_SHIMLESS_RMA_CRITICAL_ERROR_MESSAGE},
-      {"criticalErrorExitToLoginText",
-       IDS_SHIMLESS_RMA_CRITICAL_EXIT_TO_LOGIN_BUTTON},
-      {"criticalErrorRebootText", IDS_SHIMLESS_RMA_CRITICAL_REBOOT_BUTTON},
   };
 
   html_source->AddLocalizedStrings(kLocalizedStrings);
diff --git a/ash/wm/desks/templates/desks_templates_grid_view.cc b/ash/wm/desks/templates/desks_templates_grid_view.cc
index 31965a1..20b2396 100644
--- a/ash/wm/desks/templates/desks_templates_grid_view.cc
+++ b/ash/wm/desks/templates/desks_templates_grid_view.cc
@@ -179,6 +179,7 @@
   switch (event->type()) {
     case ui::ET_MOUSE_MOVED:
     case ui::ET_MOUSE_ENTERED:
+    case ui::ET_MOUSE_RELEASED:
     case ui::ET_MOUSE_EXITED:
     case ui::ET_GESTURE_LONG_PRESS:
     case ui::ET_GESTURE_LONG_TAP: {
diff --git a/ash/wm/desks/templates/desks_templates_unittest.cc b/ash/wm/desks/templates/desks_templates_unittest.cc
index 2d2bebb..047a18e 100644
--- a/ash/wm/desks/templates/desks_templates_unittest.cc
+++ b/ash/wm/desks/templates/desks_templates_unittest.cc
@@ -1219,6 +1219,17 @@
   event_generator->MoveMouseTo(first_item->GetBoundsInScreen().CenterPoint());
   EXPECT_TRUE(hover_container_view1->GetVisible());
   EXPECT_FALSE(hover_container_view2->GetVisible());
+
+  // Test to make sure hover is updated after dragging to another item.
+  event_generator->DragMouseTo(second_item->GetBoundsInScreen().CenterPoint());
+  EXPECT_FALSE(hover_container_view1->GetVisible());
+  EXPECT_TRUE(hover_container_view2->GetVisible());
+
+  // Test to make sure hover is hidden on all items when dragging to off the
+  // grid.
+  event_generator->DragMouseTo(gfx::Point(0, 0));
+  EXPECT_FALSE(hover_container_view1->GetVisible());
+  EXPECT_FALSE(hover_container_view2->GetVisible());
 }
 
 // Tests that when a supported app doesn't have any app launch info and a
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc
index 4a60078..aae060c7 100644
--- a/ash/wm/overview/overview_session.cc
+++ b/ash/wm/overview/overview_session.cc
@@ -8,6 +8,7 @@
 #include <functional>
 #include <utility>
 
+#include "ash/accelerators/debug_commands.h"
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/app_list/app_list_controller_impl.h"
 #include "ash/metrics/user_metrics_recorder.h"
@@ -25,6 +26,7 @@
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_bubble.h"
 #include "ash/wm/desks/desk.h"
+#include "ash/wm/desks/desks_bar_view.h"
 #include "ash/wm/desks/desks_controller.h"
 #include "ash/wm/desks/desks_util.h"
 #include "ash/wm/desks/templates/desks_templates_dialog_controller.h"
@@ -1075,6 +1077,21 @@
         Move(/*reverse=*/true);
       }
       break;
+    case ui::VKEY_T: {
+      // This is a debug only shortcut.
+      if (!debug::DeveloperAcceleratorsEnabled() ||
+          !desks_templates_util::AreDesksTemplatesEnabled()) {
+        return;
+      }
+
+      // There are no templates to be viewed.
+      if (!DesksTemplatesPresenter::Get()->should_show_templates_ui())
+        return;
+
+      DCHECK(!grid_list_.empty());
+      ShowDesksTemplatesGrids(grid_list_[0]->desks_bar_view()->IsZeroState());
+      break;
+    }
     case ui::VKEY_W: {
       if (!(event->flags() & ui::EF_CONTROL_DOWN))
         return;
diff --git a/base/allocator/partition_allocator/partition_alloc_config.h b/base/allocator/partition_allocator/partition_alloc_config.h
index 8fe720e8..e41d565 100644
--- a/base/allocator/partition_allocator/partition_alloc_config.h
+++ b/base/allocator/partition_allocator/partition_alloc_config.h
@@ -137,23 +137,14 @@
 // https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2492?view=msvc-160.
 // Don't use it there.
 //
-// On macOS and iOS with PartitionAlloc-Everywhere enabled, thread_local
-// allocates memory and it causes an infinite loop of ThreadCache::Get() ->
-// malloc_zone_malloc -> ShimMalloc -> ThreadCache::Get() -> ...
-// Exact stack trace is:
-//   libsystem_malloc.dylib`_malloc_zone_malloc
-//   libdyld.dylib`tlv_allocate_and_initialize_for_key
-//   libdyld.dylib`tlv_get_addr
-//   libbase.dylib`thread-local wrapper routine for
-//       base::internal::g_thread_cache
-//   libbase.dylib`base::internal::ThreadCache::Get()
-// where tlv_allocate_and_initialize_for_key performs memory allocation.
+// On macOS and iOS:
+// - With PartitionAlloc-Everywhere, thread_local allocates, reentering the
+//   allocator.
+// - Component builds triggered a clang bug: crbug.com/1243375
 //
-// Finally, we have crashes with component builds on macOS,
-// see crbug.com/1243375.
-#if !(defined(OS_WIN) && defined(COMPONENT_BUILD)) && \
-    !(defined(OS_APPLE) &&                            \
-      (BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) || defined(COMPONENT_BUILD)))
+// Regardless, the "normal" TLS access is fast on x86_64 (see partition_tls.h),
+// so don't bother with thread_local anywhere.
+#if !(defined(OS_WIN) && defined(COMPONENT_BUILD)) && !defined(OS_APPLE)
 #define PA_THREAD_LOCAL_TLS
 #endif
 
diff --git a/base/memory/raw_ptr.h b/base/memory/raw_ptr.h
index faf3c260..28fb395a 100644
--- a/base/memory/raw_ptr.h
+++ b/base/memory/raw_ptr.h
@@ -381,7 +381,7 @@
 #else
           typename Impl = internal::RawPtrNoOpImpl>
 #endif
-class raw_ptr {
+class TRIVIAL_ABI raw_ptr {
  public:
   static_assert(raw_ptr_traits::IsSupportedType<T>::value,
                 "raw_ptr<T> doesn't work with this kind of pointee type T");
diff --git a/base/sampling_heap_profiler/sampling_heap_profiler.cc b/base/sampling_heap_profiler/sampling_heap_profiler.cc
index a7109b8e..1fb57898 100644
--- a/base/sampling_heap_profiler/sampling_heap_profiler.cc
+++ b/base/sampling_heap_profiler/sampling_heap_profiler.cc
@@ -81,6 +81,18 @@
   return thread_name;
 }
 
+#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
+    defined(OFFICIAL_BUILD)
+// Checks whether unwinding from this function works.
+bool HasDefaultUnwindTables() {
+  void* stack[kMaxStackEntries];
+  size_t frame_count = base::debug::CollectStackTrace(const_cast<void**>(stack),
+                                                      kMaxStackEntries);
+  // First frame is the current function and can be found without unwind tables.
+  return frame_count > 1;
+}
+#endif
+
 }  // namespace
 
 SamplingHeapProfiler::Sample::Sample(size_t size,
@@ -102,8 +114,13 @@
     defined(OFFICIAL_BUILD)
   if (!trace_event::CFIBacktraceAndroid::GetInitializedInstance()
            ->can_unwind_stack_frames()) {
-    LOG(WARNING) << "Sampling heap profiler: Stack unwinding is not available.";
-    return 0;
+    if (HasDefaultUnwindTables()) {
+      use_default_unwinder_ = true;
+    } else {
+      LOG(WARNING)
+          << "Sampling heap profiler: Stack unwinding is not available.";
+      return 0;
+    }
   }
 #endif
 
@@ -140,7 +157,6 @@
   return UpdateAndGetThreadName(nullptr);
 }
 
-// static
 void** SamplingHeapProfiler::CaptureStackTrace(void** frames,
                                                size_t max_entries,
                                                size_t* count) {
@@ -148,9 +164,15 @@
   size_t skip_frames = 3;
 #if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \
     defined(OFFICIAL_BUILD)
-  size_t frame_count =
-      base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()->Unwind(
-          const_cast<const void**>(frames), max_entries);
+  size_t frame_count = 0;
+  if (use_default_unwinder_) {
+    frame_count =
+        base::debug::CollectStackTrace(const_cast<void**>(frames), max_entries);
+  } else {
+    frame_count =
+        base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()
+            ->Unwind(const_cast<const void**>(frames), max_entries);
+  }
 #elif BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
   size_t frame_count = base::debug::TraceStackFramePointers(
       const_cast<const void**>(frames), max_entries, skip_frames);
diff --git a/base/sampling_heap_profiler/sampling_heap_profiler.h b/base/sampling_heap_profiler/sampling_heap_profiler.h
index 59adbf0..542f235 100644
--- a/base/sampling_heap_profiler/sampling_heap_profiler.h
+++ b/base/sampling_heap_profiler/sampling_heap_profiler.h
@@ -16,6 +16,7 @@
 #include "base/synchronization/lock.h"
 #include "base/thread_annotations.h"
 #include "base/threading/thread_id_name_manager.h"
+#include "build/build_config.h"
 
 namespace heap_profiling {
 class HeapProfilerControllerTest;
@@ -89,9 +90,7 @@
   // Captures up to |max_entries| stack frames using the buffer pointed by
   // |frames|. Puts the number of captured frames into the |count| output
   // parameters. Returns the pointer to the topmost frame.
-  static void** CaptureStackTrace(void** frames,
-                                  size_t max_entries,
-                                  size_t* count);
+  void** CaptureStackTrace(void** frames, size_t max_entries, size_t* count);
 
   static void Init();
   static SamplingHeapProfiler* Get();
@@ -145,6 +144,11 @@
   // Whether it should record thread names.
   std::atomic<bool> record_thread_names_{false};
 
+#if defined(OS_ANDROID)
+  // Whether to use CFI unwinder or default unwinder.
+  std::atomic<bool> use_default_unwinder_{false};
+#endif
+
   friend class heap_profiling::HeapProfilerControllerTest;
   friend class NoDestructor<SamplingHeapProfiler>;
   friend class SamplingHeapProfilerTest;
diff --git a/build/android/pylib/base/output_manager.py b/build/android/pylib/base/output_manager.py
index e471dd1..e0efe19 100644
--- a/build/android/pylib/base/output_manager.py
+++ b/build/android/pylib/base/output_manager.py
@@ -95,7 +95,10 @@
     self._out_subdir = out_subdir
     self._datatype = datatype
 
-    self._f = tempfile.NamedTemporaryFile(delete=False)
+    mode = 'w+'
+    if datatype == Datatype.PNG:
+      mode = 'w+b'
+    self._f = tempfile.NamedTemporaryFile(mode=mode, delete=False)
     self._ready_to_archive = False
 
   @property
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index c5ac8d6..b9a9106 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -1084,7 +1084,7 @@
             test_name=args.command,
             cs_base_url='http://cs.chromium.org',
             local_output=True)
-        results_detail_file.write(result_html_string.encode('utf-8'))
+        results_detail_file.write(result_html_string)
         results_detail_file.flush()
       logging.critical('TEST RESULTS: %s', results_detail_file.Link())
 
diff --git a/build/config/linux/nss/BUILD.gn b/build/config/linux/nss/BUILD.gn
index 8c27938..638b44ef 100644
--- a/build/config/linux/nss/BUILD.gn
+++ b/build/config/linux/nss/BUILD.gn
@@ -5,14 +5,10 @@
 import("//build/config/linux/pkg_config.gni")
 
 if (is_linux || is_chromeos) {
-  # This is a dependency on NSS with no libssl. On Linux we use a built-in SSL
-  # library but the system NSS libraries. Non-Linux platforms using NSS use the
-  # hermetic one in //third_party/nss.
-  #
-  # Generally you should depend on //crypto:platform instead of using this
-  # config since that will properly pick up NSS or OpenSSL depending on
-  # platform and build config.
-  pkg_config("system_nss_no_ssl_config") {
+  # This is a dependency on NSS with no libssl3. On Linux and Chrome OS, we use
+  # NSS for platform certificate integration. We use our own TLS library, so
+  # exclude the one from NSS.
+  pkg_config("nss") {
     packages = [ "nss" ]
     extra_args = [
       "-v",
diff --git a/cc/metrics/dropped_frame_counter.cc b/cc/metrics/dropped_frame_counter.cc
index ab5d56c..047d130 100644
--- a/cc/metrics/dropped_frame_counter.cc
+++ b/cc/metrics/dropped_frame_counter.cc
@@ -197,29 +197,31 @@
   // Don't measure smoothness for frames that start before FCP is received, or
   // that have already been reported as dropped.
   if (is_dropped && fcp_received_ && args.frame_time >= time_fcp_received_ &&
-      !frame_sorter_.IsFrameDropped(args.frame_id)) {
+      !frame_sorter_.IsAlreadyReportedDropped(args.frame_id)) {
     ++total_smoothness_dropped_;
 
     if (report_for_ui_)
       ReportFramesForUI();
     else
       ReportFrames();
-  }
-  auto iter = scroll_start_per_frame_.find(args.frame_id);
-  if (iter != scroll_start_per_frame_.end()) {
-    ScrollStartInfo& scroll_start = iter->second;
-    if (args.frame_id.source_id == scroll_start.frame_id.source_id) {
-      UMA_HISTOGRAM_CUSTOM_TIMES(
-          "Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart.Time",
-          (args.frame_time - scroll_start.timestamp), base::Milliseconds(1),
-          base::Seconds(4), 50);
-      UMA_HISTOGRAM_CUSTOM_COUNTS(
-          "Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart.Frames",
-          (args.frame_id.sequence_number -
-           scroll_start.frame_id.sequence_number),
-          1, 250, 50);
+
+    auto iter = scroll_start_per_frame_.find(args.frame_id);
+    if (iter != scroll_start_per_frame_.end()) {
+      ScrollStartInfo& scroll_start = iter->second;
+      if (args.frame_id.source_id == scroll_start.frame_id.source_id) {
+        UMA_HISTOGRAM_CUSTOM_TIMES(
+            "Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart2.Time",
+            (args.frame_time - scroll_start.timestamp), base::Milliseconds(1),
+            base::Seconds(4), 50);
+        UMA_HISTOGRAM_CUSTOM_COUNTS(
+            "Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart2."
+            "Frames",
+            (args.frame_id.sequence_number -
+             scroll_start.frame_id.sequence_number),
+            1, 250, 50);
+      }
+      scroll_start_per_frame_.erase(iter);
     }
-    scroll_start_per_frame_.erase(iter);
   }
 
   if (fcp_received_)
diff --git a/cc/metrics/frame_sorter.cc b/cc/metrics/frame_sorter.cc
index 91c98d1..2c1bcc8 100644
--- a/cc/metrics/frame_sorter.cc
+++ b/cc/metrics/frame_sorter.cc
@@ -107,7 +107,7 @@
   }
 }
 
-bool FrameSorter::IsFrameDropped(const viz::BeginFrameId& id) const {
+bool FrameSorter::IsAlreadyReportedDropped(const viz::BeginFrameId& id) const {
   auto it = frame_states_.find(id);
   if (it == frame_states_.end())
     return false;
diff --git a/cc/metrics/frame_sorter.h b/cc/metrics/frame_sorter.h
index 9e612765..3feb538ac 100644
--- a/cc/metrics/frame_sorter.h
+++ b/cc/metrics/frame_sorter.h
@@ -56,7 +56,7 @@
   void AddFrameResult(const viz::BeginFrameArgs& args, bool is_dropped);
 
   // Check if a frame has been previously reported as dropped.
-  bool IsFrameDropped(const viz::BeginFrameId& id) const;
+  bool IsAlreadyReportedDropped(const viz::BeginFrameId& id) const;
 
   void Reset();
 
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 4b18631e..7c9dd74 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1742,7 +1742,7 @@
         "javatests/src/org/chromium/chrome/browser/vr/EmulatedVrController.java",
         "javatests/src/org/chromium/chrome/browser/vr/TestVrShellDelegate.java",
         "javatests/src/org/chromium/chrome/browser/vr/VrDaydreamReadyModuleInstallTest.java",
-        "javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateInfoBarTest.java",
+        "javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateMessageTest.java",
         "javatests/src/org/chromium/chrome/browser/vr/WebXrVrDeviceTest.java",
         "javatests/src/org/chromium/chrome/browser/vr/WebXrVrInputTest.java",
         "javatests/src/org/chromium/chrome/browser/vr/WebXrVrPermissionTest.java",
@@ -1761,7 +1761,7 @@
         "javatests/src/org/chromium/chrome/browser/vr/rules/WebappActivityVrTestRule.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/NativeUiUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/RenderTestUtils.java",
-        "javatests/src/org/chromium/chrome/browser/vr/util/VrInfoBarUtils.java",
+        "javatests/src/org/chromium/chrome/browser/vr/util/VrMessageUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/VrShellDelegateUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/VrTestRuleUtils.java",
         "javatests/src/org/chromium/chrome/browser/vr/util/VrTransitionUtils.java",
@@ -1775,6 +1775,9 @@
             "//components/browser_ui/site_settings/android:java",
             "//components/content_settings/android:content_settings_enums_java",
             "//components/infobars/android:java",
+            "//components/messages/android:java",
+            "//components/messages/android/internal:java",
+            "//components/messages/android/test:test_support_java",
             "//chrome/browser/profiles/android:java",
             "//chrome/browser/settings:java",
             "//chrome/browser/tabmodel:java",
diff --git a/chrome/android/features/tab_ui/java/res/layout/price_tracking_dialog_layout.xml b/chrome/android/features/tab_ui/java/res/layout/price_tracking_dialog_layout.xml
index bc516f4..0e01e8b 100644
--- a/chrome/android/features/tab_ui/java/res/layout/price_tracking_dialog_layout.xml
+++ b/chrome/android/features/tab_ui/java/res/layout/price_tracking_dialog_layout.xml
@@ -25,12 +25,14 @@
         android:text="@string/price_tracking_settings"
         android:textAppearance="@style/TextAppearance.Headline.Primary" />
     <LinearLayout
+        android:id="@+id/price_annotations_row_menu_id"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/price_tracking_dialog_items_margin"
         android:layout_marginStart="@dimen/price_tracking_dialog_text_side_margin"
         android:layout_marginEnd="@dimen/price_tracking_dialog_text_side_margin"
-        android:orientation="horizontal">
+        android:orientation="horizontal"
+        android:visibility="gone">
         <ImageView
             android:id="@+id/track_prices_icon"
             android:layout_width="0dp"
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogCoordinator.java
index 457e334..6035489 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogCoordinator.java
@@ -62,7 +62,7 @@
     }
 
     void show() {
-        mDialogView.setupPriceAlertsRowMenuVisibility();
+        mDialogView.setupRowMenuVisibility();
         mDialogView.updateSwitch();
         mModalDialogManager.showDialog(mModel, ModalDialogManager.ModalDialogType.APP);
     }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogView.java
index f1167f6..957dfbe 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogView.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogView.java
@@ -22,6 +22,7 @@
 public class PriceTrackingDialogView extends LinearLayout {
     private SwitchCompat mTrackPricesSwitch;
     private ChromeImageButton mPriceAlertsArrow;
+    private ViewGroup mPriceAnnotationsRowMenu;
     private ViewGroup mPriceAlertsRowMenu;
 
     public PriceTrackingDialogView(Context context, AttributeSet attrs) {
@@ -33,6 +34,7 @@
         super.onFinishInflate();
         mTrackPricesSwitch = (SwitchCompat) findViewById(R.id.track_prices_switch);
         mPriceAlertsArrow = (ChromeImageButton) findViewById(R.id.price_alerts_arrow);
+        mPriceAnnotationsRowMenu = (ViewGroup) findViewById(R.id.price_annotations_row_menu_id);
         mPriceAlertsRowMenu = (ViewGroup) findViewById(R.id.price_alerts_row_menu_id);
     }
 
@@ -60,11 +62,17 @@
     }
 
     /**
-     * Set visibility of the price alerts row menu.
+     * Set visibility of each row menu.
      */
-    void setupPriceAlertsRowMenuVisibility() {
+    void setupRowMenuVisibility() {
+        mPriceAnnotationsRowMenu.setVisibility(
+                PriceTrackingUtilities.allowUsersToDisablePriceAnnotations() ? View.VISIBLE
+                                                                             : View.GONE);
         mPriceAlertsRowMenu.setVisibility(PriceTrackingUtilities.isPriceDropNotificationEligible()
                         ? View.VISIBLE
                         : View.GONE);
+        // At least one row should be visible.
+        assert mPriceAnnotationsRowMenu.getVisibility() == View.VISIBLE
+                || mPriceAlertsRowMenu.getVisibility() == View.VISIBLE;
     }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingUtilities.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingUtilities.java
index ee68d31..ac6d256 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingUtilities.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingUtilities.java
@@ -19,6 +19,8 @@
 import org.chromium.components.signin.identitymanager.ConsentLevel;
 import org.chromium.components.sync.ModelType;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * A class to handle price tracking-related features.
  */
@@ -28,6 +30,9 @@
     @VisibleForTesting
     public static final String PRICE_NOTIFICATION_PARAM = "enable_price_notification";
     @VisibleForTesting
+    public static final String ALLOW_DISABLE_PRICE_ANNOTATIONS_PARAM =
+            "allow_disable_price_annotations";
+    @VisibleForTesting
     public static final String TRACK_PRICES_ON_TABS =
             ChromePreferenceKeys.PRICE_TRACKING_TRACK_PRICES_ON_TABS;
     @VisibleForTesting
@@ -42,6 +47,8 @@
     @VisibleForTesting
     public static final String PRICE_ALERTS_MESSAGE_CARD_SHOW_COUNT =
             ChromePreferenceKeys.PRICE_TRACKING_PRICE_ALERTS_MESSAGE_CARD_SHOW_COUNT;
+    private static final String PRICE_ANNOTATIONS_ENABLED_METRICS_WINDOW_DURATION_PARAM =
+            "price_annotations_enabled_metrics_window_duration_ms";
 
     @VisibleForTesting
     public static final SharedPreferencesManager SHARED_PREFERENCES_MANAGER =
@@ -227,4 +234,40 @@
         // Incognito Tabs are not eligible for price tracking.
         return !tabModel.getProfile().isOffTheRecord();
     }
+
+    /**
+     * @return how frequent we want to record metrics on whether user enables the price tracking
+     *         annotations.
+     */
+    public static int getAnnotationsEnabledMetricsWindowDurationMilliSeconds() {
+        int defaultDuration = (int) TimeUnit.DAYS.toMillis(1);
+        if (FeatureList.isInitialized()) {
+            return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
+                    ChromeFeatureList.COMMERCE_PRICE_TRACKING,
+                    PRICE_ANNOTATIONS_ENABLED_METRICS_WINDOW_DURATION_PARAM, defaultDuration);
+        }
+        return defaultDuration;
+    }
+
+    /**
+     * @return whether we allow users to disable the price annotations feature.
+     */
+    public static boolean allowUsersToDisablePriceAnnotations() {
+        if (FeatureList.isInitialized()) {
+            return isPriceTrackingEnabled()
+                    && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
+                            ChromeFeatureList.COMMERCE_PRICE_TRACKING,
+                            ALLOW_DISABLE_PRICE_ANNOTATIONS_PARAM, true);
+        }
+        return isPriceTrackingEnabled();
+    }
+
+    /**
+     * @return whether we should show the PriceTrackingSettings menu item in grid tab switcher.
+     */
+    public static boolean shouldShowPriceTrackingMenu() {
+        return isPriceTrackingEligible()
+                && (allowUsersToDisablePriceAnnotations()
+                        || getPriceTrackingNotificationsEnabled());
+    }
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java
index e82dbaa..5ccd660 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMenuCoordinator.java
@@ -8,7 +8,6 @@
 import android.content.ComponentCallbacks;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.graphics.Rect;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ListView;
@@ -104,14 +103,6 @@
 
         View decorView = ((Activity) contentView.getContext()).getWindow().getDecorView();
         ViewRectProvider rectProvider = new ViewRectProvider(anchorView);
-        Rect rect = new Rect();
-        decorView.getWindowVisibleDisplayFrame(rect);
-        int statusBarHeight = rect.top;
-        // Move the rect down by statusBarHeight because we are positioning the rect within the
-        // TabGridDialog popup window which doesn't include status bar. However, we are showing it
-        // in the root decor view which includes the status bar. Thus, adding status bar height as a
-        // offset.
-        rectProvider.setInsetPx(0, statusBarHeight, 0, statusBarHeight);
 
         mMenuWindow = new AnchoredPopupWindow(mContext, decorView,
                 ApiCompatibilityUtils.getDrawable(
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
index 2f2e9eae..ad55ec2 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -39,6 +39,8 @@
 import org.chromium.base.task.PostTask;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
@@ -1132,6 +1134,9 @@
             Collections.sort(tabsList, LAST_SHOWN_COMPARATOR);
         }
         mVisible = tabsList != null;
+        if (tabs != null) {
+            recordPriceAnnotationsEnabledMetrics();
+        }
         if (areTabsUnchanged(tabsList)) {
             if (tabsList == null) return true;
             for (int i = 0; i < tabsList.size(); i++) {
@@ -1899,4 +1904,26 @@
     private boolean isShowingTabsInMRUOrder() {
         return TabSwitcherCoordinator.isShowingTabsInMRUOrder(mMode);
     }
+
+    @VisibleForTesting
+    void recordPriceAnnotationsEnabledMetrics() {
+        if (mMode != TabListMode.GRID || !mActionsOnAllRelatedTabs
+                || !PriceTrackingUtilities.isPriceTrackingEligible()) {
+            return;
+        }
+        SharedPreferencesManager preferencesManager = SharedPreferencesManager.getInstance();
+        if (System.currentTimeMillis()
+                        - preferencesManager.readLong(
+                                ChromePreferenceKeys
+                                        .PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP,
+                                -1)
+                >= PriceTrackingUtilities
+                           .getAnnotationsEnabledMetricsWindowDurationMilliSeconds()) {
+            RecordHistogram.recordBooleanHistogram("Commerce.PriceDrop.AnnotationsEnabled",
+                    PriceTrackingUtilities.isTrackPricesOnTabsEnabled());
+            preferencesManager.writeLong(
+                    ChromePreferenceKeys.PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP,
+                    System.currentTimeMillis());
+        }
+    }
 }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogTest.java
index 83be042..7af160b8 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/PriceTrackingDialogTest.java
@@ -76,7 +76,8 @@
 public class PriceTrackingDialogTest {
     // clang-format on
     private static final String BASE_PARAMS =
-            "force-fieldtrial-params=Study.Group:enable_price_tracking/true";
+            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+            + "/allow_disable_price_annotations/true";
     private static final String ACTION_APP_NOTIFICATION_SETTINGS =
             "android.settings.APP_NOTIFICATION_SETTINGS";
     private static final int RENDER_TEST_REVISION = 1;
@@ -118,7 +119,7 @@
 
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, false);
+        verifyDialogShowing(cta, true, false);
 
         // Press back should dismiss the dialog.
         pressBack();
@@ -127,7 +128,7 @@
         // Open the price tracking dialog.
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, false);
+        verifyDialogShowing(cta, true, false);
 
         // Click outside of the dialog area to close the Price tracking dialog.
         View dialogView = mModalDialogManager.getCurrentDialogForTest().get(
@@ -149,7 +150,7 @@
 
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, false);
+        verifyDialogShowing(cta, true, false);
 
         onView(withId(R.id.track_prices_switch)).check(matches(isChecked()));
         assertTrue(PriceTrackingUtilities.isTrackPricesOnTabsEnabled());
@@ -169,7 +170,7 @@
 
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, true);
+        verifyDialogShowing(cta, true, true);
         onView(withId(R.id.price_alerts_row_menu_id)).check(matches(isDisplayed()));
         onView(withId(R.id.price_alerts_arrow)).perform(click());
 
@@ -182,6 +183,19 @@
 
     @Test
     @MediumTest
+    @CommandLineFlags.Add({"force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+            + "/allow_disable_price_annotations/false/enable_price_notification/true"})
+    public void
+    testPriceAnnotationsRowMenuVisibility_ParameterDisabled() {
+        final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+
+        MenuUtils.invokeCustomMenuActionSync(
+                InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
+        verifyDialogShowing(cta, false, true);
+    }
+
+    @Test
+    @MediumTest
     @CommandLineFlags.Add({BASE_PARAMS + "/enable_price_notification/true"})
     public void testPriceAlertsRowMenuVisibility() {
         final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
@@ -190,7 +204,7 @@
         PriceTrackingUtilities.setIsSignedInAndSyncEnabledForTesting(false);
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, false);
+        verifyDialogShowing(cta, true, false);
 
         pressBack();
         verifyDialogHiding(cta);
@@ -199,7 +213,7 @@
         PriceTrackingUtilities.setIsSignedInAndSyncEnabledForTesting(true);
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, true);
+        verifyDialogShowing(cta, true, true);
     }
 
     @Test
@@ -211,7 +225,7 @@
 
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, true);
+        verifyDialogShowing(cta, true, true);
 
         View priceTrackingDialogView = mModalDialogManager.getCurrentDialogForTest().get(
                 ModalDialogProperties.CUSTOM_VIEW);
@@ -229,15 +243,15 @@
         ActivityTestUtils.rotateActivityToOrientation(cta, Configuration.ORIENTATION_LANDSCAPE);
         MenuUtils.invokeCustomMenuActionSync(
                 InstrumentationRegistry.getInstrumentation(), cta, R.id.track_prices_row_menu_id);
-        verifyDialogShowing(cta, true);
+        verifyDialogShowing(cta, true, true);
 
         View priceTrackingDialogView = mModalDialogManager.getCurrentDialogForTest().get(
                 ModalDialogProperties.CUSTOM_VIEW);
         mRenderTestRule.render(priceTrackingDialogView, "price_tracking_dialog_landscape");
     }
 
-    private void verifyDialogShowing(
-            ChromeTabbedActivity cta, boolean isPriceAlertsRowMenuVisible) {
+    private void verifyDialogShowing(ChromeTabbedActivity cta,
+            boolean isPriceAnnotationsRowMenuVisible, boolean isPriceAlertsRowMenuVisible) {
         // Verify price tracking dialog view.
         onView(withId(R.id.price_tracking_dialog))
                 .inRoot(withDecorView(not(cta.getWindow().getDecorView())))
@@ -263,15 +277,13 @@
                     assertEquals(priceAlertsDescription,
                             ((TextView) v.findViewById(R.id.price_alerts_description)).getText());
 
-                    if (isPriceAlertsRowMenuVisible) {
-                        assertEquals(View.VISIBLE,
-                                ((ViewGroup) v.findViewById(R.id.price_alerts_row_menu_id))
-                                        .getVisibility());
-                    } else {
-                        assertEquals(View.GONE,
-                                ((ViewGroup) v.findViewById(R.id.price_alerts_row_menu_id))
-                                        .getVisibility());
-                    }
+                    assertEquals(isPriceAnnotationsRowMenuVisible ? View.VISIBLE : View.GONE,
+                            ((ViewGroup) v.findViewById(R.id.price_annotations_row_menu_id))
+                                    .getVisibility());
+
+                    assertEquals(isPriceAlertsRowMenuVisible ? View.VISIBLE : View.GONE,
+                            ((ViewGroup) v.findViewById(R.id.price_alerts_row_menu_id))
+                                    .getVisibility());
                 });
     }
 
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
index 72f41fc..0be4ea6 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -87,6 +87,8 @@
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.FeatureList;
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.build.BuildConfig;
@@ -101,6 +103,8 @@
 import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridge;
 import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridge.OptimizationGuideCallback;
 import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridgeJni;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
 import org.chromium.chrome.browser.tab.MockTab;
@@ -158,13 +162,14 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 /**
  * Tests for {@link TabListMediator}.
  */
 @SuppressWarnings(
         {"ArraysAsListWithZeroOrOneArgument", "ResultOfMethodCallIgnored", "ConstantConditions"})
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
+@Config(manifest = Config.NONE, shadows = {ShadowRecordHistogram.class})
 // clang-format off
 @Features.EnableFeatures(ChromeFeatureList.TAB_TO_GTS_ANIMATION)
 @Features.DisableFeatures({
@@ -2977,6 +2982,35 @@
         TabUiFeatureUtilities.ENABLE_LAUNCH_POLISH.setForTesting(false);
     }
 
+    @Test
+    public void testRecordPriceAnnotationsEnabledMetrics() {
+        ShadowRecordHistogram.reset();
+        setPriceTrackingEnabledForTesting(true);
+        PriceTrackingUtilities.setIsSignedInAndSyncEnabledForTesting(true);
+        mMediator.setActionOnAllRelatedTabsForTesting(true);
+        String histogramName = "Commerce.PriceDrop.AnnotationsEnabled";
+
+        SharedPreferencesManager preferencesManager = SharedPreferencesManager.getInstance();
+        long presetTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
+        preferencesManager.writeLong(
+                ChromePreferenceKeys.PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP,
+                presetTime);
+        mMediator.recordPriceAnnotationsEnabledMetrics();
+        assertThat(RecordHistogram.getHistogramTotalCountForTesting(histogramName), equalTo(1));
+        long updatedTime = preferencesManager.readLong(
+                ChromePreferenceKeys.PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP,
+                presetTime);
+        assertNotEquals(presetTime, updatedTime);
+
+        // This metrics should only be recorded once within one day.
+        mMediator.recordPriceAnnotationsEnabledMetrics();
+        assertThat(RecordHistogram.getHistogramTotalCountForTesting(histogramName), equalTo(1));
+        assertEquals(updatedTime,
+                preferencesManager.readLong(
+                        ChromePreferenceKeys.PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP,
+                        -1));
+    }
+
     private void setUpCloseButtonDescriptionString(boolean isGroup) {
         if (isGroup) {
             doAnswer(invocation -> {
diff --git a/chrome/android/features/vr/BUILD.gn b/chrome/android/features/vr/BUILD.gn
index ee2523d..8961852f 100644
--- a/chrome/android/features/vr/BUILD.gn
+++ b/chrome/android/features/vr/BUILD.gn
@@ -89,6 +89,7 @@
     "//components/embedder_support/android:content_view_java",
     "//components/external_intents/android:java",
     "//components/infobars/core:infobar_enums_java",
+    "//components/messages/android:java",
     "//components/page_info/android:java",
     "//components/policy/android:policy_java",
     "//content/public/android:content_java",
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java
index 3b0c5bce..a8d8f43c 100644
--- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java
+++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrCoreInstallUtils.java
@@ -5,6 +5,7 @@
 package org.chromium.chrome.browser.vr;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
 
@@ -17,10 +18,16 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
-import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
-import org.chromium.chrome.browser.ui.messages.infobar.SimpleConfirmInfoBarBuilder;
+import org.chromium.chrome.vr.R;
+import org.chromium.components.messages.DismissReason;
+import org.chromium.components.messages.MessageBannerProperties;
+import org.chromium.components.messages.MessageDispatcher;
+import org.chromium.components.messages.MessageDispatcherProvider;
+import org.chromium.components.messages.MessageIdentifier;
+import org.chromium.components.messages.MessageScopeType;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.modelutil.PropertyModel;
 
 /**
  * Manages logic around VrCore Installation and Versioning
@@ -178,50 +185,52 @@
         @VrCoreVersionChecker.VrCoreCompatibility
         int vrCoreCompatibility = getVrCoreVersionChecker().getVrCoreCompatibility();
 
-        String infobarText;
+        String messageTitle;
         String buttonText;
+        Context context = ContextUtils.getApplicationContext();
 
         if (vrCoreCompatibility == VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_AVAILABLE) {
             // Supported, but not installed. Ask user to install instead of upgrade.
-            infobarText = ContextUtils.getApplicationContext().getString(
-                    org.chromium.chrome.vr.R.string.vr_services_check_infobar_install_text);
-            buttonText = ContextUtils.getApplicationContext().getString(
-                    org.chromium.chrome.vr.R.string.vr_services_check_infobar_install_button);
+            messageTitle = context.getString(R.string.vr_services_check_message_install_title);
+            buttonText = context.getString(org.chromium.chrome.R.string.install);
         } else if (vrCoreCompatibility == VrCoreVersionChecker.VrCoreCompatibility.VR_OUT_OF_DATE) {
-            infobarText = ContextUtils.getApplicationContext().getString(
-                    org.chromium.chrome.vr.R.string.vr_services_check_infobar_update_text);
-            buttonText = ContextUtils.getApplicationContext().getString(
-                    org.chromium.chrome.vr.R.string.vr_services_check_infobar_update_button);
+            messageTitle = context.getString(R.string.vr_services_check_message_update_title);
+            buttonText = context.getString(org.chromium.chrome.R.string.update);
         } else {
             Log.e(TAG, "Unknown VrCore compatibility: " + vrCoreCompatibility);
             return;
         }
 
-        SimpleConfirmInfoBarBuilder.Listener listener = new SimpleConfirmInfoBarBuilder.Listener() {
-            @Override
-            public void onInfoBarDismissed() {
-                maybeNotifyNativeOnInstallResult(false);
-            }
+        MessageDispatcher messageDispatcher =
+                MessageDispatcherProvider.from(webContents.getTopLevelNativeWindow());
+        if (messageDispatcher == null) return;
+        PropertyModel message =
+                new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+                        .with(MessageBannerProperties.MESSAGE_IDENTIFIER,
+                                MessageIdentifier.VR_SERVICES_UPGRADE)
+                        .with(MessageBannerProperties.TITLE, messageTitle)
+                        .with(MessageBannerProperties.DESCRIPTION,
+                                context.getString(org.chromium.chrome.vr.R.string
+                                                          .vr_services_check_message_description))
+                        .with(MessageBannerProperties.ICON_RESOURCE_ID,
+                                org.chromium.chrome.vr.R.drawable.vr_services)
+                        .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, buttonText)
+                        .with(MessageBannerProperties.ON_PRIMARY_ACTION,
+                                () -> {
+                                    assert sRequestInstallInstance == null;
+                                    sRequestInstallInstance = VrCoreInstallUtils.this;
+                                    activity.startActivityForResult(
+                                            new Intent(Intent.ACTION_VIEW,
+                                                    Uri.parse(VR_CORE_MARKET_URI)),
+                                            VR_SERVICES_UPDATE_RESULT);
+                                })
+                        .with(MessageBannerProperties.ON_DISMISSED, this::onMessageDismissed)
+                        .build();
+        messageDispatcher.enqueueMessage(message, webContents, MessageScopeType.NAVIGATION, false);
+    }
 
-            @Override
-            public boolean onInfoBarButtonClicked(boolean isPrimary) {
-                assert sRequestInstallInstance == null;
-                sRequestInstallInstance = VrCoreInstallUtils.this;
-                activity.startActivityForResult(
-                        new Intent(Intent.ACTION_VIEW, Uri.parse(VR_CORE_MARKET_URI)),
-                        VR_SERVICES_UPDATE_RESULT);
-                return false;
-            }
-
-            @Override
-            public boolean onInfoBarLinkClicked() {
-                return false;
-            }
-        };
-        SimpleConfirmInfoBarBuilder.create(webContents, listener,
-                InfoBarIdentifier.VR_SERVICES_UPGRADE_ANDROID, activity,
-                org.chromium.chrome.vr.R.drawable.vr_services, infobarText, buttonText, null, null,
-                true);
+    private void onMessageDismissed(@DismissReason int dismissReason) {
+        maybeNotifyNativeOnInstallResult(false);
     }
 
     private void onVrCoreMaybeUpdated() {
diff --git a/chrome/android/features/vr/java/strings/android_chrome_vr_strings.grd b/chrome/android/features/vr/java/strings/android_chrome_vr_strings.grd
index b86491e..762ede9 100644
--- a/chrome/android/features/vr/java/strings/android_chrome_vr_strings.grd
+++ b/chrome/android/features/vr/java/strings/android_chrome_vr_strings.grd
@@ -176,18 +176,15 @@
           Provide feedback
         </message>
 
-        <!-- VR services check infobar -->
-        <message name="IDS_VR_SERVICES_CHECK_INFOBAR_INSTALL_TEXT" desc="Text to be displayed in the VR Services check infobar. When a WebVR page is loaded if the VR services that are needed to display WebVR don't exist an infobar will be shown to the user prompting them to install VR services.">
-          To view virtual reality content, install Google VR Services
+        <!-- VR services check message -->
+        <message name="IDS_VR_SERVICES_CHECK_MESSAGE_INSTALL_TITLE" desc="Title to be displayed in the VR Services check message. When a WebVR page is loaded if the VR services that are needed to display WebVR don't exist a message will be shown to the user prompting them to install VR services.">
+          Install Google VR Services?
         </message>
-        <message name="IDS_VR_SERVICES_CHECK_INFOBAR_UPDATE_TEXT" desc="Text to be displayed in the VR Services check infobar. When a WebVR page is loaded if the VR services that are needed to display WebVR are out of date an infobar will be shown to the user prompting them to update VR services.">
-          To view virtual reality content, update Google VR Services
+        <message name="IDS_VR_SERVICES_CHECK_MESSAGE_UPDATE_TITLE" desc="Title to be displayed in the VR Services check message. When a WebVR page is loaded if the VR services that are needed to display WebVR are out of date a message will be shown to the user prompting them to update VR services.">
+          Update Google VR Services?
         </message>
-        <message name="IDS_VR_SERVICES_CHECK_INFOBAR_INSTALL_BUTTON" desc="Text to be displayed in the VR Services check infobar confirm button for installing.">
-          Install
-        </message>
-        <message name="IDS_VR_SERVICES_CHECK_INFOBAR_UPDATE_BUTTON" desc="Text to be displayed in the VR Services check infobar confirm button for updating.">
-          Update
+        <message name="IDS_VR_SERVICES_CHECK_MESSAGE_DESCRIPTION" desc="Text to be displayed in the VR Services check message description.">
+          View virtual reality content
         </message>
     </messages>
   </release>
diff --git a/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_DESCRIPTION.png.sha1 b/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..227c9b3
--- /dev/null
+++ b/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+786cf32997830688a4de4555ef74a34a2ab4cbe6
\ No newline at end of file
diff --git a/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_INSTALL_TITLE.png.sha1 b/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_INSTALL_TITLE.png.sha1
new file mode 100644
index 0000000..227c9b3
--- /dev/null
+++ b/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_INSTALL_TITLE.png.sha1
@@ -0,0 +1 @@
+786cf32997830688a4de4555ef74a34a2ab4cbe6
\ No newline at end of file
diff --git a/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_UPDATE_TITLE.png.sha1 b/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_UPDATE_TITLE.png.sha1
new file mode 100644
index 0000000..6b95b0d
--- /dev/null
+++ b/chrome/android/features/vr/java/strings/android_chrome_vr_strings_grd/IDS_VR_SERVICES_CHECK_MESSAGE_UPDATE_TITLE.png.sha1
@@ -0,0 +1 @@
+f49a69885e0f11fd68f3aad172d0bdc7f1457914
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
index c16e68e..578bb0377 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -526,7 +526,7 @@
                                 .size()
                         > 1;
         boolean isPriceTrackingVisible = isOverviewModeMenu
-                && PriceTrackingUtilities.isPriceTrackingEligible()
+                && PriceTrackingUtilities.shouldShowPriceTrackingMenu()
                 && !DeviceClassManager.enableAccessibilityLayout(mContext) && !isIncognito;
         boolean isPriceTrackingEnabled = isPriceTrackingVisible;
         boolean hasItemBetweenDividers = false;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java
index 453913eb..59509e4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/appmenu/OverviewAppMenuTest.java
@@ -220,7 +220,8 @@
     @Features.EnableFeatures({ChromeFeatureList.COMMERCE_PRICE_TRACKING + "<Study"})
     @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"})
+            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+                    + "/allow_disable_price_annotations/true"})
     public void
     testTrackPriceOnTabsIsEnabled() throws Exception {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
@@ -238,7 +239,8 @@
     @Features.EnableFeatures({ChromeFeatureList.COMMERCE_PRICE_TRACKING + "<Study"})
     @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"})
+            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+                    + "/allow_disable_price_annotations/true"})
     public void
     testTrackPriceOnTabsIsDisabledInIncognitoMode() throws Exception {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
@@ -257,7 +259,8 @@
     @Features.EnableFeatures({ChromeFeatureList.COMMERCE_PRICE_TRACKING + "<Study"})
     @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"})
+            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+                    + "/allow_disable_price_annotations/true"})
     public void
     testTrackPriceOnTabsIsDisabledIfSyncDisabledOrNotSignedIn() throws Exception {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
@@ -272,6 +275,25 @@
     @Test
     @SmallTest
     @Feature({"Browser", "Main"})
+    @Features.EnableFeatures({ChromeFeatureList.COMMERCE_PRICE_TRACKING + "<Study"})
+    @Features.DisableFeatures({ChromeFeatureList.START_SURFACE_ANDROID})
+    @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
+            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+                    + "/allow_disable_price_annotations/false/enable_price_notification/false"})
+    public void
+    testTrackPriceOnTabsIsDisabledIfNoSettingsAvailable() throws Exception {
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            PriceTrackingUtilities.setIsSignedInAndSyncEnabledForTesting(true);
+            AppMenuTestSupport.showAppMenu(mActivityTestRule.getAppMenuCoordinator(), null, false);
+        });
+
+        assertNull(AppMenuTestSupport.getMenuItemPropertyModel(
+                mActivityTestRule.getAppMenuCoordinator(), R.id.track_prices_row_menu_id));
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"Browser", "Main"})
     @Features.EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID,
             ChromeFeatureList.COMMERCE_PRICE_TRACKING + "<Study"})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
@@ -293,7 +315,8 @@
     @Features.EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID,
             ChromeFeatureList.COMMERCE_PRICE_TRACKING + "<Study"})
     @CommandLineFlags.Add({"force-fieldtrials=Study/Group",
-            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"})
+            "force-fieldtrial-params=Study.Group:enable_price_tracking/true"
+                    + "/allow_disable_price_annotations/true"})
     public void
     testTrackPriceOnTabsIsEnabledWithStartSurface() throws Exception {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateMessageTest.java
similarity index 64%
rename from chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateInfoBarTest.java
rename to chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateMessageTest.java
index bf4b6ff..11b2347 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateInfoBarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/VrInstallUpdateMessageTest.java
@@ -6,8 +6,7 @@
 
 import static org.chromium.chrome.test.util.ChromeRestriction.RESTRICTION_TYPE_SVR;
 
-import android.view.View;
-import android.widget.TextView;
+import android.content.Context;
 
 import androidx.test.filters.MediumTest;
 
@@ -24,21 +23,24 @@
 import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Restriction;
-import org.chromium.chrome.R;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.vr.mock.MockVrCoreVersionChecker;
 import org.chromium.chrome.browser.vr.rules.XrActivityRestriction;
-import org.chromium.chrome.browser.vr.util.VrInfoBarUtils;
+import org.chromium.chrome.browser.vr.util.VrMessageUtils;
 import org.chromium.chrome.browser.vr.util.VrTestRuleUtils;
 import org.chromium.chrome.test.ChromeActivityTestRule;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
+import org.chromium.chrome.vr.R;
+import org.chromium.components.messages.MessageBannerProperties;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.List;
 import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
 
 /**
- * End-to-end tests for the InfoBar that prompts the user to update or install
+ * End-to-end tests for the message that prompts the user to update or install
  * VrCore (VR Services) when attempting to use a VR feature with an outdated
  * or entirely missing version or other VR-related update prompts.
  */
@@ -47,7 +49,7 @@
 @CommandLineFlags.
 Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "enable-features=LogJsConsoleMessages"})
 @Restriction(RESTRICTION_TYPE_SVR)
-public class VrInstallUpdateInfoBarTest {
+public class VrInstallUpdateMessageTest {
     @ClassParameter
     private static List<ParameterSet> sClassParams =
             VrTestRuleUtils.generateDefaultTestRuleParameters();
@@ -56,7 +58,7 @@
 
     private ChromeActivityTestRule mVrTestRule;
 
-    public VrInstallUpdateInfoBarTest(Callable<ChromeActivityTestRule> callable) throws Exception {
+    public VrInstallUpdateMessageTest(Callable<ChromeActivityTestRule> callable) throws Exception {
         mVrTestRule = callable.call();
         mRuleChain = VrTestRuleUtils.wrapRuleInActivityRestrictionRule(mVrTestRule);
     }
@@ -81,100 +83,99 @@
     }
 
     /**
-     * Helper function to run the tests checking for the upgrade/install InfoBar being present since
+     * Helper function to run the tests checking for the upgrade/install message being present since
      * all that differs is the value returned by VrCoreVersionChecker and a couple asserts.
      *
      * @param checkerReturnCompatibility The compatibility to have the VrCoreVersionChecker return.
      */
-    private void infoBarTestHelper(final int checkerReturnCompatibility) {
+    private void messageTestHelper(final int checkerReturnCompatibility) throws ExecutionException {
         VrCoreInstallUtils vrCoreInstallUtils = VrCoreInstallUtils.create(0);
         setVrCoreCompatibility(checkerReturnCompatibility);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             vrCoreInstallUtils.requestInstallVrCore(
                     mVrTestRule.getActivity().getCurrentWebContents());
         });
-        View decorView = mVrTestRule.getActivity().getWindow().getDecorView();
         if (checkerReturnCompatibility == VrCoreVersionChecker.VrCoreCompatibility.VR_READY) {
-            VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, false);
+            VrMessageUtils.expectMessagePresent(mVrTestRule, false);
         } else if (checkerReturnCompatibility
                         == VrCoreVersionChecker.VrCoreCompatibility.VR_OUT_OF_DATE
                 || checkerReturnCompatibility
                         == VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_AVAILABLE) {
             // Out of date and missing cases are the same, but with different text
-            String expectedMessage;
+            String expectedTitle;
             String expectedButton;
+            Context context = ContextUtils.getApplicationContext();
             if (checkerReturnCompatibility
                     == VrCoreVersionChecker.VrCoreCompatibility.VR_OUT_OF_DATE) {
-                expectedMessage = ContextUtils.getApplicationContext().getString(
-                        org.chromium.chrome.vr.R.string.vr_services_check_infobar_update_text);
-                expectedButton = ContextUtils.getApplicationContext().getString(
-                        org.chromium.chrome.vr.R.string.vr_services_check_infobar_update_button);
+                expectedTitle = context.getString(R.string.vr_services_check_message_update_title);
+                expectedButton = context.getString(org.chromium.chrome.R.string.update);
             } else {
-                expectedMessage = ContextUtils.getApplicationContext().getString(
-                        org.chromium.chrome.vr.R.string.vr_services_check_infobar_install_text);
-                expectedButton = ContextUtils.getApplicationContext().getString(
-                        org.chromium.chrome.vr.R.string.vr_services_check_infobar_install_button);
+                expectedTitle = context.getString(R.string.vr_services_check_message_install_title);
+                expectedButton = context.getString(org.chromium.chrome.R.string.install);
             }
-            VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, true);
-            TextView tempView = (TextView) decorView.findViewById(R.id.infobar_message);
-            Assert.assertEquals("VR install/update infobar text did not match expectation",
-                    expectedMessage, tempView.getText().toString());
-            tempView = (TextView) decorView.findViewById(R.id.button_primary);
-            Assert.assertEquals("VR install/update button text did not match expectation",
-                    expectedButton, tempView.getText().toString());
+            PropertyModel message = VrMessageUtils.getVrInstallUpdateMessage(mVrTestRule);
+            Assert.assertNotNull("VR install/update message should be present.", message);
+
+            Assert.assertEquals("VR install/update message text did not match expectation.",
+                    expectedTitle, message.get(MessageBannerProperties.TITLE));
+            Assert.assertEquals("VR install/update message description did not match expectation.",
+                    context.getString(R.string.vr_services_check_message_description),
+                    message.get(MessageBannerProperties.DESCRIPTION));
+            Assert.assertEquals("VR install/update message button text did not match expectation.",
+                    expectedButton, message.get(MessageBannerProperties.PRIMARY_BUTTON_TEXT));
         } else if (checkerReturnCompatibility
                 == VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_SUPPORTED) {
-            VrInfoBarUtils.expectInfoBarPresent(mVrTestRule, false);
+            VrMessageUtils.expectMessagePresent(mVrTestRule, false);
         } else {
-            Assert.fail("Invalid VrCoreVersionChecker compatibility: "
-                    + String.valueOf(checkerReturnCompatibility));
+            Assert.fail(
+                    "Invalid VrCoreVersionChecker compatibility: " + checkerReturnCompatibility);
         }
         VrCoreInstallUtils.overrideVrCoreVersionChecker(null);
     }
 
     /**
-     * Tests that the upgrade/install VR Services InfoBar is not present when VR Services is
+     * Tests that the upgrade/install VR Services message is not present when VR Services is
      * installed and up to date.
      */
     @Test
     @MediumTest
     @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
-    public void testInfoBarNotPresentWhenVrServicesCurrent() {
-        infoBarTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_READY);
+    public void testMessageNotPresentWhenVrServicesCurrent() throws ExecutionException {
+        messageTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_READY);
     }
 
     /**
-     * Tests that the upgrade VR Services InfoBar is present when VR Services is outdated.
+     * Tests that the upgrade VR Services message is present when VR Services is outdated.
      */
     @Test
     @MediumTest
     @XrActivityRestriction({XrActivityRestriction.SupportedActivity.CTA,
             XrActivityRestriction.SupportedActivity.CCT})
     public void
-    testInfoBarPresentWhenVrServicesOutdated() {
-        infoBarTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_OUT_OF_DATE);
+    testMessagePresentWhenVrServicesOutdated() throws ExecutionException {
+        messageTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_OUT_OF_DATE);
     }
 
     /**
-     * Tests that the install VR Services InfoBar is present when VR Services is missing.
+     * Tests that the install VR Services message is present when VR Services is missing.
      */
     @Test
     @MediumTest
     @XrActivityRestriction({XrActivityRestriction.SupportedActivity.CTA,
             XrActivityRestriction.SupportedActivity.CCT})
     public void
-    testInfoBarPresentWhenVrServicesMissing() {
-        infoBarTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_AVAILABLE);
+    testMessagePresentWhenVrServicesMissing() throws ExecutionException {
+        messageTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_AVAILABLE);
     }
 
     /**
-     * Tests that the install VR Services InfoBar is not present when VR is not supported on the
+     * Tests that the install VR Services message is not present when VR is not supported on the
      * device.
      */
     @Test
     @MediumTest
     @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL})
-    public void testInfoBarNotPresentWhenVrServicesNotSupported() {
-        infoBarTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_SUPPORTED);
+    public void testMessageNotPresentWhenVrServicesNotSupported() throws ExecutionException {
+        messageTestHelper(VrCoreVersionChecker.VrCoreCompatibility.VR_NOT_SUPPORTED);
     }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrInfoBarUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrInfoBarUtils.java
deleted file mode 100644
index ffa6599..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrInfoBarUtils.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.vr.util;
-
-import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
-import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_SHORT_MS;
-
-import androidx.annotation.IntDef;
-
-import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.chrome.test.ChromeActivityTestRule;
-import org.chromium.chrome.test.util.InfoBarUtil;
-import org.chromium.components.infobars.InfoBar;
-import org.chromium.content_public.browser.test.util.TestThreadUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-/**
- * Class containing utility functions for interacting with InfoBars at
- * a high level.
- */
-public class VrInfoBarUtils {
-    @IntDef({Button.PRIMARY, Button.SECONDARY})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Button {
-        int PRIMARY = 0;
-        int SECONDARY = 1;
-    }
-
-    /**
-     * Determines whether InfoBars are present in the current activity.
-     *
-     * @param rule The ChromeActivityTestRule to get the InfoBars from.
-     * @return True if there are any InfoBars present, false otherwise.
-     */
-    @SuppressWarnings("unchecked")
-    public static boolean isInfoBarPresent(ChromeActivityTestRule rule) {
-        List<InfoBar> infoBars = rule.getInfoBars();
-        return infoBars != null && !infoBars.isEmpty();
-    }
-
-    /**
-     * Clicks on either the primary or secondary button of the first InfoBar
-     * in the activity.
-     *
-     * @param button Which button to click.
-     * @param rule The ChromeActivityTestRule to get the InfoBars from.
-     */
-    @SuppressWarnings("unchecked")
-    public static void clickInfoBarButton(final @Button int button, ChromeActivityTestRule rule) {
-        if (!isInfoBarPresent(rule)) return;
-        final List<InfoBar> infoBars = rule.getInfoBars();
-        TestThreadUtils.runOnUiThreadBlocking(() -> {
-            switch (button) {
-                case Button.PRIMARY:
-                    InfoBarUtil.clickPrimaryButton(infoBars.get(0));
-                    break;
-                default:
-                    InfoBarUtil.clickSecondaryButton(infoBars.get(0));
-            }
-        });
-        InfoBarUtil.waitUntilNoInfoBarsExist(rule.getInfoBars());
-    }
-
-    /**
-     * Clicks on the close button of the first InfoBar in the activity.
-     *
-     * @param rule The ChromeActivityTestRule to get the InfoBars from.
-     */
-    @SuppressWarnings("unchecked")
-    public static void clickInfobarCloseButton(ChromeActivityTestRule rule) {
-        if (!isInfoBarPresent(rule)) return;
-        final List<InfoBar> infoBars = rule.getInfoBars();
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> { InfoBarUtil.clickCloseButton(infoBars.get(0)); });
-        InfoBarUtil.waitUntilNoInfoBarsExist(rule.getInfoBars());
-    }
-
-    /**
-     * Determines is there is any InfoBar present in the given View hierarchy.
-     *
-     * @param rule The ChromeActivityTestRule to get the InfoBars from.
-     * @param present Whether an InfoBar should be present.
-     */
-    public static void expectInfoBarPresent(
-            final ChromeActivityTestRule rule, final boolean present) {
-        CriteriaHelper.pollUiThread(()
-                                            -> { return isInfoBarPresent(rule) == present; },
-                "InfoBar bar did not " + (present ? "appear" : "disappear"), POLL_TIMEOUT_SHORT_MS,
-                POLL_CHECK_INTERVAL_SHORT_MS);
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrMessageUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrMessageUtils.java
new file mode 100644
index 0000000..9087150
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/util/VrMessageUtils.java
@@ -0,0 +1,70 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.vr.util;
+
+import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_CHECK_INTERVAL_SHORT_MS;
+import static org.chromium.chrome.browser.vr.XrTestFramework.POLL_TIMEOUT_SHORT_MS;
+
+import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.components.messages.MessageDispatcher;
+import org.chromium.components.messages.MessageDispatcherProvider;
+import org.chromium.components.messages.MessageIdentifier;
+import org.chromium.components.messages.MessageStateHandler;
+import org.chromium.components.messages.MessagesTestHelper;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.modelutil.PropertyModel;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Class containing utility functions for interacting with messages at
+ * a high level.
+ */
+public class VrMessageUtils {
+    /**
+     * Determines whether messages are present in the current activity.
+     *
+     * @param rule The ChromeActivityTestRule to get the messages from.
+     * @return True if there are any messages present, false otherwise.
+     */
+    @SuppressWarnings("unchecked")
+    public static boolean isMessagePresent(ChromeActivityTestRule rule) throws ExecutionException {
+        return getVrInstallUpdateMessage(rule) != null;
+    }
+
+    /**
+     * Determines is there is any message present in the given View hierarchy.
+     *
+     * @param rule The ChromeActivityTestRule to get the messages from.
+     * @param present Whether a message should be present.
+     */
+    public static void expectMessagePresent(
+            final ChromeActivityTestRule rule, final boolean present) {
+        CriteriaHelper.pollUiThread(()
+                                            -> isMessagePresent(rule) == present,
+                "Message did not " + (present ? "appear" : "disappear"), POLL_TIMEOUT_SHORT_MS,
+                POLL_CHECK_INTERVAL_SHORT_MS);
+    }
+
+    /**
+     * Returns the {@link PropertyModel} of an enqueued VR install/update message.
+     *
+     * @param rule The ChromeActivityTestRule to get the messages from.
+     * @return The {@link PropertyModel} of an enqueued VR install/update message, null if the
+     *         message is not present.
+     */
+    public static PropertyModel getVrInstallUpdateMessage(ChromeActivityTestRule rule)
+            throws ExecutionException {
+        MessageDispatcher messageDispatcher = TestThreadUtils.runOnUiThreadBlocking(
+                () -> MessageDispatcherProvider.from(rule.getActivity().getWindowAndroid()));
+        List<MessageStateHandler> messages = MessagesTestHelper.getEnqueuedMessages(
+                messageDispatcher, MessageIdentifier.VR_SERVICES_UPGRADE);
+        return messages == null || messages.isEmpty()
+                ? null
+                : MessagesTestHelper.getCurrentMessage(messages.get(0));
+    }
+}
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 74f49929..380f80dd 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-97.0.4666.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-amd64-97.0.4692.36_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index 4a08469..32f329c7e 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -697,6 +697,12 @@
   <message name="IDS_OS_SETTINGS_AMBIENT_MODE_DISABLED" desc="Sub label for the ambient mode row in settings page when it is disabled.">
     Disabled
   </message>
+  <message name="IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB" desc="Title for the link to open personalization hub.">
+    Personalize your device
+  </message>
+  <message name="IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB_SUBTITLE" desc="Description for the link to open personalization hub.">
+    Customize wallpaper, avatar, screensaver and more
+  </message>
 
   <!-- Ambient Mode Page -->
   <message name="IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION" desc="Description for the ambient mode settings page.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB.png.sha1
new file mode 100644
index 0000000..4a3e03e
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB.png.sha1
@@ -0,0 +1 @@
+e7a8d7eb5c5f3e8ae3d9213f28dbd150e11b8c5c
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB_SUBTITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB_SUBTITLE.png.sha1
new file mode 100644
index 0000000..4a3e03e
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB_SUBTITLE.png.sha1
@@ -0,0 +1 @@
+e7a8d7eb5c5f3e8ae3d9213f28dbd150e11b8c5c
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 31acf6a..5bcb8578 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4864,8 +4864,7 @@
 
     {flag_descriptions::kScrollableTabStripFlagId,
      flag_descriptions::kScrollableTabStripName,
-     flag_descriptions::kScrollableTabStripDescription,
-     kOsMac | kOsWin | kOsLinux | kOsFuchsia,
+     flag_descriptions::kScrollableTabStripDescription, kOsDesktop,
      FEATURE_WITH_PARAMS_VALUE_TYPE(features::kScrollableTabStrip,
                                     kTabScrollingVariations,
                                     "TabScrolling")},
diff --git a/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc b/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc
index 687809e..a79a5463 100644
--- a/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc
+++ b/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc
@@ -258,6 +258,10 @@
         /*app_id=*/"r", apps::mojom::AppType::kRemote, "",
         apps::mojom::Readiness::kReady, apps::mojom::InstallReason::kPolicy,
         apps::mojom::InstallSource::kUnknown));
+    deltas.push_back(MakeApp(
+        /*app_id=*/"subapp", apps::mojom::AppType::kWeb, "",
+        apps::mojom::Readiness::kReady, apps::mojom::InstallReason::kSubApp,
+        apps::mojom::InstallSource::kUnknown));
     cache.OnApps(std::move(deltas), apps::mojom::AppType::kUnknown,
                  false /* should_notify_initialized */);
   }
@@ -394,6 +398,13 @@
         AppPlatformMetrics::GetAppsCountPerInstallReasonHistogramNameForTest(
             AppTypeName::kSystemWeb, apps::mojom::InstallReason::kSystem),
         /*expected_count=*/1);
+    histogram_tester_.ExpectTotalCount(
+        AppPlatformMetrics::GetAppsCountHistogramNameForTest(AppTypeName::kWeb),
+        /*expected_count=*/1);
+    histogram_tester_.ExpectTotalCount(
+        AppPlatformMetrics::GetAppsCountPerInstallReasonHistogramNameForTest(
+            AppTypeName::kWeb, apps::mojom::InstallReason::kSubApp),
+        /*expected_count=*/1);
   }
 
   void ModifyInstance(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
index 44ce79a..e7fcf732 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
@@ -7,6 +7,7 @@
 #include <utility>
 
 #include "base/callback_helpers.h"
+#include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/apps/app_service/intent_util.h"
@@ -63,8 +64,13 @@
     return;
   }
 
-  controller_->LoadIcon(app_id, ConvertIconKeyToMojomIconKey(icon_key),
-                        icon_type, size_hint_in_dip, std::move(callback));
+  const uint32_t icon_effects = icon_key.icon_effects;
+  controller_->LoadIcon(
+      app_id, ConvertIconKeyToMojomIconKey(icon_key), icon_type,
+      size_hint_in_dip,
+      base::BindOnce(&StandaloneBrowserExtensionApps::OnLoadIcon,
+                     weak_factory_.GetWeakPtr(), icon_effects, size_hint_in_dip,
+                     std::move(callback)));
 }
 
 void StandaloneBrowserExtensionApps::LaunchAppWithParams(
@@ -238,4 +244,13 @@
   controller_.reset();
 }
 
+void StandaloneBrowserExtensionApps::OnLoadIcon(uint32_t icon_effects,
+                                                int size_hint_in_dip,
+                                                apps::LoadIconCallback callback,
+                                                IconValuePtr icon_value) {
+  // We apply the masking effect here, as masking is not implemented in Lacros.
+  ApplyIconEffects(static_cast<IconEffects>(icon_effects), size_hint_in_dip,
+                   std::move(icon_value), std::move(callback));
+}
+
 }  // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
index 9165c0e2..723ed695 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
@@ -124,6 +124,13 @@
   void OnReceiverDisconnected();
   void OnControllerDisconnected();
 
+  // When Lacros returns an icon for an app, ash must then apply icon effects.
+  // This function does that.
+  void OnLoadIcon(uint32_t icon_effects,
+                  int size_hint_in_dip,
+                  apps::LoadIconCallback callback,
+                  IconValuePtr icon_value);
+
   mojo::RemoteSet<apps::mojom::Subscriber> subscribers_;
 
   // This class stores a copy of the latest app_ptr received for each app_id.
diff --git a/chrome/browser/ash/policy/dlp/dlp_content_manager_browsertest.cc b/chrome/browser/ash/policy/dlp/dlp_content_manager_browsertest.cc
index 0567b35..9b0ad98 100644
--- a/chrome/browser/ash/policy/dlp/dlp_content_manager_browsertest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_content_manager_browsertest.cc
@@ -2,14 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <functional>
-#include "base/bind.h"
 #include "chrome/browser/ash/policy/dlp/dlp_content_manager.h"
 
+#include <functional>
+
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/task/sequenced_task_runner.h"
+#include "base/task/thread_pool/thread_pool_instance.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_future.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "chrome/browser/ash/policy/dlp/dlp_content_manager_test_helper.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_policy_event.pb.h"
@@ -96,6 +99,15 @@
     return dlp_rules_manager;
   }
 
+  void SetUpOnMainThread() override {
+    // Instantiate |DlpContentManagerTestHelper| after main thread has been set
+    // up cause |DlpReportingManager| needs a sequenced task runner handle to
+    // set up the report queue.
+    helper_ = std::make_unique<DlpContentManagerTestHelper>();
+  }
+
+  void TearDownOnMainThread() override { helper_.reset(); }
+
   // Sets up mock rules manager.
   void SetupDlpRulesManager() {
     DlpRulesManagerFactory::GetInstance()->SetTestingFactory(
@@ -113,7 +125,8 @@
   void SetupReporting() {
     SetupDlpRulesManager();
     // Set up mock report queue.
-    SetReportQueueForReportingManager(helper_.GetReportingManager(), events_);
+    SetReportQueueForReportingManager(helper_->GetReportingManager(), events_,
+                                      base::SequencedTaskRunnerHandle::Get());
   }
 
   void CheckEvents(DlpRulesManager::Restriction restriction,
@@ -127,7 +140,7 @@
   }
 
  protected:
-  DlpContentManagerTestHelper helper_;
+  std::unique_ptr<DlpContentManagerTestHelper> helper_;
   base::HistogramTester histogram_tester_;
   MockDlpRulesManager* mock_rules_manager_;
 
@@ -137,7 +150,7 @@
 
 IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenshotsRestricted) {
   SetupReporting();
-  DlpContentManager* manager = helper_.GetContentManager();
+  DlpContentManager* manager = helper_->GetContentManager();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl)));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -167,7 +180,7 @@
   CheckEvents(DlpRulesManager::Restriction::kScreenshot,
               DlpRulesManager::Level::kBlock, 0u);
 
-  helper_.ChangeConfidentiality(web_contents, kScreenshotRestricted);
+  helper_->ChangeConfidentiality(web_contents, kScreenshotRestricted);
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(window));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(partial_in));
@@ -180,7 +193,7 @@
               DlpRulesManager::Level::kBlock, 3u);
 
   web_contents->WasHidden();
-  helper_.ChangeVisibility(web_contents);
+  helper_->ChangeVisibility(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(window));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
@@ -193,7 +206,7 @@
               DlpRulesManager::Level::kBlock, 4u);
 
   web_contents->WasShown();
-  helper_.ChangeVisibility(web_contents);
+  helper_->ChangeVisibility(web_contents);
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(window));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(partial_in));
@@ -205,7 +218,7 @@
   CheckEvents(DlpRulesManager::Restriction::kScreenshot,
               DlpRulesManager::Level::kBlock, 7u);
 
-  helper_.DestroyWebContents(web_contents);
+  helper_->DestroyWebContents(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
@@ -218,7 +231,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenshotsWarned) {
-  DlpContentManager* manager = helper_.GetContentManager();
+  DlpContentManager* manager = helper_->GetContentManager();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl)));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -242,27 +255,27 @@
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
 
-  helper_.ChangeConfidentiality(web_contents, kScreenshotWarned);
+  helper_->ChangeConfidentiality(web_contents, kScreenshotWarned);
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(window));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
 
   web_contents->WasHidden();
-  helper_.ChangeVisibility(web_contents);
+  helper_->ChangeVisibility(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(window));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
 
   web_contents->WasShown();
-  helper_.ChangeVisibility(web_contents);
+  helper_->ChangeVisibility(web_contents);
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(window));
   EXPECT_TRUE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
 
-  helper_.DestroyWebContents(web_contents);
+  helper_->DestroyWebContents(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
@@ -270,7 +283,7 @@
 
 IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenshotsReported) {
   SetupReporting();
-  DlpContentManager* manager = helper_.GetContentManager();
+  DlpContentManager* manager = helper_->GetContentManager();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl)));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -296,7 +309,7 @@
   CheckEvents(DlpRulesManager::Restriction::kScreenshot,
               DlpRulesManager::Level::kReport, 0u);
 
-  helper_.ChangeConfidentiality(web_contents, kScreenshotReported);
+  helper_->ChangeConfidentiality(web_contents, kScreenshotReported);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(window));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
@@ -305,7 +318,7 @@
               DlpRulesManager::Level::kReport, 3u);
 
   web_contents->WasHidden();
-  helper_.ChangeVisibility(web_contents);
+  helper_->ChangeVisibility(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(window));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
@@ -314,7 +327,7 @@
               DlpRulesManager::Level::kReport, 4u);
 
   web_contents->WasShown();
-  helper_.ChangeVisibility(web_contents);
+  helper_->ChangeVisibility(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(window));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
@@ -322,7 +335,7 @@
   CheckEvents(DlpRulesManager::Restriction::kScreenshot,
               DlpRulesManager::Level::kReport, 7u);
 
-  helper_.DestroyWebContents(web_contents);
+  helper_->DestroyWebContents(web_contents);
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(fullscreen));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_in));
   EXPECT_FALSE(manager->IsScreenshotApiRestricted(partial_out));
@@ -359,7 +372,7 @@
   browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
 
   // Make first window content as confidential.
-  helper_.ChangeConfidentiality(web_contents1, kScreenshotRestricted);
+  helper_->ChangeConfidentiality(web_contents1, kScreenshotRestricted);
 
   // Start capture of the whole screen.
   base::RunLoop run_loop;
@@ -407,7 +420,7 @@
   browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
 
   // Make first window content as confidential.
-  helper_.ChangeConfidentiality(web_contents1, kScreenshotReported);
+  helper_->ChangeConfidentiality(web_contents1, kScreenshotReported);
 
   // Start capture of the whole screen.
   base::RunLoop run_loop;
@@ -456,7 +469,7 @@
   browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
 
   // Make first window content as confidential.
-  helper_.ChangeConfidentiality(web_contents1, kScreenshotRestricted);
+  helper_->ChangeConfidentiality(web_contents1, kScreenshotRestricted);
 
   // Start capture of the whole screen.
   base::RunLoop run_loop;
@@ -505,7 +518,7 @@
   browser2->window()->SetBounds(gfx::Rect(0, 0, 700, 700));
 
   // Make first window content as confidential.
-  helper_.ChangeConfidentiality(web_contents1, kScreenshotRestricted);
+  helper_->ChangeConfidentiality(web_contents1, kScreenshotRestricted);
 
   // Start capture of the whole screen.
   base::RunLoop run_loop;
@@ -532,7 +545,7 @@
 IN_PROC_BROWSER_TEST_F(DlpContentManagerBrowserTest, ScreenShareNotification) {
   SetupReporting();
   NotificationDisplayServiceTester display_service_tester(browser()->profile());
-  DlpContentManager* manager = helper_.GetContentManager();
+  DlpContentManager* manager = helper_->GetContentManager();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl)));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -552,7 +565,7 @@
   histogram_tester_.ExpectBucketCount(
       GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, false, 0);
 
-  helper_.ChangeConfidentiality(web_contents, kScreenShareRestricted);
+  helper_->ChangeConfidentiality(web_contents, kScreenShareRestricted);
 
   CheckEvents(DlpRulesManager::Restriction::kScreenShare,
               DlpRulesManager::Level::kBlock, 1u);
@@ -565,7 +578,7 @@
   histogram_tester_.ExpectBucketCount(
       GetDlpHistogramPrefix() + dlp::kScreenSharePausedOrResumedUMA, false, 0);
 
-  helper_.ChangeConfidentiality(web_contents, kEmptyRestrictionSet);
+  helper_->ChangeConfidentiality(web_contents, kEmptyRestrictionSet);
 
   EXPECT_FALSE(
       display_service_tester.GetNotification(kScreenSharePausedNotificationId));
@@ -594,7 +607,7 @@
                        ScreenShareDisabledNotification) {
   SetupReporting();
   NotificationDisplayServiceTester display_service_tester(browser()->profile());
-  DlpContentManager* manager = helper_.GetContentManager();
+  DlpContentManager* manager = helper_->GetContentManager();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(kExampleUrl)));
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -610,7 +623,7 @@
   histogram_tester_.ExpectBucketCount(
       GetDlpHistogramPrefix() + dlp::kScreenShareBlockedUMA, false, 1);
 
-  helper_.ChangeConfidentiality(web_contents, kScreenShareRestricted);
+  helper_->ChangeConfidentiality(web_contents, kScreenShareRestricted);
 
   manager->CheckScreenShareRestriction(media_id, u"example.com",
                                        base::DoNothing());
@@ -621,7 +634,7 @@
   histogram_tester_.ExpectBucketCount(
       GetDlpHistogramPrefix() + dlp::kScreenShareBlockedUMA, true, 1);
 
-  helper_.ChangeConfidentiality(web_contents, kEmptyRestrictionSet);
+  helper_->ChangeConfidentiality(web_contents, kEmptyRestrictionSet);
 }
 
 // Starting screen sharing and navigating other tabs should create exactly one
@@ -663,7 +676,7 @@
       std::unique_ptr<content::MediaStreamUI>>
       test_future;
 
-  helper_.ChangeConfidentiality(web_contents, kScreenShareReported);
+  helper_->ChangeConfidentiality(web_contents, kScreenShareReported);
 
   access_handler.HandleRequest(
       web_contents, request,
@@ -692,7 +705,7 @@
   ASSERT_NE(browser()->tab_strip_model()->GetActiveWebContents(), web_contents);
   // Just additional check that visiting a tab with restricted content does not
   // affect the shared tab.
-  helper_.ChangeConfidentiality(
+  helper_->ChangeConfidentiality(
       browser()->tab_strip_model()->GetActiveWebContents(),
       kScreenShareRestricted);
   chrome::SelectNextTab(browser());
@@ -715,7 +728,7 @@
 
   absl::optional<bool> is_printing_allowed;
 
-  helper_.GetContentManager()->CheckPrintingRestriction(
+  helper_->GetContentManager()->CheckPrintingRestriction(
       web_contents,
       base::BindOnce(
           [](absl::optional<bool>* out_result, bool should_proceed) {
@@ -741,6 +754,7 @@
     : public DlpContentManagerBrowserTest {
  public:
   void SetUpOnMainThread() override {
+    DlpContentManagerBrowserTest::SetUpOnMainThread();
     content::WebContents* first_tab =
         browser()->tab_strip_model()->GetActiveWebContents();
     ASSERT_TRUE(first_tab);
@@ -758,11 +772,13 @@
     chrome::DuplicateTab(browser());
   }
 
-  void TearDownOnMainThread() override { cloned_tab_observer_.reset(); }
+  void TearDownOnMainThread() override {
+    DlpContentManagerBrowserTest::TearDownOnMainThread();
+    cloned_tab_observer_.reset();
+  }
 
   // Sets up real report queue together with TestStorageModule
   void SetupReportQueue() {
-    const std::string dm_token_ = "FAKE_DM_TOKEN";
     const reporting::Destination destination_ =
         reporting::Destination::UPLOAD_EVENTS;
 
@@ -776,12 +792,14 @@
     ON_CALL(mocked_policy_check_, Call())
         .WillByDefault(testing::Return(reporting::Status::StatusOK()));
 
-    reporting::StatusOr<std::unique_ptr<reporting::ReportQueueConfiguration>>
-        config_result = reporting::ReportQueueConfiguration::Create(
-            dm_token_, destination_, policy_check_callback_);
+    auto config_result = ::reporting::ReportQueueConfiguration::Create(
+        ::reporting::EventType::kDevice, destination_, policy_check_callback_);
 
     ASSERT_TRUE(config_result.ok());
 
+    // Create a report queue with the test storage module, and attach it
+    // to an actual speculative report queue so we can override the one used in
+    // |DlpReportingManager| by default.
     reporting::test::TestEvent<
         reporting::StatusOr<std::unique_ptr<reporting::ReportQueue>>>
         report_queue_event;
@@ -792,8 +810,18 @@
 
     ASSERT_TRUE(report_queue_result.ok());
 
-    helper_.GetReportingManager()->GetReportQueueSetter().Run(
-        std::move(report_queue_result.ValueOrDie()));
+    auto speculative_report_queue =
+        ::reporting::SpeculativeReportQueueImpl::Create();
+    auto attach_queue_cb =
+        speculative_report_queue->PrepareToAttachActualQueue();
+
+    helper_->GetReportingManager()->SetReportQueueForTest(
+        std::move(speculative_report_queue));
+    std::move(attach_queue_cb).Run(std::move(report_queue_result.ValueOrDie()));
+
+    // Wait until the speculative report queue is initialized with the stubbed
+    // report queue posted to its internal task runner
+    base::ThreadPoolInstance::Get()->FlushForTesting();
   }
 
   reporting::test::TestStorageModule* test_storage_module() const {
@@ -864,7 +892,7 @@
   NotificationDisplayServiceTester display_service_tester(browser()->profile());
 
   absl::optional<bool> is_printing_allowed;
-  helper_.GetContentManager()->CheckPrintingRestriction(
+  helper_->GetContentManager()->CheckPrintingRestriction(
       web_contents,
       base::BindOnce(
           [](absl::optional<bool>* out_result, bool should_proceed) {
@@ -875,9 +903,9 @@
   EXPECT_TRUE(is_printing_allowed.value());
 
   // Set up printing restriction.
-  helper_.ChangeConfidentiality(web_contents, kPrintRestricted);
+  helper_->ChangeConfidentiality(web_contents, kPrintRestricted);
   is_printing_allowed.reset();
-  helper_.GetContentManager()->CheckPrintingRestriction(
+  helper_->GetContentManager()->CheckPrintingRestriction(
       web_contents,
       base::BindOnce(
           [](absl::optional<bool>* out_result, bool should_proceed) {
@@ -924,9 +952,9 @@
 
   // Set up printing restriction.
   absl::optional<bool> is_printing_allowed;
-  helper_.ChangeConfidentiality(web_contents, kPrintReported);
+  helper_->ChangeConfidentiality(web_contents, kPrintReported);
   // Printing should be reported, but still allowed.
-  helper_.GetContentManager()->CheckPrintingRestriction(
+  helper_->GetContentManager()->CheckPrintingRestriction(
       web_contents,
       base::BindOnce(
           [](absl::optional<bool>* out_result, bool should_proceed) {
diff --git a/chrome/browser/ash/policy/dlp/dlp_content_manager_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_content_manager_unittest.cc
index 91f5b4f..4598ab3 100644
--- a/chrome/browser/ash/policy/dlp/dlp_content_manager_unittest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_content_manager_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/bind.h"
 #include "base/callback_forward.h"
 #include "base/memory/ptr_util.h"
+#include "base/task/thread_pool.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
@@ -123,7 +124,11 @@
   }
 
   void SetReportQueueForReportingManager() {
-    auto report_queue = std::make_unique<reporting::MockReportQueue>();
+    auto report_queue = std::unique_ptr<::reporting::MockReportQueue,
+                                        base::OnTaskRunnerDeleter>(
+        new ::reporting::MockReportQueue(),
+        base::OnTaskRunnerDeleter(
+            base::ThreadPool::CreateSequencedTaskRunner({})));
     EXPECT_CALL(*report_queue.get(), AddRecord)
         .WillRepeatedly(
             [this](base::StringPiece record, reporting::Priority priority,
@@ -134,7 +139,7 @@
               // concurrency issues with the events in the vector.
               events_.push_back(event);
             });
-    helper_.GetReportingManager()->GetReportQueueSetter().Run(
+    helper_.GetReportingManager()->SetReportQueueForTest(
         std::move(report_queue));
   }
 
@@ -150,9 +155,9 @@
 
   TestingProfile* profile() { return profile_; }
 
-  DlpContentManagerTestHelper helper_;
   content::BrowserTaskEnvironment task_environment_{
       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  DlpContentManagerTestHelper helper_;
   base::HistogramTester histogram_tester_;
   std::vector<DlpPolicyEvent> events_;
   MockDlpRulesManager* mock_rules_manager_ = nullptr;
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.cc
index ef2eca3..d81032c 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.cc
@@ -4,39 +4,43 @@
 
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h"
 
-#include "base/memory/ptr_util.h"
+#include <utility>
+
 #include "base/task/bind_post_task.h"
-#include "chrome/browser/ash/net/network_diagnostics/https_latency_routine.h"
+#include "chrome/browser/ash/net/network_health/network_health_service.h"
+#include "components/reporting/proto/synced/metric_data.pb.h"
 
 namespace reporting {
 namespace {
 
-using RoutineResultPtr = chromeos::network_diagnostics::mojom::RoutineResultPtr;
+namespace network_diagnostics_mojom = ::chromeos::network_diagnostics::mojom;
 
 void ConvertMojomRoutineResultToTelemetry(
-    const RoutineResultPtr& routine_result,
+    const network_diagnostics_mojom::RoutineResultPtr& routine_result,
     HttpsLatencyRoutineData* https_latency_data) {
-  using chromeos::network_diagnostics::mojom::RoutineProblems;
-  using HttpsLatencyProblemMojom =
-      chromeos::network_diagnostics::mojom::HttpsLatencyProblem;
-  using RoutineVerdictMojom =
-      chromeos::network_diagnostics::mojom::RoutineVerdict;
+  CHECK(!routine_result.is_null());
+
+  if (!routine_result->result_value.is_null() &&
+      routine_result->result_value->is_https_latency_result_value()) {
+    https_latency_data->set_latency_ms(
+        routine_result->result_value->get_https_latency_result_value()
+            ->latency.InMilliseconds());
+  }
 
   switch (routine_result->verdict) {
-    case RoutineVerdictMojom::kNoProblem:
+    case network_diagnostics_mojom::RoutineVerdict::kNoProblem:
       https_latency_data->set_verdict(RoutineVerdict::NO_PROBLEM);
       break;
-    case RoutineVerdictMojom::kProblem:
+    case network_diagnostics_mojom::RoutineVerdict::kProblem:
       https_latency_data->set_verdict(RoutineVerdict::PROBLEM);
       break;
-    case RoutineVerdictMojom::kNotRun:
+    case network_diagnostics_mojom::RoutineVerdict::kNotRun:
       https_latency_data->set_verdict(RoutineVerdict::NOT_RUN);
       break;
   }
 
   if (!routine_result->problems ||
-      routine_result->problems->which() !=
-          RoutineProblems::Tag::HTTPS_LATENCY_PROBLEMS ||
+      !routine_result->problems->is_https_latency_problems() ||
       routine_result->problems->get_https_latency_problems().empty()) {
     return;
   }
@@ -44,30 +48,35 @@
   const auto& problems = routine_result->problems->get_https_latency_problems();
   // Only one problem is expected for HttpsLatencyRoutine if any.
   switch (problems[0]) {
-    case HttpsLatencyProblemMojom::kFailedDnsResolutions:
+    case network_diagnostics_mojom::HttpsLatencyProblem::kFailedDnsResolutions:
       https_latency_data->set_problem(
           HttpsLatencyProblem::FAILED_DNS_RESOLUTIONS);
       break;
-    case HttpsLatencyProblemMojom::kFailedHttpsRequests:
+    case network_diagnostics_mojom::HttpsLatencyProblem::kFailedHttpsRequests:
       https_latency_data->set_problem(
           HttpsLatencyProblem::FAILED_HTTPS_REQUESTS);
       break;
-    case HttpsLatencyProblemMojom::kHighLatency:
+    case network_diagnostics_mojom::HttpsLatencyProblem::kHighLatency:
       https_latency_data->set_problem(HttpsLatencyProblem::HIGH_LATENCY);
       break;
-    case HttpsLatencyProblemMojom::kVeryHighLatency:
+    case network_diagnostics_mojom::HttpsLatencyProblem::kVeryHighLatency:
       https_latency_data->set_problem(HttpsLatencyProblem::VERY_HIGH_LATENCY);
       break;
   }
 }
 }  // namespace
 
-HttpsLatencySampler::HttpsLatencySampler() {
+void HttpsLatencySampler::Delegate::BindDiagnosticsReceiver(
+    mojo::PendingReceiver<
+        ::chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines>
+        receiver) {
+  chromeos::network_health::NetworkHealthService::GetInstance()
+      ->BindDiagnosticsReceiver(std::move(receiver));
+}
+
+HttpsLatencySampler::HttpsLatencySampler(std::unique_ptr<Delegate> delegate)
+    : delegate_(std::move(delegate)) {
   DETACH_FROM_SEQUENCE(sequence_checker_);
-  https_latency_routine_getter_ = base::BindRepeating([]() {
-    return std::make_unique<
-        chromeos::network_diagnostics::HttpsLatencyRoutine>();
-  });
 }
 
 HttpsLatencySampler::~HttpsLatencySampler() {
@@ -83,26 +92,23 @@
     return;
   }
 
-  https_latency_routine_ = https_latency_routine_getter_.Run();
-  chromeos::network_diagnostics::RoutineResultCallback routine_callback =
+  if (!network_diagnostics_service_.is_bound()) {
+    delegate_->BindDiagnosticsReceiver(
+        network_diagnostics_service_.BindNewPipeAndPassReceiver());
+  }
+  auto routine_callback =
       base::BindOnce(&HttpsLatencySampler::OnHttpsLatencyRoutineCompleted,
                      weak_ptr_factory_.GetWeakPtr());
-  https_latency_routine_->RunRoutine(base::BindPostTask(
+  network_diagnostics_service_->RunHttpsLatency(base::BindPostTask(
       base::SequencedTaskRunnerHandle::Get(), std::move(routine_callback)));
 
   is_routine_running_ = true;
 }
 
-void HttpsLatencySampler::SetHttpsLatencyRoutineGetterForTest(
-    HttpsLatencyRoutineGetter https_latency_routine_getter) {
-  https_latency_routine_getter_ = std::move(https_latency_routine_getter);
-}
-
 void HttpsLatencySampler::OnHttpsLatencyRoutineCompleted(
-    RoutineResultPtr routine_result) {
+    ::chromeos::network_diagnostics::mojom::RoutineResultPtr routine_result) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  https_latency_routine_.reset();
   is_routine_running_ = false;
 
   MetricData metric_data;
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h
index a13098b..69c41db0 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h
@@ -5,38 +5,47 @@
 #ifndef CHROME_BROWSER_ASH_POLICY_REPORTING_METRICS_REPORTING_NETWORK_HTTPS_LATENCY_SAMPLER_H_
 #define CHROME_BROWSER_ASH_POLICY_REPORTING_METRICS_REPORTING_NETWORK_HTTPS_LATENCY_SAMPLER_H_
 
-#include "base/callback.h"
+#include <memory>
+
 #include "base/containers/queue.h"
+#include "base/memory/weak_ptr.h"
+#include "base/sequence_checker.h"
 #include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h"
 #include "components/reporting/metrics/metric_data_collector.h"
 #include "components/reporting/metrics/sampler.h"
-#include "components/reporting/proto/synced/metric_data.pb.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace chromeos {
-namespace network_diagnostics {
-
-class HttpsLatencyRoutine;
-
-}  // namespace network_diagnostics
-}  // namespace chromeos
-
 namespace reporting {
 
-using HttpsLatencyRoutineGetter = base::RepeatingCallback<
-    std::unique_ptr<chromeos::network_diagnostics::HttpsLatencyRoutine>()>;
+class MetricData;
 
 // `HttpsLatencySampler` collects a sample of the current network latency by
-// invoking the `HttpsLatencyRoutine` and parsing its results, no info is
-// collected by this sampler only telemetry is collected.
+// running https latency test of `NetworkDiagnosticsRoutines` parsing its
+// results. A single `HttpsLatencySampler` instance can be shared between
+// multiple consumers, and overlapping `Collect` calls will share the same
+// routine run and result.
 class HttpsLatencySampler : public Sampler {
-  using HttpsLatencyRoutine =
-      chromeos::network_diagnostics::HttpsLatencyRoutine;
-  using RoutineResultPtr =
-      chromeos::network_diagnostics::mojom::RoutineResultPtr;
-
  public:
-  HttpsLatencySampler();
+  class Delegate {
+   public:
+    Delegate() = default;
+
+    Delegate(const Delegate&) = delete;
+    Delegate& operator=(const Delegate&) = delete;
+
+    virtual ~Delegate() = default;
+
+    virtual void BindDiagnosticsReceiver(
+        mojo::PendingReceiver<
+            ::chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines>
+            receiver);
+  };
+
+  // Default arg is used in prod and set in test.
+  explicit HttpsLatencySampler(
+      std::unique_ptr<Delegate> delegate = std::make_unique<Delegate>());
 
   HttpsLatencySampler(const HttpsLatencySampler&) = delete;
   HttpsLatencySampler& operator=(const HttpsLatencySampler&) = delete;
@@ -45,18 +54,19 @@
 
   void Collect(MetricCallback callback) override;
 
-  void SetHttpsLatencyRoutineGetterForTest(
-      HttpsLatencyRoutineGetter https_latency_routine_getter);
-
  private:
-  void OnHttpsLatencyRoutineCompleted(RoutineResultPtr routine_result);
+  void OnHttpsLatencyRoutineCompleted(
+      ::chromeos::network_diagnostics::mojom::RoutineResultPtr routine_result);
 
   bool is_routine_running_ = false;
 
-  HttpsLatencyRoutineGetter https_latency_routine_getter_;
-  std::unique_ptr<HttpsLatencyRoutine> https_latency_routine_;
+  mojo::Remote<
+      ::chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines>
+      network_diagnostics_service_;
   base::queue<MetricCallback> metric_callbacks_;
 
+  const std::unique_ptr<Delegate> delegate_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<HttpsLatencySampler> weak_ptr_factory_{this};
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler_unittest.cc
index 56d9a52..c87c5b2 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler_unittest.cc
@@ -4,174 +4,287 @@
 
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/network/https_latency_sampler.h"
 
-#include "base/test/bind.h"
+#include <memory>
+#include <utility>
+
+#include "base/location.h"
+#include "base/run_loop.h"
 #include "base/test/task_environment.h"
-#include "chrome/browser/ash/net/network_diagnostics/https_latency_routine.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/time.h"
+#include "chrome/browser/ash/net/network_diagnostics/network_diagnostics.h"
+#include "chromeos/dbus/debug_daemon/fake_debug_daemon_client.h"
+#include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h"
 #include "components/reporting/proto/synced/metric_data.pb.h"
 #include "components/reporting/util/test_support_callbacks.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
-namespace reporting {
+using ::chromeos::network_diagnostics::NetworkDiagnostics;
+using ::chromeos::network_diagnostics::mojom::HttpsLatencyResultValue;
+using ::chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines;
+using ::chromeos::network_diagnostics::mojom::RoutineProblems;
+using ::chromeos::network_diagnostics::mojom::RoutineResult;
+using ::chromeos::network_diagnostics::mojom::RoutineResultValue;
 
+using HttpsLatencyProblemMojom =
+    ::chromeos::network_diagnostics::mojom::HttpsLatencyProblem;
+using RoutineVerdictMojom =
+    ::chromeos::network_diagnostics::mojom::RoutineVerdict;
+
+namespace reporting {
 namespace {
 
-using HttpsLatencyRoutine = chromeos::network_diagnostics::HttpsLatencyRoutine;
-
-std::unique_ptr<HttpsLatencyRoutine> HttpsLatencyRoutineGetterTestHelper(
-    std::unique_ptr<HttpsLatencyRoutine> routine) {
-  return routine;
-}
-}  // namespace
-
-class FakeHttpsLatencyRoutine
-    : public chromeos::network_diagnostics::HttpsLatencyRoutine {
+class FakeNetworkDiagnostics : public NetworkDiagnostics {
  public:
-  FakeHttpsLatencyRoutine() {
-    set_verdict(
-        chromeos::network_diagnostics::mojom::RoutineVerdict::kNoProblem);
+  FakeNetworkDiagnostics() : NetworkDiagnostics(&fake_debug_daemon_client_) {}
+
+  FakeNetworkDiagnostics(const FakeNetworkDiagnostics&) = delete;
+  FakeNetworkDiagnostics& operator=(const FakeNetworkDiagnostics&) = delete;
+
+  ~FakeNetworkDiagnostics() override = default;
+
+  void RunHttpsLatency(RunHttpsLatencyCallback callback) override {
+    ASSERT_FALSE(callback_);
+    callback_ = std::move(callback);
   }
 
-  FakeHttpsLatencyRoutine(
-      chromeos::network_diagnostics::mojom::RoutineVerdict verdict,
-      chromeos::network_diagnostics::mojom::HttpsLatencyProblem problem) {
-    using chromeos::network_diagnostics::mojom::HttpsLatencyProblem;
-    using chromeos::network_diagnostics::mojom::RoutineProblems;
-
-    set_verdict(verdict);
-    std::vector<HttpsLatencyProblem> problems;
-    problems.emplace_back(problem);
-    set_problems(RoutineProblems::NewHttpsLatencyProblems(problems));
+  void ExecuteCallback() {
+    // Block until all previously posted tasks are executed to make sure
+    // `RunHttpsLatency` is called and `callback_` is set.
+    base::RunLoop run_loop;
+    base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+                                                     run_loop.QuitClosure());
+    run_loop.Run();
+    ASSERT_TRUE(callback_);
+    std::move(callback_).Run(routine_result_.Clone());
   }
 
-  ~FakeHttpsLatencyRoutine() override = default;
+  void SetReceiver(
+      mojo::PendingReceiver<NetworkDiagnosticsRoutines> pending_receiver) {
+    receiver_ = std::make_unique<mojo::Receiver<NetworkDiagnosticsRoutines>>(
+        this, std::move(pending_receiver));
+  }
 
-  void Run() override {}
+  void SetResultNoProblem(int latency_ms) {
+    routine_result_.result_value =
+        RoutineResultValue::NewHttpsLatencyResultValue(
+            HttpsLatencyResultValue::New(base::Milliseconds(latency_ms)));
+    routine_result_.verdict = RoutineVerdictMojom::kNoProblem;
+    routine_result_.problems = RoutineProblems::NewHttpsLatencyProblems({});
+  }
 
-  void AnalyzeResultsAndExecuteCallback() override { ExecuteCallback(); }
+  void SetResultProblem(HttpsLatencyProblemMojom problem) {
+    routine_result_.problems =
+        RoutineProblems::NewHttpsLatencyProblems({problem});
+    routine_result_.verdict = RoutineVerdictMojom::kProblem;
+  }
+
+  void SetResultProblemLatency(HttpsLatencyProblemMojom problem,
+                               int latency_ms) {
+    routine_result_.result_value =
+        RoutineResultValue::NewHttpsLatencyResultValue(
+            HttpsLatencyResultValue::New(base::Milliseconds(latency_ms)));
+    SetResultProblem(problem);
+  }
+
+ private:
+  RoutineResult routine_result_;
+
+  std::unique_ptr<mojo::Receiver<NetworkDiagnosticsRoutines>> receiver_;
+
+  RunHttpsLatencyCallback callback_;
+
+  ::chromeos::FakeDebugDaemonClient fake_debug_daemon_client_;
+};
+
+class FakeHttpsLatencyDelegate : public HttpsLatencySampler::Delegate {
+ public:
+  explicit FakeHttpsLatencyDelegate(FakeNetworkDiagnostics* fake_diagnostics)
+      : fake_diagnostics_(fake_diagnostics) {}
+
+  FakeHttpsLatencyDelegate(const FakeHttpsLatencyDelegate&) = delete;
+  FakeHttpsLatencyDelegate& operator=(const FakeHttpsLatencyDelegate&) = delete;
+
+  ~FakeHttpsLatencyDelegate() override = default;
+
+  void BindDiagnosticsReceiver(mojo::PendingReceiver<NetworkDiagnosticsRoutines>
+                                   pending_receiver) override {
+    fake_diagnostics_->SetReceiver(std::move(pending_receiver));
+  }
+
+ private:
+  FakeNetworkDiagnostics* const fake_diagnostics_;
 };
 
 TEST(HttpsLatencySamplerTest, NoProblem) {
   base::test::SingleThreadTaskEnvironment task_environment;
 
-  auto routine = std::make_unique<FakeHttpsLatencyRoutine>();
-  auto* routine_ptr = routine.get();
-
-  auto sampler = std::make_unique<HttpsLatencySampler>();
-  sampler->SetHttpsLatencyRoutineGetterForTest(base::BindRepeating(
-      &HttpsLatencyRoutineGetterTestHelper, base::Passed(std::move(routine))));
+  FakeNetworkDiagnostics diagnostics;
+  int latency_ms = 100;
+  diagnostics.SetResultNoProblem(latency_ms);
+  HttpsLatencySampler sampler(
+      std::make_unique<FakeHttpsLatencyDelegate>(&diagnostics));
 
   test::TestEvent<MetricData> metric_collect_event;
-  sampler->Collect(metric_collect_event.cb());
-  routine_ptr->AnalyzeResultsAndExecuteCallback();
+  sampler.Collect(metric_collect_event.cb());
+  diagnostics.ExecuteCallback();
   const auto metric_result = metric_collect_event.result();
-  ASSERT_TRUE(metric_result.has_telemetry_data());
-  const TelemetryData& result = metric_result.telemetry_data();
 
-  EXPECT_EQ(result.networks_telemetry().https_latency_data().verdict(),
+  ASSERT_TRUE(metric_result.has_telemetry_data());
+  EXPECT_EQ(metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .verdict(),
             RoutineVerdict::NO_PROBLEM);
+  EXPECT_EQ(metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .latency_ms(),
+            latency_ms);
+  EXPECT_FALSE(metric_result.telemetry_data()
+                   .networks_telemetry()
+                   .https_latency_data()
+                   .has_problem());
 }
 
 TEST(HttpsLatencySamplerTest, FailedRequests) {
-  using HttpsLatencyProblemMojom =
-      chromeos::network_diagnostics::mojom::HttpsLatencyProblem;
-  using RoutineVerdictMojom =
-      chromeos::network_diagnostics::mojom::RoutineVerdict;
-
   base::test::SingleThreadTaskEnvironment task_environment;
 
-  auto routine = std::make_unique<FakeHttpsLatencyRoutine>(
-      RoutineVerdictMojom::kProblem,
-      HttpsLatencyProblemMojom::kFailedHttpsRequests);
-  auto* routine_ptr = routine.get();
-
-  auto sampler = std::make_unique<HttpsLatencySampler>();
-  sampler->SetHttpsLatencyRoutineGetterForTest(base::BindRepeating(
-      &HttpsLatencyRoutineGetterTestHelper, base::Passed(std::move(routine))));
+  FakeNetworkDiagnostics diagnostics;
+  diagnostics.SetResultProblem(HttpsLatencyProblemMojom::kFailedHttpsRequests);
+  HttpsLatencySampler sampler(
+      std::make_unique<FakeHttpsLatencyDelegate>(&diagnostics));
 
   test::TestEvent<MetricData> metric_collect_event;
-  sampler->Collect(metric_collect_event.cb());
-  routine_ptr->AnalyzeResultsAndExecuteCallback();
+  sampler.Collect(metric_collect_event.cb());
+  diagnostics.ExecuteCallback();
   const auto metric_result = metric_collect_event.result();
-  ASSERT_TRUE(metric_result.has_telemetry_data());
-  const TelemetryData& result = metric_result.telemetry_data();
 
-  EXPECT_EQ(result.networks_telemetry().https_latency_data().verdict(),
+  ASSERT_TRUE(metric_result.has_telemetry_data());
+  EXPECT_EQ(metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .verdict(),
             RoutineVerdict::PROBLEM);
-  EXPECT_EQ(result.networks_telemetry().https_latency_data().problem(),
+  EXPECT_FALSE(metric_result.telemetry_data()
+                   .networks_telemetry()
+                   .https_latency_data()
+                   .has_latency_ms());
+  EXPECT_EQ(metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .problem(),
             HttpsLatencyProblem::FAILED_HTTPS_REQUESTS);
 }
 
 TEST(HttpsLatencySamplerTest, OverlappingCalls) {
-  using HttpsLatencyProblemMojom =
-      chromeos::network_diagnostics::mojom::HttpsLatencyProblem;
-  using RoutineVerdictMojom =
-      chromeos::network_diagnostics::mojom::RoutineVerdict;
-
   base::test::SingleThreadTaskEnvironment task_environment;
 
-  auto routine = std::make_unique<FakeHttpsLatencyRoutine>(
-      RoutineVerdictMojom::kProblem,
-      HttpsLatencyProblemMojom::kFailedDnsResolutions);
-  auto* routine_ptr = routine.get();
+  FakeNetworkDiagnostics diagnostics;
+  diagnostics.SetResultProblem(HttpsLatencyProblemMojom::kFailedDnsResolutions);
+  HttpsLatencySampler sampler(
+      std::make_unique<FakeHttpsLatencyDelegate>(&diagnostics));
 
-  auto sampler = std::make_unique<HttpsLatencySampler>();
-  sampler->SetHttpsLatencyRoutineGetterForTest(base::BindRepeating(
-      &HttpsLatencyRoutineGetterTestHelper, base::Passed(std::move(routine))));
   test::TestEvent<MetricData> metric_collect_events[2];
-  for (int i = 0; i < 2; ++i) {
-    sampler->Collect(metric_collect_events[i].cb());
-  }
-  routine_ptr->AnalyzeResultsAndExecuteCallback();
+  sampler.Collect(metric_collect_events[0].cb());
+  sampler.Collect(metric_collect_events[1].cb());
+  diagnostics.ExecuteCallback();
 
-  for (int i = 0; i < 2; ++i) {
-    const auto metric_result = metric_collect_events[i].result();
-    ASSERT_TRUE(metric_result.has_telemetry_data());
-    const TelemetryData& result = metric_result.telemetry_data();
+  const auto first_metric_result = metric_collect_events[0].result();
+  ASSERT_TRUE(first_metric_result.has_telemetry_data());
+  EXPECT_EQ(first_metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .verdict(),
+            RoutineVerdict::PROBLEM);
+  EXPECT_FALSE(first_metric_result.telemetry_data()
+                   .networks_telemetry()
+                   .https_latency_data()
+                   .has_latency_ms());
+  EXPECT_EQ(first_metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .problem(),
+            HttpsLatencyProblem::FAILED_DNS_RESOLUTIONS);
 
-    EXPECT_EQ(result.networks_telemetry().https_latency_data().verdict(),
-              RoutineVerdict::PROBLEM);
-    EXPECT_EQ(result.networks_telemetry().https_latency_data().problem(),
-              HttpsLatencyProblem::FAILED_DNS_RESOLUTIONS);
-  }
+  const auto second_metric_result = metric_collect_events[1].result();
+  ASSERT_TRUE(second_metric_result.has_telemetry_data());
+  EXPECT_EQ(second_metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .verdict(),
+            RoutineVerdict::PROBLEM);
+  EXPECT_FALSE(second_metric_result.telemetry_data()
+                   .networks_telemetry()
+                   .https_latency_data()
+                   .has_latency_ms());
+  EXPECT_EQ(second_metric_result.telemetry_data()
+                .networks_telemetry()
+                .https_latency_data()
+                .problem(),
+            HttpsLatencyProblem::FAILED_DNS_RESOLUTIONS);
 }
 
 TEST(HttpsLatencySamplerTest, SuccessiveCalls) {
-  using HttpsLatencyProblemMojom =
-      chromeos::network_diagnostics::mojom::HttpsLatencyProblem;
-  using RoutineVerdictMojom =
-      chromeos::network_diagnostics::mojom::RoutineVerdict;
-
   base::test::SingleThreadTaskEnvironment task_environment;
 
-  HttpsLatencyProblemMojom problems[] = {
-      HttpsLatencyProblemMojom::kHighLatency,
-      HttpsLatencyProblemMojom::kVeryHighLatency};
-  HttpsLatencyProblem expected_problems[] = {
-      HttpsLatencyProblem::HIGH_LATENCY,
-      HttpsLatencyProblem::VERY_HIGH_LATENCY};
+  FakeNetworkDiagnostics diagnostics;
+  HttpsLatencySampler sampler(
+      std::make_unique<FakeHttpsLatencyDelegate>(&diagnostics));
 
-  auto sampler = std::make_unique<HttpsLatencySampler>();
-  for (int i = 0; i < 2; ++i) {
-    auto routine = std::make_unique<FakeHttpsLatencyRoutine>(
-        RoutineVerdictMojom::kProblem, problems[i]);
-    auto* routine_ptr = routine.get();
-
-    sampler->SetHttpsLatencyRoutineGetterForTest(
-        base::BindRepeating(&HttpsLatencyRoutineGetterTestHelper,
-                            base::Passed(std::move(routine))));
-
+  {
+    const int latency_ms = 1000;
+    diagnostics.SetResultProblemLatency(HttpsLatencyProblemMojom::kHighLatency,
+                                        latency_ms);
     test::TestEvent<MetricData> metric_collect_event;
-    sampler->Collect(metric_collect_event.cb());
-    routine_ptr->AnalyzeResultsAndExecuteCallback();
-    const auto metric_result = metric_collect_event.result();
-    ASSERT_TRUE(metric_result.has_telemetry_data());
-    const TelemetryData& result = metric_result.telemetry_data();
+    sampler.Collect(metric_collect_event.cb());
+    diagnostics.ExecuteCallback();
+    const auto first_metric_result = metric_collect_event.result();
 
-    EXPECT_EQ(result.networks_telemetry().https_latency_data().verdict(),
+    ASSERT_TRUE(first_metric_result.has_telemetry_data());
+    EXPECT_EQ(first_metric_result.telemetry_data()
+                  .networks_telemetry()
+                  .https_latency_data()
+                  .verdict(),
               RoutineVerdict::PROBLEM);
-    EXPECT_EQ(result.networks_telemetry().https_latency_data().problem(),
-              expected_problems[i]);
+    EXPECT_EQ(first_metric_result.telemetry_data()
+                  .networks_telemetry()
+                  .https_latency_data()
+                  .latency_ms(),
+              latency_ms);
+    EXPECT_EQ(first_metric_result.telemetry_data()
+                  .networks_telemetry()
+                  .https_latency_data()
+                  .problem(),
+              HttpsLatencyProblem::HIGH_LATENCY);
+  }
+
+  {
+    const int latency_ms = 5000;
+    diagnostics.SetResultProblemLatency(
+        HttpsLatencyProblemMojom::kVeryHighLatency, latency_ms);
+    test::TestEvent<MetricData> metric_collect_event;
+    sampler.Collect(metric_collect_event.cb());
+    diagnostics.ExecuteCallback();
+    const auto second_metric_result = metric_collect_event.result();
+
+    ASSERT_TRUE(second_metric_result.has_telemetry_data());
+    EXPECT_EQ(second_metric_result.telemetry_data()
+                  .networks_telemetry()
+                  .https_latency_data()
+                  .verdict(),
+              RoutineVerdict::PROBLEM);
+    EXPECT_EQ(second_metric_result.telemetry_data()
+                  .networks_telemetry()
+                  .https_latency_data()
+                  .latency_ms(),
+              latency_ms);
+    EXPECT_EQ(second_metric_result.telemetry_data()
+                  .networks_telemetry()
+                  .https_latency_data()
+                  .problem(),
+              HttpsLatencyProblem::VERY_HIGH_LATENCY);
   }
 }
 
@@ -286,4 +399,5 @@
   ASSERT_TRUE(event_type.has_value());
   EXPECT_EQ(event_type.value(), expected_event_type);
 }
+}  // namespace
 }  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc
index 0fed5b6..f9ccbc1 100644
--- a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc
+++ b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.cc
@@ -8,25 +8,14 @@
 
 #include "base/logging.h"
 #include "chrome/browser/ash/login/users/chrome_user_manager.h"
-#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "components/reporting/client/report_queue_factory.h"
 
 namespace reporting {
 
 UserEventReporterHelper::UserEventReporterHelper(Destination destination)
-    : report_queue_(std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter>(
-          nullptr,
-          base::OnTaskRunnerDeleter(base::SequencedTaskRunnerHandle::Get()))) {
-  policy::DMToken dm_token = GetDMToken();
-  if (!dm_token.is_valid()) {
-    DVLOG(1) << "Cannot initialize user event reporter. Invalid DMToken.";
-    return;
-  }
-  report_queue_ = ReportQueueFactory::CreateSpeculativeReportQueue(
-      dm_token.value(), destination);
-}
+    : report_queue_(
+          ReportQueueFactory::CreateSpeculativeReportQueue(EventType::kDevice,
+                                                           destination)) {}
 
 UserEventReporterHelper::UserEventReporterHelper(
     std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter> report_queue)
@@ -65,23 +54,4 @@
 bool UserEventReporterHelper::IsCurrentUserNew() const {
   return user_manager::UserManager::Get()->IsCurrentUserNew();
 }
-
-// static
-policy::DMToken UserEventReporterHelper::GetDMToken() {
-  policy::DMToken dm_token(policy::DMToken::Status::kEmpty, "");
-
-  auto* const connector =
-      g_browser_process->platform_part()->browser_policy_connector_ash();
-  if (!connector) {
-    return dm_token;
-  }
-
-  auto* const policy_manager = connector->GetDeviceCloudPolicyManager();
-  if (policy_manager && policy_manager->IsClientRegistered()) {
-    dm_token = policy::DMToken(policy::DMToken::Status::kValid,
-                               policy_manager->core()->client()->dm_token());
-  }
-
-  return dm_token;
-}
 }  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h
index e4a30d8..cd3e3fda 100644
--- a/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h
+++ b/chrome/browser/ash/policy/reporting/user_event_reporter_helper.h
@@ -7,8 +7,8 @@
 
 #include <memory>
 
-#include "base/strings/string_piece_forward.h"
-#include "components/policy/core/common/cloud/dm_token.h"
+#include "base/task/sequenced_task_runner.h"
+#include "components/reporting/client/report_queue.h"
 #include "components/reporting/client/report_queue_provider.h"
 
 namespace reporting {
@@ -40,10 +40,7 @@
   virtual bool IsCurrentUserNew() const;
 
  private:
-  // Returns the device DM token.
-  static policy::DMToken GetDMToken();
-
-  std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter> report_queue_;
+  const std::unique_ptr<ReportQueue, base::OnTaskRunnerDeleter> report_queue_;
 };
 }  // namespace reporting
 
diff --git a/chrome/browser/ash/web_applications/file_manager_web_app_info.cc b/chrome/browser/ash/web_applications/file_manager_web_app_info.cc
index 10f08e8..4000282 100644
--- a/chrome/browser/ash/web_applications/file_manager_web_app_info.cc
+++ b/chrome/browser/ash/web_applications/file_manager_web_app_info.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "ash/constants/ash_features.h"
+#include "ash/style/ash_color_provider.h"
 #include "ash/webui/file_manager/resources/grit/file_manager_swa_resources.h"
 #include "ash/webui/file_manager/url_constants.h"
 #include "base/strings/utf_string_conversions.h"
@@ -17,6 +18,7 @@
 #include "extensions/common/constants.h"
 #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/chromeos/styles/cros_styles.h"
 #include "ui/file_manager/grit/file_manager_resources.h"
 
 using ash::file_manager::kChromeUIFileManagerURL;
@@ -65,8 +67,14 @@
           {"icon256.png", 256, IDR_FILE_MANAGER_ICON_256},
       },
       *info);
-  info->theme_color = 0xFFFFFFFF;
-  info->background_color = 0xFFFFFFFF;
+
+  auto* color_provider = ash::AshColorProvider::Get();
+  info->theme_color =
+      color_provider->GetBackgroundColorInMode(/*use_dark_mode=*/false);
+  info->dark_mode_theme_color =
+      color_provider->GetBackgroundColorInMode(/*use_dark_mode=*/true);
+  info->background_color = info->theme_color;
+  info->dark_mode_background_color = info->dark_mode_theme_color;
   info->display_mode = blink::mojom::DisplayMode::kStandalone;
   info->user_display_mode = blink::mojom::DisplayMode::kStandalone;
 
diff --git a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc
index c24d301..6465c42 100644
--- a/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc
+++ b/chrome/browser/ash/web_applications/personalization_app/chrome_personalization_app_ui_delegate.cc
@@ -329,7 +329,8 @@
   std::vector<ash::OnlineWallpaperVariant> variants;
   for (auto entry : image_asset_id_map_) {
     const ImageInfo& image_info = entry.second;
-    if (image_info.unit_id == it->second.unit_id) {
+    if (image_info.unit_id == it->second.unit_id &&
+        image_info.collection_id == it->second.collection_id) {
       variants.emplace_back(image_info.asset_id, image_info.image_url,
                             image_info.type);
     }
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn b/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn
index 09f1c0e..8e49b54 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn
+++ b/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn
@@ -12,6 +12,8 @@
 
 source_set("api") {
   sources = [
+    "api_guard_delegate.cc",
+    "api_guard_delegate.h",
     "base_telemetry_extension_api_guard_function.cc",
     "base_telemetry_extension_api_guard_function.h",
     "diagnostics_api.cc",
@@ -28,6 +30,7 @@
     "//ash/webui/telemetry_extension_ui/mojom",
     "//ash/webui/telemetry_extension_ui/services:telemetry_services",
     "//base",
+    "//chrome/browser/extensions",
     "//chrome/browser/profiles:profile",
     "//chrome/browser/ui",
     "//chrome/common/chromeos/extensions",
@@ -63,6 +66,8 @@
     "base_telemetry_extension_browser_test.cc",
     "base_telemetry_extension_browser_test.h",
     "diagnostics_api_browsertest.cc",
+    "fake_api_guard_delegate.cc",
+    "fake_api_guard_delegate.h",
     "fake_hardware_info_delegate.cc",
     "fake_hardware_info_delegate.h",
     "telemetry_api_browsertest.cc",
@@ -80,7 +85,9 @@
     "//chromeos/dbus/debug_daemon",
     "//chromeos/services/cros_healthd/public/cpp",
     "//chromeos/services/cros_healthd/public/mojom",
+    "//components/user_manager",
     "//extensions:test_support",
+    "//extensions/browser",
     "//extensions/browser:test_support",
     "//extensions/common",
     "//url",
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.cc b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.cc
new file mode 100644
index 0000000..00cd549a
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.cc
@@ -0,0 +1,50 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
+
+#include <string>
+
+#include "base/memory/ptr_util.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/extension_management.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace chromeos {
+
+// static
+ApiGuardDelegate::Factory* ApiGuardDelegate::Factory::test_factory_ = nullptr;
+
+// static
+std::unique_ptr<ApiGuardDelegate> ApiGuardDelegate::Factory::Create() {
+  if (test_factory_) {
+    return test_factory_->CreateInstance();
+  }
+  return base::WrapUnique<ApiGuardDelegate>(new ApiGuardDelegate());
+}
+
+// static
+void ApiGuardDelegate::Factory::SetForTesting(Factory* test_factory) {
+  test_factory_ = test_factory;
+}
+
+ApiGuardDelegate::Factory::Factory() = default;
+ApiGuardDelegate::Factory::~Factory() = default;
+
+ApiGuardDelegate::ApiGuardDelegate() = default;
+ApiGuardDelegate::~ApiGuardDelegate() = default;
+
+bool ApiGuardDelegate::IsExtensionForceInstalled(
+    content::BrowserContext* context,
+    const std::string& extension_id) {
+  const auto force_install_list =
+      extensions::ExtensionManagementFactory::GetForBrowserContext(context)
+          ->GetForceInstallList();
+  return force_install_list->FindKey(extension_id) != nullptr;
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h
new file mode 100644
index 0000000..bd916fadf
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h
@@ -0,0 +1,49 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_API_GUARD_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_API_GUARD_DELEGATE_H_
+
+#include <memory>
+#include <string>
+
+namespace content {
+class BrowserContext;
+}
+
+namespace chromeos {
+
+// ApiGuardDelegate is a helper class to offload API guard checks and make it
+// test-friendly. E.g. check if the extension is force installed by policy.
+class ApiGuardDelegate {
+ public:
+  class Factory {
+   public:
+    static std::unique_ptr<ApiGuardDelegate> Create();
+    static void SetForTesting(Factory* test_factory);
+
+    virtual ~Factory();
+
+   protected:
+    Factory();
+    virtual std::unique_ptr<ApiGuardDelegate> CreateInstance() = 0;
+
+   private:
+    static Factory* test_factory_;
+  };
+
+  ApiGuardDelegate(const ApiGuardDelegate&) = delete;
+  ApiGuardDelegate& operator=(const ApiGuardDelegate&) = delete;
+  virtual ~ApiGuardDelegate();
+
+  virtual bool IsExtensionForceInstalled(content::BrowserContext* context,
+                                         const std::string& extension_id);
+
+ protected:
+  ApiGuardDelegate();
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_API_GUARD_DELEGATE_H_
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
new file mode 100644
index 0000000..a310c53e
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc
@@ -0,0 +1,58 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/values.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
+#include "chrome/browser/extensions/extension_management_test_util.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "content/public/test/browser_task_environment.h"
+#include "extensions/common/extension_urls.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace {
+
+constexpr char kExtensionId[] = "gogonhoemckpdpadfnjnpgbjpbjnodgc";
+
+}  // namespace
+
+class ApiGuardDelegateTest : public testing::Test {
+ public:
+  ApiGuardDelegateTest()
+      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {}
+  ~ApiGuardDelegateTest() override = default;
+
+ protected:
+  content::BrowserTaskEnvironment task_environment_;
+  TestingProfile profile_;
+};
+
+TEST_F(ApiGuardDelegateTest, IsExtensionForceInstalledFalse) {
+  EXPECT_FALSE(ApiGuardDelegate::Factory::Create()->IsExtensionForceInstalled(
+      &profile_, kExtensionId));
+}
+
+TEST_F(ApiGuardDelegateTest, IsExtensionForceInstalledTrue) {
+  {
+    extensions::ExtensionManagementPrefUpdater<
+        sync_preferences::TestingPrefServiceSyncable>
+        updater(profile_.GetTestingPrefService());
+    updater.SetIndividualExtensionAutoInstalled(
+        kExtensionId, extension_urls::kChromeWebstoreUpdateURL,
+        /*forced=*/true);
+  }
+
+  EXPECT_TRUE(ApiGuardDelegate::Factory::Create()->IsExtensionForceInstalled(
+      &profile_, kExtensionId));
+
+  // Make sure IsExtensionForceInstalled() doesn't return true blindly.
+  EXPECT_FALSE(ApiGuardDelegate::Factory::Create()->IsExtensionForceInstalled(
+      &profile_, "alnedpmllcfpgldkagbfbjkloonjlfjb"));
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function.cc
index d6286e4..a65e542 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function.cc
@@ -4,18 +4,23 @@
 
 #include "chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function.h"
 
+#include <memory>
 #include <string>
 
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/hardware_info_delegate.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chromeos/extensions/chromeos_system_extension_info.h"
+#include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/web_contents.h"
 #include "extensions/browser/extension_function.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/management_policy.h"
 #include "extensions/common/manifest_handlers/externally_connectable.h"
 #include "url/gurl.h"
 
@@ -28,7 +33,19 @@
 
 ExtensionFunction::ResponseAction
 BaseTelemetryExtensionApiGuardFunction::Run() {
-  if (!user_manager::UserManager::Get()->IsCurrentUserOwner()) {
+  // As agreed with the privacy team, a user can access telemetry APIs in one of
+  // the following cases:
+  // 1. The user is managed and the extension was force-installed via policy.
+  // 2. The user is the device owner.
+  if (user_manager::UserManager::Get()->GetActiveUser()->IsAffiliated()) {
+    if (!ApiGuardDelegate::Factory::Create()->IsExtensionForceInstalled(
+            browser_context(), extension_id())) {
+      return RespondNow(Error(
+          base::StringPrintf("Unauthorized access to chrome.%s. "
+                             "This extension is not installed by the admin",
+                             name())));
+    }
+  } else if (!user_manager::UserManager::Get()->IsCurrentUserOwner()) {
     return RespondNow(Error(
         base::StringPrintf("Unauthorized access to chrome.%s. "
                            "This extension is not run by the device owner",
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
index a00bdb1..35faec9 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
@@ -2,12 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+
 #include "base/strings/string_util.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/fake_hardware_info_delegate.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_test.h"
+#include "extensions/browser/test_management_policy.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
@@ -155,8 +160,7 @@
 IN_PROC_BROWSER_TEST_P(TelemetryExtensionApiGuardBrowserTest,
                        ActiveUserNotOwner) {
   // Make sure that current user is not a device owner.
-  auto* const user_manager =
-      static_cast<FakeChromeUserManager*>(user_manager::UserManager::Get());
+  auto* const user_manager = GetFakeUserManager();
   const AccountId regular_user = AccountId::FromUserEmail("regular@gmail.com");
   user_manager->AddUser(regular_user);
   user_manager->SetOwnerId(regular_user);
@@ -179,8 +183,33 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     TelemetryExtensionApiGuardBrowserTest,
-    testing::ValuesIn(
-        BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams));
+    testing::Combine(
+        testing::Values(false),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
+
+using TelemetryExtensionApiGuardManagedUserNotPolicyInstalledExtensionBrowserTest =
+    BaseTelemetryExtensionBrowserTest;
+
+IN_PROC_BROWSER_TEST_P(
+    TelemetryExtensionApiGuardManagedUserNotPolicyInstalledExtensionBrowserTest,
+    AffiliatedUserNotPolicyInstalledExtension) {
+  // Make sure that ApiGuardDelegate::IsExtensionForceInstalled() returns false.
+  api_guard_delegate_factory_ = std::make_unique<FakeApiGuardDelegate::Factory>(
+      /*is_extension_force_installed=*/false);
+  ApiGuardDelegate::Factory::SetForTesting(api_guard_delegate_factory_.get());
+
+  CreateExtensionAndRunServiceWorker(
+      GetServiceWorkerForError("This extension is not installed by the admin"));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    TelemetryExtensionApiGuardManagedUserNotPolicyInstalledExtensionBrowserTest,
+    testing::Combine(
+        testing::Values(true),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
 
 class TelemetryExtensionApiGuardWithoutPwaBrowserTest
     : public BaseTelemetryExtensionBrowserTest {
@@ -205,7 +234,9 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     TelemetryExtensionApiGuardWithoutPwaBrowserTest,
-    testing::ValuesIn(
-        BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams));
+    testing::Combine(
+        testing::Bool(),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
index 4f5295e..a2b798a 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
@@ -14,11 +14,18 @@
 #include "base/location.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
+#include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/fake_hardware_info_delegate.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/hardware_info_delegate.h"
 #include "chrome/common/chromeos/extensions/chromeos_system_extension_info.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/user_manager/scoped_user_manager.h"
+#include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/management_policy.h"
 #include "extensions/test/result_catcher.h"
 #include "extensions/test/test_extension_dir.h"
 #include "net/dns/mock_host_resolver.h"
@@ -64,11 +71,26 @@
 void BaseTelemetryExtensionBrowserTest::SetUpOnMainThread() {
   extensions::ExtensionBrowserTest::SetUpOnMainThread();
 
-  // Make sure that current user is a device owner.
-  auto* const user_manager =
-      static_cast<FakeChromeUserManager*>(user_manager::UserManager::Get());
-  user_manager->SetOwnerId(
-      user_manager::UserManager::Get()->GetActiveUser()->GetAccountId());
+  if (is_user_affiliated()) {
+    // Make sure that ApiGuardDelegate::IsExtensionForceInstalled returns true.
+    api_guard_delegate_factory_ =
+        std::make_unique<FakeApiGuardDelegate::Factory>(
+            /*is_extension_force_installed=*/true);
+    ApiGuardDelegate::Factory::SetForTesting(api_guard_delegate_factory_.get());
+  }
+
+  // Must be initialized before dealing with UserManager.
+  user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
+      std::make_unique<ash::FakeChromeUserManager>());
+  // Add a new user and make it active.
+  auto* const user_manager = GetFakeUserManager();
+  const AccountId account_id = AccountId::FromUserEmail("user@example.com");
+  user_manager->AddUserWithAffiliation(account_id,
+                                       /*is_affiliated=*/is_user_affiliated());
+  user_manager->LoginUser(account_id);
+  user_manager->SwitchActiveUser(account_id);
+  if (!is_user_affiliated())
+    user_manager->SetOwnerId(account_id);
 
   // Make sure device OEM is allowlisted.
   hardware_info_delegate_factory_ =
@@ -79,18 +101,45 @@
   if (should_open_pwa_ui_) {
     host_resolver()->AddRule("*", "127.0.0.1");
     // Make sure PWA UI is open.
-    pwa_page_rfh_ =
-        ui_test_utils::NavigateToURL(browser(), GURL(GetParam().pwa_page_url));
+    pwa_page_rfh_ = ui_test_utils::NavigateToURL(
+        browser(), GURL(extension_info_params().pwa_page_url));
     ASSERT_TRUE(pwa_page_rfh_);
   }
 }
 
+void BaseTelemetryExtensionBrowserTest::TearDownOnMainThread() {
+  // Explicitly removing the user is required; otherwise ProfileHelper keeps
+  // a dangling pointer to the User.
+  // TODO(b/208629291): Consider removing all users from ProfileHelper in the
+  // destructor of ash::FakeChromeUserManager.
+  GetFakeUserManager()->RemoveUserFromList(
+      GetFakeUserManager()->GetActiveUser()->GetAccountId());
+  user_manager_enabler_.reset();
+
+  extensions::ExtensionBrowserTest::TearDownOnMainThread();
+}
+
+bool BaseTelemetryExtensionBrowserTest::is_user_affiliated() const {
+  return std::get<0>(GetParam());
+}
+ExtensionInfoTestParams
+BaseTelemetryExtensionBrowserTest::extension_info_params() const {
+  return std::get<1>(GetParam());
+}
+
+ash::FakeChromeUserManager*
+BaseTelemetryExtensionBrowserTest::GetFakeUserManager() const {
+  return static_cast<ash::FakeChromeUserManager*>(
+      user_manager::UserManager::Get());
+}
+
 void BaseTelemetryExtensionBrowserTest::CreateExtensionAndRunServiceWorker(
     const std::string& service_worker_content) {
   // Must outlive the extension.
   extensions::TestExtensionDir test_dir;
   test_dir.WriteManifest(
-      GetManifestFile(GetParam().public_key, GetParam().matches_origin));
+      GetManifestFile(extension_info_params().public_key,
+                      extension_info_params().matches_origin));
   test_dir.WriteFile(FILE_PATH_LITERAL("sw.js"), service_worker_content);
   test_dir.WriteFile(FILE_PATH_LITERAL("options.html"), "");
 
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h
index 3c13cf7..58843fc 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h
@@ -5,12 +5,21 @@
 #ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_BASE_TELEMETRY_EXTENSION_BROWSER_TEST_H_
 #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_BASE_TELEMETRY_EXTENSION_BROWSER_TEST_H_
 
+#include <memory>
 #include <string>
+#include <tuple>
 #include <vector>
 
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/hardware_info_delegate.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
+#include "components/user_manager/scoped_user_manager.h"
 #include "content/public/browser/render_frame_host.h"
+#include "extensions/browser/test_management_policy.h"
+
+namespace ash {
+class FakeChromeUserManager;
+}
 
 namespace chromeos {
 
@@ -28,9 +37,17 @@
   const std::string matches_origin;
 };
 
+// The base test class for all TelemetryExtension browser tests. All tests are
+// parameterized with the following parameters:
+// * |is_user_affiliated| - a flag used to setup the testing environment for two
+//                          scenarios: affiliated and normal user.
+// * |extension_info_params| - parameters of the extension under test.
+// Note: All tests must be defined using the IN_PROC_BROWSER_TEST_P macro and
+// must use the INSTANTIATE_TEST_SUITE_P macro to instantiate the test suite.
 class BaseTelemetryExtensionBrowserTest
     : public extensions::ExtensionBrowserTest,
-      public testing::WithParamInterface<ExtensionInfoTestParams> {
+      public testing::WithParamInterface<
+          std::tuple<bool, ExtensionInfoTestParams>> {
  public:
   static const std::vector<ExtensionInfoTestParams> kAllExtensionInfoTestParams;
 
@@ -44,18 +61,25 @@
 
   // BrowserTestBase:
   void SetUpOnMainThread() override;
+  void TearDownOnMainThread() override;
 
  protected:
+  bool is_user_affiliated() const;
+  ExtensionInfoTestParams extension_info_params() const;
+  ash::FakeChromeUserManager* GetFakeUserManager() const;
   void CreateExtensionAndRunServiceWorker(
       const std::string& service_worker_content);
   virtual std::string GetManifestFile(const std::string& public_key,
                                       const std::string& matches_origin);
 
+  std::unique_ptr<ApiGuardDelegate::Factory> api_guard_delegate_factory_;
   std::unique_ptr<HardwareInfoDelegate::Factory>
       hardware_info_delegate_factory_;
-
   bool should_open_pwa_ui_ = true;
   content::RenderFrameHost* pwa_page_rfh_ = nullptr;
+
+ private:
+  std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
index 6d23302..d9d26dc 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
@@ -297,7 +297,9 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     TelemetryExtensionDiagnosticsApiBrowserTest,
-    testing::ValuesIn(
-        BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams));
+    testing::Combine(
+        testing::Bool(),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.cc b/chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.cc
new file mode 100644
index 0000000..159908b
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.cc
@@ -0,0 +1,40 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.h"
+
+#include <memory>
+#include <string>
+
+#include "base/memory/ptr_util.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace chromeos {
+
+FakeApiGuardDelegate::Factory::Factory(bool is_extension_force_installed)
+    : is_extension_force_installed_(is_extension_force_installed) {}
+
+FakeApiGuardDelegate::Factory::~Factory() = default;
+
+std::unique_ptr<ApiGuardDelegate>
+FakeApiGuardDelegate::Factory::CreateInstance() {
+  return base::WrapUnique<ApiGuardDelegate>(
+      new FakeApiGuardDelegate(is_extension_force_installed_));
+}
+
+FakeApiGuardDelegate::FakeApiGuardDelegate(bool is_extension_force_installed)
+    : is_extension_force_installed_(is_extension_force_installed) {}
+
+FakeApiGuardDelegate::~FakeApiGuardDelegate() = default;
+
+bool FakeApiGuardDelegate::IsExtensionForceInstalled(
+    content::BrowserContext* context,
+    const std::string& extension_id) {
+  return is_extension_force_installed_;
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.h b/chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.h
new file mode 100644
index 0000000..20b7bd1
--- /dev/null
+++ b/chrome/browser/chromeos/extensions/telemetry/api/fake_api_guard_delegate.h
@@ -0,0 +1,51 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_FAKE_API_GUARD_DELEGATE_H_
+#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_FAKE_API_GUARD_DELEGATE_H_
+
+#include <memory>
+#include <string>
+
+#include "chrome/browser/chromeos/extensions/telemetry/api/api_guard_delegate.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace chromeos {
+
+class FakeApiGuardDelegate : public ApiGuardDelegate {
+ public:
+  class Factory : public ApiGuardDelegate::Factory {
+   public:
+    explicit Factory(bool is_extension_force_installed);
+    ~Factory() override;
+
+   protected:
+    // ApiGuardDelegate::Factory:
+    std::unique_ptr<ApiGuardDelegate> CreateInstance() override;
+
+   private:
+    bool is_extension_force_installed_;
+  };
+
+  FakeApiGuardDelegate(const FakeApiGuardDelegate&) = delete;
+  FakeApiGuardDelegate& operator=(const FakeApiGuardDelegate&) = delete;
+  ~FakeApiGuardDelegate() override;
+
+  // ApiGuardDelegate:
+  bool IsExtensionForceInstalled(content::BrowserContext* context,
+                                 const std::string& extension_id) override;
+
+ protected:
+  explicit FakeApiGuardDelegate(bool is_extension_force_installed);
+
+ private:
+  bool is_extension_force_installed_;
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_EXTENSIONS_TELEMETRY_API_FAKE_API_GUARD_DELEGATE_H_
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc
index ab9fb700..55cf1c9 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api.cc
@@ -54,7 +54,7 @@
         std::make_unique<std::string>(vpd_info->sku_number.value());
   }
 
-  // Protect accessing the serial number by a runtime permission.
+  // Protect accessing the serial number by a permission.
   if (extension()->permissions_data()->HasAPIPermission(
           extensions::mojom::APIPermissionID::kChromeOSTelemetrySerialNumber) &&
       vpd_info->serial_number.has_value()) {
@@ -71,7 +71,7 @@
 OsTelemetryGetOemDataFunction::~OsTelemetryGetOemDataFunction() = default;
 
 void OsTelemetryGetOemDataFunction::RunIfAllowed() {
-  // Protect accessing the serial number by a runtime permission.
+  // Protect accessing the serial number by a permission.
   if (!extension()->permissions_data()->HasAPIPermission(
           extensions::mojom::APIPermissionID::kChromeOSTelemetrySerialNumber)) {
     Respond(
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc
index 767f51ad..e8e4782d 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_api_browsertest.cc
@@ -125,8 +125,10 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     TelemetryExtensionTelemetryApiBrowserTest,
-    testing::ValuesIn(
-        BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams));
+    testing::Combine(
+        testing::Bool(),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
 
 class TelemetryExtensionTelemetryApiWithoutSerialNumberBrowserTest
     : public TelemetryExtensionTelemetryApiBrowserTest {
@@ -228,7 +230,9 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     TelemetryExtensionTelemetryApiWithoutSerialNumberBrowserTest,
-    testing::ValuesIn(
-        BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams));
+    testing::Combine(
+        testing::Bool(),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc
index 386fce0..5507455 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc
@@ -34,9 +34,12 @@
   // Must outlive the extension.
   extensions::TestExtensionDir test_dir_receiver;
   test_dir_receiver.WriteManifest(
-      GetManifestFile(GetParam().public_key, GetParam().matches_origin));
+      GetManifestFile(extension_info_params().public_key,
+                      extension_info_params().matches_origin));
   test_dir_receiver.WriteFile(FILE_PATH_LITERAL("options.html"), "");
-  test_dir_receiver.WriteFile("sw.js", base::StringPrintf(R"(
+  test_dir_receiver.WriteFile(
+      "sw.js",
+      base::StringPrintf(R"(
         chrome.test.runTests([
           function runtimeOnMessageExternal() {
             chrome.runtime.onMessageExternal.addListener(
@@ -48,7 +51,8 @@
             chrome.test.sendMessage('ready');
           }
         ]);
-      )", GetParam().pwa_page_url.c_str()));
+      )",
+                         extension_info_params().pwa_page_url.c_str()));
 
   // Load and run the extenion (chromeos_system_extension).
   const extensions::Extension* receiver =
@@ -66,7 +70,7 @@
   // Note: |pwa_page_rfh_| is the RenderFrameHost for |kPwaPageUrlString| page.
   const auto script = base::StringPrintf(
       "window.chrome.runtime.sendMessage('%s', 'ping', (result) => {});",
-      GetParam().extension_id.c_str());
+      extension_info_params().extension_id.c_str());
   pwa_page_rfh_->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
                                            base::NullCallback());
 
@@ -85,7 +89,8 @@
   // Must outlive the extension.
   extensions::TestExtensionDir test_dir;
   test_dir.WriteManifest(
-      GetManifestFile(GetParam().public_key, GetParam().matches_origin));
+      GetManifestFile(extension_info_params().public_key,
+                      extension_info_params().matches_origin));
   test_dir.WriteFile(FILE_PATH_LITERAL("options.html"),
                      "<script>chrome.test.sendMessage('done')</script>");
   test_dir.WriteFile("sw.js", "chrome.test.sendMessage('ready');");
@@ -114,7 +119,9 @@
 INSTANTIATE_TEST_SUITE_P(
     All,
     TelemetryExtensionBrowserTest,
-    testing::ValuesIn(
-        BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams));
+    testing::Combine(
+        testing::Bool(),
+        testing::ValuesIn(
+            BaseTelemetryExtensionBrowserTest::kAllExtensionInfoTestParams)));
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index 01cca48..12782a0a 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -8,6 +8,7 @@
 #include "ash/shell.h"
 #include "base/json/json_writer.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/threading/sequenced_task_runner_handle.h"
 #include "base/values.h"
 #include "chrome/browser/ash/crostini/crostini_manager.h"
 #include "chrome/browser/ash/crostini/crostini_util.h"
@@ -139,7 +140,7 @@
 class MockDlpRulesManager : public DlpRulesManagerImpl {
  public:
   explicit MockDlpRulesManager(PrefService* local_state)
-      : DlpRulesManagerImpl(local_state, /* dm_token_value= */ "") {}
+      : DlpRulesManagerImpl(local_state) {}
   ~MockDlpRulesManager() override = default;
 
   MOCK_CONST_METHOD0(GetReportingManager, DlpReportingManager*());
@@ -746,7 +747,8 @@
 
   DlpReportingManager reporting_manager;
   std::vector<DlpPolicyEvent> events;
-  SetReportQueueForReportingManager(&reporting_manager, events);
+  SetReportQueueForReportingManager(&reporting_manager, events,
+                                    base::SequencedTaskRunnerHandle::Get());
   EXPECT_CALL(rules_manager, GetReportingManager)
       .WillRepeatedly(::testing::Return(&reporting_manager));
 
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
index c419e084..d6dd426 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/stl_util.h"
+#include "base/task/thread_pool.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/mock_callback.h"
 #include "build/chromeos_buildflags.h"
@@ -268,7 +269,9 @@
         CreateEndpoint(base::OptionalOrNullptr(endpoint_type), do_notify_);
     dst_ptr_ = base::OptionalOrNullptr(data_dst_);
 
-    SetReportQueueForReportingManager(&reporting_manager_, events_);
+    SetReportQueueForReportingManager(
+        &reporting_manager_, events_,
+        base::ThreadPool::CreateSequencedTaskRunner({}));
     EXPECT_CALL(rules_manager_, GetReportingManager)
         .WillRepeatedly(::testing::Return(&reporting_manager_));
   }
@@ -465,7 +468,9 @@
     ASSERT_TRUE(endpoint_type_.has_value());
     data_dst_ = ui::DataTransferEndpoint(endpoint_type_.value(), do_notify_);
 
-    SetReportQueueForReportingManager(&reporting_manager_, events_);
+    SetReportQueueForReportingManager(
+        &reporting_manager_, events_,
+        base::ThreadPool::CreateSequencedTaskRunner({}));
     EXPECT_CALL(rules_manager_, GetReportingManager)
         .WillRepeatedly(::testing::Return(&reporting_manager_));
   }
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc
index 6e936a0..8871405 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/policy/dm_token_utils.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "components/reporting/client/report_queue.h"
+#include "components/reporting/client/report_queue_factory.h"
 #include "components/reporting/util/status.h"
 #include "url/gurl.h"
 
@@ -194,17 +195,18 @@
   return event;
 }
 
-DlpReportingManager::DlpReportingManager() : report_queue_{nullptr} {}
+DlpReportingManager::DlpReportingManager()
+    : report_queue_(
+          ::reporting::ReportQueueFactory::CreateSpeculativeReportQueue(
+              ::reporting::EventType::kUser,
+              ::reporting::Destination::DLP_EVENTS)) {}
+
 DlpReportingManager::~DlpReportingManager() = default;
 
-DlpReportingManager::ReportQueueSetterCallback
-DlpReportingManager::GetReportQueueSetter() {
-  return base::BindOnce(&DlpReportingManager::SetReportQueue,
-                        weak_factory_.GetWeakPtr());
-}
-
-void DlpReportingManager::SetReportQueue(
-    std::unique_ptr<reporting::ReportQueue> report_queue) {
+void DlpReportingManager::SetReportQueueForTest(
+    std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter>
+        report_queue) {
+  report_queue_.reset();
   report_queue_ = std::move(report_queue);
 }
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h
index 4434ffe3..bd617ae 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/task/sequenced_task_runner.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_policy_event.pb.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
 #include "components/reporting/client/report_queue.h"
@@ -75,15 +76,19 @@
     ReportEvent(CreateDlpPolicyWarningProceededEvent(args...));
   }
 
-  ReportQueueSetterCallback GetReportQueueSetter();
-
   size_t events_reported() const { return events_reported_; }
 
+  // Test hook for overriding the default report queue used for reporting
+  // purposes.
+  //
+  // TODO(b/202746926): Ideally, the report queue should be overridden at
+  // |DlpReportingManager| instantiation, but since a lot of test scenarios
+  // follow deferred mock setup we defer refactoring this part for later.
+  void SetReportQueueForTest(
+      std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter>
+          report_queue);
+
  private:
-  friend class DlpReportingManagerTestHelper;
-
-  void SetReportQueue(std::unique_ptr<reporting::ReportQueue> report_queue);
-
   void OnEventEnqueued(reporting::Status status);
 
   void ReportEvent(DlpPolicyEvent event);
@@ -91,7 +96,8 @@
   // Counter for the number of events reported from login.
   size_t events_reported_ = 0;
 
-  std::unique_ptr<reporting::ReportQueue> report_queue_;
+  std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter>
+      report_queue_;
 
   base::WeakPtrFactory<DlpReportingManager> weak_factory_{this};
 };
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc
index 1297054..ceed943 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/task/sequenced_task_runner.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_policy_event.pb.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
@@ -71,10 +72,15 @@
   return Matcher<const DlpPolicyEvent&>(new DlpPolicyEventMatcher(event));
 }
 
-void SetReportQueueForReportingManager(policy::DlpReportingManager* manager,
-                                       std::vector<DlpPolicyEvent>& events) {
-  auto report_queue = std::make_unique<reporting::MockReportQueue>();
-  EXPECT_CALL(*report_queue.get(), AddRecord)
+void SetReportQueueForReportingManager(
+    policy::DlpReportingManager* manager,
+    std::vector<DlpPolicyEvent>& events,
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+  auto report_queue =
+      std::unique_ptr<::reporting::MockReportQueue, base::OnTaskRunnerDeleter>(
+          new ::reporting::MockReportQueue(),
+          base::OnTaskRunnerDeleter(std::move(task_runner)));
+  EXPECT_CALL(*report_queue, AddRecord)
       .WillRepeatedly(
           [&events](base::StringPiece record, reporting::Priority priority,
                     reporting::ReportQueue::EnqueueCallback callback) {
@@ -85,7 +91,7 @@
             events.push_back(event);
             std::move(callback).Run(reporting::Status::StatusOK());
           });
-  manager->GetReportQueueSetter().Run(std::move(report_queue));
+  manager->SetReportQueueForTest(std::move(report_queue));
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.h b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.h
index bf38f3c..07c66e0 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_test_helper.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_REPORTING_MANAGER_TEST_HELPER_H_
 #define CHROME_BROWSER_CHROMEOS_POLICY_DLP_DLP_REPORTING_MANAGER_TEST_HELPER_H_
 
+#include "base/task/sequenced_task_runner.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 class DlpPolicyEvent;
@@ -19,8 +20,10 @@
 // Sets MockReportQueue for DlpReportingManager. Whenever AddRecord function of
 // MockReportQueue is called (a DLP restriction is triggered) a new
 // DlpPolicyEvent is pushed to |events|.
-void SetReportQueueForReportingManager(policy::DlpReportingManager* manager,
-                                       std::vector<DlpPolicyEvent>& events);
+void SetReportQueueForReportingManager(
+    policy::DlpReportingManager* manager,
+    std::vector<DlpPolicyEvent>& events,
+    scoped_refptr<base::SequencedTaskRunner> task_runner);
 
 }  // namespace policy
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
index 4afda990..8e57103 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 
 #include "base/memory/ptr_util.h"
+#include "base/task/thread_pool.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_histogram_helper.h"
@@ -16,6 +17,7 @@
 #include "components/account_id/account_id.h"
 #include "components/reporting/util/status.h"
 #include "components/user_manager/scoped_user_manager.h"
+#include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -25,7 +27,6 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "chromeos/lacros/lacros_service.h"
-#include "content/public/test/browser_task_environment.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
 using ::testing::_;
@@ -43,14 +44,15 @@
 
   void SetUp() override {
     testing::Test::SetUp();
-    SetReportQueueForReportingManager(&manager_, events_);
+    SetReportQueueForReportingManager(
+        &manager_, events_, base::ThreadPool::CreateSequencedTaskRunner({}));
   }
 
  protected:
+  content::BrowserTaskEnvironment task_environment_;
   DlpReportingManager manager_;
   std::vector<DlpPolicyEvent> events_;
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-  content::BrowserTaskEnvironment task_environment_;
   chromeos::LacrosService lacros_service_;
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 };
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc
index 0e1e897..9a2b058 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.cc
@@ -5,11 +5,9 @@
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
 
 #include "base/no_destructor.h"
-#include "base/strings/string_piece.h"
 #include "base/task/bind_post_task.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/policy/dlp/dlp_reporting_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h"
 #include "chrome/browser/policy/dm_token_utils.h"
@@ -108,12 +106,6 @@
   if (!local_state)
     return nullptr;
 
-  auto dm_token = GetDMToken(profile);
-  if (!dm_token.is_valid()) {
-    LOG(ERROR) << "DlpReporting has invalid DMToken. Reporting disabled.";
-    return nullptr;
-  }
-
-  return new DlpRulesManagerImpl(local_state, dm_token.value());
+  return new DlpRulesManagerImpl(local_state);
 }
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
index fc11ddd3..0f111f4 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.cc
@@ -14,7 +14,6 @@
 #include "base/containers/contains.h"
 #include "base/containers/fixed_flat_map.h"
 #include "base/feature_list.h"
-#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h"
@@ -28,7 +27,6 @@
 #include "components/policy/core/common/policy_pref_names.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
-#include "components/reporting/client/report_queue_factory.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace policy {
@@ -340,8 +338,7 @@
   return level_url_pair.first;
 }
 
-DlpRulesManagerImpl::DlpRulesManagerImpl(PrefService* local_state,
-                                         base::StringPiece dm_token_value) {
+DlpRulesManagerImpl::DlpRulesManagerImpl(PrefService* local_state) {
   pref_change_registrar_.Init(local_state);
   pref_change_registrar_.Add(
       policy_prefs::kDlpRulesList,
@@ -352,9 +349,6 @@
   if (!IsReportingEnabled())
     return;
   reporting_manager_ = std::make_unique<DlpReportingManager>();
-  reporting::ReportQueueFactory::Create(
-      dm_token_value, reporting::Destination::DLP_EVENTS,
-      reporting_manager_->GetReportQueueSetter());
 }
 
 bool DlpRulesManagerImpl::IsReportingEnabled() const {
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
index ee641dc..5d333bb9 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h
@@ -11,7 +11,6 @@
 #include <memory>
 #include <set>
 
-#include "base/strings/string_piece_forward.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/url_matcher/url_matcher.h"
 
@@ -60,8 +59,7 @@
  protected:
   friend class DlpRulesManagerFactory;
 
-  DlpRulesManagerImpl(PrefService* local_state,
-                      base::StringPiece dm_token_value);
+  explicit DlpRulesManagerImpl(PrefService* local_state);
 
  private:
   void OnPolicyUpdate();
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
index 9cced26..0c2b4a5 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_unittest.cc
@@ -50,7 +50,7 @@
 class MockDlpRulesManager : public DlpRulesManagerImpl {
  public:
   explicit MockDlpRulesManager(PrefService* local_state)
-      : DlpRulesManagerImpl(local_state, /* dm_token_value= */ "") {}
+      : DlpRulesManagerImpl(local_state) {}
 };
 
 }  // namespace
@@ -67,6 +67,7 @@
                                     std::move(rules_list));
   }
 
+  content::BrowserTaskEnvironment task_environment_;
   ScopedTestingLocalState testing_local_state_;
   MockDlpRulesManager dlp_rules_manager_;
   base::HistogramTester histogram_tester_;
@@ -639,7 +640,6 @@
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitAndEnableFeature(
       features::kDataLeakPreventionFilesRestriction);
-  content::BrowserTaskEnvironment task_environment;
   chromeos::DlpClient::InitializeFake();
 
   EXPECT_EQ(0, chromeos::DlpClient::Get()
@@ -672,7 +672,6 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 TEST_F(DlpRulesManagerImplTest, FilesRestriction_FeatureNotEnabled) {
-  content::BrowserTaskEnvironment task_environment;
   chromeos::DlpClient::InitializeFake();
 
   EXPECT_EQ(0, chromeos::DlpClient::Get()
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
index 2a39125..43a98077 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -114,10 +114,7 @@
         break;
       }
       case api::desktop_capture::DESKTOP_CAPTURE_SOURCE_TYPE_AUDIO: {
-        if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-                extensions::switches::kDisableDesktopCaptureAudio)) {
-          request_audio = true;
-        }
+        request_audio = true;
         break;
       }
     }
diff --git a/chrome/browser/feed/android/java/res/layout/new_tab_page_section_tab.xml b/chrome/browser/feed/android/java/res/layout/new_tab_page_section_tab.xml
index 6f532c1..f3074b0 100644
--- a/chrome/browser/feed/android/java/res/layout/new_tab_page_section_tab.xml
+++ b/chrome/browser/feed/android/java/res/layout/new_tab_page_section_tab.xml
@@ -25,7 +25,7 @@
       android:layout_width="@dimen/ntp_header_dropdown_size"
       android:layout_height="@dimen/ntp_header_dropdown_size"
       android:scaleType="centerInside"
-      app:tint="@color/default_text_color_blue"
+      app:tint="@macro/tab_layout_selected_tab_color"
       android:visibility="gone"
       android:src="@drawable/mtrl_ic_arrow_drop_down"
       android:layout_gravity="center_vertical"
diff --git a/chrome/browser/feed/android/java/res/xml/tab_layout_badge.xml b/chrome/browser/feed/android/java/res/xml/tab_layout_badge.xml
index 7be9b18..e987cc0 100644
--- a/chrome/browser/feed/android/java/res/xml/tab_layout_badge.xml
+++ b/chrome/browser/feed/android/java/res/xml/tab_layout_badge.xml
@@ -5,6 +5,6 @@
 
 <badge
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    app:backgroundColor="@macro/default_icon_color_accent1"
+    app:backgroundColor="@macro/default_text_color_accent1"
     app:badgeRadius="3dp"
     app:horizontalOffset="-5dp" />
diff --git a/chrome/browser/lacros/lacros_extension_apps_publisher.cc b/chrome/browser/lacros/lacros_extension_apps_publisher.cc
index ac7b2b5..efc9c6f 100644
--- a/chrome/browser/lacros/lacros_extension_apps_publisher.cc
+++ b/chrome/browser/lacros/lacros_extension_apps_publisher.cc
@@ -8,6 +8,7 @@
 
 #include "base/containers/extend.h"
 #include "base/scoped_observation.h"
+#include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/intent_util.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_ui_util.h"
@@ -265,6 +266,7 @@
     // Apps is deprecated, it's unclear if we'll ever get around to implementing
     // this functionality.
     app->icon_key = apps::mojom::IconKey::New();
+    app->icon_key->icon_effects = apps::IconEffects::kCrOsStandardIcon;
 
     auto* prefs = extensions::ExtensionPrefs::Get(profile_);
     if (prefs) {
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
index a4b3708..18835adb 100644
--- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
+++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -485,12 +485,8 @@
        loopback_audio_supported) ||
       media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS;
 
-  const bool check_audio_permission =
-      !base::CommandLine::ForCurrentProcess()->HasSwitch(
-          extensions::switches::kDisableDesktopCaptureAudio);
   const bool capture_audio =
-      (check_audio_permission ? audio_permitted : true) && audio_requested &&
-      audio_supported;
+      audio_permitted && audio_requested && audio_supported;
 
   // Determine if the extension is required to display a notification.
   const bool display_notification =
diff --git a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java
index 95271b4..5f2c00b 100644
--- a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java
+++ b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationUmaTracker.java
@@ -240,6 +240,10 @@
                 recordNotificationAgeHistogram(
                         "Mobile.SystemNotification.Content.Click.Age.SmsFetcher", createTime);
                 break;
+            case SystemNotificationType.PRICE_DROP_ALERTS:
+                recordNotificationAgeHistogram(
+                        "Mobile.SystemNotification.Content.Click.Age.PriceDrop", createTime);
+                break;
         }
     }
 
@@ -274,6 +278,10 @@
                 recordNotificationAgeHistogram(
                         "Mobile.SystemNotification.Dismiss.Age.SmsFetcher", createTime);
                 break;
+            case SystemNotificationType.PRICE_DROP_ALERTS:
+                recordNotificationAgeHistogram(
+                        "Mobile.SystemNotification.Dismiss.Age.PriceDrop", createTime);
+                break;
         }
     }
 
@@ -310,6 +318,10 @@
                 recordNotificationAgeHistogram(
                         "Mobile.SystemNotification.Action.Click.Age.SmsFetcher", createTime);
                 break;
+            case SystemNotificationType.PRICE_DROP_ALERTS:
+                recordNotificationAgeHistogram(
+                        "Mobile.SystemNotification.Action.Click.Age.PriceDrop", createTime);
+                break;
         }
     }
 
diff --git a/chrome/browser/payments/chrome_payment_request_delegate.cc b/chrome/browser/payments/chrome_payment_request_delegate.cc
index 3811ec96..25e02dcb 100644
--- a/chrome/browser/payments/chrome_payment_request_delegate.cc
+++ b/chrome/browser/payments/chrome_payment_request_delegate.cc
@@ -41,7 +41,6 @@
 #include "content/public/browser/web_contents.h"
 #include "services/metrics/public/cpp/ukm_recorder.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 #include "third_party/libaddressinput/chromium/chrome_metadata_source.h"
 #include "third_party/libaddressinput/chromium/chrome_storage_impl.h"
 
@@ -65,12 +64,6 @@
   return autofill::ValidationRulesStorageFactory::CreateStorage();
 }
 
-bool FrameSupportsPayments(content::RenderFrameHost* rfh) {
-  return rfh && rfh->IsActive() &&
-         rfh->IsFeatureEnabled(
-             blink::mojom::PermissionsPolicyFeature::kPayment);
-}
-
 }  // namespace
 
 ChromePaymentRequestDelegate::ChromePaymentRequestDelegate(
@@ -158,10 +151,9 @@
 
 const GURL& ChromePaymentRequestDelegate::GetLastCommittedURL() const {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  return FrameSupportsPayments(rfh)
-             ? content::WebContents::FromRenderFrameHost(rfh)
-                   ->GetLastCommittedURL()
-             : GURL::EmptyGURL();
+  return rfh && rfh->IsActive() ? content::WebContents::FromRenderFrameHost(rfh)
+                                      ->GetLastCommittedURL()
+                                : GURL::EmptyGURL();
 }
 
 void ChromePaymentRequestDelegate::DoFullCardRequest(
@@ -169,7 +161,7 @@
     base::WeakPtr<autofill::payments::FullCardRequest::ResultDelegate>
         result_delegate) {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!FrameSupportsPayments(rfh) || !shown_dialog_)
+  if (!rfh || !rfh->IsActive() || !shown_dialog_)
     return;
   content::WebContents* web_contents =
       content::WebContents::FromRenderFrameHost(rfh);
@@ -221,7 +213,7 @@
 
 bool ChromePaymentRequestDelegate::IsBrowserWindowActive() const {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (FrameSupportsPayments(rfh))
+  if (!rfh || !rfh->IsActive())
     return false;
 
   Browser* browser = chrome::FindBrowserWithWebContents(
@@ -233,7 +225,7 @@
     const std::u16string& merchant_name,
     base::OnceClosure response_callback) {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!FrameSupportsPayments(rfh))
+  if (!rfh || !rfh->IsActive())
     return;
   content::WebContents* web_contents =
       content::WebContents::FromRenderFrameHost(rfh);
@@ -252,7 +244,7 @@
   // displays the top-level origin in its UI before the user can click on the
   // [Verify] button to invoke this authenticator.
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  return FrameSupportsPayments(rfh)
+  return rfh && rfh->IsActive()
              ? std::make_unique<content::InternalAuthenticatorImpl>(rfh)
              : nullptr;
 }
@@ -289,7 +281,7 @@
 std::string
 ChromePaymentRequestDelegate::GetInvalidSslCertificateErrorMessage() {
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  return FrameSupportsPayments(rfh)
+  return rfh && rfh->IsActive()
              ? SslValidityChecker::GetInvalidSslCertificateErrorMessage(
                    content::WebContents::FromRenderFrameHost(rfh))
              : "";
@@ -302,7 +294,7 @@
 std::string ChromePaymentRequestDelegate::GetTwaPackageName() const {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   auto* rfh = content::RenderFrameHost::FromID(frame_routing_id_);
-  if (!FrameSupportsPayments(rfh))
+  if (!rfh || !rfh->IsActive())
     return "";
 
   auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
index e9c3ae23..0a354a8 100644
--- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -697,6 +697,13 @@
             "Chrome.OfflineIndicatorV2.HasPersistentOfflineContent";
 
     /**
+     * Save the timestamp of the last time that we record metrics on whether user enables the price
+     * tracking annotations.
+     */
+    public static final String PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP =
+            "Chrome.PriceTracking.AnnotationsEnabledMetricsTimestamp";
+
+    /**
      * Whether the PriceAlertsMessageCard is enabled.
      */
     public static final String PRICE_TRACKING_PRICE_ALERTS_MESSAGE_CARD =
@@ -1109,6 +1116,7 @@
                 OPEN_RECENT_TABS_COUNT,
                 OPTIMIZATION_GUIDE_PUSH_NOTIFICATION_CACHE.pattern(),
                 PERSISTENT_OFFLINE_CONTENT_AVAILABILITY_STATUS,
+                PRICE_TRACKING_ANNOTATIONS_ENABLED_METRICS_TIMESTAMP,
                 PRICE_TRACKING_PRICE_ALERTS_MESSAGE_CARD,
                 PRICE_TRACKING_PRICE_ALERTS_MESSAGE_CARD_SHOW_COUNT,
                 PRICE_TRACKING_PRICE_WELCOME_MESSAGE_CARD,
diff --git a/chrome/browser/prefs/pref_service_browsertest.cc b/chrome/browser/prefs/pref_service_browsertest.cc
index 8336af0..f7c8b97 100644
--- a/chrome/browser/prefs/pref_service_browsertest.cc
+++ b/chrome/browser/prefs/pref_service_browsertest.cc
@@ -24,9 +24,11 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "content/public/test/browser_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "ui/gfx/geometry/rect.h"
 
 typedef InProcessBrowserTest PreservedWindowPlacement;
+using ::testing::Optional;
 
 IN_PROC_BROWSER_TEST_F(PreservedWindowPlacement, PRE_Test) {
   browser()->window()->SetBounds(gfx::Rect(20, 30, 600, 600));
@@ -106,32 +108,22 @@
   gfx::Rect bounds = browser()->window()->GetRestoredBounds();
 
   // Retrieve the expected rect values from "Preferences"
-  int bottom = 0;
   std::string kBrowserWindowPlacement(prefs::kBrowserWindowPlacement);
-  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".bottom",
-      &bottom));
-  EXPECT_EQ(bottom, bounds.y() + bounds.height());
+  EXPECT_THAT(root_dict->FindIntPath(kBrowserWindowPlacement + ".bottom"),
+              Optional(bounds.y() + bounds.height()));
 
-  int top = 0;
-  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".top",
-      &top));
-  EXPECT_EQ(top, bounds.y());
+  EXPECT_THAT(root_dict->FindIntPath(kBrowserWindowPlacement + ".top"),
+              Optional(bounds.y()));
 
-  int left = 0;
-  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".left",
-      &left));
-  EXPECT_EQ(left, bounds.x());
+  EXPECT_THAT(root_dict->FindIntPath(kBrowserWindowPlacement + ".left"),
+              Optional(bounds.x()));
 
-  int right = 0;
-  EXPECT_TRUE(root_dict->GetInteger(kBrowserWindowPlacement + ".right",
-      &right));
-  EXPECT_EQ(right, bounds.x() + bounds.width());
+  EXPECT_THAT(root_dict->FindIntPath(kBrowserWindowPlacement + ".right"),
+              Optional(bounds.x() + bounds.width()));
 
   // Find if launched window is maximized.
   bool is_window_maximized = browser()->window()->IsMaximized();
-  bool is_maximized = false;
-  EXPECT_TRUE(root_dict->GetBoolean(kBrowserWindowPlacement + ".maximized",
-      &is_maximized));
-  EXPECT_EQ(is_maximized, is_window_maximized);
+  EXPECT_THAT(root_dict->FindBoolPath(kBrowserWindowPlacement + ".maximized"),
+              Optional(is_window_maximized));
 }
 #endif
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
index 26ae3036..4249253 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -146,7 +146,7 @@
 class MockDlpRulesManager : public policy::DlpRulesManagerImpl {
  public:
   explicit MockDlpRulesManager(PrefService* local_state)
-      : DlpRulesManagerImpl(local_state, /* dm_token_value= */ "") {}
+      : DlpRulesManagerImpl(local_state) {}
 };
 #endif
 
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
index 941779e..3de7180 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
@@ -373,15 +373,16 @@
    * @private
    */
   setInterimText_(text) {
+    if (this.chromeVoxEnabled_ || !this.commandsFeatureEnabled_) {
+      // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
+      return;
+    }
+
     // TODO(crbug.com/1252037): Need to find a way to show interim text that is
     // only whitespace. Google Cloud Speech can return a newline character
     // although SODA does not seem to do that. The newline character looks wrong
     // here.
     this.interimText_ = text;
-    if (this.chromeVoxEnabled_) {
-      // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
-      return;
-    }
     this.inputController_.showAnnotation(this.interimText_);
     if (this.clearUITextTimeoutId_) {
       clearTimeout(this.clearUITextTimeoutId_);
@@ -395,10 +396,11 @@
    * @private
    */
   clearInterimText_() {
-    if (this.chromeVoxEnabled_) {
+    if (this.chromeVoxEnabled_ || !this.commandsFeatureEnabled_) {
       // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
       return;
     }
+
     this.interimText_ = '';
     this.inputController_.showAnnotation('....');
     if (this.clearUITextTimeoutId_) {
@@ -420,6 +422,7 @@
       // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
       return;
     }
+
     if (macro.getMacroName() === MacroName.INPUT_TEXT_VIEW ||
         macro.getMacroName() === MacroName.NEW_LINE) {
       // Return to the '....' UI.
@@ -448,6 +451,7 @@
       // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
       return;
     }
+
     this.interimText_ = '';
     // TODO(crbug.com/1252037): Finalize string and internationalization.
     this.inputController_.showAnnotation(`ⓘ Failed to execute: ` + transcript);
@@ -462,11 +466,12 @@
    * @private
    */
   hideCommandsUI_() {
-    if (this.chromeVoxEnabled_) {
+    if (this.chromeVoxEnabled_ || !this.commandsFeatureEnabled_) {
       return;
     }
-    this.inputController_.hideAnnotation();
+
     this.interimText_ = '';
+    this.inputController_.hideAnnotation();
     if (this.clearUITextTimeoutId_) {
       clearTimeout(this.clearUITextTimeoutId_);
       this.clearUITextTimeoutId_ = null;
diff --git a/chrome/browser/resources/print_preview/ui/app.ts b/chrome/browser/resources/print_preview/ui/app.ts
index b778b47..c813e3c 100644
--- a/chrome/browser/resources/print_preview/ui/app.ts
+++ b/chrome/browser/resources/print_preview/ui/app.ts
@@ -646,4 +646,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'print-preview-app': PrintPreviewAppElement;
+  }
+}
+
 customElements.define(PrintPreviewAppElement.is, PrintPreviewAppElement);
diff --git a/chrome/browser/resources/print_preview/ui/header.ts b/chrome/browser/resources/print_preview/ui/header.ts
index 39d7daad..ebe836da 100644
--- a/chrome/browser/resources/print_preview/ui/header.ts
+++ b/chrome/browser/resources/print_preview/ui/header.ts
@@ -116,4 +116,10 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'print-preview-header': PrintPreviewHeaderElement;
+  }
+}
+
 customElements.define(PrintPreviewHeaderElement.is, PrintPreviewHeaderElement);
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn
index 8de5a9d3..6a5338b 100644
--- a/chrome/browser/resources/settings/chromeos/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -285,6 +285,7 @@
     "chromeos/os_settings.js",
     "chromeos/parental_controls_page/parental_controls_browser_proxy.js",
     "chromeos/personalization_page/change_picture_browser_proxy.js",
+    "chromeos/personalization_page/personalization_hub_browser_proxy.js",
     "chromeos/personalization_page/wallpaper_browser_proxy.js",
     "chromeos/prefs_behavior.js",
     "chromeos/os_privacy_page/peripheral_data_access_browser_proxy.js",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni
index ab87a25..73b3061 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.gni
+++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -114,6 +114,7 @@
                                    "settings.DataAccessPolicyState|DataAccessPolicyState",
                                    "settings.MetricsConsentBrowserProxy|MetricsConsentBrowserProxy",
                                    "settings.MetricsConsentState|MetricsConsentState",
+                                   "settings.PersonalizationHubBrowserProxy|PersonalizationHubBrowserProxy",
                                    "settings.PhoneHubNotificationAccessStatus|PhoneHubNotificationAccessStatus",
                                    "settings.PowerSource|PowerSource",
                                    "settings.PowerManagementSettings|PowerManagementSettings",
@@ -234,6 +235,7 @@
                              "chrome/browser/resources/settings/chromeos/os_route.html|routes",
                              "chrome/browser/resources/settings/chromeos/os_settings_routes.html|OsSettingsRoutes",
                              "chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.html|ChangePictureBrowserProxy,ChangePictureBrowserProxyImpl,DefaultImage",
+                             "chrome/browser/resources/settings/chromeos/personalization_page/personalization_hub_browser_proxy.html|PersonalizationHubBrowserProxy,PersonalizationHubBrowserProxyImpl",
                              "chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.html|WallpaperBrowserProxy,WallpaperBrowserProxyImpl",
                              "chrome/browser/resources/settings/chromeos/parental_controls_page/parental_controls_browser_proxy.html|ParentalControlsBrowserProxy,ParentalControlsBrowserProxyImpl",
                              "chrome/browser/resources/settings/chromeos/route_origin_behavior.html|RouteOriginBehaviorImpl,RouteOriginBehavior",
@@ -485,6 +487,7 @@
                                  "chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.html",
                                  "chrome/browser/resources/settings/chromeos/os_toolbar/os_toolbar.html",
                                  "chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.html",
+                                 "chrome/browser/resources/settings/chromeos/personalization_page/personalization_hub_browser_proxy.html",
                                  "chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.html",
                                  "chrome/browser/resources/settings/chromeos/personalization_page/change_picture.html",
                                  "chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js
index 5d7f180..92743b9 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings.js
+++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -151,5 +151,6 @@
 export {SearchEngine, SearchEnginesBrowserProxy, SearchEnginesBrowserProxyImpl, SearchEnginesInfo} from './os_search_page/search_engines_browser_proxy.js';
 export {ParentalControlsBrowserProxy, ParentalControlsBrowserProxyImpl} from './parental_controls_page/parental_controls_browser_proxy.js';
 export {ChangePictureBrowserProxy, ChangePictureBrowserProxyImpl} from './personalization_page/change_picture_browser_proxy.js';
+export {PersonalizationHubBrowserProxy, PersonalizationHubBrowserProxyImpl} from './personalization_page/personalization_hub_browser_proxy.js';
 export {WallpaperBrowserProxyImpl} from './personalization_page/wallpaper_browser_proxy.js';
 export {getSearchHandler, setSearchHandlerForTesting} from './search_handler.m.js';
diff --git a/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn
index 3b7024da..0d8e816 100644
--- a/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/personalization_page/BUILD.gn
@@ -13,6 +13,7 @@
     ":change_picture",
     ":change_picture_browser_proxy",
     ":dark_mode_subpage",
+    ":personalization_hub_browser_proxy",
     ":personalization_page",
     ":wallpaper_browser_proxy",
   ]
@@ -57,6 +58,7 @@
 
 js_library("personalization_page") {
   deps = [
+    ":personalization_hub_browser_proxy",
     ":wallpaper_browser_proxy",
     "..:deep_linking_behavior.m",
     "..:os_route.m",
@@ -68,6 +70,11 @@
   ]
 }
 
+js_library("personalization_hub_browser_proxy") {
+  deps = [ "//ui/webui/resources/js:cr.m" ]
+  externs_list = [ "$externs_path/chrome_send.js" ]
+}
+
 js_library("wallpaper_browser_proxy") {
   deps = [ "//ui/webui/resources/js:cr.m" ]
   externs_list = [ "$externs_path/chrome_send.js" ]
diff --git a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_hub_browser_proxy.js b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_hub_browser_proxy.js
new file mode 100644
index 0000000..b6ba0b98
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_hub_browser_proxy.js
@@ -0,0 +1,24 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// clang-format off
+import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
+// clang-format on
+
+/** @interface */
+export class PersonalizationHubBrowserProxy {
+  openPersonalizationHub() {}
+}
+
+/**
+ * @implements {PersonalizationHubBrowserProxy}
+ */
+export class PersonalizationHubBrowserProxyImpl {
+  /** @override */
+  openPersonalizationHub() {
+    chrome.send('openPersonalizationHub');
+  }
+}
+
+addSingletonGetter(PersonalizationHubBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html
index 39338683..c96a3881 100644
--- a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html
+++ b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.html
@@ -1,77 +1,90 @@
 <style include="settings-shared"></style>
 <settings-animated-pages id="pages" section="personalization"
     focus-config="[[focusConfig_]]">
-  <div route-path="default">
-    <cr-link-row id="changePictureRow"
-        label="$i18n{changePictureTitle}"
-        on-click="navigateToChangePicture_"
-        role-description="$i18n{subpageArrowRoleDescription}">
-    </cr-link-row>
-    <cr-link-row class="hr" id="wallpaperButton"
-        hidden="[[!showWallpaperRow_]]"
-        on-click="openWallpaperManager_" label="$i18n{setWallpaper}"
-        sub-label="$i18n{openWallpaperApp}"
-        disabled="[[isWallpaperPolicyControlled_]]" external
-        deep-link-focus-id$="[[Setting.kOpenWallpaper]]">
-      <template is="dom-if" if="[[isWallpaperPolicyControlled_]]">
-        <cr-policy-indicator id="wallpaperPolicyIndicator"
-            indicator-type="devicePolicy">
-        </cr-policy-indicator>
+
+  <template is="dom-if" if="[[isPersonalizationHubEnabled_]]">
+    <div route-path="default">
+      <cr-link-row class="hr" id="personalizationHubButton"
+          label="$i18n{personalizationHubTitle}"
+          sub-label="$i18n{personalizationHubSubtitle}" external
+          on-click="openPersonalizationHub_">
+      </cr-link-row>
+    </div>
+  </template>
+
+  <template is="dom-if" if="[[!isPersonalizationHubEnabled_]]">
+    <div route-path="default">
+      <cr-link-row id="changePictureRow"
+          label="$i18n{changePictureTitle}"
+          on-click="navigateToChangePicture_"
+          role-description="$i18n{subpageArrowRoleDescription}">
+      </cr-link-row>
+      <cr-link-row class="hr" id="wallpaperButton"
+          hidden="[[!showWallpaperRow_]]"
+          on-click="openWallpaperManager_" label="$i18n{setWallpaper}"
+          sub-label="$i18n{openWallpaperApp}"
+          disabled="[[isWallpaperPolicyControlled_]]" external
+          deep-link-focus-id$="[[Setting.kOpenWallpaper]]">
+        <template is="dom-if" if="[[isWallpaperPolicyControlled_]]">
+          <cr-policy-indicator id="wallpaperPolicyIndicator"
+              indicator-type="devicePolicy">
+          </cr-policy-indicator>
+        </template>
+      </cr-link-row>
+
+      <!-- Ambient mode -->
+      <template is="dom-if" if="[[isAmbientModeEnabled_]]">
+        <cr-link-row
+            class="hr"
+            id="ambientModeRow"
+            label="$i18n{ambientModeTitle}"
+            sub-label="[[getAmbientModeRowSubLabel_(
+                prefs.settings.ambient_mode.enabled.value)]]"
+            on-click="navigateToAmbientMode_"
+            role-description="$i18n{subpageArrowRoleDescription}">
+        </cr-link-row>
       </template>
-    </cr-link-row>
 
-    <!-- Ambient mode -->
+      <!-- Dark mode -->
+      <template is="dom-if" if="[[isDarkModeAllowed_]]">
+        <cr-link-row
+            class="hr"
+            id="darkModeRow"
+            label="$i18n{darkModeTitle}"
+            on-click="navigateToDarkMode_"
+            role-description="$i18n{subpageArrowRoleDescription}">
+        </cr-link-row>
+      </template>
+    </div>
+
+    <template is="dom-if" route-path="/changePicture">
+      <settings-subpage page-title="$i18n{changePictureTitle}">
+        <settings-change-picture></settings-change-picture>
+      </settings-subpage>
+    </template>
+
     <template is="dom-if" if="[[isAmbientModeEnabled_]]">
-      <cr-link-row
-          class="hr"
-          id="ambientModeRow"
-          label="$i18n{ambientModeTitle}"
-          sub-label="[[getAmbientModeRowSubLabel_(
-              prefs.settings.ambient_mode.enabled.value)]]"
-          on-click="navigateToAmbientMode_"
-          role-description="$i18n{subpageArrowRoleDescription}">
-      </cr-link-row>
+      <template is="dom-if" route-path="/ambientMode">
+        <settings-subpage page-title="$i18n{ambientModeTitle}">
+          <settings-ambient-mode-page prefs="{{prefs}}">
+          </settings-ambient-mode-page>
+        </settings-subpage>
+      </template>
+
+      <template is="dom-if" route-path="/ambientMode/photos">
+        <settings-subpage>
+          <settings-ambient-mode-photos-page>
+          </settings-ambient-mode-photos-page>
+        </settings-subpage>
+      </template>
+
     </template>
 
-    <!-- Dark mode -->
-    <template is="dom-if" if="[[isDarkModeAllowed_]]">
-      <cr-link-row
-          class="hr"
-          id="darkModeRow"
-          label="$i18n{darkModeTitle}"
-          on-click="navigateToDarkMode_"
-          role-description="$i18n{subpageArrowRoleDescription}">
-      </cr-link-row>
-    </template>
-  </div>
-
-  <template is="dom-if" route-path="/changePicture">
-    <settings-subpage page-title="$i18n{changePictureTitle}">
-      <settings-change-picture></settings-change-picture>
-    </settings-subpage>
-  </template>
-
-  <template is="dom-if" if="[[isAmbientModeEnabled_]]">
-    <template is="dom-if" route-path="/ambientMode">
-      <settings-subpage page-title="$i18n{ambientModeTitle}">
-        <settings-ambient-mode-page prefs="{{prefs}}">
-        </settings-ambient-mode-page>
+    <template is="dom-if" route-path="/darkMode">
+      <settings-subpage page-title="$i18n{darkModeTitle}">
+        <settings-dark-mode-subpage prefs="{{prefs}}">
+        </settings-dark-mode-subpage>
       </settings-subpage>
     </template>
-
-    <template is="dom-if" route-path="/ambientMode/photos">
-      <settings-subpage>
-        <settings-ambient-mode-photos-page>
-        </settings-ambient-mode-photos-page>
-      </settings-subpage>
-    </template>
-
-  </template>
-
-  <template is="dom-if" route-path="/darkMode">
-    <settings-subpage page-title="$i18n{darkModeTitle}">
-      <settings-dark-mode-subpage prefs="{{prefs}}">
-      </settings-dark-mode-subpage>
-    </settings-subpage>
   </template>
 </settings-animated-pages>
diff --git a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.js b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.js
index cd9f6bd..eb4493251 100644
--- a/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.js
+++ b/chrome/browser/resources/settings/chromeos/personalization_page/personalization_page.js
@@ -24,6 +24,7 @@
 import {routes} from '../os_route.m.js';
 import {RouteObserverBehavior} from '../route_observer_behavior.js';
 
+import {PersonalizationHubBrowserProxy, PersonalizationHubBrowserProxyImpl} from './personalization_hub_browser_proxy.js';
 import {WallpaperBrowserProxy, WallpaperBrowserProxyImpl} from './wallpaper_browser_proxy.js';
 
 Polymer({
@@ -66,6 +67,15 @@
       readOnly: true,
     },
 
+    /** @private */
+    isPersonalizationHubEnabled_: {
+      type: Boolean,
+      value() {
+        return loadTimeData.getBoolean('isPersonalizationHubEnabled');
+      },
+      readOnly: true,
+    },
+
     /** @private {!Map<string, string>} */
     focusConfig_: {
       type: Object,
@@ -91,21 +101,26 @@
     },
   },
 
+  /** @private {?PersonalizationHubBrowserProxy} */
+  personalizationHubBrowserProxy_: null,
+
   /** @private {?WallpaperBrowserProxy} */
-  browserProxy_: null,
+  wallpaperBrowserProxy_: null,
 
   /** @override */
   created() {
-    this.browserProxy_ = WallpaperBrowserProxyImpl.getInstance();
+    this.wallpaperBrowserProxy_ = WallpaperBrowserProxyImpl.getInstance();
+    this.personalizationHubBrowserProxy_ =
+        PersonalizationHubBrowserProxyImpl.getInstance();
   },
 
   /** @override */
   ready() {
-    this.browserProxy_.isWallpaperSettingVisible().then(
+    this.wallpaperBrowserProxy_.isWallpaperSettingVisible().then(
         isWallpaperSettingVisible => {
           this.showWallpaperRow_ = isWallpaperSettingVisible;
         });
-    this.browserProxy_.isWallpaperPolicyControlled().then(
+    this.wallpaperBrowserProxy_.isWallpaperPolicyControlled().then(
         isPolicyControlled => {
           this.isWallpaperPolicyControlled_ = isPolicyControlled;
         });
@@ -128,7 +143,12 @@
    * @private
    */
   openWallpaperManager_() {
-    this.browserProxy_.openWallpaperManager();
+    this.wallpaperBrowserProxy_.openWallpaperManager();
+  },
+
+  /** @private */
+  openPersonalizationHub_() {
+    this.personalizationHubBrowserProxy_.openPersonalizationHub();
   },
 
   /** @private */
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts
index 57da7ca5..bfb6dce 100644
--- a/chrome/browser/resources/settings/lazy_load.ts
+++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -91,6 +91,7 @@
 export {SettingsPasswordsDeletionDialogElement} from './clear_browsing_data_dialog/passwords_deletion_dialog.js';
 export {ControlledButtonElement} from './controls/controlled_button.js';
 export {SettingsCheckboxElement} from './controls/settings_checkbox.js';
+export {SettingsRadioGroupElement} from './controls/settings_radio_group.js';
 export {SettingsSliderElement} from './controls/settings_slider.js';
 export {SettingsTextareaElement} from './controls/settings_textarea.js';
 export {DownloadsBrowserProxy, DownloadsBrowserProxyImpl} from './downloads_page/downloads_browser_proxy.js';
@@ -120,6 +121,7 @@
 export {PrivacyReviewHistorySyncFragmentElement} from './privacy_page/privacy_review/privacy_review_history_sync_fragment.js';
 export {PrivacyReviewMsbbFragmentElement} from './privacy_page/privacy_review/privacy_review_msbb_fragment.js';
 export {SettingsPrivacyReviewPageElement} from './privacy_page/privacy_review/privacy_review_page.js';
+export {PrivacyReviewWelcomeFragmentElement} from './privacy_page/privacy_review/privacy_review_welcome_fragment.js';
 export {SettingsSecureDnsElement} from './privacy_page/secure_dns.js';
 export {SecureDnsInputElement} from './privacy_page/secure_dns_input.js';
 export {BioEnrollDialogPage, SettingsSecurityKeysBioEnrollDialogElement} from './privacy_page/security_keys_bio_enroll_dialog.js';
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_history_sync_fragment.ts b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_history_sync_fragment.ts
index f976131..644026b2 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_history_sync_fragment.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_history_sync_fragment.ts
@@ -10,18 +10,27 @@
 import '../../prefs/prefs.js';
 import './privacy_review_description_item.js';
 import './privacy_review_fragment_shared_css.js';
+import './privacy_review_fragment_shared_css.js';
+import '../../controls/settings_toggle_button.js';
 
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {WebUIListenerMixin, WebUIListenerMixinInterface} from 'chrome://resources/js/web_ui_listener_mixin.js';
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {BaseMixin} from '../../base_mixin.js';
+import {SettingsToggleButtonElement} from '../../controls/settings_toggle_button.js';
 import {SyncBrowserProxy, SyncBrowserProxyImpl, SyncPrefs, syncPrefsIndividualDataTypes} from '../../people_page/sync_browser_proxy.js';
 import {routes} from '../../route.js';
 import {Route, RouteObserverMixin, RouteObserverMixinInterface, Router} from '../../router.js';
 
 import {PrivacyReviewStep} from './constants.js';
 
+export interface PrivacyReviewHistorySyncFragmentElement {
+  $: {
+    historyToggle: SettingsToggleButtonElement,
+  };
+}
+
 const PrivacyReviewHistorySyncFragmentElementBase =
     RouteObserverMixin(WebUIListenerMixin(BaseMixin(PolymerElement))) as {
   new (): PolymerElement&RouteObserverMixinInterface&
@@ -134,6 +143,12 @@
     return true;
   }
 }
+declare global {
+  interface HTMLElementTagNameMap {
+    'privacy-review-history-sync-fragment':
+        PrivacyReviewHistorySyncFragmentElement;
+  }
+}
 
 customElements.define(
     PrivacyReviewHistorySyncFragmentElement.is,
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts
index dbd5a0f8..452c730 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_page.ts
@@ -97,7 +97,7 @@
       stepIndicatorModel_: {
         type: Object,
         computed:
-            'computeStepIndicatorModel_(privacyReviewStep_, prefs.generated.cookie_primary_setting, prefs.generated.safe_browsing)',
+            'computeStepIndicatorModel(privacyReviewStep_, prefs.generated.cookie_primary_setting, prefs.generated.safe_browsing)',
       },
     };
   }
@@ -334,7 +334,9 @@
         .onBackNavigation!();
   }
 
-  private computeStepIndicatorModel_(): StepIndicatorModel {
+  // TODO(rainhard): This is made public only because it is accessed by tests.
+  // Should change tests so that this method can be made private again.
+  computeStepIndicatorModel(): StepIndicatorModel {
     let stepCount = 0;
     let activeIndex = 0;
     for (const step of Object.values(PrivacyReviewStep)) {
@@ -396,5 +398,11 @@
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'settings-privacy-review-page': SettingsPrivacyReviewPageElement;
+  }
+}
+
 customElements.define(
     SettingsPrivacyReviewPageElement.is, SettingsPrivacyReviewPageElement);
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_welcome_fragment.ts b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_welcome_fragment.ts
index 7f2c23b7..9340c78 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_welcome_fragment.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_review/privacy_review_welcome_fragment.ts
@@ -13,6 +13,12 @@
 
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+export interface PrivacyReviewWelcomeFragmentElement {
+  $: {
+    startButton: HTMLElement,
+  };
+}
+
 export class PrivacyReviewWelcomeFragmentElement extends PolymerElement {
   static get is() {
     return 'privacy-review-welcome-fragment';
@@ -44,4 +50,4 @@
 
 customElements.define(
     PrivacyReviewWelcomeFragmentElement.is,
-    PrivacyReviewWelcomeFragmentElement);
\ No newline at end of file
+    PrivacyReviewWelcomeFragmentElement);
diff --git a/chrome/browser/share/share_submenu_model.cc b/chrome/browser/share/share_submenu_model.cc
index d5d0ff7..889713f6 100644
--- a/chrome/browser/share/share_submenu_model.cc
+++ b/chrome/browser/share/share_submenu_model.cc
@@ -98,7 +98,8 @@
   AddGenerateQRCodeItem();
   AddSendTabToSelfItem();
   AddCopyLinkItem();
-  AddShareToThirdPartyItems();
+  // Temporarily disabled: https://crbug.com/1272875
+  // AddShareToThirdPartyItems();
 }
 
 ShareSubmenuModel::~ShareSubmenuModel() = default;
diff --git a/chrome/browser/ssl/ocsp_browsertest.cc b/chrome/browser/ssl/ocsp_browsertest.cc
index a071967..943d83d3 100644
--- a/chrome/browser/ssl/ocsp_browsertest.cc
+++ b/chrome/browser/ssl/ocsp_browsertest.cc
@@ -27,6 +27,7 @@
 #include "net/cert/ev_root_ca_metadata.h"
 #include "net/test/cert_test_util.h"
 #include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/test_data_directory.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/mojom/ssl_config.mojom.h"
 #include "third_party/blink/public/common/features.h"
@@ -35,14 +36,6 @@
 
 namespace {
 
-// SHA256 hash of the testserver root_ca_cert DER.
-// openssl x509 -in root_ca_cert.pem -outform der | \
-//   openssl dgst -sha256 -binary | xxd -i
-static const net::SHA256HashValue kTestRootCertHash = {
-    {0xb2, 0xab, 0xa3, 0xa5, 0xd4, 0x11, 0x56, 0xcb, 0xb9, 0x23, 0x35,
-     0x07, 0x6d, 0x0b, 0x51, 0xbe, 0xd3, 0xee, 0x2e, 0xab, 0xe7, 0xab,
-     0x6b, 0xad, 0xcc, 0x2a, 0xfa, 0x35, 0xfb, 0x8e, 0x31, 0x5e}};
-
 // The test EV policy OID used for generated certs.
 static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1";
 
@@ -84,8 +77,12 @@
     // TODO(https://crbug.com/1085233): when the CertVerifierService is moved
     // out of process, the ScopedTestEVPolicy needs to be instantiated in
     // that process.
+    scoped_refptr<net::X509Certificate> root_cert = net::ImportCertFromFile(
+        net::GetTestCertsDirectory(), "root_ca_cert.pem");
+    ASSERT_TRUE(root_cert);
     ev_test_policy_ = std::make_unique<net::ScopedTestEVPolicy>(
-        net::EVRootCAMetadata::GetInstance(), kTestRootCertHash,
+        net::EVRootCAMetadata::GetInstance(),
+        net::X509Certificate::CalculateFingerprint256(root_cert->cert_buffer()),
         kOCSPTestCertPolicy);
   }
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 121599a..c23001d 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2822,6 +2822,8 @@
       "webui/settings/chromeos/people_section.h",
       "webui/settings/chromeos/peripheral_data_access_handler.cc",
       "webui/settings/chromeos/peripheral_data_access_handler.h",
+      "webui/settings/chromeos/personalization_hub_handler.cc",
+      "webui/settings/chromeos/personalization_hub_handler.h",
       "webui/settings/chromeos/personalization_section.cc",
       "webui/settings/chromeos/personalization_section.h",
       "webui/settings/chromeos/plugin_vm_handler.cc",
@@ -4656,6 +4658,8 @@
       "views/user_education/tutorial_bubble_factory_views.h",
       "views/web_apps/file_handler_launch_dialog_view.cc",
       "views/web_apps/file_handler_launch_dialog_view.h",
+      "views/web_apps/frame_toolbar/system_app_accessible_name.cc",
+      "views/web_apps/frame_toolbar/system_app_accessible_name.h",
       "views/web_apps/frame_toolbar/web_app_content_settings_container.cc",
       "views/web_apps/frame_toolbar/web_app_content_settings_container.h",
       "views/web_apps/frame_toolbar/web_app_frame_toolbar_utils.cc",
diff --git a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
index 81ebb91..387c342 100644
--- a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
+++ b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
@@ -241,7 +241,9 @@
   ~SelfDestroyAppItem() override = default;
 
   // ChromeAppListItem:
-  void Activate(int event_flags) override { updater_->RemoveItem(id()); }
+  void Activate(int event_flags) override {
+    updater_->RemoveItem(id(), /*is_uninstall=*/true);
+  }
 
  private:
   AppListModelUpdater* updater_;
diff --git a/chrome/browser/ui/app_list/app_list_model_builder.cc b/chrome/browser/ui/app_list/app_list_model_builder.cc
index 191a520a..11086e8e 100644
--- a/chrome/browser/ui/app_list/app_list_model_builder.cc
+++ b/chrome/browser/ui/app_list/app_list_model_builder.cc
@@ -68,7 +68,10 @@
     service_->RemoveUninstalledItem(id);
     return;
   }
-  model_updater_->RemoveUninstalledItem(id);
+
+  // The parameter `is_uninstall` is true because the item is removed due to
+  // local app uninstallation rather than sync.
+  model_updater_->RemoveItem(id, /*is_uninstall=*/true);
 }
 
 const app_list::AppListSyncableService::SyncItem*
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index 1448a0c..ff847c03 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -57,8 +57,7 @@
   virtual void AddAppItemToFolder(std::unique_ptr<ChromeAppListItem> app_item,
                                   const std::string& folder_id,
                                   bool add_from_local) {}
-  virtual void RemoveItem(const std::string& id) {}
-  virtual void RemoveUninstalledItem(const std::string& id) {}
+  virtual void RemoveItem(const std::string& id, bool is_uninstall) {}
   virtual void SetStatus(ash::AppListModelStatus status) {}
   // For SearchModel:
   virtual void SetSearchEngineIsGoogle(bool is_google) {}
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc
index a0c8acc..409106b2 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -920,14 +920,14 @@
 
 void AppListSyncableService::RemoveItem(const std::string& id) {
   RemoveSyncItem(id);
-  model_updater_->RemoveItem(id);
+  model_updater_->RemoveItem(id, /*is_uninstall=*/false);
   PruneEmptySyncFolders();
   PruneRedundantPageBreakItems();
 }
 
 void AppListSyncableService::RemoveUninstalledItem(const std::string& id) {
   RemoveSyncItem(id);
-  model_updater_->RemoveUninstalledItem(id);
+  model_updater_->RemoveItem(id, /*is_uninstall=*/true);
   PruneEmptySyncFolders();
   PruneRedundantPageBreakItems();
 }
@@ -1328,7 +1328,7 @@
       LOG(ERROR) << "Synced item type: " << specifics.item_type()
                  << " != existing sync item type: " << sync_item->item_type
                  << " Deleting item from model!";
-      model_updater_->RemoveItem(item_id);
+      model_updater_->RemoveItem(item_id, /*is_uninstall=*/false);
     }
     VLOG(2) << this << " - ProcessSyncItem: Delete existing entry: "
             << sync_item->ToString();
@@ -1487,7 +1487,7 @@
   // when all children have been deleted.
   if (item_type == sync_pb::AppListSpecifics::TYPE_APP ||
       item_type == sync_pb::AppListSpecifics::TYPE_PAGE_BREAK) {
-    model_updater_->RemoveItem(item_id);
+    model_updater_->RemoveItem(item_id, /*is_uninstall=*/false);
   }
 }
 
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index 4954c3a0..3a4a0700 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -2047,7 +2047,7 @@
   // A hacky way to emulate that an item is disabled locally (in other words,
   // the app's sync data exists but its app list item data is missing).
   AppListModelUpdater* model_updater = GetModelUpdater();
-  model_updater->RemoveItem(kItemId1);
+  model_updater->RemoveItem(kItemId1, /*is_uninstall=*/true);
 
   // Install a new app and verify the app order.
   const std::string kItemId4 = CreateNextAppId(GenerateId("app_id4"));
@@ -2058,7 +2058,7 @@
             std::vector<std::string>({"A", "B", "C", "D"}));
 
   // Remove another item from the model. Now only "A" and "B" are in the model.
-  model_updater->RemoveItem(kItemId3);
+  model_updater->RemoveItem(kItemId3, /*is_uninstall=*/true);
 
   // Install a new app and verify the app order.
   const std::string kItemId5 = CreateNextAppId(GenerateId("app_id5"));
@@ -2069,7 +2069,7 @@
             std::vector<std::string>({"A", "B", "C", "D", "F"}));
 
   // Remove another item from the model. Now only "A" and "B" are in the model.
-  model_updater->RemoveItem(kItemId5);
+  model_updater->RemoveItem(kItemId5, /*is_uninstall=*/true);
 
   // Install a new app and verify the app order.
   const std::string kItemId6 = CreateNextAppId(GenerateId("app_id6"));
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc b/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc
index 18b6ca8..a23ff4a 100644
--- a/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/app_service/app_service_app_model_builder_unittest.cc
@@ -152,7 +152,7 @@
   proxy->AppRegistryCache().ForEachApp(
       [&model_updater, &app_type](const apps::AppUpdate& update) {
         if (update.AppType() != app_type) {
-          model_updater->RemoveItem(update.AppId());
+          model_updater->RemoveItem(update.AppId(), /*is_uninstall=*/true);
         }
       });
 }
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
index 81d34300..de5adb5 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -436,7 +436,7 @@
   proxy->AppRegistryCache().ForEachApp(
       [&model_updater](const apps::AppUpdate& update) {
         if (update.AppType() != apps::mojom::AppType::kArc) {
-          model_updater->RemoveItem(update.AppId());
+          model_updater->RemoveItem(update.AppId(), /*is_uninstall=*/true);
         }
       });
   base::RunLoop().RunUntilIdle();
@@ -448,7 +448,7 @@
       ->AppRegistryCache()
       .ForEachApp([&model_updater](const apps::AppUpdate& update) {
         if (update.AppType() == apps::mojom::AppType::kArc) {
-          model_updater->RemoveItem(update.AppId());
+          model_updater->RemoveItem(update.AppId(), /*is_uninstall=*/true);
         }
       });
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
index 5c79cd0..d56111e5 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -230,20 +230,17 @@
     EndTemporarySortAndTakeAction(EndAction::kCommit);
 }
 
-void ChromeAppListModelUpdater::RemoveItem(const std::string& id) {
+void ChromeAppListModelUpdater::RemoveItem(const std::string& id,
+                                           bool is_uninstall) {
   // Copy the ID to the stack since it may to be destroyed in
   // RemoveChromeItem(). See crbug.com/1190347.
   std::string id_copy = id;
-  item_manager_->RemoveChromeItem(id_copy);
-  model_.DeleteItem(id_copy, /*can_clean_folder=*/false);
-}
 
-void ChromeAppListModelUpdater::RemoveUninstalledItem(const std::string& id) {
-  // Copy the ID to the stack since it may to be destroyed in
-  // RemoveChromeItem(). See crbug.com/1190347.
-  std::string id_copy = id;
   item_manager_->RemoveChromeItem(id_copy);
-  model_.DeleteItem(id_copy, /*can_clean_folder=*/true);
+
+  // Clean the parent folder if any, when item is deleted due to app
+  // uninstallation rather than sync.
+  model_.DeleteItem(id_copy, is_uninstall);
 }
 
 void ChromeAppListModelUpdater::SetStatus(ash::AppListModelStatus status) {
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
index 43a318fd..08bea1f 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -46,8 +46,7 @@
   void AddAppItemToFolder(std::unique_ptr<ChromeAppListItem> app_item,
                           const std::string& folder_id,
                           bool add_from_local) override;
-  void RemoveItem(const std::string& id) override;
-  void RemoveUninstalledItem(const std::string& id) override;
+  void RemoveItem(const std::string& id, bool is_uninstall) override;
   void SetStatus(ash::AppListModelStatus status) override;
   void SetSearchEngineIsGoogle(bool is_google) override;
   void UpdateSearchBox(const std::u16string& text,
diff --git a/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc b/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc
index 1fdec79..da78b5a 100644
--- a/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc
+++ b/chrome/browser/ui/app_list/test/app_list_syncable_service_test_base.cc
@@ -41,12 +41,13 @@
   AppListModelUpdater* model_updater = GetModelUpdater();
   for (std::string& id : existing_item_ids) {
     app_list_syncable_service()->RemoveItem(id);
-    model_updater->RemoveItem(id);
+    model_updater->RemoveItem(id, /*is_uninstall=*/true);
   }
 
   // Delete all default page breaks.
   for (size_t i = 0; i < app_list::kDefaultPageBreakAppIdsLength; ++i)
-    model_updater->RemoveItem(app_list::kDefaultPageBreakAppIds[i]);
+    model_updater->RemoveItem(app_list::kDefaultPageBreakAppIds[i],
+                              /*is_uninstall=*/true);
 
   content::RunAllTasksUntilIdle();
 }
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
index e7841b8..255b4d3 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -33,7 +33,8 @@
   items_.push_back(std::move(item));
 }
 
-void FakeAppListModelUpdater::RemoveItem(const std::string& id) {
+void FakeAppListModelUpdater::RemoveItem(const std::string& id,
+                                         bool is_uninstall) {
   size_t index;
   if (FindItemIndexForTest(id, &index)) {
     const std::string folder_id = items_[index]->folder_id();
@@ -49,14 +50,10 @@
         ++folder_item_count;
     }
     if (!folder_item_count)
-      RemoveItem(folder_id);
+      RemoveItem(folder_id, is_uninstall);
   }
 }
 
-void FakeAppListModelUpdater::RemoveUninstalledItem(const std::string& id) {
-  RemoveItem(id);
-}
-
 void FakeAppListModelUpdater::SetItemIcon(const std::string& id,
                                           const gfx::ImageSkia& icon) {
   ++update_image_count_;
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
index ae31bef..c82d535 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -34,8 +34,7 @@
       app_list::AppListSyncableService::SyncItem* sync_item,
       bool update_name,
       bool update_folder) override;
-  void RemoveItem(const std::string& id) override;
-  void RemoveUninstalledItem(const std::string& id) override;
+  void RemoveItem(const std::string& id, bool is_uninstall) override;
   void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) override;
   void SetItemFolderId(const std::string& id,
                        const std::string& folder_id) override;
diff --git a/chrome/browser/ui/tabs/tab_menu_model.h b/chrome/browser/ui/tabs/tab_menu_model.h
index 7c2cb0cb..174daca0 100644
--- a/chrome/browser/ui/tabs/tab_menu_model.h
+++ b/chrome/browser/ui/tabs/tab_menu_model.h
@@ -35,8 +35,7 @@
   TabMenuModel& operator=(const TabMenuModel&) = delete;
   ~TabMenuModel() override;
 
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TabMenuModel,
-                                         kAddToNewGroupItemIdentifier);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kAddToNewGroupItemIdentifier);
 
  private:
   void Build(TabStripModel* tab_strip, int index);
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h
index 07c74992..88cf52d6 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.h
+++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -121,7 +121,7 @@
                      public TabStripModelObserver,
                      public content::WebContentsObserver {
  public:
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(AppMenuModel, kHistoryMenuItem);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kHistoryMenuItem);
 
   // First command ID to use for the recent tabs menu. This is one higher than
   // the first command id used for the bookmarks menus, as the command ids for
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
index eca56071..55e89c7 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_sync_browsertest.cc
@@ -97,30 +97,14 @@
       const PageInfoBubbleViewSyncBrowserTest& chip) = delete;
 
  protected:
-  void SetupSyncForAccount(Profile* profile) {
-    syncer::SyncServiceImpl* sync_service =
-        SyncServiceFactory::GetAsSyncServiceImplForProfile(profile);
-
-    sync_service->OverrideNetworkForTest(
-        fake_server::CreateFakeServerHttpPostProviderFactory(
-            GetFakeServer()->AsWeakPtr()));
-
-    std::string username;
-
-    if (username.empty()) {
-      username = "user@gmail.com";
-    }
-
-    std::unique_ptr<SyncServiceImplHarness> harness =
-        SyncServiceImplHarness::Create(
-            browser()->profile(), username, "password",
-            SyncServiceImplHarness::SigninType::FAKE_SIGNIN);
+  void SetupSyncForAccount() {
+    ASSERT_TRUE(SetupClients());
 
     // Sign the profile in.
-    ASSERT_TRUE(harness->SignInPrimaryAccount());
+    ASSERT_TRUE(GetClient(0)->SignInPrimaryAccount());
 
     CoreAccountInfo current_info =
-        IdentityManagerFactory::GetForProfile(browser()->profile())
+        IdentityManagerFactory::GetForProfile(GetProfile(0))
             ->GetPrimaryAccountInfo(signin::ConsentLevel::kSync);
     // Need to update hosted domain since it is not populated.
     AccountInfo account_info;
@@ -129,10 +113,9 @@
     account_info.email = current_info.email;
     account_info.hosted_domain = kNoHostedDomainFound;
     signin::UpdateAccountInfoForAccount(
-        IdentityManagerFactory::GetForProfile(browser()->profile()),
-        account_info);
+        IdentityManagerFactory::GetForProfile(GetProfile(0)), account_info);
 
-    ASSERT_TRUE(harness->SetupSync());
+    ASSERT_TRUE(SetupSync());
   }
 
   const std::u16string GetPageInfoBubbleViewDetailText() {
@@ -147,23 +130,25 @@
 // SB_THREAT_TYPE_GAIA_PASSWORD_REUSE threat type.
 IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewSyncBrowserTest,
                        VerifySignInPasswordReusePageInfoBubble) {
-  Profile* profile = browser()->profile();
   // PageInfo calls GetPasswordProtectionReusedPasswordAccountType which checks
   // to see if the account is syncing.
-  SetupSyncForAccount(profile);
+  SetupSyncForAccount();
 
   ASSERT_TRUE(embedded_test_server()->Start());
   base::HistogramTester histograms;
   histograms.ExpectTotalCount(safe_browsing::kSyncPasswordPageInfoHistogram, 0);
+
+  AddBlankTabAndShow(GetBrowser(0));
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
-      browser(), embedded_test_server()->GetURL("/")));
+      GetBrowser(0), embedded_test_server()->GetURL("/")));
   // Update security state of the current page to match
   // SB_THREAT_TYPE_GAIA_PASSWORD_REUSE.
-  safe_browsing::ChromePasswordProtectionService* service = safe_browsing::
-      ChromePasswordProtectionService::GetPasswordProtectionService(profile);
+  safe_browsing::ChromePasswordProtectionService* service =
+      safe_browsing::ChromePasswordProtectionService::
+          GetPasswordProtectionService(GetProfile(0));
   service->set_username_for_last_shown_warning("user@gmail.com");
   content::WebContents* contents =
-      browser()->tab_strip_model()->GetActiveWebContents();
+      GetBrowser(0)->tab_strip_model()->GetActiveWebContents();
   safe_browsing::ReusedPasswordAccountType account_type;
   account_type.set_account_type(
       safe_browsing::ReusedPasswordAccountType::GMAIL);
@@ -177,11 +162,12 @@
       safe_browsing::LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED,
       "unused_token", account_type);
 
-  OpenPageInfoBubble(browser());
-  views::View* change_password_button = GetView(
-      browser(), PageInfoViewFactory::VIEW_ID_PAGE_INFO_BUTTON_CHANGE_PASSWORD);
+  OpenPageInfoBubble(GetBrowser(0));
+  views::View* change_password_button =
+      GetView(GetBrowser(0),
+              PageInfoViewFactory::VIEW_ID_PAGE_INFO_BUTTON_CHANGE_PASSWORD);
   views::View* safelist_password_reuse_button = GetView(
-      browser(),
+      GetBrowser(0),
       PageInfoViewFactory::VIEW_ID_PAGE_INFO_BUTTON_ALLOWLIST_PASSWORD_REUSE);
 
   SecurityStateTabHelper* helper =
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
index 53c5ddb..15c5e9b 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -33,7 +33,6 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
-#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_header_macros.h"
@@ -292,9 +291,10 @@
   }
 }
 
-void PaymentHandlerWebFlowViewController::PrimaryPageChanged(
-    content::Page& page) {
-  UpdateHeaderView();
+void PaymentHandlerWebFlowViewController::DidStartNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsSameDocument())
+    UpdateHeaderView();
 }
 
 void PaymentHandlerWebFlowViewController::AddNewContents(
@@ -348,8 +348,6 @@
     return;
   }
 
-  DCHECK(FrameSupportsPayments(navigation_handle->GetRenderFrameHost()));
-
   if (first_navigation_complete_callback_) {
     std::move(first_navigation_complete_callback_)
         .Run(true, web_contents()->GetMainFrame()->GetProcess()->GetID(),
@@ -371,13 +369,6 @@
   UpdateHeaderView();
 }
 
-bool PaymentHandlerWebFlowViewController::FrameSupportsPayments(
-    content::RenderFrameHost* rfh) const {
-  return rfh && rfh->IsActive() &&
-         rfh->IsFeatureEnabled(
-             blink::mojom::PermissionsPolicyFeature::kPayment);
-}
-
 void PaymentHandlerWebFlowViewController::AbortPayment() {
   if (web_contents())
     web_contents()->Close();
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
index 1f3cb61..c0f43625 100644
--- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.h
@@ -19,11 +19,6 @@
 
 class Profile;
 
-namespace content {
-class Page;
-class RenderFrameHost;
-}  // namespace content
-
 namespace views {
 class ProgressBar;
 }
@@ -90,14 +85,13 @@
       const content::NativeWebKeyboardEvent& event) override;
 
   // content::WebContentsObserver:
-  void PrimaryPageChanged(content::Page& page) override;
+  void DidStartNavigation(
+      content::NavigationHandle* navigation_handle) override;
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
   void LoadProgressChanged(double progress) override;
   void TitleWasSet(content::NavigationEntry* entry) override;
 
-  bool FrameSupportsPayments(content::RenderFrameHost* rfh) const;
-
   void AbortPayment();
 
   DeveloperConsoleLogger log_;
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
index 709da4b..116da9a0 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
@@ -33,8 +33,7 @@
 class PermissionPromptBubbleView : public views::BubbleDialogDelegateView {
  public:
   METADATA_HEADER(PermissionPromptBubbleView);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(PermissionPromptBubbleView,
-                                         kPermissionPromptBubbleViewIdentifier);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kPermissionPromptBubbleViewIdentifier);
   PermissionPromptBubbleView(Browser* browser,
                              permissions::PermissionPrompt::Delegate* delegate,
                              base::TimeTicks permission_requested_time,
diff --git a/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h b/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h
index 3d6de9fb..5b81363 100644
--- a/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h
+++ b/chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.h
@@ -36,8 +36,7 @@
 class TabGroupEditorBubbleView : public views::BubbleDialogDelegateView {
  public:
   METADATA_HEADER(TabGroupEditorBubbleView);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TabGroupEditorBubbleView,
-                                         kEditorBubbleIdentifier);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kEditorBubbleIdentifier);
 
   static constexpr int TAB_GROUP_HEADER_CXMENU_SAVE_GROUP = 13;
   static constexpr int TAB_GROUP_HEADER_CXMENU_NEW_TAB_IN_GROUP = 14;
diff --git a/chrome/browser/ui/views/tabs/tab_group_header.h b/chrome/browser/ui/views/tabs/tab_group_header.h
index 2df1b44..06ce6b5 100644
--- a/chrome/browser/ui/views/tabs/tab_group_header.h
+++ b/chrome/browser/ui/views/tabs/tab_group_header.h
@@ -32,8 +32,7 @@
  public:
   METADATA_HEADER(TabGroupHeader);
 
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TabGroupHeader,
-                                         kTabGroupHeaderIdentifier);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTabGroupHeaderIdentifier);
 
   TabGroupHeader(TabStrip* tab_strip, const tab_groups::TabGroupId& group);
   TabGroupHeader(const TabGroupHeader&) = delete;
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.h b/chrome/browser/ui/views/translate/translate_bubble_view.h
index 114b03c..299a844f 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.h
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.h
@@ -58,27 +58,18 @@
   };
 
   // Element IDs for ui::ElementTracker
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView, kIdentifier);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kSourceLanguageTab);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kTargetLanguageTab);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView, kCloseButton);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kOptionsMenuButton);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kChangeTargetLanguage);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kTargetLanguageCombobox);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kTargetLanguageDoneButton);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kChangeSourceLanguage);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kSourceLanguageCombobox);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView,
-                                         kSourceLanguageDoneButton);
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(TranslateBubbleView, kErrorMessage);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kIdentifier);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSourceLanguageTab);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTargetLanguageTab);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kCloseButton);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kOptionsMenuButton);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kChangeTargetLanguage);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTargetLanguageCombobox);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTargetLanguageDoneButton);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kChangeSourceLanguage);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSourceLanguageCombobox);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSourceLanguageDoneButton);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kErrorMessage);
 
   TranslateBubbleView(const TranslateBubbleView&) = delete;
   TranslateBubbleView& operator=(const TranslateBubbleView&) = delete;
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc
new file mode 100644
index 0000000..fd22be1
--- /dev/null
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.cc
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.h"
+
+#include <utility>
+
+#include "chrome/browser/ui/views/chrome_typography.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_node_data.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/views/view.h"
+
+SystemAppAccessibleName::SystemAppAccessibleName(const std::u16string& app_name)
+    // TODO(crbug.com/1275657): Clean up the empty string (or remove this class)
+    // after reaching a consensus with UX on button search behavior.
+    : views::Label(u" ",
+                   ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL,
+                   views::style::STYLE_PRIMARY),
+      app_name_(app_name) {
+  SetEnabledColor(SK_ColorTRANSPARENT);
+  SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
+}
+
+SystemAppAccessibleName::~SystemAppAccessibleName() = default;
+
+void SystemAppAccessibleName::GetAccessibleNodeData(ui::AXNodeData* node_data) {
+  node_data->role = ax::mojom::Role::kApplication;
+  node_data->SetName(app_name_);
+}
+
+BEGIN_METADATA(SystemAppAccessibleName, views::View)
+END_METADATA
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.h b/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.h
new file mode 100644
index 0000000..898c162
--- /dev/null
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.h
@@ -0,0 +1,28 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_WEB_APPS_FRAME_TOOLBAR_SYSTEM_APP_ACCESSIBLE_NAME_H_
+#define CHROME_BROWSER_UI_VIEWS_WEB_APPS_FRAME_TOOLBAR_SYSTEM_APP_ACCESSIBLE_NAME_H_
+
+#include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/views/controls/label.h"
+
+// An invisible, but accessible label that indicates the system app name. This
+// label can only be focused by accessibility features.
+class SystemAppAccessibleName : public views::Label {
+ public:
+  METADATA_HEADER(SystemAppAccessibleName);
+  explicit SystemAppAccessibleName(const std::u16string& app_name);
+  SystemAppAccessibleName(const SystemAppAccessibleName&) = delete;
+  SystemAppAccessibleName& operator=(const SystemAppAccessibleName&) = delete;
+  ~SystemAppAccessibleName() override;
+
+  // views::View:
+  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
+
+ private:
+  std::u16string app_name_;
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_WEB_APPS_FRAME_TOOLBAR_SYSTEM_APP_ACCESSIBLE_NAME_H_
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
index 603e6a5..1b1c8bb 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_controller.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_params.h"
+#include "chrome/browser/ui/views/web_apps/frame_toolbar/system_app_accessible_name.h"
 #include "chrome/browser/ui/views/web_apps/frame_toolbar/terminal_system_app_menu_button_chromeos.h"
 #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_content_settings_container.h"
 #include "chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_utils.h"
@@ -87,6 +88,11 @@
         std::make_unique<WebAppOriginText>(browser_view_->browser()));
   }
 
+  if (app_controller->system_app()) {
+    AddChildView(std::make_unique<SystemAppAccessibleName>(
+        app_controller->GetAppShortName()));
+  }
+
   if (app_controller->AppUsesWindowControlsOverlay()) {
     window_controls_overlay_toggle_button_ = AddChildView(
         std::make_unique<WindowControlsOverlayToggleButton>(browser_view_));
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h
index b78661c9..4f46f06 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_toolbar_button_container.h
@@ -27,6 +27,7 @@
 class WebAppMenuButton;
 class WebAppOriginText;
 class WindowControlsOverlayToggleButton;
+class SystemAppAccessibleName;
 
 class WebAppToolbarButtonContainer : public views::View,
                                      public IconLabelBubbleView::Delegate,
@@ -155,6 +156,7 @@
   raw_ptr<WebAppContentSettingsContainer> content_settings_container_ = nullptr;
   raw_ptr<ExtensionsToolbarContainer> extensions_container_ = nullptr;
   raw_ptr<WebAppMenuButton> web_app_menu_button_ = nullptr;
+  raw_ptr<SystemAppAccessibleName> system_app_accessible_name_ = nullptr;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_WEB_APPS_FRAME_TOOLBAR_WEB_APP_TOOLBAR_BUTTON_CONTAINER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc b/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc
new file mode 100644
index 0000000..b85399f3
--- /dev/null
+++ b/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.cc
@@ -0,0 +1,37 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.h"
+
+#include "ash/constants/ash_features.h"
+#include "base/bind.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
+#include "content/public/browser/web_ui.h"
+
+namespace chromeos {
+namespace settings {
+
+PersonalizationHubHandler::PersonalizationHubHandler() = default;
+
+PersonalizationHubHandler::~PersonalizationHubHandler() = default;
+
+void PersonalizationHubHandler::RegisterMessages() {
+  DCHECK(ash::features::IsPersonalizationHubEnabled());
+  web_ui()->RegisterMessageCallback(
+      "openPersonalizationHub",
+      base::BindRepeating(
+          &PersonalizationHubHandler::HandleOpenPersonalizationHub,
+          base::Unretained(this)));
+}
+
+void PersonalizationHubHandler::HandleOpenPersonalizationHub(
+    base::Value::ConstListView args) {
+  CHECK_EQ(0U, args.size());
+  web_app::LaunchSystemWebAppAsync(Profile::FromWebUI(web_ui()),
+                                   web_app::SystemAppType::PERSONALIZATION);
+}
+
+}  // namespace settings
+}  // namespace chromeos
diff --git a/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.h b/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.h
new file mode 100644
index 0000000..94634ce
--- /dev/null
+++ b/chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.h
@@ -0,0 +1,38 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PERSONALIZATION_HUB_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PERSONALIZATION_HUB_HANDLER_H_
+
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+#include "base/values.h"
+
+namespace chromeos {
+namespace settings {
+
+// Chrome "Personalization Hub" settings page UI handler.
+class PersonalizationHubHandler : public ::settings::SettingsPageUIHandler {
+ public:
+  PersonalizationHubHandler();
+
+  PersonalizationHubHandler(const PersonalizationHubHandler&) = delete;
+  PersonalizationHubHandler& operator=(const PersonalizationHubHandler&) =
+      delete;
+
+  ~PersonalizationHubHandler() override;
+
+  // SettingsPageUIHandler:
+  void RegisterMessages() override;
+  void OnJavascriptAllowed() override {}
+  void OnJavascriptDisallowed() override {}
+
+ private:
+  void HandleOpenPersonalizationHub(base::Value::ConstListView args);
+};
+
+}  // namespace settings
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_PERSONALIZATION_HUB_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc b/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
index 68adb4d..ed47d5f 100644
--- a/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/personalization_section.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/webui/settings/chromeos/ambient_mode_handler.h"
 #include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h"
 #include "chrome/browser/ui/webui/settings/chromeos/os_settings_features_util.h"
+#include "chrome/browser/ui/webui/settings/chromeos/personalization_hub_handler.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
 #include "chrome/browser/ui/webui/settings/chromeos/wallpaper_handler.h"
 #include "chrome/browser/ui/webui/webui_util.h"
@@ -313,6 +314,9 @@
        IDS_SETTINGS_PHOTO_DISCARD_ACCESSIBLE_TEXT},
       {"photoModeAccessibleText", IDS_SETTINGS_PHOTO_MODE_ACCESSIBLE_TEXT},
       {"videoModeAccessibleText", IDS_SETTINGS_VIDEO_MODE_ACCESSIBLE_TEXT},
+      {"personalizationHubTitle", IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB},
+      {"personalizationHubSubtitle",
+       IDS_OS_SETTINGS_OPEN_PERSONALIZATION_HUB_SUBTITLE},
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
@@ -333,6 +337,8 @@
           IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM,
           base::UTF8ToUTF16(GetGooglePhotosURL().spec())));
   html_source->AddBoolean("isDarkModeAllowed", IsDarkModeAllowed());
+  html_source->AddBoolean("isPersonalizationHubEnabled",
+                          ash::features::IsPersonalizationHubEnabled());
 }
 
 void PersonalizationSection::AddHandlers(content::WebUI* web_ui) {
@@ -340,6 +346,10 @@
       std::make_unique<chromeos::settings::WallpaperHandler>());
   web_ui->AddMessageHandler(
       std::make_unique<chromeos::settings::ChangePictureHandler>());
+  if (ash::features::IsPersonalizationHubEnabled()) {
+    web_ui->AddMessageHandler(
+        std::make_unique<chromeos::settings::PersonalizationHubHandler>());
+  }
 
   if (!profile()->IsGuestSession() &&
       chromeos::features::IsAmbientModeEnabled()) {
diff --git a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
index 5ce7c8f..ed907ec 100644
--- a/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/web_applications/system_web_apps/test/system_web_app_manager_browsertest.cc
@@ -70,6 +70,8 @@
 #include "ash/public/cpp/shelf_item_delegate.h"
 #include "ash/public/cpp/shelf_model.h"
 #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
+#include "chrome/browser/ash/accessibility/accessibility_manager.h"
+#include "chrome/browser/ash/accessibility/speech_monitor.h"
 #include "chrome/browser/ash/file_manager/file_manager_test_util.h"
 #include "chrome/browser/policy/system_features_disable_list_policy_handler.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
@@ -78,6 +80,8 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/policy/core/common/policy_pref_names.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "extensions/browser/browsertest_util.h"
+#include "ui/base/test/ui_controls.h"
 #endif
 
 namespace {
@@ -1750,6 +1754,54 @@
 }
 #endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+class SystemWebAppAccessibilityTest : public SystemWebAppManagerBrowserTest {
+ public:
+  SystemWebAppAccessibilityTest()
+      : SystemWebAppManagerBrowserTest(/*install_mock*/ false) {
+    maybe_installation_ =
+        TestSystemWebAppInstallation::SetUpStandaloneSingleWindowApp();
+  }
+  ~SystemWebAppAccessibilityTest() override = default;
+
+ protected:
+  ash::test::SpeechMonitor speech_monitor_;
+};
+
+IN_PROC_BROWSER_TEST_P(SystemWebAppAccessibilityTest,
+                       CanCycleToWindowControlButtons) {
+  ash::AccessibilityManager::Get()->EnableSpokenFeedback(true);
+  WaitForTestSystemAppInstall();
+
+  // Launch the app so it shows up in shelf.
+  Browser* app_browser;
+  LaunchApp(maybe_installation_->GetType(), &app_browser);
+
+  auto* app_window = app_browser->window()->GetNativeWindow();
+
+  // F6 to switch pane.
+  speech_monitor_.Call([&]() {
+    ui_controls::SendKeyPress(app_window, ui::VKEY_F6, /*Ctrl*/ false,
+                              /*Shift*/ false, /*Alt*/ false,
+                              /*Launcher*/ false);
+  });
+  speech_monitor_.ExpectSpeech("Test System App");
+  speech_monitor_.ExpectSpeech("Application");
+
+  // Launcher-B to find minimize button.
+  speech_monitor_.Call([&]() {
+    ui_controls::SendKeyPress(app_window, ui::VKEY_B, /*Ctrl*/ false,
+                              /*Shift*/ false, /*Alt*/ false,
+                              /*Launcher*/ true);
+  });
+  speech_monitor_.ExpectSpeech("Minimize");
+  speech_monitor_.ExpectSpeech("Button");
+
+  // Start the actions.
+  speech_monitor_.Replay();
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 #if !BUILDFLAG(IS_CHROMEOS_LACROS)
 INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_REGULAR_PROFILE_P(
     SystemWebAppManagerBrowserTest);
@@ -1811,6 +1863,8 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_REGULAR_PROFILE_P(
     SystemWebAppManagerDefaultBoundsTest);
+INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_REGULAR_PROFILE_P(
+    SystemWebAppAccessibilityTest);
 #endif
 
 #if !BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc
index 4f9a7ba..45ef40a 100644
--- a/chrome/browser/web_applications/web_app_unittest.cc
+++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -106,6 +106,9 @@
   app.AddSource(Source::kPolicy);
   EXPECT_FALSE(app.WasInstalledByUser());
 
+  app.AddSource(Source::kSubApp);
+  EXPECT_FALSE(app.WasInstalledByUser());
+
   app.RemoveSource(Source::kDefault);
   EXPECT_FALSE(app.WasInstalledByUser());
 
@@ -114,6 +117,9 @@
 
   app.RemoveSource(Source::kPolicy);
   EXPECT_FALSE(app.WasInstalledByUser());
+
+  app.RemoveSource(Source::kSubApp);
+  EXPECT_FALSE(app.WasInstalledByUser());
 }
 
 TEST(WebAppTest, CanUserUninstallWebApp) {
@@ -128,6 +134,8 @@
   EXPECT_TRUE(app.CanUserUninstallWebApp());
   app.AddSource(Source::kWebAppStore);
   EXPECT_TRUE(app.CanUserUninstallWebApp());
+  app.AddSource(Source::kSubApp);
+  EXPECT_TRUE(app.CanUserUninstallWebApp());
 
   app.AddSource(Source::kPolicy);
   EXPECT_FALSE(app.CanUserUninstallWebApp());
@@ -138,6 +146,8 @@
   EXPECT_FALSE(app.CanUserUninstallWebApp());
   app.RemoveSource(Source::kWebAppStore);
   EXPECT_FALSE(app.CanUserUninstallWebApp());
+  app.RemoveSource(Source::kSubApp);
+  EXPECT_FALSE(app.CanUserUninstallWebApp());
 
   app.RemoveSource(Source::kSystem);
   EXPECT_FALSE(app.CanUserUninstallWebApp());
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index b1e6b59e..79bc330 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1638359845-f3a57e1e3576a79c171a346bc89e56327c8249db.profdata
+chrome-mac-main-1638381523-35fdf6e0563ae96cbb2c28af5c2765528fead16c.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index b030f0b..dc6483f 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1638370723-e0c73e87080a6ac5bf65eb692830edd320203e34.profdata
+chrome-win32-main-1638381523-6d31ae1c0f737a5ee506e74bc72e3bcf8b6c9109.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 7a0702c2..2cc579d 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1638359845-0eeca6d18241e270ef9d38dd6cc8143e8ae53d88.profdata
+chrome-win64-main-1638381523-85bc055d254c2949c21c33d15f6eeba0de7e86f2.profdata
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
index 9505e0e..a25adac 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info.cc
@@ -9,9 +9,19 @@
 #include <string>
 
 #include "base/check.h"
+#include "base/command_line.h"
 
 namespace chromeos {
 
+namespace switches {
+
+// Overrides |pwa_origin| field of the ChromeOSSystemExtensionInfo structure.
+// Used for development/testing.
+const char kTelemetryExtensionPwaOriginOverrideForTesting[] =
+    "telemetry-extension-pwa-origin-override-for-testing";
+
+}  // namespace switches
+
 namespace {
 
 using ChromeOSSystemExtensionInfos =
@@ -43,11 +53,20 @@
   return getMap().size();
 }
 
-const ChromeOSSystemExtensionInfo& GetChromeOSExtensionInfoForId(
+ChromeOSSystemExtensionInfo GetChromeOSExtensionInfoForId(
     const std::string& id) {
   CHECK(IsChromeOSSystemExtension(id));
 
-  return getMap().at(id);
+  auto info = getMap().at(id);
+
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  if (command_line->HasSwitch(
+          switches::kTelemetryExtensionPwaOriginOverrideForTesting)) {
+    info.pwa_origin = command_line->GetSwitchValueASCII(
+        switches::kTelemetryExtensionPwaOriginOverrideForTesting);
+  }
+
+  return info;
 }
 
 bool IsChromeOSSystemExtension(const std::string& id) {
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info.h b/chrome/common/chromeos/extensions/chromeos_system_extension_info.h
index 51f593381..556ebea 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info.h
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info.h
@@ -10,6 +10,12 @@
 
 namespace chromeos {
 
+namespace switches {
+
+extern const char kTelemetryExtensionPwaOriginOverrideForTesting[];
+
+}  // namespace switches
+
 struct ChromeOSSystemExtensionInfo {
   ChromeOSSystemExtensionInfo(const std::string& manufacturer,
                               const std::string& pwa_origin);
@@ -17,11 +23,11 @@
   ~ChromeOSSystemExtensionInfo();
 
   const std::string manufacturer;
-  const std::string pwa_origin;
+  std::string pwa_origin;
 };
 
 size_t GetChromeOSSystemExtensionInfosSize();
-const ChromeOSSystemExtensionInfo& GetChromeOSExtensionInfoForId(
+ChromeOSSystemExtensionInfo GetChromeOSExtensionInfoForId(
     const std::string& id);
 bool IsChromeOSSystemExtension(const std::string& id);
 
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc b/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
index f09e86e..05f824f 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extension_info_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/common/chromeos/extensions/chromeos_system_extension_info.h"
 
+#include "base/command_line.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(ChromeOSSystemExtensionInfo, AllowlistedExtensionsSizeEqualsToOne) {
@@ -29,3 +30,19 @@
   EXPECT_EQ("HP", extension_info.manufacturer);
   EXPECT_EQ("*://hpcs-appschr.hpcloud.hp.com/*", extension_info.pwa_origin);
 }
+
+TEST(ChromeOSSystemExtensionInfo, PwaOriginOverride) {
+  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+      chromeos::switches::kTelemetryExtensionPwaOriginOverrideForTesting,
+      "*://pwa.website.com/*");
+
+  const auto google_extension_info = chromeos::GetChromeOSExtensionInfoForId(
+      "gogonhoemckpdpadfnjnpgbjpbjnodgc");
+  EXPECT_EQ("*://pwa.website.com/*", google_extension_info.pwa_origin);
+  EXPECT_EQ("HP", google_extension_info.manufacturer);
+
+  const auto hp_extension_info = chromeos::GetChromeOSExtensionInfoForId(
+      "alnedpmllcfpgldkagbfbjkloonjlfjb");
+  EXPECT_EQ("*://pwa.website.com/*", hp_extension_info.pwa_origin);
+  EXPECT_EQ("HP", hp_extension_info.manufacturer);
+}
diff --git a/chrome/common/net/x509_certificate_model_nss_unittest.cc b/chrome/common/net/x509_certificate_model_nss_unittest.cc
index 17073895a..1e4f1a57 100644
--- a/chrome/common/net/x509_certificate_model_nss_unittest.cc
+++ b/chrome/common/net/x509_certificate_model_nss_unittest.cc
@@ -384,25 +384,17 @@
 
 TEST_F(X509CertificateModelTest, ProcessRawBitsSignatureWrap) {
   net::ScopedCERTCertificate cert(net::ImportCERTCertificateFromFile(
-      net::GetTestCertsDirectory(), "root_ca_cert.pem"));
+      net::GetTestCertsDirectory(), "google.single.pem"));
   ASSERT_TRUE(cert.get());
 
   EXPECT_EQ(
-      "B1 B1 83 61 AF DB ED 98 CF 3D 43 5F A7 42 B8 6D\n"
-      "94 36 57 BB AB 04 EE DD 3B B7 6D EC 78 7D 46 59\n"
-      "B1 E6 2A C3 AA A5 70 A7 E1 0C FA 65 37 C6 CB 7D\n"
-      "A1 37 35 A1 FF F0 DD CE B6 A4 2C 12 D4 46 A9 9C\n"
-      "A2 91 3A B0 95 55 97 55 E6 0A DA 63 60 24 19 AC\n"
-      "20 C9 B1 94 40 E9 99 B1 F5 C3 ED 61 5D DE 4C E4\n"
-      "EB D9 0E AC 3A 0A FC 44 7D 0F 77 A6 B6 DA 28 D4\n"
-      "ED EA 3A BC 57 23 9C 72 2B 2D B0 5D 11 02 4D C5\n"
-      "BC B0 D6 7E 00 8E F7 E7 F5 19 3A 23 DF 33 02 AA\n"
-      "4B BF 81 F4 5A 99 EE 74 20 F3 77 A1 F0 85 1E A8\n"
-      "D6 CC A4 CB 31 FA 73 24 A2 0E DD 9F 6F 82 38 5F\n"
-      "85 AC 8D 76 BD D8 F2 69 73 E3 46 44 42 E3 5E F3\n"
-      "AA 5E 44 13 51 EA 0B 78 91 77 96 EE 73 FE 2A B5\n"
-      "88 C1 38 8D 8D A8 19 76 94 05 02 CF D4 6F EB E6\n"
-      "07 F5 9D 52 24 B8 50 A3 0E C4 45 A6 09 B4 06 2D\n"
-      "3E 14 A5 3F 1C 1A BC DA B8 40 3E C1 1C F6 3C 05",
+      "9F 43 CF 5B C4 50 29 B1 BF E2 B0 9A FF 6A 21 1D\n"
+      "2D 12 C3 2C 4E 5A F9 12 E2 CE B9 82 52 2D E7 1D\n"
+      "7E 1A 76 96 90 79 D1 24 52 38 79 BB 63 8D 80 97\n"
+      "7C 23 20 0F 91 4D 16 B9 EA EE F4 6D 89 CA C6 BD\n"
+      "CC 24 68 D6 43 5B CE 2A 58 BF 3C 18 E0 E0 3C 62\n"
+      "CF 96 02 2D 28 47 50 34 E1 27 BA CF 99 D1 50 FF\n"
+      "29 25 C0 36 36 15 33 52 70 BE 31 8F 9F E8 7F E7\n"
+      "11 0C 8D BF 84 A0 42 1A 80 89 B0 31 58 41 07 5F",
       x509_certificate_model::ProcessRawBitsSignatureWrap(cert.get()));
 }
diff --git a/chrome/installer/mac/sign_chrome.py b/chrome/installer/mac/sign_chrome.py
index e675a50..ddbc5376 100755
--- a/chrome/installer/mac/sign_chrome.py
+++ b/chrome/installer/mac/sign_chrome.py
@@ -47,6 +47,10 @@
                 # spctl assessment so don't do it.
                 return False
 
+            @property
+            def inject_get_task_allow_entitlement(self):
+                return True
+
         config_class = DevelopmentCodeSignConfig
 
     return config_class(*config_args)
diff --git a/chrome/installer/mac/signing/README.md b/chrome/installer/mac/signing/README.md
index 4d22a94..2660259 100644
--- a/chrome/installer/mac/signing/README.md
+++ b/chrome/installer/mac/signing/README.md
@@ -30,7 +30,8 @@
 The `--disable-packaging` flag skips the creation of DMG and PKG files, which
 speeds up the signing process when one is only interested in a signed .app
 bundle. The `--development` flag skips over code signing requirements and checks
-that do not work without the official Google signing identity.
+that do not work without the official Google signing identity, and it injects
+the `com.apple.security.get-task-allow` that lets the app be debugged.
 
 ## The Installer Identity
 
diff --git a/chrome/installer/mac/signing/config.py b/chrome/installer/mac/signing/config.py
index 3382f01..1f33eeac 100644
--- a/chrome/installer/mac/signing/config.py
+++ b/chrome/installer/mac/signing/config.py
@@ -182,6 +182,15 @@
         """
         return True
 
+    @property
+    def inject_get_task_allow_entitlement(self):
+        """Returns whether the com.apple.security.get-task-allow entitlement
+        should be added to all entitlement files. This will permit attaching a
+        debugger to a signed process, if the binary was signed with the
+        hardened runtime.
+        """
+        return False
+
     # Computed Properties ######################################################
 
     @property
diff --git a/chrome/installer/mac/signing/modification.py b/chrome/installer/mac/signing/modification.py
index 849ba3d..6a101b0 100644
--- a/chrome/installer/mac/signing/modification.py
+++ b/chrome/installer/mac/signing/modification.py
@@ -17,6 +17,7 @@
 _CF_BUNDLE_ID = 'CFBundleIdentifier'
 _CF_BUNDLE_NAME = 'CFBundleName'
 _ENT_APP_ID = 'com.apple.application-identifier'
+_ENT_GET_TASK_ALLOW = 'com.apple.security.get-task-allow'
 _KS_BRAND_ID = 'KSBrandID'
 _KS_CHANNEL_ID = 'KSChannelID'
 _KS_PRODUCT_ID = 'KSProductID'
@@ -186,14 +187,16 @@
         commands.copy_files(
             os.path.join(packaging_dir, entitlements_name), entitlements_file)
 
-        if dist.channel_customize:
+        if dist.channel_customize or config.inject_get_task_allow_entitlement:
             with commands.PlistContext(
                     entitlements_file, rewrite=True) as entitlements:
-                if _ENT_APP_ID in entitlements:
+                if dist.channel_customize and _ENT_APP_ID in entitlements:
                     app_id = entitlements[_ENT_APP_ID]
                     entitlements[_ENT_APP_ID] = app_id.replace(
                         config.base_config.base_bundle_id,
                         config.base_bundle_id)
+                if config.inject_get_task_allow_entitlement:
+                    entitlements[_ENT_GET_TASK_ALLOW] = True
 
 
 def customize_distribution(paths, dist, config):
diff --git a/chrome/installer/mac/signing/modification_test.py b/chrome/installer/mac/signing/modification_test.py
index 6876746..8ef6c53 100644
--- a/chrome/installer/mac/signing/modification_test.py
+++ b/chrome/installer/mac/signing/modification_test.py
@@ -450,3 +450,89 @@
         ])
 
         self.assertFalse(self._is_framework_unchanged(kwargs))
+
+    def test_get_task_allow_no_channel_customize(self, read_plist, **kwargs):
+        dist = model.Distribution()
+        self.config = test_config.TestConfigInjectGetTaskAllow()
+        config = dist.to_config(self.config)
+
+        modification.customize_distribution(self.paths, dist, config)
+
+        self.assertEqual(5, kwargs['write_plist'].call_count)
+        kwargs['write_plist'].assert_has_calls([
+            mock.call(
+                {
+                    'CFBundleDisplayName': 'Product',
+                    'CFBundleIdentifier': config.base_bundle_id,
+                    'CFBundleName': 'Product',
+                    'KSProductID': 'test.ksproduct',
+                    'KSChannelID-full': '-full'
+                }, '/$W/App Product.app/Contents/Info.plist', 'xml1'),
+            mock.call(
+                {
+                    'com.apple.security.get-task-allow': True,
+                    'com.apple.application-identifier': config.base_bundle_id
+                }, '/$W/app-entitlements.plist', 'xml1'),
+            mock.call({'com.apple.security.get-task-allow': True},
+                      '/$W/helper-gpu-entitlements.plist', 'xml1'),
+            mock.call({'com.apple.security.get-task-allow': True},
+                      '/$W/helper-plugin-entitlements.plist', 'xml1'),
+            mock.call({'com.apple.security.get-task-allow': True},
+                      '/$W/helper-renderer-entitlements.plist', 'xml1'),
+        ])
+
+    def test_get_task_allow_customize_channel(self, read_plist, **kwargs):
+        dist = model.Distribution(
+            channel='canary',
+            app_name_fragment='Canary',
+            product_dirname='Acme/Product Canary',
+            creator_code='Mooo',
+            channel_customize=True)
+        self.config = test_config.TestConfigInjectGetTaskAllow()
+        config = dist.to_config(self.config)
+
+        modification.customize_distribution(self.paths, dist, config)
+
+        self.assertEqual(8, kwargs['write_plist'].call_count)
+        kwargs['write_plist'].assert_has_calls([
+            mock.call(
+                {
+                    'CFBundleIdentifier':
+                        'test.signing.bundle_id.canary.AlertNotificationService'
+                },
+                '/$W/App Product Canary.app/Contents/Frameworks/Product Framework.framework/Helpers/Product Helper (Alerts).app/Contents/Info.plist',
+                'xml1'),
+            mock.call({
+                'CFBundleDisplayName': 'Product Canary'
+            }, '/$W/App Product Canary.app/Contents/Frameworks/Product Framework.framework/Helpers/Product Helper (Alerts).app/Contents/Resources/base.lproj/InfoPlist.strings',
+                      'binary1'),
+            mock.call(
+                {
+                    'CFBundleDisplayName': 'Product Canary',
+                    'CFBundleIdentifier': config.base_bundle_id,
+                    'CFBundleExecutable': config.app_product,
+                    'CFBundleName': 'Product Canary',
+                    'KSProductID': 'test.ksproduct.canary',
+                    'KSChannelID': 'canary',
+                    'KSChannelID-full': 'canary-full',
+                    'CrProductDirName': 'Acme/Product Canary',
+                    'CFBundleSignature': 'Mooo'
+                }, '/$W/App Product Canary.app/Contents/Info.plist', 'xml1'),
+            mock.call(
+                {
+                    'com.apple.security.get-task-allow':
+                        True,
+                    'com.apple.application-identifier':
+                        'test.signing.bundle_id.canary'
+                }, '/$W/app-entitlements.plist', 'xml1'),
+            mock.call({'com.apple.security.get-task-allow': True},
+                      '/$W/helper-gpu-entitlements.plist', 'xml1'),
+            mock.call({'com.apple.security.get-task-allow': True},
+                      '/$W/helper-plugin-entitlements.plist', 'xml1'),
+            mock.call({'com.apple.security.get-task-allow': True},
+                      '/$W/helper-renderer-entitlements.plist', 'xml1'),
+            mock.call({
+                'pfm_domain': 'test.signing.bundle_id.canary'
+            }, '/$W/App Product Canary.app/Contents/Resources/test.signing.bundle_id.canary.manifest/Contents/Resources/test.signing.bundle_id.canary.manifest',
+                      'xml1')
+        ])
diff --git a/chrome/installer/mac/signing/test_config.py b/chrome/installer/mac/signing/test_config.py
index 79f536d9..96a9d69 100644
--- a/chrome/installer/mac/signing/test_config.py
+++ b/chrome/installer/mac/signing/test_config.py
@@ -51,3 +51,10 @@
     @staticmethod
     def is_chrome_branded():
         return False
+
+
+class TestConfigInjectGetTaskAllow(TestConfig):
+
+    @property
+    def inject_get_task_allow_entitlement(self):
+        return True
diff --git a/chrome/service/cloud_print/print_system_cups.cc b/chrome/service/cloud_print/print_system_cups.cc
index 42d625d..0738fd2 100644
--- a/chrome/service/cloud_print/print_system_cups.cc
+++ b/chrome/service/cloud_print/print_system_cups.cc
@@ -433,13 +433,15 @@
 
 void PrintSystemCUPS::InitPrintBackends(
     const base::DictionaryValue* print_system_settings) {
-  const base::ListValue* url_list;
-  if (print_system_settings &&
-      print_system_settings->GetList(kCUPSPrintServerURLs, &url_list)) {
-    for (size_t i = 0; i < url_list->GetList().size(); i++) {
-      std::string print_server_url;
-      if (url_list->GetString(i, &print_server_url))
-        AddPrintServer(print_server_url);
+  if (print_system_settings) {
+    const base::Value* url_list =
+        print_system_settings->FindListKey(kCUPSPrintServerURLs);
+    if (url_list) {
+      for (const base::Value& val : url_list->GetList()) {
+        const std::string* print_server_url = val.GetIfString();
+        if (print_server_url)
+          AddPrintServer(*print_server_url);
+      }
     }
   }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index a12d2b9..82a25e0d 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -7201,6 +7201,9 @@
         "../browser/ash/login/easy_unlock/smartlock_feature_usage_metrics_unittest.cc",
         "../browser/ash/login/easy_unlock/smartlock_state_handler_unittest.cc",
         "../browser/chromeos/extensions/extensions_permissions_tracker_unittest.cc",
+
+        # TODO(b/207754758): Move the following two files into the appropriate target
+        "../browser/chromeos/extensions/telemetry/api/api_guard_delegate_unittest.cc",
         "../browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc",
         "../browser/extensions/api/file_system/consent_provider_unittest.cc",
         "../browser/extensions/api/image_writer_private/removable_storage_provider_chromeos_unittest.cc",
@@ -7218,6 +7221,7 @@
       ]
 
       deps += [
+        "//chrome/browser/chromeos/extensions/telemetry/api",
         "//chrome/browser/chromeos/extensions/telemetry/api:unit_tests",
         "//chrome/common/chromeos/extensions",
         "//chromeos/dbus/image_burner",
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index 38cd8ed..06c4392 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -387,6 +387,7 @@
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_lifetime_browser_proxy.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_reset_browser_proxy.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_sync_browser_proxy.m.js",
+        "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_personalization_hub_browser_proxy.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_wallpaper_browser_proxy.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/tether_connection_dialog_test.m.js",
         "$root_gen_dir/chrome/test/data/webui/settings/chromeos/text_to_speech_subpage_tests.m.js",
diff --git a/chrome/test/data/webui/print_preview/BUILD.gn b/chrome/test/data/webui/print_preview/BUILD.gn
index 02c9a683..f03595de 100644
--- a/chrome/test/data/webui/print_preview/BUILD.gn
+++ b/chrome/test/data/webui/print_preview/BUILD.gn
@@ -15,7 +15,7 @@
   "destination_settings_test.ts",
   "destination_store_test.ts",
   "duplex_settings_test.ts",
-  "invalid_settings_browsertest.js",
+  "invalid_settings_browsertest.ts",
   "key_event_test.js",
   "native_layer_stub.ts",
   "policy_test.js",
@@ -40,7 +40,7 @@
   "destination_item_test.ts",
   "destination_list_test.ts",
   "dpi_settings_test.ts",
-  "header_test.js",
+  "header_test.ts",
   "layout_settings_test.js",
   "link_container_test.js",
   "margins_settings_test.js",
diff --git a/chrome/test/data/webui/print_preview/header_test.js b/chrome/test/data/webui/print_preview/header_test.ts
similarity index 73%
rename from chrome/test/data/webui/print_preview/header_test.js
rename to chrome/test/data/webui/print_preview/header_test.ts
index 078739b..da52d4d 100644
--- a/chrome/test/data/webui/print_preview/header_test.js
+++ b/chrome/test/data/webui/print_preview/header_test.ts
@@ -2,31 +2,29 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationType, Error, GooglePromotedDestinationId, PrintPreviewHeaderElement, PrintPreviewModelElement, PrintPreviewPluralStringProxyImpl, State} from 'chrome://print/print_preview.js';
+import {Destination, DestinationConnectionStatus, DestinationOrigin, DestinationType, Error, GooglePromotedDestinationId, PrintPreviewHeaderElement, PrintPreviewPluralStringProxyImpl, State} from 'chrome://print/print_preview.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {TestPluralStringProxy} from 'chrome://webui-test/test_plural_string_proxy.js';
 import {fakeDataBind} from 'chrome://webui-test/test_util.js';
 
-window.header_test = {};
-const header_test = window.header_test;
-header_test.suiteName = 'HeaderTest';
-/** @enum {string} */
-header_test.TestNames = {
-  HeaderPrinterTypes: 'header printer types',
-  HeaderChangesForState: 'header changes for state',
-  EnterprisePolicy: 'enterprise policy',
+const header_test = {
+  suiteName: 'HeaderTest',
+  TestNames: {
+    HeaderPrinterTypes: 'header printer types',
+    HeaderChangesForState: 'header changes for state',
+    EnterprisePolicy: 'enterprise policy',
+  },
 };
 
+Object.assign(window, {header_test: header_test});
+
 suite(header_test.suiteName, function() {
-  /** @type {!PrintPreviewHeaderElement} */
-  let header;
+  let header: PrintPreviewHeaderElement;
 
-  /** @type {TestPluralStringProxy} */
-  let pluralString = null;
+  let pluralString: TestPluralStringProxy;
 
-  /** @override */
   setup(function() {
     document.body.innerHTML = '';
 
@@ -34,12 +32,10 @@
     PrintPreviewPluralStringProxyImpl.setInstance(pluralString);
     pluralString.text = '1 sheet of paper';
 
-    const model = /** @type {!PrintPreviewModelElement} */ (
-        document.createElement('print-preview-model'));
+    const model = document.createElement('print-preview-model');
     document.body.appendChild(model);
 
-    header = /** @type {!PrintPreviewHeaderElement} */ (
-        document.createElement('print-preview-header'));
+    header = document.createElement('print-preview-header');
     header.settings = model.settings;
     model.set('settings.duplex.available', true);
     model.set('settings.duplex.value', false);
@@ -66,11 +62,11 @@
   // Tests that the 4 different messages (non-virtual printer singular and
   // plural, virtual printer singular and plural) all show up as expected.
   test(assert(header_test.TestNames.HeaderPrinterTypes), async function() {
-    const summary = header.shadowRoot.querySelector('.summary');
+    const summary = header.shadowRoot!.querySelector('.summary')!;
     {
       const {messageName, itemCount} =
           await pluralString.whenCalled('getPluralString');
-      assertEquals('1 sheet of paper', summary.textContent.trim());
+      assertEquals('1 sheet of paper', summary.textContent!.trim());
       assertEquals('printPreviewSheetSummaryLabel', messageName);
       assertEquals(1, itemCount);
     }
@@ -107,33 +103,33 @@
   // Tests that the correct message is shown for non-READY states, and that
   // the print button is disabled appropriately.
   test(assert(header_test.TestNames.HeaderChangesForState), async function() {
-    const summary = header.shadowRoot.querySelector('.summary');
+    const summary = header.shadowRoot!.querySelector('.summary')!;
     await pluralString.whenCalled('getPluralString');
-    assertEquals('1 sheet of paper', summary.textContent.trim());
+    assertEquals('1 sheet of paper', summary.textContent!.trim());
 
     header.state = State.NOT_READY;
-    assertEquals('', summary.textContent.trim());
+    assertEquals('', summary.textContent!.trim());
 
     header.state = State.PRINTING;
     assertEquals(
-        loadTimeData.getString('printing'), summary.textContent.trim());
+        loadTimeData.getString('printing'), summary.textContent!.trim());
     setPdfDestination();
-    assertEquals(loadTimeData.getString('saving'), summary.textContent.trim());
+    assertEquals(loadTimeData.getString('saving'), summary.textContent!.trim());
 
     header.state = State.ERROR;
-    assertEquals('', summary.textContent.trim());
+    assertEquals('', summary.textContent!.trim());
 
     const testError = 'Error printing to cloud print';
     header.cloudPrintErrorMessage = testError;
     header.error = Error.CLOUD_PRINT_ERROR;
     header.state = State.FATAL_ERROR;
-    assertEquals(testError, summary.textContent.trim());
+    assertEquals(testError, summary.textContent!.trim());
   });
 
   // Tests that enterprise badge shows up if any setting is managed.
   test(assert(header_test.TestNames.EnterprisePolicy), function() {
-    assertTrue(header.shadowRoot.querySelector('iron-icon').hidden);
+    assertTrue(header.shadowRoot!.querySelector('iron-icon')!.hidden);
     header.managed = true;
-    assertFalse(header.shadowRoot.querySelector('iron-icon').hidden);
+    assertFalse(header.shadowRoot!.querySelector('iron-icon')!.hidden);
   });
 });
diff --git a/chrome/test/data/webui/print_preview/invalid_settings_browsertest.js b/chrome/test/data/webui/print_preview/invalid_settings_browsertest.ts
similarity index 67%
rename from chrome/test/data/webui/print_preview/invalid_settings_browsertest.js
rename to chrome/test/data/webui/print_preview/invalid_settings_browsertest.ts
index 0ee13bf4..2bf15eb5 100644
--- a/chrome/test/data/webui/print_preview/invalid_settings_browsertest.js
+++ b/chrome/test/data/webui/print_preview/invalid_settings_browsertest.ts
@@ -2,11 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {CloudPrintInterfaceEventType, CloudPrintInterfaceImpl, Destination, DestinationConnectionStatus, DestinationOrigin, DestinationStore, DestinationStoreEventType, DestinationType, makeRecentDestination, MeasurementSystemUnitType, NativeLayerImpl, PluginProxyImpl, PrintPreviewAppElement, PrintPreviewDestinationSettingsElement, PrintPreviewLayoutSettingsElement, PrintPreviewNumberSettingsSectionElement, PrintPreviewPreviewAreaElement, PrintPreviewSidebarElement, ScalingType, State, whenReady} from 'chrome://print/print_preview.js';
+import {CloudPrintInterfaceEventType, CloudPrintInterfaceImpl, CrButtonElement, Destination, DestinationStoreEventType, LocalDestinationInfo, makeRecentDestination, MeasurementSystemUnitType, NativeInitialSettings, NativeLayerImpl, PluginProxyImpl, PrintPreviewAppElement, ScalingType, State, whenReady} from 'chrome://print/print_preview.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {isWindows} from 'chrome://resources/js/cr.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {eventToPromise, waitBeforeNextRender} from 'chrome://webui-test/test_util.js';
 
@@ -18,38 +16,34 @@
 import {createDestinationWithCertificateStatus, getCddTemplate, getDefaultMediaSize, getDefaultOrientation} from './print_preview_test_utils.js';
 import {TestPluginProxy} from './test_plugin_proxy.js';
 
-window.invalid_settings_browsertest = {};
-const invalid_settings_browsertest = window.invalid_settings_browsertest;
-invalid_settings_browsertest.suiteName = 'InvalidSettingsBrowserTest';
-/** @enum {string} */
-invalid_settings_browsertest.TestNames = {
-  InvalidSettingsError: 'invalid settings error',
-  InvalidCertificateError: 'invalid certificate error',
-  InvalidCertificateErrorReselectDestination: 'invalid certificate reselect',
+const invalid_settings_browsertest = {
+  suiteName: 'InvalidSettingsBrowserTest',
+  TestNames: {
+    InvalidSettingsError: 'invalid settings error',
+    InvalidCertificateError: 'invalid certificate error',
+    InvalidCertificateErrorReselectDestination: 'invalid certificate reselect',
+  },
 };
 
+Object.assign(
+    window, {invalid_settings_browsertest: invalid_settings_browsertest});
+
 suite(invalid_settings_browsertest.suiteName, function() {
-  /** @type {!PrintPreviewAppElement} */
-  let page;
+  let page: PrintPreviewAppElement;
 
-  /** @type {!NativeLayerStub} */
-  let nativeLayer;
+  let nativeLayer: NativeLayerStub;
 
-  /** @type {!CloudPrintInterfaceStub} */
-  let cloudPrintInterface;
+  let cloudPrintInterface: CloudPrintInterfaceStub;
 
-  /** @type {!NativeInitialSettings} */
-  const initialSettings = {
+  const initialSettings: NativeInitialSettings = {
     isInKioskAutoPrintMode: false,
     isInAppKioskMode: false,
     thousandsDelimiter: ',',
     decimalDelimiter: '.',
     unitType: MeasurementSystemUnitType.IMPERIAL,
-    previewIsPdf: false,
     previewModifiable: true,
     destinationsManaged: false,
     previewIsFromArc: false,
-    syncAvailable: true,
     documentTitle: 'title',
     documentHasSelection: true,
     shouldPrintSelectionOnly: false,
@@ -60,13 +54,11 @@
     serializedDefaultDestinationSelectionRulesStr: null
   };
 
-  /** @type {!Array<!LocalDestinationInfo>} */
-  let localDestinationInfos = [
+  let localDestinationInfos: LocalDestinationInfo[] = [
     {printerName: 'FooName', deviceName: 'FooDevice'},
     {printerName: 'BarName', deviceName: 'BarDevice'},
   ];
 
-  /** @override */
   setup(function() {
     nativeLayer = new NativeLayerStub();
     NativeLayerImpl.setInstance(nativeLayer);
@@ -89,12 +81,9 @@
     nativeLayer.setLocalDestinations(localDestinationInfos);
     PluginProxyImpl.setInstance(new TestPluginProxy());
 
-    page = /** @type {!PrintPreviewAppElement} */ (
-        document.createElement('print-preview-app'));
+    page = document.createElement('print-preview-app');
     document.body.appendChild(page);
-    page.shadowRoot.querySelector('#documentInfo')
-        .init(true, false, false, 'title', false);
-    const previewArea = page.shadowRoot.querySelector('#previewArea');
+    page.$.documentInfo.init(true, false, 'title', false);
   }
 
   /**
@@ -102,19 +91,17 @@
    * in |printers|. printers[0] will be set as the most recent destination,
    * and printers[1] will be the second most recent destination. Sets up
    * cloud print interface, user info, and runs createPage().
-   * @param {!Array<!Destination>} printers
    */
-  function setupInvalidCertificateTest(printers) {
+  function setupInvalidCertificateTest(printers: Destination[]) {
     initialSettings.printerName = '';
     initialSettings.serializedAppStateStr = JSON.stringify({
       version: 2,
       recentDestinations: [
-        makeRecentDestination(printers[0]),
-        makeRecentDestination(printers[1]),
+        makeRecentDestination(printers[0]!),
+        makeRecentDestination(printers[1]!),
       ],
     });
     initialSettings.cloudPrintURL = 'cloudprint URL';
-    initialSettings.userAccounts = [printers[0].account];
     localDestinationInfos = [];
 
     loadTimeData.overrideValues({isEnterpriseManaged: false});
@@ -145,26 +132,24 @@
             'printer.';
 
         // Get references to relevant elements.
-        const previewAreaEl = /** @type {!PrintPreviewPreviewAreaElement} */ (
-            page.shadowRoot.querySelector('#previewArea'));
-        const overlay = previewAreaEl.shadowRoot.querySelector(
-            '.preview-area-overlay-layer');
+        const previewAreaEl = page.$.previewArea;
+        const overlay = previewAreaEl.shadowRoot!.querySelector(
+            '.preview-area-overlay-layer')!;
         const messageEl =
-            previewAreaEl.shadowRoot.querySelector('.preview-area-message');
-        const sidebar = /** @type {!PrintPreviewSidebarElement} */ (
-            page.shadowRoot.querySelector('print-preview-sidebar'));
-        let printButton = null;
-        const destinationSettings =
-            /** @type {!PrintPreviewDestinationSettingsElement} */ (
-                sidebar.shadowRoot.querySelector(
-                    'print-preview-destination-settings'));
+            previewAreaEl.shadowRoot!.querySelector('.preview-area-message')!;
+        const sidebar =
+            page.shadowRoot!.querySelector('print-preview-sidebar')!;
+        let printButton: CrButtonElement;
+        const destinationSettings = sidebar.shadowRoot!.querySelector(
+            'print-preview-destination-settings')!;
 
         return waitBeforeNextRender(page)
             .then(() => {
-              const parentElement = sidebar.shadowRoot.querySelector(
-                  'print-preview-button-strip');
+              const parentElement = sidebar.shadowRoot!.querySelector(
+                  'print-preview-button-strip')!;
               printButton =
-                  parentElement.shadowRoot.querySelector('.action-button');
+                  parentElement.shadowRoot!.querySelector<CrButtonElement>(
+                      '.action-button')!;
 
               return Promise.all([
                 whenReady(),
@@ -184,7 +169,7 @@
               // Print preview should have failed with invalid settings, since
               // FooDevice was set as an invalid printer.
               assertFalse(overlay.classList.contains('invisible'));
-              assertTrue(messageEl.textContent.includes(expectedMessage));
+              assertTrue(messageEl.textContent!.includes(expectedMessage));
               assertEquals(State.ERROR, page.state);
 
               // Verify that the print button is disabled
@@ -192,9 +177,7 @@
 
               // Select should still be enabled so that the user can select a
               // new printer.
-              assertFalse(destinationSettings.shadowRoot
-                              .querySelector('#destinationSelect')
-                              .disabled);
+              assertFalse(destinationSettings.$.destinationSelect.disabled);
 
               // Reset
               nativeLayer.reset();
@@ -203,9 +186,9 @@
               const barDestination =
                   destinationSettings.getDestinationStoreForTest()
                       .destinations()
-                      .find(d => d.id === 'BarDevice');
+                      .find((d: Destination) => d.id === 'BarDevice');
               destinationSettings.getDestinationStoreForTest()
-                  .selectDestination(assert(barDestination));
+                  .selectDestination(assert(barDestination!));
 
               // Wait for the preview to be updated.
               return nativeLayer.whenCalled('getPreview');
@@ -213,7 +196,7 @@
             .then(function() {
               // Message should be gone.
               assertTrue(overlay.classList.contains('invisible'));
-              assertFalse(messageEl.textContent.includes(expectedMessage));
+              assertFalse(messageEl.textContent!.includes(expectedMessage));
 
               // Has active print button and successfully 'prints', indicating
               assertFalse(printButton.disabled);
@@ -230,7 +213,8 @@
                 function(printTicket) {
                   // Sanity check some printing argument values.
                   const ticket = JSON.parse(printTicket);
-                  assertEquals(barDevice.printer.deviceName, ticket.deviceName);
+                  assertEquals(
+                      barDevice.printer!.deviceName, ticket.deviceName);
                   assertEquals(
                       getDefaultOrientation(barDevice) === 'LANDSCAPE',
                       ticket.landscape);
@@ -267,36 +251,30 @@
             'computer\'s system settings.';
 
         // Get references to relevant elements.
-        const previewAreaEl = /** @type {!PrintPreviewPreviewAreaElement} */ (
-            page.shadowRoot.querySelector('#previewArea'));
-        const overlayEl = previewAreaEl.shadowRoot.querySelector(
-            '.preview-area-overlay-layer');
+        const previewAreaEl = page.$.previewArea;
+        const overlayEl = previewAreaEl.shadowRoot!.querySelector(
+            '.preview-area-overlay-layer')!;
         const messageEl =
-            previewAreaEl.shadowRoot.querySelector('.preview-area-message');
-        const sidebar = /** @type {!PrintPreviewSidebarElement} */ (
-            page.shadowRoot.querySelector('print-preview-sidebar'));
-        let printButton = null;
-        const destinationSettings =
-            /** @type {!PrintPreviewDestinationSettingsElement} */ (
-                sidebar.shadowRoot.querySelector(
-                    'print-preview-destination-settings'));
+            previewAreaEl.shadowRoot!.querySelector('.preview-area-message')!;
+        const sidebar =
+            page.shadowRoot!.querySelector('print-preview-sidebar')!;
+        let printButton: CrButtonElement;
+        const destinationSettings = sidebar.shadowRoot!.querySelector(
+            'print-preview-destination-settings')!;
         const scalingSettings =
-            /** @type {!PrintPreviewNumberSettingsSectionElement} */ (
-                sidebar.shadowRoot
-                    .querySelector('print-preview-scaling-settings')
-                    .shadowRoot.querySelector(
-                        'print-preview-number-settings-section'));
+            sidebar.shadowRoot!.querySelector('print-preview-scaling-settings')!
+                .shadowRoot!.querySelector(
+                    'print-preview-number-settings-section')!;
         const layoutSettings =
-            /** @type {!PrintPreviewLayoutSettingsElement} */ (
-                sidebar.shadowRoot.querySelector(
-                    'print-preview-layout-settings'));
+            sidebar.shadowRoot!.querySelector('print-preview-layout-settings')!;
 
         return waitBeforeNextRender(page)
             .then(() => {
-              const parentElement = sidebar.shadowRoot.querySelector(
-                  'print-preview-button-strip');
+              const parentElement = sidebar.shadowRoot!.querySelector(
+                  'print-preview-button-strip')!;
               printButton =
-                  parentElement.shadowRoot.querySelector('.action-button');
+                  parentElement.shadowRoot!.querySelector<CrButtonElement>(
+                      '.action-button')!;
               return Promise.all([
                 whenReady(),
                 nativeLayer.whenCalled('getInitialSettings'),
@@ -320,8 +298,8 @@
               assertFalse(overlayEl.classList.contains('invisible'));
 
               // Verify that the correct message is shown.
-              assertTrue(messageEl.textContent.includes(expectedMessageStart));
-              assertTrue(messageEl.textContent.includes(expectedMessageEnd));
+              assertTrue(messageEl.textContent!.includes(expectedMessageStart));
+              assertTrue(messageEl.textContent!.includes(expectedMessageEnd));
 
               // Verify that the print button is disabled
               assertTrue(printButton.disabled);
@@ -330,15 +308,13 @@
               // also disabled, so there is no way to regenerate the preview.
               assertEquals(State.ERROR, page.state);
               assertTrue(
-                  layoutSettings.shadowRoot.querySelector('select').disabled);
-              assertTrue(scalingSettings.shadowRoot.querySelector('cr-input')
-                             .disabled);
+                  layoutSettings.shadowRoot!.querySelector('select')!.disabled);
+              assertTrue(scalingSettings.shadowRoot!.querySelector(
+                                                        'cr-input')!.disabled);
 
               // The destination select dropdown should be enabled, so that the
               // user can select a new printer.
-              assertFalse(destinationSettings.shadowRoot
-                              .querySelector('#destinationSelect')
-                              .disabled);
+              assertFalse(destinationSettings.$.destinationSelect.disabled);
 
               // Reset
               nativeLayer.reset();
@@ -356,18 +332,17 @@
 
               // Settings sections are now active.
               assertFalse(
-                  layoutSettings.shadowRoot.querySelector('select').disabled);
-              assertFalse(scalingSettings.shadowRoot.querySelector('cr-input')
-                              .disabled);
+                  layoutSettings.shadowRoot!.querySelector('select')!.disabled);
+              assertFalse(scalingSettings.shadowRoot!.querySelector(
+                                                         'cr-input')!.disabled);
 
               // The destination select dropdown should still be enabled.
-              assertFalse(destinationSettings.shadowRoot
-                              .querySelector('#destinationSelect')
-                              .disabled);
+              assertFalse(destinationSettings.$.destinationSelect.disabled);
 
               // Message text should have changed and overlay should be
               // invisible.
-              assertFalse(messageEl.textContent.includes(expectedMessageStart));
+              assertFalse(
+                  messageEl.textContent!.includes(expectedMessageStart));
               assertTrue(overlayEl.classList.contains('invisible'));
             });
       });
@@ -387,26 +362,22 @@
         setupInvalidCertificateTest([validPrinter, invalidPrinter]);
 
         // Get references to relevant elements.
-        const previewAreaEl = /** @type {!PrintPreviewPreviewAreaElement} */ (
-            page.shadowRoot.querySelector('#previewArea'));
-        const overlayEl = previewAreaEl.shadowRoot.querySelector(
-            '.preview-area-overlay-layer');
-        const messageEl =
-            previewAreaEl.shadowRoot.querySelector('.preview-area-message');
-        const sidebar = /** @type {!PrintPreviewSidebarElement} */ (
-            page.shadowRoot.querySelector('print-preview-sidebar'));
-        let printButton = null;
-        const destinationSettings =
-            /** @type {!PrintPreviewDestinationSettingsElement} */ (
-                sidebar.shadowRoot.querySelector(
-                    'print-preview-destination-settings'));
+        const previewAreaEl = page.$.previewArea;
+        const overlayEl = previewAreaEl.shadowRoot!.querySelector(
+            '.preview-area-overlay-layer')!;
+        const sidebar =
+            page.shadowRoot!.querySelector('print-preview-sidebar')!;
+        let printButton: CrButtonElement;
+        const destinationSettings = sidebar.shadowRoot!.querySelector(
+            'print-preview-destination-settings')!;
 
         return waitBeforeNextRender(page)
             .then(() => {
-              const parentElement = sidebar.shadowRoot.querySelector(
-                  'print-preview-button-strip');
+              const parentElement = sidebar.shadowRoot!.querySelector(
+                  'print-preview-button-strip')!;
               printButton =
-                  parentElement.shadowRoot.querySelector('.action-button');
+                  parentElement.shadowRoot!.querySelector<CrButtonElement>(
+                      '.action-button')!;
               return Promise.all([
                 whenReady(),
                 nativeLayer.whenCalled('getInitialSettings'),
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index 5049e6ec..de13926 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -78,7 +78,7 @@
   "prefs_test_cases.ts",
   "prefs_tests.js",
   "pref_util_tests.js",
-  "privacy_review_page_test.js",
+  "privacy_review_page_test.ts",
   "privacy_sandbox_test.ts",
   "protocol_handlers_tests.ts",
   "recent_site_permissions_test.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index dd2c0e8..26cb9ea 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -176,6 +176,7 @@
     "test_os_lifetime_browser_proxy.js",
     "test_os_reset_browser_proxy.js",
     "test_os_sync_browser_proxy.js",
+    "test_personalization_hub_browser_proxy.js",
     "test_wallpaper_browser_proxy.js",
     "tether_connection_dialog_test.js",
     "text_to_speech_subpage_tests.js",
diff --git a/chrome/test/data/webui/settings/chromeos/os_namespace_rewrites.gni b/chrome/test/data/webui/settings/chromeos/os_namespace_rewrites.gni
index f30c801..326ceb10 100644
--- a/chrome/test/data/webui/settings/chromeos/os_namespace_rewrites.gni
+++ b/chrome/test/data/webui/settings/chromeos/os_namespace_rewrites.gni
@@ -22,6 +22,7 @@
                                "settings.TestLanguagesBrowserProxy|TestLanguagesBrowserProxy",
                                "settings.TestLanguagesMetricsProxy|TestLanguagesMetricsProxy",
                                "settings.TestLifetimeBrowserProxy|TestLifetimeBrowserProxy",
+                               "settings.TestPersonalizationHubBrowserProxy|TestPersonalizationHubBrowserProxy",
                                "settings.TestWallpaperBrowserProxy|TestWallpaperBrowserProxy",
                                "printerBrowserProxy.TestCupsPrintersBrowserProxy|TestCupsPrintersBrowserProxy",
                                "test_util.eventToPromise|eventToPromise",
diff --git a/chrome/test/data/webui/settings/chromeos/personalization_page_test.js b/chrome/test/data/webui/settings/chromeos/personalization_page_test.js
index 0b9fb6f6..374c6858 100644
--- a/chrome/test/data/webui/settings/chromeos/personalization_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/personalization_page_test.js
@@ -5,9 +5,10 @@
 // clang-format off
 // #import 'chrome://os-settings/chromeos/os_settings.js';
 
-// #import {WallpaperBrowserProxyImpl, routes, Router} from 'chrome://os-settings/chromeos/os_settings.js';
+// #import {PersonalizationHubBrowserProxyImpl, WallpaperBrowserProxyImpl, routes, Router} from 'chrome://os-settings/chromeos/os_settings.js';
 // #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js';
 // #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+// #import {TestPersonalizationHubBrowserProxy} from './test_personalization_hub_browser_proxy.m.js';
 // #import {TestWallpaperBrowserProxy} from './test_wallpaper_browser_proxy.m.js';
 // #import {getDeepActiveElement} from 'chrome://resources/js/util.m.js';
 // #import {flushTasks, waitAfterNextRender} from 'chrome://test/test_util.js';
@@ -15,10 +16,14 @@
 
 let personalizationPage = null;
 
+/** @type {?settings.TestPersonalizationHubBrowserProxy} */
+let PersonalizationHubBrowserProxy = null;
+
 /** @type {?settings.TestWallpaperBrowserProxy} */
 let WallpaperBrowserProxy = null;
 
 function createPersonalizationPage() {
+  PersonalizationHubBrowserProxy.reset();
   WallpaperBrowserProxy.reset();
   PolymerTest.clearBody();
 
@@ -59,6 +64,10 @@
   setup(function() {
     WallpaperBrowserProxy = new settings.TestWallpaperBrowserProxy();
     settings.WallpaperBrowserProxyImpl.instance_ = WallpaperBrowserProxy;
+    PersonalizationHubBrowserProxy =
+        new settings.TestPersonalizationHubBrowserProxy();
+    settings.PersonalizationHubBrowserProxyImpl.instance_ =
+        PersonalizationHubBrowserProxy;
     createPersonalizationPage();
   });
 
@@ -74,7 +83,8 @@
     // the page to be recreated.
     createPersonalizationPage();
     await WallpaperBrowserProxy.whenCalled('isWallpaperPolicyControlled');
-    const button = personalizationPage.$.wallpaperButton;
+    const button =
+        personalizationPage.shadowRoot.getElementById('wallpaperButton');
     assertTrue(!!button);
     assertFalse(button.disabled);
     button.click();
@@ -105,7 +115,8 @@
         settings.routes.PERSONALIZATION, params);
 
     const deepLinkElement =
-        personalizationPage.$.wallpaperButton.shadowRoot.querySelector('#icon');
+        personalizationPage.shadowRoot.getElementById('wallpaperButton')
+            .shadowRoot.querySelector('#icon');
     await test_util.waitAfterNextRender(deepLinkElement);
     assertEquals(
         deepLinkElement, getDeepActiveElement(),
@@ -113,7 +124,8 @@
   });
 
   test('changePicture', function() {
-    const row = personalizationPage.$.changePictureRow;
+    const row =
+        personalizationPage.shadowRoot.getElementById('changePictureRow');
     assertTrue(!!row);
     row.click();
     assertEquals(
@@ -187,4 +199,32 @@
         deepLinkElement, getDeepActiveElement(),
         'Account picture elem should be focused for settingId=503.');
   });
+
+  test('Personalization hub feature shows only link to hub', async () => {
+    loadTimeData.overrideValues({isPersonalizationHubEnabled: true});
+    assertTrue(loadTimeData.getBoolean('isPersonalizationHubEnabled'));
+    createPersonalizationPage();
+    Polymer.dom.flush();
+    await test_util.waitAfterNextRender(personalizationPage);
+
+    const crLinks =
+        personalizationPage.shadowRoot.querySelectorAll('cr-link-row');
+
+    assertEquals(1, crLinks.length);
+    assertEquals('personalizationHubButton', crLinks[0].id);
+  });
+
+  test('Opens personalization hub when clicked', async () => {
+    loadTimeData.overrideValues({isPersonalizationHubEnabled: true});
+    assertTrue(loadTimeData.getBoolean('isPersonalizationHubEnabled'));
+    createPersonalizationPage();
+    Polymer.dom.flush();
+    await test_util.waitAfterNextRender(personalizationPage);
+
+    const hubLink = personalizationPage.shadowRoot.getElementById(
+        'personalizationHubButton');
+    hubLink.click();
+
+    await PersonalizationHubBrowserProxy.whenCalled('openPersonalizationHub');
+  });
 });
diff --git a/chrome/test/data/webui/settings/chromeos/test_personalization_hub_browser_proxy.js b/chrome/test/data/webui/settings/chromeos/test_personalization_hub_browser_proxy.js
new file mode 100644
index 0000000..1241c10
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/test_personalization_hub_browser_proxy.js
@@ -0,0 +1,23 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// #import {TestBrowserProxy} from '../../test_browser_proxy.js';
+
+cr.define('settings', function() {
+  /** @implements {settings.PersonalizationHubBrowserProxy} */
+  /* #export */ class TestPersonalizationHubBrowserProxy extends
+      TestBrowserProxy {
+    constructor() {
+      super(['openPersonalizationHub']);
+    }
+
+    /** @override */
+    openPersonalizationHub() {
+      this.methodCalled('openPersonalizationHub');
+    }
+  }
+
+  // #cr_define_end
+  return {TestPersonalizationHubBrowserProxy};
+});
diff --git a/chrome/test/data/webui/settings/privacy_review_page_test.js b/chrome/test/data/webui/settings/privacy_review_page_test.ts
similarity index 77%
rename from chrome/test/data/webui/settings/privacy_review_page_test.js
rename to chrome/test/data/webui/settings/privacy_review_page_test.ts
index 87590d0..99455ca 100644
--- a/chrome/test/data/webui/settings/privacy_review_page_test.js
+++ b/chrome/test/data/webui/settings/privacy_review_page_test.ts
@@ -5,11 +5,10 @@
 // clang-format off
 import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {CookiePrimarySetting, PrivacyReviewHistorySyncFragmentElement, PrivacyReviewStep, SafeBrowsingSetting, SettingsPrivacyReviewPageElement} from 'chrome://settings/lazy_load.js';
-import {Route, Router, routes, SyncBrowserProxyImpl, syncPrefsIndividualDataTypes} from 'chrome://settings/settings.js';
-
+import {CookiePrimarySetting, PrivacyReviewHistorySyncFragmentElement, PrivacyReviewStep, PrivacyReviewWelcomeFragmentElement, SafeBrowsingSetting, SettingsCheckboxElement, SettingsPrivacyReviewPageElement, SettingsRadioGroupElement} from 'chrome://settings/lazy_load.js';
+import {Router, routes, SyncBrowserProxyImpl, SyncPrefs, syncPrefsIndividualDataTypes} from 'chrome://settings/settings.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
-import {flushTasks, isChildVisible} from 'chrome://webui-test/test_util.js';
+import {eventToPromise, flushTasks, isChildVisible} from 'chrome://webui-test/test_util.js';
 
 import {TestSyncBrowserProxy} from './test_sync_browser_proxy.js';
 
@@ -21,16 +20,14 @@
 const PRIVACY_REVIEW_STEPS = 4;
 
 suite('PrivacyReviewPage', function() {
-  /** @type {!SettingsPrivacyReviewPageElement} */
-  let page;
-  let isSyncOn;
-  let shouldShowCookiesCard;
-  let shouldShowSafeBrowsingCard;
+  let page: SettingsPrivacyReviewPageElement;
+  let isSyncOn: boolean;
+  let shouldShowCookiesCard: boolean;
+  let shouldShowSafeBrowsingCard: boolean;
 
   setup(function() {
     document.body.innerHTML = '';
-    page = /** @type {!SettingsPrivacyReviewPageElement} */
-        (document.createElement('settings-privacy-review-page'));
+    page = document.createElement('settings-privacy-review-page');
     page.prefs = {
       privacy_review: {
         show_welcome_card: {
@@ -71,16 +68,9 @@
 
   /**
    * Returns a new promise that resolves after a window 'popstate' event.
-   * @return {!Promise}
    */
-  function whenPopState(causeEvent) {
-    const promise = new Promise(function(resolve) {
-      window.addEventListener('popstate', function callback() {
-        window.removeEventListener('popstate', callback);
-        resolve();
-      });
-    });
-
+  function whenPopState(causeEvent: () => void): Promise<void> {
+    const promise = eventToPromise('popstate', window);
     causeEvent();
     return promise;
   }
@@ -88,29 +78,23 @@
   /**
    * Equivalent of the user manually navigating to the corresponding step via
    * typing the URL and step parameter in the Omnibox.
-   * @private
-   * @param {string} step
    */
-  function navigateToStep(step) {
+  function navigateToStep(step: PrivacyReviewStep) {
     Router.getInstance().navigateTo(
         routes.PRIVACY_REVIEW,
         /* opt_dynamicParameters */ new URLSearchParams('step=' + step));
     flush();
   }
 
-  /**
-   * @param {string} step
-   */
-  function assertQueryParameter(step) {
+  function assertQueryParameter(step: PrivacyReviewStep) {
     assertEquals(step, Router.getInstance().getQueryParameters().get('step'));
   }
 
 
   /**
    * Fire a sync status changed event and flush the UI.
-   * @param {boolean} syncOn
    */
-  function setSyncEnabled(syncOn) {
+  function setSyncEnabled(syncOn: boolean) {
     const event = {
       signedIn: syncOn,
       hasError: false,
@@ -122,9 +106,8 @@
 
   /**
    * Set the cookies setting for the privacy review.
-   * @param {CookiePrimarySetting} setting
    */
-  function setCookieSetting(setting) {
+  function setCookieSetting(setting: CookiePrimarySetting) {
     page.set('prefs.generated.cookie_primary_setting', {
       type: chrome.settingsPrivate.PrefType.NUMBER,
       value: setting,
@@ -137,9 +120,8 @@
 
   /**
    * Set the safe browsing setting for the privacy review.
-   * @param {SafeBrowsingSetting} setting
    */
-  function setSafeBrowsingSetting(setting) {
+  function setSafeBrowsingSetting(setting: SafeBrowsingSetting) {
     page.set('prefs.generated.safe_browsing', {
       type: chrome.settingsPrivate.PrefType.NUMBER,
       value: setting,
@@ -151,9 +133,8 @@
 
   /**
    * Fire a sign in status change event and flush the UI.
-   * @param {boolean} signedIn
    */
-  function setSignInState(signedIn) {
+  function setSignInState(signedIn: boolean) {
     const event = {
       signedIn: signedIn,
     };
@@ -161,21 +142,20 @@
     flush();
   }
 
-  /**
-   * @param {!{
-   *   headerTextExpected: (string|undefined),
-   *   headerImgSrcExpected: (string|undefined),
-   *   isSettingFooterVisibleExpected: (boolean|undefined),
-   *   isBackButtonVisibleExpected: (boolean|undefined),
-   *   isWelcomeFragmentVisibleExpected: (boolean|undefined),
-   *   isCompletionFragmentVisibleExpected: (boolean|undefined),
-   *   isMsbbFragmentVisibleExpected: (boolean|undefined),
-   *   isClearOnExitFragmentVisibleExpected: (boolean|undefined),
-   *   isHistorySyncFragmentVisibleExpected: (boolean|undefined),
-   *   isSafeBrowsingFragmentVisibleExpected: (boolean|undefined),
-   *   isCookiesFragmentVisibleExpected: (boolean|undefined),
-   * }} destructured1
-   */
+  type AssertCardComponentsVisibleParams = {
+    headerTextExpected?: string,
+    headerImgSrcExpected?: string,
+    isSettingFooterVisibleExpected?: boolean,
+    isBackButtonVisibleExpected?: boolean,
+    isWelcomeFragmentVisibleExpected?: boolean,
+    isCompletionFragmentVisibleExpected?: boolean,
+    isMsbbFragmentVisibleExpected?: boolean,
+    isClearOnExitFragmentVisibleExpected?: boolean,
+    isHistorySyncFragmentVisibleExpected?: boolean,
+    isSafeBrowsingFragmentVisibleExpected?: boolean,
+    isCookiesFragmentVisibleExpected?: boolean,
+  };
+
   function assertCardComponentsVisible({
     headerTextExpected,
     headerImgSrcExpected,
@@ -188,24 +168,27 @@
     isHistorySyncFragmentVisibleExpected,
     isSafeBrowsingFragmentVisibleExpected,
     isCookiesFragmentVisibleExpected,
-  }) {
+  }: AssertCardComponentsVisibleParams) {
     assertEquals(!!headerTextExpected, isChildVisible(page, '#header'));
     if (headerTextExpected) {
       assertEquals(
           headerTextExpected,
-          page.shadowRoot.querySelector('#headerLabel').innerText);
+          page.shadowRoot!.querySelector<HTMLElement>(
+                              '#headerLabel')!.textContent);
       assertTrue(!!headerImgSrcExpected);
       assertEquals(
           'chrome://settings/privacy/images/privacy_review/' +
               headerImgSrcExpected,
-          page.shadowRoot.querySelector('#headerImage').src);
+          page.shadowRoot!.querySelector<HTMLImageElement>(
+                              '#headerImage')!.src);
     }
     assertEquals(
         !!isSettingFooterVisibleExpected,
         isChildVisible(page, '#settingFooter'));
     if (isSettingFooterVisibleExpected) {
       const backButtonVisibility =
-          getComputedStyle(page.shadowRoot.querySelector('#backButton'))
+          getComputedStyle(
+              page.shadowRoot!.querySelector<HTMLElement>('#backButton')!)
               .visibility;
       assertEquals(
           isBackButtonVisibleExpected ? 'visible' : 'hidden',
@@ -251,11 +234,8 @@
     return numSteps;
   }
 
-  /**
-   * @param {number} activeIndex
-   */
-  function assertStepIndicatorModel(activeIndex) {
-    const model = page.computeStepIndicatorModel_();
+  function assertStepIndicatorModel(activeIndex: number) {
+    const model = page.computeStepIndicatorModel();
     assertEquals(activeIndex, model.active);
     assertEquals(getExpectedNumberOfActiveCards(), model.total);
   }
@@ -285,18 +265,6 @@
     assertStepIndicatorModel(0);
   }
 
-  function assertClearOnExitCardVisible() {
-    assertQueryParameter(PrivacyReviewStep.CLEAR_ON_EXIT);
-    assertCardComponentsVisible({
-      headerTextExpected: page.i18n('privacyReviewClearOnExitCardHeader'),
-      headerImgSrcExpected: 'clear_on_exit_graphic.svg',
-      isSettingFooterVisibleExpected: true,
-      isBackButtonVisibleExpected: true,
-      isClearOnExitFragmentVisibleExpected: true,
-    });
-    assertStepIndicatorModel(1);
-  }
-
   function assertHistorySyncCardVisible() {
     assertQueryParameter(PrivacyReviewStep.HISTORY_SYNC);
     assertCardComponentsVisible({
@@ -352,12 +320,14 @@
     assertWelcomeCardVisible();
 
     const welcomeFragment =
-        page.shadowRoot.querySelector('#' + PrivacyReviewStep.WELCOME);
+        page.shadowRoot!.querySelector<PrivacyReviewWelcomeFragmentElement>(
+            '#' + PrivacyReviewStep.WELCOME)!;
     const dontShowAgainCheckbox =
-        welcomeFragment.shadowRoot.querySelector('#dontShowAgainCheckbox');
+        welcomeFragment.shadowRoot!.querySelector<SettingsCheckboxElement>(
+            '#dontShowAgainCheckbox')!;
     assertFalse(dontShowAgainCheckbox.checked);
     dontShowAgainCheckbox.$.checkbox.click();
-    welcomeFragment.shadowRoot.querySelector('#startButton').click();
+    welcomeFragment.$.startButton.click();
     flush();
     assertMsbbCardVisible();
 
@@ -379,8 +349,9 @@
     assertWelcomeCardVisible();
 
     const welcomeFragment =
-        page.shadowRoot.querySelector('#' + PrivacyReviewStep.WELCOME);
-    welcomeFragment.shadowRoot.querySelector('#startButton').click();
+        page.shadowRoot!.querySelector<PrivacyReviewWelcomeFragmentElement>(
+            '#' + PrivacyReviewStep.WELCOME)!;
+    welcomeFragment.$.startButton.click();
     flush();
     assertMsbbCardVisible();
 
@@ -394,7 +365,7 @@
     setSyncEnabled(true);
     assertMsbbCardVisible();
 
-    page.shadowRoot.querySelector('#nextButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
     flush();
     assertHistorySyncCardVisible();
   });
@@ -404,7 +375,7 @@
     setSyncEnabled(false);
     assertMsbbCardVisible();
 
-    page.shadowRoot.querySelector('#nextButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
     flush();
     assertSafeBrowsingCardVisible();
   });
@@ -414,7 +385,7 @@
     setSyncEnabled(true);
     assertHistorySyncCardVisible();
 
-    page.shadowRoot.querySelector('#backButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#backButton')!.click();
     flush();
     assertMsbbCardVisible();
   });
@@ -443,7 +414,7 @@
         setCookieSetting(CookiePrimarySetting.BLOCK_THIRD_PARTY);
         assertHistorySyncCardVisible();
 
-        page.shadowRoot.querySelector('#nextButton').click();
+        page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
         flush();
         assertSafeBrowsingCardVisible();
       });
@@ -456,7 +427,7 @@
         setCookieSetting(CookiePrimarySetting.BLOCK_THIRD_PARTY);
         assertHistorySyncCardVisible();
 
-        page.shadowRoot.querySelector('#nextButton').click();
+        page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
         flush();
         assertCookiesCardVisible();
       });
@@ -466,7 +437,7 @@
     setSyncEnabled(true);
     assertSafeBrowsingCardVisible();
 
-    page.shadowRoot.querySelector('#backButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#backButton')!.click();
     flush();
     assertHistorySyncCardVisible();
   });
@@ -476,7 +447,7 @@
     setSyncEnabled(false);
     assertSafeBrowsingCardVisible();
 
-    page.shadowRoot.querySelector('#backButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#backButton')!.click();
     flush();
     assertMsbbCardVisible();
   });
@@ -487,8 +458,9 @@
     setCookieSetting(CookiePrimarySetting.BLOCK_THIRD_PARTY);
     assertSafeBrowsingCardVisible();
     const radioButtonGroup =
-        page.shadowRoot.querySelector('#' + PrivacyReviewStep.SAFE_BROWSING)
-            .shadowRoot.querySelector('#safeBrowsingRadioGroup');
+        page.shadowRoot!.querySelector('#' + PrivacyReviewStep.SAFE_BROWSING)!
+            .shadowRoot!.querySelector<SettingsRadioGroupElement>(
+                '#safeBrowsingRadioGroup')!;
     assertEquals(
         Number(radioButtonGroup.selected), SafeBrowsingSetting.ENHANCED);
 
@@ -509,7 +481,7 @@
     setCookieSetting(CookiePrimarySetting.BLOCK_THIRD_PARTY);
     assertSafeBrowsingCardVisible();
 
-    page.shadowRoot.querySelector('#nextButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
     flush();
     assertCookiesCardVisible();
   });
@@ -519,7 +491,7 @@
     setCookieSetting(CookiePrimarySetting.ALLOW_ALL);
     assertSafeBrowsingCardVisible();
 
-    page.shadowRoot.querySelector('#nextButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
     flush();
     assertCompletionCardVisible();
   });
@@ -530,7 +502,7 @@
     setSafeBrowsingSetting(SafeBrowsingSetting.STANDARD);
     assertCookiesCardVisible();
 
-    page.shadowRoot.querySelector('#backButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#backButton')!.click();
     flush();
     assertSafeBrowsingCardVisible();
   });
@@ -541,7 +513,7 @@
     setSafeBrowsingSetting(SafeBrowsingSetting.DISABLED);
     assertCookiesCardVisible();
 
-    page.shadowRoot.querySelector('#backButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#backButton')!.click();
     flush();
     assertHistorySyncCardVisible();
   });
@@ -550,7 +522,7 @@
     navigateToStep(PrivacyReviewStep.COOKIES);
     assertCookiesCardVisible();
 
-    page.shadowRoot.querySelector('#nextButton').click();
+    page.shadowRoot!.querySelector<HTMLElement>('#nextButton')!.click();
     flush();
     assertCompletionCardVisible();
   });
@@ -560,8 +532,9 @@
     setCookieSetting(CookiePrimarySetting.BLOCK_THIRD_PARTY);
     assertCookiesCardVisible();
     const radioButtonGroup =
-        page.shadowRoot.querySelector('#' + PrivacyReviewStep.COOKIES)
-            .shadowRoot.querySelector('#cookiesRadioGroup');
+        page.shadowRoot!.querySelector('#' + PrivacyReviewStep.COOKIES)!
+            .shadowRoot!.querySelector<SettingsRadioGroupElement>(
+                '#cookiesRadioGroup')!;
     assertEquals(
         Number(radioButtonGroup.selected),
         CookiePrimarySetting.BLOCK_THIRD_PARTY);
@@ -585,8 +558,9 @@
     assertCompletionCardVisible();
 
     const completionFragment =
-        page.shadowRoot.querySelector('#' + PrivacyReviewStep.COMPLETION);
-    completionFragment.shadowRoot.querySelector('#backButton').click();
+        page.shadowRoot!.querySelector('#' + PrivacyReviewStep.COMPLETION)!;
+    completionFragment.shadowRoot!.querySelector<HTMLElement>(
+                                      '#backButton')!.click();
     flush();
     assertCookiesCardVisible();
   });
@@ -596,10 +570,10 @@
     assertCompletionCardVisible();
 
     return whenPopState(function() {
-             const completionFragment = page.shadowRoot.querySelector(
-                 '#' + PrivacyReviewStep.COMPLETION);
-             completionFragment.shadowRoot.querySelector('#leaveButton')
-                 .click();
+             const completionFragment = page.shadowRoot!.querySelector(
+                 '#' + PrivacyReviewStep.COMPLETION)!;
+             completionFragment.shadowRoot!
+                 .querySelector<HTMLElement>('#leaveButton')!.click();
            })
         .then(function() {
           assertEquals(routes.PRIVACY, Router.getInstance().getCurrentRoute());
@@ -612,7 +586,7 @@
     assertCompletionCardVisible();
 
     const completionFragment =
-        page.shadowRoot.querySelector('#' + PrivacyReviewStep.COMPLETION);
+        page.shadowRoot!.querySelector('#' + PrivacyReviewStep.COMPLETION)!;
     assertTrue(isChildVisible(completionFragment, '#privacySandboxRow'));
     assertTrue(isChildVisible(completionFragment, '#waaRow'));
 
@@ -624,18 +598,15 @@
 });
 
 suite('HistorySyncFragment', function() {
-  /** @type {!PrivacyReviewHistorySyncFragmentElement} */
-  let page;
-  /** @type {!SyncBrowserProxy} */
-  let syncBrowserProxy;
+  let page: PrivacyReviewHistorySyncFragmentElement;
+  let syncBrowserProxy: TestSyncBrowserProxy;
 
   setup(function() {
     syncBrowserProxy = new TestSyncBrowserProxy();
     SyncBrowserProxyImpl.setInstance(syncBrowserProxy);
 
     document.body.innerHTML = '';
-    page = /** @type {!PrivacyReviewHistorySyncFragmentElement} */
-        (document.createElement('privacy-review-history-sync-fragment'));
+    page = document.createElement('privacy-review-history-sync-fragment');
     document.body.appendChild(page);
     return flushTasks();
   });
@@ -644,25 +615,22 @@
     page.remove();
   });
 
-  /**
-   * @param {!{
-   *   syncAllDataTypes: boolean,
-   *   typedUrlsSynced: boolean,
-   *   passwordsSynced: boolean,
-   * }} destructured1
-   */
   function setSyncStatus({
     syncAllDataTypes,
     typedUrlsSynced,
     passwordsSynced,
+  }: {
+    syncAllDataTypes: boolean,
+    typedUrlsSynced: boolean,
+    passwordsSynced: boolean,
   }) {
     if (syncAllDataTypes) {
       assertTrue(typedUrlsSynced);
       assertTrue(passwordsSynced);
     }
-    const event = {};
+    const event: SyncPrefs = {} as unknown as SyncPrefs;
     for (const datatype of syncPrefsIndividualDataTypes) {
-      event[datatype] = true;
+      (event as unknown as {[key: string]: boolean})[datatype] = true;
     }
     // Overwrite datatypes needed in tests.
     event.syncAllDataTypes = syncAllDataTypes;
@@ -672,15 +640,12 @@
     flush();
   }
 
-  /**
-   * @param {!{
-   *   syncAllDatatypesExpected: boolean,
-   *   typedUrlsSyncedExpected: boolean,
-   * }} destructured1
-   */
   async function assertBrowserProxyCall({
     syncAllDatatypesExpected,
     typedUrlsSyncedExpected,
+  }: {
+    syncAllDatatypesExpected: boolean,
+    typedUrlsSyncedExpected: boolean,
   }) {
     const syncPrefs = await syncBrowserProxy.whenCalled('setSyncDatatypes');
     assertEquals(syncAllDatatypesExpected, syncPrefs.syncAllDataTypes);
@@ -694,7 +659,7 @@
       typedUrlsSynced: true,
       passwordsSynced: true,
     });
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     await assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: false,
@@ -702,7 +667,7 @@
 
     // Re-enabling history sync re-enables sync all if sync all was on before
     // and if all sync datatypes are still enabled.
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     return assertBrowserProxyCall({
       syncAllDatatypesExpected: true,
       typedUrlsSyncedExpected: true,
@@ -715,7 +680,7 @@
       typedUrlsSynced: true,
       passwordsSynced: true,
     });
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     await assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: false,
@@ -730,7 +695,7 @@
 
     // Re-enabling history sync in the privacy review doesn't re-enable sync
     // all.
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     return assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: true,
@@ -743,7 +708,7 @@
       typedUrlsSynced: true,
       passwordsSynced: true,
     });
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     await assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: false,
@@ -759,7 +724,7 @@
 
     // Re-enabling history sync in the privacy review doesn't re-enable sync
     // all.
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     return assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: true,
@@ -772,7 +737,7 @@
       typedUrlsSynced: true,
       passwordsSynced: true,
     });
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     await assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: false,
@@ -780,9 +745,8 @@
 
     // Re-enabling history sync doesn't re-enable sync all if sync all wasn't on
     // originally.
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     return assertBrowserProxyCall({
-      syncAllDataTypes: false,
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: true,
     });
@@ -794,7 +758,7 @@
       typedUrlsSynced: false,
       passwordsSynced: true,
     });
-    page.shadowRoot.querySelector('#historyToggle').click();
+    page.$.historyToggle.click();
     return assertBrowserProxyCall({
       syncAllDatatypesExpected: false,
       typedUrlsSyncedExpected: true,
diff --git a/chromecast/crash/BUILD.gn b/chromecast/crash/BUILD.gn
index 5a7237d..7b8c125c 100644
--- a/chromecast/crash/BUILD.gn
+++ b/chromecast/crash/BUILD.gn
@@ -87,6 +87,7 @@
 
     deps += [
       ":build_info",
+      "//chromecast:chromecast_buildflags",
       "//chromecast/base",
       "//chromecast/base:cast_sys_info_util",
       "//chromecast/base:cast_version",
diff --git a/chromecast/crash/linux/crash_util.cc b/chromecast/crash/linux/crash_util.cc
index 8835374..e543b1a 100644
--- a/chromecast/crash/linux/crash_util.cc
+++ b/chromecast/crash/linux/crash_util.cc
@@ -15,6 +15,7 @@
 #include "chromecast/base/path_utils.h"
 #include "chromecast/base/process_utils.h"
 #include "chromecast/base/version.h"
+#include "chromecast/chromecast_buildflags.h"
 #include "chromecast/crash/app_state_tracker.h"
 #include "chromecast/crash/linux/dummy_minidump_generator.h"
 #include "chromecast/crash/linux/minidump_writer.h"
@@ -26,6 +27,11 @@
 const char kMinidumpsDir[] = "minidumps";
 const size_t kMaxFilesInMinidumpsDir = 22;  // 10 crashes
 
+#if BUILDFLAG(ENABLE_CAST_MEDIA_RUNTIME)
+// Crash product name for Core web runtime.
+constexpr const char kCoreRuntimeCrashProductName[] = "CastCoreRuntime";
+#endif  // BUILDFLAG(ENABLE_CAST_MEDIA_RUNTIME)
+
 // This can be set to a callback for testing. This allows us to inject a fake
 // dumpstate routine to avoid calling an executable during an automated test.
 // This value should not be mutated through any other function except
@@ -97,6 +103,12 @@
       AppStateTracker::GetLastLaunchedApp(), CAST_BUILD_RELEASE,
       CAST_BUILD_INCREMENTAL, "", /* reason */
       AppStateTracker::GetStadiaSessionId());
+
+// Set crash product name for Core runtime. If not set, defaults to "Eureka".
+#if BUILDFLAG(ENABLE_CAST_MEDIA_RUNTIME)
+  params.crash_product_name = kCoreRuntimeCrashProductName;
+#endif  // BUILDFLAG(ENABLE_CAST_MEDIA_RUNTIME)
+
   DummyMinidumpGenerator minidump_generator(existing_minidump_path);
 
   base::FilePath filename = base::FilePath(existing_minidump_path).BaseName();
diff --git a/chromecast/crash/linux/dump_info.cc b/chromecast/crash/linux/dump_info.cc
index c75f868..36bc28ad 100644
--- a/chromecast/crash/linux/dump_info.cc
+++ b/chromecast/crash/linux/dump_info.cc
@@ -34,6 +34,7 @@
 const char kBuildNumberKey[] = "build_number";
 const char kReasonKey[] = "reason";
 const char kStadiaSessionIdKey[] = "stadia_session_id";
+const char kCrashProductNameKey[] = "crash_product_name";
 const char kExecNameKey[] = "exec_name";
 const char kExtraInfoKey[] = "extra_info";
 
@@ -91,6 +92,7 @@
   entry->SetString(kStadiaSessionIdKey, params_.stadia_session_id);
   entry->SetString(kExecNameKey, params_.exec_name);
   entry->SetString(kExtraInfoKey, params_.extra_info);
+  entry->SetString(kCrashProductNameKey, params_.crash_product_name);
 
   return result;
 }
@@ -159,6 +161,8 @@
     ++num_params;
   if (dict->GetString(kExtraInfoKey, &params_.extra_info))
     ++num_params;
+  if (dict->GetString(kCrashProductNameKey, &params_.crash_product_name))
+    ++num_params;
 
   // Disallow extraneous params
   if (dict->DictSize() != num_params)
diff --git a/chromecast/crash/linux/minidump_params.cc b/chromecast/crash/linux/minidump_params.cc
index c76f3bd4..52a0b05 100644
--- a/chromecast/crash/linux/minidump_params.cc
+++ b/chromecast/crash/linux/minidump_params.cc
@@ -16,7 +16,8 @@
                                const std::string& p_reason,
                                const std::string& p_stadia_session_id,
                                const std::string& p_extra_info,
-                               const std::string& p_exec_name)
+                               const std::string& p_exec_name,
+                               const std::string& p_crash_product_name)
     : process_uptime(p_process_uptime),
       suffix(p_suffix),
       previous_app_name(p_previous_app_name),
@@ -27,7 +28,8 @@
       reason(p_reason),
       stadia_session_id(p_stadia_session_id),
       extra_info(p_extra_info),
-      exec_name(p_exec_name) {}
+      exec_name(p_exec_name),
+      crash_product_name(p_crash_product_name) {}
 
 MinidumpParams::MinidumpParams() : process_uptime(0) {}
 
diff --git a/chromecast/crash/linux/minidump_params.h b/chromecast/crash/linux/minidump_params.h
index 63454e6..c0bbd6e 100644
--- a/chromecast/crash/linux/minidump_params.h
+++ b/chromecast/crash/linux/minidump_params.h
@@ -23,7 +23,8 @@
                  const std::string& p_reason,
                  const std::string& p_stadia_session_id,
                  const std::string& p_extra_info = "",
-                 const std::string& p_exec_name = "");
+                 const std::string& p_exec_name = "",
+                 const std::string& p_crash_product_name = "");
   MinidumpParams(const MinidumpParams& params);
   ~MinidumpParams();
 
@@ -42,6 +43,8 @@
   std::string stadia_session_id;
   std::string extra_info;
   std::string exec_name;
+  // Crash Product name, used to identify/group crash reports in go/crash.
+  std::string crash_product_name;
 };
 
 }  // namespace chromecast
diff --git a/chromecast/external_mojo/external_service_support/tracing_client_impl.cc b/chromecast/external_mojo/external_service_support/tracing_client_impl.cc
index a6f4e5d..41dd177 100644
--- a/chromecast/external_mojo/external_service_support/tracing_client_impl.cc
+++ b/chromecast/external_mojo/external_service_support/tracing_client_impl.cc
@@ -34,7 +34,8 @@
   // TODO(cletnick): Support initializing startup tracing without
   // depending on per-process command-line arguments.
   tracing::EnableStartupTracingIfNeeded();
-  tracing::InitTracingPostThreadPoolStartAndFeatureList();
+  tracing::InitTracingPostThreadPoolStartAndFeatureList(
+      /* enable_consumer */ false);
 
   // Connect to service.
   connector_->BindInterface(TracingClient::kTracingServiceName,
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn
index f6fc390..53af5eb 100644
--- a/chromeos/BUILD.gn
+++ b/chromeos/BUILD.gn
@@ -27,10 +27,7 @@
   sources = []
 
   if (is_chromeos_ash) {
-    configs += [
-      ":chromeos_implementation",
-      "//build/config/linux/nss:system_nss_no_ssl_config",
-    ]
+    configs += [ ":chromeos_implementation" ]
     if (is_chromeos_device) {
       configs += [ "//build/config/compiler:use_orderfile_for_hugepage" ]
     }
@@ -130,10 +127,7 @@
 }
 
 test("chromeos_unittests") {
-  configs += [
-    "//build/config/linux/dbus",
-    "//build/config/linux/nss:system_nss_no_ssl_config",
-  ]
+  configs += [ "//build/config/linux/dbus" ]
 
   deps = [
     "//base/test:test_support",
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 777c280..181d494 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -2418,7 +2418,7 @@
       <message name="IDS_SHIMLESS_RMA_CONFIRM_DEVICE_INFO_SKU_WARNING" translateable="false" desc="The text warning explaining when the device's SKU should be changed.">
         The SKU should only be changed if the new component(s) are different from the ones they replaced. For example, a touchscreen replacing a non-touchscreen, or memory being upgraded from 8GB to 16GB.
       </message>
-      <!-- RO firmware reimaging page -->
+      <!-- Firmware reimaging page -->
       <message name="IDS_SHIMLESS_RMA_REIMAGING_FIRMWARE_TITLE_REIMAGE_REQUIRED" translateable="false" desc="The title for the page when reimaging is required.">
         Select an option for firmware reimaging
       </message>
@@ -2489,21 +2489,8 @@
       <message name="IDS_SHIMLESS_RMA_ONBOARDING_UPDATE_PERMISSION" translateable="false" desc="The update permission required operation name.">
         need permission to update
       </message>
-      <!-- Critical error page -->
-      <message name="IDS_SHIMLESS_RMA_CRITICAL_ERROR_TITLE" translateable="false" desc="The title for the critical error page. Critical errors cause the RMA process to attempt to exit to login or reboot the device at users discretion. It will try to cancel RMA, but if that fails the next boot may also trigger an RMA critical error.">
-        Critical Error
-      </message>
-      <message name="IDS_SHIMLESS_RMA_CRITICAL_ERROR_MESSAGE" translateable="false" desc="The message for the critical error when Shimless RMA app is launched when not in RMA. This should never happen.">
-        Repair finalization is in an unexpected state. You can exit to the login screen to investigate or backup data or reboot the device to attempt to resolve the issue. If you continue to see this message you should use the recovery shim.
-      </message>
-      <message name="IDS_SHIMLESS_RMA_CRITICAL_EXIT_TO_LOGIN_BUTTON" translateable="false" desc="Label for the button that attempts to cancel RMA and exit to the login screen.">
-        Exit to login
-      </message>
-      <message name="IDS_SHIMLESS_RMA_CRITICAL_REBOOT_BUTTON" translateable="false" desc="Label for the button that attempts to cancel RMA and reboot the device.">
-        Reboot
-      </message>
 
-      <!-- Peripheral Firmware Update -->
+      <!-- Firmware Update -->
       <message name="IDS_FIRMWARE_TITLE_TEXT" desc="The title of the Firmware update app.">
         Update peripherals
       </message>
diff --git a/chromeos/dbus/rmad/fake_rmad_client.cc b/chromeos/dbus/rmad/fake_rmad_client.cc
index 6a9e3f0b..e0d83ca3 100644
--- a/chromeos/dbus/rmad/fake_rmad_client.cc
+++ b/chromeos/dbus/rmad/fake_rmad_client.cc
@@ -96,14 +96,10 @@
 }
 
 rmad::GetStateReply CreateStateReply(rmad::RmadState::StateCase state,
-                                     rmad::RmadErrorCode error,
-                                     bool can_go_back = true,
-                                     bool can_abort = true) {
+                                     rmad::RmadErrorCode error) {
   rmad::GetStateReply reply;
   reply.set_allocated_state(CreateState(state));
   reply.set_error(error);
-  reply.set_can_go_back(can_go_back);
-  reply.set_can_abort(can_abort);
   return reply;
 }
 }  // namespace
@@ -205,7 +201,6 @@
         CreateStateReply(rmad::RmadState::kRepairComplete, rmad::RMAD_ERROR_OK),
     };
     fake->SetFakeStateReplies(fake_states);
-    fake->SetAbortable(true);
   }
 }
 
diff --git a/chromeos/memory/BUILD.gn b/chromeos/memory/BUILD.gn
index 6e26369..c1adb29 100644
--- a/chromeos/memory/BUILD.gn
+++ b/chromeos/memory/BUILD.gn
@@ -14,10 +14,7 @@
 
 component("memory") {
   defines = [ "IS_CHROMEOS_MEMORY_IMPL" ]
-  configs += [
-    ":chromeos_implementation",
-    "//build/config/linux/nss:system_nss_no_ssl_config",
-  ]
+  configs += [ ":chromeos_implementation" ]
   deps = [
     "//base",
     "//chromeos:chromeos_export",
@@ -45,7 +42,6 @@
 
 source_set("unit_tests") {
   testonly = true
-  configs += [ "//build/config/linux/nss:system_nss_no_ssl_config" ]
   deps = [
     ":memory",
     "//base/test:test_support",
diff --git a/chromeos/memory/userspace_swap/BUILD.gn b/chromeos/memory/userspace_swap/BUILD.gn
index 85b41ffa..38876fd 100644
--- a/chromeos/memory/userspace_swap/BUILD.gn
+++ b/chromeos/memory/userspace_swap/BUILD.gn
@@ -23,10 +23,7 @@
 }
 
 component("userspace_swap") {
-  configs += [
-    ":chromeos_implementation",
-    "//build/config/linux/nss:system_nss_no_ssl_config",
-  ]
+  configs += [ ":chromeos_implementation" ]
   deps = [
     ":mojom",
     "//base",
@@ -56,7 +53,6 @@
 
 source_set("unit_tests") {
   testonly = true
-  configs += [ "//build/config/linux/nss:system_nss_no_ssl_config" ]
   deps = [
     ":mojom",
     ":userspace_swap",
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc
index e0bb7be..41cba0a 100644
--- a/components/autofill/core/browser/autofill_field.cc
+++ b/components/autofill/core/browser/autofill_field.cc
@@ -28,16 +28,6 @@
       CalculateFieldSignatureByNameAndType(name, form_control_type);
 }
 
-AutofillField::AutofillField(const FormFieldData& field,
-                             const std::u16string& unique_name)
-    : FormFieldData(field),
-      unique_name_(unique_name),
-      parseable_name_(field.name),
-      parseable_label_(field.label) {
-  field_signature_ =
-      CalculateFieldSignatureByNameAndType(name, form_control_type);
-}
-
 AutofillField::~AutofillField() = default;
 
 std::unique_ptr<AutofillField> AutofillField::CreateForPasswordManagerUpload(
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h
index a9e8fa8..33ccb1ac 100644
--- a/components/autofill/core/browser/autofill_field.h
+++ b/components/autofill/core/browser/autofill_field.h
@@ -39,7 +39,6 @@
 
   AutofillField();
   explicit AutofillField(const FormFieldData& field);
-  AutofillField(const FormFieldData& field, const std::u16string& unique_name);
 
   AutofillField(const AutofillField&) = delete;
   AutofillField& operator=(const AutofillField&) = delete;
@@ -52,11 +51,6 @@
   static std::unique_ptr<AutofillField> CreateForPasswordManagerUpload(
       FieldSignature field_signature);
 
-  // Unique names are not stable across dynamic change. Use renderer IDs instead
-  // if possible.
-  // TODO(crbug/896689): Remove unique_name.
-  const std::u16string& unique_name() const { return unique_name_; }
-
   ServerFieldType heuristic_type() const { return heuristic_type_; }
   ServerFieldType server_type() const;
   bool server_type_prediction_is_override() const;
@@ -224,8 +218,6 @@
   bool IsCreditCardPrediction() const;
 
   absl::optional<FieldSignature> field_signature_;
-  // The unique name of this field, generated by Autofill.
-  std::u16string unique_name_;
 
   // The possible types of the field, as determined by the Autofill server.
   std::vector<
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index 0fad152..857fe45 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -1605,7 +1605,7 @@
   credit_card_action_ = mojom::RendererFormDataAction::kPreview;
   initial_interaction_timestamp_ = TimeTicks();
   external_delegate_->Reset();
-  filling_context_by_global_id_.clear();
+  filling_context_.clear();
 }
 
 bool BrowserAutofillManager::RefreshDataModels() {
@@ -2403,13 +2403,13 @@
 void BrowserAutofillManager::SetFillingContext(
     const FormStructure& form,
     std::unique_ptr<FillingContext> context) {
-  filling_context_by_global_id_[form.global_id()] = std::move(context);
+  filling_context_[form.global_id()] = std::move(context);
 }
 
 BrowserAutofillManager::FillingContext*
 BrowserAutofillManager::GetFillingContext(const FormStructure& form) {
-  auto it = filling_context_by_global_id_.find(form.global_id());
-  return it != filling_context_by_global_id_.end() ? it->second.get() : nullptr;
+  auto it = filling_context_.find(form.global_id());
+  return it != filling_context_.end() ? it->second.get() : nullptr;
 }
 
 bool BrowserAutofillManager::ShouldTriggerRefill(
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index 0877376..455d1f8 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -747,13 +747,9 @@
   // Delegate used in test to get notifications on certain events.
   raw_ptr<BrowserAutofillManagerTestDelegate> test_delegate_ = nullptr;
 
-  // A map of form names to FillingContext instances used to make refill
+  // A map from FormGlobalId to FillingContext instances used to make refill
   // attempts for dynamic forms.
-  // TODO(crbug/896689): Remove code duplication once experiment is finished.
-  std::map<FormGlobalId, std::unique_ptr<FillingContext>>
-      filling_context_by_global_id_;
-  std::map<std::u16string, std::unique_ptr<FillingContext>>
-      filling_context_by_unique_name_;
+  std::map<FormGlobalId, std::unique_ptr<FillingContext>> filling_context_;
 
   // Used to record metrics. This should be set at the beginning of the
   // interaction and re-used throughout the context of this manager.
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field.cc b/components/autofill/core/browser/form_parsing/credit_card_field.cc
index d14dc475..21bd0b8 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field.cc
+++ b/components/autofill/core/browser/form_parsing/credit_card_field.cc
@@ -259,9 +259,7 @@
   if (credit_card_field->cardholder_) {
     // If we got the cardholder name with a dangerous check, require at least a
     // card number and one of expiration or verification fields.
-    if (!base::FeatureList::IsEnabled(
-            features::kAutofillStrictContextualCardNameConditions) ||
-        !cardholder_name_match_has_low_confidence ||
+    if (!cardholder_name_match_has_low_confidence ||
         (!credit_card_field->numbers_.empty() &&
          (credit_card_field->verification_ ||
           credit_card_field->HasExpiration()))) {
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc b/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc
index b3ef9ae0..d32bde7 100644
--- a/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/credit_card_field_unittest.cc
@@ -514,53 +514,33 @@
 }
 
 TEST_F(CreditCardFieldTest, ParseCreditCardContextualNameNotCard) {
-  base::test::ScopedFeatureList enabled;
-  enabled.InitWithFeatures(
-      {features::kAutofillStrictContextualCardNameConditions}, {});
-
   AddTextFormFieldData("accNum", "Account ID", UNKNOWN_TYPE);
   AddTextFormFieldData("name", "Account Name", UNKNOWN_TYPE);
   AddTextFormFieldData("toAcctNum", "Move to Account ID", UNKNOWN_TYPE);
-
   ClassifyAndVerify(ParseResult::NOT_PARSED);
 }
 
 TEST_F(CreditCardFieldTest, ParseCreditCardContextualNameNotCardAcctMatch) {
-  base::test::ScopedFeatureList enabled;
-  enabled.InitWithFeatures(
-      {features::kAutofillStrictContextualCardNameConditions}, {});
-
   // TODO(crbug.com/1167977): This should be not parseable, but waiting before
   // changing kNameOnCardRe to use word boundaries.
   AddTextFormFieldData("acctNum", "Account ID", CREDIT_CARD_NUMBER);
   AddTextFormFieldData("acctName", "Account Name", CREDIT_CARD_NAME_FULL);
   AddTextFormFieldData("toAcctNum", "Move to Account ID", CREDIT_CARD_NUMBER);
-
   ClassifyAndVerify(ParseResult::PARSED);
 }
 
 TEST_F(CreditCardFieldTest, ParseCreditCardContextualNameWithExpiration) {
-  base::test::ScopedFeatureList enabled;
-  enabled.InitWithFeatures(
-      {features::kAutofillStrictContextualCardNameConditions}, {});
-
   AddTextFormFieldData("acctNum", "Account ID", CREDIT_CARD_NUMBER);
   AddTextFormFieldData("name", "Account Name", CREDIT_CARD_NAME_FULL);
   AddTextFormFieldData("ccmonth", "Exp Month", CREDIT_CARD_EXP_MONTH);
   AddTextFormFieldData("ccyear", "Exp Year", CREDIT_CARD_EXP_4_DIGIT_YEAR);
-
   ClassifyAndVerify(ParseResult::PARSED);
 }
 
 TEST_F(CreditCardFieldTest, ParseCreditCardContextualNameWithVerification) {
-  base::test::ScopedFeatureList enabled;
-  enabled.InitWithFeatures(
-      {features::kAutofillStrictContextualCardNameConditions}, {});
-
   AddTextFormFieldData("acctNum", "Account ID", CREDIT_CARD_NUMBER);
   AddTextFormFieldData("name", "Account Name", CREDIT_CARD_NAME_FULL);
   AddTextFormFieldData("cvv", "Verification", CREDIT_CARD_VERIFICATION_CODE);
-
   ClassifyAndVerify(ParseResult::PARSED);
 }
 
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 68219b4..b53a8ec 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -650,7 +650,6 @@
       host_frame_(form.host_frame),
       unique_renderer_id_(form.unique_renderer_id) {
   // Copy the form fields.
-  std::map<std::u16string, size_t> unique_names;
   for (const FormFieldData& field : form.fields) {
     if (!ShouldSkipField(field))
       ++active_field_count_;
@@ -660,12 +659,7 @@
     else
       all_fields_are_passwords_ = false;
 
-    // Generate a unique name for this field by appending a counter to the name.
-    // Make sure to prepend the counter with a non-numeric digit so that we are
-    // guaranteed to avoid collisions.
-    std::u16string unique_name =
-        field.name + u"_" + base::NumberToString16(++unique_names[field.name]);
-    fields_.push_back(std::make_unique<AutofillField>(field, unique_name));
+    fields_.push_back(std::make_unique<AutofillField>(field));
   }
 
   form_signature_ = autofill::CalculateFormSignature(form);
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 5536057..2acfb96f 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -363,13 +363,6 @@
 const base::Feature kAutofillSkipComparingInferredLabels{
     "AutofillSkipComparingInferredLabels", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Controls whether we require an expiration date or verification field when a
-// name field is detected for a credit card, but we aren't confident it's not
-// a non-credit card specific name field.
-const base::Feature kAutofillStrictContextualCardNameConditions{
-    "AutofillStrictContextualCardNameConditions",
-    base::FEATURE_ENABLED_BY_DEFAULT};
-
 // Controls whether Autofill should search prefixes of all words/tokens when
 // filtering profiles, or only on prefixes of the whole string.
 const base::Feature kAutofillTokenPrefixMatching{
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 352aaf36..00a98356 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -139,8 +139,6 @@
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillSkipComparingInferredLabels;
 COMPONENT_EXPORT(AUTOFILL)
-extern const base::Feature kAutofillStrictContextualCardNameConditions;
-COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillTokenPrefixMatching;
 COMPONENT_EXPORT(AUTOFILL) extern const base::Feature kAutofillUploadThrottling;
 COMPONENT_EXPORT(AUTOFILL)
diff --git a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
index a800452..1ad0bfbe 100644
--- a/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
+++ b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -48,17 +48,17 @@
 const char kNumBlockedHistogram[] =
     "ContentSettings.Popups.StrongBlocker.NumBlocked";
 
-class SafeBrowsingTriggeredPopupBlockerTest
+class SafeBrowsingTriggeredPopupBlockerTestBase
     : public content::RenderViewHostTestHarness {
  public:
-  SafeBrowsingTriggeredPopupBlockerTest() = default;
+  SafeBrowsingTriggeredPopupBlockerTestBase() = default;
 
-  SafeBrowsingTriggeredPopupBlockerTest(
-      const SafeBrowsingTriggeredPopupBlockerTest&) = delete;
-  SafeBrowsingTriggeredPopupBlockerTest& operator=(
-      const SafeBrowsingTriggeredPopupBlockerTest&) = delete;
+  SafeBrowsingTriggeredPopupBlockerTestBase(
+      const SafeBrowsingTriggeredPopupBlockerTestBase&) = delete;
+  SafeBrowsingTriggeredPopupBlockerTestBase& operator=(
+      const SafeBrowsingTriggeredPopupBlockerTestBase&) = delete;
 
-  ~SafeBrowsingTriggeredPopupBlockerTest() override {
+  ~SafeBrowsingTriggeredPopupBlockerTestBase() override {
     settings_map_->ShutdownOnUIThread();
   }
 
@@ -77,7 +77,6 @@
         &pref_service_, false /* is_off_the_record */,
         false /* store_last_modified */, false /* restore_session*/);
 
-    scoped_feature_list_ = DefaultFeatureList();
     subresource_filter::SubresourceFilterObserverManager::CreateForWebContents(
         web_contents());
     PopupBlockerTabHelper::CreateForWebContents(web_contents());
@@ -93,25 +92,14 @@
         std::make_unique<content::TestNavigationThrottleInserter>(
             web_contents(),
             base::BindRepeating(
-                &SafeBrowsingTriggeredPopupBlockerTest::CreateThrottle,
+                &SafeBrowsingTriggeredPopupBlockerTestBase::CreateThrottle,
                 base::Unretained(this)));
   }
 
-  virtual std::unique_ptr<base::test::ScopedFeatureList> DefaultFeatureList() {
-    auto feature_list = std::make_unique<base::test::ScopedFeatureList>();
-    feature_list->InitAndEnableFeature(kAbusiveExperienceEnforce);
-    return feature_list;
-  }
-
   FakeSafeBrowsingDatabaseManager* fake_safe_browsing_database() {
     return fake_safe_browsing_database_.get();
   }
 
-  base::test::ScopedFeatureList* ResetFeatureAndGet() {
-    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
-    return scoped_feature_list_.get();
-  }
-
   SafeBrowsingTriggeredPopupBlocker* popup_blocker() { return popup_blocker_; }
 
   void SimulateDeleteContents() {
@@ -154,7 +142,7 @@
         fake_safe_browsing_database_);
   }
 
-  std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
+  base::test::ScopedFeatureList scoped_feature_list_;
   variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
       variations::VariationsIdsProvider::Mode::kUseSignedInState};
   scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_;
@@ -164,6 +152,14 @@
   scoped_refptr<HostContentSettingsMap> settings_map_;
 };
 
+class SafeBrowsingTriggeredPopupBlockerTest
+    : public SafeBrowsingTriggeredPopupBlockerTestBase {
+ public:
+  SafeBrowsingTriggeredPopupBlockerTest() {
+    scoped_feature_list_.InitAndEnableFeature(kAbusiveExperienceEnforce);
+  }
+};
+
 struct RedirectSamplesAndResults {
   GURL initial_url;
   GURL redirect_url;
@@ -272,8 +268,10 @@
   EXPECT_TRUE(GetMainFrameConsoleMessages().empty());
 }
 
-TEST_F(SafeBrowsingTriggeredPopupBlockerTest, FeatureEnabledByDefault) {
-  ResetFeatureAndGet();
+class SafeBrowsingTriggeredPopupBlockerDefaultTest
+    : public SafeBrowsingTriggeredPopupBlockerTestBase {};
+
+TEST_F(SafeBrowsingTriggeredPopupBlockerDefaultTest, FeatureEnabledByDefault) {
   SafeBrowsingTriggeredPopupBlocker::MaybeCreate(web_contents());
   EXPECT_NE(nullptr,
             SafeBrowsingTriggeredPopupBlocker::FromWebContents(web_contents()));
@@ -427,12 +425,20 @@
   histogram_tester.ExpectUniqueSample(kNumBlockedHistogram, 1, 1);
 }
 
-TEST_F(SafeBrowsingTriggeredPopupBlockerTest,
-       WarningMatchWithoutAdBlockOnAbusiveSites_OnlyLogs) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(
-      subresource_filter::kFilterAdsOnAbusiveSites);
+class SafeBrowsingTriggeredPopupBlockerFilterAdsDisabledTest
+    : public SafeBrowsingTriggeredPopupBlockerTestBase {
+ public:
+  SafeBrowsingTriggeredPopupBlockerFilterAdsDisabledTest() {
+    scoped_feature_list_.InitAndDisableFeature(
+        subresource_filter::kFilterAdsOnAbusiveSites);
+  }
 
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(SafeBrowsingTriggeredPopupBlockerFilterAdsDisabledTest,
+       WarningMatchWithoutAdBlockOnAbusiveSites_OnlyLogs) {
   const GURL url("https://example.test/");
   MarkUrlAsAbusiveWarning(url);
   NavigateAndCommit(url);
@@ -445,12 +451,20 @@
       web_contents()->GetPrimaryPage()));
 }
 
-TEST_F(SafeBrowsingTriggeredPopupBlockerTest,
-       WarningMatchWithAdBlockOnAbusiveSites_OnlyLogs) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(
-      subresource_filter::kFilterAdsOnAbusiveSites);
+class SafeBrowsingTriggeredPopupBlockerFilterAdsEnabledTest
+    : public SafeBrowsingTriggeredPopupBlockerTestBase {
+ public:
+  SafeBrowsingTriggeredPopupBlockerFilterAdsEnabledTest() {
+    scoped_feature_list_.InitAndEnableFeature(
+        subresource_filter::kFilterAdsOnAbusiveSites);
+  }
 
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(SafeBrowsingTriggeredPopupBlockerFilterAdsEnabledTest,
+       WarningMatchWithAdBlockOnAbusiveSites_OnlyLogs) {
   const GURL url("https://example.test/");
   MarkUrlAsAbusiveWarning(url);
   NavigateAndCommit(url);
diff --git a/components/components_strings.grd b/components/components_strings.grd
index 5f3971e0..cc221ec 100644
--- a/components/components_strings.grd
+++ b/components/components_strings.grd
@@ -386,10 +386,10 @@
       <message name="IDS_MENU" desc="The accessible name for the Menu. This is used as the aria-roledescription for context menus.">
         Menu
       </message>
-      <message name="IDS_INSTALL" desc="Text to be displayed when an action will trigger an installation (of a component, app from the Play Store, etc.).">
+      <message name="IDS_INSTALL" desc="Text to be displayed when an action will trigger an installation (of a component, app from the Play Store, etc.)." formatter_data="android_java">
         Install
       </message>
-      <message name="IDS_UPDATE" desc="Text to be displayed when an action will trigger an update of an existing item (e.g. a component, app from the Play Store, etc.).">
+      <message name="IDS_UPDATE" desc="Text to be displayed when an action will trigger an update of an existing item (e.g. a component, app from the Play Store, etc.)." formatter_data="android_java">
         Update
       </message>
       <if expr="is_android">
diff --git a/components/error_page/common/alt_game_images.cc b/components/error_page/common/alt_game_images.cc
index 6ffd77c..8f2454e 100644
--- a/components/error_page/common/alt_game_images.cc
+++ b/components/error_page/common/alt_game_images.cc
@@ -4,2890 +4,22 @@
 
 #include "components/error_page/common/alt_game_images.h"
 
-#include <cstring>
-
-#include "base/base64.h"
-#include "base/base64url.h"
-#include "base/rand_util.h"
-#include "base/strings/strcat.h"
-#include "base/strings/string_util.h"
-#include "crypto/encryptor.h"
-#include "crypto/symmetric_key.h"
+#include "base/notreached.h"
 
 namespace error_page {
-namespace {
-const uint8_t kAltGameImages1xA[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x40, 0xcc, 0xc1, 0x2f,
-    0xc8, 0x25, 0x29, 0x6e, 0xe,  0x12, 0x32, 0xe9, 0xe3, 0xad, 0xfa, 0xdf,
-    0x55, 0x8a, 0x6,  0x12, 0xa2, 0x4e, 0xa6, 0x2e, 0xbd, 0x3,  0xeb, 0xdc,
-    0x54, 0x29, 0xf4, 0x22, 0x7f, 0xdc, 0x80, 0xb3, 0xe1, 0xe2, 0xa5, 0xcf,
-    0xa7, 0x7f, 0x7,  0x8a, 0xe,  0xa,  0x50, 0x50, 0xf7, 0x45, 0xa9, 0x9,
-    0xee, 0xea, 0x93, 0xdb, 0xb2, 0xe5, 0x41, 0xfd, 0xc2, 0xf9, 0x2f, 0xf2,
-    0x41, 0x0,  0x6d, 0x68, 0x2,  0x9e, 0x20, 0xe7, 0x90, 0x73, 0x6b, 0x57,
-    0x44, 0x54, 0xcd, 0xd2, 0x90, 0x0,  0x2d, 0x58, 0xe8, 0x9d, 0x53, 0x59,
-    0x32, 0xee, 0xca, 0xf0, 0xd4, 0xa6, 0x3c, 0x3,  0x52, 0x75, 0x7d, 0x83,
-    0x97, 0x4e, 0x44, 0x79, 0xf2, 0xb6, 0x2,  0xab, 0xcc, 0xc9, 0xa8, 0x3,
-    0xb9, 0x11, 0x2f, 0xe2, 0x1e, 0x16, 0xc6, 0x6c, 0x5b, 0x8c, 0xfb, 0xbb,
-    0xe2, 0xd3, 0x86, 0xe9, 0x1b, 0xfa, 0xcc, 0x4c, 0xf8, 0xa,  0xd7, 0x1c,
-    0xa1, 0x7,  0xd6, 0xf9, 0x13, 0x1,  0xb,  0x3c, 0x18, 0x1f, 0x1e, 0x6f,
-    0x7d, 0xdf, 0xb8, 0xd6, 0xbd, 0xb3, 0x36, 0x8f, 0xef, 0xd3, 0x5,  0x17,
-    0x2d, 0xf,  0x57, 0xcf, 0xa5, 0x73, 0x14, 0xc8, 0xee, 0x4e, 0xc2, 0x22,
-    0x71, 0x8d, 0x29, 0x4b, 0xc2, 0xd5, 0xa0, 0x37, 0xe6, 0xad, 0xa4, 0xc1,
-    0x8a, 0x72, 0xc1, 0x29, 0x87, 0x16, 0xb1, 0xad, 0xd3, 0xc7, 0x0,  0xa0,
-    0x14, 0x5c, 0x2a, 0x10, 0x4f, 0xff, 0xe2, 0xb0, 0x3a, 0x93, 0xa8, 0xd5,
-    0x43, 0xb,  0xa3, 0x78, 0x87, 0xbf, 0xf5, 0x79, 0x37, 0x34, 0xa8, 0xb2,
-    0x1b, 0xab, 0x44, 0x86, 0x9c, 0x23, 0xc4, 0x76, 0x89, 0x6,  0x2e, 0x6c,
-    0x8f, 0x5a, 0xfe, 0x96, 0xd4, 0xbf, 0x8,  0x3c, 0x3b, 0xd6, 0x34, 0xb4,
-    0xc7, 0xb1, 0xa0, 0x38, 0x8f, 0x4b, 0xb4, 0xc6, 0x16, 0xaf, 0xc9, 0x28,
-    0x8,  0xf1, 0x6a, 0xaa, 0x72, 0xf0, 0x53, 0xa8, 0x4b, 0x7,  0x22, 0x4b,
-    0xa6, 0xa0, 0x65, 0xfc, 0xa8, 0xcd, 0x98, 0x26, 0x3c, 0xe6, 0xa6, 0x64,
-    0x0,  0x3d, 0xd9, 0xa2, 0x77, 0xe1, 0x75, 0x5f, 0xf0, 0x1f, 0x69, 0xee,
-    0x5b, 0x2f, 0x47, 0xdb, 0x75, 0x73, 0xed, 0xe4, 0x9f, 0x41, 0xd8, 0xb1,
-    0x58, 0x6e, 0x5f, 0x45, 0xe1, 0x39, 0xae, 0xd1, 0xc,  0x78, 0x62, 0xb,
-    0xef, 0x40, 0xd4, 0x15, 0xea, 0x7f, 0xa3, 0xb1, 0x5b, 0x44, 0xc0, 0xd,
-    0x7f, 0x69, 0xb,  0x43, 0xbe, 0x11, 0xd,  0x7d, 0xaa, 0xd9, 0xaf, 0x78,
-    0x99, 0xad, 0x1c, 0x25, 0xd2, 0x88, 0xb5, 0x5c, 0xf0, 0x27, 0xd9, 0x31,
-    0xf0, 0x84, 0xbb, 0xf4, 0x66, 0x9f, 0x8b, 0xc,  0x18, 0x6e, 0xf7, 0x4d,
-    0x3,  0xb5, 0x66, 0xb2, 0xdf, 0xf2, 0xd4, 0x8e, 0xef, 0xca, 0x99, 0xdd,
-    0xd,  0x47, 0x86, 0xa,  0xc,  0xba, 0xce, 0xab, 0x7f, 0xae, 0x2f, 0xa9,
-    0x49, 0x2b, 0x20, 0xe1, 0x80, 0x73, 0x0,  0xa9, 0x91, 0xe5, 0xce, 0x34,
-    0x2c, 0xdb, 0x3c, 0xe3, 0x13, 0xdb, 0x65, 0x80, 0x90, 0xe4, 0x10, 0x8f,
-    0x9b, 0xa5, 0xaa, 0xfe, 0x87, 0x6a, 0x73, 0x3,  0x64, 0x32, 0xe,  0xc4,
-    0x3b, 0x8b, 0xb7, 0x2b, 0x42, 0x79, 0x60, 0x9d, 0x83, 0x12, 0xe3, 0x6a,
-    0x65, 0x1f, 0x47, 0x3e, 0x6c, 0xa5, 0xe9, 0xda, 0x1e, 0x21, 0xe7, 0x44,
-    0xdb, 0x72, 0x3c, 0xd4, 0x25, 0x39, 0x5a, 0x2,  0xb6, 0x53, 0xbe, 0x18,
-    0x9a, 0x99, 0x26, 0xc6, 0x86, 0xfb, 0x2e, 0x79, 0xe2, 0x21, 0xaa, 0x56,
-    0x52, 0x2b, 0xa0, 0xd9, 0x1f, 0x75, 0x99, 0x4c, 0xe2, 0x3f, 0x87, 0x90,
-    0xc1, 0x29, 0x99, 0x78, 0xab, 0x15, 0x27, 0x55, 0xa2, 0x4f, 0x5c, 0x72,
-    0x49, 0x4e, 0xc2, 0xd6, 0xaa, 0xe1, 0x0,  0x8,  0x70, 0x50, 0x64, 0x13,
-    0xf0, 0x97, 0x38, 0x0,  0x95, 0x8f, 0x87, 0x4a, 0x46, 0x3f, 0xba, 0x83,
-    0x96, 0x20, 0x29, 0x11, 0x19, 0xe5, 0x5b, 0x31, 0x8,  0xf1, 0x4a, 0x97,
-    0xdd, 0x52, 0x1c, 0x6a, 0xc,  0xc,  0x6a, 0x13, 0x5b, 0x23, 0x49, 0xdf,
-    0x95, 0x86, 0x82, 0x43, 0xde, 0x4a, 0x35, 0x88, 0x9a, 0x83, 0x2,  0xcc,
-    0xc3, 0x16, 0x48, 0x0,  0x46, 0xeb, 0xde, 0x87, 0x98, 0xbd, 0xf7, 0x81,
-    0xb9, 0xc6, 0xfc, 0xf4, 0x46, 0x98, 0x1,  0xd5, 0x7a, 0xf6, 0x1b, 0x3f,
-    0xdb, 0x98, 0xf3, 0x22, 0x37, 0x5b, 0x7c, 0x3c, 0xd2, 0x41, 0x19, 0x11,
-};
-const uint8_t kAltGameImages1xB[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0xff, 0xe5, 0xb7, 0xbe,
-    0x33, 0xdd, 0x84, 0x73, 0x82, 0xc,  0xa1, 0x47, 0x40, 0x9f, 0x40, 0x4c,
-    0x13, 0x4a, 0xf5, 0xa0, 0x9b, 0x79, 0xc7, 0xcb, 0x4c, 0x57, 0xce, 0xbc,
-    0x34, 0x95, 0x4e, 0xd9, 0xb6, 0x68, 0x9e, 0xf3, 0xaa, 0xea, 0xa3, 0x5a,
-    0x57, 0x58, 0x30, 0x2c, 0xc8, 0x4b, 0x68, 0xd7, 0x11, 0x8a, 0x36, 0xdb,
-    0x60, 0xb4, 0x3e, 0xca, 0xa,  0xba, 0x12, 0x36, 0x38, 0x56, 0xc0, 0x61,
-    0xbc, 0xd3, 0x4b, 0x95, 0x3,  0x9a, 0x8e, 0x7b, 0xd2, 0x62, 0x81, 0x7,
-    0x56, 0x42, 0x88, 0xbe, 0xea, 0x2c, 0xdd, 0x7e, 0xf2, 0x5a, 0xb5, 0x5a,
-    0xc7, 0x35, 0x4d, 0xe8, 0x8f, 0xd2, 0x4a, 0x3,  0x5c, 0xb7, 0xcf, 0x23,
-    0x5f, 0xd1, 0x11, 0x13, 0x7a, 0xc1, 0x46, 0x26, 0x6c, 0x4d, 0xa2, 0x56,
-    0x30, 0xf6, 0x5d, 0x27, 0xa,  0x35, 0x50, 0x2f, 0xee, 0xe1, 0x3,  0x9d,
-    0xdd, 0xa5, 0x85, 0xb,  0xcc, 0x46, 0xbc, 0x95, 0x40, 0x97, 0xd,  0xba,
-    0x9d, 0x24, 0x47, 0xe0, 0xd1, 0xca, 0x4b, 0x30, 0x87, 0x23, 0x3c, 0xe1,
-    0xc8, 0x50, 0x29, 0x56, 0x9b, 0xee, 0x4c, 0xb8, 0x1c, 0x26, 0xce, 0xb,
-    0x8a, 0xd5, 0xb5, 0x75, 0xbc, 0x76, 0xad, 0x87, 0xc,  0x47, 0x62, 0xf5,
-    0x57, 0xf4, 0x0,  0xa1, 0xad, 0xfa, 0xc6, 0xc3, 0xf7, 0x83, 0xfe, 0x9d,
-    0x25, 0xdd, 0x35, 0x81, 0xf5, 0x1a, 0x82, 0x1b, 0x93, 0xa5, 0x40, 0x11,
-    0xe9, 0xe5, 0x6e, 0xac, 0x36, 0x33, 0xcc, 0x99, 0x7e, 0x11, 0x85, 0x79,
-    0x24, 0x22, 0x74, 0xf7, 0x8d, 0xfb, 0x40, 0x80, 0x9a, 0xca, 0xb5, 0xbe,
-    0x3a, 0x58, 0x6f, 0xa9, 0x76, 0xd4, 0xe8, 0x29, 0x80, 0xc7, 0xe,  0xdd,
-    0xe,  0x75, 0xf6, 0xc8, 0x11, 0x21, 0x81, 0xce, 0x3f, 0x41, 0x4d, 0xd8,
-    0x4c, 0x4b, 0x2e, 0xeb, 0x9f, 0xb3, 0x1a, 0xa4, 0x2f, 0xa5, 0x44, 0xbb,
-    0xcd, 0x46, 0xe6, 0x1f, 0xd,  0xd0, 0xc3, 0x27, 0x8b, 0x3a, 0xbf, 0xda,
-    0x8f, 0xaa, 0xfd, 0xc2, 0x49, 0xd,  0x5c, 0xb7, 0xbc, 0x23, 0x57, 0x2f,
-    0x83, 0xd4, 0x8,  0xee, 0x1,  0x56, 0x78, 0xee, 0x90, 0xb8, 0x5a, 0x64,
-    0x51, 0xad, 0xad, 0xfe, 0xe9, 0xae, 0x8e, 0xae, 0xe9, 0x26, 0x57, 0xf0,
-    0x77, 0xe1, 0xc1, 0xd8, 0x9d, 0x49, 0x8e, 0x8f, 0x7,  0x8,  0xcc, 0x45,
-    0x6a, 0x3c, 0xf2, 0xbf, 0xee, 0x4f, 0xb,  0xe9, 0x5a, 0xaf, 0xd4, 0x12,
-    0xb0, 0xcd, 0x3,  0x3c, 0x96, 0x1e, 0xa9, 0x24, 0xab, 0x1d, 0x16, 0xea,
-    0x1a, 0x41, 0x56, 0xc6, 0xc1, 0xb7, 0x96, 0x36, 0xec, 0x20, 0xeb, 0xc2,
-    0x19, 0x37, 0x55, 0x66, 0x12, 0xf5, 0x3,  0x55, 0x2d, 0x27, 0x28, 0x65,
-    0xdb, 0x64, 0xc5, 0x71, 0xfc, 0x76, 0x2f, 0xc0, 0x7b, 0x49, 0x90, 0x5f,
-    0x5d, 0x4d, 0x6a, 0x66, 0x7d, 0xfb, 0xe2, 0x16, 0x72, 0x84, 0xb6, 0xcb,
-    0x65, 0x2d, 0x8b, 0x22, 0x4b, 0x1d, 0x4a, 0xde, 0x6b, 0x8c, 0x2c, 0x45,
-    0x6,  0xe6, 0x92, 0x2e, 0xaf, 0x55, 0x66, 0xb,  0xae, 0xe9, 0xd7, 0xd2,
-    0x3e, 0xc1, 0xdc, 0xe4, 0x4,  0x58, 0x4a, 0x64, 0x30, 0x20, 0xc6, 0x2f,
-    0xa9, 0xee, 0xed, 0xb3, 0xe4, 0xc9, 0xca, 0x34, 0x71, 0xfc, 0x2,  0x95,
-    0x51, 0xe4, 0xd2, 0x3,  0x4d, 0x3d, 0x10, 0xa5, 0xdc, 0xc6, 0x5e, 0x5c,
-    0x1f, 0x27, 0xc4, 0x7c, 0xd,  0xfc, 0xdb, 0xd6, 0xd5, 0x2b, 0xaa, 0xbc,
-    0x22, 0x61, 0x56, 0x10, 0xc2, 0xfc, 0x58, 0x53, 0xea, 0x12, 0x9d, 0x49,
-    0xbd, 0x7e, 0xf7, 0x8d, 0x16, 0x25, 0x86, 0x84, 0x92, 0x70, 0x5f, 0xdd,
-    0x73, 0xc1, 0x7,  0xfa, 0xd3, 0xc1, 0xdc, 0x61, 0x36, 0x1c, 0x74, 0xa2,
-    0x9,  0x3f, 0x66, 0x90, 0x47, 0x9e, 0x27, 0x39, 0x44, 0xde, 0x48, 0xa8,
-    0x5b, 0xdc, 0x42, 0xc1, 0x49, 0x87, 0x64, 0xa,  0xea, 0x5,  0x7e, 0x48,
-    0xf9, 0x42, 0xf0, 0xf6, 0x5a, 0x4c, 0xc2, 0xd2, 0xb2, 0x4f, 0x16, 0x63,
-    0xce, 0x10, 0x13, 0xce, 0xf7, 0x6a, 0xa4, 0xe8, 0x3,  0xe3, 0xd6, 0x10,
-    0x6f, 0xbd, 0xf4, 0x24, 0x3,  0x16, 0x1f, 0x51, 0x2f, 0x85, 0x5f, 0x5d,
-    0xd6, 0xc4, 0xd2, 0x3f, 0xd2, 0xab, 0x6b, 0x89, 0x52, 0xdb, 0x6c, 0x7a,
-    0xa1, 0xf8, 0xe3, 0x19, 0x47, 0x2e, 0x64, 0xe3, 0xf0, 0x4e, 0x6d, 0x5e,
-    0xbc, 0x54, 0x54, 0x5d, 0x9a, 0xdf, 0xed, 0xa7, 0xcf, 0xa0, 0x6f, 0x5e,
-    0x23, 0x6f, 0x52, 0x90, 0x50, 0x35, 0x68, 0x45, 0xd8, 0xc2, 0x9a, 0x9e,
-    0xae, 0x13, 0x8a, 0xc1, 0x60, 0x72, 0xb7, 0x6d, 0xd,  0x61, 0xe9, 0x3c,
-    0xe1, 0xbe, 0x22, 0xc5, 0xa2, 0x7d, 0x8a, 0x8b, 0x43, 0x14, 0xef, 0x5c,
-    0xa4, 0x10, 0xb7, 0x7,  0x73, 0xad, 0xb4, 0x86, 0xae, 0xc0, 0x1c, 0xf4,
-    0xd2, 0x6,  0xda, 0x1,  0x35, 0x17, 0xcd, 0xa6, 0x28, 0x44, 0xc9, 0xbf,
-    0x97, 0xe5, 0x41, 0x37, 0xe5, 0xcf, 0x3f, 0x96, 0xb5, 0x67, 0xcc, 0xea,
-    0x69, 0x8e, 0xfd, 0xd6, 0x92, 0x5d, 0x72, 0xf5, 0xfd, 0x57, 0xb8, 0x4e,
-    0x1b, 0x2d, 0x31, 0x3b, 0x99, 0x1a, 0x3e, 0xd4, 0x54, 0x77, 0x2e, 0x4b,
-    0x2e, 0x5f, 0xcd, 0x56, 0xd4, 0xf7, 0xfc, 0x7,  0x92, 0x28, 0x3f, 0xdb,
-    0x4f, 0x41, 0x1e, 0x43, 0xbc, 0x37, 0x81, 0xda, 0xe4, 0xeb, 0x9c, 0xf3,
-    0xa5, 0x5b, 0xf7, 0x11, 0xf6, 0x5b, 0x12, 0x85, 0x57, 0xdb, 0xf,  0x1,
-    0xc5, 0xfb, 0x33, 0x65, 0xa6, 0x51, 0xfa, 0x43, 0x8d, 0x9d, 0x42, 0xe2,
-    0xe,  0x61, 0x9d, 0xcb, 0x6b, 0xe2, 0xa0, 0x60, 0x67, 0xba, 0x7e, 0x55,
-    0xaf, 0x24, 0x7d, 0x32, 0xb0, 0x27, 0xa8, 0xa1, 0xad, 0xa,  0xd,  0xed,
-    0xed, 0x2c, 0xeb, 0x98, 0xd9, 0x49, 0xcb, 0xd5, 0x2e, 0x7,  0x32, 0x87,
-    0x37, 0xa4, 0x2a, 0x1c, 0xf2, 0xce, 0xfb, 0xa8, 0x6a, 0xf2, 0xf7, 0x70,
-    0x20, 0xbd, 0xca, 0x48, 0x76, 0xc9, 0x49, 0x58, 0x15, 0xbb, 0xcc, 0x21,
-    0x60, 0x37, 0x31, 0xee, 0xbb, 0xff, 0xde, 0xd8, 0x6c, 0xeb, 0x55, 0x12,
-    0xf8, 0xbb, 0x36, 0x11, 0xa4, 0x6f, 0x1d, 0x81, 0xd,  0xc3, 0xd9, 0xa7,
-    0xee, 0xc2, 0x9c, 0x45, 0x78, 0x12, 0xd,  0x73, 0x11, 0x69, 0x14, 0x7d,
-    0x23, 0xdb, 0x69, 0xdf, 0xc2, 0xc8, 0x5b, 0x4,  0xd5, 0x4f, 0xa,  0xfb,
-    0x4f, 0x2d, 0x52, 0x3c, 0x99, 0x15, 0xec, 0xf8, 0x2b, 0x98, 0x3c, 0x2a,
-    0xd5, 0x59, 0x57, 0xbb, 0xa0, 0x14, 0x5f, 0x9,  0x7e, 0xd5, 0xbe, 0x0,
-    0x99, 0x61, 0x7c, 0x8b, 0xdb, 0x94, 0xc6, 0x43, 0x7c, 0x13, 0xee, 0x1c,
-    0xfa, 0x61, 0x2b, 0xd2, 0xc6, 0xa,  0xba, 0x30, 0x55, 0x50, 0x9a, 0xa1,
-    0x14, 0x78, 0x97, 0x46, 0x6f, 0xe0, 0xa8, 0xd4, 0x3f, 0xf5, 0x39, 0xc8,
-    0x1e, 0x4f, 0x3f, 0xc8, 0x67, 0x10, 0x25, 0x36, 0x8a, 0x8,  0x2,  0x67,
-    0x6a, 0x73, 0x93, 0x76, 0x74, 0x54, 0x9,  0x87, 0xac, 0x9f, 0x90, 0x3,
-    0xb6, 0xb4, 0x79, 0xa7, 0x56, 0x7f, 0x71, 0x9a, 0x41, 0xb0, 0xf4, 0xc7,
-    0xbb, 0xd8, 0x68, 0xa7, 0xa,  0xfe, 0xe,  0x15, 0xe2, 0xcf, 0x2d, 0xd4,
-    0x3,  0xee, 0x12, 0xa9, 0xef, 0x81, 0xa1, 0xa6, 0x12, 0x38, 0x6c, 0x37,
-    0xd3, 0x11, 0xaa, 0x7,  0x8f, 0xfe, 0xb4, 0xf0, 0x92, 0x66, 0xfc, 0xa,
-    0xc2, 0x21, 0xa3, 0x62, 0xec, 0xec, 0xda, 0x4f, 0xb3, 0xeb, 0x1d, 0x8c,
-    0x1a, 0x7c, 0x58, 0x12, 0x30, 0x52, 0x1f, 0xf3, 0x90, 0xcf, 0x8e, 0xc5,
-    0xd5, 0x5d, 0xe3, 0x92, 0xf3, 0x66, 0x7a, 0x1d, 0xea, 0x9c, 0x95, 0x91,
-    0xe9, 0x13, 0x82, 0xe6, 0xea, 0x66, 0x3f, 0x31, 0xab, 0xb7, 0x46, 0x87,
-    0x4d, 0xc4, 0x1a, 0x4a, 0x34, 0xfb, 0x0,  0x85, 0xd2, 0xa5, 0x18, 0xf3,
-    0x50, 0x3f, 0x79, 0x5c, 0xe5, 0x5b, 0xc2, 0xcb, 0xd5, 0xa3, 0x63, 0x6f,
-    0x11, 0xae, 0xf1, 0x5,  0xb1, 0x53, 0x8b, 0x65, 0x80, 0x8d, 0xd3, 0x98,
-    0x1e, 0xba, 0xe4, 0xe1, 0x4f, 0xd0, 0x9c, 0x2,  0x6c, 0xd1, 0x6e, 0x18,
-    0xce, 0xec, 0x10, 0x28, 0x29, 0xd8, 0xd2, 0xfa, 0x38, 0xb0, 0x3,  0xb7,
-    0xc4, 0x99, 0xa7, 0x56, 0x24, 0xba, 0x70, 0xf3, 0x8,  0xae, 0x7f, 0xf4,
-    0xb1, 0x84, 0xb5, 0xa8, 0xd7, 0x7a, 0xd8, 0x53, 0xde, 0x2d, 0xc9, 0xd3,
-    0x27, 0x95, 0xe3, 0x5a, 0x11, 0xcc, 0xdf, 0x5b, 0x13, 0x36, 0x25, 0x92,
-    0x49, 0x31, 0x1d, 0x83, 0x87, 0x61, 0x91, 0x9b, 0x18, 0xb,  0xc0, 0x6e,
-    0xab, 0xfc, 0x73, 0x76, 0x92, 0xbc, 0x27, 0xc4, 0x37, 0x83, 0xb0, 0x80,
-    0x71, 0x82, 0x17, 0x8c, 0x8f, 0x9e, 0x32, 0xb,  0x5a, 0x3d, 0x4d, 0xb1,
-    0x24, 0x7,  0x91, 0x2a, 0x42, 0x43, 0xcc, 0xba, 0xbc, 0xee, 0x7f, 0x41,
-    0x46, 0xcf, 0x5e, 0x85, 0xd7, 0x4d, 0xbc, 0x9,  0xe7, 0xbe, 0xab, 0x4d,
-    0x63, 0x5c, 0xc7, 0x1a, 0x7f, 0x57, 0xf8, 0xd7, 0xbe, 0x50, 0x1,  0xa1,
-    0xe,  0x27, 0x9a, 0xb2, 0x3f, 0x2a, 0xbc, 0x8f, 0x1b, 0x6a, 0xe0, 0x3e,
-    0x5b, 0x97, 0x3f, 0x2b, 0xdb, 0x1e, 0x4f, 0x7,  0xbf, 0x29, 0x7b, 0x8e,
-    0x2a, 0x64, 0x30, 0xbd, 0x1f, 0x53, 0xaa, 0x63, 0xad, 0x1d, 0x3e, 0xfd,
-    0xd6, 0x6b, 0x32, 0x94, 0x84, 0xbe, 0x7e, 0x49, 0x72, 0x20, 0xec, 0xd4,
-    0x63, 0xe7, 0xd,  0xbb, 0x3f, 0x70, 0x70, 0x43, 0x3a, 0xab, 0x6f, 0xb7,
-    0x5b, 0x23, 0x7f, 0x23, 0xe,  0x36, 0xa2, 0xee, 0x72, 0xf9, 0x5d, 0x63,
-    0x78, 0xfc, 0x19, 0x1e, 0x9c, 0x64, 0x87, 0xdb, 0xe6, 0x70, 0xd6, 0x60,
-    0x1c, 0x3e, 0x38, 0x31, 0x94, 0xf4, 0xd9, 0x3f, 0xa1, 0x9c, 0x16, 0xae,
-    0x80, 0x7b, 0x8d, 0x20, 0xa6, 0xf6, 0xd4, 0x37, 0x74, 0x44, 0x94, 0xaf,
-    0x3c, 0x89, 0x8c, 0xdb, 0x3b, 0x96, 0x79, 0x15, 0xa,  0x2f, 0x1,  0xd,
-    0x74, 0x99, 0x82, 0x51, 0x17, 0x97, 0x47, 0x68, 0x80, 0x55, 0x2d, 0x6c,
-    0x11, 0x45, 0x5a, 0xee, 0x4a, 0xd6, 0x84, 0x76, 0x97, 0xad, 0x58, 0x40,
-    0xf7, 0x15, 0x2f, 0xdc, 0x5c, 0x4a, 0x7b, 0x65, 0xc6, 0x20, 0x5a, 0x24,
-    0xc5, 0xf4, 0xb0, 0x36, 0xb9, 0x61, 0xd,  0xbf, 0xe,  0x9f, 0x2d, 0x97,
-    0xbb, 0x86, 0x5c, 0x40, 0x70, 0x86, 0x0,  0x4,  0x70, 0x66, 0x70, 0x65,
-    0xdb, 0x39, 0x1d, 0x78, 0xd5, 0x7d, 0x92, 0xae, 0x0,  0x19, 0xef, 0x90,
-    0x21, 0x92, 0x4,  0xcd, 0x22, 0x19, 0xa7, 0xc8, 0x3f, 0xa0, 0x38, 0x5b,
-    0xfb, 0x46, 0x56, 0xd2, 0x11, 0xf1, 0xf9, 0x37, 0x53, 0xc,  0x98, 0x38,
-    0x87, 0xc4, 0xed, 0x88, 0xf9, 0xc3, 0x6,  0x50, 0x19, 0x4b, 0xa8, 0x43,
-    0x5f, 0xe5, 0xf,  0x79, 0x5f, 0x59, 0x22, 0x3c, 0x76, 0xdc, 0x51, 0x6d,
-    0xb0, 0x2b, 0xf0, 0x95, 0x5c, 0xe4, 0x33, 0xb0, 0xff, 0xa3, 0xc8, 0xe0,
-    0x85, 0xe0, 0x8a, 0xfe, 0xf,  0x63, 0x2d, 0x2b, 0x4a, 0x1a, 0xf9, 0xcb,
-    0xb4, 0x86, 0x1,  0x1,  0xd4, 0x8f, 0x57, 0x82, 0xb0, 0xac, 0x52, 0x5d,
-    0x5a, 0x79, 0x2c, 0x2d, 0x18, 0x1,  0x78, 0x3f, 0xb8, 0x31, 0x66, 0x9,
-    0x61, 0x0,  0x8f, 0x4c, 0x4f, 0x18, 0x57, 0xc8, 0x39, 0x7,  0x44, 0x15,
-    0xe4, 0x64, 0xed, 0x3c, 0xa2, 0x59, 0x38, 0x88, 0x13, 0xd0, 0x4c, 0xef,
-    0xc6, 0x7,  0x37, 0x3,  0x81, 0xb1, 0x9,  0xce, 0xa6, 0x8e, 0x3b, 0x70,
-    0x25, 0x87, 0xc4, 0x46, 0x60, 0x9a, 0xb5, 0xa8, 0xd3, 0x39, 0xd7, 0xa1,
-    0xc8, 0x84, 0xa,  0x96, 0xe8, 0x73, 0x9,  0x1e, 0xb9, 0xde, 0x38, 0xc4,
-    0x5,  0x60, 0x26, 0xc6, 0x51, 0x1b, 0x65, 0x66, 0x53, 0xd6, 0xa2, 0x2d,
-    0x97, 0x5a, 0xb0, 0x9a, 0xb9, 0xf0, 0xcb, 0x7a, 0x94, 0xac, 0x9b, 0x9d,
-    0xc3, 0x22, 0xf3, 0x44, 0x59, 0x13, 0x88, 0x18, 0x76, 0x26, 0x16, 0x67,
-    0x85, 0x2a, 0x3d, 0x11, 0xc3, 0x69, 0x81, 0x9e, 0x96, 0x1e, 0x8,  0x23,
-    0x9,  0x1a, 0x39, 0x44, 0xf2, 0x21, 0xd7, 0xa0, 0xc2, 0xb3, 0x6d, 0x42,
-    0x6,  0xee, 0x6e, 0xf9, 0xad, 0x9c, 0x8c, 0x1,  0x6,  0xe6, 0x6,  0x19,
-    0x7,  0xb1, 0x18, 0xdf, 0xe2, 0xa2, 0x97, 0x25, 0x32, 0x27, 0x1,  0x50,
-    0xfc, 0xef, 0xa,  0x84, 0xd7, 0x43, 0x1b, 0xa2, 0xa0, 0x1e, 0x7e, 0x72,
-    0x84, 0xce, 0xee, 0x25, 0x90, 0xcb, 0x47, 0xe3, 0xa0, 0xd1, 0x96, 0xbb,
-    0xec, 0x95, 0x95, 0x73, 0xe7, 0xbc, 0x9c, 0xc5, 0x49, 0x8e, 0x71, 0x85,
-    0x52, 0xf4, 0x27, 0x35, 0x89, 0xbb, 0x73, 0x78, 0xe2, 0xdb, 0xd8, 0xd2,
-    0xe7, 0x92, 0xa3, 0x31, 0x22, 0x28, 0xf9, 0x56, 0x72, 0x9f, 0x3c, 0x72,
-    0xda, 0x77, 0x5a, 0xd8, 0x9f, 0xc5, 0x75, 0xc6, 0xc5, 0xae, 0xb2, 0x33,
-    0x40, 0x35, 0x71, 0x88, 0x11, 0xb0, 0xf1, 0xeb, 0xa0, 0x4d, 0xed, 0x46,
-    0xd9, 0x6b, 0x8a, 0xf1, 0xcc, 0x36, 0x6d, 0x90, 0x58, 0x79, 0x7b, 0xad,
-    0x81, 0xef, 0xd6, 0x39, 0xa3, 0xeb, 0x14, 0xd4, 0x82, 0x3a, 0x5a, 0x51,
-    0x53, 0xf9, 0x9a, 0x54, 0x52, 0x76, 0xd,  0xa,  0xc3, 0x15, 0x87, 0x65,
-    0x11, 0x38, 0x61, 0x83, 0x67, 0xd6, 0x6a, 0x9b, 0xbf, 0xf2, 0x1c, 0x65,
-    0x7c, 0x58, 0xd9, 0x7f, 0x49, 0xa1, 0x63, 0x61, 0x17, 0xc9, 0x3d, 0x9a,
-    0x26, 0xc0, 0xd3, 0x6a, 0x71, 0x95, 0xeb, 0x62, 0x26, 0xca, 0x14, 0x60,
-    0x49, 0x32, 0xa,  0x5a, 0x8f, 0x29, 0x80, 0xc8, 0xfb, 0x6,  0xff, 0x1a,
-    0x7e, 0x55, 0x65, 0x5c, 0x44, 0xc4, 0xa0, 0x72, 0xf0, 0xa1, 0xad, 0x4d,
-    0xad, 0x3,  0xbe, 0x6e, 0xdb, 0x75, 0xd5, 0x6c, 0x5f, 0xaf, 0xa3, 0xaf,
-    0xef, 0x62, 0x15, 0x49, 0x73, 0x87, 0x1,  0x78, 0xbc, 0xe,  0x85, 0xa2,
-    0x81, 0xb4, 0xb5, 0xea, 0x65, 0xc0, 0x8c, 0xf2, 0x9b, 0x5a, 0x2c, 0x2f,
-    0xcf, 0xd6, 0x9c, 0xdf, 0x74, 0x62, 0x68, 0x40, 0xf7, 0x30, 0xff, 0x96,
-    0x9d, 0x66, 0x6c, 0x2d, 0x11, 0x7f, 0x90, 0x28, 0x16, 0xc7, 0xa5, 0x4a,
-    0xe2, 0xd6, 0x5c, 0xdb, 0x97, 0xe7, 0xc6, 0x37, 0xe1, 0x5b, 0x7d, 0x4e,
-    0xaa, 0x2b, 0x7f, 0xf5, 0x77, 0x20, 0x71, 0xec, 0xa9, 0x2f, 0x57, 0x6f,
-    0xea, 0xb4, 0x43, 0x57, 0xc5, 0xee, 0xd8, 0xf6, 0xef, 0xf,  0xc,  0x6c,
-    0x3c, 0xb2, 0x77, 0x83, 0x81, 0xaa, 0x8a, 0x2a, 0xc9, 0x9f, 0x2,  0xab,
-    0xcc, 0x58, 0x3c, 0xb0, 0x42, 0x4,  0x1e, 0xe0, 0xf0, 0xf9, 0xa9, 0x2c,
-    0xe8, 0x76, 0x5e, 0x39, 0xa0, 0xd6, 0xa8, 0x1,  0x56, 0x32, 0xc1, 0x27,
-    0x96, 0xbe, 0x27, 0x5b, 0x74, 0xa7, 0x77, 0xf0, 0x6e, 0x2,  0xdf, 0x4a,
-    0x5,  0x50, 0x2b, 0xf8, 0x73, 0xb0, 0x73, 0xce, 0xb8, 0xfa, 0xaf, 0xd2,
-    0x9a, 0x2,  0x6d, 0xe0, 0x5d, 0x5e, 0x3,  0xff, 0x2d, 0x6a, 0xb0, 0xd6,
-    0xa0, 0x1a, 0xd7, 0x77, 0x7,  0x27, 0xf8, 0x3f, 0xe0, 0x5,  0xe4, 0x42,
-    0x18, 0xa4, 0xe9, 0xf0, 0xd7, 0xb4, 0xf1, 0x2b, 0x92, 0x76, 0x39, 0xb1,
-    0x48, 0x62, 0xa3, 0xf,  0x95, 0x1c, 0x8a, 0xd,  0x79, 0xf6, 0x3d, 0x35,
-    0x64, 0xa1, 0x66, 0x61, 0xa1, 0x38, 0xdd, 0x48, 0x5,  0xa4, 0x73, 0x59,
-    0xca, 0x80, 0x57, 0x4a, 0x65, 0x73, 0x64, 0x5e, 0x9b, 0x7c, 0x85, 0x97,
-    0x52, 0x89, 0x74, 0x79, 0x6f, 0x66, 0xe2, 0x3e, 0x69, 0x89, 0x78, 0xe3,
-    0xee, 0x0,  0xae, 0x8e, 0xbd, 0x91, 0x76, 0xfe, 0x12, 0x7c, 0x2,  0x1d,
-    0x55, 0x62, 0xba, 0x38, 0xf4, 0xba, 0x83, 0x18, 0xba, 0x9e, 0xa1, 0x15,
-    0xdb, 0x7c, 0x56, 0xdb, 0x4f, 0xf3, 0x7a, 0xbe, 0xbd, 0x63, 0x61, 0x72,
-    0xf2, 0x9d, 0x78, 0x4e, 0xa4, 0x22, 0xec, 0xfa, 0xa5, 0xf4, 0x3a, 0x5d,
-    0xd9, 0x30, 0x3a, 0xd9, 0x3c, 0x88, 0xd8, 0x56, 0x59, 0xfb, 0xbd, 0xa6,
-    0xe2, 0x37, 0x47, 0x7b, 0xf3, 0x6f, 0x3b, 0x8f, 0x81, 0xab, 0xbd, 0x95,
-    0xe9, 0xaa, 0xfc, 0x33, 0xe4, 0x5e, 0x3,  0x9c, 0xb2, 0xfe, 0x6a, 0x7d,
-    0xc,  0xcb, 0x17, 0x82, 0xfa, 0xb6, 0xf1, 0xa1, 0x6,  0x95, 0xda, 0x75,
-    0xb8, 0x3f, 0x1,  0x49, 0x7d, 0x9,  0x8d, 0x7e, 0x8b, 0xa0, 0x73, 0xfc,
-    0x37, 0x95, 0xa0, 0x4f, 0x2c, 0x37, 0x98, 0xd5, 0x76, 0xed, 0xd4, 0xc9,
-    0xbd, 0x11, 0x63, 0x67, 0x5e, 0x8f, 0x85, 0x32, 0x57, 0x59, 0xd7, 0xaa,
-    0xc8, 0x66, 0x61, 0xf,  0xea, 0x2b, 0x68, 0x57, 0xa8, 0x90, 0x29, 0x50,
-    0xed, 0x78, 0xb6, 0xe,  0x5a, 0x6b, 0x15, 0x8d, 0xb7, 0xd5, 0x7d, 0x9,
-    0x22, 0x54, 0x43, 0x96, 0x58, 0xa1, 0x2b, 0xe8, 0x89, 0x77, 0x3,  0xa6,
-    0x18, 0xd7, 0xe7, 0x34, 0xe6, 0xe7, 0xbf, 0xae, 0x17, 0x27, 0x63, 0x10,
-    0x1e, 0x4f, 0x97, 0x51, 0x28, 0x90, 0x11, 0x44, 0x8c, 0xe5, 0x15, 0xcb,
-    0x3e, 0xa3, 0x6c, 0xc4, 0xfc, 0xa7, 0x5e, 0x54, 0x4a, 0x70, 0xc1, 0x31,
-    0xf7, 0xd5, 0xed, 0xb0, 0xd1, 0x36, 0x1f, 0xfc, 0x49, 0x60, 0xe9, 0x88,
-    0x3,  0x3d, 0xae, 0x7d, 0x4d, 0x55, 0x69, 0x62, 0xed, 0x16, 0x9a, 0xcc,
-    0xf1, 0x8e, 0xf5, 0x86, 0xec, 0x60, 0x8c, 0x88, 0xa4, 0x6,  0xe4, 0xb8,
-    0xdc, 0x35, 0xad, 0x2e, 0x13, 0xe,  0x7e, 0x90, 0x8c, 0x9f, 0xe5, 0xb1,
-    0xa1, 0x9d, 0x1d, 0xa7, 0x4f, 0x94, 0x44, 0xc6, 0xe6, 0x45, 0xc2, 0x6,
-    0x50, 0x96, 0xa0, 0x84, 0xca, 0x99, 0xc,  0xbf, 0x3c, 0x11, 0xf8, 0xb,
-    0x74, 0x25, 0xf2, 0x91, 0xc9, 0x63, 0xe,  0xe4, 0x3c, 0x3b, 0xfd, 0xe8,
-    0xe,  0xfb, 0x19, 0xe,  0x4b, 0x3c, 0x5d, 0x3f, 0x96, 0xa1, 0x76, 0x20,
-    0x4c, 0x8d, 0x2a, 0x5f, 0xd2, 0x7c, 0x43, 0xf8, 0xb8, 0x49, 0x95, 0xad,
-    0x6,  0xfa, 0x44, 0x4f, 0x72, 0x9,  0xa,  0x85, 0x3e, 0xca, 0xc0, 0x20,
-    0x34, 0x6b, 0xc9, 0x3c, 0xa6, 0xad, 0xbe, 0xe4, 0x80, 0x40, 0x89, 0xee,
-    0x87, 0x34, 0x22, 0xd1, 0xd0, 0x53, 0xb0, 0xb8, 0x65, 0xe6, 0x0,  0xb5,
-    0x41, 0xfb, 0x6b, 0xeb, 0x6,  0x56, 0xd1, 0x83, 0x85, 0x1,  0x46, 0x6e,
-    0x31, 0x43, 0xa2, 0x91, 0xe4, 0xcd, 0xa4, 0x43, 0x43, 0x8c, 0x26, 0xc,
-    0xcb, 0x9b, 0xe1, 0x38, 0x42, 0xf1, 0xcd, 0x8f, 0x64, 0x3d, 0xd9, 0x4e,
-    0x82, 0x80, 0x3,  0x16, 0xb5, 0x25, 0xc6, 0x6b, 0x5e, 0xfc, 0x5a, 0x97,
-    0xe9, 0xa2, 0x24, 0x1e, 0xcd, 0x2d, 0xae, 0xca, 0x8,  0x4b, 0x29, 0x61,
-    0xd1, 0xe6, 0xd,  0xc3, 0x98, 0x12, 0xf5, 0x23, 0xf8, 0x54, 0xcd, 0x51,
-    0xec, 0x2e, 0x6c, 0x61, 0xdb, 0xa5, 0xaf, 0xf7, 0x48, 0x47, 0x27, 0x70,
-    0xb3, 0xf6, 0xa3, 0x6e, 0x9c, 0xfb, 0x32, 0xd1, 0x23, 0x29, 0xe7, 0x43,
-    0xa1, 0xa,  0x1,  0x3,  0xce, 0x45, 0x8d, 0x63, 0xd7, 0x23, 0x1d, 0xdb,
-    0x3c, 0x66, 0xf9, 0x1e, 0x4b, 0x7f, 0x7,  0x3e, 0xd2, 0xd6, 0xf4, 0xcb,
-    0xa2, 0x3a, 0xb2, 0x99, 0xd5, 0xc3, 0x53, 0x19, 0x79, 0xd9, 0x24, 0xe2,
-    0x3e, 0xbd, 0x9e, 0x5,  0x3a, 0xa9, 0x67, 0x2c, 0x85, 0xdb, 0xd7, 0x17,
-    0x9c, 0x59, 0xaa, 0xe6, 0x9f, 0x10, 0xb0, 0x2e, 0x20, 0x61, 0xcc, 0xf2,
-    0x18, 0x88, 0xd0, 0x1c, 0x52, 0xc8, 0xab, 0x8c, 0x7a, 0x49, 0xee, 0x97,
-    0x55, 0xf5, 0x48, 0x54, 0x4b, 0xbb, 0x11, 0xde, 0x8d, 0x26, 0x3f, 0x18,
-    0x68, 0x15, 0xa7, 0x4c, 0x5c, 0x23, 0xf2, 0x74, 0x59, 0x4e, 0xca, 0x61,
-    0x4c, 0x93, 0x7d, 0x84, 0x26, 0xf9, 0x13, 0x67, 0xc3, 0x76, 0xe5, 0x59,
-    0x96, 0xab, 0xb,  0x23, 0x53, 0xef, 0x5,  0xae, 0x1,  0x2f, 0xe,  0xe5,
-    0xc6, 0x2b, 0xc7, 0x73, 0xaa, 0x14, 0x48, 0xfe, 0x16, 0x97, 0xd5, 0xc8,
-    0xbb, 0xd1, 0xb7, 0x5f, 0x70, 0xcc, 0xce, 0x49, 0x1b, 0x5d, 0x1a, 0xbb,
-    0x6b, 0x93, 0xde, 0xdf, 0x98, 0x37, 0x9b, 0xcc, 0x4b, 0x35, 0xe0, 0xce,
-    0xcb, 0x77, 0x29, 0x1e, 0x4d, 0x23, 0x42, 0x97, 0xa0, 0x4f, 0x7b, 0x95,
-    0x44, 0x3d, 0x4f, 0x98, 0x32, 0x8,  0x77, 0xcd, 0xc5, 0x3f, 0xe5, 0xb6,
-    0xc5, 0xf4, 0x50, 0x29, 0x71, 0x79, 0xca, 0x65, 0x80, 0x8c, 0xa7, 0xdc,
-    0xcd, 0xbe, 0x57, 0x3a, 0xab, 0x75, 0x73, 0x38, 0x32, 0x20, 0x4b, 0xd8,
-    0xe8, 0xed, 0xf,  0x6f, 0x8b, 0x47, 0xb4, 0x1a, 0xc3, 0x4e, 0x3c, 0x27,
-    0xfc, 0x4a, 0x8a, 0xbd, 0x56, 0xe5, 0xc5, 0x6f, 0x47, 0x2e, 0xc1, 0x3e,
-    0xf5, 0x82, 0x9a, 0x36, 0xc,  0xd0, 0x68, 0x17, 0x43, 0x93, 0xb1, 0xb2,
-    0x11, 0xa0, 0x8f, 0xed, 0xc0, 0xca, 0x6c, 0x52, 0x92, 0x2e, 0x96, 0x86,
-    0x90, 0x0,  0x37, 0x18, 0xf5, 0x66, 0xee, 0xa1, 0x3,  0x95, 0x1e, 0x16,
-    0xa9, 0xe8, 0xce, 0xb4, 0x50, 0x16, 0x5b, 0xb0, 0x75, 0x8a, 0x99, 0xb0,
-    0x29, 0x52, 0x9d, 0x1d, 0xe2, 0xa5, 0xfe, 0x38, 0x56, 0x61, 0x22, 0xb5,
-    0x77, 0x9,  0xfc, 0x5f, 0x31, 0x2b, 0xa2, 0x83,
-};
-const uint8_t kAltGameImages1xC[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0xff, 0xe5, 0xb7, 0xbe,
-    0x33, 0xdd, 0x84, 0x73, 0x82, 0xc,  0xa1, 0x47, 0x40, 0x9f, 0x40, 0x4c,
-    0xda, 0x49, 0x65, 0xea, 0xd,  0xbe, 0xe2, 0x3e, 0xad, 0x5e, 0x7d, 0xf9,
-    0x74, 0xac, 0xe9, 0xfd, 0xf3, 0x6f, 0x3,  0x3f, 0xaf, 0x80, 0xf8, 0x6a,
-    0xdb, 0xcf, 0x1c, 0xc7, 0x93, 0x4,  0x9c, 0x1c, 0x66, 0xb8, 0xf2, 0x38,
-    0x54, 0xa3, 0x3f, 0x85, 0xf4, 0x6e, 0x2f, 0xa9, 0x3d, 0xe2, 0xd7, 0x3,
-    0xcc, 0x46, 0x13, 0x89, 0x85, 0xd1, 0xc6, 0xa2, 0xd4, 0x58, 0xb5, 0x4c,
-    0x2c, 0xfc, 0x76, 0x2c, 0x7a, 0x51, 0xb3, 0xc9, 0xd7, 0x33, 0xe0, 0x64,
-    0xd6, 0xfe, 0xab, 0xae, 0xaa, 0x72, 0x52, 0x91, 0xf1, 0x67, 0xfe, 0xd8,
-    0x63, 0xb4, 0xec, 0x50, 0xbd, 0xe1, 0xe7, 0x61, 0xfd, 0xfb, 0x69, 0x9d,
-    0x2d, 0xf2, 0xc1, 0x35, 0xed, 0x7a, 0x8e, 0x3b, 0x2e, 0xd9, 0x56, 0xf8,
-    0xf2, 0xd2, 0x4f, 0x10, 0x0,  0x57, 0x75, 0x96, 0xce, 0x4e, 0x70, 0x71,
-    0x7b, 0x98, 0x80, 0x7d, 0xe8, 0x51, 0xde, 0x79, 0xa0, 0xd9, 0xaa, 0xf3,
-    0x2,  0x20, 0xee, 0x9c, 0x75, 0x8,  0x44, 0x79, 0xf,  0xd9, 0x29, 0xba,
-    0x89, 0x2e, 0xac, 0x6f, 0xdf, 0xdd, 0x2d, 0x1a, 0xde, 0xf4, 0x7b, 0x52,
-    0x0,  0xc1, 0x19, 0x6d, 0xae, 0x93, 0x22, 0x53, 0x6d, 0xe0, 0xe1, 0x96,
-    0x8c, 0x6,  0xcb, 0x84, 0x73, 0xde, 0x37, 0xf7, 0x2d, 0xb,  0x8a, 0xca,
-    0x15, 0xd0, 0x46, 0xa7, 0x33, 0x32, 0xea, 0xfe, 0x64, 0x11, 0x6e, 0x90,
-    0x3b, 0xa,  0x81, 0x4,  0xbe, 0x1b, 0x13, 0x7a, 0xb3, 0xbe, 0x98, 0x35,
-    0x22, 0x99, 0x66, 0x75, 0x75, 0x87, 0x66, 0x4,  0x1c, 0xec, 0x8d, 0x90,
-    0xc3, 0xe4, 0x8c, 0x7f, 0x1e, 0x60, 0x18, 0xff, 0x2,  0x80, 0xdf, 0x21,
-    0x87, 0x32, 0x8,  0x71, 0xd3, 0xf5, 0xfa, 0x21, 0x10, 0x15, 0x38, 0x9a,
-    0xd9, 0x1a, 0x28, 0xae, 0xd5, 0xaf, 0xba, 0x40, 0xe9, 0xa5, 0x73, 0x48,
-    0xbf, 0xc,  0xf0, 0x60, 0xc0, 0x1f, 0x88, 0xa,  0x7d, 0x22, 0x57, 0x68,
-    0xff, 0x4e, 0xb,  0x4,  0x86, 0x80, 0x4d, 0x5a, 0x88, 0x4c, 0x54, 0xb7,
-    0x5b, 0x6d, 0x1c, 0xe5, 0xe8, 0xeb, 0x74, 0x20, 0xf6, 0x7e, 0x51, 0x44,
-    0x16, 0x1a, 0x9a, 0xe8, 0x11, 0x5c, 0xd0, 0xa,  0xf9, 0x58, 0xa0, 0xcf,
-    0x41, 0x98, 0x6a, 0x4d, 0x5b, 0x6b, 0xca, 0x9a, 0xe3, 0x2a, 0xd1, 0xe5,
-    0x74, 0xb6, 0xe1, 0x9b, 0xb9, 0x45, 0xdb, 0xeb, 0x15, 0x71, 0xdb, 0x29,
-    0x92, 0xc3, 0x9f, 0xdf, 0xb9, 0x7,  0x3f, 0x4f, 0xe9, 0x96, 0x11, 0x94,
-    0x5e, 0x40, 0x4b, 0x74, 0x2c, 0x9c, 0x8a, 0x5c, 0x44, 0x4d, 0x1c, 0x54,
-    0x47, 0x40, 0x4a, 0xa6, 0xdf, 0x43, 0x6b, 0xa1, 0x6a, 0x4d, 0xe4, 0x84,
-    0x7b, 0x18, 0x7f, 0x84, 0x76, 0x2f, 0xd6, 0x57, 0x70, 0xe1, 0xa,  0xf6,
-    0xb5, 0xc6, 0xe2, 0xf7, 0x31, 0x4f, 0xde, 0xa4, 0x2c, 0x35, 0x33, 0xb1,
-    0x77, 0x39, 0xb7, 0xac, 0xe5, 0xf6, 0x59, 0x74, 0x7,  0xb9, 0x8,  0xf9,
-    0x5c, 0x9e, 0x13, 0x7,  0x23, 0x81, 0x60, 0xf9, 0xa,  0xf3, 0x41, 0xbb,
-    0x8a, 0x72, 0xdb, 0x99, 0x47, 0x4a, 0x86, 0xc0, 0x9,  0x8f, 0xf9, 0x8a,
-    0xf5, 0xdf, 0x73, 0x34, 0xa9, 0x88, 0xf6, 0x79, 0x12, 0xbe, 0x50, 0xc5,
-    0x4,  0x79, 0x35, 0x24, 0xe9, 0x71, 0x4f, 0xef, 0x13, 0xeb, 0x54, 0x94,
-    0x9c, 0x20, 0x68, 0x81, 0xa9, 0x33, 0xac, 0xe6, 0xa7, 0x4b, 0x3f, 0x52,
-    0x67, 0xab, 0x1a, 0xd6, 0x78, 0x2b, 0xd0, 0x8d, 0x98, 0x2f, 0x90, 0xaa,
-    0xe5, 0x80, 0x5d, 0x1f, 0xa9, 0x33, 0x7,  0x5a, 0xe5, 0x2d, 0x5a, 0xa2,
-    0x28, 0x84, 0x83, 0x7,  0xb7, 0xfd, 0x84, 0xc7, 0x6d, 0x53, 0xd4, 0x46,
-    0xc2, 0xc6, 0x24, 0xbe, 0xe2, 0x25, 0xcf, 0x24, 0x5b, 0x3e, 0x39, 0xcb,
-    0xbb, 0x7a, 0x3b, 0x2e, 0xc,  0x92, 0x68, 0x30, 0xa6, 0xe0, 0x69, 0xd5,
-    0x1d, 0x6c, 0x95, 0x7b, 0xe2, 0x48, 0x10, 0xed, 0x1e, 0xbd, 0x10, 0x14,
-    0x25, 0x41, 0xd7, 0x1b, 0xf2, 0x74, 0x12, 0x2c, 0x17, 0xd6, 0x36, 0x65,
-    0x1,  0x3e, 0x87, 0x11, 0x90, 0x8e, 0x12, 0x71, 0xb2, 0xd1, 0x37, 0xda,
-    0xa2, 0x5d, 0x80, 0x64, 0x32, 0x8e, 0x37, 0x3a, 0x8e, 0x4c, 0xbb, 0x40,
-    0xe3, 0x1a, 0x73, 0x83, 0xb0, 0x82, 0x2d, 0x5e, 0x48, 0x20, 0xd2, 0xaf,
-    0x0,  0x55, 0xff, 0x56, 0x7e, 0x8e, 0xb3, 0x6b, 0xc4, 0x11, 0x40, 0x17,
-    0x25, 0x76, 0x35, 0xc,  0x9d, 0x3d, 0xe2, 0xea, 0x7,  0xec, 0xe2, 0xe3,
-    0xd4, 0x10, 0xda, 0xf6, 0xb5, 0xe8, 0xf6, 0x7a, 0xb7, 0xe1, 0x38, 0x65,
-    0x27, 0x97, 0x2b, 0x5a, 0x4,  0x1b, 0xd2, 0x21, 0xea, 0x5b, 0x9f, 0x5b,
-    0xdf, 0xca, 0xd1, 0xad, 0x47, 0x25, 0xd,  0xed, 0xbb, 0xca, 0x6d, 0x45,
-    0x29, 0x6d, 0xb7, 0xef, 0x70, 0x2b, 0x79, 0xc2, 0x29, 0x83, 0x75, 0xdb,
-    0xa5, 0x60, 0xcd, 0x6f, 0x1a, 0xd4, 0xad, 0x6f, 0x8a, 0x51, 0xfb, 0x92,
-    0x62, 0xd4, 0x97, 0x41, 0x8a, 0xb8, 0x79, 0x2a, 0x95, 0x14, 0x9,  0x95,
-    0x6b, 0x7f, 0xf,  0xfb, 0xf5, 0x0,  0xf,  0x25, 0xc3, 0x81, 0xb,  0x81,
-    0xa3, 0x5e, 0x29, 0xc5, 0x9c, 0xd1, 0x45, 0xff, 0xfc, 0x80, 0x24, 0x75,
-    0xa1, 0x33, 0xd5, 0x6e, 0x8b, 0x85, 0x39, 0x93, 0x8f, 0x7c, 0xd0, 0x7e,
-    0x39, 0xde, 0xdf, 0x93, 0x28, 0x4f, 0xf3, 0xe6, 0x41, 0xcf, 0x85, 0x32,
-    0x82, 0xe5, 0x65, 0x52, 0xff, 0x37, 0x79, 0x54, 0x2,  0x47, 0x63, 0x1a,
-    0xd4, 0xf0, 0xcf, 0x5,  0x11, 0xbd, 0x8c, 0x4,  0x47, 0xfe, 0xa2, 0x34,
-    0x32, 0xda, 0x82, 0xfd, 0xe6, 0x3f, 0x7a, 0x1c, 0x5c, 0x43, 0x6d, 0x4c,
-    0xa2, 0xad, 0x33, 0x15, 0x2d, 0xd4, 0xbd, 0xdf, 0x97, 0xa2, 0x1a, 0x3b,
-    0x89, 0x3c, 0xd5, 0x19, 0x7d, 0x24, 0x13, 0xa,  0xeb, 0xd7, 0x66, 0x79,
-    0xc5, 0x61, 0xea, 0x4c, 0x2d, 0x6d, 0xca, 0xea, 0x81, 0x81, 0x29, 0x88,
-    0xaf, 0xcd, 0x3b, 0xff, 0xba, 0x1a, 0xe6, 0x60, 0x8,  0xdb, 0x17, 0x3e,
-    0x37, 0xc2, 0xb8, 0x39, 0x91, 0x18, 0x74, 0xa4, 0xe0, 0x5f, 0xf1, 0x8d,
-    0x7d, 0x30, 0x7d, 0xac, 0x3a, 0x2b, 0x80, 0x4e, 0x7e, 0xe0, 0x25, 0x39,
-    0xeb, 0x0,  0xe1, 0x52, 0xe1, 0xa1, 0x31, 0x2d, 0x3c, 0xf1, 0xe3, 0xfd,
-    0xa3, 0xf6, 0x3,  0xec, 0xf3, 0x0,  0x7a, 0x55, 0xe3, 0x21, 0x19, 0xea,
-    0x5a, 0xb5, 0x7b, 0xc9, 0xdb, 0xa5, 0x3b, 0x9e, 0x62, 0xd5, 0x2f, 0x2a,
-    0xbb, 0xae, 0x86, 0x61, 0xff, 0x45, 0x91, 0xce, 0x92, 0x51, 0x24, 0x8b,
-    0x9c, 0x49, 0x2a, 0xbd, 0xa4, 0x54, 0x80, 0xa6, 0xe6, 0x88, 0xe,  0x40,
-    0x95, 0xe4, 0x9e, 0xd0, 0xd3, 0x42, 0x3b, 0xda, 0xe5, 0xf,  0x11, 0x0,
-    0x55, 0x69, 0xe1, 0xba, 0x65, 0x1a, 0x6f, 0x9f, 0x64, 0x76, 0xdc, 0xa5,
-    0xc6, 0x32, 0xe8, 0x80, 0x6d, 0x10, 0xa7, 0x21, 0xdf, 0x35, 0xb1, 0xbe,
-    0x2c, 0xf9, 0xa6, 0xcc, 0x2e, 0xe5, 0xeb, 0x6c, 0x10, 0xf7, 0x85, 0xd9,
-    0xac, 0xd3, 0x4c, 0x5c, 0xe5, 0xc0, 0x3b, 0xcf, 0x27, 0x8f, 0xde, 0xc2,
-    0x4e, 0xd6, 0x94, 0x58, 0xea, 0x37, 0xaa, 0x3b, 0x21, 0x38, 0x1e, 0x5d,
-    0x3d, 0xa7, 0xe3, 0x3c, 0x5e, 0x2b, 0x45, 0x81, 0x22, 0x55, 0x66, 0xcf,
-    0xfd, 0x5b, 0xec, 0xc6, 0xd1, 0x9f, 0xa9, 0x4c, 0x4,  0xe4, 0x33, 0x36,
-    0xa3, 0xd6, 0x4d, 0x8c, 0xd3, 0xe9, 0xe9, 0x5c, 0xc2, 0xff, 0x75, 0x2c,
-    0x4c, 0x87, 0x4f, 0x6b, 0xb9, 0x96, 0xa,  0x8c, 0x4d, 0x44, 0x8,  0x9e,
-    0x3d, 0x2f, 0x8,  0xca, 0x84, 0x33, 0x38, 0x2a, 0xcf, 0xf,  0x69, 0xe,
-    0x2d, 0xd3, 0xad, 0x2d, 0xe,  0xdb, 0x79, 0x6c, 0x85, 0xf2, 0x13, 0xc8,
-    0xf2, 0x97, 0x7e, 0x8d, 0x40, 0xb6, 0x10, 0x52, 0x58, 0xd0, 0xec, 0x50,
-    0xc7, 0x38, 0x68, 0xad, 0xfb, 0x27, 0xb6, 0xde, 0x96, 0x8c, 0x4,  0x97,
-    0xb1, 0x39, 0x6c, 0x1b, 0xe8, 0xfb, 0x4b, 0x37, 0xc2, 0xa4, 0x61, 0xc8,
-    0x71, 0xee, 0x49, 0x8c, 0x12, 0x59, 0xbf, 0x46, 0x78, 0xe,  0x8d, 0x4d,
-    0xd5, 0x1c, 0x57, 0x1c, 0x38, 0x2,  0xd2, 0x1b, 0x8a, 0xe3, 0x7b, 0x65,
-    0x1e, 0xf8, 0x77, 0xa0, 0xb4, 0xbd, 0x1a, 0x29, 0xee, 0x8b, 0xc2, 0xa5,
-    0x34, 0x82, 0x44, 0x9c, 0x4a, 0x7f, 0xc1, 0x28, 0x9e, 0xc6, 0x42, 0xca,
-    0xaf, 0xeb, 0x19, 0xd7, 0x77, 0xf1, 0x60, 0xfa, 0x17, 0xf,  0x82, 0x97,
-    0xcd, 0xe0, 0x11, 0x56, 0xe0, 0x85, 0x8a, 0x5f, 0xc,  0x1d, 0xe6, 0x66,
-    0x2b, 0xfe, 0x3f, 0x42, 0x45, 0x91, 0x1c, 0xda, 0xf3, 0xe2, 0xea, 0x4b,
-    0xe5, 0x18, 0x3a, 0xb2, 0x2b, 0x5f, 0x3e, 0x74, 0x97, 0xff, 0x4e, 0x95,
-    0xbc, 0xa6, 0x66, 0x24, 0xb5, 0x15, 0x18, 0xd8, 0x2e, 0x33, 0x12, 0x27,
-    0x16, 0xa2, 0xe5, 0x3d, 0xf,  0x38, 0xc3, 0x75, 0x40, 0xc,  0x94, 0x67,
-    0x65, 0xf,  0x6b, 0x78, 0x69, 0xa1, 0x61, 0xb7, 0xf,  0xf2, 0x61, 0x29,
-    0x83, 0x4e, 0x34, 0xc6, 0xc0, 0x3b, 0xe8, 0x5d, 0x8c, 0x81, 0xe4, 0x81,
-    0x18, 0xdf, 0x3c, 0xd1, 0x6e, 0x7e, 0x7c, 0xf3, 0x76, 0xb4, 0x79, 0x49,
-    0x7,  0xc1, 0x83, 0xb6, 0x86, 0x26, 0x70, 0x57, 0x2,  0xfc, 0xa1, 0xcc,
-    0xa6, 0x4b, 0xac, 0x7e, 0x9e, 0x3c, 0xf,  0xa7, 0xe4, 0xb,  0x58, 0xcb,
-    0x13, 0xb7, 0x4,  0xec, 0xd2, 0xa8, 0xb2, 0x53, 0x32, 0x2c, 0x8a, 0x70,
-    0xfb, 0xec, 0xa4, 0xde, 0xf3, 0xbd, 0x4b, 0xbd, 0x86, 0x72, 0x96, 0x4b,
-    0x94, 0x8c, 0x5a, 0x47, 0x4a, 0x46, 0xda, 0xb9, 0xe,  0x16, 0x63, 0x85,
-    0x9f, 0xdf, 0xa4, 0xef, 0x82, 0x78, 0x68, 0x0,  0xd7, 0x4f, 0x2,  0x37,
-    0x67, 0x7a, 0x33, 0x51, 0x3f, 0xd6, 0x29, 0x99, 0xa3, 0x63, 0x7,  0x82,
-    0x2b, 0x12, 0xe5, 0xa0, 0xb6, 0x2a, 0xc4, 0x28, 0xee, 0xac, 0xd2, 0xd2,
-    0x39, 0x62, 0x37, 0xf6, 0x3e, 0x91, 0xd1, 0x14, 0x89, 0xea, 0x52, 0xc8,
-    0x62, 0xc7, 0xb,  0x9f, 0x9b, 0x81, 0x9d, 0x18, 0x1e, 0x3f, 0x70, 0x5b,
-    0x6c, 0x34, 0x33, 0x21, 0x23, 0xba, 0x6f, 0xed, 0x28, 0x63, 0x53, 0x4,
-    0x72, 0x85, 0xa3, 0x16, 0xc0, 0xd2, 0x81, 0xfe, 0x67, 0x22, 0x3,  0x9,
-    0xd8, 0xbf, 0x94, 0x4,  0x6c, 0xc4, 0x43, 0x27, 0x5d, 0x36, 0xe0, 0x6d,
-    0x4e, 0xec, 0xa5, 0x54, 0xb4, 0x7d, 0xd4, 0xb0, 0xce, 0x47, 0x67, 0x8c,
-    0x81, 0x19, 0x42, 0x48, 0x83, 0x43, 0x3c, 0x14, 0xe8, 0x41, 0xd,  0xe,
-    0xa7, 0xdc, 0xa7, 0x7e, 0x78, 0x6d, 0xe3, 0xc3, 0x9c, 0xf0, 0xb8, 0xf6,
-    0x16, 0xc7, 0xfd, 0xef, 0xe2, 0x59, 0xc,  0xda, 0x46, 0x58, 0x6a, 0x33,
-    0xdf, 0x4d, 0xc7, 0x1b, 0x89, 0xca, 0xd3, 0xe1, 0xc6, 0x24, 0xcf, 0x83,
-    0x99, 0xa4, 0xf4, 0xd2, 0x55, 0xff, 0x47, 0x94, 0xfe, 0xb2, 0xdc, 0x6f,
-    0xb7, 0x47, 0x3b, 0xfc, 0xdc, 0xa2, 0x92, 0x87, 0xbc, 0xc0, 0x15, 0x6,
-    0xbf, 0xd0, 0x99, 0xa4, 0x2b, 0x38, 0xdb, 0xae, 0xe,  0x77, 0x9c, 0xa1,
-    0xc,  0x76, 0xec, 0xbf, 0x34, 0x9f, 0x8f, 0x11, 0xc8, 0xb9, 0x6e, 0xf5,
-    0xdf, 0xf0, 0x47, 0x1e, 0xf0, 0x8e, 0x41, 0x1b, 0xb5, 0x85, 0xdd, 0x50,
-    0xf6, 0xdf, 0x84, 0x8e, 0x8c, 0x4,  0x9e, 0x1c, 0x7,  0xe3, 0x70, 0x37,
-    0xc2, 0xb2, 0x6f, 0x9a, 0x4f, 0xb7, 0x92, 0xcf, 0xc2, 0x51, 0x5f, 0xd4,
-    0x7,  0xc,  0xc5, 0x61, 0x1b, 0x6a, 0x2e, 0x4c, 0x76, 0x78, 0x69, 0x47,
-    0x97, 0x0,  0xa,  0x5,  0x3e, 0xef, 0xeb, 0x25, 0xd9, 0x3e, 0x17, 0xf7,
-    0x98, 0xea, 0xc,  0xa7, 0x14, 0x5,  0x1f, 0x21, 0x4a, 0x21, 0xef, 0x36,
-    0x95, 0xcd, 0xed, 0xda, 0x95, 0x69, 0x7f, 0x62, 0x7e, 0x6c, 0xb4, 0x89,
-    0x54, 0xe9, 0x95, 0x0,  0x1d, 0xa4, 0xa1, 0x18, 0xfb, 0x35, 0xf6, 0x3b,
-    0xe0, 0x2a, 0x3f, 0x86, 0x6e, 0x21, 0xc7, 0xb5, 0x2c, 0xa4, 0x8c, 0xc,
-    0x87, 0xb6, 0xb7, 0x1c, 0xa,  0xf6, 0x4a, 0x47, 0x88, 0x18, 0x88, 0x5,
-    0x1e, 0x40, 0xee, 0xe9, 0xc3, 0x10, 0x9c, 0x9a, 0xd5, 0xdb, 0x8b, 0x13,
-    0xa8, 0x24, 0x5c, 0xd0, 0xc9, 0x29, 0x3f, 0xa,  0x90, 0x6d, 0x92, 0x7d,
-    0x24, 0xad, 0x64, 0x7f, 0xf1, 0x6,  0x7e, 0x31, 0xb8, 0x7,  0xac, 0x8d,
-    0xf7, 0x50, 0x46, 0x79, 0x63, 0x50, 0xa4, 0x66, 0xb3, 0x86, 0xa0, 0xb2,
-    0xa4, 0x29, 0x66, 0x13, 0x1f, 0xea, 0x9b, 0x12, 0xf1, 0x13, 0x31, 0x18,
-    0x3c, 0x4c, 0x2d, 0xff, 0x29, 0xe5, 0x27, 0xb3, 0xcf, 0xcc, 0xfe, 0x21,
-    0xde, 0x54, 0xc5, 0xcf, 0xdd, 0x4f, 0x28, 0x7e, 0x7a, 0xcb, 0x8,  0x4f,
-    0x84, 0x9b, 0xb4, 0x91, 0x28, 0x2c, 0x67, 0xee, 0xfd, 0xed, 0x58, 0xc0,
-    0xda, 0xc5, 0x23, 0xed, 0xd7, 0xa0, 0x68, 0xf4, 0xc7, 0xd0, 0xd9, 0x33,
-    0xa2, 0xd5, 0x78, 0x94, 0x91, 0x1f, 0x12, 0x12, 0xef, 0x8f, 0xdd, 0xd0,
-    0x77, 0x6c, 0x50, 0xd7, 0xd5, 0x1b, 0xde, 0x2,  0xaf, 0x63, 0x91, 0xb5,
-    0xce, 0xa2, 0x2c, 0x35, 0xf0, 0x21, 0xf3, 0xca, 0x3a, 0xe2, 0xc8, 0xa3,
-    0x8d, 0x10, 0x95, 0x40, 0xfb, 0x2f, 0xbd, 0x50, 0x93, 0x8b, 0xa2, 0x75,
-    0x82, 0xcd, 0xf8, 0x8f, 0x42, 0x64, 0x1a, 0xed, 0x59, 0x8c, 0xb1, 0x86,
-    0xb6, 0xc8, 0x99, 0xed, 0x13, 0x86, 0x9,  0xfd, 0x2d, 0x21, 0x51, 0x90,
-    0xac, 0x34, 0x2f, 0xe5, 0x2d, 0xb,  0xbc, 0xec, 0x99, 0x45, 0xde, 0xef,
-    0xb2, 0xfd, 0xca, 0xc5, 0xdc, 0x47, 0xb2, 0xd6, 0xf6, 0x13, 0x4,  0x16,
-    0x50, 0x1c, 0xf7, 0x24, 0xc7, 0xb4, 0x75, 0xdf, 0x21, 0x26, 0xbb, 0x41,
-    0x8c, 0x4f, 0xe,  0xaa, 0x5c, 0x3a, 0x5f, 0xa4, 0x31, 0x58, 0xab, 0x58,
-    0xb9, 0xce, 0x8,  0x32, 0xa0, 0xbc, 0xbc, 0x7f, 0x6,  0x75, 0x65, 0xed,
-    0x2d, 0x9,  0x9b, 0xbe, 0xea, 0xf9, 0x21, 0x5d, 0xca, 0x1d, 0x98, 0x8c,
-    0xc0, 0x50, 0xf4, 0x91, 0xec, 0x54, 0xf,  0xe7, 0x34, 0x67, 0x5f, 0x41,
-    0xbf, 0x60, 0xd8, 0xcf, 0x37, 0xc0, 0x5f, 0x46, 0x9e, 0x2b, 0x3c, 0xda,
-    0xcf, 0x1,  0x24, 0xd3, 0xe9, 0x49, 0x3f, 0x64, 0x5b, 0x41, 0xe4, 0x3f,
-    0x7c, 0xb0, 0xad, 0xf,  0xe7, 0x90, 0x32, 0x65, 0xd0, 0x46, 0xb9, 0x55,
-    0x22, 0xdb, 0xc0, 0xdf, 0xce, 0x63, 0x9b, 0xbe, 0xc9, 0xf9, 0x6b, 0x35,
-    0x63, 0x75, 0xc3, 0x80, 0x6d, 0x66, 0xaf, 0x3b, 0x8a, 0x1e, 0x55, 0x74,
-    0x23, 0xbc, 0xb9, 0x6b, 0x72, 0x8,  0x19, 0xa,  0x8b, 0x73, 0xc1, 0x92,
-    0x34, 0x1,  0xba, 0x3b, 0xa4, 0xa2, 0x76, 0x2a, 0x35, 0xd6, 0xe0, 0x16,
-    0xa8, 0x7f, 0xa8, 0xdc, 0xf,  0x93, 0x85, 0x8b, 0xc9, 0xa7, 0x98, 0x2a,
-    0xf9, 0x91, 0x9a, 0x2a, 0x50, 0x2,  0x7e, 0x44, 0xa8, 0x10, 0xc5, 0x93,
-    0x1b, 0xbe, 0xb1, 0xa7, 0x45, 0x3c, 0xb4, 0x5e, 0xe0, 0x4f, 0x39, 0x48,
-    0xa3, 0x74, 0x2,  0x6d, 0xc7, 0x1a, 0x79, 0xb5, 0x8b, 0xb7, 0x14, 0x88,
-    0x4c, 0xaf, 0x64, 0x3f, 0x70, 0xf8, 0xb6, 0xa0, 0xcc, 0x2,  0xd6, 0x75,
-    0xfc, 0x75, 0x72, 0x12, 0x9d, 0x27, 0x1d, 0x75, 0x33, 0x25, 0xb1, 0x14,
-    0xc,  0x66, 0xc6, 0x7a, 0x9e, 0xde, 0x26, 0xbb, 0x6e, 0xe,  0x25, 0xd2,
-    0xf1, 0xe6, 0x8d, 0x85, 0x64, 0x75, 0xb7, 0xe8, 0x96, 0x84, 0xe,  0x8f,
-    0x25, 0x24, 0x12, 0x41, 0x52, 0xdb, 0xa6, 0x7,  0x44, 0x60, 0x91, 0xd1,
-    0xee, 0x9e, 0x19, 0x4c, 0xfc, 0x4a, 0x69, 0x97, 0x27, 0xc1, 0x7c, 0x32,
-    0x19, 0x4b, 0x21, 0xe5, 0xc7, 0x38, 0x42, 0x86, 0x90, 0x47, 0x5c, 0xdc,
-    0x73, 0xff, 0x5f, 0xba, 0xc1, 0xf4, 0x26, 0xa0, 0x38, 0xa5, 0xdb, 0x41,
-    0x76, 0x49, 0x5,  0x58, 0xa8, 0xe8, 0xf9, 0x6,  0x57, 0x6d, 0xd4, 0x8e,
-    0x86, 0x5a, 0xc1, 0xd8, 0x8f, 0x7b, 0xa6, 0x4b, 0xe5, 0xff, 0xd7, 0x6c,
-    0x4d, 0x9f, 0x51, 0xa9, 0xdf, 0xe9, 0xe6, 0x91, 0xf,  0xe9, 0x13, 0xd1,
-    0x7e, 0x28, 0x67, 0x1b, 0xb0, 0xac, 0x88, 0x25, 0xc3, 0x17, 0x6c, 0xde,
-    0x6e, 0x88, 0xa8, 0x65, 0xb8, 0xd5, 0xf0, 0x40, 0x85, 0xc4, 0x52, 0x79,
-    0x8c, 0x19, 0xe7, 0x33, 0x3a, 0x76, 0x34, 0x2d, 0x4c, 0x77, 0xc1, 0x3,
-    0xc0, 0x11, 0xc1, 0x2f, 0x9c, 0xa0, 0x19, 0x51, 0x5f, 0x5,  0x9e, 0xfe,
-    0x3b, 0x88, 0x5f, 0x59, 0x24, 0xb9, 0x8,  0x97, 0x44, 0xee, 0x56, 0xa8,
-    0x12, 0xd6, 0x80, 0x9c, 0x51, 0xa3, 0x12, 0xaf, 0x47, 0xc4, 0x73, 0x8b,
-    0x55, 0xc0, 0x4b, 0xe7, 0xf0, 0x4,  0x47, 0xeb, 0x5e, 0xad, 0xee, 0x64,
-    0x83, 0xcd, 0xaa, 0x9,  0x57, 0x8f, 0x9,  0xae, 0x31, 0x70, 0x90, 0x49,
-    0x61, 0xd7, 0x7,  0xf4, 0x8,  0xb0, 0xe9, 0xff, 0xfe, 0x8f, 0x9c, 0x6f,
-    0xf7, 0x3,  0x11, 0xf5, 0x74, 0xe4, 0xd3, 0x84, 0xf6, 0x10, 0x58, 0xdf,
-    0x17, 0xc9, 0x2e, 0x30, 0xcd, 0x1b, 0xe4, 0xab, 0x53, 0x43, 0x13, 0xb8,
-    0x49, 0x54, 0x7a, 0xd9, 0xe7, 0xc8, 0xe7, 0xa9, 0xe1, 0xb6, 0x87, 0xa6,
-    0x45, 0xcb, 0x5d, 0x21, 0xd7, 0xa4, 0x37, 0xc,  0x95, 0x70, 0xd8, 0x11,
-    0x15, 0x41, 0x3a, 0xee, 0x92, 0xe7, 0xfc, 0x9,  0x19, 0x18, 0xcc, 0xe0,
-    0x85, 0x2f, 0x55, 0xe5, 0x7d, 0x5e, 0x33, 0x3a, 0x21, 0x2c, 0xa5, 0x95,
-    0x95, 0xc8, 0x55, 0xe4, 0x21, 0x18, 0x43, 0xb7, 0x98, 0x4,  0x6d, 0xb4,
-    0x3a, 0x87, 0x5f, 0xc9, 0xc0, 0x6c, 0xf5, 0x2a, 0x7c, 0xb4, 0xd5, 0x16,
-    0x63, 0x5c, 0xed, 0xb3, 0x82, 0xf6, 0x71, 0x2d, 0xd5, 0x82, 0x28, 0x5c,
-    0x7f, 0x2e, 0x1a, 0xdd, 0xa5, 0x22, 0x89, 0x77, 0x3a, 0xba, 0x30, 0xa6,
-    0x1c, 0xb3, 0x2,  0x64, 0x52, 0xf8, 0xd9, 0x6f, 0xd0, 0xab, 0xbe, 0x39,
-    0x65, 0xb6, 0x5e, 0x51, 0x28, 0xec, 0x4,  0xc,  0x66, 0x7,  0x73, 0xc4,
-    0x74, 0xe3, 0xc4, 0xb0, 0x7e, 0x97, 0x4d, 0xe4, 0x4c, 0x83, 0x5a, 0x61,
-};
-const uint8_t kAltGameImages1xD[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0xff, 0xe5, 0xb7, 0xbe,
-    0x33, 0xdd, 0x84, 0x73, 0x82, 0xc,  0xa1, 0x47, 0x40, 0x9f, 0x40, 0x4c,
-    0x94, 0x23, 0x34, 0xaa, 0x29, 0xa0, 0x98, 0xd7, 0xc3, 0x15, 0xf2, 0xab,
-    0xe,  0xc2, 0x5c, 0xff, 0x19, 0xeb, 0xa6, 0x5a, 0x79, 0x8d, 0xd7, 0x68,
-    0xd2, 0x75, 0xc2, 0x4a, 0xc3, 0x9d, 0xd1, 0xba, 0xaf, 0x15, 0x12, 0xeb,
-    0x87, 0xab, 0xc2, 0xaf, 0x45, 0xa3, 0x15, 0x8f, 0x47, 0x85, 0x13, 0xfc,
-    0xb2, 0x90, 0x5,  0xac, 0x30, 0xa0, 0x6b, 0x93, 0xb5, 0x93, 0xcb, 0x4b,
-    0x8c, 0xb9, 0x30, 0x56, 0x57, 0xa0, 0xfb, 0xba, 0x1e, 0xfb, 0x46, 0xac,
-    0xe5, 0xa1, 0x7b, 0xf1, 0xf4, 0xfd, 0xf7, 0x92, 0xa3, 0x38, 0x5,  0x4a,
-    0x2b, 0x67, 0x91, 0xd,  0x48, 0xf6, 0x5a, 0xf,  0x68, 0xeb, 0xb4, 0xfa,
-    0x12, 0xd,  0x6d, 0x62, 0x3c, 0xcc, 0x92, 0x40, 0x5a, 0x74, 0x2f, 0xad,
-    0xf0, 0x18, 0x66, 0x71, 0xc7, 0xcd, 0xd3, 0xde, 0x7b, 0x56, 0x53, 0x95,
-    0x5,  0xae, 0x8,  0x44, 0xe2, 0xe0, 0xfd, 0x6c, 0x6f, 0xa0, 0xc1, 0x81,
-    0xcf, 0x45, 0x41, 0x90, 0x7,  0x1,  0xd9, 0x74, 0x2c, 0x5,  0x56, 0x98,
-    0x2e, 0x82, 0x89, 0xeb, 0xfc, 0xe,  0xd3, 0x14, 0x96, 0x38, 0xe0, 0x85,
-    0xac, 0x77, 0xf,  0x2e, 0xdc, 0xaf, 0x8f, 0x19, 0xa2, 0x31, 0x72, 0xe9,
-    0xe3, 0xc1, 0x8e, 0xb9, 0xff, 0x7d, 0xb9, 0x28, 0x8d, 0x3d, 0x51, 0xeb,
-    0x43, 0xef, 0x4c, 0x0,  0xde, 0xb8, 0x36, 0xe8, 0x2e, 0xcb, 0x39, 0xba,
-    0xcd, 0x93, 0x8d, 0x5,  0xf,  0x6f, 0xab, 0xe6, 0xbe, 0xaf, 0x40, 0xab,
-    0xf8, 0x7b, 0x7e, 0x4,  0x90, 0x8,  0xbd, 0x2e, 0x13, 0x3d, 0x8a, 0x8,
-    0xf,  0x96, 0x8f, 0xfd, 0x20, 0xc7, 0x21, 0x36, 0x66, 0x4c, 0x67, 0x66,
-    0xa1, 0x88, 0x80, 0x14, 0x8b, 0xb4, 0x4a, 0x8,  0x6c, 0x5c, 0x84, 0xa8,
-    0x5c, 0x22, 0x0,  0x31, 0x60, 0x77, 0x96, 0xda, 0x99, 0xe4, 0x24, 0x6f,
-    0xd2, 0xb4, 0x2a, 0xe,  0x69, 0xa8, 0x13, 0x13, 0x4e, 0x7f, 0xed, 0xdb,
-    0x26, 0x35, 0xaa, 0x34, 0x38, 0x16, 0xbb, 0x1,  0x7c, 0x25, 0x28, 0x13,
-    0xbb, 0x28, 0x8a, 0xdd, 0x9b, 0xfc, 0x71, 0xa9, 0xb6, 0x92, 0xc5, 0x3b,
-    0x14, 0xae, 0xdc, 0xf0, 0x7,  0x14, 0x70, 0xaf, 0xd6, 0xf7, 0xb4, 0x22,
-    0x4a, 0x7e, 0x16, 0x76, 0x63, 0x48, 0xb5, 0xdd, 0xec, 0x1,  0xa,  0x97,
-    0xab, 0xb,  0x52, 0x7e, 0xeb, 0x76, 0x3e, 0xbb, 0xd5, 0x9e, 0x4f, 0xe1,
-    0x84, 0x6d, 0x31, 0xcc, 0x10, 0x2a, 0xd5, 0x8a, 0xea, 0x43, 0x1e, 0xe5,
-    0x8f, 0xa7, 0x3f, 0x9c, 0xfb, 0x1e, 0xc2, 0xd2, 0xb4, 0xa1, 0x4a, 0x42,
-    0xdf, 0x82, 0x5,  0x76, 0xbb, 0xd5, 0x14, 0x10, 0xf2, 0xd9, 0x6f, 0xca,
-    0x7f, 0x61, 0x78, 0x2d, 0xf2, 0x75, 0xbb, 0x47, 0x6e, 0x1d, 0xe4, 0xc,
-    0xe7, 0xdf, 0x5,  0x1c, 0x68, 0x51, 0xf,  0xc6, 0x8,  0xcc, 0xbd, 0xe7,
-    0x82, 0x26, 0xc3, 0x8b, 0xa2, 0x3a, 0xda, 0x12, 0x8,  0xef, 0xdd, 0x89,
-    0x48, 0xb9, 0x59, 0xca, 0x91, 0xd4, 0xe0, 0x53, 0xff, 0xb8, 0xb6, 0x2e,
-    0xc5, 0xa7, 0x35, 0x8d, 0x24, 0x30, 0xe3, 0x81, 0x94, 0x1a, 0xe8, 0xe6,
-    0x30, 0x56, 0x1,  0xe1, 0x22, 0x8e, 0x10, 0x78, 0x2e, 0x9c, 0x79, 0x6f,
-    0x6c, 0xa7, 0xa1, 0x50, 0xfe, 0xe8, 0xc4, 0x31, 0x1a, 0xa7, 0xb5, 0x62,
-    0x9c, 0xff, 0xf,  0x1e, 0x3c, 0x5c, 0x3a, 0x2a, 0xce, 0x3e, 0xb,  0xcf,
-    0x2b, 0xfa, 0xfa, 0x40, 0x7b, 0x86, 0xbd, 0xf1, 0xed, 0xa7, 0x6f, 0x9e,
-    0xde, 0xc8, 0xaf, 0xd6, 0x5f, 0x1c, 0x75, 0xb7, 0xb8, 0x27, 0xca, 0x67,
-    0xe1, 0xee, 0x52, 0x73, 0x48, 0xb7, 0xd5, 0x4a, 0xa7, 0x9b, 0x1f, 0x3,
-    0xbf, 0x6e, 0x17, 0x18, 0xb9, 0xed, 0xa3, 0x28, 0xf9, 0x1d, 0x42, 0x97,
-    0x5,  0x9a, 0x1b, 0x7c, 0xc2, 0x55, 0xa9, 0xdc, 0x16, 0x1a, 0xdb, 0x81,
-    0x4e, 0x21, 0xa5, 0x66, 0x69, 0x1d, 0xcf, 0x7c, 0x43, 0x66, 0xc5, 0x96,
-    0xcd, 0xd,  0xf8, 0x25, 0x19, 0x90, 0xfe, 0x1d, 0x99, 0x22, 0x93, 0x9,
-    0x54, 0xe8, 0xa2, 0x36, 0x1d, 0x4d, 0xe9, 0x86, 0xe1, 0xa8, 0x45, 0x3b,
-    0xb6, 0x17, 0x38, 0x39, 0xbd, 0xc7, 0xed, 0x87, 0xcf, 0xa4, 0xec, 0x4e,
-    0x12, 0x7c, 0xe,  0x36, 0x1a, 0x95, 0xd7, 0xe3, 0xe8, 0xd4, 0xb5, 0x83,
-    0x50, 0xfd, 0x7d, 0xfd, 0x22, 0xcd, 0x72, 0x26, 0x55, 0x75, 0x86, 0x70,
-    0xdb, 0xd6, 0x18, 0x10, 0x6b, 0x12, 0x27, 0xce, 0xa4, 0x92, 0x69, 0xdf,
-    0xa2, 0xcb, 0xaa, 0x48, 0x99, 0xd6, 0xd2, 0xe1, 0x7b, 0xd6, 0xf5, 0x97,
-    0x54, 0x26, 0xc1, 0xe5, 0xba, 0xb9, 0x5e, 0x15, 0x26, 0xd6, 0x1d, 0x84,
-    0xa6, 0xdf, 0x54, 0xb6, 0x9f, 0x9c, 0x2,  0x7,  0x5e, 0x12, 0xad, 0x9a,
-    0x68, 0x22, 0x52, 0xec, 0xcd, 0xc8, 0x11, 0x62, 0xf7, 0x1a, 0xb8, 0x7c,
-    0x58, 0x67, 0x2f, 0xa1, 0xb,  0xdd, 0xb,  0xaf, 0x62, 0x4,  0x1d, 0x4a,
-    0x31, 0x3,  0xa,  0xc8, 0xb1, 0x56, 0x1,  0x1f, 0x8d, 0xc0, 0x65, 0x5a,
-    0x84, 0x7b, 0x55, 0xda, 0x88, 0x32, 0xac, 0x52, 0x3b, 0xd,  0x10, 0x48,
-    0x64, 0x51, 0xa9, 0xa5, 0xbb, 0xe7, 0xd8, 0xee, 0xc6, 0xd0, 0x4e, 0x71,
-    0xe9, 0x8f, 0xdf, 0x5c, 0x87, 0xa4, 0x5d, 0x38, 0x1e, 0xbf, 0xd5, 0xe7,
-    0xc9, 0xb0, 0x4,  0xd4, 0xdf, 0xde, 0xd7, 0x64, 0xe9, 0x2,  0xce, 0x31,
-    0x4e, 0x56, 0xc0, 0x90, 0xb0, 0xc5, 0x46, 0x36, 0x5a, 0xb8, 0x9e, 0x44,
-    0xc3, 0x76, 0x5d, 0xfa, 0x79, 0xe6, 0x67, 0x16, 0x17, 0xde, 0x31, 0xb2,
-    0x74, 0x21, 0x1c, 0xf3, 0x26, 0x4c, 0xd6, 0xf7, 0x4b, 0x73, 0x52, 0x5e,
-    0x4d, 0xdd, 0xc0, 0x5b, 0x6b, 0xd8, 0x75, 0x83, 0x60, 0x3,  0x9e, 0xcb,
-    0xac, 0x9f, 0x39, 0xc8, 0x66, 0x47, 0x4a, 0x2f, 0x72, 0x2c, 0x93, 0x16,
-    0xb4, 0xb8, 0x73, 0xc1, 0x2c, 0xbe, 0xe6, 0x6e, 0xaf, 0x71, 0x66, 0xcd,
-    0xc5, 0x91, 0xdd, 0x13, 0xf3, 0x70, 0x3,  0xc9, 0x63, 0xf6, 0x20, 0xed,
-    0x62, 0x13, 0x40, 0xe9, 0x68, 0x3f, 0xc8, 0x74, 0xa7, 0x29, 0x51, 0xa2,
-    0xa5, 0xa9, 0x3d, 0x67, 0x6b, 0xa7, 0x43, 0xa4, 0x97, 0x66, 0x57, 0x54,
-    0x6a, 0xe2, 0xae, 0xe0, 0xff, 0xed, 0xbd, 0xe,  0x71, 0x78, 0xf,  0xf9,
-    0xdf, 0x82, 0x5,  0x1a, 0x8f, 0xc9, 0x69, 0x23, 0x90, 0xd1, 0x85, 0x96,
-    0x70, 0xa4, 0x92, 0xaf, 0xec, 0x82, 0x98, 0xbc, 0x12, 0x48, 0xd3, 0x20,
-    0x88, 0x80, 0xbd, 0xc5, 0xc4, 0xca, 0x1c, 0x72, 0xa8, 0xe1, 0xc,  0x31,
-    0xa3, 0x5a, 0x85, 0x66, 0x18, 0xed, 0x93, 0x58, 0xae, 0x53, 0x33, 0x76,
-    0xfa, 0xc0, 0x52, 0x51, 0x59, 0xf4, 0xf,  0xc9, 0xc0, 0x62, 0xfe, 0x30,
-    0xdf, 0x4d, 0xdb, 0x4c, 0x61, 0xde, 0x3d, 0x84, 0x7b, 0x82, 0x2b, 0x29,
-    0xc0, 0xab, 0x1a, 0x94, 0x30, 0xf,  0x6b, 0xb2, 0xd8, 0x7e, 0x54, 0x38,
-    0xdd, 0xfd, 0x8,  0xaf, 0x1,  0x62, 0xef, 0x2f, 0x43, 0x56, 0xc5, 0x5e,
-    0x9a, 0x78, 0x62, 0xe7, 0x67, 0x2,  0xbe, 0xa7, 0xcc, 0x9c, 0x3d, 0x72,
-    0xbb, 0xff, 0x37, 0x6a, 0xe4, 0xb2, 0x36, 0x27, 0x6d, 0x35, 0xcd, 0x60,
-    0xd4, 0x93, 0xc2, 0x34, 0xbe, 0x6c, 0x16, 0x46, 0x97, 0x4c, 0x6d, 0x99,
-    0xd5, 0xb3, 0x5a, 0x68, 0xdf, 0x4f, 0x8,  0x93, 0x28, 0xe2, 0x76, 0x66,
-    0x1d, 0x50, 0xfb, 0xec, 0x63, 0x14, 0x36, 0xc8, 0x68, 0xd6, 0xcf, 0xa1,
-    0x2d, 0x4e, 0x41, 0x25, 0x3f, 0xe0, 0x25, 0x40, 0xdb, 0xe1, 0xff, 0x7b,
-    0xf0, 0x5b, 0x69, 0x4a, 0x31, 0xf5, 0xd0, 0xf4, 0x1d, 0xc4, 0x78, 0x3d,
-    0xa7, 0x78, 0xea, 0xa9, 0x72, 0x22, 0xae, 0x67, 0x65, 0x82, 0x63, 0x2d,
-    0x91, 0x5d, 0xed, 0xad, 0xb,  0xc3, 0xd2, 0xa7, 0xaf, 0xae, 0x8e, 0xb5,
-    0x78, 0xf8, 0xca, 0x68, 0x67, 0xfe, 0x91, 0x3,  0x49, 0xa7, 0x35, 0x6a,
-    0x87, 0x9d, 0x2d, 0x3a, 0x9f, 0x63, 0xf1, 0x68, 0x72, 0xb9, 0x35, 0xc3,
-    0xd5, 0xe4, 0x7c, 0x5a, 0x5d, 0x9e, 0x3f, 0xc1, 0xc1, 0xed, 0xaa, 0x1e,
-    0x88, 0xe5, 0xad, 0x27, 0x79, 0x80, 0x4,  0x1f, 0xec, 0xb1, 0x3c, 0x5f,
-    0x15, 0x3c, 0x20, 0xce, 0x4e, 0xc6, 0xda, 0x39, 0x88, 0xef, 0xb5, 0xf2,
-    0x39, 0x96, 0xb8, 0xbe, 0xc7, 0x3,  0x32, 0xcf, 0xe4, 0x33, 0x5b, 0x1,
-    0xc,  0xfc, 0x3e, 0x63, 0xec, 0x67, 0x24, 0xec, 0x24, 0x97, 0xdf, 0xff,
-    0x0,  0xcb, 0xa,  0x14, 0xbf, 0x5c, 0x10, 0xa6, 0x52, 0x29, 0xee, 0xc2,
-    0x56, 0xe5, 0x25, 0x67, 0xe5, 0xf9, 0xd0, 0xb,  0x8b, 0xee, 0xd6, 0x19,
-    0x8,  0x6f, 0x2a, 0xcc, 0xc7, 0x7a, 0xcd, 0xec, 0xc3, 0xbd, 0xdd, 0xd4,
-    0x54, 0xa2, 0x76, 0xe1, 0x9f, 0x21, 0xa5, 0xde, 0x6,  0x7,  0x4d, 0x56,
-    0xa7, 0x71, 0x93, 0x8,  0xd8, 0x56, 0xea, 0xbe, 0x78, 0xe4, 0x8d, 0xce,
-    0x7a, 0xda, 0xc6, 0xb6, 0xb6, 0xc0, 0xce, 0x30, 0x18, 0xbd, 0x6e, 0x20,
-    0xc6, 0xa0, 0x96, 0x26, 0x7e, 0xef, 0x6b, 0x1f, 0xe5, 0xc9, 0x15, 0x77,
-    0xa7, 0xe9, 0xda, 0x9f, 0x53, 0x24, 0xe1, 0x2f, 0x70, 0x68, 0x62, 0x99,
-    0xcb, 0xcd, 0xa0, 0xe1, 0xef, 0xe2, 0x38, 0x17, 0x9d, 0xfd, 0x5c, 0x41,
-    0xee, 0x4d, 0x3b, 0xeb, 0x7d, 0x72, 0x45, 0x6e, 0x1b, 0x75, 0x46, 0x9d,
-    0x75, 0x9f, 0xf4, 0xff, 0x31, 0x0,  0xaa, 0x2,  0xcc, 0x93, 0xa4, 0xbe,
-    0x84, 0x8d, 0xd7, 0xb0, 0x42, 0x80, 0x8e, 0x29, 0xfb, 0x6,  0x32, 0x26,
-    0xc,  0xe9, 0x67, 0x3a, 0xff, 0x9,  0xa2, 0x30, 0x70, 0xe2, 0xcc, 0x73,
-    0xe8, 0x94, 0xf,  0xdb, 0xbb, 0x53, 0x43, 0x68, 0x15, 0x56, 0x9c, 0x75,
-    0x61, 0xae, 0x59, 0xa4, 0x42, 0xcd, 0xe0, 0xbc, 0x5e, 0xc,  0x8c, 0xd1,
-    0x3e, 0x8d, 0x8d, 0xf3, 0x2f, 0x2b, 0xbc, 0x98, 0x3,  0xec, 0xd9, 0xd3,
-    0x38, 0x59, 0x9f, 0xde, 0x15, 0x6b, 0x55, 0x8,  0xef, 0xf,  0x5c, 0x9f,
-    0xe,  0x74, 0xf9, 0x10, 0xde, 0xdc, 0x3d, 0x1d, 0xcf, 0xc9, 0xfd, 0x1,
-    0xd7, 0x84, 0x44, 0xa0, 0xc4, 0x5e, 0xda, 0x6f, 0x6a, 0x97, 0x7e, 0x17,
-    0x8d, 0x77, 0x62, 0x5b, 0x87, 0xd7, 0xa7, 0x31, 0x38, 0x41, 0xbf, 0x2b,
-    0x7b, 0x5c, 0x72, 0x96, 0x6f, 0xe5, 0xa2, 0x99, 0xe,  0xdc, 0x69, 0x54,
-    0xf0, 0x35, 0x78, 0xc6, 0xbc, 0x7e, 0x9d, 0x67, 0x73, 0xa6, 0x14, 0xf6,
-    0xde, 0x6e, 0x91, 0x8e, 0x16, 0x2e, 0x18, 0xdd, 0xd,  0x16, 0x3,  0xbc,
-    0x6f, 0x4,  0xfa, 0x20, 0xbf, 0xc1, 0x7c, 0x47, 0x45, 0x59, 0xc9, 0x5a,
-    0xf7, 0xbd, 0x6,  0xa,  0x50, 0xf,  0x29, 0xa3, 0x12, 0x67, 0x58, 0x88,
-    0xeb, 0x8d, 0x37, 0x8f, 0x6b, 0xef, 0xf,  0xc6, 0x13, 0xde, 0x8f, 0xe4,
-    0xd,  0x2b, 0x93, 0x34, 0x48, 0x5e, 0x27, 0xf1, 0xaa, 0xc3, 0x7c, 0x79,
-    0x7d, 0xc3, 0x89, 0xca, 0xce, 0xb3, 0x7a, 0x5a, 0xfe, 0xef, 0x83, 0x1f,
-    0x43, 0xd5, 0xe4, 0x2b, 0x59, 0x2c, 0x44, 0x96, 0xba, 0xbc, 0x25, 0xe5,
-    0x13, 0x7b, 0xbb, 0x78, 0x86, 0xef, 0x4d, 0x33, 0xf9, 0x95, 0xc5, 0x26,
-    0x46, 0x80, 0x3f, 0xed, 0xf9, 0x9f, 0x76, 0x7f, 0xe6, 0x72, 0xa,  0xf6,
-    0xc7, 0x55, 0x81, 0x43, 0x72, 0x41, 0xe9, 0x7e, 0x35, 0x3f, 0x8d, 0xf1,
-    0x4b, 0x21, 0xdb, 0x58, 0xb4, 0x3a, 0xf2, 0x0,  0xab, 0x5c, 0xfd, 0x4e,
-    0xe5, 0x30, 0x14, 0xe6, 0x5c, 0xa0, 0x15, 0x50, 0x2b, 0xb4, 0xd8, 0xe7,
-    0x99, 0xb4, 0xd3, 0x98, 0x1c, 0x8,  0x4,  0xbc, 0x38, 0x88, 0x36, 0x51,
-    0x94, 0x2f, 0xdc, 0x5e, 0x95, 0xa3, 0xf6, 0xde, 0x39, 0x90, 0x8c, 0x7c,
-    0xfd, 0x3b, 0xbd, 0x23, 0xf4, 0x15, 0x74, 0x7c, 0x6f, 0xc0, 0x37, 0x48,
-    0x85, 0xce, 0xa9, 0xd8, 0x67, 0xae, 0x1c, 0x22, 0x7d, 0x75, 0x5c, 0x61,
-    0xb6, 0x96, 0x1a, 0xec, 0x91, 0xd8, 0x54, 0xe3, 0xdc, 0xf5, 0x4a, 0xf3,
-    0x3a, 0xda, 0x48, 0xdc, 0xfa, 0x3d, 0xcc, 0xe7, 0xad, 0x4c, 0x8d, 0x49,
-    0xdc, 0xa9, 0xd7, 0x1f, 0xf3, 0xef, 0xa8, 0x28, 0x2,  0x68, 0x79, 0x82,
-    0x27, 0x81, 0x32, 0x5f, 0x55, 0x9,  0x28, 0xf6, 0xc9, 0x6e, 0xe5, 0x4b,
-    0xa9, 0x3c, 0x46, 0xb4, 0xec, 0xd3, 0x77, 0xda, 0x62, 0x3d, 0x1f, 0xe6,
-    0x3a, 0xc5, 0x8d, 0x32, 0xdb, 0xf8, 0x53, 0xb4, 0xca, 0xd6, 0xd5, 0x40,
-    0xaf, 0x3e, 0x4f, 0x3e, 0x64, 0x21, 0xc2, 0xa9, 0x6a, 0x3a, 0x86, 0xd1,
-    0x29, 0x18, 0xfb, 0xb8, 0xe1, 0x39, 0xd1, 0xb1, 0x18, 0xf3, 0x58, 0x6f,
-    0x32, 0xf9, 0x28, 0x42, 0xbe, 0x9,  0x9d, 0xef, 0xb5, 0x7b, 0xa8, 0x12,
-    0x7d, 0xc8, 0x4c, 0x32, 0x24, 0xca, 0x62, 0x6a, 0xd7, 0x23, 0xfc, 0x3d,
-    0xc,  0xcb, 0x55, 0x75, 0x75, 0x1e, 0x84, 0x8d, 0xa4, 0x8f, 0x7d, 0x14,
-    0x79, 0xe1, 0x2e, 0xf9, 0xaa, 0x7a, 0x13, 0x83, 0x30, 0xa4, 0x41, 0x56,
-    0x2a, 0x13, 0xcc, 0x38, 0x5e, 0xfa, 0xbd, 0x1b, 0xba, 0x3d, 0xf6, 0xcc,
-    0x68, 0x4a, 0x6b, 0xa9, 0x3b, 0xe5, 0x87, 0x43, 0xb3, 0xd2, 0x78, 0xcb,
-    0x3e, 0x3,  0xd7, 0x8e, 0x49, 0xc7, 0x7b, 0xd5, 0x44, 0x61, 0x56, 0xd2,
-    0x8e, 0x0,  0xd2, 0xde, 0x5c, 0xae, 0xbf, 0x35, 0x4,  0x11, 0xc4, 0x5,
-    0x9,  0x50, 0x31, 0xf4, 0x4f, 0x1c, 0x5e, 0x1b, 0xf3, 0x91, 0x99, 0x1,
-    0x7f, 0x69, 0xcc, 0xba, 0x91, 0xba, 0xb6, 0x2d, 0xc7, 0x99, 0x7e, 0xf2,
-    0x1b, 0x68, 0x8,  0x7,  0x11, 0xe2, 0x31, 0x29, 0xd1, 0xc6, 0x68, 0x45,
-    0x17, 0x7e, 0xf9, 0x0,  0x27, 0x23, 0x18, 0xa4, 0xb2, 0x61, 0xd5, 0x24,
-    0xe8, 0x8,  0xb7, 0xb2, 0xb1, 0x14, 0x6f, 0xb,  0x3e, 0xe7, 0x37, 0x64,
-    0xdb, 0x2f, 0x5e, 0x93, 0xf0, 0xa9, 0xf6, 0xad, 0x83, 0xa3, 0xba, 0xcc,
-    0x92, 0x65, 0x15, 0x60, 0x11, 0x6c, 0x88, 0x2f, 0xf5, 0x52, 0x98, 0x2d,
-    0xd0, 0x6e, 0x5d, 0x68, 0x24, 0xf6, 0xcf, 0xea, 0x33, 0xb9, 0x4d, 0xc8,
-    0xa0, 0x87, 0x65, 0xfa, 0xc7, 0x6a, 0x7f, 0xae, 0xa9, 0x44, 0x19, 0x92,
-    0xc3, 0x36, 0x1f, 0xf1, 0xf1, 0x4f, 0x9e, 0x1f, 0x2b, 0x4c, 0x2c, 0x94,
-    0x34, 0x52, 0x70, 0x43, 0x73, 0x90, 0xfe, 0x24, 0x7a, 0x2d, 0x3b, 0x8a,
-    0x24, 0x1d, 0xbd, 0xf5, 0xc6, 0x58, 0x65, 0x89, 0x9,  0xcc, 0x26, 0x46,
-    0xeb, 0x8b, 0x1b, 0x6a, 0x80, 0x31, 0xf,  0xc2, 0xd4, 0xf3, 0x63, 0x75,
-    0x1c, 0x77, 0x14, 0xe2, 0xcc, 0xc9, 0x94, 0x2c, 0x74, 0x7d, 0x29, 0x86,
-    0x7f, 0x81, 0x5,  0xa9, 0x18, 0x3d, 0x1d, 0xa4, 0x50, 0xea, 0x86, 0x3,
-    0x1f, 0xb,  0x49, 0xfd, 0x43, 0xf4, 0xa1, 0xe3, 0xbb, 0x17, 0x7c, 0x63,
-    0x57, 0xbb, 0x5d, 0x5d, 0x3c, 0xca, 0xf2, 0x7b, 0x49, 0xd0, 0x30, 0x77,
-    0x71, 0x71, 0x44, 0x9c, 0xc2, 0xfc, 0x2b, 0x4c, 0x1c, 0xc8, 0xe7, 0x35,
-    0x6b, 0x1a, 0x72, 0xfe, 0xf4, 0xc1, 0x67, 0x18, 0x49, 0x32, 0x64, 0xef,
-    0x85, 0x46, 0xfc, 0x5a, 0x94, 0xe7, 0x98, 0x6f, 0xb5, 0xbc, 0xb,  0x0,
-    0x87, 0x3,  0x7f, 0x8a, 0x99, 0xc2, 0x60, 0x9a, 0xc7, 0x50, 0x80, 0x66,
-    0x20, 0x55, 0x18, 0x89, 0xde, 0xf0, 0x2e, 0x32, 0x6b, 0xc5, 0xc1, 0x5b,
-    0x70, 0x1f, 0xbb, 0xde, 0x87, 0xa1, 0x22, 0x4c, 0x8d, 0x6e, 0x95, 0x6f,
-    0x9e, 0x71, 0x21, 0xdc, 0x5d, 0x55, 0xa2, 0xb1, 0xd4, 0x6,  0x61, 0x7,
-    0x3c, 0x52, 0xa,  0xf4, 0x93, 0x21, 0xd7, 0x6f, 0xa4, 0xf3, 0x4f, 0xd0,
-    0xda, 0x9,  0xf0, 0x31, 0x8b, 0xc,  0xb2, 0x8b, 0x2d, 0x33, 0xc4, 0x72,
-    0xdc, 0xf,  0x2c, 0xd0, 0x2d, 0xd5, 0xf4, 0xff, 0x62, 0xaf, 0x85, 0xf7,
-    0x10, 0xc8, 0x40, 0xba, 0x8b, 0x8a, 0xad, 0xcf, 0xc0, 0x24, 0xa5, 0xa3,
-    0x64, 0x5d, 0x71, 0x2b, 0xba, 0xc1, 0x13, 0xea, 0x32, 0x2a, 0xb7, 0x6d,
-    0x5d, 0xa5, 0x32, 0x12, 0x92, 0x71, 0xaf, 0xda, 0x3e, 0x0,  0xae, 0x13,
-    0x37, 0x50, 0x44, 0xb4, 0x4c, 0xfb, 0xa0, 0x79, 0x6d, 0x97, 0x52, 0x9b,
-    0x1b, 0x8d, 0xdf, 0x98, 0x78, 0xd9, 0xed, 0x90, 0x2,  0xb8, 0x1f, 0x4f,
-    0xeb, 0xbf, 0x97, 0x19, 0x9c, 0x3f, 0x1a, 0x58, 0x1e, 0x77, 0x53, 0x5f,
-    0xa2, 0xce, 0xf6, 0x36, 0x28, 0x8f, 0xbc, 0x7c, 0x39, 0x8f, 0x2,  0x6,
-    0x29, 0x84, 0x37, 0x96, 0x86, 0x8a, 0x90, 0x6d, 0xcd, 0x72, 0xbf, 0xf0,
-    0xc0, 0x51, 0xcf, 0xda, 0x7f, 0xd0, 0x42, 0x30, 0xe9, 0x83, 0xb2, 0x7d,
-    0xbd, 0xd2, 0xe2, 0x47, 0x96, 0xd6, 0xc0, 0x34, 0xdc, 0x90, 0x45, 0x29,
-    0x11, 0x11, 0xb0, 0x65, 0x44, 0xec, 0xe,  0xe4, 0x20, 0xba, 0x9a, 0xe0,
-    0x85, 0x78, 0xa8, 0x37, 0x53, 0x8b, 0x2a, 0x1,  0x19, 0x84, 0xad, 0xa,
-    0x5c, 0xba, 0x10, 0x38, 0xe1, 0x88, 0xdc, 0x52, 0x41, 0x19, 0xf4, 0x4c,
-    0xad, 0x97, 0xa8, 0xa,  0xfc, 0x29, 0x3e, 0x9a, 0xd8, 0x34, 0x4f, 0xe7,
-    0x17, 0xfb, 0x4a, 0x1c, 0x7d, 0x39, 0x8f, 0xc0, 0xb8, 0xf4, 0xcd, 0x9a,
-    0xe2, 0x83, 0x76, 0x61, 0xc6, 0x30, 0x54, 0xa6, 0x2,  0xb0, 0x11, 0x8f,
-    0xae, 0x90, 0x7c, 0x66, 0x9e, 0x3e, 0xb7, 0x82, 0xc2, 0x22, 0xaa, 0x53,
-    0xca, 0x26, 0x5e, 0x94, 0x15, 0x68, 0xcd, 0xc1, 0x1e, 0x3a, 0x2,  0xec,
-    0xfb, 0x48, 0xb6, 0x61, 0x15, 0x3b, 0x26, 0x8a, 0x1d, 0xfd, 0xb,  0x48,
-    0xa0, 0x81, 0x2e, 0xd0, 0xc6, 0x24, 0x9e, 0x37, 0x90, 0xc5, 0x80, 0xaa,
-    0xcf, 0x96, 0xee, 0xc5, 0x1d, 0xa9, 0xbe, 0x20, 0xc4, 0xb8, 0x59, 0x5f,
-    0x95, 0x2b, 0x3a, 0x58, 0xe3, 0xe8, 0xe0, 0x3d, 0x43, 0x5b, 0x4b, 0x2a,
-    0xf5, 0x8c, 0x36, 0x43, 0xaf, 0x8,  0x84, 0xbb, 0xa2, 0x2f, 0xd2, 0xac,
-    0x6f, 0x55, 0x34, 0x45, 0x4,  0xbd, 0xa7, 0x53, 0x4f, 0x92, 0x9c, 0xba,
-    0xf7, 0x50, 0x17, 0x5a, 0x47, 0x69, 0x96, 0x8f, 0x87, 0xb0, 0xd6, 0x4c,
-    0xd6, 0xe3, 0x93, 0x7a, 0x9,  0xe4, 0x35, 0x18, 0xea, 0x83, 0xe4, 0x71,
-    0xb2, 0xed, 0x94, 0x31, 0x20, 0xab, 0xdf, 0xb8, 0xab, 0xe0, 0x33, 0xcf,
-    0x4d, 0x68, 0x15, 0x87, 0x5c, 0xbf, 0x97, 0x7f, 0xbc, 0xa3, 0xa1, 0x99,
-    0x54, 0x3,  0x60, 0xc9, 0xb6, 0xe6, 0x82, 0xc6, 0x38, 0xab, 0x5b, 0xf0,
-    0xe5, 0x2d, 0x51, 0x53, 0x91, 0x72, 0xf4, 0x14, 0xfc, 0x45, 0x66, 0xed,
-    0x8,  0x24, 0x8d, 0xf0, 0x35, 0x14, 0xb9, 0xb4, 0xa7, 0xe,  0xa2, 0x45,
-    0x20, 0xe5, 0x70, 0x2d, 0x46, 0xd2, 0x6b, 0x8f, 0xf1, 0xa4, 0xc6, 0x25,
-    0xa0, 0x75, 0xcf, 0x5a, 0xce, 0xee, 0x33, 0xda, 0xf4, 0x46, 0x33, 0x1c,
-    0x95, 0x87, 0xe1, 0xbe, 0x62, 0x88, 0x75, 0x40, 0x1d, 0xcb, 0x92, 0x86,
-    0x98, 0xc3, 0x61, 0x6b, 0xd9, 0x46, 0x2d, 0xbb, 0x74, 0xb6, 0x57, 0xc4,
-    0xea, 0xc,  0x53, 0x5c, 0x3,  0x39, 0x9e, 0x93, 0x70, 0x1b, 0xcb, 0x21,
-    0xac, 0x87, 0xa4, 0x91, 0x37, 0xa1, 0x61, 0xed, 0xbe, 0xb3, 0x85, 0x75,
-    0x35, 0x98, 0xf,  0x89, 0x1a, 0xcb, 0x5a, 0x54, 0xad, 0x5b, 0x6b, 0x1a,
-    0x3d, 0x77, 0xab, 0x2d, 0x4e, 0x23, 0xef, 0x9c, 0x74, 0x46, 0x15, 0x4a,
-    0x0,  0xe2, 0xfd, 0xfe, 0xe4, 0x3d, 0x73, 0xc6, 0x4f, 0x29, 0xe6, 0x89,
-    0xd9, 0xb6, 0x9f, 0x8c, 0x37, 0x96, 0xc1, 0x8f, 0x55, 0x6b, 0x6a, 0x33,
-    0xc3, 0x6c, 0xa5, 0x5b, 0x2f, 0x34, 0x25, 0xa4, 0x74, 0x3c, 0x3f, 0x4e,
-    0xf4, 0xcf, 0xe9, 0x15, 0x57, 0xba, 0x65, 0x55, 0x2e, 0x3f, 0x1c, 0xc9,
-    0x3c, 0x20, 0x99, 0xd1, 0x3d, 0x86, 0x5c, 0x9c, 0xd5, 0x93, 0x86, 0x39,
-    0x6f, 0x6c, 0xd1, 0xe2, 0x26, 0xf8, 0xae, 0xed, 0x59, 0x6e, 0x15, 0xde,
-    0xc9, 0xc7, 0x3f, 0xc6, 0x5c, 0x6c, 0x5b, 0x34, 0xce, 0x97, 0xe2, 0xfd,
-    0xb8, 0xc8, 0xff, 0xd0, 0x4d, 0x7b, 0xbb, 0x59, 0x64, 0xc5, 0x2a, 0x70,
-    0x37, 0x9d, 0xc5, 0x8d, 0xe4, 0xf,  0x16, 0x37, 0x98, 0x5c, 0xe2, 0x14,
-    0xcb, 0x3f, 0x69, 0x46, 0xcf, 0xf1, 0xa8, 0x61, 0x8d, 0xcd, 0x99, 0x20,
-    0x3,  0x53, 0xf7, 0xca, 0x4f, 0x2d, 0x23, 0x4c, 0xab, 0x94, 0xf5, 0xd9,
-    0x4c, 0x32, 0xfa, 0xc3, 0x3,  0x21, 0x7a, 0x5e, 0x8b, 0xd4, 0x1c, 0xc0,
-    0x1d, 0x85, 0x28, 0x36, 0xeb, 0x40, 0xac, 0xae, 0xb6, 0x13, 0x2e, 0x77,
-    0xc2, 0xf5, 0xbe, 0x84, 0x47, 0xa0, 0xe3, 0x28, 0x4a, 0xf8, 0x17, 0x9e,
-    0x3c, 0x29, 0x51, 0x86, 0xf9, 0x12, 0x7a, 0x5b, 0xdf, 0x75, 0x1e, 0x87,
-    0x6f, 0xff, 0x3d, 0x32, 0x48, 0x79, 0x6e, 0x58, 0xa2, 0xc7, 0x9a, 0xc4,
-    0xf3, 0x2,  0x1c, 0xf1, 0x7f, 0xb,  0x31, 0xb7, 0x19, 0xd,  0x62, 0xcf,
-    0x3e, 0xa8, 0x59, 0x92, 0xfb, 0x61, 0xea, 0x8c, 0xca, 0x76, 0x1,  0x15,
-    0xa6, 0xf,  0xff, 0x8a, 0xc7, 0xb3, 0xed, 0xee, 0xa4, 0x8d, 0x8d, 0x7,
-    0xce, 0xb2, 0xc,  0x1c, 0xbc, 0x48, 0xad, 0xcb, 0x17, 0x9a, 0x61, 0x99,
-    0x38, 0x4b, 0x40, 0xc9, 0xed, 0x21, 0x4,  0x9e, 0xd0, 0x4f, 0xc7, 0x71,
-    0xb9, 0xf1, 0x11, 0x0,  0x7d, 0x4,  0xe3, 0xd5, 0xb7, 0xd9, 0x3,  0xe0,
-    0xf9, 0x87, 0xdb, 0xf7, 0x96, 0x7d, 0x93, 0x24, 0x70, 0x8d, 0xbc, 0x17,
-    0x41, 0x1a, 0x4d, 0x6b, 0x9e, 0x9b, 0x83, 0x67, 0x96, 0x67, 0x5a, 0x60,
-    0xa8, 0xa8, 0xbe, 0x8e, 0x27, 0xa1, 0x2c, 0xfa, 0xc0, 0xe1, 0xd6, 0x69,
-    0xea, 0x65, 0x58, 0x56, 0x9b, 0x3c, 0x92, 0x10, 0x76, 0xaf, 0x6b, 0x97,
-    0xe1, 0x64, 0x19, 0x14, 0x1b, 0xc4, 0xe9, 0xc,  0xd0, 0x1a, 0x9c, 0x8,
-    0x74, 0x3b, 0xd2, 0x48, 0x92, 0xa8, 0x5e, 0xbf, 0xc9, 0x5a, 0x2b, 0xe0,
-    0x3,  0xbc, 0x62, 0x9e, 0xe9, 0x5d, 0x23, 0xd4, 0xdb, 0xf6, 0x8,  0x6d,
-    0x67, 0x6f, 0x38, 0xe6, 0xb0, 0x83, 0xae, 0x82, 0xe4, 0xa9, 0xd8, 0xaf,
-    0x7f, 0xd2, 0x45, 0xa4, 0x49, 0xc3, 0x68, 0xcc, 0x79, 0x65, 0xad, 0xfa,
-    0x1b, 0x9f, 0x89, 0xd6, 0xe3, 0xbc, 0xe8, 0x7a, 0x7,  0xf9, 0x2d, 0x58,
-    0xa3, 0x50, 0xe4, 0xc2, 0x0,  0xe1, 0x8b, 0xfe, 0x2d, 0x46, 0x1,  0xaa,
-    0xa0, 0x1,  0x20, 0xef, 0x6a, 0x9,  0x69, 0x88, 0xf2, 0x4,  0xf5, 0xe1,
-    0x15, 0x54, 0x5a, 0x26, 0x14, 0x6b, 0x9,  0xf5, 0x90, 0x9e, 0x44, 0x55,
-    0x2d, 0x7e, 0xd5, 0xa9, 0xc1, 0x2a, 0xa2, 0x49, 0xec, 0x5c, 0xf8, 0x39,
-    0x81, 0xe3, 0x86, 0xb7, 0xa3, 0x2a, 0xfd, 0xb2, 0x61, 0xa8, 0xb2, 0x80,
-    0x9c, 0xb4, 0x48, 0x79, 0x17, 0x36, 0xe1, 0x30, 0x7d, 0xad, 0xde, 0x32,
-    0x85, 0xbd, 0x54, 0xa1, 0x9,  0xf2, 0x74, 0xa0, 0x5f, 0xf6, 0xcd, 0x96,
-    0xc4, 0x1c, 0x7a, 0x18, 0x8d, 0xae, 0xc1, 0x96, 0xbb, 0xdd, 0x8,  0x4e,
-    0x2d, 0x86, 0xc,  0x89, 0xe,  0xf0, 0xd0, 0xae, 0x31, 0x96, 0xda, 0xa4,
-    0x4e, 0x81, 0xaf, 0x27, 0x98, 0x53, 0xaf, 0x39, 0x9a, 0x2d, 0x92, 0x97,
-    0x20, 0x5e, 0xfb, 0x4f, 0x6f, 0x4f, 0xa6, 0x7f, 0x2f, 0x92, 0x8b, 0xc6,
-    0x51, 0x31, 0x2,  0x92, 0xbc, 0xdb, 0x48, 0x22, 0x7c, 0x8f, 0x84, 0x50,
-    0x21, 0x43, 0x65, 0x2d, 0x6,  0xdd, 0xe0, 0x9f, 0x8a, 0x7c, 0x2f, 0xa9,
-    0xc3, 0x1b, 0xde, 0x7a, 0x81, 0x7e, 0x1c, 0xb2, 0x2a, 0x53, 0xa0, 0xf7,
-    0xc4, 0xb9, 0xfe, 0xce, 0x18, 0xba, 0xf2, 0x10, 0xfb, 0x54, 0x68, 0xa1,
-    0x26, 0xb0, 0x0,  0x6b, 0x2e, 0x2f, 0x9e, 0xb2, 0x68, 0xea, 0x20, 0xe5,
-    0x76, 0xf3, 0xe2, 0xe6, 0x4f, 0x40, 0x7d, 0x5e, 0x20, 0x96, 0xdf, 0x45,
-    0x77, 0xb6, 0xd8, 0xf0, 0x5,  0x31, 0xf7, 0x86, 0xd3, 0x70, 0x12, 0x80,
-    0x3a, 0xde, 0x75, 0x4a, 0x82, 0x1c, 0x9d, 0xe8, 0xc0, 0xed, 0xd7, 0x7,
-    0xd5, 0x79, 0x24, 0x75, 0x5a, 0xac, 0x64, 0x8e, 0xb8, 0xc1, 0x19, 0xe,
-    0xe4, 0xa9, 0xca, 0xc6, 0x27, 0xcc, 0x8c, 0xe8, 0xd8, 0xf4, 0xda, 0x4c,
-    0x14, 0x88, 0x16, 0xe8, 0xae, 0x84, 0x71, 0xc5, 0x54, 0x21, 0x12, 0x98,
-    0xa6, 0x43, 0x44, 0x48, 0x1,  0xf,  0x57, 0xf4, 0x4,  0x33, 0x50, 0x8c,
-    0xe0, 0xbf, 0x3d, 0x36, 0x76, 0xfe, 0x72, 0x41, 0xe2, 0xfb, 0x4c, 0x35,
-    0x1c, 0x65, 0x16, 0xaa, 0xb7, 0x1d, 0x13, 0xcb, 0x5f, 0x5a, 0x3f, 0x1c,
-    0xaa, 0x1d, 0x6a, 0xe3, 0x54, 0x77, 0xd8, 0x15, 0x51, 0xe9, 0x7d, 0x50,
-};
-const uint8_t kAltGameImages1xE[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0xff, 0xe5, 0xb7, 0xbe,
-    0x33, 0xdd, 0x84, 0x73, 0x82, 0xc,  0xa1, 0x47, 0x40, 0x9f, 0x40, 0x4c,
-    0x71, 0x24, 0xa1, 0xbd, 0x1f, 0x3f, 0x12, 0x23, 0x43, 0x2,  0x1e, 0x8e,
-    0x36, 0xe5, 0x4e, 0xb8, 0x69, 0xf1, 0xd0, 0x12, 0xbe, 0x32, 0x17, 0x2f,
-    0xd9, 0x54, 0x88, 0xf7, 0x67, 0x6e, 0xb,  0xdf, 0x39, 0x9e, 0xeb, 0x79,
-    0x18, 0x2a, 0x16, 0x50, 0x90, 0x55, 0xc0, 0x2a, 0xc0, 0xbf, 0x77, 0xa3,
-    0x47, 0xa4, 0xf3, 0x3f, 0xb,  0x74, 0xa9, 0x83, 0x4f, 0x2f, 0x4e, 0x73,
-    0x84, 0x2c, 0x73, 0x7e, 0xd3, 0xc1, 0xc0, 0x2d, 0x36, 0xb5, 0x60, 0xb,
-    0xc6, 0xd5, 0x50, 0x10, 0x1a, 0x2f, 0xa5, 0xa0, 0x17, 0x49, 0xaf, 0xcf,
-    0xd9, 0xb7, 0xde, 0xeb, 0xc0, 0x9a, 0x4c, 0xf7, 0xf4, 0x96, 0xe1, 0x1,
-    0x68, 0xe3, 0x26, 0xa3, 0xd3, 0x45, 0x7b, 0x57, 0xac, 0xc2, 0xa9, 0x88,
-    0x8d, 0xdb, 0x4,  0x56, 0x34, 0xf5, 0x97, 0xd1, 0x7a, 0x60, 0xf8, 0x46,
-    0xa,  0xf1, 0x19, 0x92, 0x2d, 0x7,  0x66, 0xec, 0x6f, 0x86, 0xc4, 0x3b,
-    0x4b, 0xc8, 0xa8, 0x39, 0xe3, 0x94, 0x63, 0xb4, 0x5e, 0x9b, 0x5e, 0xd,
-    0x9a, 0x32, 0xa8, 0x4e, 0xc5, 0x58, 0x39, 0x1b, 0x83, 0x74, 0x4e, 0x6d,
-    0xa9, 0xf7, 0x14, 0x94, 0xbd, 0xa2, 0xd2, 0xe2, 0xa2, 0x66, 0x7,  0xc9,
-    0x2b, 0xe0, 0x43, 0x8d, 0x6d, 0x28, 0x0,  0x9f, 0x3f, 0x94, 0x4b, 0xe5,
-    0x68, 0xf8, 0x4d, 0x27, 0xcd, 0x33, 0x1d, 0xee, 0x11, 0x11, 0xe4, 0x2d,
-    0x36, 0x64, 0xd4, 0xd0, 0xce, 0xa9, 0xa,  0x91, 0x7c, 0x1d, 0x6e, 0xe2,
-    0xcb, 0x8,  0x65, 0x8b, 0x6f, 0xe1, 0x1b, 0x3c, 0xed, 0xa7, 0x42, 0x32,
-    0x28, 0xa8, 0xbc, 0x8d, 0x1,  0x9b, 0x3b, 0x7e, 0xa3, 0xcf, 0x7d, 0x8e,
-    0x6,  0x23, 0x42, 0xe9, 0xda, 0xa6, 0xf2, 0xa3, 0x15, 0x4a, 0x7c, 0xa5,
-    0xba, 0xd3, 0xd5, 0x89, 0x44, 0x82, 0x86, 0xa,  0x3d, 0x9c, 0xfc, 0x64,
-    0x43, 0x2e, 0xc5, 0x17, 0xe2, 0x24, 0x65, 0xc5, 0x73, 0x9c, 0x12, 0x37,
-    0x7,  0x58, 0x7b, 0x12, 0xc,  0x82, 0x7,  0xad, 0x52, 0x7c, 0x43, 0x15,
-    0xb5, 0xc0, 0x67, 0x99, 0x3,  0x2a, 0x5a, 0xf3, 0x66, 0xcf, 0xd7, 0x23,
-    0xec, 0xb8, 0xf,  0x66, 0x48, 0x60, 0x74, 0x10, 0xe4, 0x61, 0xb2, 0x51,
-    0x52, 0xbf, 0x87, 0xd5, 0x20, 0x5b, 0x5c, 0x63, 0xe5, 0x45, 0x18, 0x43,
-    0xb4, 0xfe, 0x50, 0x6e, 0x57, 0xe0, 0x34, 0xe5, 0x12, 0x2d, 0xbf, 0x38,
-    0xa5, 0x15, 0x1d, 0x8e, 0xf5, 0xfe, 0x4d, 0x59, 0x14, 0xde, 0xc1, 0xd1,
-    0xf7, 0x34, 0x11, 0xac, 0xb5, 0xef, 0x76, 0xee, 0xb6, 0x2c, 0x1f, 0x23,
-    0x0,  0xa3, 0x93, 0x9d, 0x77, 0xa9, 0x8f, 0x32, 0x16, 0x4,  0x6f, 0xe3,
-    0xa8, 0x21, 0x45, 0xd4, 0x5a, 0x6d, 0xc,  0xb9, 0x7,  0x29, 0x2b, 0x17,
-    0x6c, 0x3c, 0x58, 0xb7, 0x8,  0x4b, 0xb3, 0x20, 0x83, 0xf1, 0x60, 0xaa,
-    0xfe, 0xf1, 0x38, 0xd7, 0xf5, 0x59, 0x5,  0x76, 0x74, 0xd,  0x5,  0xf4,
-    0x8c, 0x8f, 0xbb, 0xb9, 0x32, 0x41, 0xb7, 0x7e, 0x14, 0xdc, 0xf1, 0xe2,
-    0x39, 0xf4, 0xf9, 0x25, 0x4d, 0xc5, 0xb2, 0xa8, 0x9f, 0x77, 0x31, 0xe4,
-    0x75, 0xf4, 0x6b, 0x73, 0xc8, 0xed, 0x8b, 0x1c, 0xe3, 0xfa, 0x5d, 0x30,
-    0xbc, 0x71, 0x64, 0xe8, 0xde, 0x98, 0x11, 0xe6, 0x4b, 0xd6, 0x70, 0x72,
-    0x45, 0xe3, 0x6b, 0xd6, 0x8c, 0x4f, 0xff, 0xec, 0x81, 0x34, 0x14, 0x26,
-    0xed, 0xee, 0x8d, 0x53, 0x5d, 0xe0, 0x52, 0xdd, 0x9c, 0x31, 0x14, 0x51,
-    0xbc, 0x1f, 0x6d, 0xfc, 0x91, 0xd4, 0xa3, 0xe6, 0xaf, 0x46, 0x9e, 0x41,
-    0xe0, 0x2d, 0xa7, 0xfb, 0xd,  0x3b, 0x64, 0x3e, 0x67, 0x63, 0x96, 0xd4,
-    0xe0, 0x40, 0xa5, 0x71, 0xbd, 0x67, 0xd1, 0xdb, 0xf5, 0x7d, 0xb0, 0x98,
-    0x38, 0xc5, 0xe1, 0x13, 0x6e, 0x99, 0xb4, 0x92, 0x2c, 0x46, 0x40, 0x8,
-    0x52, 0x9,  0xae, 0x70, 0x67, 0x1,  0x3f, 0xd2, 0x25, 0x61, 0x98, 0x9e,
-    0xef, 0xcd, 0x1f, 0x37, 0x96, 0xce, 0xf1, 0x53, 0xff, 0xb8, 0x95, 0x2b,
-    0xc6, 0x8d, 0xa2, 0xae, 0x9,  0xf8, 0x9b, 0xf4, 0x18, 0x17, 0x15, 0xed,
-    0x98, 0xdf, 0x1c, 0xb8, 0xd5, 0x32, 0xf6, 0xbd, 0xdd, 0x8,  0xea, 0x38,
-    0xb,  0x2b, 0x2f, 0x13, 0xab, 0x59, 0xcf, 0xce, 0xbe, 0x49, 0x39, 0xc,
-    0x98, 0xe4, 0xbc, 0x1c, 0xe4, 0xf9, 0x88, 0x96, 0xe2, 0xf2, 0x8d, 0xac,
-    0xa0, 0x31, 0xe9, 0x4a, 0x42, 0x37, 0x92, 0x7a, 0xcf, 0xb7, 0xee, 0x65,
-    0xcd, 0xcd, 0x2f, 0xe8, 0x2f, 0xe2, 0x70, 0x8a, 0x7,  0xd5, 0x93, 0x3e,
-    0xc4, 0xf1, 0x9,  0x19, 0x4a, 0xb1, 0x96, 0x4c, 0xb0, 0x9b, 0x41, 0x5a,
-    0x1e, 0x52, 0x0,  0x2b, 0xa4, 0xc3, 0xd2, 0x9,  0xd8, 0x7f, 0x93, 0x53,
-    0x25, 0x96, 0xe6, 0xbe, 0x41, 0x84, 0x6c, 0x3b, 0x72, 0x51, 0xec, 0x4e,
-    0x91, 0xbd, 0x6c, 0x37, 0x34, 0xb7, 0x6f, 0xda, 0x3c, 0xac, 0xc,  0x1a,
-    0xb,  0xdc, 0x4a, 0x55, 0xc8, 0x37, 0x4,  0x48, 0xd5, 0x1f, 0x27, 0x66,
-    0xb9, 0x2c, 0x82, 0x9f, 0x62, 0xd,  0x1a, 0xdc, 0x7e, 0x44, 0x62, 0x51,
-    0xf1, 0x30, 0x82, 0x90, 0x42, 0x4f, 0x3e, 0xda, 0x22, 0xca, 0xf4, 0x98,
-    0x38, 0x46, 0xd0, 0x74, 0x2b, 0x71, 0x2d, 0x7d, 0x8e, 0x48, 0xae, 0xcb,
-    0x19, 0xb6, 0x95, 0xf3, 0x53, 0xf6, 0x14, 0xff, 0xc,  0x56, 0xe1, 0x16,
-    0x68, 0xb3, 0xc6, 0x59, 0xf5, 0x4e, 0x58, 0x7f, 0x42, 0x4a, 0xa4, 0xa4,
-    0x7d, 0xc9, 0x1b, 0xd7, 0xa0, 0x5e, 0x1a, 0xec, 0xf9, 0xd7, 0xe3, 0x8b,
-    0xbf, 0xde, 0x2,  0xab, 0x39, 0x6b, 0x8a, 0xf1, 0xe9, 0xc3, 0x4d, 0x3f,
-    0x50, 0xd8, 0xa1, 0xed, 0x40, 0xb9, 0xb7, 0x42, 0xa7, 0x25, 0x78, 0xab,
-    0x2,  0x3f, 0xd,  0x8e, 0x3c, 0x8a, 0x6b, 0xa7, 0xb2, 0x74, 0xf2, 0x0,
-    0xd9, 0xaf, 0x8e, 0x1c, 0x8a, 0xd5, 0xd8, 0x2,  0x3a, 0xf3, 0x55, 0xbf,
-    0x57, 0x31, 0x20, 0xf9, 0xa9, 0x2d, 0x62, 0x79, 0xac, 0xa0, 0xd4, 0xac,
-    0x9b, 0x73, 0xc0, 0x6,  0x2d, 0x20, 0xa6, 0x49, 0x35, 0x3,  0x76, 0x81,
-    0xec, 0x2f, 0xfc, 0x1e, 0x6d, 0x9d, 0x28, 0xfc, 0xe5, 0x27, 0x4d, 0x50,
-    0x74, 0x41, 0xbf, 0x33, 0x51, 0x90, 0x41, 0x9,  0x6c, 0x8d, 0xe9, 0xff,
-    0x48, 0xaf, 0x77, 0xe1, 0xfd, 0xe5, 0x45, 0x37, 0x45, 0x33, 0x6a, 0x8c,
-    0xf3, 0x19, 0x31, 0x92, 0x4f, 0xbb, 0xd4, 0xc,  0x4c, 0x81, 0xd3, 0xab,
-    0xde, 0x57, 0xb4, 0xc6, 0x31, 0xf5, 0xc6, 0x2c, 0xa,  0x7b, 0x98, 0xf7,
-    0x13, 0x7d, 0x51, 0x77, 0x92, 0x71, 0xce, 0x1a, 0xb1, 0xf4, 0x44, 0xee,
-    0xba, 0x8a, 0x66, 0x57, 0x16, 0x9a, 0x33, 0xca, 0xc3, 0xa4, 0x7a, 0xd8,
-    0xcf, 0x3b, 0x89, 0x5e, 0x87, 0xa5, 0x52, 0x13, 0xa8, 0xc0, 0xab, 0xac,
-    0xd2, 0xa7, 0xdd, 0xb3, 0xe8, 0x35, 0x69, 0xab, 0x44, 0xec, 0x4b, 0x1d,
-    0x92, 0x36, 0x26, 0x5d, 0xdb, 0xa7, 0x32, 0x17, 0x56, 0x9a, 0x8f, 0x87,
-    0xdd, 0x54, 0xba, 0x37, 0xd2, 0x4d, 0x2e, 0xfc, 0xc9, 0xc6, 0xb0, 0x34,
-    0x20, 0x53, 0x71, 0xbb, 0x40, 0xc1, 0xd7, 0x6,  0x37, 0xc9, 0x26, 0x1b,
-    0xd7, 0xb8, 0x69, 0x23, 0xab, 0xa3, 0xfc, 0xd1, 0xc,  0x0,  0x67, 0xb0,
-    0xb3, 0x2c, 0xfc, 0xc2, 0xd4, 0x0,  0x16, 0xad, 0x65, 0x57, 0x4d, 0x4,
-    0x5b, 0x9c, 0xa4, 0x80, 0xb2, 0xa,  0x92, 0xad, 0x60, 0x2f, 0x4e, 0xba,
-    0x16, 0x36, 0x8f, 0xe7, 0x64, 0xf7, 0xfc, 0xa1, 0x68, 0xa4, 0x70, 0x26,
-    0x67, 0x34, 0x6b, 0x1a, 0x9d, 0xf,  0x1d, 0xf4, 0x92, 0x9d, 0xc,  0x8b,
-    0x3e, 0xdd, 0xcf, 0x5c, 0x52, 0x69, 0x98, 0x5c, 0x44, 0x47, 0x52, 0xc6,
-    0x1d, 0xf5, 0xf9, 0xc3, 0x52, 0xd7, 0x88, 0x6d, 0x20, 0xf,  0x97, 0x28,
-    0x36, 0x8d, 0x60, 0x18, 0x9e, 0x7a, 0xaf, 0xcc, 0x84, 0xc1, 0x50, 0x8f,
-    0x7c, 0x59, 0x1f, 0x42, 0x20, 0x33, 0x59, 0x74, 0x20, 0x25, 0x67, 0xf8,
-    0x17, 0x49, 0x6c, 0xf,  0x2e, 0x35, 0x6a, 0xd4, 0x53, 0x60, 0x80, 0x84,
-    0x29, 0x85, 0x5c, 0x99, 0x87, 0x3,  0x22, 0xa5, 0xe5, 0xe5, 0x57, 0x4f,
-    0xfc, 0x29, 0xcf, 0x4,  0x8b, 0x58, 0xe6, 0x21, 0x17, 0x9a, 0xc4, 0x13,
-    0x22, 0x32, 0x46, 0x6f, 0x7f, 0xc4, 0xd8, 0x38, 0xc,  0xb1, 0xce, 0xe2,
-    0xe0, 0x36, 0x4f, 0xcf, 0x6,  0xb,  0xa,  0xc1, 0x5e, 0x92, 0x3,  0x5c,
-    0x73, 0x6,  0x54, 0x67, 0xe8, 0x52, 0x9f, 0xd8, 0x94, 0x48, 0x45, 0x65,
-    0x54, 0xf,  0xa,  0x1d, 0x28, 0xd7, 0x72, 0x69, 0xbf, 0xe,  0xf1, 0xc8,
-    0x50, 0x8e, 0x4a, 0xf1, 0x4e, 0x31, 0x92, 0xca, 0x48, 0x18, 0xc9, 0x53,
-    0xfe, 0x92, 0xf5, 0xcf, 0x90, 0xe0, 0x66, 0x16, 0xf4, 0xc1, 0x33, 0x66,
-    0xff, 0xf1, 0x3e, 0x33, 0x6f, 0xfe, 0xc5, 0xbf, 0x14, 0x70, 0xf3, 0xfc,
-    0xc4, 0x2,  0xd3, 0x0,  0xd0, 0x78, 0x20, 0xbb, 0x71, 0x25, 0x7c, 0x47,
-    0x33, 0xd7, 0xbb, 0x1e, 0xa8, 0x10, 0x5e, 0xe4, 0xcb, 0xcb, 0x5b, 0x2b,
-    0x5f, 0xcb, 0x37, 0x87, 0x8f, 0xa3, 0x87, 0x37, 0x1,  0xa8, 0x8a, 0xf5,
-    0x79, 0xae, 0xb0, 0x68, 0x80, 0x41, 0x1,  0x98, 0xf8, 0xbd, 0x7f, 0x59,
-    0x65, 0xea, 0xc8, 0x92, 0xb5, 0x29, 0xa9, 0x38, 0xb0, 0x1a, 0x24, 0x36,
-    0x48, 0xfc, 0xe9, 0x7e, 0xb2, 0x65, 0xb5, 0x18, 0x42, 0xc6, 0xe5, 0xa7,
-    0xf,  0x5,  0x85, 0xff, 0x27, 0x52, 0xe7, 0x17, 0xf3, 0x27, 0xca, 0xf6,
-    0xeb, 0x64, 0xf8, 0x52, 0x66, 0xa1, 0xe9, 0xc8, 0x7d, 0x6f, 0x1,  0x53,
-    0x41, 0x64, 0xe9, 0x5,  0xd,  0x44, 0xf4, 0x81, 0x63, 0x25, 0xc6, 0xe8,
-    0xb1, 0x83, 0x4f, 0x73, 0x5d, 0xbf, 0xa7, 0x27, 0x99, 0x7b, 0xbe, 0xa9,
-    0x8d, 0x1,  0xe9, 0xd9, 0x3c, 0xb,  0x8d, 0xd5, 0x0,  0xf7, 0x49, 0xcf,
-    0x14, 0x50, 0x4e, 0x26, 0x13, 0xd3, 0x80, 0x93, 0x6e, 0x3a, 0xde, 0x8d,
-    0x1,  0xcd, 0x78, 0xf3, 0xe,  0x26, 0xe3, 0x1a, 0xe,  0xd6, 0xa7, 0xc0,
-    0xac, 0xcb, 0x1d, 0x13, 0x6,  0xaf, 0xdb, 0x8f, 0x65, 0xd4, 0x5b, 0x19,
-    0x48, 0xae, 0x6a, 0x63, 0x43, 0xa9, 0x86, 0x43, 0x93, 0x27, 0x1b, 0x41,
-    0x68, 0x3a, 0xe9, 0xec, 0xdb, 0xe6, 0xa6, 0x6e, 0xd5, 0x6f, 0x30, 0xcc,
-    0xda, 0x15, 0x2c, 0xb,  0x13, 0x6f, 0xf,  0xc7, 0xbd, 0x42, 0x6f, 0x3e,
-    0x58, 0x95, 0xc6, 0x29, 0x30, 0x19, 0x9f, 0x50, 0x4f, 0x4c, 0x1,  0x48,
-    0x69, 0xcb, 0x57, 0x14, 0xbc, 0xd0, 0x94, 0x9f, 0xe,  0x31, 0x16, 0xde,
-    0x1e, 0x15, 0x18, 0x33, 0xc7, 0x8,  0x63, 0x9,  0xb2, 0x99, 0x31, 0x99,
-    0xde, 0x7c, 0xaf, 0x15, 0x13, 0xf6, 0x32, 0x8f, 0x48, 0xe0, 0xd7, 0xc1,
-    0xbe, 0x7e, 0x66, 0x98, 0xf3, 0x6,  0xe2, 0x99, 0x4,  0x9d, 0x23, 0x3f,
-    0x44, 0xea, 0xbb, 0x2a, 0xf9, 0x33, 0xf0, 0xbc, 0xd,  0x23, 0x3e, 0x5e,
-    0x89, 0xf4, 0x6,  0x1,  0xfe, 0x77, 0x2d, 0x9d, 0xd5, 0xfa, 0xc3, 0x39,
-    0x3c, 0x41, 0x53, 0x40, 0xbb, 0x77, 0xc3, 0x56, 0x16, 0xd,  0x7c, 0x86,
-    0x1c, 0x9,  0x2c, 0xad, 0x38, 0x59, 0x70, 0xdc, 0x38, 0x9e, 0x3b, 0x8a,
-    0x34, 0xa5, 0x93, 0xcf, 0xc5, 0x34, 0x87, 0xe5, 0xca, 0x61, 0x96, 0x7d,
-    0xa,  0x57, 0x8b, 0x8,  0x76, 0x8f, 0x4b, 0x8c, 0x96, 0xc8, 0xdf, 0x7e,
-    0x5d, 0x51, 0x9a, 0x8c, 0x82, 0x8a, 0x8b, 0xa,  0x92, 0x87, 0xd5, 0x39,
-    0xb,  0xac, 0xbf, 0x65, 0x62, 0x12, 0x71, 0x35, 0xda, 0x74, 0x2d, 0xdc,
-    0xd0, 0x64, 0x25, 0xe9, 0x9f, 0xe9, 0x99, 0xf2, 0x46, 0xf9, 0x9d, 0xe6,
-    0x4,  0xa3, 0x3e, 0x6c, 0x90, 0xd8, 0xa0, 0xc9, 0x11, 0xd1, 0xf4, 0x35,
-    0xfc, 0x9e, 0xf,  0xb8, 0xca, 0x30, 0xd,  0xa4, 0x90, 0x61, 0x1e, 0x2a,
-    0xca, 0x29, 0xbd, 0x72, 0x1f, 0xf6, 0x42, 0x14, 0x86, 0xbe, 0x69, 0x82,
-    0x2b, 0xd5, 0xa4, 0x33, 0x62, 0x34, 0x3,  0x78, 0xa2, 0x92, 0x4b, 0x43,
-    0x98, 0x84, 0xd3, 0x30, 0xba, 0x9,  0x22, 0xb2, 0xfd, 0xbd, 0x94, 0x63,
-    0x1f, 0x38, 0x39, 0x0,  0x9e, 0x6b, 0xe8, 0x57, 0xb,  0xf5, 0x75, 0xec,
-    0x73, 0xdf, 0x75, 0xba, 0x79, 0xe7, 0x4a, 0x88, 0xf0, 0xf0, 0xb0, 0x10,
-    0xc3, 0xe3, 0x48, 0x4e, 0xc1, 0x2c, 0x9c, 0x5,  0x58, 0x7e, 0xd6, 0x2e,
-    0xea, 0x99, 0xad, 0xa2, 0x6,  0xd6, 0xd7, 0xcc, 0x1c, 0x4c, 0x68, 0x64,
-    0x59, 0xab, 0xcf, 0xdd, 0xc1, 0x1d, 0x70, 0xaf, 0x72, 0xe2, 0x61, 0x49,
-    0xc7, 0x63, 0x40, 0x94, 0x1b, 0xae, 0xbd, 0xc0, 0xc0, 0xfd, 0x76, 0xa9,
-    0x1b, 0x83, 0x91, 0x2,  0xe,  0xf2, 0xad, 0xd8, 0x0,  0x67, 0x1f, 0x6d,
-    0xfc, 0xca, 0x77, 0x76, 0xe8, 0x59, 0xc,  0x51, 0x5d, 0x2d, 0xb1, 0x1e,
-    0xb8, 0xc4, 0x0,  0x6a, 0xae, 0xd7, 0x3b, 0xe6, 0xb4, 0xe3, 0xb3, 0x59,
-    0xf5, 0x5a, 0xde, 0x7d, 0x22, 0x45, 0x71, 0xe6, 0xdb, 0x23, 0x18, 0x35,
-    0xaa, 0x0,  0x41, 0xfd, 0x56, 0xce, 0xd9, 0x2b, 0x5f, 0x2a, 0xa5, 0xa7,
-    0xd5, 0x53, 0x34, 0x27, 0xbd, 0x26, 0x92, 0x2d,
-};
-const uint8_t kAltGameImages1xF[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0xff, 0xe5, 0xb7, 0xbe,
-    0x33, 0xdd, 0x84, 0x73, 0x82, 0xc,  0xa1, 0x47, 0x40, 0x9f, 0x40, 0x4c,
-    0x48, 0x31, 0x55, 0x3a, 0xc9, 0x57, 0x30, 0x6a, 0x80, 0x88, 0xe8, 0x56,
-    0xc4, 0x30, 0x4c, 0x85, 0x3a, 0x32, 0x5a, 0xd1, 0x44, 0xa4, 0x15, 0xa,
-    0x2f, 0xac, 0xff, 0x9b, 0x25, 0x6c, 0x7,  0x68, 0x72, 0x79, 0x31, 0x4b,
-    0xed, 0x2e, 0xdb, 0xf9, 0x82, 0xf4, 0xf,  0xf7, 0xf6, 0x7e, 0x64, 0xe7,
-    0xa2, 0xef, 0xbd, 0x20, 0x71, 0x5b, 0xbc, 0xa7, 0xed, 0x70, 0x93, 0x1f,
-    0xe9, 0x65, 0x1d, 0xb8, 0xd2, 0xfd, 0xc1, 0x4,  0x24, 0x56, 0xee, 0xf,
-    0xca, 0x41, 0x77, 0xf7, 0x1c, 0x16, 0x39, 0x33, 0x66, 0x26, 0x81, 0x9c,
-    0x3,  0xa2, 0x41, 0x8a, 0x71, 0x44, 0xb6, 0xc8, 0x2b, 0x31, 0xb6, 0x21,
-    0xe2, 0x41, 0x92, 0xcd, 0x71, 0x98, 0x81, 0x75, 0x97, 0xdc, 0x0,  0x66,
-    0x1c, 0xfc, 0x4a, 0xaa, 0x43, 0x75, 0x5d, 0x6c, 0xa7, 0xbe, 0x45, 0xa2,
-    0x61, 0x47, 0x8b, 0x59, 0x4e, 0xe3, 0x0,  0x7,  0x3a, 0xb2, 0xc6, 0xdf,
-    0x70, 0x28, 0xe6, 0xbd, 0x55, 0x20, 0x8b, 0x36, 0x72, 0xb9, 0x8a, 0x7d,
-    0x6c, 0xbd, 0x73, 0x2d, 0x6,  0xe2, 0x9b, 0xc4, 0x3b, 0x1f, 0xdf, 0x1d,
-    0xc8, 0x67, 0x87, 0x2c, 0x15, 0x22, 0xe1, 0xaf, 0x6f, 0x1a, 0x90, 0xb,
-    0x25, 0x10, 0xd0, 0xdb, 0x5f, 0xd8, 0x69, 0x81, 0xf2, 0xf7, 0xf8, 0xca,
-    0xfb, 0xa3, 0x76, 0x24, 0xc0, 0xd3, 0xc4, 0xfb, 0xa1, 0x94, 0xc2, 0x15,
-    0x8d, 0x91, 0x6d, 0x3,  0x8e, 0x8d, 0xf,  0x46, 0xfd, 0x4a, 0x1,  0x95,
-    0xf3, 0xf7, 0x6e, 0x45, 0x35, 0xb8, 0x3d, 0x4a, 0x19, 0xd3, 0x4a, 0x9b,
-    0x6e, 0x81, 0x67, 0xe1, 0x5b, 0x25, 0xcd, 0x4e, 0x8e, 0x8d, 0x17, 0x1a,
-    0x98, 0xb,  0xc2, 0xe6, 0x6e, 0x2a, 0x6b, 0x65, 0x30, 0x8a, 0x54, 0x21,
-    0xd4, 0xbe, 0x1d, 0x2,  0x68, 0x7c, 0xee, 0x3c, 0x48, 0xba, 0xf7, 0xe7,
-    0x46, 0xd6, 0x57, 0xf9, 0x1a, 0x63, 0x55, 0x70, 0x0,  0x87, 0x82, 0x42,
-    0xc8, 0x5b, 0x7b, 0xf0, 0x88, 0x55, 0x4,  0xa6, 0x6d, 0x5c, 0x3a, 0x88,
-    0xa0, 0xf4, 0xd3, 0x5f, 0xcd, 0x27, 0x8d, 0x2e, 0x1a, 0x76, 0xe8, 0x73,
-    0x11, 0x32, 0xde, 0x4e, 0x44, 0x4e, 0x3e, 0x35, 0xfe, 0x8c, 0x90, 0x6,
-    0x9c, 0x6b, 0x52, 0x73, 0xd0, 0x2a, 0x57, 0x77, 0x2c, 0xf1, 0xe6, 0x8a,
-    0x7,  0x97, 0x9f, 0xae, 0x82, 0xa9, 0xfd, 0xe7, 0x25, 0x2f, 0xde, 0x2b,
-    0xf1, 0x7e, 0x64, 0xcf, 0xd4, 0x1,  0xa5, 0x29, 0xe9, 0x2d, 0xde, 0x30,
-    0x80, 0xe9, 0xdc, 0x9c, 0x20, 0x1d, 0x12, 0xd3, 0xa6, 0x74, 0x5d, 0xb0,
-    0x25, 0x10, 0x7a, 0xa2, 0x65, 0x3,  0x8d, 0xfc, 0x9b, 0x2a, 0xfb, 0xa8,
-    0xa0, 0x7e, 0x75, 0x10, 0x3f, 0xc2, 0x97, 0x4b, 0xd8, 0x19, 0x84, 0xd6,
-    0xb1, 0x14, 0x39, 0xb8, 0x90, 0x29, 0x93, 0xaa, 0x3c, 0x62, 0x35, 0xa,
-    0x11, 0x1a, 0x0,  0xf2, 0xf3, 0xb2, 0x4,  0xe,  0x6d, 0xa2, 0x14, 0x34,
-    0xbd, 0x70, 0xb4, 0x8e, 0xa1, 0x92, 0x32, 0xc3, 0xa1, 0xdb, 0xdd, 0xac,
-    0xa2, 0x4e, 0x35, 0x53, 0x16, 0xbb, 0xa7, 0x7b, 0x87, 0x7a, 0x37, 0x33,
-    0xf6, 0x49, 0xa6, 0x36, 0xd8, 0xdd, 0x3f, 0x8,  0x5b, 0xe4, 0xcb, 0xe4,
-    0xc7, 0x85, 0x8e, 0x17, 0x6d, 0xed, 0xe8, 0x8e, 0x6d, 0xa1, 0xb,  0x19,
-    0x7c, 0x2c, 0xf9, 0xff, 0xb5, 0x77, 0x91, 0xa9, 0x59, 0x10, 0x16, 0x92,
-    0x89, 0xcb, 0x8a, 0xb9, 0xa2, 0x28, 0x36, 0xf6, 0x36, 0x8b, 0xf1, 0xaa,
-    0x5e, 0x3,  0x88, 0x76, 0xd9, 0x47, 0xa8, 0x67, 0x71, 0x7f, 0xeb, 0xd,
-    0x84, 0x48, 0xa2, 0x90, 0x35, 0xe3, 0xbd, 0x8d, 0xe7, 0xeb, 0x7,  0xa6,
-    0x2a, 0x9a, 0xe4, 0xb5, 0xab, 0x3e, 0xf2, 0x92, 0x84, 0x78, 0x42, 0x9,
-    0xb0, 0xd7, 0x1c, 0x1c, 0x27, 0xd6, 0x78, 0x50, 0xad, 0x2a, 0xe8, 0x33,
-    0x91, 0xa,  0xf9, 0x7c, 0xf,  0x5d, 0x75, 0x5c, 0xf8, 0x59, 0x7f, 0xa1,
-    0x6f, 0x3d, 0xf9, 0xb8, 0x4b, 0x6a, 0x5,  0x54, 0xa0, 0x8a, 0xf1, 0xc,
-    0x95, 0x25, 0x10, 0xb2, 0x1c, 0xfe, 0x36, 0x0,  0x83, 0xbe, 0x79, 0xd2,
-    0x7e, 0xe9, 0x3f, 0x6c, 0x8a, 0xa7, 0x92, 0x86, 0xff, 0x56, 0xa9, 0x28,
-    0x86, 0xf1, 0x94, 0xf1, 0xf7, 0x25, 0xd4, 0xe6, 0xd8, 0x71, 0xf8, 0xf5,
-    0x7e, 0x20, 0x13, 0xb7, 0xa3, 0x38, 0xf0, 0x90, 0x17, 0x24, 0x45, 0xda,
-    0x6e, 0xb4, 0xbd, 0x59, 0xba, 0x29, 0xba, 0x25, 0x78, 0xb8, 0xdd, 0x91,
-    0x1c, 0x50, 0x8e, 0x5c, 0x2f, 0x57, 0x98, 0x5f, 0x61, 0xb0, 0x83, 0xeb,
-    0x88, 0xe9, 0x42, 0x67, 0x51, 0x83, 0x9c, 0x4d, 0xd8, 0x5,  0x1d, 0x6c,
-    0x7c, 0x83, 0xb7, 0xdb, 0x92, 0xa4, 0x3,  0xf8, 0x91, 0x90, 0xbb, 0xa5,
-    0x64, 0xff, 0xb1, 0x1e, 0xf8, 0x46, 0x6f, 0x3b, 0xce, 0x9f, 0x70, 0x1d,
-    0x5a, 0x64, 0x43, 0x8f, 0xcd, 0xcf, 0xa2, 0xa8, 0x38, 0x52, 0xcf, 0xf2,
-    0x91, 0x1b, 0x32, 0xae, 0x32, 0xf7, 0x29, 0x36, 0x6f, 0xb3, 0x9d, 0x25,
-    0x78, 0x3e, 0xbf, 0x41, 0x6b, 0xb4, 0x79, 0x5f, 0xf1, 0x92, 0x63, 0xd6,
-    0xec, 0xbe, 0x4b, 0xef, 0x72, 0xca, 0x19, 0xca, 0x23, 0x98, 0xe2, 0xca,
-    0x7d, 0x55, 0x87, 0xcc, 0xac, 0xb1, 0x33, 0xc4, 0xd6, 0x1e, 0xc6, 0xf8,
-    0x82, 0x5,  0x23, 0x11, 0xe6, 0xf9, 0x85, 0x13, 0xa0, 0x81, 0xf1, 0x4,
-    0x92, 0xbe, 0x43, 0xff, 0x3c, 0x96, 0xa0, 0x93, 0xe0, 0x72, 0xa,  0xee,
-    0x4c, 0xf7, 0x25, 0x60, 0x74, 0xa2, 0xc7, 0xe8, 0xe4, 0xb9, 0x39, 0x6b,
-    0xd5, 0xcb, 0x18, 0x71, 0x56, 0x53, 0xad, 0xe1, 0x7e, 0xa4, 0x33, 0x50,
-    0x42, 0xd1, 0x2e, 0x12, 0x30, 0xd3, 0x32, 0xfd, 0xc8, 0x48, 0x86, 0x75,
-    0xae, 0x37, 0xb2, 0x1b, 0x87, 0x3d, 0x9a, 0xd7, 0x10, 0xb0, 0xe1, 0x39,
-    0xb9, 0xfb, 0xf5, 0xc6, 0x18, 0x9c, 0xb2, 0x6e, 0x6c, 0x64, 0x52, 0x5f,
-    0x3e, 0xa7, 0x37, 0xb0, 0x9d, 0xc7, 0x85, 0x40, 0x71, 0xf3, 0xa6, 0xd6,
-    0x80, 0x83, 0xa7, 0xc5, 0x46, 0x0,  0x9c, 0x88, 0x4e, 0x7d, 0x26, 0x87,
-    0x7,  0x53, 0x1d, 0x27, 0x1f, 0xa5, 0x58, 0x6d, 0x73, 0xbb, 0x53, 0xa8,
-    0xb1, 0x76, 0xc8, 0xe,  0xb7, 0x3a, 0x44, 0x87, 0x4a, 0x82, 0x1a, 0x25,
-    0x2a, 0x96, 0x31, 0x16, 0xc8, 0xaf, 0x9a, 0x39, 0x9d, 0xf7, 0x2e, 0x79,
-    0x70, 0x68, 0x2f, 0xdc, 0x6d, 0xe0, 0xb1, 0xee, 0x86, 0x2e, 0x24, 0xae,
-    0x42, 0x95, 0xa3, 0xd8, 0xdf, 0xe0, 0xb6, 0xa3, 0x96, 0xf8, 0x4f, 0xfb,
-    0x43, 0x9d, 0x50, 0x54, 0x41, 0x17, 0x75, 0xf4, 0xac, 0x8f, 0xcb, 0x9a,
-    0x5b, 0x34, 0x75, 0x75, 0x50, 0xa7, 0x22, 0x4c, 0xae, 0x7,  0x46, 0xce,
-    0x61, 0xa3, 0x53, 0xa7, 0xe9, 0x6b, 0x79, 0x32, 0xe0, 0xd1, 0xe8, 0xbf,
-    0xf9, 0xce, 0x20, 0xae, 0xef, 0xc0, 0xf4, 0x4b, 0x95, 0x19, 0x13, 0xf0,
-    0x89, 0x92, 0x12, 0xdc, 0x23, 0xa6, 0xb0, 0x2a, 0xc6, 0x47, 0xcc, 0xa9,
-    0x4,  0x95, 0x69, 0x64, 0xb7, 0x21, 0x7f, 0xd,  0x4b, 0x60, 0x6d, 0x55,
-    0xad, 0x11, 0xbe, 0xfe, 0x8a, 0x7e, 0x3,  0xa9, 0xc8, 0xc1, 0xbb, 0x12,
-    0xd2, 0x3e, 0xfa, 0x8b, 0x53, 0xce, 0x54, 0x65, 0xfc, 0x79, 0xd3, 0x7b,
-    0xdd, 0x6,  0xc3, 0x43, 0xc6, 0x5f, 0xe0, 0xe9, 0xfc, 0xca, 0xda, 0x1b,
-    0xd6, 0xf4, 0xe4, 0x86, 0x1b, 0x6b, 0xb2, 0x8c, 0x16, 0x26, 0x33, 0xe6,
-    0xca, 0xa4, 0x36, 0x80, 0x13, 0xf0, 0x90, 0xf3, 0x5,  0xff, 0x0,  0x61,
-    0x13, 0x71, 0xab, 0x35, 0x83, 0xa2, 0x35, 0x24, 0x61, 0x91, 0xb0, 0x0,
-    0x6f, 0x74, 0xb0, 0xeb, 0x46, 0xb3, 0x94, 0x46, 0x78, 0x55, 0x2e, 0x1d,
-    0x6e, 0x1,  0x39, 0xea, 0x73, 0x8e, 0xcf, 0x97, 0x7b, 0xb3, 0xa9, 0x2f,
-    0xc9, 0xfa, 0x74, 0x0,  0x35, 0x44, 0x58, 0x2f, 0x70, 0x3a, 0x1b, 0x44,
-    0x56, 0x8b, 0xca, 0x34, 0x7f, 0x72, 0xd5, 0x77, 0x60, 0x7b, 0xce, 0x90,
-    0x33, 0x7d, 0xd1, 0x39, 0x6d, 0x26, 0xa9, 0xc0, 0x51, 0x8c, 0x49, 0x24,
-    0x16, 0xe6, 0xa5, 0x7d, 0x67, 0x40, 0x9a, 0xc9, 0xb4, 0x36, 0x3c, 0x6f,
-    0x83, 0x65, 0xe2, 0x1a, 0xce, 0x95, 0xae, 0x58, 0xe0, 0x8a, 0x5d, 0xdc,
-    0x70, 0xd2, 0xb9, 0x78, 0xb8, 0xc0, 0x12, 0xc1, 0xdd, 0x39, 0x52, 0x4c,
-    0x8f, 0x19, 0xcf, 0x78, 0xf9, 0xcc, 0xc6, 0x44, 0xce, 0x95, 0x17, 0x8c,
-    0x74, 0x7b, 0xfd, 0x73, 0x20, 0xe9, 0x3a, 0x5c, 0x51, 0x39, 0xc6, 0x99,
-    0x1a, 0x57, 0x13, 0x37, 0xa7, 0x9a, 0x55, 0x20, 0x3f, 0x86, 0x27, 0x11,
-    0xa5, 0x48, 0xc7, 0xee, 0xf3, 0xba, 0x1a, 0xc4, 0xce, 0x9,  0x14, 0xa8,
-    0x90, 0x5,  0xe6, 0x96, 0xe4, 0x89, 0xc5, 0x42, 0x53, 0xdb, 0xce, 0xe5,
-    0xf5, 0x36, 0x7c, 0x42, 0xb3, 0x1a, 0x43, 0xe,  0xcc, 0xbf, 0x98, 0x88,
-    0x44, 0xc2, 0x4a, 0x2,  0xad, 0xc4, 0x46, 0xbc, 0x66, 0x8f, 0x18, 0x41,
-    0xf9, 0xfa, 0x33, 0x86, 0x87, 0x4d, 0x94, 0x67, 0x79, 0x2a, 0x88, 0xbc,
-    0xf6, 0x46, 0x7c, 0x8e, 0xb1, 0x35, 0xb1, 0xfd, 0xe7, 0xf,  0xec, 0x9b,
-    0x90, 0xfe, 0x1e, 0x96, 0xf9, 0x91, 0xcc, 0x71, 0xca, 0xb8, 0x2d, 0x2b,
-    0x9a, 0x5a, 0x19, 0xa9, 0x30, 0x3c, 0x64, 0xe,  0x84, 0xb4, 0x92, 0x7b,
-    0xa6, 0x76, 0x35, 0xa4, 0xa,  0x39, 0x67, 0xdb, 0xf4, 0x1e, 0xda, 0x5,
-    0xc8, 0x50, 0xff, 0xbc, 0xa0, 0x68, 0x66, 0x54, 0xf0, 0xcf, 0xb0, 0x39,
-    0x77, 0x39, 0x23, 0xc8, 0x19, 0x27, 0xa,  0x2a, 0xf1, 0xd6, 0xe6, 0x55,
-    0x38, 0x1e, 0xa8, 0xe3, 0x5e, 0x8f, 0xed, 0x90, 0xe1, 0x35, 0x1d, 0x8a,
-    0x1,  0xac, 0xe7, 0x43, 0xc5, 0x43, 0xc7, 0x87, 0x5f, 0x35, 0xe0, 0x4c,
-    0xfd, 0xef, 0x63, 0x1b, 0x70, 0xf2, 0x5c, 0x9f, 0x67, 0xe8, 0xe8, 0x1,
-    0xe2, 0x89, 0x4c, 0x85, 0x2d, 0xf0, 0x91, 0x78, 0x8e, 0xe6, 0x7e, 0x9a,
-    0x12, 0xa3, 0x99, 0x8,  0x3f, 0x93, 0x7f, 0x7e, 0x19, 0x95, 0x93, 0xf,
-    0x43, 0x86, 0x1b, 0xe8, 0x74, 0xdf, 0xe6, 0x89, 0xa,  0xbd, 0x37, 0x82,
-    0x5f, 0xa4, 0x84, 0xf1, 0x12, 0xc2, 0xbd, 0x45, 0x89, 0x17, 0xc9, 0x41,
-    0x87, 0x77, 0x59, 0x1b, 0x72, 0x3f, 0x69, 0x90, 0xa0, 0x43, 0x8f, 0xad,
-    0xc5, 0xa,  0x44, 0x33, 0x2b, 0xef, 0x7e, 0x81, 0x3a, 0x48, 0x43, 0x1a,
-    0xf5, 0x3b, 0x2d, 0x15, 0x57, 0x41, 0x29, 0x5a, 0x25, 0x93, 0xb7, 0xdd,
-    0x6,  0x9d, 0x96, 0xf7, 0x54, 0xd7, 0x9d, 0x1f, 0x96, 0x5f, 0xb4, 0xfb,
-    0x43, 0x8f, 0xed, 0xbe, 0x82, 0x7d, 0xbb, 0x84, 0xb9, 0x58, 0x8e, 0x2d,
-    0xc8, 0xff, 0x98, 0x2b, 0x8a, 0xe5, 0x2d, 0x38, 0xc7, 0x46, 0x63, 0x26,
-    0x27, 0x70, 0x29, 0x99, 0x61, 0x5b, 0x72, 0xee, 0x7d, 0x3b, 0xd7, 0x56,
-    0xfe, 0x96, 0xb0, 0xc0, 0x59, 0x91, 0x91, 0x43, 0xd6, 0x54, 0x7d, 0xce,
-    0xf6, 0x76, 0x20, 0xb1, 0x24, 0x77, 0x66, 0x16, 0xd3, 0x1,  0xb4, 0x6b,
-    0xdf, 0x3d, 0xc4, 0xab, 0xbf, 0xd1, 0x9d, 0xaa, 0x9f, 0xd0, 0x15, 0x2c,
-    0x3b, 0x1d, 0x19, 0xa3, 0x8,  0x1f, 0xfb, 0xb6, 0xb4, 0x4c, 0x2e, 0x62,
-    0x3f, 0x4e, 0x8,  0x55, 0x61, 0x17, 0xc,  0x60, 0xbe, 0xa,  0xf1, 0xf3,
-    0xe7, 0xbd, 0x6a, 0x6d, 0xe2, 0x48, 0x74, 0x65, 0xd1, 0x3c, 0x39, 0x85,
-    0xe3, 0xbc, 0x58, 0x59, 0x32, 0x49, 0x70, 0x8,  0xfd, 0x40, 0x76, 0xb7,
-    0xdf, 0x61, 0xb7, 0x6e, 0xcc, 0x40, 0xc2, 0x2,  0xb0, 0x74, 0x59, 0x2d,
-    0xf,  0xe,  0xd5, 0x56, 0x9b, 0x15, 0x1e, 0xcd, 0xdb, 0x27, 0xe5, 0x4c,
-    0x3f, 0x86, 0x9a, 0x10, 0x47, 0x68, 0x7b, 0xa9, 0xca, 0xa2, 0x5d, 0xc1,
-    0xd0, 0x26, 0x80, 0xb0, 0x14, 0x0,  0x33, 0xc4, 0xb7, 0x4d, 0x24, 0xcc,
-    0x99, 0xe9, 0x62, 0xad, 0xc,  0xa5, 0x4e, 0x1f, 0x6c, 0x2f, 0xc7, 0xb0,
-    0x62, 0xe7, 0xa6, 0xb9, 0x20, 0x44, 0x4a, 0xd8, 0xe3, 0x6,  0xbc, 0x26,
-    0x84, 0xc9, 0x94, 0xfa, 0xc0, 0xa5, 0xc0, 0x3a, 0xaa, 0x58, 0x96, 0x56,
-    0xe0, 0x6c, 0x4b, 0x75, 0xc3, 0x90, 0x46, 0xe0, 0xfd, 0x1d, 0xc5, 0x94,
-    0xb7, 0xf0, 0x37, 0x5d, 0x42, 0x38, 0x20, 0x75, 0x90, 0x95, 0x6b, 0xff,
-    0xcd, 0xf4, 0x56, 0xca, 0xf7, 0x26, 0xee, 0xaf, 0x75, 0x5f, 0x52, 0xdc,
-    0x3b, 0xac, 0x98, 0x7,  0x72, 0xbb, 0xb9, 0xb3, 0x38, 0x21, 0xac, 0x2c,
-    0xf9, 0xe9, 0xee, 0xbf, 0x93, 0x15, 0x75, 0xd6, 0xa7, 0xd,  0xae, 0x5e,
-    0x22, 0x79, 0x8e, 0x84, 0x17, 0xb2, 0x49, 0x8,  0x2c, 0x13, 0x12, 0x72,
-    0x70, 0x31, 0x4c, 0xba, 0x6c, 0x82, 0x10, 0x69, 0xf3, 0x43, 0x16, 0x47,
-    0x96, 0xbd, 0xc6, 0x43, 0xbd, 0xe0, 0xf6, 0xa5, 0x2a, 0x64, 0x7a, 0xe0,
-    0x4f, 0x91, 0xf2, 0x51, 0x42, 0x80, 0xba, 0x11, 0xf7, 0x61, 0x3f, 0xa9,
-    0xb9, 0x62, 0x21, 0x78, 0xef, 0x99, 0x68, 0x2a, 0x82, 0xcf, 0x62, 0xb3,
-    0xb7, 0xe9, 0x79, 0x69, 0x9c, 0x84, 0xcb, 0x3f, 0x59, 0x79, 0xc8, 0x17,
-    0x5b, 0x7,  0x74, 0xf0, 0x8c, 0x65, 0x85, 0x3,  0x48, 0x7b, 0x80, 0x3c,
-    0xcd, 0xe3, 0xf6, 0x50, 0xc1, 0x0,  0x3b, 0x14, 0xa,  0xfd, 0xcb, 0x46,
-    0x99, 0x31, 0xb5, 0xa2, 0x72, 0x94, 0x25, 0x10, 0xd4, 0x7f, 0x2a, 0x2d,
-    0x91, 0x47, 0xff, 0x55, 0xb3, 0x4f, 0x99, 0xfe, 0x9d, 0xbf, 0xb1, 0xf8,
-    0xec, 0xac, 0x6d, 0xc,  0xe0, 0x94, 0x49, 0xe2, 0x1b, 0x73, 0xcc, 0x9a,
-    0xc9, 0x95, 0xdb, 0x4b, 0x0,  0x86, 0xb9, 0x85, 0x42, 0xbc, 0xd5, 0xb8,
-    0xc3, 0x2b, 0x39, 0xa2, 0x8,  0xc8, 0x2e, 0x1,  0xf0, 0x39, 0x6d, 0x7e,
-    0xe1, 0x67, 0x42, 0xad, 0xc7, 0x3,  0x6f, 0x7a, 0x84, 0x5,  0xe0, 0x6a,
-    0xbe, 0x24, 0x59, 0x87, 0x46, 0xcf, 0x1d, 0x3b, 0xa,  0x8c, 0xd9, 0x8e,
-    0x60, 0xc1, 0x52, 0xb2, 0x18, 0xfc, 0x56, 0x1a, 0x20, 0x55, 0x8a, 0xa5,
-    0x41, 0x2e, 0x4d, 0x4d, 0x0,  0x11, 0x93, 0xe3, 0x7f, 0xdc, 0x7f, 0x2d,
-    0xde, 0xe3, 0x81, 0x1c, 0xf7, 0x11, 0xeb, 0x2a, 0xc3, 0x5f, 0x2c, 0xdb,
-    0x45, 0xa3, 0x9a, 0x94, 0x6c, 0x5c, 0xd6, 0x38, 0xf,  0xe6, 0x91, 0x13,
-    0xc4, 0xd7, 0xe2, 0x19, 0xfd, 0x90, 0x31, 0xc0, 0x9e, 0xeb, 0x2d, 0xfa,
-    0x8c, 0xdc, 0xee, 0x27, 0xb9, 0x62, 0xb0, 0xa2, 0x4b, 0x4f, 0xb6, 0xd8,
-    0x38, 0xe6, 0xb5, 0x39, 0xc0, 0xfa, 0x7,  0x62, 0xd2, 0xf0, 0x53, 0xa5,
-    0x10, 0x9e, 0x5a, 0xe6, 0xdf, 0x89, 0x9f, 0x14, 0x1c, 0x1c, 0xd4, 0x59,
-    0x85, 0x67, 0x90, 0xa2, 0xe6, 0xb0, 0xfa, 0x2d, 0x26, 0x7b, 0xcc, 0xab,
-    0xde, 0xd5, 0xc7, 0x24, 0xfd, 0xfe, 0xa7, 0x5a, 0x77, 0x63, 0x1c, 0x8e,
-    0xe8, 0x85, 0x83, 0x16, 0x77, 0x44, 0x34, 0xda, 0xd4, 0x98, 0x1d, 0x22,
-    0xa5, 0xe6, 0x95, 0xe7, 0x7b, 0xd8, 0xfa, 0xde, 0xdf, 0x5,  0x27, 0x4b,
-    0x29, 0x80, 0xbf, 0x5f, 0x87, 0x14, 0xe0, 0xa0, 0xa0, 0xe9, 0xc7, 0xc1,
-    0xa1, 0x48, 0x22, 0x30, 0x37, 0xb3, 0x9,  0xd9, 0xa6, 0x18, 0x54, 0xe,
-    0xb1, 0x3d, 0x48, 0xa4, 0x63, 0x70, 0x3e, 0xcb, 0x1d, 0x9b, 0x6f, 0x97,
-    0xd2, 0xbf, 0x22, 0x93, 0xd0, 0x51, 0xdf, 0x9c, 0xf8, 0x47, 0x57, 0x74,
-    0xc8, 0x40, 0x1b, 0x51, 0x3a, 0x14, 0x4b, 0x6e, 0xce, 0xd5, 0x38, 0x81,
-    0x94, 0xda, 0x2f, 0x39, 0x84, 0x46, 0x8a, 0xf,  0x46, 0x6f, 0x7b, 0x5e,
-    0x7d, 0x53, 0x30, 0x7,  0xea, 0xb,  0xaa, 0xd0, 0x7a, 0x98, 0xf4, 0xb8,
-    0x51, 0x10, 0xca, 0x83, 0x72, 0x10, 0x86, 0x91, 0x81, 0x12, 0x53, 0x64,
-    0x9a, 0xc8, 0xab, 0x9f, 0xd0, 0x82, 0x99, 0xb1, 0x43, 0x97, 0xc8, 0xa5,
-    0x8,  0x7,  0xe,  0x23, 0xdb, 0xaf, 0x2d, 0x31, 0x3a, 0x87, 0xfa, 0x77,
-    0x28, 0x49, 0x5e, 0x2c, 0x82, 0x40, 0x15, 0xa5, 0xb4, 0x46, 0x1,  0x93,
-    0x5c, 0x19, 0x56, 0x67, 0x39, 0x23, 0x76, 0x67, 0x8d, 0xa9, 0xb4, 0x44,
-    0x59, 0x1e, 0x5e, 0x93, 0x4c, 0x6e, 0xb0, 0x30, 0xd3, 0x87, 0x57, 0xfa,
-    0xa5, 0xee, 0x42, 0xa0, 0xe5, 0x8d, 0x15, 0x8b, 0xd4, 0x12, 0x1c, 0x60,
-    0xdf, 0xc,  0x27, 0xdf, 0x8f, 0x1,  0x7c, 0x31, 0xae, 0xd9, 0xd0, 0xad,
-    0x3,  0x27, 0x32, 0x28, 0xbb, 0xd8, 0xb,  0x3b, 0xd,  0x3e, 0x9c, 0x3a,
-    0x73, 0x8b, 0xd,  0x52, 0x8d, 0x4,  0x11, 0xe6, 0x65, 0x61, 0xcb, 0x9b,
-    0x89, 0xe2, 0x1d, 0x43, 0xb3, 0xd5, 0x1,  0x1b, 0x0,  0xe0, 0xd1, 0x10,
-    0x26, 0xf0, 0xda, 0x2,  0x56, 0xf4, 0x10, 0x39, 0xab, 0xc,  0x2f, 0x57,
-    0x66, 0x54, 0x42, 0x72, 0x78, 0x45, 0x4c, 0x1c,
-};
-const uint8_t* kAltGameImages1x[] = {
-    kAltGameImages1xA, kAltGameImages1xB, kAltGameImages1xC,
-    kAltGameImages1xD, kAltGameImages1xE, kAltGameImages1xF,
-};
-constexpr int kAltGameImagesCount = base::size(kAltGameImages1x);
-const size_t kAltGameImages1xLength[] = {
-    base::size(kAltGameImages1xA), base::size(kAltGameImages1xB),
-    base::size(kAltGameImages1xC), base::size(kAltGameImages1xD),
-    base::size(kAltGameImages1xE), base::size(kAltGameImages1xF),
-};
-static_assert(base::size(kAltGameImages1xLength) == kAltGameImagesCount, "");
-const uint8_t kAltGameImages2xA[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x9b, 0xf6, 0x93, 0x5e,
-    0xf4, 0xc1, 0x6b, 0xa3, 0x71, 0x3b, 0xf3, 0x64, 0x61, 0xb5, 0xd1, 0x1d,
-    0xb,  0xe5, 0xb6, 0x81, 0x61, 0x56, 0xd0, 0xa3, 0xd7, 0x75, 0xaa, 0x55,
-    0x2e, 0x56, 0xf9, 0xf2, 0x1a, 0xe2, 0x93, 0x19, 0x47, 0xf4, 0x1d, 0x20,
-    0xad, 0x83, 0x41, 0xa,  0x31, 0x36, 0x5b, 0x1e, 0x5e, 0xfe, 0x5e, 0x37,
-    0x96, 0x3e, 0x1c, 0x34, 0xc4, 0xcd, 0x13, 0x3a, 0xc5, 0xc,  0xc5, 0x21,
-    0xaf, 0x58, 0x9c, 0x5a, 0xc9, 0x90, 0xfc, 0x2b, 0x4b, 0xbc, 0x27, 0x96,
-    0x57, 0xb5, 0x17, 0x99, 0x6,  0x48, 0x29, 0x67, 0x16, 0x28, 0xd6, 0xfd,
-    0xb0, 0xe7, 0x59, 0x41, 0xa3, 0xbf, 0x5,  0xce, 0x26, 0xc4, 0x61, 0x2b,
-    0xf1, 0xd,  0x2b, 0x39, 0x5a, 0x99, 0xb6, 0x62, 0x30, 0x4,  0xd2, 0x4d,
-    0x68, 0x23, 0x9a, 0x5b, 0xd9, 0x7d, 0xe6, 0xeb, 0xba, 0x96, 0x91, 0xb6,
-    0x3d, 0x9a, 0x54, 0xaa, 0xe7, 0x9c, 0xd3, 0x78, 0x11, 0x70, 0xd4, 0xdc,
-    0xcd, 0x39, 0xbb, 0x98, 0x38, 0xb0, 0x82, 0x3c, 0x1,  0xed, 0x6c, 0xc2,
-    0x82, 0x2,  0xc8, 0x6a, 0xcb, 0x26, 0x7a, 0x12, 0xd0, 0x10, 0xc3, 0xaa,
-    0x95, 0x2f, 0x5c, 0x80, 0xc,  0xba, 0xaf, 0xf2, 0x75, 0x51, 0x95, 0xf9,
-    0xba, 0xa7, 0x71, 0x2f, 0x38, 0x9a, 0x23, 0xfd, 0xf6, 0x7b, 0x1a, 0xcd,
-    0xdb, 0xda, 0xf4, 0x4d, 0x54, 0xc5, 0x7,  0xfa, 0x53, 0x4f, 0x7e, 0x8,
-    0x4f, 0x20, 0x69, 0x20, 0x8d, 0xc8, 0xb6, 0x1a, 0x80, 0x79, 0x5e, 0x86,
-    0x8b, 0xb,  0xc0, 0x2a, 0x40, 0x58, 0x2d, 0x6b, 0x31, 0x5d, 0xee, 0x24,
-    0x9,  0xa1, 0x14, 0x9c, 0x40, 0x44, 0x36, 0x3a, 0x62, 0x7,  0xe4, 0x2f,
-    0x38, 0xa2, 0x3,  0x72, 0x95, 0xf1, 0xa3, 0x86, 0x6d, 0x56, 0x4c, 0x80,
-    0xf6, 0xa4, 0x4d, 0xb6, 0x1c, 0xad, 0x7c, 0x24, 0x2f, 0x57, 0x12, 0xf,
-    0x26, 0x18, 0xef, 0xa5, 0xa2, 0xe8, 0x5e, 0xc5, 0x81, 0x1f, 0x29, 0x85,
-    0x5a, 0x3c, 0x39, 0x2c, 0x4d, 0x23, 0x5b, 0x92, 0xf5, 0xe4, 0xf3, 0xc6,
-    0x56, 0xde, 0xc0, 0x6b, 0x54, 0x18, 0x8b, 0xa8, 0x45, 0x5,  0xde, 0xf8,
-    0x60, 0xa6, 0x75, 0x30, 0x5d, 0x3b, 0x7b, 0x99, 0xfc, 0x61, 0xd9, 0xe7,
-    0xc4, 0x13, 0xd8, 0x54, 0xde, 0x1c, 0xe4, 0xf1, 0x5c, 0xf6, 0x67, 0x51,
-    0x33, 0x79, 0xcd, 0x10, 0xaa, 0xc7, 0xb4, 0xdf, 0xa3, 0x4a, 0x3b, 0xc1,
-    0x5e, 0x14, 0x6c, 0xca, 0x4c, 0xbe, 0xef, 0x4b, 0x70, 0x6,  0xbb, 0xc1,
-    0xc8, 0x4,  0xf9, 0x1d, 0x93, 0xb5, 0x8c, 0x0,  0xda, 0x73, 0xc7, 0x7a,
-    0xc8, 0xdc, 0xec, 0x92, 0xe0, 0x94, 0x41, 0x1a, 0xab, 0xce, 0x60, 0x42,
-    0x8e, 0x7c, 0xb6, 0x93, 0xdb, 0xc2, 0xe5, 0x50, 0xc1, 0x52, 0x46, 0x2d,
-    0xf6, 0xa2, 0x22, 0x26, 0x2d, 0xcd, 0x4b, 0x1f, 0x86, 0x22, 0xe5, 0x95,
-    0x1,  0x57, 0xe4, 0x1f, 0x3f, 0xd2, 0xb3, 0xcb, 0xf0, 0x44, 0x9e, 0x5a,
-    0xbb, 0xc7, 0x27, 0x88, 0x92, 0x81, 0x7d, 0x50, 0xfc, 0xf2, 0x18, 0x21,
-    0x66, 0x2c, 0x9b, 0xb5, 0x42, 0x8a, 0x3,  0xf9, 0x6b, 0x77, 0x6b, 0xc8,
-    0x8a, 0xf8, 0xa,  0x51, 0xa8, 0xbc, 0x12, 0xe,  0x6b, 0xbc, 0x57, 0xa3,
-    0x49, 0xe2, 0xee, 0x2e, 0xe5, 0x5e, 0x12, 0xfa, 0xe1, 0x59, 0xee, 0x8b,
-    0x2,  0xad, 0xac, 0xd9, 0x3b, 0x2e, 0xf6, 0x16, 0xee, 0x98, 0x8b, 0x1d,
-    0xd6, 0x14, 0x6b, 0x61, 0x60, 0x88, 0x96, 0x89, 0x2b, 0xaf, 0x23, 0xde,
-    0xb9, 0xba, 0x6b, 0xc4, 0x82, 0xe5, 0x24, 0x9,  0x3d, 0x32, 0x65, 0x8e,
-    0x68, 0x8d, 0xec, 0x94, 0x3d, 0x5,  0xc1, 0xbd, 0x87, 0x87, 0xaa, 0x53,
-    0x27, 0xfe, 0xf9, 0x12, 0x74, 0xc7, 0xaf, 0x42, 0x7d, 0x1b, 0x23, 0xbc,
-    0x41, 0xa1, 0xba, 0xa6, 0x1f, 0x62, 0x49, 0x32, 0x90, 0x38, 0xa8, 0xec,
-    0x83, 0xa4, 0xd1, 0x34, 0x2,  0x63, 0xb1, 0xaf, 0xd9, 0x78, 0x55, 0x90,
-    0x3d, 0x1,  0x74, 0xf1, 0x2a, 0x37, 0x2f, 0x46, 0x16, 0xb9, 0xa6, 0x4f,
-    0xf6, 0x37, 0xc6, 0xe5, 0x7e, 0x50, 0x4e, 0x49, 0x31, 0x31, 0x61, 0x1f,
-    0x8a, 0xe7, 0xf1, 0x7a, 0xd6, 0xd3, 0x4a, 0xbf, 0xc1, 0xd9, 0x7b, 0x68,
-    0xa6, 0x9f, 0xd3, 0x69, 0xec, 0x9d, 0xe5, 0x9d, 0xe9, 0x35, 0xdc, 0x55,
-    0x21, 0xe3, 0xd2, 0x63, 0x71, 0xf,  0xb6, 0xbd, 0x9c, 0x47, 0x46, 0x61,
-    0x1f, 0xf0, 0x44, 0x77, 0x7d, 0xfa, 0xf9, 0x32, 0x5f, 0x71, 0x21, 0xdb,
-    0x55, 0x41, 0x64, 0xe2, 0xe6, 0xc4, 0x5,  0xbd, 0x76, 0xfc, 0x44, 0x6e,
-    0xef, 0xd7, 0x5,  0x61, 0x94, 0x58, 0xec, 0xcc, 0xdc, 0xd3, 0x1c, 0x4f,
-    0x38, 0xa1, 0x28, 0xc,  0xf2, 0x18, 0xa8, 0xf6, 0xb0, 0x4f, 0x29, 0x10,
-    0x4b, 0x52, 0x76, 0xb1, 0xc1, 0x6b, 0xb9, 0xe2, 0xd1, 0xd7, 0x4e, 0x82,
-    0x48, 0xb6, 0xc8, 0xb3, 0x42, 0x2f, 0xdb, 0xd3, 0x7,  0x6,  0x60, 0xb9,
-    0x48, 0x55, 0xdc, 0x27, 0xa3, 0x9d, 0xfa, 0xc2, 0x43, 0xfc, 0xd2, 0xfd,
-    0x60, 0x65, 0xd5, 0x50, 0xc,  0x6c, 0x3c, 0x71, 0xdd, 0x19, 0x97, 0xba,
-    0xc3, 0x5,  0x2b, 0xcd, 0xd2, 0xf1, 0x0,  0x35, 0x5a, 0x29, 0xc6, 0xf0,
-    0x93, 0xd9, 0x2a, 0xf0, 0x22, 0x9f, 0xc0, 0x33, 0x9b, 0xd0, 0x46, 0xae,
-    0x1d, 0xe9, 0x65, 0x3d, 0x66, 0xf0, 0xc0, 0xcc,
-};
-const uint8_t kAltGameImages2xB[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x29, 0xa3, 0xa8, 0xaa,
-    0x9c, 0x8a, 0xfe, 0x4,  0xe6, 0xc8, 0x54, 0xf6, 0x2b, 0xa1, 0x37, 0xe8,
-    0x44, 0x59, 0x55, 0xf7, 0x6,  0x26, 0x3c, 0x46, 0xcf, 0x87, 0xd,  0xfa,
-    0xc,  0x4,  0xb8, 0xd1, 0x9a, 0x96, 0x2,  0x3f, 0xa3, 0x31, 0xdd, 0x26,
-    0xc5, 0xb4, 0x97, 0xd9, 0xf6, 0x1a, 0xc8, 0xe9, 0x38, 0x9f, 0x52, 0xc3,
-    0xb7, 0x9b, 0x4a, 0x4a, 0xc1, 0x8c, 0x27, 0x79, 0x5b, 0xc,  0x95, 0xe6,
-    0xa0, 0x4b, 0xa7, 0x70, 0x6d, 0x54, 0xdb, 0x20, 0x56, 0x5f, 0xa4, 0x13,
-    0x4d, 0x97, 0xff, 0x3d, 0xf4, 0x48, 0x3e, 0x74, 0x41, 0x9a, 0x6c, 0x72,
-    0x4c, 0xc1, 0x89, 0xcd, 0xf,  0xdb, 0x7a, 0x47, 0xf,  0x2d, 0x3d, 0xaf,
-    0xff, 0x20, 0x6,  0x55, 0x78, 0x3b, 0xe3, 0xbc, 0xd1, 0x56, 0xd4, 0xbc,
-    0x0,  0x4a, 0x9b, 0x48, 0x7b, 0xbd, 0x18, 0x10, 0x6e, 0xe0, 0xbb, 0xcf,
-    0xe7, 0xb0, 0x82, 0xd5, 0x50, 0x6c, 0x90, 0xdd, 0x32, 0xc6, 0xd,  0xc2,
-    0x64, 0x13, 0xae, 0xa1, 0x74, 0xde, 0x23, 0x78, 0xdd, 0xd,  0x4f, 0x8b,
-    0xe4, 0xa3, 0x31, 0x95, 0xde, 0x86, 0xd3, 0x9a, 0x73, 0x3d, 0x44, 0x23,
-    0xaa, 0xbb, 0xf9, 0x34, 0x8f, 0xba, 0x53, 0x50, 0xa4, 0x50, 0x8b, 0x51,
-    0x63, 0xe3, 0xd0, 0x1e, 0x9c, 0x1c, 0x93, 0x12, 0x67, 0xe0, 0xf1, 0xf9,
-    0x57, 0x26, 0x97, 0x16, 0x84, 0xe5, 0x14, 0xd1, 0x18, 0x65, 0xb0, 0x2c,
-    0xab, 0x80, 0xd7, 0x76, 0xd3, 0xed, 0x15, 0xe3, 0xc5, 0xbc, 0x0,  0xf5,
-    0x48, 0x63, 0x25, 0xb3, 0x23, 0x30, 0x17, 0x2a, 0x1f, 0x13, 0x43, 0x1a,
-    0x6f, 0x52, 0xb7, 0x49, 0x47, 0x1b, 0xaf, 0x41, 0xeb, 0x6e, 0x8e, 0x4c,
-    0xe6, 0x20, 0xfb, 0x63, 0xd4, 0x98, 0xe,  0xff, 0xb9, 0xbb, 0x91, 0x17,
-    0x10, 0x9f, 0x7f, 0xb2, 0xf0, 0xae, 0x57, 0xba, 0x96, 0x1,  0xbb, 0x4b,
-    0x7e, 0xd7, 0xc4, 0xc,  0xdb, 0xa9, 0x36, 0x23, 0x6b, 0xaa, 0x3d, 0x8b,
-    0x11, 0x7a, 0x17, 0xe4, 0x52, 0x84, 0xc4, 0x5f, 0x95, 0xf7, 0xc5, 0x9,
-    0x9b, 0xb,  0xc2, 0x8c, 0x4,  0xd3, 0x32, 0xb7, 0xa9, 0x86, 0x1e, 0x19,
-    0xf0, 0xf3, 0xb9, 0x9b, 0xee, 0x17, 0x9f, 0xa,  0x35, 0xd6, 0x5e, 0xb1,
-    0x72, 0x92, 0xf,  0x7,  0x50, 0x41, 0x9a, 0xef, 0x35, 0xca, 0xbf, 0xd4,
-    0x3e, 0x90, 0x83, 0xfa, 0xa7, 0x52, 0x18, 0x7b, 0xb4, 0x8a, 0x1d, 0x62,
-    0x8b, 0xfd, 0x36, 0xda, 0x20, 0x40, 0x33, 0x14, 0x50, 0xb2, 0xfd, 0xc8,
-    0xc6, 0x76, 0x82, 0x81, 0xda, 0xb6, 0xd7, 0x47, 0xda, 0x4b, 0xc9, 0xac,
-    0x13, 0x87, 0xa2, 0x53, 0xc,  0xbb, 0x32, 0x1,  0xba, 0x24, 0xcb, 0x76,
-    0xea, 0xa0, 0x9c, 0x70, 0xd8, 0x3b, 0x52, 0x75, 0xdc, 0x5,  0x40, 0x0,
-    0xa2, 0xe3, 0x4c, 0xc5, 0x5f, 0x64, 0xaa, 0xfa, 0x64, 0x9,  0x58, 0x4c,
-    0x4a, 0x35, 0xf0, 0x99, 0xd,  0x44, 0xe9, 0x9b, 0x32, 0x9b, 0xa0, 0x84,
-    0x81, 0x2,  0xef, 0x65, 0x3b, 0x6b, 0x7f, 0x1b, 0x89, 0x59, 0x9a, 0xd5,
-    0x90, 0x44, 0xb9, 0xe7, 0x55, 0xd2, 0x3d, 0x16, 0x68, 0xdd, 0x38, 0xf0,
-    0xb2, 0xc6, 0x3c, 0x49, 0xe6, 0xf8, 0x7f, 0xc5, 0x87, 0x67, 0x1c, 0x36,
-    0x87, 0xf7, 0x4e, 0xa5, 0x6f, 0x2,  0xab, 0x44, 0xf9, 0xc,  0xee, 0x7d,
-    0x82, 0xe7, 0xbf, 0xff, 0x69, 0xf8, 0xa6, 0xbb, 0xf6, 0x91, 0x11, 0x40,
-    0x68, 0xc9, 0x94, 0x7b, 0xd4, 0x31, 0xf2, 0x70, 0x49, 0x43, 0x55, 0xa9,
-    0xac, 0xce, 0x7d, 0xbf, 0xed, 0x2,  0x9b, 0x57, 0x4c, 0xc,  0x1f, 0xcb,
-    0xc5, 0xc7, 0xa3, 0xc0, 0xe7, 0xd8, 0xf4, 0x21, 0xe6, 0xa4, 0x95, 0x27,
-    0x1a, 0x52, 0xe5, 0xd7, 0xf,  0x45, 0x2d, 0xd2, 0x85, 0x3c, 0xbb, 0xa0,
-    0x3,  0xab, 0x7c, 0xfb, 0xc8, 0x4c, 0x42, 0x2a, 0x68, 0x4e, 0xc9, 0xdc,
-    0xbd, 0x11, 0xf2, 0xe2, 0xf1, 0x5b, 0x9,  0x81, 0x28, 0xe3, 0xb0, 0x4a,
-    0x38, 0xbc, 0xb3, 0x14, 0xcc, 0x76, 0x24, 0x44, 0x99, 0x4a, 0x8f, 0x8f,
-    0x89, 0x54, 0xc,  0x7b, 0xdd, 0x2e, 0xbf, 0xc7, 0xa4, 0x44, 0xec, 0x22,
-    0x8c, 0xa4, 0x3b, 0xce, 0x94, 0x64, 0xc6, 0x8e, 0xde, 0xa6, 0x6c, 0x67,
-    0xd2, 0x3d, 0xc9, 0xf3, 0x41, 0x58, 0xf7, 0x3f, 0x15, 0xa2, 0xdb, 0x97,
-    0xa8, 0x9,  0x60, 0x28, 0x62, 0xbd, 0xe0, 0xa9, 0x4f, 0x9b, 0x66, 0x30,
-    0x51, 0x6e, 0x84, 0xf2, 0xdd, 0xab, 0x5a, 0x48, 0x1b, 0x7,  0x87, 0x2f,
-    0xfc, 0x3c, 0x6b, 0x49, 0x34, 0x71, 0xd8, 0x32, 0x2a, 0x20, 0x38, 0xdb,
-    0xb7, 0x20, 0xba, 0x87, 0xcd, 0x1a, 0x19, 0xf6, 0x7b, 0x91, 0x70, 0x3d,
-    0x3a, 0xff, 0xd3, 0xa4, 0x7f, 0x32, 0x62, 0xad, 0x2c, 0x29, 0xae, 0x6,
-    0xe5, 0x90, 0x88, 0x76, 0x92, 0x64, 0x57, 0xe6, 0x37, 0x68, 0x2a, 0xb9,
-    0x12, 0x4c, 0xd6, 0xc,  0x4,  0xd9, 0x9f, 0x68, 0xac, 0x32, 0x1a, 0x33,
-    0xbc, 0x83, 0x32, 0x45, 0xd3, 0x2d, 0x16, 0x8e, 0xaa, 0xcc, 0x85, 0x8c,
-    0xd3, 0xda, 0xa1, 0x82, 0xfa, 0x8d, 0x0,  0x1b, 0xad, 0x83, 0xd1, 0xa2,
-    0xb9, 0x4f, 0x41, 0x1e, 0xe3, 0x1f, 0x1a, 0x18, 0x9a, 0x91, 0x2c, 0x52,
-    0xa5, 0x14, 0xc4, 0xaa, 0x33, 0x20, 0xfc, 0xd5, 0x2b, 0xe0, 0x38, 0x21,
-    0x9d, 0xeb, 0x21, 0x16, 0x34, 0xd5, 0x4d, 0x84, 0x95, 0x46, 0x3a, 0xa3,
-    0xe8, 0xf5, 0xe6, 0xde, 0x9e, 0x88, 0x1f, 0xdd, 0x25, 0x6b, 0x30, 0x2f,
-    0x32, 0xe3, 0x60, 0x1a, 0xc6, 0x6c, 0xe6, 0x63, 0x5c, 0xa7, 0x1d, 0xa2,
-    0x43, 0x6d, 0x0,  0x1b, 0x64, 0xce, 0xb3, 0x38, 0xe,  0xae, 0x5b, 0x2b,
-    0x1,  0xa7, 0x4c, 0x8b, 0x9e, 0xbc, 0x5a, 0x8a, 0x46, 0x4,  0xa4, 0xb2,
-    0xfb, 0x12, 0x61, 0xe5, 0x84, 0x63, 0x1e, 0x13, 0x9c, 0xc7, 0x19, 0x37,
-    0x9,  0xb9, 0x6e, 0xcf, 0x64, 0xed, 0x41, 0xb1, 0x8,  0x82, 0x31, 0xc9,
-    0xda, 0x2,  0x80, 0x67, 0xf9, 0x85, 0xcf, 0x9f, 0x26, 0xae, 0xfb, 0x3b,
-    0x2f, 0x80, 0x38, 0x33, 0x22, 0x34, 0x4,  0xec, 0x5b, 0xc8, 0x55, 0xd6,
-    0xa6, 0xef, 0x1d, 0x68, 0x39, 0x70, 0xc4, 0xdc, 0x7e, 0xba, 0x33, 0x9f,
-    0xd1, 0xb2, 0xd5, 0x56, 0x95, 0xde, 0x38, 0xd5, 0x26, 0x5d, 0x23, 0xd8,
-    0xca, 0xd,  0xe2, 0xdc, 0x3c, 0x61, 0xcb, 0x1d, 0x51, 0xfc, 0x5e, 0x42,
-    0x97, 0x83, 0x72, 0xc5, 0xa5, 0x6c, 0xb6, 0x90, 0xa3, 0xe7, 0xda, 0xb2,
-    0x8,  0xfc, 0x7e, 0x41, 0x3b, 0xa2, 0x4a, 0xa9, 0x1b, 0x6b, 0x42, 0x1,
-    0x5,  0x5b, 0x86, 0xa5, 0x9f, 0x40, 0x4f, 0x87, 0x2e, 0x5f, 0xda, 0x39,
-    0x9a, 0xdc, 0x67, 0xff, 0xf8, 0x9d, 0xcb, 0x49, 0xd4, 0x9,  0x41, 0x2d,
-    0xf7, 0x2e, 0x44, 0xe,  0x93, 0x96, 0xf2, 0x76, 0xb5, 0xa5, 0x61, 0x3a,
-    0x51, 0x9a, 0xa9, 0xb,  0xc2, 0xc1, 0x7d, 0x3d, 0xfb, 0xf4, 0xd9, 0x5f,
-    0xbe, 0xa,  0xa2, 0x95, 0xaf, 0x42, 0xf6, 0x5e, 0xc4, 0x1d, 0x34, 0x26,
-    0x1,  0x37, 0xbc, 0xa0, 0x4e, 0x4c, 0x1a, 0xd4, 0x10, 0x5f, 0x5a, 0xe4,
-    0x69, 0x3e, 0x49, 0xdc, 0x57, 0x56, 0x7e, 0x51, 0x1b, 0x86, 0x6e, 0x87,
-    0x4e, 0x40, 0xa4, 0x94, 0x5,  0xbc, 0xf0, 0xaa, 0xf0, 0xef, 0x2d, 0x39,
-    0xf1, 0x42, 0x73, 0x4,  0xe4, 0x17, 0x23, 0xec, 0xdd, 0x84, 0x3,  0x2,
-    0x4,  0x6b, 0x8c, 0x5a, 0x78, 0xbe, 0x38, 0x61, 0x53, 0x17, 0xc3, 0xcc,
-    0xb9, 0x68, 0xc9, 0x1d, 0x6d, 0x37, 0xfb, 0xe3, 0xce, 0xa7, 0x1,  0xb7,
-    0xe4, 0x2d, 0xc1, 0xcc, 0xae, 0xb4, 0xf9, 0xfb, 0x53, 0x19, 0x6f, 0xdd,
-    0x30, 0xed, 0x54, 0x74, 0xc2, 0x70, 0xec, 0xf8, 0xde, 0xd3, 0x5e, 0x22,
-    0xe5, 0xab, 0xc2, 0x19, 0xec, 0x7,  0xcf, 0x28, 0x8,  0xdb, 0xe0, 0x69,
-    0x82, 0x58, 0xf6, 0x8d, 0xe9, 0xe5, 0xab, 0x50, 0xa0, 0x63, 0xd,  0x8a,
-    0x23, 0x7c, 0xc6, 0x46, 0x4a, 0x18, 0x1e, 0xad, 0x76, 0xfb, 0xb7, 0xc5,
-    0x20, 0xa0, 0xa1, 0xfb, 0xa0, 0x11, 0x4a, 0xdf, 0xd2, 0xb3, 0x4b, 0xc2,
-    0xce, 0xa9, 0x34, 0xdc, 0xaa, 0x3,  0xcc, 0x45, 0x3a, 0xe9, 0xa5, 0x9a,
-    0xc3, 0xaf, 0xc6, 0xb7, 0x7e, 0x73, 0x4c, 0x0,  0x3e, 0x26, 0x35, 0x50,
-    0x6a, 0x1f, 0x24, 0x6e, 0xd2, 0x1a, 0x50, 0xb3, 0xa6, 0x4c, 0xfe, 0xd2,
-    0xc7, 0x9d, 0xa4, 0xc,  0x5d, 0xc4, 0x36, 0xf6, 0xe9, 0xc5, 0xfe, 0x4d,
-    0x87, 0xe3, 0x74, 0xb5, 0xd6, 0x96, 0x6f, 0x6,  0x2c, 0x34, 0x2d, 0x4,
-    0xc8, 0xfe, 0xbb, 0x9,  0xa7, 0x32, 0xd3, 0x2d, 0xfd, 0xb1, 0x9,  0xe6,
-    0x64, 0x47, 0x5e, 0x5d, 0x9e, 0xe,  0xaf, 0x2,  0x9d, 0xbc, 0x20, 0x21,
-    0xa1, 0x75, 0x67, 0x4e, 0x19, 0x7a, 0xa,  0x3b, 0x65, 0xe1, 0xec, 0x6e,
-    0xbe, 0xc3, 0x1d, 0x77, 0x3b, 0x97, 0xb5, 0xf1, 0x4a, 0xaf, 0x9e, 0x2e,
-    0xdb, 0xb,  0x49, 0xac, 0x11, 0xda, 0x60, 0x83, 0x23, 0xb7, 0xd9, 0x92,
-    0x8f, 0x6c, 0x6f, 0xaf, 0xea, 0x18, 0xb0, 0x53, 0x11, 0x84, 0x14, 0x31,
-    0x78, 0x6d, 0x9,  0x25, 0x4c, 0x90, 0x8e, 0xe4, 0x7b, 0x79, 0x1f, 0x17,
-    0x64, 0x40, 0x78, 0x8e, 0x7f, 0x27, 0x5b, 0x10, 0x75, 0x13, 0xce, 0xd2,
-    0x5b, 0xe2, 0xca, 0x16, 0x23, 0xee, 0x92, 0xd6, 0xea, 0x7e, 0xde, 0x68,
-    0x98, 0x73, 0x3f, 0x1c, 0x9c, 0x1e, 0x67, 0xfb, 0x92, 0x10, 0x51, 0xe1,
-    0x97, 0x15, 0x5d, 0xbb, 0x26, 0x7f, 0xee, 0xb,  0x7d, 0xf6, 0xc6, 0x81,
-    0x23, 0xd5, 0x55, 0xae, 0x86, 0x60, 0x5d, 0x8c, 0x0,  0x55, 0x1e, 0xb7,
-    0x4b, 0x1c, 0xc5, 0x3e, 0x5b, 0x1f, 0x89, 0x47, 0x17, 0x28, 0x2b, 0x46,
-    0x2b, 0xc3, 0x21, 0xdf, 0x1c, 0x20, 0x22, 0x49, 0xea, 0xe8, 0xb5, 0xff,
-    0xfd, 0xd0, 0x91, 0x27, 0xe0, 0x15, 0x3f, 0x15, 0xca, 0xd4, 0xe1, 0x28,
-    0xa0, 0x7a, 0xf1, 0xb0, 0xa5, 0x6a, 0x62, 0x90, 0x4e, 0xdc, 0x9d, 0xe,
-    0x94, 0x31, 0x5f, 0x8f, 0xbf, 0x15, 0xa5, 0xec, 0x9f, 0x66, 0x6,  0xf1,
-    0xe8, 0x97, 0x8f, 0xe1, 0xc6, 0xd3, 0xea, 0xc9, 0xa5, 0x50, 0xe1, 0xdc,
-    0x91, 0x18, 0xfb, 0xf1, 0x48, 0xe4, 0x91, 0x1a, 0xc,  0xeb, 0xf4, 0xd,
-    0xc3, 0x20, 0x3a, 0xac, 0xf7, 0x4b, 0x4c, 0xa2, 0xab, 0x4a, 0x4a, 0x92,
-    0xe3, 0x57, 0x94, 0xf7, 0x92, 0x90, 0xb2, 0xa2, 0xd1, 0x9d, 0xcc, 0x4e,
-    0x6a, 0x28, 0x83, 0xd3, 0xb8, 0x40, 0x38, 0x1b, 0x4f, 0x8a, 0x25, 0x95,
-    0x2d, 0xde, 0xca, 0xc0, 0xc6, 0x15, 0xe7, 0xc9, 0x7f, 0x89, 0xbf, 0x57,
-    0xc3, 0x3a, 0x9c, 0xd9, 0x88, 0x97, 0x58, 0xa7, 0xe5, 0x2d, 0xec, 0x47,
-    0x87, 0x9,  0x88, 0x21, 0x87, 0x39, 0xc7, 0xbe, 0x40, 0xa,  0x2b, 0x17,
-    0x8b, 0x82, 0x4f, 0xa3, 0x31, 0x5,  0x63, 0xfa, 0x36, 0x83, 0x33, 0x28,
-    0x51, 0x38, 0xfd, 0xd7, 0xa3, 0x3b, 0xb3, 0xe8, 0x27, 0x3,  0xda, 0xf8,
-    0x35, 0x24, 0x78, 0xcd, 0x20, 0xf6, 0xcd, 0x34, 0xca, 0xf2, 0x66, 0xa3,
-    0xaf, 0xd0, 0x29, 0xab, 0xf0, 0x76, 0x5e, 0x23, 0x35, 0xf7, 0x91, 0xa6,
-    0x13, 0x2a, 0x91, 0xe8, 0x56, 0x38, 0x1d, 0x8a, 0x2c, 0xad, 0xe9, 0x6f,
-    0x50, 0x7,  0x83, 0x64, 0xd5, 0x40, 0xd8, 0x9,  0x2c, 0x7d, 0x14, 0x47,
-    0xaa, 0xf5, 0xdb, 0x62, 0x5e, 0x14, 0xa7, 0x78, 0xa6, 0x1b, 0x8c, 0x5b,
-    0xc5, 0xef, 0x79, 0x69, 0xfd, 0x78, 0xa9, 0x31, 0xb9, 0xf,  0x51, 0xb3,
-    0xe8, 0x2b, 0x51, 0x28, 0x49, 0x8e, 0x86, 0x36, 0x9d, 0x57, 0x45, 0x68,
-    0xd4, 0xe1, 0xe,  0x12, 0x76, 0x39, 0x77, 0x6f, 0x5a, 0x1f, 0x2f, 0xad,
-    0x60, 0x4e, 0x93, 0xdf, 0x73, 0xdd, 0x49, 0x7d, 0xdb, 0x23, 0x8b, 0xaf,
-    0xfa, 0xef, 0xf0, 0xee, 0x30, 0xf6, 0x25, 0x71, 0xa,  0x24, 0x78, 0xe9,
-    0xaa, 0x2f, 0x12, 0x44, 0x8f, 0x97, 0x6c, 0x7,  0x21, 0xb0, 0x2f, 0x9b,
-    0xd,  0x19, 0x6b, 0xc3, 0xb7, 0x31, 0x85, 0x1c, 0xe9, 0xc2, 0xdd, 0x78,
-    0xef, 0xf7, 0xed, 0x31, 0xa2, 0x2d, 0x64, 0xcf, 0xcf, 0xa6, 0x42, 0x28,
-    0x62, 0x22, 0xb8, 0x2e, 0xf8, 0xfc, 0xd0, 0xe5, 0xcf, 0x27, 0x7d, 0x2b,
-    0x37, 0xbe, 0xd4, 0xb5, 0x6e, 0xd5, 0xbc, 0xfe, 0x77, 0x19, 0x7f, 0xa4,
-    0x19, 0xcb, 0xcb, 0x63, 0x9c, 0x7c, 0x5,  0xfd, 0xf4, 0xe7, 0x43, 0x83,
-    0xca, 0xbd, 0x72, 0x48, 0x18, 0xb4, 0xe3, 0xa,  0xe,  0x71, 0x8b, 0xa8,
-    0x2d, 0xed, 0xd,  0x94, 0xea, 0x3a, 0xe,  0xc0, 0xe9, 0x82, 0x93, 0xad,
-    0xa0, 0x6,  0x4c, 0x61, 0xf1, 0x9,  0x15, 0x42, 0x2d, 0xc9, 0x9,  0xb,
-    0xb6, 0xc,  0x22, 0x6f, 0x84, 0x29, 0xbe, 0x8e, 0x18, 0xe4, 0x9d, 0xb7,
-    0xc1, 0x1e, 0xc,  0x5b, 0x2,  0xc2, 0x40, 0xb4, 0xe2, 0xb8, 0xd7, 0x55,
-    0x2,  0xd3, 0x81, 0x3a, 0xd7, 0xca, 0x4b, 0x2f, 0x4b, 0x1c, 0x5d, 0xa2,
-    0x4d, 0xba, 0x9e, 0xa6, 0xa3, 0xd5, 0xc8, 0x87, 0x48, 0xd2, 0xdf, 0xa1,
-    0x41, 0x5,  0x2,  0xa4, 0xee, 0x36, 0x23, 0x1e, 0x41, 0xd0, 0x60, 0x2e,
-    0x29, 0x33, 0xb5, 0x50, 0xc5, 0xae, 0x97, 0xe9, 0xbc, 0x15, 0xa5, 0x2d,
-    0x4a, 0xae, 0x50, 0xa7, 0xde, 0x1d, 0x6a, 0x4e, 0xe,  0xbc, 0x99, 0xc6,
-    0x9,  0x72, 0x1d, 0xb7, 0xf9, 0xbd, 0x61, 0xce, 0x21, 0xc1, 0x29, 0x60,
-    0xda, 0xa5, 0x83, 0x4f, 0x9d, 0xff, 0x14, 0xf9, 0x8,  0xbd, 0x3a, 0x85,
-    0xc0, 0x5,  0xf2, 0xff, 0x76, 0xeb, 0x1d, 0x5c, 0xb7, 0x41, 0xc4, 0x55,
-    0xaa, 0x3f, 0x20, 0x59, 0x9d, 0x9c, 0xc,  0x64, 0xb7, 0x40, 0xd5, 0xfd,
-    0xab, 0xd,  0xd6, 0x84, 0xe0, 0x4d, 0x33, 0xd7, 0xdc, 0xfb, 0xde, 0xd3,
-    0xa4, 0x94, 0x1f, 0xee, 0x75, 0x60, 0x7d, 0x90, 0xb2, 0xa3, 0xab, 0xcc,
-    0xe4, 0xf0, 0x40, 0xaf, 0xce, 0x73, 0xfb, 0x14, 0x9d, 0x43, 0xe4, 0x91,
-    0x31, 0xbf, 0x97, 0x8d, 0xa1, 0x0,  0x51, 0x59, 0xe6, 0x7,  0xad, 0x13,
-    0x2e, 0x21, 0xd1, 0x37, 0x1e, 0x6,  0xdc, 0xf6, 0xa3, 0xae, 0x9f, 0x14,
-    0x97, 0x7b, 0xea, 0x92, 0xfb, 0x93, 0xa4, 0xd4, 0x8a, 0x94, 0xa0, 0x19,
-    0x22, 0xfb, 0x3b, 0xce, 0x2,  0x7e, 0x2,  0x40, 0xd0, 0x9b, 0x91, 0x12,
-    0xc3, 0x29, 0xd1, 0xf2, 0x85, 0xd8, 0x86, 0xf0, 0x34, 0xda, 0x9b, 0xcb,
-    0x17, 0xef, 0xe,  0x29, 0xcb, 0x26, 0xc5, 0xfe, 0x1d, 0xd6, 0x86, 0x43,
-    0x5d, 0x8d, 0xec, 0x81, 0x13, 0x89, 0x1a, 0xb6, 0x2a, 0x25, 0x6c, 0x6a,
-    0x95, 0x88, 0xd3, 0x69, 0x6e, 0x1f, 0xa3, 0x63, 0x5,  0xf8, 0x1d, 0x8a,
-    0xab, 0xcb, 0x63, 0xb9, 0xb9, 0xbc, 0xea, 0x20, 0xdb, 0x81, 0x2c, 0xf9,
-    0x81, 0x78, 0x6,  0x91, 0xa6, 0xe0, 0xb7, 0x73, 0x39, 0x43, 0x87, 0xb,
-    0x66, 0xb2, 0xc,  0x83, 0xd2, 0x21, 0xeb, 0xfa, 0xc1, 0x99, 0xa2, 0xfb,
-    0x8b, 0x41, 0x91, 0x36, 0xdc, 0x95, 0xa2, 0x2e, 0xe0, 0xb6, 0x6e, 0xdc,
-    0x6f, 0x76, 0xe0, 0xd0, 0x93, 0x1d, 0x87, 0xdb, 0x4,  0xe,  0x33, 0x83,
-    0xf,  0xd,  0x7f, 0xae, 0x5,  0x71, 0x45, 0x11, 0x79, 0xb0, 0xd0, 0x56,
-    0x2b, 0x69, 0x7d, 0xe4, 0x6f, 0x2a, 0xc9, 0x7b, 0xe4, 0xb,  0xb4, 0x3e,
-    0x73, 0x13, 0x9c, 0xf5, 0xe2, 0xea, 0xd3, 0xbb, 0xed, 0xc4, 0x49, 0xa5,
-    0xbb, 0x31, 0x22, 0x29, 0xb8, 0xa6, 0xdb, 0xb1, 0xb0, 0xc,  0x6f, 0x7b,
-    0x8a, 0xe6, 0x73, 0x7,  0xb6, 0x12, 0xc3, 0xdd, 0x6e, 0xa9, 0x30, 0xb9,
-    0xe9, 0xd1, 0x3a, 0x81, 0x65, 0xd,  0x8a, 0x77, 0x33, 0xab, 0xcf, 0x8,
-    0x39, 0x16, 0xca, 0x44, 0x93, 0xdf, 0xcb, 0xa8, 0x3f, 0x93, 0xc1, 0xd6,
-    0x11, 0x37, 0x67, 0x9b, 0x6,  0x44, 0x36, 0x78, 0xbf, 0xc3, 0x9d, 0xd8,
-    0x3e, 0x31, 0x56, 0x3,  0xc,  0x2f, 0xa4, 0xf0, 0x7b, 0xff, 0x10, 0x5a,
-    0xed, 0x31, 0xff, 0xee, 0x22, 0x6c, 0xb6, 0xaa, 0x3b, 0xa7, 0x17, 0xe1,
-    0xc1, 0x47, 0x45, 0x37, 0x90, 0xb7, 0x7a, 0xcf, 0x7c, 0xdb, 0x0,  0xbe,
-    0xca, 0xc5, 0xe9, 0xfe, 0x1c, 0xa3, 0x58, 0x89, 0xd8, 0xea, 0xff, 0xc2,
-    0xa5, 0x8f, 0xe7, 0x42, 0x28, 0x5f, 0x2,  0x68, 0xc6, 0x88, 0x89, 0x29,
-    0x56, 0x38, 0x53, 0xd3, 0x27, 0xf8, 0x77, 0xb4, 0x99, 0x55, 0xe9, 0xa4,
-    0xfa, 0xfb, 0xad, 0xe0, 0x99, 0xf4, 0xc0, 0xef, 0xe5, 0x63, 0x6b, 0x36,
-    0x90, 0xb8, 0x9c, 0x1a, 0xe7, 0x12, 0xad, 0xab, 0xd9, 0x51, 0xbe, 0x5,
-    0x95, 0xe4, 0x1e, 0xda, 0x95, 0xd1, 0xd4, 0x51, 0xc5, 0x80, 0x64, 0x17,
-    0xeb, 0xf1, 0xee, 0xe0, 0xe0, 0x8c, 0x8a, 0x32, 0xa6, 0xfc, 0x55, 0xa9,
-    0x2d, 0xe1, 0xbe, 0xc3, 0x76, 0x78, 0x5f, 0xba, 0xf0, 0x8e, 0x16, 0x5,
-    0x1a, 0xc,  0x78, 0xfa, 0xc4, 0x21, 0xcd, 0xaf, 0xc6, 0x8f, 0x84, 0xf5,
-    0x16, 0xf8, 0x48, 0xab, 0x5a, 0x68, 0xb0, 0xd4, 0x75, 0xd8, 0x91, 0x69,
-    0x4f, 0x93, 0xd1, 0xee, 0xf0, 0x4c, 0x4d, 0x17, 0xc3, 0x89, 0xa0, 0x7b,
-    0x56, 0x38, 0xf4, 0xd7, 0x12, 0xa7, 0x7d, 0x39, 0x81, 0x48, 0xb3, 0x67,
-    0xe1, 0x15, 0xa0, 0xa4, 0x2a, 0x60, 0x56, 0xa5, 0xed, 0x9c, 0x76, 0x8b,
-    0xa7, 0x14, 0x73, 0x33, 0x9f, 0x55, 0x16, 0x6b, 0x5,  0x40, 0x3b, 0xfe,
-    0x93, 0x58, 0x7e, 0xee, 0x2d, 0x61, 0xc5, 0x19, 0x6b, 0x6,  0x71, 0x69,
-    0x39, 0x21, 0x0,  0x8,  0x39, 0xb7, 0x76, 0xe,  0x81, 0xe5, 0xe3, 0x77,
-    0xff, 0x4b, 0x9b, 0x3,  0x8e, 0xc5, 0xe0, 0xb1, 0x8b, 0x16, 0xbd, 0x71,
-    0xbc, 0xc6, 0x62, 0x19, 0xaa, 0x6e, 0x54, 0xb6, 0x7a, 0x17, 0xdb, 0xe5,
-    0xd9, 0x2,  0xaa, 0x57, 0x78, 0x2f, 0xd2, 0x85, 0xfb, 0x36, 0xb5, 0xdd,
-    0x17, 0xbd, 0x4c, 0x8,  0x3c, 0x6b, 0x79, 0x3e, 0x28, 0xab, 0x38, 0xc3,
-    0xe9, 0xdb, 0xf1, 0x28, 0xc3, 0x2a, 0xba, 0x51, 0x1a, 0xf,  0x78, 0xec,
-    0x25, 0xa8, 0xf5, 0xed, 0xe4, 0x9f, 0xb,  0xa5, 0x66, 0x58, 0x18, 0xb0,
-    0xe4, 0x40, 0xb9, 0xf,  0xce, 0x78, 0xc9, 0x49, 0x4d, 0x2e, 0x29, 0xd9,
-    0xbb, 0x59, 0x99, 0xef, 0x3d, 0x44, 0x99, 0x75, 0x8f, 0xe1, 0x1d, 0x5,
-    0x70, 0xeb, 0x65, 0x93, 0xeb, 0x3f, 0x76, 0x4f, 0xae, 0xa0, 0x12, 0x5b,
-    0x18, 0x28, 0xe6, 0x2a, 0x26, 0xae, 0xe0, 0xd3, 0x26, 0xd2, 0x5f, 0xf5,
-    0x89, 0xec, 0x1e, 0xc6, 0x1,  0xe9, 0xe1, 0x7c, 0x30, 0x6a, 0x65, 0x4d,
-    0x7c, 0x82, 0xb4, 0xd,  0x92, 0xde, 0x2f, 0xe8, 0x9,  0xde, 0x6f, 0x15,
-    0x21, 0x78, 0x91, 0xb2, 0x39, 0xab, 0x20, 0xbb, 0x96, 0xf6, 0xc0, 0xba,
-    0xeb, 0x8b, 0x63, 0x97, 0xab, 0xc7, 0x21, 0xd2, 0x85, 0xb,  0x66, 0x91,
-    0x31, 0xeb, 0x17, 0x18, 0x4e, 0x12, 0x3e, 0xa5, 0x57, 0x6e, 0xe5, 0x95,
-    0x70, 0x3c, 0x25, 0x1b, 0x53, 0x4a, 0xde, 0x29, 0x20, 0x13, 0x90, 0xd9,
-    0xc7, 0x3f, 0x15, 0xcf, 0x98, 0x94, 0x43, 0xe6, 0x98, 0xee, 0x33, 0xa0,
-    0x8a, 0xc6, 0xfb, 0x71, 0x73, 0xfe, 0xd1, 0xf5, 0xd,  0x71, 0xfe, 0x15,
-    0xdb, 0x7e, 0xaf, 0x36, 0x5a, 0x59, 0xab, 0xaf, 0x96, 0xa0, 0x3b, 0x5,
-    0xda, 0xa,  0x46, 0x76, 0xa0, 0x55, 0x93, 0xd9, 0xf0, 0x63, 0xc9, 0x8c,
-    0x40, 0x2d, 0x97, 0x1b, 0x6e, 0x54, 0x0,  0x78, 0xfb, 0x88, 0xc2, 0x46,
-    0xef, 0xf,  0x45, 0xba, 0xa0, 0xc7, 0x99, 0xa2, 0xcf, 0x88, 0x9e, 0x96,
-    0x27, 0x15, 0x24, 0x28, 0xf8, 0xa0, 0xa4, 0xbb, 0x57, 0x7c, 0xc7, 0xef,
-    0x2b, 0x50, 0xa,  0x78, 0x92, 0x82, 0x6e, 0x6e, 0x75, 0x4a, 0x29, 0x20,
-    0xab, 0xef, 0x9e, 0x85, 0x7f, 0x33, 0x2c, 0x5,  0xfa, 0xd,  0x6e, 0xab,
-    0xc8, 0xb9, 0xee, 0xd0, 0x22, 0xd6, 0xd9, 0xc9, 0x90, 0xe4, 0xea, 0x42,
-    0x9,  0x72, 0x15, 0x3c, 0xbe, 0x6f, 0x6e, 0x85, 0x18, 0x2e, 0xb0, 0xc8,
-    0xac, 0xe2, 0xc,  0xd3, 0xa3, 0x6,  0xbf, 0xdc, 0x93, 0x2a, 0xb8, 0xa0,
-    0x21, 0x3c, 0x7f, 0x8c, 0xbe, 0xda, 0x8e, 0xf3, 0xf7, 0xfe, 0x83, 0x4a,
-    0x35, 0x5,  0x80, 0x39, 0x66, 0xab, 0x38, 0x3a, 0x8a, 0xc6, 0x5e, 0xca,
-    0xb0, 0x74, 0x39, 0xfd, 0x23, 0xa0, 0x4f, 0x5,  0xb3, 0x23, 0xe9, 0xfd,
-    0xb5, 0xe,  0x47, 0x20, 0x14, 0x27, 0x6,  0x33, 0x60, 0xbc, 0xd4, 0xb0,
-    0x84, 0x17, 0x87, 0xcf, 0x24, 0x79, 0xa0, 0x26, 0x91, 0x81, 0xe3, 0x4c,
-    0x73, 0x7c, 0xa3, 0xc2, 0xc6, 0x4b, 0xb8, 0xda, 0xff, 0xaa, 0x89, 0x38,
-    0x84, 0xea, 0xfe, 0x58, 0xd9, 0x11, 0x82, 0x30, 0x90, 0x39, 0x39, 0x88,
-    0x10, 0xec, 0xf8, 0xc0, 0x1,  0x16, 0xb6, 0xc1, 0x74, 0xf6, 0xb2, 0xb3,
-    0x6d, 0x8d, 0xf8, 0x76, 0xa0, 0x7f, 0x12, 0x26, 0xba, 0x9d, 0xed, 0x45,
-    0x27, 0x5d, 0x3f, 0x4b, 0xe7, 0xd2, 0xc5, 0xf9, 0xf8, 0xde, 0x95, 0x74,
-    0xb1, 0x2a, 0x3f, 0xed, 0x1f, 0x73, 0x15, 0x18, 0xc4, 0xb1, 0x32, 0x90,
-    0x52, 0xc4, 0x11, 0x78, 0x21, 0x25, 0x61, 0x2c, 0x8f, 0x78, 0x7f, 0xee,
-    0x31, 0x92, 0x4f, 0x36, 0xbc, 0xd5, 0x70, 0x84, 0x4c, 0xb4, 0x39, 0xa3,
-    0x73, 0x53, 0xbb, 0x48, 0x3d, 0xff, 0x3,  0x74, 0xea, 0x2f, 0x7,  0xf3,
-    0xaa, 0xeb, 0x1b, 0x69, 0xa3, 0x28, 0x56, 0x45, 0x6d, 0xb2, 0xb2, 0x12,
-    0xc1, 0xf7, 0x21, 0x35, 0x5,  0x14, 0x9c, 0x6,  0xf9, 0x1c, 0x9e, 0x8e,
-    0xda, 0x19, 0xa8, 0x6,  0x5f, 0xa1, 0x21, 0x1e, 0x1e, 0x96, 0x38, 0x2,
-    0x29, 0xd5, 0x6d, 0x8e, 0x24, 0x4e, 0x94, 0x79, 0x22, 0xc7, 0x67, 0xe8,
-    0xc2, 0x12, 0xdf, 0xed, 0x82, 0x22, 0xdb, 0x80, 0x52, 0xc,  0x60, 0xdf,
-    0x84, 0x92, 0x55, 0xc2, 0xce, 0xfc, 0x7,  0x69, 0x9f, 0xd2, 0xd0, 0x37,
-    0xbf, 0x1d, 0x11, 0x8a, 0xab, 0x26, 0x92, 0x6b, 0xe,  0xbc, 0x1c, 0x6f,
-    0xdf, 0x78, 0x8f, 0x8a, 0xce, 0x16, 0x70, 0x90, 0x2a, 0x66, 0x13, 0x9a,
-    0x57, 0xda, 0x5f, 0x93, 0xcd, 0xef, 0x8f, 0x76, 0x1e, 0x8e, 0x59, 0xdf,
-    0x7,  0x49, 0x35, 0x81, 0xa4, 0x7d, 0x1b, 0xe0, 0x61, 0x6f, 0x10, 0xc1,
-    0x1c, 0xf2, 0xc6, 0x7f, 0x1,  0x92, 0xa0, 0x4d, 0x58, 0x2a, 0xe0, 0x27,
-    0xbf, 0x3a, 0x8f, 0xb0, 0x2a, 0xfd, 0x6,  0xb,  0x35, 0xfd, 0x49, 0x2,
-    0x2,  0xf6, 0x52, 0x35, 0x15, 0x78, 0x3d, 0xa0, 0x99, 0x98, 0x5f, 0xf3,
-    0xce, 0x38, 0xfd, 0xd6, 0x81, 0xb1, 0xed, 0xb1, 0x89, 0x2d, 0x7c, 0xee,
-    0x1c, 0x65, 0x36, 0x24, 0xc2, 0xd,  0xbe, 0xa6, 0xf1, 0xa2, 0x95, 0xb8,
-    0x9d, 0xc9, 0xaf, 0x5,  0xb2, 0xe5, 0x95, 0x45, 0xe5, 0x9b, 0x82, 0x3d,
-    0xbb, 0x65, 0x0,  0xfe, 0x24, 0xb9, 0xc8, 0x43, 0x57, 0xd6, 0x2d, 0x9e,
-    0xa4, 0xfa, 0x99, 0x1a, 0xc9, 0xb0, 0xdb, 0x70, 0xd9, 0x28, 0x85, 0x4c,
-    0x33, 0x33, 0xa7, 0x37, 0x86, 0xa7, 0x62, 0x8a, 0xca, 0xbc, 0xfd, 0x25,
-    0x43, 0x4c, 0xbe, 0x3e, 0xb7, 0xfb, 0x99, 0x5e, 0xe4, 0x9,  0x9a, 0x92,
-    0xdd, 0xec, 0x6f, 0xab, 0x39, 0x65, 0x75, 0x6e, 0x98, 0xbd, 0xd0, 0xd9,
-    0x87, 0x46, 0xa3, 0x9c, 0xfe, 0x41, 0x4f, 0x20, 0x3d, 0x68, 0x32, 0x21,
-    0x94, 0x5a, 0xbd, 0x67, 0x9f, 0x79, 0x51, 0x8a, 0xe9, 0x16, 0xa3, 0xc0,
-    0x33, 0x69, 0x21, 0x45, 0x62, 0xa2, 0x45, 0x36, 0xaa, 0xd1, 0x80, 0x3a,
-    0x6a, 0x51, 0x86, 0xb4, 0x49, 0x56, 0xd6, 0x65, 0xdd, 0x87, 0x9e, 0xb0,
-    0x4a, 0xbe, 0x80, 0x42, 0x13, 0x44, 0xc4, 0x5d, 0x8a, 0x54, 0x37, 0x11,
-    0xfc, 0xe6, 0xa5, 0xd,  0x59, 0xd7, 0x11, 0xa6, 0x61, 0x44, 0x87, 0xf0,
-    0x93, 0x36, 0x57, 0x15, 0x6c, 0xe2, 0x8f, 0x37, 0x27, 0x87, 0x96, 0x1,
-    0xe0, 0x98, 0xc4, 0xda, 0x1,  0xf4, 0x21, 0x3,  0x97, 0x28, 0x71, 0xdc,
-    0xd2, 0xf3, 0xb0, 0x24, 0x10, 0xb9, 0x89, 0xd5, 0x97, 0x34, 0x60, 0xcb,
-    0x39, 0x6,  0xb3, 0x59, 0xeb, 0x3b, 0x86, 0xd0, 0x1b, 0x51, 0x6d, 0x46,
-    0xa8, 0xb6, 0xcd, 0xec, 0xf7, 0xe1, 0xf6, 0xc8, 0x9,  0xe0, 0xfa, 0x29,
-    0xf4, 0x96, 0x53, 0x9f, 0x3,  0xe1, 0x3e, 0x72, 0x23, 0x32, 0x8f, 0xa7,
-    0xb,  0x94, 0x55, 0x71, 0x4f, 0x41, 0x6d, 0xcf, 0xf,  0x87, 0xd,  0x45,
-    0xcd, 0x33, 0x63, 0x10, 0x7,  0xff, 0x95, 0x58, 0xb6, 0xc1, 0x2,  0x0,
-    0x8d, 0xbb, 0x4e, 0x16, 0x9f, 0x5d, 0x3f, 0xbe, 0x44, 0x16, 0x4,  0x73,
-    0x6e, 0xf5, 0xb8, 0x72, 0x5b, 0xed, 0x36, 0x4e, 0xf8, 0x86, 0xb9, 0x71,
-    0x63, 0x10, 0x7f, 0x4e, 0x69, 0xc8, 0xa,  0xc0, 0x75, 0xdd, 0xd3, 0xe0,
-    0xa5, 0x2c, 0xd2, 0xf4, 0xc1, 0x9a, 0x72, 0xe3, 0xf2, 0xb1, 0x46, 0x56,
-    0x6b, 0x3f, 0x3,  0x87, 0x53, 0x75, 0x7d, 0xce, 0x1b, 0x31, 0xd6, 0x29,
-    0x99, 0xcf, 0xc0, 0x5f, 0xb5, 0x7b, 0x3a, 0xa0, 0x7d, 0x66, 0xda, 0x86,
-    0x5f, 0x74, 0x29, 0x8f, 0x37, 0x90, 0x65, 0xec, 0xef, 0x1c, 0xb0, 0xf6,
-    0x68, 0xe,  0x34, 0x78, 0xd5, 0xae, 0x4,  0x5d, 0x6,  0xa,  0x5c, 0xb8,
-    0x74, 0x67, 0xbc, 0xa8, 0x97, 0x3d, 0x2a, 0xbe, 0xd3, 0x74, 0x5,  0xdc,
-    0x3d, 0x61, 0x22, 0x5a, 0x84, 0x98, 0xe1, 0xae, 0x59, 0x20, 0x6a, 0xe0,
-    0xb6, 0x78, 0xc,  0x8,  0xfa, 0x75, 0xb4, 0xb7, 0xd2, 0x14, 0x1e, 0x8a,
-    0x3c, 0x58, 0x7c, 0x95, 0x91, 0x5d, 0x56, 0xbf, 0xfe, 0xbe, 0x7f, 0xb1,
-    0x2e, 0x81, 0x7b, 0x4e, 0x1e, 0xd1, 0x2a, 0x25, 0x30, 0x87, 0xf5, 0x40,
-    0xd7, 0xcc, 0x1d, 0xd8, 0x9d, 0x77, 0x37, 0x3,  0x6,  0x91, 0x6c, 0x1d,
-    0xa3, 0xaa, 0xa9, 0x9b, 0xa9, 0xf5, 0x92, 0x31, 0x44, 0xdc, 0x7b, 0xcf,
-    0xe8, 0x9a, 0xa5, 0x46, 0x9a, 0xac, 0x20, 0x56, 0x8,  0x56, 0x7d, 0x82,
-    0xba, 0x4b, 0x3,  0x3e, 0xa3, 0x62, 0xe2, 0xcc, 0x19, 0x48, 0xc7, 0xfe,
-    0xde, 0x2,  0xa4, 0x59, 0x6e, 0xf0, 0x19, 0x40, 0xd7, 0x35, 0x64, 0x8b,
-    0x40, 0xb,  0x3d, 0x87, 0xb8, 0xd9, 0x11, 0xed, 0xae, 0x2c, 0x8b, 0x6c,
-    0x45, 0x91, 0x81, 0x27, 0xc,  0xea, 0xb2, 0x9f, 0xb7, 0x27, 0x90, 0x32,
-    0xd4, 0x19, 0xb1, 0xff, 0x48, 0xa,  0xac, 0x55, 0x8d, 0x1b, 0x22, 0xef,
-    0x51, 0xcc, 0x9,  0xff, 0xab, 0x1e, 0x70, 0xa8, 0x49, 0xf2, 0x68, 0xc4,
-    0xdf, 0xd,  0xee, 0x3,  0x67, 0xb3, 0xa,  0x39, 0x8b, 0x59, 0x1a, 0x8a,
-    0x95, 0xba, 0xc8, 0xde, 0x6,  0xf6, 0xb7, 0xa5, 0xbc, 0xa0, 0x4d, 0xb2,
-    0xd2, 0x58, 0x6e, 0xcc, 0x94, 0xa1, 0xaf, 0xf1, 0xf4, 0x73, 0x64, 0xc3,
-    0x90, 0xdd, 0xd7, 0x4f, 0xb7, 0xbc, 0x65, 0x11, 0xdd, 0x40, 0xd6, 0xf,
-    0x73, 0xeb, 0xef, 0x4e, 0x57, 0x72, 0xd7, 0xe6, 0xe6, 0xe1, 0xb1, 0x2d,
-    0x80, 0xb2, 0x59, 0x95, 0xa9, 0xca, 0x85, 0x3f, 0x5e, 0x9c, 0x7d, 0xa9,
-    0x9d, 0x22, 0x7b, 0xcc, 0x89, 0xda, 0xe0, 0x7e, 0x56, 0x42, 0x69, 0x28,
-    0x76, 0x12, 0x2a, 0xa,  0xa1, 0xc9, 0x19, 0x2c, 0x46, 0xd3, 0xe8, 0x22,
-    0xd4, 0x9,  0x92, 0x9f, 0x75, 0x53, 0x82, 0xfb, 0xf0, 0x2f, 0x96, 0x4,
-    0xc6, 0xf4, 0xc3, 0xdf, 0x2,  0x31, 0xfd, 0x74, 0x24, 0xda, 0xe5, 0xdf,
-    0x4d, 0x68, 0xe4, 0x5e, 0x20, 0xd5, 0x55, 0x9b, 0x9d, 0xe3, 0xc6, 0x70,
-    0x10, 0x70, 0x56, 0xe4, 0x4d, 0x7e, 0x78, 0x69, 0xb3, 0x7f, 0xc0, 0x8c,
-    0xea, 0xc,  0xf0, 0xdc, 0x3a, 0x87, 0x34, 0xa8, 0x9f, 0x6a, 0x4d, 0xae,
-    0x49, 0x9e, 0x35, 0x66, 0xc8, 0x6f, 0xaa, 0xa7, 0xfb, 0x4c, 0xf6, 0xb,
-    0x58, 0x11, 0x26, 0xa7, 0x45, 0xef, 0x3c, 0xdb, 0x5e, 0xce, 0xf8, 0xb4,
-    0x6d, 0x7c, 0x85, 0x93, 0xb1, 0x27, 0x56, 0x60, 0x3a, 0x1b, 0xd0, 0x96,
-    0xba, 0x8b, 0xf4, 0x65, 0xa4, 0xda, 0x8f, 0x71, 0xc,  0xa6, 0x81, 0x8c,
-    0x8a, 0x3c, 0xb4, 0x27, 0x6a, 0xcf, 0x16, 0x7,  0x81, 0x2e, 0xa0, 0xb,
-    0xf6, 0xd1, 0xec, 0x1d, 0x85, 0x0,  0xf7, 0x49, 0xeb, 0x19, 0xd3, 0xa7,
-    0xc0, 0xec, 0x79, 0xf7, 0xa3, 0x91, 0x27, 0x9a, 0xe3, 0x16, 0x60, 0x52,
-    0xe7, 0xfe, 0xe5, 0x7,  0x16, 0x88, 0xf4, 0x27, 0x69, 0x47, 0x5,  0x1e,
-    0x76, 0xe6, 0x16, 0x5d, 0x32, 0x5a, 0x92, 0x41, 0x5,  0x97, 0x3e, 0xcf,
-    0x3f, 0x22, 0x63, 0xa1, 0xa7, 0x8f, 0xac, 0xa9, 0x56, 0x82, 0x7,  0xbc,
-    0x79, 0xbc, 0x4f, 0xe5, 0x84, 0xa4, 0xe8, 0xde, 0xd3, 0xe7, 0x96, 0x5f,
-    0x0,  0xde, 0xba, 0x27, 0xa4, 0x23, 0x57, 0xc6, 0x4a, 0x69, 0xab, 0xbf,
-    0x3d, 0x34, 0xe7, 0xec, 0xc4, 0xe9, 0xee, 0xd6, 0xc8, 0x2d, 0x52, 0x47,
-    0x11, 0x19, 0xd8, 0xc6, 0x4e, 0x2c, 0xf2, 0x68, 0x9a, 0xd5, 0xb,  0x25,
-    0xe8, 0x77, 0xa1, 0x38, 0x7e, 0x15, 0xf,  0xc6, 0x85, 0x7d, 0x14, 0x2a,
-    0x41, 0x55, 0xb,  0xe7, 0x83, 0xcc, 0x6b, 0x4f, 0xbe, 0xde, 0xec, 0x38,
-    0xd1, 0xf4, 0x32, 0x4c, 0x36, 0xe1, 0xf3, 0x70, 0x1b, 0xbb, 0x82, 0xd9,
-    0x80, 0x19, 0x67, 0x25, 0xa0, 0x1c, 0xdd, 0x63, 0xb2, 0x80, 0xf8, 0xef,
-    0xd,  0xa9, 0xde, 0x77, 0x4c, 0x53, 0x17, 0x9d, 0x2f, 0x3d, 0x91, 0x80,
-    0x6b, 0xcc, 0x55, 0x5d, 0xbc, 0x14, 0x8f, 0xfa, 0x6e, 0xfd, 0xf5, 0xf1,
-    0x22, 0x33, 0xf5, 0x39, 0x6f, 0xe0, 0xc,  0x69,
-};
-const uint8_t kAltGameImages2xC[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x29, 0xa3, 0xa8, 0xaa,
-    0x9c, 0x8a, 0xfe, 0x4,  0xe6, 0xc8, 0x54, 0xf6, 0x2b, 0xa1, 0x37, 0xe8,
-    0x9c, 0xe5, 0x73, 0xd9, 0x39, 0xba, 0x2,  0x36, 0xe2, 0x8a, 0xd1, 0x1,
-    0xb,  0x82, 0x86, 0x7e, 0x6,  0xa9, 0xae, 0xfd, 0x76, 0x74, 0xfb, 0x7b,
-    0xea, 0xea, 0x4a, 0xd4, 0x8c, 0xd2, 0xec, 0x68, 0xf5, 0xd2, 0xfe, 0x7e,
-    0xc6, 0x5f, 0xa7, 0x53, 0x22, 0xe7, 0xed, 0x68, 0x22, 0xf7, 0x1d, 0x8b,
-    0xcb, 0x84, 0xfd, 0x82, 0xf9, 0x48, 0xe6, 0x91, 0xc9, 0x81, 0x2c, 0x40,
-    0x53, 0x7b, 0x7f, 0x85, 0x83, 0xab, 0x99, 0xf6, 0xbb, 0xc2, 0x20, 0xaf,
-    0x40, 0xd9, 0xb,  0xc8, 0x7d, 0x55, 0x68, 0xda, 0x6d, 0xe6, 0x8c, 0xd9,
-    0x20, 0xaf, 0xd,  0x7e, 0x8b, 0x66, 0xe1, 0x43, 0x3a, 0x6e, 0xb8, 0x97,
-    0x50, 0xbe, 0xd1, 0x33, 0xb7, 0x18, 0xe3, 0x68, 0xa,  0x4,  0x4b, 0x76,
-    0x1e, 0xd6, 0x6e, 0x6c, 0x68, 0x43, 0xd7, 0x14, 0xff, 0xc6, 0xee, 0xfb,
-    0xe7, 0xab, 0x36, 0x81, 0x85, 0x58, 0xe,  0x4b, 0xdd, 0x24, 0x7,  0x8b,
-    0xa7, 0x3a, 0x8f, 0xc0, 0x58, 0xad, 0x68, 0x32, 0xaf, 0xf6, 0xdf, 0x2a,
-    0x86, 0xd1, 0x47, 0xa7, 0x76, 0xe1, 0x2b, 0xcb, 0xf7, 0xfc, 0x75, 0x35,
-    0x2c, 0x1a, 0x24, 0xd,  0x6d, 0x91, 0x27, 0x4,  0x4d, 0x2b, 0xad, 0xa7,
-    0x8f, 0x48, 0xf4, 0xa4, 0xfe, 0x92, 0x75, 0xc3, 0x10, 0x82, 0xb2, 0xd0,
-    0x2d, 0xf4, 0x89, 0xda, 0x25, 0xb3, 0x85, 0x1,  0x50, 0xd5, 0x27, 0x27,
-    0x81, 0x5,  0x4e, 0x9,  0x1a, 0x36, 0x87, 0xd3, 0xe2, 0x32, 0xb7, 0x43,
-    0x4d, 0x4c, 0x15, 0x83, 0xe1, 0x1b, 0xd8, 0xae, 0xe8, 0x10, 0x44, 0x78,
-    0x11, 0x9f, 0x52, 0xc0, 0xa6, 0x70, 0x23, 0xe4, 0xa9, 0xbc, 0xdd, 0x44,
-    0x61, 0x42, 0xc5, 0x30, 0xd3, 0xe8, 0x1,  0x24, 0x61, 0x2b, 0x9,  0x1,
-    0xe2, 0x8e, 0xca, 0x2,  0x1b, 0x52, 0xc5, 0xe2, 0xd8, 0x1b, 0x25, 0x49,
-    0xed, 0x29, 0x85, 0x56, 0xef, 0xa4, 0xce, 0x32, 0x9,  0xcd, 0x94, 0x6b,
-    0x7d, 0x9,  0x7d, 0xf1, 0xcc, 0x4c, 0xc7, 0x42, 0x98, 0xd3, 0x70, 0xd2,
-    0xf2, 0xee, 0xa3, 0xac, 0x6b, 0x7c, 0x52, 0xfe, 0x26, 0x1d, 0x9b, 0x6d,
-    0x53, 0xb3, 0x33, 0xa6, 0x9f, 0x8d, 0xb1, 0xd3, 0x8a, 0x87, 0x52, 0xf5,
-    0x42, 0xff, 0xf3, 0x81, 0x0,  0x5f, 0xf0, 0x2f, 0x25, 0xf2, 0xf6, 0xc1,
-    0xe1, 0x8c, 0x41, 0x10, 0x74, 0xd6, 0x3c, 0x2e, 0x5b, 0x2c, 0x93, 0xd6,
-    0xcb, 0x67, 0x15, 0x4,  0x1f, 0x27, 0x28, 0xf9, 0xe9, 0x4d, 0x4,  0x47,
-    0x49, 0x77, 0xeb, 0x8c, 0x3c, 0x96, 0x1b, 0x7f, 0xf3, 0x31, 0xf5, 0xff,
-    0x20, 0x9d, 0x18, 0x94, 0xdf, 0x6f, 0x77, 0x9c, 0x63, 0x7c, 0xcf, 0x4f,
-    0x3e, 0x55, 0x32, 0xc8, 0xe9, 0xd5, 0x37, 0x8f, 0x3e, 0x9c, 0x4b, 0x12,
-    0x6,  0xcf, 0xf4, 0xfb, 0x1a, 0x9a, 0x58, 0x2,  0xb0, 0xc1, 0xf5, 0x32,
-    0x91, 0xfd, 0xec, 0xa5, 0xb2, 0x79, 0x99, 0x64, 0xbb, 0xb8, 0x8b, 0xf9,
-    0xe4, 0xb2, 0xa2, 0x84, 0xdf, 0x92, 0x71, 0x87, 0xbb, 0x75, 0x3,  0xfc,
-    0x37, 0x72, 0x13, 0x31, 0xd,  0xec, 0xdd, 0x6e, 0xa6, 0x3f, 0xef, 0xbf,
-    0xe2, 0xdd, 0x20, 0x98, 0x24, 0x7c, 0x57, 0xfd, 0x4b, 0x77, 0x6,  0x73,
-    0xbd, 0xb2, 0xa1, 0xb0, 0x6e, 0x8c, 0x28, 0x71, 0x11, 0x92, 0x1d, 0x7b,
-    0x2b, 0x28, 0x1,  0x85, 0x73, 0x1b, 0xff, 0xf3, 0xdc, 0x31, 0xbb, 0x14,
-    0x2c, 0x6e, 0x77, 0x19, 0x67, 0xf7, 0x1c, 0xc4, 0xba, 0x1c, 0xaa, 0x4d,
-    0x9f, 0xa6, 0x33, 0xa0, 0x7d, 0xc4, 0x70, 0xd7, 0xeb, 0x93, 0x7c, 0x64,
-    0x18, 0xf7, 0x77, 0xc,  0x1b, 0x1,  0x91, 0x70, 0x90, 0x3f, 0x92, 0x5e,
-    0xc2, 0xe7, 0xc9, 0x3e, 0x0,  0xab, 0x3a, 0x75, 0x8a, 0x42, 0x39, 0x47,
-    0x26, 0x51, 0x91, 0x20, 0xbb, 0x96, 0xac, 0xfb, 0xa6, 0x9c, 0x5f, 0xa8,
-    0x58, 0x3c, 0x4e, 0x1e, 0xe0, 0xd0, 0xf1, 0x84, 0x7e, 0xe8, 0x83, 0xa5,
-    0x54, 0x3e, 0xae, 0xdf, 0xd9, 0x75, 0xf8, 0x7a, 0xed, 0xb7, 0x28, 0xfb,
-    0x11, 0xb7, 0xd,  0x67, 0xf,  0xea, 0x3b, 0xbd, 0x97, 0xc0, 0x43, 0x41,
-    0x26, 0xaf, 0xfb, 0x5c, 0xb7, 0x56, 0xb1, 0x7d, 0xcb, 0x8,  0xa8, 0x63,
-    0xfc, 0xfb, 0x61, 0x1b, 0xc1, 0x77, 0xee, 0xd,  0x2e, 0xdd, 0xc6, 0x74,
-    0x14, 0x9f, 0x90, 0x5d, 0x50, 0xe4, 0x96, 0xc,  0xb3, 0x5c, 0x5e, 0x6c,
-    0xec, 0x63, 0x43, 0xf4, 0xa5, 0xc0, 0xf1, 0x18, 0xc0, 0x25, 0x76, 0x80,
-    0x8a, 0x51, 0x38, 0xb9, 0x29, 0x2b, 0x8e, 0x5,  0x63, 0xb1, 0x4f, 0x3e,
-    0x92, 0xc0, 0xc1, 0xf7, 0x94, 0x4a, 0xd8, 0x9d, 0xba, 0xc1, 0x8e, 0xc9,
-    0x16, 0x4c, 0xe4, 0xd4, 0x6f, 0x78, 0x4d, 0xa3, 0x79, 0x44, 0x63, 0x66,
-    0x9d, 0x28, 0xee, 0xae, 0x8e, 0x1d, 0xa0, 0x45, 0x1b, 0xf,  0x13, 0x87,
-    0x45, 0x48, 0x47, 0xf9, 0xe7, 0x90, 0x4e, 0x47, 0xce, 0xcf, 0xca, 0x26,
-    0xb3, 0x5d, 0xa3, 0xb9, 0xa0, 0x97, 0x1e, 0x57, 0x7d, 0x11, 0xa7, 0xfc,
-    0x1c, 0xe8, 0x93, 0x47, 0xc9, 0x1f, 0x60, 0x1f, 0x15, 0x9f, 0x61, 0xc5,
-    0x2c, 0xc6, 0xaa, 0xa2, 0xc2, 0xaa, 0x25, 0xdc, 0xfe, 0x74, 0x2,  0xb6,
-    0xd0, 0x5,  0x63, 0xe7, 0x4,  0xa8, 0xe,  0x3e, 0x3d, 0x80, 0x45, 0x95,
-    0xa7, 0xc6, 0x53, 0xd7, 0xed, 0xb,  0x1c, 0x1d, 0x21, 0x8,  0x8f, 0x3e,
-    0xec, 0xf,  0x71, 0x14, 0x3e, 0xc0, 0x88, 0x15, 0xfd, 0x18, 0x7f, 0x7b,
-    0x8,  0x5c, 0xfd, 0x27, 0xa2, 0x82, 0xfd, 0xb8, 0x4,  0xed, 0xe1, 0x10,
-    0x33, 0xdd, 0x43, 0x6d, 0x75, 0xd5, 0x26, 0x50, 0xb,  0xc1, 0xa0, 0x14,
-    0xa1, 0x6b, 0xad, 0xc8, 0x1f, 0xe0, 0x25, 0x2c, 0x3e, 0x1f, 0x58, 0xf9,
-    0x3f, 0x18, 0x5f, 0xb7, 0xa4, 0x56, 0x90, 0x4d, 0x66, 0xab, 0x77, 0x66,
-    0x54, 0xbd, 0x7d, 0xff, 0x1f, 0x3a, 0x6c, 0x7,  0x6e, 0x5a, 0x64, 0xf0,
-    0x5b, 0x75, 0x20, 0xc4, 0x30, 0x1d, 0x3e, 0xd0, 0xf3, 0x31, 0x14, 0xe5,
-    0x6d, 0xd0, 0x35, 0xa0, 0x62, 0x7,  0x14, 0x25, 0x14, 0x45, 0x19, 0xfb,
-    0x7a, 0x93, 0x69, 0xbc, 0x1,  0xd2, 0x17, 0x92, 0xc4, 0x53, 0xa2, 0xcf,
-    0xa5, 0xa,  0xde, 0xc5, 0x3d, 0x25, 0x91, 0x62, 0x4e, 0x0,  0xdd, 0xc5,
-    0x2b, 0xc9, 0x39, 0x80, 0x3a, 0xc8, 0x4a, 0x15, 0xe5, 0x62, 0x2a, 0x25,
-    0xfc, 0x3d, 0xaf, 0x4b, 0x72, 0x74, 0x12, 0x1c, 0xdc, 0xbb, 0x79, 0x34,
-    0xfb, 0x4,  0xeb, 0xd4, 0x87, 0xf6, 0x60, 0x3a, 0x84, 0x97, 0x17, 0x58,
-    0x44, 0x8f, 0xd4, 0xbf, 0x27, 0x27, 0x6a, 0x7a, 0x7a, 0x1a, 0x4a, 0x38,
-    0xfe, 0xa8, 0xde, 0xcf, 0xd0, 0x23, 0xcd, 0x7a, 0x56, 0x7f, 0x76, 0x62,
-    0x3f, 0xaf, 0xb6, 0xde, 0x47, 0x4c, 0xea, 0xb4, 0x6,  0x7c, 0xb0, 0x8,
-    0x2d, 0x4b, 0xfe, 0x6b, 0x1e, 0x94, 0x91, 0x72, 0xb9, 0x13, 0x67, 0x71,
-    0x21, 0xeb, 0x8e, 0xd4, 0xf5, 0x3c, 0xe8, 0xc8, 0x7c, 0xcb, 0x1d, 0xcf,
-    0x82, 0x8b, 0xa7, 0x60, 0x81, 0x9f, 0xb,  0xce, 0x4e, 0x22, 0x23, 0x11,
-    0x72, 0x5e, 0xeb, 0xd,  0xca, 0x31, 0xdb, 0x18, 0x9d, 0x1d, 0x3f, 0xa3,
-    0xe5, 0x25, 0xdc, 0xc2, 0xd3, 0x99, 0xad, 0xaa, 0xd6, 0x89, 0xc4, 0x2d,
-    0x3f, 0x54, 0x3,  0x90, 0x75, 0xfb, 0xc7, 0x73, 0xc3, 0xbc, 0x4e, 0xe7,
-    0xaf, 0x9,  0x6a, 0x67, 0xec, 0xb5, 0x9c, 0x6b, 0x3a, 0xc6, 0x24, 0xa8,
-    0x12, 0xd,  0xbe, 0xf8, 0xec, 0x3d, 0xe7, 0x76, 0x2b, 0xb9, 0x1e, 0xed,
-    0x65, 0xf6, 0xb3, 0x7e, 0x54, 0x58, 0xbf, 0x60, 0x78, 0x74, 0x0,  0xe1,
-    0x93, 0x18, 0xd,  0x64, 0xc0, 0x89, 0xfb, 0x5a, 0x1b, 0x1b, 0x30, 0x4c,
-    0x9a, 0xa5, 0x6e, 0x72, 0x1f, 0x77, 0x60, 0xb8, 0x36, 0x63, 0x5a, 0x35,
-    0x4,  0xd6, 0x19, 0xbb, 0x84, 0x11, 0xbd, 0x8d, 0x10, 0x8e, 0xe5, 0xee,
-    0xa7, 0x7e, 0xc2, 0xf8, 0x4f, 0xf4, 0x48, 0x63, 0xd3, 0x5c, 0xdc, 0x63,
-    0x71, 0x2f, 0xdf, 0xe,  0xbf, 0x6c, 0x6a, 0x54, 0x25, 0xe4, 0xea, 0xd7,
-    0x6e, 0x25, 0x36, 0x84, 0xf0, 0xcf, 0x2d, 0x5f, 0x4c, 0x49, 0x1b, 0x19,
-    0xdd, 0x38, 0xb,  0x69, 0xa,  0x2c, 0x51, 0xfe, 0x4,  0xf5, 0x57, 0xa7,
-    0xf0, 0xd6, 0x8c, 0x54, 0x78, 0x50, 0x11, 0x88, 0xd3, 0x5c, 0xdc, 0x1a,
-    0x3d, 0x6b, 0xb1, 0x3a, 0x1,  0x66, 0xf0, 0xb4, 0x11, 0x5,  0x14, 0x38,
-    0x34, 0x72, 0xbb, 0xde, 0xec, 0x26, 0xdb, 0x8b, 0x4c, 0xdf, 0xa7, 0xb6,
-    0x52, 0xfe, 0x30, 0x46, 0xf3, 0x10, 0x7c, 0xc6, 0xa1, 0x97, 0x13, 0xdc,
-    0xd6, 0xa1, 0x20, 0x45, 0x5e, 0x47, 0x98, 0x77, 0xf6, 0x57, 0xd2, 0x81,
-    0x44, 0x2b, 0x4,  0x7f, 0x19, 0x80, 0x38, 0xc6, 0xfd, 0xcf, 0xa8, 0xa0,
-    0x80, 0x10, 0xfb, 0xb0, 0x8b, 0x48, 0x52, 0xf8, 0x5c, 0x24, 0x20, 0x42,
-    0x50, 0xfc, 0x6c, 0x76, 0x76, 0x5,  0x3d, 0x9f, 0xd4, 0xa7, 0xa8, 0x38,
-    0x1c, 0xa3, 0xd1, 0xe8, 0x3f, 0xfd, 0x4b, 0xb5, 0x7,  0x3f, 0xe7, 0x9c,
-    0x4a, 0xa4, 0x7d, 0xd6, 0x7c, 0x3e, 0xfb, 0x9c, 0x3d, 0xf2, 0xa9, 0x2e,
-    0x82, 0x1b, 0x51, 0xb0, 0x94, 0x3f, 0x37, 0xc8, 0x1c, 0x6c, 0xff, 0xcb,
-    0xe0, 0x87, 0xd3, 0xab, 0x56, 0x41, 0xd7, 0xc1, 0xee, 0x6d, 0x9d, 0xab,
-    0xd8, 0x29, 0x79, 0xec, 0xff, 0xa8, 0xaa, 0xf4, 0xd9, 0xfc, 0xa0, 0xe4,
-    0xf7, 0x22, 0x79, 0xe4, 0xcf, 0x5,  0x7e, 0x59, 0x94, 0x4d, 0x2f, 0x18,
-    0xeb, 0x4c, 0xab, 0x78, 0xb3, 0x58, 0x69, 0x73, 0x8e, 0x7b, 0xc1, 0xc9,
-    0x7f, 0x90, 0x63, 0xe,  0x48, 0x7c, 0x40, 0x49, 0x2c, 0xb9, 0xf0, 0x50,
-    0xed, 0x82, 0x15, 0x14, 0x8f, 0xac, 0xab, 0x46, 0xf2, 0x46, 0x59, 0x9c,
-    0x5f, 0x7b, 0xf7, 0x42, 0xc8, 0x31, 0x90, 0xa0, 0x39, 0xe8, 0x69, 0xd2,
-    0xd4, 0xe6, 0x96, 0x5e, 0xe4, 0x57, 0x32, 0xa3, 0x39, 0x7f, 0x67, 0xb,
-    0xfd, 0xf1, 0x54, 0x45, 0xe1, 0xa0, 0xe,  0x69, 0xa7, 0x31, 0x2,  0xf3,
-    0xd1, 0x57, 0xea, 0x2,  0x93, 0xdc, 0xb6, 0x6,  0x74, 0x3,  0xae, 0xd7,
-    0x18, 0x51, 0x6c, 0xf4, 0x96, 0x16, 0x59, 0x90, 0x3a, 0xe,  0x23, 0xf4,
-    0x41, 0xc4, 0x43, 0xa2, 0x22, 0xa2, 0xaa, 0xf7, 0x68, 0x72, 0x98, 0x69,
-    0x95, 0xc1, 0xc8, 0xf3, 0xc6, 0xb2, 0x9d, 0xc4, 0x5e, 0xbd, 0x56, 0xd8,
-    0xc5, 0x21, 0x76, 0x3f, 0x83, 0xbf, 0x4b, 0xb4, 0xd7, 0xc6, 0x67, 0xf5,
-    0x49, 0x9,  0x7d, 0x99, 0xee, 0x72, 0x22, 0x6c, 0xc0, 0x6b, 0xe3, 0x3c,
-    0x38, 0xb7, 0x37, 0xe2, 0x3c, 0x44, 0x5e, 0x67, 0xbd, 0xff, 0xd3, 0xfa,
-    0xe3, 0x56, 0x50, 0x26, 0xc6, 0xbe, 0x2a, 0x4f, 0xba, 0x50, 0xe5, 0x43,
-    0xb5, 0x4a, 0xc4, 0xe,  0xe3, 0x67, 0xa5, 0xa9, 0xf,  0x2d, 0xbc, 0x9a,
-    0x34, 0xba, 0xed, 0xa1, 0x4f, 0xd9, 0xd,  0x81, 0xf6, 0x44, 0x4c, 0xa2,
-    0x4a, 0x69, 0x4c, 0xe2, 0x77, 0xb3, 0x91, 0x9c, 0xa5, 0x9b, 0xe9, 0xa4,
-    0xba, 0xbd, 0x84, 0xc9, 0x45, 0x60, 0xdd, 0x5d, 0x27, 0x95, 0x16, 0xa1,
-    0x95, 0xfa, 0xf,  0x3c, 0x92, 0xc0, 0xee, 0xc8, 0x6b, 0x25, 0x30, 0xf2,
-    0x64, 0x5f, 0x8d, 0x84, 0xd9, 0x34, 0x41, 0x62, 0xdf, 0x4e, 0x5,  0x4f,
-    0x8d, 0xa8, 0x90, 0x1b, 0xe,  0xc8, 0xc7, 0xe,  0xdd, 0xd3, 0x47, 0x88,
-    0x9a, 0xc5, 0xf8, 0xbf, 0x34, 0x1d, 0x84, 0xd1, 0x67, 0xd3, 0xee, 0x4e,
-    0x62, 0x60, 0x66, 0x5a, 0x8f, 0x5c, 0xe4, 0x88, 0xc9, 0xd8, 0x9e, 0xb9,
-    0x15, 0xd1, 0x4,  0x70, 0x62, 0x7,  0x4e, 0x4d, 0xfd, 0x25, 0x83, 0xc9,
-    0xa4, 0xa7, 0x97, 0xd7, 0xf7, 0x5,  0xca, 0x14, 0x5f, 0xc1, 0x38, 0x34,
-    0x4a, 0xc9, 0x7e, 0x2d, 0xdb, 0x1b, 0x4f, 0x3d, 0xab, 0xd3, 0x6a, 0x64,
-    0xe9, 0xbf, 0x5a, 0x84, 0xa7, 0xc1, 0x31, 0xf5, 0x45, 0xec, 0x1e, 0x29,
-    0x98, 0x1f, 0xc5, 0xab, 0x37, 0xd,  0xcc, 0xf,  0xc4, 0x56, 0x3,  0x6d,
-    0xdb, 0xd1, 0x57, 0x4e, 0x9e, 0x9c, 0x64, 0x29, 0x87, 0x95, 0x8c, 0x6d,
-    0x3c, 0x4e, 0x68, 0x24, 0xd6, 0x4,  0xc7, 0xed, 0xc1, 0x5f, 0x43, 0x4e,
-    0x1c, 0x59, 0x1c, 0x84, 0x58, 0x97, 0xa9, 0xf3, 0x49, 0x90, 0x22, 0x6e,
-    0x51, 0xae, 0x96, 0x9f, 0xb3, 0x55, 0x59, 0xf4, 0xc3, 0xfe, 0x87, 0x97,
-    0xa8, 0xa6, 0xee, 0x0,  0xae, 0xf2, 0x7e, 0x28, 0xe1, 0xca, 0x83, 0xcc,
-    0x1b, 0xf0, 0x56, 0xee, 0xba, 0x25, 0xf6, 0x7e, 0xf4, 0xb6, 0x2e, 0xaf,
-    0xbf, 0x6f, 0x3b, 0xac, 0xf0, 0xc5, 0x8d, 0xe7, 0x4b, 0x61, 0x2c, 0x11,
-    0xcd, 0x85, 0x5c, 0xe6, 0x3b, 0xbe, 0xa4, 0x3c, 0x5e, 0x15, 0x1f, 0x51,
-    0x65, 0xe2, 0xcb, 0xbe, 0x34, 0x27, 0x97, 0x6,  0x7e, 0x35, 0xc8, 0x19,
-    0x99, 0xe0, 0x54, 0x64, 0x12, 0x52, 0x1e, 0x97, 0x9f, 0x1,  0x1f, 0x96,
-    0x35, 0xdc, 0x56, 0xc6, 0x95, 0xa3, 0x54, 0x1f, 0xc8, 0x20, 0x1e, 0xcc,
-    0xe9, 0xf8, 0x7b, 0xf,  0x63, 0x18, 0xd2, 0xfd, 0x64, 0x84, 0x0,  0xdf,
-    0x13, 0x33, 0x27, 0x47, 0x6f, 0xb9, 0x92, 0xe,  0x1e, 0xec, 0x25, 0xe5,
-    0x77, 0x36, 0xd6, 0x70, 0x91, 0x2e, 0x2a, 0xd7, 0x5c, 0x38, 0xfa, 0x53,
-    0xc,  0x1e, 0xae, 0xef, 0x54, 0xbd, 0x91, 0x76, 0x99, 0x2c, 0xbb, 0xa2,
-    0xdc, 0xa8, 0x2e, 0xc7, 0x25, 0x4b, 0x66, 0xe3, 0xa5, 0x54, 0x56, 0xa8,
-    0x53, 0xc2, 0xe,  0xe8, 0x0,  0xaf, 0xcf, 0x8b, 0xc5, 0x77, 0x74, 0x31,
-    0x75, 0xe1, 0x22, 0x24, 0x31, 0xb2, 0x69, 0xec, 0x3,  0x69, 0xa3, 0xf7,
-    0x14, 0x69, 0x2e, 0x3d, 0x75, 0x69, 0x9c, 0xaa, 0x52, 0x1,  0xb1, 0x91,
-    0x16, 0x9b, 0x95, 0xd4, 0x11, 0x6d, 0x73, 0x1e, 0xb1, 0x5c, 0x5f, 0x9b,
-    0xb7, 0x42, 0xf2, 0x3a, 0xc5, 0xc8, 0xad, 0xa7, 0xd,  0x5f, 0x65, 0xe7,
-    0x42, 0x86, 0xd,  0x5b, 0x8a, 0x40, 0x15, 0x7a, 0x5c, 0xa1, 0x59, 0x7d,
-    0xe7, 0xf6, 0xff, 0xa2, 0x33, 0xb1, 0x6d, 0x97, 0x4b, 0x22, 0xb6, 0x79,
-    0xf0, 0xd1, 0x5a, 0x25, 0x6,  0x9c, 0x72, 0xf,  0x95, 0xc6, 0x2e, 0x29,
-    0xc8, 0x5,  0x9d, 0x79, 0x1e, 0xc7, 0x10, 0x4a, 0x96, 0xe5, 0xa9, 0x1,
-    0x81, 0xc7, 0x87, 0x5a, 0x62, 0xed, 0x4f, 0xa9, 0x24, 0xe6, 0x76, 0x85,
-    0x95, 0xf9, 0xf1, 0x73, 0x30, 0xad, 0xd4, 0xbc, 0xeb, 0x91, 0x6a, 0xcc,
-    0xfc, 0xb6, 0x18, 0xc2, 0xcb, 0x20, 0x32, 0x7f, 0xd0, 0x4d, 0x55, 0x1c,
-    0x91, 0xd5, 0xd4, 0x2,  0x3a, 0xab, 0xcd, 0x61, 0x7,  0x92, 0x31, 0x4e,
-    0xc6, 0xdb, 0xed, 0x5,  0x76, 0x2d, 0x2,  0x9a, 0xd8, 0xd2, 0x54, 0x40,
-    0x98, 0x79, 0xd2, 0x95, 0xfd, 0xda, 0x1d, 0x8e, 0xf4, 0xc8, 0xd1, 0xe0,
-    0x24, 0x8b, 0x7d, 0x5a, 0x7b, 0xfa, 0xa2, 0xc7, 0xe0, 0x14, 0xbc, 0x9,
-    0x7e, 0xe8, 0x19, 0x16, 0x93, 0x3a, 0xc6, 0x26, 0x9d, 0x3d, 0x6e, 0xec,
-    0x4a, 0x9a, 0x61, 0xc9, 0xc,  0x74, 0x93, 0xd1, 0x41, 0x97, 0x17, 0x88,
-    0x40, 0x8e, 0x60, 0x76, 0xdd, 0xb0, 0x46, 0x3e, 0x25, 0xad, 0xa4, 0x5f,
-    0x8b, 0x26, 0x81, 0x92, 0x51, 0x77, 0xe,  0x85, 0xa6, 0xb,  0xac, 0x8b,
-    0x8c, 0x30, 0x24, 0x88, 0xf1, 0xc5, 0xf2, 0x3a, 0x9d, 0x49, 0x54, 0xe8,
-    0x52, 0xe1, 0x20, 0xc8, 0x41, 0xee, 0x46, 0xee, 0x6,  0x40, 0x74, 0x3,
-    0x14, 0xe7, 0x96, 0xe4, 0x44, 0xcf, 0xa2, 0xae, 0xf8, 0x9b, 0xcd, 0x5f,
-    0x48, 0xc8, 0xb4, 0x27, 0x85, 0x9d, 0x51, 0x8f, 0x73, 0x64, 0x56, 0x9a,
-    0xef, 0x87, 0xbf, 0x94, 0x8a, 0x54, 0x1b, 0xd1, 0xc7, 0x7a, 0xd5, 0x2c,
-    0xbd, 0xba, 0x3d, 0x1,  0xb4, 0xfa, 0x82, 0x84, 0x88, 0x4c, 0x0,  0x29,
-    0x37, 0x4e, 0xc0, 0x23, 0xf2, 0x75, 0x27, 0x55, 0xd5, 0xa8, 0x83, 0xea,
-    0x7a, 0xab, 0xd5, 0x5f, 0x79, 0xa6, 0x4f, 0xf2, 0x9b, 0xc0, 0x32, 0x94,
-    0xcb, 0x8,  0xa9, 0x92, 0xf7, 0x36, 0xef, 0x9,  0xb9, 0x63, 0x6a, 0xe0,
-    0x75, 0x3,  0x26, 0x53, 0xf,  0xda, 0x36, 0x10, 0x29, 0x4c, 0xaf, 0xa9,
-    0x75, 0xb0, 0xc0, 0xd7, 0xef, 0xd5, 0xf9, 0x2b, 0xb9, 0x5a, 0xe7, 0xfb,
-    0xc1, 0xc7, 0x34, 0x7b, 0x33, 0x55, 0x8,  0xc4, 0x19, 0xf8, 0x7c, 0xa1,
-    0x61, 0x0,  0x43, 0x68, 0xf0, 0xf,  0xbc, 0x41, 0xce, 0x78, 0xc9, 0x61,
-    0xbb, 0xa3, 0x8e, 0xc1, 0xac, 0x7,  0x8b, 0x80, 0xf9, 0x34, 0x14, 0xe8,
-    0xee, 0x2e, 0xb6, 0xb2, 0x82, 0x74, 0x78, 0x96, 0xf0, 0xf2, 0xd5, 0x4f,
-    0xaf, 0x16, 0x5f, 0x8c, 0x50, 0xe9, 0xb2, 0x92, 0xbc, 0xe5, 0x68, 0x26,
-    0x11, 0xf9, 0xbc, 0xa5, 0xd8, 0xe1, 0xd4, 0xad, 0xc,  0x0,  0xde, 0x3a,
-    0x57, 0xfe, 0x4b, 0x63, 0x9a, 0x5b, 0x32, 0xd0, 0x52, 0xc3, 0x88, 0x2b,
-    0x26, 0xc2, 0x73, 0x4,  0x1a, 0xf5, 0x92, 0x54, 0x42, 0x35, 0x8e, 0x11,
-    0x60, 0xb0, 0x10, 0x6c, 0xb4, 0xe2, 0x3a, 0xdc, 0xec, 0x13, 0xa2, 0x44,
-    0xac, 0x95, 0xe5, 0x2c, 0xed, 0x15, 0xe3, 0xdd, 0x52, 0x8,  0x78, 0x21,
-    0x76, 0xfa, 0xab, 0x8d, 0x38, 0x28, 0xda, 0x28, 0x2b, 0x55, 0xe2, 0x95,
-    0x51, 0xeb, 0x51, 0x20, 0xa3, 0x7e, 0xe9, 0x5a, 0x26, 0xd9, 0x5,  0x7d,
-    0x76, 0x55, 0xb6, 0xd8, 0x5b, 0x37, 0x8e, 0xda, 0x2f, 0x71, 0x12, 0xc9,
-    0x9b, 0xdf, 0x3d, 0x6e, 0x8c, 0xf0, 0xe4, 0xb1, 0x9,  0xe4, 0x5,  0x54,
-    0x56, 0x23, 0xf3, 0x7e, 0x6,  0x23, 0xc6, 0xf4, 0x7f, 0x7f, 0x7f, 0xe7,
-    0x7c, 0x23, 0x9c, 0xc4, 0x55, 0x38, 0x3b, 0x59, 0xe3, 0x37, 0x9f, 0xfc,
-    0x6e, 0x89, 0x6d, 0x8d, 0x33, 0xfc, 0x15, 0x68, 0xda, 0x56, 0x8e, 0x14,
-    0x57, 0x3e, 0x8b, 0x7,  0xa3, 0xce, 0xe2, 0x8e, 0x43, 0xef, 0x94, 0xaf,
-    0x2d, 0x10, 0xa3, 0x45, 0xb2, 0x68, 0x8e, 0xd7, 0xf4, 0xe0, 0x2c, 0x62,
-    0x7d, 0x98, 0x7c, 0xe3, 0xc9, 0x8a, 0x99, 0x7a, 0xdb, 0x63, 0xe,  0xb1,
-    0x6f, 0x81, 0xfd, 0x60, 0x8d, 0xaa, 0x9e, 0x53, 0x7a, 0xa3, 0x31, 0x7f,
-    0x1c, 0xbf, 0x0,  0xe9, 0x4c, 0xd,  0x2b, 0xa5, 0x49, 0x23, 0xff, 0x20,
-    0x62, 0xcf, 0xc9, 0x4e, 0x2e, 0xd3, 0x26, 0xaf, 0xdf, 0xe7, 0xef, 0xbf,
-    0xad, 0x3f, 0xa7, 0xb,  0x47, 0x8,  0xc9, 0x59, 0xb1, 0x59, 0xfa, 0xc6,
-    0x39, 0xb9, 0x27, 0xdf, 0x7a, 0xbb, 0x6c, 0xde, 0x9d, 0x81, 0x9a, 0xee,
-    0x4a, 0x9e, 0x8a, 0xc6, 0xd4, 0x48, 0xe9, 0xc9, 0x94, 0x57, 0x6e, 0x84,
-    0x46, 0x69, 0x62, 0x9f, 0x89, 0x94, 0x38, 0x4a, 0xc1, 0xa9, 0x5a, 0x22,
-    0x91, 0x3e, 0xcf, 0x1d, 0x83, 0x7a, 0xe6, 0x7c, 0x8d, 0x74, 0x7,  0x7f,
-    0xf8, 0x44, 0xb5, 0x3f, 0xda, 0x65, 0xe8, 0x2b, 0x9b, 0x1,  0x51, 0x1b,
-    0x89, 0xb0, 0x5c, 0x27, 0x94, 0x1,  0x43, 0x1d, 0x2c, 0x19, 0xcd, 0xda,
-    0xdd, 0x9d, 0x20, 0xe3, 0x24, 0x3,  0x88, 0x83, 0x5,  0xd6, 0x83, 0xee,
-    0x3d, 0x3c, 0x77, 0x14, 0xfd, 0x82, 0x3b, 0x0,  0xbd, 0xb5, 0x0,  0x56,
-    0x59, 0x6b, 0xfb, 0xeb, 0x69, 0xbc, 0xe1, 0xe2, 0x57, 0x53, 0x9f, 0xf6,
-    0xdc, 0x1a, 0x5a, 0x96, 0xea, 0xc6, 0x61, 0x1b, 0xd9, 0x15, 0x14, 0xce,
-    0xd2, 0x3c, 0x59, 0x9a, 0x78, 0x94, 0x5a, 0xe7, 0xd8, 0xea, 0x87, 0xee,
-    0xcd, 0x9d, 0x54, 0xd6, 0xce, 0x9a, 0x91, 0xab, 0x49, 0x61, 0x9,  0xa4,
-    0x5b, 0x9f, 0x78, 0x75, 0xdc, 0x45, 0x7a, 0x34, 0xd1, 0xfb, 0x5c, 0xc0,
-    0x95, 0xe4, 0x49, 0x4f, 0x8a, 0xda, 0xcf, 0x4a, 0x27, 0x3,  0x1b, 0x59,
-    0xcf, 0x23, 0x19, 0xcc, 0x75, 0xdf, 0x26, 0xa6, 0x3c, 0xfa, 0x7f, 0x6d,
-    0x90, 0x8e, 0xcf, 0xc,  0x5e, 0x94, 0x38, 0x1e, 0xe4, 0x82, 0x78, 0xd1,
-    0x4c, 0xcc, 0xac, 0xe8, 0x4d, 0x87, 0xf2, 0x95, 0x8,  0xa3, 0xd6, 0xf4,
-    0x5a, 0x46, 0xde, 0x0,  0x4f, 0x86, 0x2f, 0xf4, 0x15, 0x2d, 0xe7, 0x90,
-    0x11, 0x40, 0xb6, 0xa7, 0x5c, 0x4f, 0x3,  0x28, 0x4a, 0x8b, 0x1d, 0x47,
-    0xfb, 0x49, 0x77, 0x65, 0x83, 0x1e, 0x18, 0xfd, 0xe7, 0x5e, 0x5c, 0x3a,
-    0x21, 0x7f, 0xff, 0xf8, 0x2a, 0x5e, 0x6b, 0xba, 0x19, 0xf2, 0x6e, 0x2b,
-    0x17, 0x80, 0xa7, 0x5b, 0xf7, 0xb2, 0xa3, 0xc3, 0x37, 0x2b, 0xd9, 0x29,
-    0x25, 0x9c, 0x98, 0x6e, 0x5c, 0xed, 0x1d, 0x8f, 0xf4, 0xcb, 0xb6, 0x43,
-    0x80, 0xf8, 0x4d, 0x7d, 0xe8, 0x94, 0xd1, 0x44, 0x2f, 0x7e, 0xb6, 0x80,
-    0xc0, 0x1,  0xc5, 0xc6, 0xb,  0xfc, 0x1,  0xc7, 0x11, 0x13, 0x90, 0xcb,
-    0x29, 0x64, 0xbf, 0xfa, 0x84, 0xde, 0x50, 0x91, 0xfa, 0x8d, 0x87, 0x8c,
-    0xc,  0x19, 0x4b, 0x83, 0x4e, 0x8a, 0x83, 0xb8, 0xbc, 0x79, 0x5f, 0x8d,
-    0xe3, 0x19, 0x9a, 0xae, 0xdd, 0xe6, 0x8f, 0xda, 0xb2, 0x11, 0x63, 0xe9,
-    0x44, 0x4c, 0x20, 0x11, 0x1d, 0x27, 0x63, 0x10, 0xf9, 0x70, 0x1d, 0x42,
-    0xf,  0x3f, 0x8b, 0x30, 0x92, 0x66, 0x7c, 0x20, 0x9e, 0xfc, 0xf6, 0x87,
-    0x6b, 0x3b, 0xc4, 0x8f, 0x8,  0xdf, 0x74, 0x92, 0xb8, 0x7,  0xc4, 0x47,
-    0x6b, 0xe9, 0xc0, 0x93, 0xc7, 0x27, 0x7f, 0xc4, 0x42, 0xaf, 0xde, 0x10,
-    0xfb, 0x8d, 0x7b, 0x3f, 0xba, 0x5,  0x71, 0x43, 0xc3, 0xa7, 0xc1, 0x65,
-    0x35, 0x52, 0xba, 0xb7, 0xe3, 0x4a, 0x9e, 0x7,  0xb4, 0x95, 0x74, 0x82,
-    0x60, 0x9f, 0xbc, 0x84, 0xf4, 0xa4, 0x82, 0x37, 0xcf, 0x12, 0x44, 0x15,
-    0xed, 0x68, 0x1f, 0x6b, 0x4c, 0xbc, 0xe8, 0xd8, 0x2e, 0x9e, 0x81, 0x87,
-    0x4a, 0x40, 0xf2, 0x1e, 0xd0, 0x60, 0xee, 0xeb, 0x5e, 0x4d, 0x44, 0xc8,
-    0x9,  0x11, 0x77, 0x5d, 0xa5, 0x1b, 0xf3, 0x1a, 0x31, 0xbe, 0xba, 0x7d,
-    0x33, 0x97, 0x36, 0xcd, 0x91, 0xea, 0x1c, 0xc7, 0xbf, 0x1d, 0xd0, 0x3e,
-    0x24, 0x7c, 0x10, 0x6c, 0xbb, 0x5c, 0xfd, 0xbe, 0xde, 0xdb, 0x48, 0x1a,
-    0xbf, 0x91, 0x1b, 0xe7, 0x7e, 0xc2, 0xb,  0x7c, 0x36, 0x13, 0xb1, 0x18,
-    0xad, 0x60, 0xf2, 0x1d, 0x2b, 0xb1, 0x88, 0xb1, 0x72, 0x7a, 0x7a, 0xa0,
-    0xe6, 0x38, 0xde, 0xa4, 0x86, 0xfc, 0x43, 0xc4, 0xa1, 0xa6, 0xf5, 0x2f,
-    0x9a, 0x9e, 0x5,  0xf1, 0xef, 0xaa, 0x42, 0x40, 0xe2, 0xba, 0x81, 0x3e,
-    0xa,  0x5f, 0xa0, 0xa6, 0x37, 0x5a, 0xc8, 0x4b, 0x7,  0x60, 0x5f, 0xb6,
-    0xf8, 0x70, 0xd6, 0x5c, 0x85, 0x97, 0x1a, 0x66, 0x7c, 0xae, 0x9d, 0xd7,
-    0xb4, 0xfa, 0x94, 0x3a, 0x2f, 0x1e, 0x1f, 0xee, 0x2b, 0x45, 0xa6, 0xc6,
-    0xd7, 0x9b, 0xec, 0x7b, 0x3e, 0xf8, 0xc,  0x4f, 0x6a, 0xad, 0x6e, 0xc7,
-    0x9d, 0xee, 0xc,  0x29, 0x9,  0xfc, 0x86, 0x4b, 0xe4, 0x8,  0x44, 0x2a,
-    0x6f, 0xbc, 0xea, 0x9f, 0xcf, 0x58, 0xb1, 0x36, 0x2f, 0xce, 0xb4, 0x93,
-    0xae, 0x67, 0xca, 0xe5, 0x3b, 0xed, 0xe0, 0x6d, 0xaf, 0xc7, 0x9,  0xc8,
-    0x42, 0x3d, 0x9a, 0x33, 0xc5, 0x80, 0x72, 0x1,  0xd3, 0x67, 0xbf, 0x2f,
-    0x9c, 0xe1, 0xb9, 0x4d, 0x0,  0x58, 0x5e, 0x94, 0x9a, 0xda, 0x72, 0xc5,
-    0x17, 0x81, 0xd8, 0xb6, 0xcd, 0xa8, 0xf6, 0xed, 0x91, 0x43, 0xa2, 0x82,
-    0x80, 0x7d, 0xa,  0x75, 0xe4, 0xef, 0x2,  0xb9, 0x1,  0x5a, 0x6a, 0xd4,
-    0x47, 0x70, 0x2c, 0x66, 0x2c, 0x39, 0xcb, 0xad, 0xd5, 0x89, 0x89, 0x4a,
-    0x39, 0x59, 0x7d, 0xd6, 0x6a, 0x27, 0x2c, 0x7a, 0xcc, 0xc9, 0x85, 0xe2,
-    0xc5, 0x50, 0xf7, 0x13, 0xfc, 0x41, 0x1a, 0xaa, 0x24, 0x66, 0x88, 0x54,
-    0x99, 0xe1, 0x72, 0x2a, 0xd4, 0x42, 0x67, 0x4d, 0xa2, 0x81, 0x27, 0xce,
-    0xd,  0x7e, 0x7f, 0x81, 0x44, 0xaa, 0x92, 0x69, 0x75, 0x3c, 0xb,  0x60,
-    0xa5, 0xa3, 0xd0, 0x45, 0x56, 0x17, 0x58, 0xce, 0xdd, 0x9f, 0x4e, 0x32,
-    0x25, 0x98, 0x4b, 0xfb, 0xd0, 0xf0, 0x4b, 0x24, 0x1a, 0xb2, 0xec, 0xca,
-    0x16, 0x74, 0xdf, 0xf8, 0x4,  0x27, 0x64, 0xf3, 0x85, 0x9,  0x11, 0x2a,
-    0xf6, 0x43, 0x40, 0x4c, 0x3a, 0xe1, 0x4d, 0xdb, 0x2,  0xd1, 0xb7, 0x29,
-    0x2f, 0x9e, 0x38, 0x4f, 0xb0, 0x6,  0xb8, 0xe5, 0xc3, 0x18, 0x54, 0xb9,
-    0x49, 0xcb, 0x4a, 0xc9, 0x47, 0xba, 0x3a, 0x67, 0x1,  0x10, 0x76, 0x1a,
-    0xe8, 0xa7, 0xd6, 0x9b, 0x78, 0x9d, 0xf5, 0xb2, 0xf8, 0xb5, 0x24, 0x45,
-    0xf,  0x92, 0x64, 0x19, 0xe7, 0x78, 0x1d, 0xdb, 0x43, 0x2a, 0x27, 0x6a,
-    0x66, 0xdf, 0xc1, 0xc2, 0x59, 0xf8, 0x4f, 0x76, 0xd3, 0x87, 0x75, 0x46,
-    0x9d, 0xd9, 0xd8, 0x4d, 0xd3, 0xcf, 0x92, 0x7d, 0x4f, 0x4e, 0x90, 0xc9,
-    0x6c, 0x7a, 0x42, 0x71, 0x99, 0xc1, 0x2a, 0xb0, 0x31, 0x80, 0x33, 0x30,
-    0x78, 0x5c, 0xac, 0x12, 0xa3, 0x8b, 0x7,  0x4a, 0x36, 0x1c, 0xf9, 0xcc,
-    0xc,  0xb4, 0xec, 0x34, 0x68, 0xa6, 0x21, 0x81, 0xe4, 0x65, 0x2f, 0x2c,
-    0x18, 0x20, 0x55, 0x4,  0xad, 0xf4, 0x21, 0x43, 0x3b, 0xb0, 0xfc, 0xe3,
-    0xea, 0x39, 0x4f, 0x51, 0x77, 0x7e, 0xa8, 0xd,  0x8b, 0xb9, 0xef, 0x9c,
-    0x2d, 0xfd, 0x4b, 0x2a, 0xac, 0x34, 0x4a, 0x60, 0xb7, 0xa6, 0xa5, 0x8c,
-    0xd8, 0x2d, 0x45, 0x1b, 0x0,  0xe7, 0xdd, 0x2d, 0xeb, 0x9d, 0x7e, 0x4c,
-    0x49, 0xa8, 0xe6, 0x8d, 0x48, 0xde, 0x8b, 0x98, 0xff, 0x4f, 0xd5, 0x16,
-    0x8,  0x6,  0x36, 0x7a, 0xe1, 0x7d, 0x2a, 0x85, 0xc8, 0xb1, 0x6f, 0x3e,
-    0xb2, 0x10, 0x90, 0x91, 0xdc, 0x56, 0xb,  0xbf, 0xe5, 0x46, 0xa6, 0x56,
-    0x4e, 0x9c, 0x2d, 0xdd, 0x34, 0x0,  0xe1, 0xe9, 0xf7, 0xaf, 0x90, 0x63,
-    0x32, 0x74, 0x35, 0xfd, 0xf5, 0x28, 0x73, 0x81, 0x32, 0x50, 0x42, 0x11,
-    0xbe, 0x33, 0x77, 0x6a, 0xea, 0x29, 0xdf, 0x98, 0x6e, 0xeb, 0xc6, 0x2f,
-    0x5a, 0x5a, 0x93, 0xd9, 0xdf, 0xc8, 0x41, 0x33, 0x3c, 0xae, 0xc7, 0x2f,
-    0x35, 0x1c, 0xce, 0x5b, 0xa8, 0x68, 0x3e, 0x43, 0x73, 0x62, 0x30, 0xd3,
-    0xa3, 0xfc, 0x61, 0x2c, 0x95, 0xe0, 0xdb, 0xf,  0x35, 0x96, 0x1c, 0x28,
-    0xb9, 0x6e, 0xbb, 0xda, 0x96, 0xf2, 0x92, 0x5a, 0x7,  0xbf, 0x4c, 0xd1,
-    0xe1, 0x77, 0x14, 0x90, 0xb6, 0x48, 0x2b, 0xc1, 0x3e, 0xe4, 0x9a, 0xfe,
-    0x3c, 0xbc, 0xf4, 0xf1, 0x1f, 0x54, 0x17, 0xdd, 0x85, 0xf5, 0xc3, 0x7b,
-    0xda, 0xca, 0x9e, 0xc8, 0x91, 0xe9, 0xbd, 0xc7, 0xa3, 0x51, 0x4e, 0x3d,
-    0x55, 0xd9, 0xf7, 0x79, 0x1b, 0xbf, 0x69, 0xa3, 0x58, 0x4d, 0x96, 0xd8,
-    0x57, 0x3a, 0x49, 0x71, 0x38, 0xe,  0xec, 0x68, 0x73, 0x8f, 0x2b, 0xbc,
-    0xb9, 0x53, 0x43, 0x11, 0xc8, 0xff, 0x92, 0x81, 0x7d, 0xe6, 0x29, 0xdf,
-    0x7a, 0xb0, 0xd3, 0x7f, 0x31, 0xa,  0xef, 0xce, 0xac, 0xdd, 0x57, 0xbb,
-    0x3a, 0x0,  0x87, 0x57, 0x7,  0xce, 0x84, 0xa7, 0x5,  0x76, 0x10, 0xe0,
-    0x69, 0xf3, 0xec, 0xa5, 0x12, 0x91, 0x97, 0x5d, 0x83, 0xd5, 0x35, 0xba,
-    0x30, 0xe1, 0xf1, 0x1,  0x49, 0xe1, 0x86, 0x50, 0xd4, 0x52, 0x32, 0x73,
-    0xc7, 0xab, 0x1a, 0xe6, 0xb2, 0xab, 0xff, 0x77, 0xc4, 0x14, 0x20, 0xad,
-    0xd1, 0xbf, 0x69, 0xc6, 0x11, 0x4c, 0x24, 0x3e, 0x1d, 0xc9, 0x84, 0x9d,
-    0xe2, 0xa6, 0xc8, 0x4d, 0xed, 0xf5, 0x84, 0x74, 0xae, 0x68, 0x17, 0x70,
-    0x59, 0xe,  0xeb, 0xe2, 0xda, 0x83, 0x21, 0xfd, 0x81, 0x66, 0x21, 0x61,
-    0x47, 0xb2, 0xb7, 0xa5, 0x9a, 0x95, 0xf8, 0x91, 0x51, 0x5c, 0xf8, 0x63,
-    0x52, 0xe2, 0x5a, 0x5e, 0x58, 0xd3, 0xda, 0x74, 0x68, 0xba, 0xfe, 0xda,
-    0xe7, 0x96, 0xd8, 0x61, 0x5c, 0xf6, 0x7c, 0xd,  0x1d, 0xb1, 0x80, 0x1b,
-    0x7f, 0x5e, 0x85, 0x4a, 0xfe, 0xe,  0x62, 0x65, 0x77, 0x84, 0xe,  0x4e,
-    0x59, 0xfc, 0x7d, 0xc2, 0xe4, 0x7d, 0x43, 0x27, 0x6d, 0xc7, 0x4,  0xb8,
-    0x47, 0xe,  0x8c, 0x25, 0xec, 0x25, 0x9d, 0x88, 0x16, 0x73, 0x7d, 0x6f,
-    0x46, 0x24, 0xd5, 0x16, 0x14, 0xde, 0x54, 0x94, 0xed, 0x1c, 0x9e, 0xe3,
-    0x6d, 0xb3, 0xe1, 0x57, 0xab, 0xab, 0x87, 0xbb, 0xf7, 0x6c, 0x87, 0xcf,
-    0x94, 0xde, 0x8d, 0x23, 0xe2, 0x9d, 0xbb, 0x93, 0xf8, 0x69, 0x43, 0x74,
-    0x22, 0x31, 0x85, 0x8e, 0x6a, 0x91, 0x9,  0x9e, 0xac, 0xc9, 0xdb, 0xe6,
-    0xec, 0x39, 0xe3, 0x86, 0x42, 0xd3, 0xfc, 0xbe, 0x57, 0xdb, 0x7c, 0xa7,
-    0x9b, 0x5,  0xed, 0x8e, 0x26, 0xde, 0x5a, 0xc4, 0xe2, 0x4b, 0xa2, 0x13,
-    0xd8, 0x59, 0x9d, 0x67, 0x3,  0x6a, 0x93, 0x68, 0x41, 0x34, 0x5,  0xfd,
-    0x1e, 0x65, 0xdf, 0xac, 0xbe, 0xa6, 0x17, 0xf1, 0x56, 0x92, 0x7a, 0xfe,
-    0x80, 0xbd, 0xd9, 0xfa, 0xb6, 0x37, 0x2d, 0x56, 0x23, 0xc9, 0x5d, 0x87,
-    0x1c, 0xa9, 0x7,  0xbc, 0xf3, 0x3c, 0x28, 0xdc, 0x4d, 0x85, 0x29, 0x72,
-    0x64, 0x7,  0x49, 0x6f, 0x96, 0xae, 0xb4, 0x55, 0xc8, 0x18, 0xfe, 0xb,
-    0x36, 0x10, 0xc8, 0xbd, 0x5b, 0x66, 0xd,  0xef, 0xf5, 0x22, 0xe9, 0x5e,
-    0x39, 0x2e, 0xb5, 0x2a, 0x36, 0x2a, 0x53, 0x8e, 0xda, 0x7c, 0x3d, 0xbb,
-    0xc,  0x7d, 0x27, 0x5a, 0x21, 0x7a, 0xf8, 0xb3, 0xd2, 0x26, 0x1f, 0x0,
-    0xe5, 0x13, 0xee, 0x70, 0x56, 0x6d, 0x85, 0x30, 0x24, 0x10, 0xe7, 0x49,
-    0x11, 0x5c, 0xec, 0x3a, 0x5,  0x74, 0xc7, 0xe7, 0x51, 0x93, 0x5,  0x3a,
-    0x7c, 0x96, 0x43, 0xe7, 0xd4, 0x5d, 0x32, 0x62, 0xf7, 0xff, 0x3a, 0xc7,
-    0x72, 0xba, 0x91, 0x59, 0x86, 0xa,  0x7d, 0x84, 0xd4, 0xd4, 0x0,  0x1d,
-    0xe3, 0xb9, 0x1a, 0xc5, 0xa2, 0xed, 0x67, 0xc2, 0x4f, 0xe3, 0xeb, 0xd0,
-    0xae, 0x1a, 0x49, 0x55, 0x50, 0x57, 0xf0, 0x78, 0xc8, 0xbc, 0x20, 0x8,
-    0x6a, 0x4,  0x1c, 0x21, 0xa1, 0xf,  0x5b, 0x9d, 0xad, 0xc1, 0x22, 0x26,
-    0xe0, 0x50, 0x8,  0x1f, 0xfe, 0xe5, 0x8c, 0x9e, 0xf7, 0xd9, 0x3d, 0x92,
-    0xed, 0xb3, 0x7d, 0x7e, 0xa6, 0xac, 0x3a, 0x57, 0xaa, 0x4c, 0xb3, 0xb,
-    0xc0, 0x86, 0xd2, 0x9b, 0x2e, 0xbe, 0xbe, 0xfd, 0xc2, 0xc2, 0xd6, 0xe7,
-    0xec, 0x53, 0x4,  0xe9, 0x21, 0x81, 0x1f, 0x37, 0xe4, 0xbe, 0xa9, 0x92,
-    0x72, 0x7d, 0x9f, 0x9a, 0xe8, 0x80, 0x2d, 0xe5, 0x6f, 0xbb, 0x21, 0xbd,
-    0x7d, 0xbe, 0xee, 0xac, 0x11, 0x3c, 0x7b, 0x15, 0x16, 0x27, 0xa7, 0x13,
-    0x42, 0x40, 0xa3, 0x73, 0xf7, 0x3b, 0xd9, 0xf2, 0xc9, 0x69, 0x5f, 0xed,
-    0xbf, 0x2e, 0xd6, 0x4e, 0xe5, 0x17, 0x95, 0x1c, 0xdd, 0x81, 0xae, 0x64,
-    0x6a, 0x2c, 0x15, 0x6f, 0xe4, 0x37, 0x65, 0x26, 0xd6, 0xd0, 0x86, 0x48,
-    0x4d, 0x3d, 0xa1, 0x2e, 0x9e, 0xd4, 0xd4, 0x8d, 0xd2, 0x33, 0x6c, 0x8b,
-    0x1d, 0x50, 0x3e, 0x1e, 0xe0, 0xad, 0x9a, 0xe7, 0x45, 0x17, 0xa8, 0xbe,
-    0x52, 0x13, 0xec, 0x5d, 0x8d, 0x10, 0x85, 0x1a, 0xf7, 0xbc, 0x98, 0xe8,
-    0x57, 0xbd, 0x75, 0x1d, 0x7a, 0xb9, 0x7f, 0xf1, 0xa1, 0x83, 0x8f, 0x53,
-    0x5f, 0xc7, 0x8,  0x31, 0x86, 0xb3, 0x33, 0x73, 0xa1, 0x6a, 0xce, 0x88,
-    0x8b, 0x5d, 0xe4, 0x3f, 0x90, 0x1b, 0x4e, 0xb,  0x51, 0x2f, 0xb3, 0x4b,
-    0x60, 0x9f, 0xf6, 0xc7, 0x90, 0xfb, 0x4c, 0x38, 0xd6, 0xaa, 0xc0, 0x78,
-    0x52, 0x9a, 0x85, 0xf0, 0x1,  0xeb, 0xd0, 0x4c, 0xc8, 0x72, 0x39, 0x75,
-    0x22, 0xae, 0xd1, 0x62, 0x9d, 0x4f, 0x4e, 0xf3, 0xdd, 0x1b, 0x89, 0x9f,
-    0x1e, 0x4f, 0x8a, 0x45, 0xd6, 0x4e, 0x15, 0xef, 0xf2, 0x6b, 0x32, 0x15,
-    0x5b, 0xf8, 0x94, 0xbb, 0x1,  0x25, 0xd2, 0xf1, 0x77, 0x7a, 0x9b, 0x73,
-    0xc4, 0xe4, 0x2d, 0x3f,
-};
-const uint8_t kAltGameImages2xD[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x29, 0xa3, 0xa8, 0xaa,
-    0x9c, 0x8a, 0xfe, 0x4,  0xe6, 0xc8, 0x54, 0xf6, 0x2b, 0xa1, 0x37, 0xe8,
-    0x96, 0xf6, 0x93, 0xd,  0x9d, 0xce, 0xd2, 0xdd, 0x5e, 0x30, 0xaf, 0x79,
-    0x5e, 0x2d, 0x5b, 0x8c, 0xac, 0x2,  0x2a, 0x7e, 0xbb, 0x7b, 0xb7, 0xb6,
-    0xd6, 0x1d, 0xf0, 0x24, 0xd,  0x14, 0xd0, 0x5a, 0x22, 0xea, 0xda, 0x95,
-    0x3a, 0xd1, 0x12, 0x93, 0xd3, 0xb2, 0xc8, 0xbd, 0x37, 0xbf, 0xc3, 0xfa,
-    0x2d, 0x7c, 0x3,  0x7d, 0xab, 0xdc, 0xf6, 0x40, 0x5e, 0xad, 0x77, 0xa,
-    0x21, 0xe3, 0xc0, 0xec, 0x42, 0x3b, 0x2b, 0xf3, 0xa6, 0x7d, 0x59, 0x5b,
-    0xe8, 0xcf, 0x5,  0x5c, 0x75, 0xb5, 0x6f, 0x10, 0x7a, 0xa3, 0xb8, 0x71,
-    0xaa, 0x39, 0xe0, 0x13, 0x5e, 0xa2, 0x7,  0xa5, 0x85, 0xd4, 0x4c, 0xb6,
-    0x13, 0x94, 0xe0, 0x62, 0xc0, 0xb2, 0xa4, 0xbe, 0x96, 0xe5, 0x3,  0xf2,
-    0xb5, 0xd7, 0x93, 0x69, 0xb5, 0x85, 0x4a, 0x84, 0x92, 0xc7, 0x45, 0xf5,
-    0xec, 0x5b, 0x91, 0x6a, 0xf7, 0x64, 0xf7, 0x4,  0x70, 0x88, 0x5c, 0xca,
-    0xf,  0xa1, 0x91, 0x12, 0x6d, 0x7a, 0xe9, 0x4b, 0xc,  0x7c, 0x1b, 0x1b,
-    0x5e, 0xba, 0x13, 0xd6, 0x88, 0x9b, 0xc1, 0x19, 0x6a, 0x30, 0xa2, 0xc2,
-    0x3a, 0x1e, 0x21, 0x5b, 0xc3, 0x2,  0x3f, 0xbb, 0xf6, 0x1c, 0x56, 0x60,
-    0xf9, 0xb7, 0xad, 0xaa, 0x7,  0x62, 0x37, 0xbb, 0xcc, 0xd5, 0x1d, 0xeb,
-    0x92, 0x12, 0x37, 0x75, 0xcb, 0x4f, 0xeb, 0x44, 0x7a, 0x3c, 0xd4, 0xc5,
-    0x3e, 0x2f, 0x73, 0x9b, 0x50, 0x12, 0x8d, 0xa7, 0x7f, 0xe6, 0xe6, 0xc0,
-    0xe,  0x47, 0x39, 0x60, 0x3a, 0x9b, 0x26, 0x93, 0x4d, 0xa3, 0xef, 0xc9,
-    0x8a, 0xa7, 0x69, 0xfb, 0x8f, 0x68, 0x3a, 0x93, 0x6a, 0x44, 0x28, 0x33,
-    0x15, 0xdd, 0xcb, 0x0,  0xe8, 0xcd, 0x43, 0xeb, 0xd0, 0x6b, 0xeb, 0x2b,
-    0x10, 0x9a, 0x9f, 0x7a, 0x40, 0xf5, 0x62, 0xa3, 0x78, 0xb2, 0xfa, 0x29,
-    0xcb, 0x21, 0xec, 0xcd, 0x4c, 0xd6, 0xd9, 0x75, 0xc0, 0xb8, 0x53, 0xa9,
-    0x5f, 0xc2, 0x25, 0x1c, 0x29, 0xed, 0x9,  0x25, 0xf,  0xf7, 0xd5, 0xc1,
-    0x4d, 0xd9, 0x97, 0x23, 0x38, 0xda, 0x78, 0x1c, 0x93, 0x6f, 0xca, 0x3c,
-    0xd0, 0xa6, 0xbd, 0x17, 0xa6, 0xc4, 0xd5, 0xa4, 0x6c, 0x8a, 0x9e, 0xa3,
-    0x94, 0x83, 0xb4, 0xbf, 0x20, 0x35, 0xbd, 0x68, 0xeb, 0x7e, 0x71, 0xc4,
-    0xc0, 0x49, 0x47, 0xbd, 0x8b, 0xe9, 0x96, 0x74, 0x4d, 0xe7, 0xd1, 0xe9,
-    0xcf, 0x7,  0x79, 0xf5, 0x7f, 0x21, 0x52, 0x9a, 0x50, 0x2,  0xdc, 0x8b,
-    0xb0, 0x63, 0xb1, 0x34, 0xb8, 0x7b, 0x6b, 0x3f, 0xa3, 0xa7, 0xa0, 0x2f,
-    0xfa, 0xb3, 0xd3, 0xbe, 0xd3, 0xd4, 0xa6, 0xde, 0x30, 0x7c, 0x1,  0x86,
-    0x3e, 0xa1, 0xd,  0x11, 0x1d, 0xd8, 0xe1, 0x90, 0xd2, 0x6e, 0x2a, 0x81,
-    0x2e, 0x43, 0xb5, 0x46, 0x45, 0xc6, 0x47, 0x80, 0xab, 0x8d, 0x6c, 0xc6,
-    0xd2, 0xe1, 0xe4, 0x76, 0x6e, 0x2a, 0x3d, 0x1b, 0x73, 0x5b, 0x24, 0x36,
-    0x61, 0xda, 0x6d, 0x30, 0xd3, 0x1a, 0x3,  0xf,  0x26, 0x67, 0x8f, 0x9f,
-    0xbc, 0xc1, 0xed, 0x90, 0x8e, 0xaf, 0x6b, 0x9a, 0xc4, 0x1d, 0xad, 0x1e,
-    0x4d, 0xbc, 0xe,  0xfa, 0x17, 0xde, 0xcc, 0x7b, 0xd0, 0x5a, 0xb2, 0x53,
-    0x71, 0x8f, 0xf2, 0x45, 0x69, 0x38, 0xe0, 0xd3, 0xd4, 0xd2, 0xab, 0xad,
-    0xe0, 0x3,  0x3,  0x58, 0xe,  0xcc, 0xe9, 0x65, 0x52, 0x1f, 0xe,  0xc3,
-    0x9d, 0x68, 0x4a, 0xc3, 0x22, 0x71, 0x67, 0x22, 0x41, 0x50, 0x8,  0x28,
-    0xb2, 0x26, 0x0,  0x8a, 0x52, 0xf3, 0x66, 0xa8, 0x6e, 0xa1, 0x33, 0x2c,
-    0xab, 0x5a, 0x29, 0x69, 0x46, 0x73, 0xeb, 0x2c, 0xa8, 0xbe, 0x3f, 0xc6,
-    0xd7, 0x32, 0x14, 0x3d, 0x56, 0xf6, 0xdf, 0x8c, 0x65, 0x68, 0x87, 0xfd,
-    0xf2, 0xdc, 0xcc, 0x71, 0x21, 0xd0, 0x13, 0xe,  0x56, 0x94, 0xa0, 0x1a,
-    0xf2, 0x11, 0x7a, 0xe,  0x2b, 0x87, 0x98, 0x48, 0xb8, 0x76, 0xda, 0xf3,
-    0xeb, 0x30, 0xc,  0xa8, 0x87, 0x4a, 0x91, 0xb7, 0x95, 0xf0, 0x86, 0x5,
-    0xe2, 0xd7, 0xd6, 0xf9, 0x5,  0xbd, 0x3,  0x62, 0x90, 0x32, 0x37, 0xb4,
-    0xf,  0x29, 0xaf, 0x7,  0x6d, 0x82, 0x56, 0x97, 0xb3, 0x9c, 0x55, 0x33,
-    0xd7, 0x24, 0x1d, 0x7,  0xc7, 0xf,  0x3e, 0x18, 0xd4, 0x69, 0xd4, 0x35,
-    0xb4, 0x5,  0x13, 0xf3, 0xe,  0xe1, 0xf8, 0x19, 0x21, 0x7,  0x46, 0xa4,
-    0x57, 0x93, 0x7,  0x2f, 0x49, 0x30, 0x3c, 0xa6, 0xde, 0x4,  0xee, 0x33,
-    0xe3, 0x4d, 0x4,  0x46, 0xca, 0x6b, 0xe6, 0xda, 0x87, 0x44, 0x9f, 0xf5,
-    0xc7, 0xce, 0x60, 0x66, 0x32, 0xde, 0x89, 0xc5, 0x23, 0xd,  0xe3, 0x53,
-    0xdd, 0x99, 0xd1, 0x17, 0x81, 0x83, 0x7b, 0x7c, 0xb6, 0xed, 0x8c, 0xaa,
-    0x6c, 0x5e, 0x7b, 0xba, 0x58, 0x89, 0x61, 0xea, 0x2f, 0x15, 0xa6, 0x67,
-    0x6d, 0x2,  0x91, 0xd6, 0x7,  0x2f, 0x68, 0xaa, 0xf1, 0x7,  0x73, 0x1c,
-    0xe1, 0xc9, 0x98, 0xc,  0x61, 0xfa, 0x52, 0x63, 0x8f, 0x14, 0xb0, 0x54,
-    0x64, 0xd9, 0xfe, 0x2d, 0x74, 0x5c, 0x80, 0x36, 0x86, 0xb,  0xb9, 0xe2,
-    0xf7, 0x45, 0xb3, 0x56, 0xb8, 0x49, 0x21, 0x39, 0x2f, 0x90, 0xf3, 0x3d,
-    0x2f, 0xb8, 0xc8, 0x9c, 0x2a, 0x3b, 0xb5, 0x99, 0x35, 0xa5, 0x31, 0xaa,
-    0x1d, 0x30, 0xf,  0x12, 0xe0, 0x43, 0xaa, 0xf9, 0xd5, 0x5f, 0x75, 0xcf,
-    0xda, 0xd2, 0x92, 0x7a, 0x73, 0xc2, 0x93, 0x5a, 0xdf, 0x3d, 0x92, 0x3a,
-    0x32, 0xa9, 0xd4, 0x4f, 0x88, 0xb0, 0x4d, 0xdf, 0xf4, 0xb7, 0xa9, 0x81,
-    0xa8, 0x68, 0x1f, 0x3,  0xd4, 0x5f, 0xe6, 0xd0, 0x36, 0x8d, 0x6c, 0xa,
-    0x2b, 0x32, 0x83, 0x75, 0xfa, 0x76, 0xd0, 0xc3, 0xc6, 0xcd, 0xd1, 0xb0,
-    0x58, 0x7a, 0xa0, 0x28, 0xe8, 0xf1, 0x94, 0xcd, 0xb9, 0x97, 0x6d, 0xc0,
-    0x8f, 0xd3, 0xc8, 0xd8, 0x11, 0xcf, 0xc8, 0x5f, 0xa6, 0x3e, 0xfd, 0x22,
-    0x2,  0xcc, 0x7,  0xc9, 0x3f, 0xf9, 0x9e, 0x6d, 0x79, 0x5a, 0xa5, 0x7f,
-    0x40, 0x58, 0x2c, 0x64, 0xa8, 0x9c, 0x26, 0x6c, 0xbe, 0x93, 0x9,  0xf7,
-    0xf,  0x9e, 0x41, 0xef, 0x1d, 0x64, 0xed, 0x46, 0x76, 0x96, 0xb8, 0x47,
-    0xa8, 0x2c, 0x30, 0xbf, 0xae, 0x31, 0xff, 0x2,  0x74, 0x4b, 0xb6, 0x72,
-    0x43, 0x37, 0x3d, 0x28, 0x54, 0x8e, 0x98, 0xcb, 0x5d, 0xeb, 0xc6, 0x51,
-    0x8,  0xc,  0xd9, 0xb5, 0xef, 0x5d, 0x78, 0xe3, 0x8a, 0xce, 0x99, 0xbe,
-    0xb8, 0xc1, 0x16, 0x64, 0xad, 0x52, 0xc,  0x33, 0x7,  0xad, 0x7d, 0xbb,
-    0xcb, 0x27, 0xb8, 0x20, 0x54, 0xab, 0x49, 0xa8, 0xf3, 0xbb, 0xfd, 0x7e,
-    0xb3, 0x2,  0x40, 0xd8, 0x7,  0x43, 0xce, 0xa,  0xb5, 0xe5, 0xa4, 0x28,
-    0xaa, 0xcd, 0x54, 0x5c, 0xc8, 0xd3, 0x13, 0x4,  0xda, 0x28, 0x15, 0xd8,
-    0xb7, 0xea, 0x99, 0x6,  0x7,  0xad, 0x43, 0x50, 0xe4, 0xe0, 0xe9, 0xf3,
-    0x31, 0x65, 0xd7, 0x4f, 0xd1, 0x27, 0xe3, 0x4d, 0x56, 0xd8, 0xfb, 0x67,
-    0x2f, 0xed, 0x1c, 0xfd, 0xf7, 0xf0, 0xe9, 0x27, 0x1c, 0x8c, 0x93, 0xeb,
-    0x59, 0x6f, 0x6b, 0x69, 0x6,  0x9f, 0x71, 0x7a, 0x2,  0x33, 0xf4, 0x95,
-    0xfa, 0x61, 0x1,  0xfb, 0xc8, 0x7,  0x5d, 0x12, 0x46, 0x50, 0xef, 0xe9,
-    0xa7, 0xd3, 0xe3, 0x33, 0x69, 0x59, 0xd0, 0x83, 0xad, 0xf0, 0x99, 0xdd,
-    0x2d, 0xcd, 0x5e, 0xf7, 0x4,  0xac, 0xd4, 0x36, 0xcf, 0xc0, 0xdf, 0xd5,
-    0xce, 0xbd, 0x3d, 0xc8, 0x40, 0x3d, 0xc2, 0x6b, 0xb8, 0x32, 0xff, 0x82,
-    0xa2, 0x62, 0x94, 0x51, 0x9,  0xb6, 0x86, 0xa1, 0x71, 0xf7, 0xbf, 0x7,
-    0x45, 0x2a, 0x63, 0xc3, 0xc3, 0x3a, 0xa4, 0x21, 0x39, 0x12, 0x6f, 0x49,
-    0x53, 0x1b, 0xde, 0x53, 0xa3, 0xde, 0xbb, 0xa4, 0x6d, 0x65, 0x39, 0x7c,
-    0x6d, 0x31, 0x5a, 0x8,  0x8c, 0x5a, 0x87, 0xee, 0x6f, 0xfb, 0x92, 0x4a,
-    0xf9, 0x73, 0x56, 0x9a, 0xb8, 0x3f, 0x8d, 0xb6, 0x5b, 0x8,  0x80, 0xec,
-    0x51, 0xbb, 0x6,  0x2f, 0x98, 0x80, 0x7c, 0x26, 0xab, 0xbb, 0x85, 0xfb,
-    0x9e, 0xe6, 0x90, 0x16, 0xa2, 0xa5, 0x9b, 0xb3, 0x53, 0x40, 0x5c, 0x75,
-    0x23, 0x3,  0xee, 0xe8, 0x8f, 0x4,  0xb2, 0x77, 0x3,  0x9,  0xd6, 0xa3,
-    0xe5, 0xd8, 0xd,  0x11, 0xb3, 0x2d, 0x33, 0xf2, 0x39, 0x64, 0x8,  0x41,
-    0x69, 0x38, 0xaa, 0xfb, 0xac, 0xaa, 0xd,  0x85, 0x82, 0x7a, 0x4b, 0x87,
-    0x43, 0x95, 0xca, 0x43, 0x10, 0x69, 0x3d, 0x47, 0x6f, 0x28, 0x36, 0x52,
-    0xcd, 0x9d, 0x61, 0xa9, 0x2e, 0x4a, 0x7c, 0xcb, 0x60, 0x4c, 0x80, 0xc1,
-    0x8f, 0x61, 0x1d, 0xb6, 0xd2, 0x9f, 0x1a, 0x87, 0xd,  0x78, 0xe7, 0xb9,
-    0x83, 0xaf, 0x48, 0xb0, 0x53, 0xe1, 0x22, 0x99, 0xa3, 0x80, 0xae, 0x8b,
-    0xd0, 0x2f, 0x94, 0x2c, 0xbb, 0xf5, 0x84, 0x6a, 0x9,  0xb7, 0x28, 0xbe,
-    0x3f, 0x4,  0xb7, 0xb8, 0x9c, 0x41, 0xe6, 0x61, 0x5,  0x13, 0x6e, 0x36,
-    0xa1, 0x7e, 0x80, 0x95, 0x5f, 0x23, 0x73, 0xac, 0xe5, 0xd9, 0xb1, 0x82,
-    0xb2, 0xd9, 0x3d, 0xe8, 0x28, 0x27, 0xcb, 0xb7, 0xfc, 0xe,  0xb4, 0x3e,
-    0xc5, 0x14, 0x1d, 0x33, 0x63, 0xc3, 0x15, 0x79, 0x2e, 0xa8, 0xf4, 0xa5,
-    0xbd, 0xd8, 0x3a, 0x61, 0xdf, 0x59, 0xff, 0x8a, 0xd7, 0xe9, 0xe3, 0x51,
-    0xd2, 0xd2, 0x4e, 0x96, 0x2d, 0x7,  0xa,  0xe,  0xa5, 0x7b, 0x64, 0x68,
-    0xcc, 0xc6, 0x40, 0x3a, 0x81, 0x73, 0x67, 0xbc, 0x6b, 0xaa, 0x41, 0x82,
-    0xd5, 0xbd, 0xeb, 0xe9, 0xb8, 0x49, 0x8a, 0x1f, 0x9d, 0xbb, 0x36, 0x39,
-    0x7a, 0xa6, 0xc1, 0xed, 0x42, 0x83, 0xe6, 0x77, 0xa7, 0x6,  0xaa, 0x32,
-    0xdc, 0x2,  0x59, 0x11, 0x94, 0x3,  0xd5, 0xc3, 0x22, 0xb9, 0xf7, 0x8e,
-    0x27, 0x44, 0xec, 0xfb, 0x1a, 0x25, 0x99, 0x47, 0x0,  0x7c, 0xa3, 0xc6,
-    0x1d, 0x58, 0xbf, 0xcd, 0xa5, 0x13, 0x4d, 0xba, 0xc8, 0x2d, 0x7f, 0x97,
-    0x9d, 0xc2, 0x57, 0x20, 0xf1, 0x9a, 0xa7, 0x6e, 0xc8, 0x44, 0x89, 0x53,
-    0x94, 0xdd, 0x21, 0xd0, 0xd4, 0x54, 0x65, 0x20, 0x7f, 0x3d, 0x55, 0xfe,
-    0x13, 0x4d, 0xa0, 0xe2, 0x39, 0x74, 0x1c, 0x18, 0xc5, 0x58, 0x56, 0x15,
-    0x5e, 0x27, 0x6d, 0xca, 0x8a, 0x90, 0x24, 0x2,  0x7,  0xe9, 0xd1, 0x5d,
-    0x6c, 0xc8, 0xe4, 0x6a, 0x5e, 0x17, 0x49, 0x0,  0x8f, 0xea, 0xcb, 0x3b,
-    0x8b, 0x2f, 0x9e, 0xae, 0x8d, 0x8d, 0x65, 0x65, 0xb1, 0x28, 0xd1, 0x5c,
-    0x7c, 0xd,  0x1c, 0x52, 0xb8, 0xb7, 0x4e, 0x3b, 0x33, 0x5,  0x5f, 0x6e,
-    0x1d, 0x94, 0x3,  0xc6, 0x25, 0xd2, 0x53, 0x99, 0x35, 0xd9, 0xaf, 0xec,
-    0x42, 0x90, 0x14, 0x94, 0x66, 0x6a, 0x3a, 0xa7, 0xf3, 0xa6, 0x7e, 0x7f,
-    0x25, 0x57, 0xba, 0x94, 0xff, 0x50, 0x64, 0x4e, 0x63, 0x79, 0xc2, 0x76,
-    0xd5, 0x32, 0x13, 0x22, 0xe0, 0x62, 0x64, 0x24, 0xe4, 0x35, 0x54, 0x99,
-    0xa,  0xe8, 0x64, 0x75, 0xa0, 0x36, 0xbf, 0xa0, 0xc2, 0x82, 0xdf, 0xa3,
-    0xbf, 0xc1, 0x6f, 0xbb, 0xe7, 0x20, 0x6e, 0xb3, 0x49, 0xcc, 0xb9, 0xdc,
-    0xdb, 0xd2, 0x52, 0x2c, 0x1f, 0xbb, 0x6c, 0x21, 0xb,  0x8,  0xfa, 0x33,
-    0x22, 0xa6, 0xaa, 0xe0, 0x4,  0x20, 0x5f, 0xaa, 0x29, 0xdd, 0x8b, 0xf2,
-    0x15, 0x8a, 0x67, 0xdc, 0xc2, 0x95, 0xac, 0xbd, 0x3e, 0x72, 0x2a, 0x6c,
-    0x11, 0x5d, 0x6e, 0xfc, 0x77, 0x94, 0xa7, 0x81, 0x93, 0xb9, 0x49, 0x2b,
-    0x21, 0xb1, 0xd9, 0xa,  0xc5, 0x1f, 0xe8, 0x5c, 0xce, 0x11, 0xab, 0x65,
-    0xe2, 0x32, 0xa5, 0x5,  0xc2, 0x8b, 0x9d, 0x1c, 0xae, 0x7d, 0x1,  0x6c,
-    0x20, 0xed, 0xbe, 0xb8, 0x1e, 0xbd, 0xc7, 0xaa, 0x84, 0x87, 0xc4, 0xf1,
-    0x8,  0x32, 0xe5, 0x27, 0xb1, 0xa7, 0x15, 0x86, 0xf9, 0x32, 0xf,  0x16,
-    0x9c, 0x3f, 0xdd, 0xa4, 0xfb, 0x0,  0x65, 0xe8, 0xf5, 0x7e, 0xbc, 0x14,
-    0x78, 0x82, 0x1b, 0xdc, 0x13, 0xd6, 0x98, 0xe6, 0x69, 0x6d, 0x4a, 0xc2,
-    0xcd, 0x39, 0x7d, 0x71, 0xf1, 0xca, 0x26, 0x55, 0xcc, 0xe9, 0x99, 0xc5,
-    0x50, 0x9a, 0xb8, 0x25, 0x4b, 0x11, 0xb5, 0x7,  0xa7, 0x7f, 0x75, 0x21,
-    0x16, 0x24, 0xc5, 0xc,  0x69, 0xff, 0x59, 0x8d, 0xaa, 0xda, 0xc7, 0x57,
-    0x1a, 0x6e, 0xc4, 0xcc, 0xc,  0x54, 0xfc, 0x81, 0x32, 0x74, 0x86, 0xeb,
-    0xf9, 0xfa, 0x73, 0x60, 0x1e, 0xed, 0x93, 0x6,  0x99, 0xdb, 0xf,  0xbc,
-    0x2c, 0x99, 0x6,  0xe6, 0x1a, 0xf5, 0x6d, 0xc7, 0x18, 0xc2, 0x6c, 0xc7,
-    0x57, 0x48, 0x59, 0x9f, 0xed, 0x24, 0xb1, 0xb9, 0xb5, 0xe4, 0x8b, 0xc1,
-    0x3e, 0x50, 0x20, 0x7d, 0x60, 0xba, 0x2b, 0xaa, 0x2b, 0x64, 0xe7, 0xac,
-    0x6e, 0xce, 0x53, 0x84, 0xea, 0x79, 0x70, 0xe8, 0xfa, 0x14, 0xca, 0x4d,
-    0x38, 0x9,  0x85, 0x28, 0xc7, 0xd3, 0x6e, 0xd,  0xe9, 0xbf, 0xff, 0x0,
-    0xb9, 0x14, 0xff, 0x38, 0xb8, 0x92, 0x35, 0x63, 0xa1, 0xee, 0x4c, 0xb0,
-    0x64, 0x90, 0x1,  0x84, 0xd,  0x89, 0xaa, 0x5c, 0xf0, 0x8,  0x99, 0xb3,
-    0x8a, 0x72, 0x1,  0x62, 0x77, 0x73, 0x92, 0xbb, 0x5c, 0x71, 0x50, 0xa4,
-    0xdf, 0x1c, 0x2a, 0xdd, 0x79, 0x1a, 0x7b, 0xb6, 0x36, 0xff, 0x7d, 0x8c,
-    0xd0, 0x4f, 0x3f, 0x56, 0x5f, 0x95, 0x92, 0x58, 0xc,  0x3a, 0xe0, 0x10,
-    0x48, 0x77, 0xd,  0x2,  0xfc, 0xba, 0x82, 0xff, 0x45, 0xd6, 0x19, 0xb5,
-    0xaa, 0x1c, 0xab, 0xcd, 0x54, 0xf,  0x84, 0xe,  0xa3, 0xfb, 0xcd, 0xac,
-    0x3b, 0xa0, 0x38, 0x4c, 0xf9, 0xb1, 0xf6, 0xa2, 0x21, 0xb8, 0x57, 0x45,
-    0x3d, 0x4,  0x75, 0x5,  0xc8, 0x64, 0xd2, 0x6c, 0xfb, 0x28, 0xd1, 0x48,
-    0x35, 0xde, 0x4a, 0x91, 0xe1, 0x9,  0xea, 0x3c, 0xa6, 0xa9, 0x15, 0xc8,
-    0xa5, 0xf3, 0x3f, 0xa2, 0xae, 0x4a, 0xca, 0xe5, 0xb1, 0xfa, 0xeb, 0x9c,
-    0xc7, 0xd6, 0x1,  0xbd, 0xb7, 0x3c, 0x8a, 0x24, 0x4b, 0x3,  0xc2, 0x36,
-    0x38, 0x3a, 0x65, 0xd4, 0xbb, 0x7a, 0x87, 0xf8, 0x5f, 0x14, 0xdd, 0x94,
-    0x74, 0xd9, 0xf0, 0x43, 0x35, 0xbc, 0x68, 0x39, 0x2b, 0x28, 0xb8, 0x39,
-    0x40, 0x2,  0x51, 0x30, 0x8b, 0x90, 0xb5, 0xc2, 0xcb, 0x7d, 0x6,  0x2d,
-    0xeb, 0xed, 0xc6, 0x47, 0x76, 0xcb, 0x2,  0x47, 0x85, 0xe0, 0xff, 0x77,
-    0x6d, 0x1a, 0x24, 0xff, 0xbb, 0x5a, 0xf4, 0xdb, 0xa1, 0xea, 0x16, 0x11,
-    0x50, 0x13, 0xc5, 0xe4, 0x66, 0xcb, 0xc7, 0x90, 0x10, 0xe4, 0xa7, 0x74,
-    0x93, 0xde, 0x67, 0x16, 0x1e, 0x21, 0x28, 0x96, 0x93, 0x71, 0xdc, 0xb5,
-    0x6d, 0x3e, 0x5f, 0x1e, 0x9b, 0xd4, 0x78, 0x5d, 0xdb, 0xce, 0xfe, 0x60,
-    0x38, 0xed, 0xd7, 0xce, 0x12, 0x33, 0x1c, 0x34, 0x40, 0xeb, 0xfe, 0x69,
-    0x5d, 0x3d, 0xd3, 0xf3, 0xd1, 0x3d, 0xd4, 0x1f, 0x4a, 0xd9, 0xab, 0xc5,
-    0x94, 0x8b, 0x9a, 0x33, 0xe2, 0xf4, 0x92, 0xda, 0xe2, 0x8f, 0x75, 0x8f,
-    0xb3, 0x23, 0x24, 0x3e, 0xd7, 0x53, 0x78, 0x4d, 0xf0, 0xa6, 0x1d, 0xb1,
-    0x6a, 0xcc, 0x66, 0x21, 0x26, 0x43, 0x6d, 0xbe, 0x86, 0x12, 0x9,  0xed,
-    0xf2, 0xd6, 0xd3, 0x90, 0x19, 0x10, 0xe1, 0x44, 0x11, 0x90, 0x6a, 0x86,
-    0x30, 0x6d, 0x77, 0x0,  0x3,  0xae, 0x0,  0xdd, 0x51, 0x97, 0xa8, 0xc2,
-    0x77, 0x77, 0x0,  0xdd, 0x62, 0x84, 0x1,  0x7e, 0xc6, 0xd6, 0x4c, 0x49,
-    0x72, 0x8a, 0xdb, 0x4e, 0x7e, 0x1a, 0x4b, 0xfb, 0xd6, 0x40, 0xad, 0x64,
-    0x64, 0x99, 0x9,  0x56, 0xec, 0xad, 0x3d, 0x88, 0x9a, 0xb4, 0x6c, 0x17,
-    0x62, 0xf9, 0xd8, 0xb3, 0x2f, 0x8,  0x3e, 0xc,  0xc6, 0xc1, 0xee, 0x20,
-    0x9f, 0xe6, 0xeb, 0xc6, 0xe6, 0xcc, 0xb4, 0xe7, 0xe6, 0xca, 0xf1, 0x2c,
-    0x9,  0x73, 0xb2, 0xa,  0xd6, 0xf5, 0x40, 0x44, 0xfd, 0xa,  0x36, 0xb3,
-    0xe6, 0xf,  0x84, 0xf8, 0x8a, 0x22, 0xc,  0x15, 0x99, 0xf1, 0xe1, 0x3f,
-    0xe5, 0x73, 0x5f, 0x63, 0x1d, 0xdf, 0xb6, 0xf6, 0x2f, 0xa3, 0x7e, 0x2,
-    0x7,  0xba, 0xc1, 0x0,  0x72, 0x38, 0x41, 0xe3, 0x33, 0x3,  0x16, 0x2f,
-    0x2a, 0xd7, 0x54, 0x94, 0x78, 0xd2, 0x5e, 0xe4, 0x6e, 0x19, 0xa0, 0xe3,
-    0xa,  0xc1, 0x8b, 0xd4, 0x6f, 0x1f, 0xc2, 0x5f, 0xca, 0x23, 0x30, 0x7b,
-    0xd3, 0xe,  0x45, 0xf9, 0x2a, 0x1d, 0x6e, 0x8c, 0x8,  0xc8, 0x9c, 0x84,
-    0xd2, 0x71, 0xe8, 0xfc, 0x68, 0x1b, 0xf5, 0xca, 0xb3, 0x98, 0xe3, 0xeb,
-    0xb4, 0xb7, 0x88, 0x4f, 0xfb, 0x37, 0xdf, 0x4c, 0xf9, 0x3e, 0x71, 0x36,
-    0xfa, 0xd0, 0x98, 0x38, 0x8,  0x77, 0xa8, 0xdb, 0x75, 0x8d, 0x1f, 0x25,
-    0x92, 0x4c, 0xe,  0x47, 0x5c, 0x83, 0x91, 0x36, 0x57, 0x3a, 0x8e, 0xf,
-    0x70, 0xb1, 0x2b, 0x15, 0x46, 0x92, 0x35, 0x16, 0x78, 0xca, 0xf,  0x37,
-    0xa1, 0xce, 0x9c, 0x44, 0x29, 0xad, 0xdf, 0x28, 0x69, 0x27, 0x6d, 0x72,
-    0x71, 0x62, 0x48, 0xe5, 0xdc, 0xe8, 0x64, 0x11, 0x47, 0x9b, 0x2d, 0xc,
-    0xe4, 0x5,  0xd8, 0x72, 0x1f, 0xc6, 0x35, 0x14, 0x8e, 0x6a, 0x11, 0x90,
-    0xa9, 0x1f, 0xd3, 0x8d, 0x7c, 0x28, 0x10, 0x22, 0x88, 0x2e, 0x15, 0xcb,
-    0x3d, 0xf7, 0xef, 0x60, 0x4a, 0x83, 0xeb, 0x1a, 0x8,  0xd2, 0x43, 0xae,
-    0x5e, 0xbe, 0xd6, 0x8e, 0x69, 0x9,  0x2f, 0x7f, 0x7f, 0x2a, 0xcd, 0x55,
-    0x5d, 0x30, 0x8,  0x5,  0xe3, 0xd6, 0xc8, 0xb4, 0x7,  0x78, 0xc4, 0x69,
-    0x0,  0x70, 0x4f, 0x92, 0x1b, 0x9c, 0x9d, 0xaa, 0x1a, 0x6a, 0x13, 0x54,
-    0xa8, 0x3d, 0x66, 0xf4, 0xad, 0xc3, 0x8a, 0xb4, 0x48, 0x31, 0xc3, 0xe8,
-    0x23, 0x48, 0x1b, 0xee, 0x32, 0x66, 0x23, 0xca, 0xe6, 0x97, 0x3c, 0x63,
-    0xfc, 0xf,  0x4c, 0x45, 0xd1, 0xbf, 0x55, 0x78, 0xf2, 0x7b, 0x32, 0xd9,
-    0x7d, 0xe4, 0xdb, 0x8,  0x2c, 0xdd, 0xa7, 0xf0, 0xae, 0xfb, 0x74, 0x6,
-    0x5d, 0x62, 0xb1, 0x6f, 0xc6, 0x2b, 0x93, 0x82, 0xd7, 0x98, 0x4,  0x8f,
-    0x9a, 0x9e, 0xa2, 0x88, 0x8d, 0xa2, 0xe,  0xc1, 0x8b, 0xdc, 0x1b, 0xb4,
-    0xcc, 0xe6, 0x6f, 0xe,  0x23, 0x3f, 0xaf, 0x3b, 0x60, 0x4c, 0xaa, 0x1d,
-    0xb0, 0xe6, 0x14, 0x0,  0x1b, 0x68, 0x4f, 0xcc, 0xdb, 0x16, 0xdd, 0x96,
-    0x71, 0x6c, 0xbe, 0x1,  0x7b, 0x80, 0x2b, 0xb8, 0xc4, 0x85, 0xf9, 0x98,
-    0x25, 0x3d, 0xa7, 0x28, 0x71, 0xab, 0xbe, 0x80, 0x3e, 0x45, 0x42, 0x14,
-    0xa6, 0x5c, 0x84, 0x37, 0x49, 0x66, 0x2f, 0x2d, 0x4b, 0x3d, 0x22, 0x92,
-    0x6a, 0x1a, 0x9e, 0x1d, 0xe6, 0xc7, 0x58, 0x16, 0x70, 0xb2, 0xe,  0x89,
-    0xd1, 0xec, 0xc8, 0x47, 0xdf, 0x8b, 0xce, 0x5a, 0x31, 0x64, 0xa1, 0xa0,
-    0xf1, 0xed, 0x51, 0x89, 0x86, 0x72, 0xd0, 0xa,  0x9b, 0x65, 0xbb, 0x57,
-    0x35, 0x13, 0x21, 0x86, 0xbf, 0xb9, 0x49, 0x7c, 0x94, 0xfe, 0x40, 0xaf,
-    0x3b, 0x27, 0xc3, 0x74, 0x2e, 0xcd, 0xea, 0x30, 0x60, 0xb8, 0x5c, 0x7c,
-    0x21, 0x39, 0x30, 0xd9, 0x57, 0x5f, 0xd3, 0xc7, 0xd6, 0x6b, 0xb2, 0x88,
-    0x7d, 0xb6, 0xa0, 0xca, 0x18, 0xf3, 0x9c, 0xf,  0xb0, 0xb6, 0x98, 0x20,
-    0x33, 0xe9, 0xf5, 0x92, 0x7,  0xba, 0x1c, 0x6a, 0x59, 0x4c, 0xe6, 0xf0,
-    0x43, 0xdf, 0x49, 0x72, 0x1a, 0x8a, 0x8f, 0x9a, 0x6b, 0x28, 0xef, 0xeb,
-    0x5a, 0x96, 0x6d, 0xa5, 0x3a, 0xd4, 0xf9, 0x1e, 0x93, 0x8f, 0xef, 0xd2,
-    0x1f, 0xbc, 0x2a, 0xd6, 0x21, 0xd0, 0x4b, 0x49, 0x5d, 0x6d, 0x45, 0xd0,
-    0xc,  0xbf, 0xf7, 0x25, 0xe9, 0xca, 0x45, 0x8f, 0x22, 0xed, 0x48, 0x1a,
-    0xa0, 0xc5, 0x73, 0xb5, 0x44, 0x96, 0x0,  0x8,  0x9b, 0xfd, 0xc0, 0xd0,
-    0x7e, 0xd5, 0x1b, 0xb1, 0xe1, 0xf7, 0x19, 0x5c, 0x59, 0xbb, 0x86, 0xd5,
-    0xb1, 0x17, 0x16, 0xbf, 0x10, 0x5b, 0xdc, 0x6f, 0xa9, 0x8f, 0xf9, 0x4a,
-    0x11, 0xac, 0x2,  0xc1, 0x9e, 0x92, 0x23, 0xd8, 0xfb, 0x38, 0x95, 0xc9,
-    0x70, 0x1f, 0x57, 0x5f, 0x7,  0xb2, 0xa1, 0xe2, 0xe2, 0xd5, 0x24, 0xe5,
-    0xbb, 0x6a, 0x90, 0xf,  0xbe, 0x18, 0x90, 0xf3, 0x47, 0x95, 0xfa, 0xe8,
-    0x13, 0xe2, 0x2c, 0x4f, 0xc5, 0xb9, 0x64, 0xb,  0x67, 0x1f, 0xbc, 0x34,
-    0xb0, 0x66, 0xd2, 0xa3, 0x6,  0xfa, 0xae, 0x6,  0xff, 0x17, 0x96, 0xfe,
-    0xa,  0xec, 0xf2, 0xe2, 0x7c, 0x3c, 0xe1, 0x16, 0xcc, 0x3c, 0x69, 0xf7,
-    0x23, 0xaa, 0x51, 0x3f, 0x39, 0xb3, 0x94, 0xa0, 0x8c, 0x59, 0x21, 0xd3,
-    0xb0, 0xac, 0x35, 0xa2, 0xa,  0x50, 0x89, 0x33, 0x34, 0x83, 0x45, 0xa1,
-    0x9d, 0xf4, 0xec, 0xbe, 0x8d, 0x9,  0xda, 0xd7, 0x10, 0xee, 0xb3, 0x10,
-    0xea, 0x85, 0x16, 0xc8, 0x89, 0x8e, 0xdf, 0x8b, 0xf1, 0x7a, 0x7,  0xb4,
-    0xe7, 0xc9, 0x1f, 0x4c, 0x6a, 0x4a, 0xfe, 0x0,  0xd8, 0xd4, 0xd0, 0x1c,
-    0xc4, 0xa4, 0x3,  0x4c, 0xf,  0xc3, 0x95, 0x2d, 0xb5, 0x80, 0x4,  0x61,
-    0xdf, 0xac, 0x79, 0x10, 0xd3, 0xd8, 0x1d, 0xc5, 0x80, 0x10, 0xe6, 0x77,
-    0x37, 0xec, 0x80, 0x44, 0x30, 0x5a, 0xad, 0x21, 0xa,  0x4f, 0xe6, 0x77,
-    0x45, 0x6b, 0x5d, 0xc2, 0x10, 0x26, 0xaa, 0x9e, 0x5f, 0x4e, 0x31, 0x22,
-    0x27, 0xa7, 0xef, 0x44, 0x17, 0x3b, 0xad, 0xea, 0xc7, 0x55, 0x32, 0x2,
-    0x2a, 0x5b, 0xfc, 0xbd, 0x13, 0xe5, 0x7e, 0x96, 0x19, 0x89, 0xd3, 0xc9,
-    0x7c, 0x23, 0x7d, 0x4c, 0x4d, 0x90, 0xc1, 0x46, 0x32, 0x21, 0xdb, 0xbd,
-    0xdc, 0x65, 0x4,  0x4,  0x23, 0x8a, 0x24, 0xe4, 0xf0, 0x61, 0x8e, 0x9e,
-    0x57, 0x8e, 0x99, 0x2b, 0xe6, 0xda, 0x10, 0xd6, 0x6d, 0xae, 0xb4, 0x4b,
-    0xfa, 0x3a, 0x1e, 0x4,  0xb4, 0xd0, 0xd1, 0x8f, 0x97, 0x51, 0x82, 0x80,
-    0x67, 0x56, 0x3b, 0xed, 0x6d, 0x86, 0x47, 0x34, 0x3c, 0x40, 0xd2, 0x9d,
-    0xa9, 0x12, 0x77, 0x60, 0x94, 0x4f, 0x35, 0x85, 0x7e, 0x29, 0xb8, 0x50,
-    0x1,  0x9f, 0x32, 0x95, 0x99, 0x6a, 0x7b, 0xf8, 0xf0, 0xc2, 0x4d, 0x4,
-    0x7e, 0x8a, 0x88, 0x57, 0x67, 0x62, 0x98, 0x7c, 0x49, 0x7d, 0x3d, 0x49,
-    0x98, 0x9,  0xd9, 0xff, 0x85, 0xdb, 0xfd, 0xc5, 0xa2, 0xdc, 0xc0, 0xa7,
-    0xc0, 0xd7, 0x23, 0x19, 0x2b, 0x33, 0x1c, 0x2a, 0xb8, 0xe6, 0xef, 0xb9,
-    0x41, 0x12, 0xea, 0xc,  0x20, 0x52, 0x7b, 0xd2, 0xc6, 0xfb, 0xea, 0xc1,
-    0x30, 0x18, 0x67, 0xe9, 0x3e, 0x3e, 0x1,  0xb3, 0xf8, 0x72, 0xd2, 0x79,
-    0xc6, 0x27, 0x62, 0xfd, 0x2c, 0xe1, 0xeb, 0xf4, 0x4e, 0xa6, 0x68, 0x6c,
-    0x17, 0x3a, 0xbf, 0xfb, 0x4b, 0x6c, 0xe,  0x3a, 0x7a, 0xcc, 0x9a, 0xe4,
-    0x45, 0xd2, 0x35, 0x8,  0x7c, 0xcc, 0x43, 0x91, 0x31, 0x1d, 0x40, 0x7d,
-    0xd7, 0x62, 0xab, 0x5d, 0x30, 0xa2, 0x10, 0xea, 0x9c, 0xa9, 0xb2, 0x35,
-    0xa,  0xb9, 0x84, 0xd8, 0xf4, 0xd3, 0x82, 0x96, 0xb4, 0xbb, 0x3c, 0x65,
-    0xe8, 0xa4, 0x74, 0xc7, 0xa5, 0xde, 0x3b, 0xea, 0xf3, 0xf6, 0xf3, 0xf1,
-    0xd9, 0xb1, 0xd5, 0x29, 0x68, 0x51, 0x1d, 0x1e, 0x7a, 0xd4, 0xab, 0x44,
-    0x61, 0x49, 0xa5, 0x94, 0xd1, 0x7b, 0x77, 0x93, 0x24, 0x7d, 0x9f, 0xa1,
-    0x6d, 0xf0, 0x10, 0xfc, 0x96, 0xfc, 0xc7, 0xa3, 0x2d, 0x43, 0x9,  0x56,
-    0x23, 0x0,  0xaf, 0x4b, 0xb8, 0xe3, 0xc5, 0x3c, 0x1b, 0x7c, 0x6a, 0x25,
-    0x2e, 0xa2, 0xdc, 0x2d, 0x6e, 0xb3, 0xa6, 0x63, 0xed, 0xb2, 0xa6, 0x12,
-    0x33, 0x6e, 0xfa, 0x3a, 0x66, 0x83, 0xcd, 0x20, 0x39, 0xd7, 0xb7, 0xe,
-    0x2b, 0x26, 0x69, 0xd9, 0x29, 0x35, 0x72, 0xc9, 0xee, 0x57, 0xef, 0x6c,
-    0x6f, 0x7e, 0x57, 0xa9, 0x12, 0xd2, 0x8c, 0x6,  0xa8, 0x74, 0xe0, 0x2,
-    0x28, 0xdf, 0x54, 0x6b, 0x32, 0x9c, 0x53, 0x64, 0x23, 0xd6, 0x9e, 0xf9,
-    0x75, 0xe0, 0x56, 0x27, 0xf8, 0x56, 0xdb, 0x27, 0xd5, 0x39, 0x61, 0x4f,
-    0x82, 0x79, 0x35, 0xa4, 0x1,  0x35, 0x74, 0x74, 0x47, 0x29, 0x98, 0xa4,
-    0x19, 0x28, 0x95, 0x1e, 0xac, 0x0,  0x63, 0x40, 0xac, 0x2,  0x12, 0x86,
-    0x86, 0xf0, 0x6c, 0x7f, 0xd9, 0xe9, 0xe4, 0x57, 0x96, 0x37, 0x77, 0xb9,
-    0x4b, 0xda, 0x3c, 0x82, 0x86, 0x53, 0xf2, 0x89, 0x6b, 0x71, 0x5b, 0xef,
-    0x46, 0xa9, 0x84, 0x99, 0xf7, 0x30, 0x5f, 0xbb, 0xf4, 0x90, 0x50, 0xbe,
-    0xb7, 0x45, 0xec, 0x19, 0x62, 0xab, 0x8b, 0xdf, 0xa7, 0x54, 0x11, 0xc0,
-    0xf7, 0x78, 0xe3, 0x80, 0x4b, 0xa2, 0x8c, 0x26, 0x49, 0x6d, 0x96, 0xb,
-    0xca, 0x2a, 0xd1, 0xe2, 0x88, 0xd3, 0x9,  0xef, 0xef, 0x89, 0xca, 0xe,
-    0xb8, 0x5d, 0x2f, 0xea, 0xc6, 0x26, 0x24, 0xc2, 0x96, 0xaf, 0xf9, 0x6e,
-    0xd4, 0x1c, 0xae, 0x24, 0x68, 0x3b, 0xad, 0x24, 0x59, 0x80, 0xc3, 0x15,
-    0x25, 0xb0, 0xd8, 0x65, 0x5b, 0x17, 0x93, 0xe7, 0x15, 0xc9, 0x39, 0xbf,
-    0x81, 0xfd, 0xa8, 0x16, 0xf0, 0x1f, 0x43, 0xf0, 0xb,  0x1d, 0x63, 0xa8,
-    0x50, 0x8e, 0x2e, 0xe9, 0x42, 0xec, 0x53, 0xa0, 0x5a, 0xa5, 0x2e, 0x93,
-    0x19, 0xbf, 0x9a, 0xf7, 0x9c, 0x9,  0x44, 0x56, 0xf5, 0x68, 0xd6, 0x90,
-    0xb3, 0xc3, 0x77, 0x9d, 0x7c, 0x85, 0x53, 0xcf, 0xb8, 0x53, 0x48, 0x88,
-    0xa,  0xfa, 0x9c, 0xdb, 0x5a, 0xbe, 0xcd, 0xce, 0x81, 0xab, 0xb,  0x18,
-    0x3d, 0xf4, 0xc9, 0xfb, 0xac, 0xf9, 0x68, 0xf6, 0x2b, 0xd9, 0x4a, 0xe,
-    0x2d, 0x20, 0x3e, 0xd8, 0x29, 0x1a, 0xa,  0xe6, 0x9f, 0xf,  0xf,  0x13,
-    0x48, 0x8c, 0xdd, 0x66, 0x2b, 0x4e, 0x70, 0x9b, 0x54, 0x8a, 0x9f, 0x83,
-    0x71, 0x86, 0xc,  0xae, 0x6d, 0xd5, 0x2c, 0x13, 0xf1, 0x16, 0x9d, 0xe9,
-    0xcc, 0xa2, 0xfc, 0x6c, 0xc3, 0xbf, 0x94, 0xfd, 0xd5, 0xac, 0xd8, 0x46,
-    0x2f, 0xf5, 0xc6, 0x53, 0xe5, 0xdf, 0x90, 0x23, 0x20, 0x1d, 0xa5, 0x86,
-    0x11, 0x63, 0xea, 0xe1, 0xc5, 0xf8, 0x31, 0x80, 0x27, 0xba, 0x71, 0x54,
-    0x78, 0x12, 0xc1, 0xa9, 0x42, 0x6f, 0xba, 0xe8, 0x11, 0x34, 0x6e, 0xc7,
-    0xca, 0x4c, 0x56, 0x23, 0x19, 0x8a, 0xa9, 0x43, 0x23, 0xab, 0xcb, 0x37,
-    0xb5, 0xaf, 0xe4, 0xcd, 0x23, 0xcb, 0xf7, 0xcf, 0x64, 0x8a, 0x68, 0x87,
-    0x84, 0x4f, 0x55, 0xde, 0x22, 0x3b, 0xca, 0x7c, 0x4c, 0x3,  0xf4, 0xd3,
-    0x67, 0x3c, 0xf3, 0xd1, 0xeb, 0xf0, 0x90, 0xb1, 0xa7, 0xd9, 0x39, 0x19,
-    0xd9, 0x40, 0xea, 0x55, 0x13, 0x56, 0xc7, 0x12, 0x9e, 0x34, 0x17, 0xcf,
-    0xbf, 0xc7, 0x17, 0xb5, 0xe7, 0xfd, 0xdc, 0xd8, 0x51, 0x85, 0x75, 0x37,
-    0xc4, 0xdc, 0xf3, 0x51, 0x2d, 0x62, 0xfc, 0x2a, 0x76, 0x84, 0x36, 0xc3,
-    0x3a, 0xf3, 0xeb, 0x7f, 0x6f, 0x9f, 0xe0, 0xe8, 0x92, 0x37, 0xf7, 0x53,
-    0xb2, 0x7d, 0x1d, 0xef, 0xe4, 0x8f, 0x72, 0xe9, 0xea, 0x8b, 0x2d, 0xf5,
-    0x7,  0x12, 0xbf, 0xee, 0x89, 0xc3, 0xc0, 0x59, 0x7a, 0x91, 0xdd, 0x76,
-    0x21, 0xb5, 0xeb, 0xda, 0x9a, 0xb4, 0x87, 0x29, 0xbd, 0x14, 0xa3, 0x3f,
-    0xd0, 0x9b, 0xb,  0x12, 0xf6, 0x65, 0x1a, 0x43, 0x44, 0xed, 0x88, 0xb9,
-    0xba, 0xef, 0xe1, 0xc5, 0x10, 0x7d, 0xe4, 0x55, 0x72, 0x90, 0xc4, 0xa5,
-    0x7f, 0x2a, 0xee, 0x62, 0x7e, 0xfe, 0x21, 0x27, 0xac, 0x7c, 0x41, 0x75,
-    0x2b, 0x46, 0xef, 0x3c, 0x37, 0x86, 0xbb, 0xeb, 0x4c, 0xf1, 0x21, 0x62,
-    0xdd, 0x44, 0xca, 0xce, 0xf7, 0xbb, 0xf8, 0x3d, 0x44, 0x84, 0x47, 0x0,
-    0x44, 0xf4, 0x26, 0xd7, 0x8a, 0x24, 0x14, 0x99, 0xaa, 0x93, 0x86, 0x48,
-    0x86, 0x2,  0x39, 0x55, 0x26, 0x76, 0xbf, 0xdc, 0x99, 0x3,  0x3b, 0x93,
-    0x7d, 0x50, 0x8d, 0x75, 0x3f, 0xd7, 0xfd, 0x25, 0xcf, 0x64, 0xaf, 0xcb,
-    0x66, 0x24, 0xed, 0x13, 0xbc, 0x1d, 0xe3, 0x9e, 0x21, 0xd7, 0xcb, 0xc9,
-    0x1f, 0x3b, 0xc0, 0x2e, 0xad, 0xcf, 0x96, 0x2,  0x26, 0x92, 0x61, 0xce,
-    0xa9, 0xea, 0xd8, 0xec, 0x15, 0x9c, 0x65, 0x12, 0x26, 0x9c, 0xf5, 0x79,
-    0x3e, 0x3c, 0xa5, 0x80, 0x4f, 0xf2, 0xb4, 0x95, 0x75, 0xf4, 0x57, 0x20,
-    0xf0, 0xf5, 0x89, 0x58, 0x19, 0x92, 0x25, 0x86, 0x41, 0x82, 0x8c, 0x31,
-    0x23, 0x71, 0xf4, 0xbf, 0x13, 0xd6, 0xcb, 0xc7, 0xff, 0x2f, 0x96, 0x7a,
-    0x7c, 0xec, 0xcd, 0xa6, 0xba, 0x21, 0x14, 0xf,  0x4,  0x6f, 0xa7, 0x10,
-    0xc4, 0x8f, 0xb4, 0xb9, 0xa9, 0x5c, 0x59, 0x94, 0xa0, 0xf1, 0xf9, 0x60,
-    0xc3, 0xf0, 0xe4, 0xf5, 0x2f, 0xe4, 0x98, 0xf0, 0xe0, 0x88, 0x88, 0xa1,
-    0xd5, 0xdf, 0x9b, 0xb4, 0x33, 0xa0, 0x29, 0xa3, 0xbb, 0xd5, 0x1c, 0x71,
-    0x5d, 0xec, 0x60, 0x9f, 0x40, 0x20, 0x64, 0xf,  0x26, 0x18, 0x17, 0xdc,
-    0x1f, 0x68, 0x8d, 0x1c, 0x57, 0xf0, 0x14, 0xbc, 0xb1, 0xec, 0x60, 0x5a,
-    0x9a, 0xe8, 0x49, 0xfb, 0x64, 0x41, 0xbf, 0x14, 0x69, 0x40, 0x5c, 0xb8,
-    0x8c, 0x96, 0x21, 0x5c, 0x4d, 0xae, 0x75, 0x22, 0x9c, 0x94, 0x1f, 0xf8,
-    0xb,  0xab, 0xc0, 0x67, 0xd4, 0x58, 0x56, 0xfa, 0xb5, 0x23, 0xef, 0x1c,
-    0x4d, 0x91, 0xde, 0x6a, 0x27, 0x69, 0x17, 0x54, 0x94, 0xbe, 0x32, 0x3f,
-    0x8d, 0x13, 0x66, 0x45, 0x9c, 0xf0, 0x7,  0x16, 0x9,  0xf0, 0xe,  0x9a,
-    0x6e, 0x8c, 0x28, 0x8a, 0xc9, 0x2b, 0x2b, 0x89, 0x30, 0x9f, 0xde, 0xf7,
-    0xbd, 0x55, 0x4f, 0x1d, 0xf4, 0xeb, 0x80, 0xf3, 0x41, 0x5d, 0xe0, 0x1a,
-    0x54, 0xb6, 0x44, 0x46, 0x71, 0xc8, 0xe2, 0xfa, 0x98, 0x20, 0xcd, 0x35,
-    0x46, 0xb4, 0xd0, 0x5d, 0x94, 0xed, 0xd8, 0x9c, 0xda, 0x2a, 0x5c, 0xec,
-    0x7,  0xb2, 0x22, 0xa3, 0xce, 0xa6, 0x43, 0x4d, 0x49, 0xf8, 0x78, 0x68,
-    0xa7, 0x3,  0xed, 0xfb, 0x52, 0x9f, 0x92, 0x16, 0x84, 0x72, 0xd7, 0x94,
-    0x53, 0x1a, 0x91, 0xb7, 0x1d, 0xbf, 0x91, 0x7c, 0x2d, 0x65, 0x28, 0x5f,
-    0xff, 0xb0, 0xfb, 0xe4, 0xa3, 0xf5, 0x35, 0x74, 0x11, 0x59, 0x64, 0x45,
-    0x44, 0xeb, 0x7a, 0xf7, 0xca, 0x2d, 0x73, 0x9d, 0x4,  0x25, 0xb5, 0xad,
-    0xde, 0xd4, 0x17, 0xc5, 0x55, 0x66, 0x19, 0xb1, 0x61, 0x47, 0x45, 0x6c,
-    0x99, 0x8,  0xe9, 0x83, 0x8e, 0x84, 0x5f, 0xf6, 0xca, 0x5,  0x42, 0x8,
-    0x7d, 0x69, 0x8f, 0x69, 0x89, 0x6e, 0x84, 0x44, 0x44, 0x52, 0x98, 0xc3,
-    0x90, 0xa9, 0xfa, 0xf,  0xd0, 0x2,  0xe2, 0x6f, 0xbb, 0x23, 0xe2, 0x5b,
-    0x34, 0xb1, 0xfc, 0x48, 0xaf, 0xbe, 0x96, 0x1a, 0xe,  0x5c, 0x5e, 0xa,
-    0xaf, 0x1a, 0xc4, 0x5f, 0x13, 0x65, 0x3f, 0x7c, 0xd6, 0x27, 0x9e, 0xfc,
-    0x53, 0x37, 0x59, 0x40, 0x48, 0x9,  0x24, 0xfa, 0x59, 0x45, 0xf,  0xc0,
-    0xae, 0xa1, 0x71, 0x9,  0xb,  0x77, 0x41, 0xe0, 0xdd, 0xaa, 0xfe, 0xc4,
-    0x31, 0x2b, 0x90, 0xfa, 0x28, 0x5c, 0x88, 0x67, 0xd7, 0xcf, 0x40, 0x31,
-    0x8c, 0x85, 0x6,  0xd,  0x8,  0x3e, 0x5e, 0x3c, 0x87, 0xf,  0x3f, 0x7b,
-    0x22, 0x3d, 0x47, 0x3e, 0xdf, 0x9b, 0x72, 0x8c, 0x77, 0x29, 0xd5, 0xfe,
-    0x5d, 0x16, 0x91, 0x87, 0x6d, 0x45, 0x92, 0x7d, 0xea, 0x13, 0x7c, 0xc9,
-    0x94, 0xc3, 0xb,  0xf7, 0x49, 0xf3, 0x22, 0xd5, 0x5b, 0x60, 0xda, 0xc3,
-    0x53, 0x6e, 0x70, 0x8d, 0x87, 0x79, 0x6e, 0x90, 0xd3, 0x6a, 0x7c, 0xae,
-    0xc8, 0x28, 0xb,  0x9c, 0x6,  0xf6, 0xdb, 0x1e, 0x4b, 0x18, 0x34, 0x69,
-    0x1c, 0x3c, 0x1a, 0xf4, 0xf8, 0x9c, 0xc8, 0x7f, 0xf9, 0x40, 0xf2, 0xb1,
-    0x3f, 0xa,  0x56, 0xc7, 0xc5, 0x3c, 0x31, 0xdb, 0x8f, 0x1b, 0xc3, 0x5,
-    0x0,  0xd4, 0x8c, 0x34, 0x73, 0xc,  0xa7, 0x3e, 0xd1, 0xca, 0x8b, 0x6e,
-    0x42, 0x71, 0xfc, 0x62, 0x90, 0x4c, 0x33, 0xca, 0xdd, 0x4d, 0xc9, 0xe0,
-    0x38, 0xb4, 0xa8, 0x50, 0xd4, 0x18, 0x7d, 0xd4, 0x59, 0x4d, 0x2,  0xdb,
-    0xbd, 0x92, 0x60, 0xf1, 0x7e, 0x61, 0x36, 0xf5, 0x2a, 0x55, 0x8f, 0x32,
-    0x3d, 0x21, 0xa7, 0xa,  0x23, 0x35, 0xe7, 0xb4, 0x35, 0x83, 0x6a, 0x35,
-    0xbd, 0xe7, 0xfc, 0x55, 0x1a, 0x53, 0xc1, 0x63, 0xe4, 0x89, 0xa8, 0xce,
-    0xc8, 0x23, 0x55, 0x17, 0xea, 0xa8, 0xe9, 0xf2, 0xe9, 0x4e, 0x6f, 0xf8,
-    0x78, 0xa7, 0xdf, 0xe0, 0x75, 0xf4, 0x2e, 0x3,  0xb5, 0x57, 0x99, 0xb3,
-    0x93, 0x1f, 0xf0, 0x7,  0x43, 0xc6, 0x3a, 0xf2, 0x5d, 0xae, 0xd7, 0xe6,
-    0x1b, 0x4c, 0x8a, 0x5,  0x35, 0x12, 0x74, 0x25, 0x76, 0x8d, 0x83, 0xba,
-    0xbe, 0x25, 0x4f, 0x10, 0x5e, 0xd2, 0xc8, 0xc5, 0xa8, 0xdc, 0x31, 0x2c,
-    0xe9, 0x18, 0x40, 0x3d, 0x4a, 0x4a, 0x5f, 0xd7, 0xf0, 0xfa, 0xd9, 0xa0,
-    0x6e, 0x0,  0x14, 0xf7, 0xa9, 0xe6, 0x6e, 0x43, 0xb3, 0x80, 0x95, 0x1f,
-    0x2d, 0x72, 0x77, 0x3f, 0x2f, 0xbc, 0xc4, 0xea, 0x5f, 0xaa, 0xa1, 0x1f,
-    0x55, 0x94, 0x94, 0xe8, 0x9f, 0x21, 0x28, 0xbd, 0xd,  0x4a, 0x39, 0x4c,
-    0xac, 0x27, 0xd,  0xf3, 0x4c, 0x34, 0xc7, 0xc,  0xf8, 0x4f, 0x70, 0x7,
-    0xa7, 0x49, 0x63, 0x1,  0xc7, 0xe9, 0xb9, 0xc6, 0xe6, 0x4a, 0x26, 0xec,
-    0xfd, 0x73, 0xb3, 0x45, 0xe9, 0x69, 0xf4, 0x2c, 0x1e, 0xc5, 0xd7, 0xa,
-    0x1d, 0x95, 0xd6, 0x9b, 0x4c, 0xb0, 0xa,  0x80, 0x45, 0x98, 0x70, 0x80,
-    0xa7, 0x15, 0xc7, 0x8,  0x76, 0xa9, 0x87, 0x99, 0xcb, 0xeb, 0x44, 0xb2,
-    0x36, 0xdd, 0x75, 0x60, 0x13, 0x75, 0x33, 0xe1, 0xb8, 0x3b, 0xde, 0xac,
-    0xcc, 0xc,  0x15, 0x2c, 0x4a, 0xb5, 0x7b, 0x65, 0x49, 0x1f, 0x1,  0x4c,
-    0x56, 0xcb, 0x5d, 0x8f, 0x99, 0xcc, 0xc4, 0x21, 0xe7, 0x6c, 0x84, 0x89,
-    0xac, 0x9c, 0x50, 0x77, 0x32, 0xf9, 0xc8, 0xf2, 0x61, 0x87, 0x3f, 0xc7,
-    0x69, 0xff, 0xb7, 0xbd,
-};
-const uint8_t kAltGameImages2xE[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x29, 0xa3, 0xa8, 0xaa,
-    0x9c, 0x8a, 0xfe, 0x4,  0xe6, 0xc8, 0x54, 0xf6, 0x2b, 0xa1, 0x37, 0xe8,
-    0xa2, 0x67, 0x30, 0xc1, 0x9a, 0x9b, 0x60, 0x1,  0x9e, 0x5f, 0xc3, 0xba,
-    0xdb, 0xdc, 0x7,  0xf7, 0x41, 0x11, 0xf3, 0xe3, 0x98, 0x14, 0xfe, 0x57,
-    0xa4, 0x20, 0x8e, 0xf5, 0x2,  0x52, 0xd0, 0xac, 0x81, 0xb2, 0x93, 0x5a,
-    0x67, 0xee, 0x2e, 0x8d, 0x87, 0xf5, 0x49, 0x93, 0x75, 0x76, 0x34, 0x1a,
-    0x3a, 0x76, 0xdd, 0x5f, 0x8f, 0xdf, 0x5,  0x5e, 0xea, 0xa8, 0xb9, 0xae,
-    0xf9, 0xd,  0x87, 0xa0, 0x66, 0x68, 0x6,  0xfe, 0xad, 0xc7, 0xe2, 0x12,
-    0x88, 0xd1, 0x3f, 0x6d, 0xd7, 0x6d, 0xb0, 0x7,  0x71, 0xe2, 0x75, 0x88,
-    0x8b, 0xb6, 0xb5, 0xcd, 0x7d, 0x67, 0xe3, 0x80, 0x4f, 0xcc, 0x63, 0xd3,
-    0x8f, 0x1a, 0x4,  0xd6, 0xe5, 0xf3, 0x56, 0xa,  0x21, 0x18, 0x56, 0x7b,
-    0x1,  0x15, 0x46, 0x19, 0xb8, 0xd4, 0xe8, 0xad, 0xb9, 0x49, 0x13, 0x3e,
-    0x8f, 0x27, 0xfd, 0x38, 0xe4, 0x85, 0x58, 0xae, 0x30, 0x2a, 0x8,  0x69,
-    0xa4, 0x22, 0xef, 0xcc, 0x3b, 0x26, 0x9f, 0x57, 0xc4, 0x9b, 0x7e, 0x3b,
-    0xf3, 0x72, 0xb3, 0x2a, 0x27, 0x18, 0xd9, 0xc4, 0xf3, 0x1e, 0x9a, 0xda,
-    0x71, 0x29, 0x1d, 0xf3, 0xaf, 0x85, 0xc,  0x5e, 0x53, 0x90, 0xc0, 0x33,
-    0x44, 0x88, 0x51, 0x59, 0xd8, 0x95, 0xbc, 0x31, 0xed, 0xed, 0x35, 0x7,
-    0xf4, 0xb2, 0x8a, 0xe6, 0x84, 0x19, 0xab, 0xed, 0xab, 0xae, 0xce, 0x9,
-    0x30, 0xee, 0xa9, 0x3d, 0xf0, 0xf8, 0x67, 0xfa, 0xaf, 0xeb, 0x7e, 0xb0,
-    0x79, 0xe3, 0xfc, 0x2,  0xc3, 0x74, 0xf6, 0x69, 0xbd, 0x3c, 0xef, 0xf0,
-    0x3c, 0x85, 0xc2, 0xf4, 0x7c, 0xe3, 0xef, 0x2f, 0x54, 0x8e, 0x1f, 0x95,
-    0xbb, 0x40, 0x5d, 0x2f, 0x0,  0x5,  0xc3, 0x39, 0x8b, 0xbe, 0x51, 0x77,
-    0xbe, 0xe8, 0x5b, 0x6e, 0x16, 0x27, 0x94, 0xda, 0xba, 0x3e, 0x2f, 0xb1,
-    0x61, 0x77, 0x2d, 0xfe, 0x2a, 0x5a, 0x70, 0xd2, 0xab, 0xdb, 0x46, 0x7a,
-    0xb6, 0x42, 0x86, 0xbf, 0x97, 0x9f, 0xa,  0xa3, 0xc1, 0x82, 0x2c, 0x58,
-    0x21, 0xba, 0xad, 0x61, 0xab, 0x4d, 0x31, 0xe1, 0xd8, 0x81, 0x59, 0xfb,
-    0x29, 0xe9, 0xaf, 0xef, 0x79, 0xfa, 0x9,  0x4a, 0x32, 0x3,  0xa9, 0xc,
-    0x7d, 0xb5, 0x8b, 0x28, 0xbf, 0xfb, 0xae, 0xd7, 0x55, 0x5f, 0x10, 0x7d,
-    0xc6, 0xe8, 0x87, 0x2d, 0x6e, 0xdb, 0x84, 0xa7, 0xbb, 0x2d, 0xb4, 0x8b,
-    0x49, 0xf1, 0x3c, 0x7a, 0xdd, 0x7e, 0xcc, 0x4b, 0x1d, 0x5d, 0x1f, 0x3e,
-    0x3c, 0xf3, 0xcd, 0x4f, 0xde, 0x17, 0xe2, 0xcc, 0x1d, 0x9b, 0x6e, 0x34,
-    0xf3, 0xca, 0x4b, 0xda, 0x0,  0xb7, 0xc4, 0x82, 0x5e, 0x97, 0xbb, 0x59,
-    0x7d, 0xe8, 0x76, 0x5c, 0x5b, 0x7d, 0x79, 0x41, 0x29, 0x32, 0xe1, 0xa7,
-    0xce, 0x82, 0x51, 0xbe, 0x7,  0x81, 0x8,  0x79, 0xc1, 0x94, 0x65, 0xf9,
-    0xfb, 0x6e, 0xa2, 0x52, 0xe5, 0xc,  0xa6, 0x9e, 0xe4, 0xcd, 0xa8, 0x76,
-    0xb3, 0xb1, 0x97, 0xc6, 0x37, 0xb0, 0x59, 0xe2, 0x93, 0x9b, 0xc5, 0x9d,
-    0x4b, 0xc7, 0xcf, 0x6b, 0xd2, 0x3d, 0x74, 0xda, 0x7e, 0xd1, 0x92, 0xf3,
-    0xd2, 0xb7, 0x86, 0x53, 0x25, 0x2a, 0xdf, 0x6d, 0xe2, 0x6,  0x25, 0x38,
-    0x36, 0xb2, 0x39, 0xe1, 0x2e, 0xa,  0xe9, 0x18, 0xfe, 0x37, 0xfe, 0x3f,
-    0xcd, 0x1a, 0xcf, 0x9,  0xb6, 0xfd, 0x90, 0xc0, 0x8a, 0x28, 0xde, 0xa9,
-    0x94, 0xa,  0x77, 0xf3, 0x22, 0xf8, 0xbc, 0xa6, 0xba, 0x1a, 0xb7, 0x3b,
-    0x1f, 0x80, 0x4c, 0x1f, 0xa6, 0x59, 0xb9, 0x64, 0x73, 0xfa, 0x4c, 0xe8,
-    0x1a, 0xd5, 0x9,  0xa5, 0x2e, 0x24, 0xb0, 0x68, 0xf0, 0x68, 0x12, 0xef,
-    0x72, 0x2b, 0x1,  0x15, 0xfc, 0xd9, 0x70, 0x41, 0x1,  0xa6, 0x94, 0x89,
-    0x3f, 0x76, 0x25, 0x79, 0xf8, 0x5d, 0x24, 0xe,  0x83, 0xdb, 0x8a, 0xfb,
-    0x93, 0xeb, 0x61, 0x63, 0xc0, 0x4e, 0xf8, 0x7e, 0x55, 0xf0, 0xfe, 0x2c,
-    0xf7, 0x18, 0xd7, 0x83, 0x29, 0x3,  0x68, 0xf5, 0xd9, 0xd0, 0x20, 0x52,
-    0x63, 0x5,  0xbd, 0x74, 0x15, 0xe6, 0xab, 0xf2, 0x49, 0x34, 0xe7, 0x20,
-    0xb1, 0x12, 0xbd, 0x87, 0x14, 0x82, 0xbc, 0xef, 0x79, 0x1c, 0x4e, 0xdd,
-    0x62, 0x0,  0xba, 0x87, 0x4e, 0x64, 0xe5, 0x9b, 0x97, 0xf4, 0x2b, 0xc,
-    0x22, 0x65, 0x35, 0x35, 0xa6, 0xb0, 0x80, 0x75, 0x14, 0x35, 0x2e, 0x9a,
-    0xdb, 0x75, 0x92, 0x2,  0xec, 0x33, 0x53, 0x43, 0x57, 0x44, 0x19, 0x7e,
-    0x5e, 0x2c, 0x3e, 0x49, 0xa9, 0xa8, 0xb1, 0x26, 0x5f, 0xa3, 0x21, 0x96,
-    0xee, 0x66, 0x2d, 0x27, 0x8d, 0x36, 0xaf, 0xe3, 0x80, 0x15, 0xce, 0x8c,
-    0xff, 0xa8, 0xd4, 0x7a, 0x7f, 0x28, 0x99, 0x8,  0xe9, 0x13, 0x3,  0x2e,
-    0x83, 0x26, 0xa4, 0x36, 0x3d, 0x1f, 0xcf, 0x2,  0x5c, 0x7b, 0x0,  0x3c,
-    0xb,  0x18, 0xa2, 0xe4, 0x1b, 0x13, 0xbf, 0x67, 0x61, 0x7d, 0x27, 0x6c,
-    0xbf, 0xa,  0xfd, 0xcf, 0x74, 0xa8, 0x74, 0x3a, 0xdd, 0xe3, 0x81, 0xb9,
-    0x2f, 0xda, 0x95, 0xd,  0xfa, 0xf7, 0x7c, 0xd7, 0xf6, 0xc6, 0xca, 0x7a,
-    0x2d, 0xf2, 0xe1, 0xd9, 0xf5, 0xcd, 0xff, 0x75, 0x79, 0x32, 0xe7, 0xb1,
-    0x6e, 0xf4, 0xa9, 0xe4, 0xbd, 0xdc, 0xf2, 0xcd, 0xa4, 0xaf, 0xa5, 0xa7,
-    0xf2, 0x27, 0xc1, 0x1d, 0x70, 0x0,  0xa7, 0xa6, 0xf3, 0x6b, 0x2c, 0xef,
-    0x84, 0x59, 0xba, 0xfc, 0x4e, 0x92, 0xe,  0x29, 0x5e, 0xfa, 0x96, 0x5f,
-    0xde, 0x1b, 0x34, 0x1a, 0x58, 0x2f, 0xfd, 0x62, 0x22, 0xb9, 0xdd, 0x38,
-    0xf0, 0x70, 0x9,  0x30, 0x47, 0x5b, 0x3a, 0x38, 0x49, 0x77, 0x44, 0xc,
-    0x22, 0x5c, 0xb0, 0x5f, 0x17, 0x52, 0x50, 0xd8, 0x51, 0x7e, 0x96, 0xcc,
-    0x3d, 0xea, 0x7f, 0x25, 0x6d, 0xdb, 0x39, 0x97, 0x71, 0xc3, 0xea, 0xbd,
-    0x71, 0x92, 0x2f, 0x4d, 0xe9, 0x5d, 0xac, 0x26, 0x41, 0x71, 0x42, 0xfa,
-    0xe3, 0x8c, 0x22, 0xfa, 0x85, 0xc5, 0x21, 0xca, 0x85, 0x70, 0xc9, 0x69,
-    0xbf, 0x48, 0x95, 0x6,  0x7a, 0x33, 0x77, 0xf3, 0x76, 0x7a, 0x9b, 0x4e,
-    0xf3, 0xd2, 0xd1, 0x8f, 0xbd, 0x3c, 0xe2, 0xa8, 0xe7, 0x7b, 0xde, 0xa,
-    0xaf, 0x3e, 0x6e, 0x21, 0x96, 0xe,  0x52, 0x93, 0x75, 0x97, 0x6b, 0x6,
-    0xbf, 0x9e, 0x50, 0x51, 0xa,  0xdc, 0x96, 0x15, 0x62, 0x1,  0x94, 0x2d,
-    0x44, 0x2a, 0xc0, 0xc0, 0xf,  0x8c, 0xd6, 0x63, 0x74, 0x73, 0x99, 0xe5,
-    0x49, 0xad, 0xf5, 0xb4, 0x41, 0x97, 0x6,  0xbc, 0x81, 0x6c, 0x40, 0xd7,
-    0x45, 0x6f, 0x72, 0xa5, 0x51, 0xf8, 0xc0, 0xa1, 0x4e, 0xce, 0x75, 0x93,
-    0x85, 0x5f, 0xe8, 0x8b, 0x5e, 0x6b, 0x48, 0xc1, 0xf8, 0x55, 0xea, 0xc6,
-    0xc5, 0x7,  0x83, 0x33, 0xcc, 0x1f, 0x55, 0xe1, 0xc9, 0xe4, 0x6d, 0x31,
-    0x3c, 0x41, 0x5c, 0xa8, 0xec, 0x82, 0xfa, 0x30, 0x87, 0xfa, 0x16, 0x90,
-    0x16, 0x29, 0xb5, 0x4b, 0x7e, 0xb9, 0xc5, 0x32, 0xc8, 0xb2, 0xa6, 0x59,
-    0xfa, 0x80, 0x26, 0x1,  0xfb, 0x3c, 0xe4, 0x3b, 0xb5, 0x2,  0x7b, 0xd,
-    0xf7, 0x5a, 0xaa, 0x8,  0x51, 0xa0, 0x54, 0x7d, 0x1,  0x28, 0x31, 0x14,
-    0x3b, 0x24, 0x1f, 0x25, 0x9e, 0xd5, 0x51, 0x2a, 0x1f, 0xad, 0xd7, 0x34,
-    0x46, 0x95, 0x74, 0x48, 0xa4, 0x1e, 0x62, 0xd1, 0x29, 0x84, 0xfc, 0x7b,
-    0x75, 0x36, 0xfe, 0xa1, 0x41, 0xda, 0x6c, 0xe9, 0x59, 0xf8, 0xd0, 0x68,
-    0x7a, 0x4b, 0x93, 0x26, 0xb9, 0x28, 0xf5, 0xdd, 0x7a, 0xd7, 0xb6, 0x69,
-    0xae, 0xd0, 0x4c, 0xc3, 0x98, 0xca, 0x12, 0xc,  0x55, 0x59, 0x96, 0x59,
-    0xde, 0xad, 0xac, 0xbd, 0xe3, 0xb,  0x48, 0x3c, 0x13, 0x80, 0xbf, 0x49,
-    0x59, 0xfa, 0x38, 0x82, 0x9b, 0x9,  0x33, 0xbc, 0x9c, 0x17, 0x93, 0x93,
-    0xad, 0x8e, 0x58, 0x3f, 0x5,  0x40, 0x75, 0x3f, 0xf7, 0xcd, 0x54, 0x8d,
-    0x52, 0x8d, 0xf6, 0xeb, 0xbc, 0x31, 0x4a, 0xce, 0xb2, 0x3f, 0xc8, 0x8e,
-    0x52, 0x7a, 0xa4, 0x46, 0xea, 0x1e, 0x9a, 0xa,  0x69, 0x20, 0x98, 0x98,
-    0x45, 0xb0, 0xed, 0xa2, 0x6b, 0x65, 0xec, 0x6d, 0x53, 0xba, 0xaf, 0xb1,
-    0xe7, 0xf7, 0x41, 0xbf, 0x35, 0x97, 0xc1, 0xb7, 0xa2, 0xe4, 0x8e, 0x93,
-    0xea, 0x1b, 0xb1, 0xb5, 0xe3, 0x65, 0xab, 0xd1, 0x28, 0xd8, 0x50, 0x86,
-    0x33, 0x86, 0x60, 0x26, 0xf4, 0x56, 0x48, 0xe5, 0x54, 0x6a, 0x17, 0x44,
-    0x46, 0x76, 0x55, 0x4f, 0x43, 0xaf, 0x28, 0x99, 0x7b, 0x96, 0x6e, 0x7c,
-    0xcb, 0xb9, 0xcc, 0x1c, 0xf,  0x84, 0x4a, 0x80, 0x53, 0x4c, 0x42, 0xcd,
-    0xf0, 0x23, 0x2d, 0x3f, 0x8d, 0x2,  0x79, 0xc0, 0x7d, 0xce, 0x7d, 0xe5,
-    0xfb, 0xe4, 0x7b, 0x65, 0x65, 0x6,  0x30, 0x44, 0x4e, 0x36, 0x85, 0x44,
-    0x5a, 0x32, 0x47, 0x23, 0xe5, 0x98, 0x80, 0xb2, 0xb8, 0x5a, 0x1c, 0x84,
-    0x86, 0x2,  0x71, 0x6d, 0xbe, 0x99, 0x88, 0xd,  0x26, 0x2e, 0x95, 0x1d,
-    0xde, 0xb8, 0x2d, 0x40, 0xd5, 0xec, 0x7a, 0xb1, 0x8b, 0x6b, 0x67, 0xf4,
-    0x2a, 0x93, 0xb4, 0xcb, 0xef, 0xab, 0x24, 0x13, 0x2b, 0xa1, 0x34, 0x18,
-    0xa0, 0x28, 0xfe, 0xb3, 0x5,  0x3,  0x92, 0x49, 0x9,  0xa,  0xf2, 0x63,
-    0xde, 0xd1, 0xf9, 0xfb, 0x50, 0xc1, 0x4,  0x26, 0xc8, 0x8b, 0xf2, 0x20,
-    0x8,  0xb4, 0xbb, 0x45, 0x15, 0x3a, 0x27, 0xb4, 0xd3, 0x27, 0x85, 0xbc,
-    0x8,  0x8f, 0xf1, 0xa2, 0x42, 0x16, 0x19, 0xb6, 0xc6, 0x11, 0x6f, 0x39,
-    0x6c, 0x69, 0x53, 0xc,  0x31, 0x9e, 0x57, 0x4,  0x71, 0xf5, 0xf7, 0xff,
-    0x11, 0xc4, 0x65, 0xde, 0x22, 0x11, 0x37, 0x3,  0x4c, 0x56, 0x4d, 0xf8,
-    0x40, 0x34, 0x32, 0x69, 0x2,  0x54, 0xaf, 0x96, 0x10, 0x18, 0xd9, 0x35,
-    0xf,  0x53, 0x53, 0x69, 0x9c, 0x36, 0x95, 0x62, 0x57, 0xf9, 0xed, 0xf0,
-    0x41, 0x97, 0x72, 0xdb, 0x1c, 0xb6, 0xda, 0xab, 0x7a, 0x24, 0xac, 0x89,
-    0x97, 0x15, 0x37, 0x6e, 0xfe, 0xef, 0x3c, 0xfc, 0x16, 0x91, 0x4b, 0xf0,
-    0x57, 0x4a, 0xbc, 0x48, 0xe,  0x8,  0xe,  0x81, 0xe8, 0x8e, 0x98, 0x29,
-    0x6,  0x58, 0xfc, 0xc1, 0x80, 0x1c, 0x63, 0x3c, 0x6a, 0xa7, 0xe4, 0x78,
-    0x13, 0x53, 0xb6, 0x4b, 0xb2, 0x67, 0xc9, 0xfd, 0x3b, 0x6e, 0xaf, 0xd0,
-    0xd5, 0x2b, 0x38, 0xf9, 0xc0, 0x0,  0x4,  0xc4, 0x25, 0xf9, 0xd2, 0x2a,
-    0x83, 0xec, 0x1d, 0x49, 0x27, 0xda, 0xf8, 0xd1, 0x9e, 0x8e, 0x37, 0x73,
-    0x6e, 0xb6, 0x25, 0x65, 0x39, 0xf9, 0xef, 0x74, 0xb6, 0xd3, 0x16, 0x94,
-    0x9c, 0x6e, 0xac, 0xc6, 0x8b, 0x13, 0xc,  0xcf, 0x28, 0x94, 0xe9, 0xed,
-    0x2e, 0xe4, 0x75, 0xc4, 0xe7, 0x1e, 0xc9, 0xd3, 0xad, 0xa9, 0x35, 0x7f,
-    0x23, 0x8a, 0x88, 0x6,  0x3b, 0x89, 0xcc, 0x6,  0xc0, 0xc1, 0x79, 0x5e,
-    0x70, 0x6c, 0xc2, 0x9b, 0x76, 0x22, 0x99, 0x5c, 0xbe, 0xcf, 0x16, 0x2a,
-    0x47, 0x98, 0xfb, 0xe6, 0x83, 0x83, 0x8c, 0xab, 0x27, 0xc6, 0xb2, 0x5e,
-    0x76, 0x2,  0x85, 0xf,  0x91, 0x19, 0x38, 0x57, 0xbc, 0x6f, 0xd9, 0x5,
-    0xac, 0xf3, 0x7e, 0xfc, 0x68, 0x3,  0xb3, 0x4f, 0x96, 0xab, 0x84, 0x71,
-    0x58, 0xce, 0xd9, 0x61, 0xfe, 0xd6, 0x1c, 0xd1, 0xcc, 0xb2, 0x7e, 0xc8,
-    0x3a, 0x41, 0x9d, 0x5b, 0x64, 0xc2, 0xf2, 0xd8, 0xa1, 0x9e, 0xfa, 0xec,
-    0xea, 0xf9, 0x1c, 0x35, 0x71, 0xe5, 0x42, 0xec, 0x8e, 0x46, 0x17, 0x9b,
-    0x8e, 0xdc, 0x7e, 0x81, 0x1,  0x1b, 0xab, 0x2e, 0x9d, 0xea, 0xe0, 0x28,
-    0xe7, 0x70, 0xdd, 0x8d, 0xf7, 0x19, 0x4f, 0xb,  0x60, 0x2e, 0xca, 0x7d,
-    0x7a, 0x11, 0x2d, 0x1e, 0xa2, 0xe,  0x9f, 0x15, 0x8b, 0x8a, 0x58, 0x9d,
-    0xd0, 0x0,  0xe,  0xc9, 0x6b, 0xde, 0x94, 0x88, 0xcf, 0x1d, 0x71, 0x44,
-    0x9c, 0x1,  0x74, 0x69, 0x71, 0x14, 0xf9, 0x62, 0x7,  0x9e, 0xa2, 0x87,
-    0xa6, 0x4f, 0xa6, 0x5,  0xe,  0xfd, 0x1e, 0xf5, 0xa6, 0xe4, 0x30, 0x9b,
-    0x39, 0x91, 0xe0, 0x3c, 0xbd, 0x72, 0x30, 0x84, 0x85, 0xb5, 0x67, 0xad,
-    0xf,  0x87, 0x88, 0xf8, 0x83, 0x1,  0x3c, 0x14, 0x7f, 0x72, 0xee, 0x58,
-    0x62, 0xa1, 0xf0, 0x46, 0x65, 0x7e, 0x74, 0xbf, 0xc6, 0xee, 0x74, 0x85,
-    0x46, 0xe,  0x82, 0x8c, 0x48, 0x40, 0x66, 0x99, 0x6d, 0x97, 0x7d, 0x35,
-    0x5b, 0x2a, 0x48, 0x77, 0xd2, 0xd2, 0x32, 0x35, 0x7e, 0xa1, 0x4c, 0xa8,
-    0x64, 0x8d, 0x30, 0xa4, 0xe3, 0xe0, 0x9a, 0x4,  0x73, 0x9a, 0xef, 0x46,
-    0x82, 0x38, 0x7b, 0x58, 0x6e, 0xaf, 0xe5, 0x38, 0x13, 0xa1, 0xe0, 0x65,
-    0x6a, 0xda, 0x88, 0x47, 0xde, 0xf3, 0xc4, 0x4c, 0xca, 0xdb, 0xf9, 0x6e,
-    0x4e, 0xe8, 0xd9, 0x8,  0x8a, 0x84, 0x90, 0x8f, 0x7b, 0xc0, 0x9e, 0x86,
-    0x29, 0x38, 0xbc, 0xf0, 0x13, 0xb4, 0xee, 0xc8, 0xb2, 0xc6, 0xb4, 0xdf,
-    0x22, 0x68, 0x27, 0x9d, 0x6,  0x76, 0x65, 0xfd, 0xe0, 0xbf, 0xe9, 0x0,
-    0xe9, 0x17, 0x29, 0x7f, 0xf1, 0x8c, 0xf1, 0xc,  0x21, 0xe3, 0xa2, 0x8d,
-    0xc8, 0xf1, 0x36, 0x62, 0x60, 0x98, 0xd9, 0x24, 0xc2, 0xba, 0x2c, 0x83,
-    0x99, 0x1,  0xcc, 0x73, 0xd,  0x52, 0x14, 0x98, 0xd6, 0xf3, 0x6c, 0x48,
-    0x44, 0x83, 0xe6, 0x5c, 0xfa, 0x41, 0x1d, 0xb8, 0x1c, 0xf6, 0xf6, 0x89,
-    0xab, 0xbd, 0x7c, 0x45, 0x87, 0xed, 0xc6, 0x2b, 0x94, 0x22, 0x8b, 0xfd,
-    0xa4, 0x7a, 0x64, 0xf7, 0xab, 0x29, 0xb7, 0x2,  0xb7, 0xc4, 0xba, 0xa2,
-    0x15, 0x15, 0x26, 0x19, 0x82, 0x89, 0x52, 0x73, 0x32, 0xb4, 0xd6, 0xae,
-    0x3b, 0x42, 0xb,  0xbe, 0x4c, 0xff, 0x3c, 0xe4, 0xa3, 0x98, 0x77, 0x32,
-    0x3e, 0x3b, 0x7f, 0x98, 0x40, 0x7e, 0x5f, 0xa2, 0x24, 0x39, 0xfd, 0x25,
-    0x93, 0x51, 0xe3, 0x1b, 0x47, 0xe2, 0xce, 0xc7, 0x3d, 0x8d, 0x4a, 0x96,
-    0xd7, 0x13, 0xf0, 0x39, 0x28, 0xc7, 0xbd, 0xfd, 0x68, 0xee, 0x31, 0x4d,
-    0x9e, 0xaa, 0xc2, 0x7,  0x7a, 0x6d, 0xfc, 0x66, 0x80, 0x7a, 0xca, 0xe5,
-    0xff, 0x78, 0x28, 0xca, 0xe5, 0xa,  0x1,  0x52, 0x2,  0xf4, 0x3d, 0x37,
-    0x3c, 0x3f, 0x72, 0xa5, 0x7f, 0x2a, 0xa2, 0x4d, 0x63, 0x65, 0x60, 0xe9,
-    0x51, 0x18, 0xdb, 0x59, 0x3d, 0xb2, 0xe3, 0xb0, 0x3f, 0xf0, 0x97, 0x9b,
-    0xc4, 0x51, 0x7f, 0x88, 0xfb, 0x85, 0x61, 0xea, 0xaa, 0xb3, 0x6e, 0xd6,
-    0x8f, 0x1b, 0x1e, 0xb7, 0x8d, 0x25, 0xed, 0x7c, 0x59, 0xd4, 0xd5, 0x14,
-    0x95, 0xc,  0x2f, 0x8e, 0xa5, 0x48, 0xfa, 0x14, 0xf1, 0x7b, 0x2a, 0x21,
-    0xd5, 0xc4, 0x75, 0x2,  0xe4, 0x49, 0xd,  0x9b, 0x2e, 0x83, 0x13, 0x22,
-    0xe6, 0xdf, 0xf2, 0xfc, 0xf8, 0xa7, 0x5a, 0xd2, 0xe1, 0x7a, 0x27, 0xe9,
-    0x8b, 0x3,  0xa1, 0xde, 0xe1, 0x27, 0xd8, 0xfc, 0x2c, 0x6a, 0x67, 0x85,
-    0xdc, 0x1d, 0x1f, 0x59, 0x10, 0x99, 0xce, 0x2e, 0x48, 0x86, 0xf6, 0x9c,
-    0xf6, 0x79, 0x79, 0x7c, 0xdf, 0x8e, 0xa3, 0x14, 0x9a, 0xa3, 0xe5, 0xf3,
-    0x74, 0x62, 0x62, 0x37, 0x83, 0x89, 0xf2, 0xd7, 0xda, 0xdd, 0x5,  0x11,
-    0xaf, 0xc1, 0xe4, 0x2a, 0xaa, 0xa7, 0xc0, 0xa6, 0x2a, 0xc5, 0x17, 0xa7,
-    0xea, 0x23, 0x56, 0xea, 0x3d, 0x52, 0x32, 0x31, 0x16, 0xb1, 0x4d, 0xa8,
-    0x0,  0x44, 0x59, 0x7a, 0xf7, 0x6b, 0x5,  0x4d, 0x5c, 0xf8, 0xe,  0xa,
-    0x48, 0x63, 0xe5, 0x94, 0xef, 0x74, 0x8e, 0x47, 0x3e, 0xd9, 0xb1, 0x2d,
-    0x15, 0xaf, 0x52, 0x6e, 0x63, 0xe6, 0x88, 0x5d, 0xcd, 0xc0, 0x8a, 0xd2,
-    0xa,  0x96, 0x24, 0x1,  0xe5, 0xe6, 0xad, 0xf1, 0xee, 0xe6, 0xbb, 0xa1,
-    0x5f, 0x50, 0x63, 0x1d, 0xa,  0xec, 0xda, 0xb1, 0xff, 0x7a, 0x4d, 0x83,
-    0x24, 0xcd, 0xde, 0x38, 0x31, 0x7f, 0xe5, 0x93, 0x2d, 0x3e, 0x3c, 0xa8,
-    0x55, 0x81, 0x7b, 0xa2, 0x5f, 0xfb, 0xa7, 0xa7, 0x1b, 0x27, 0xd9, 0x22,
-    0x19, 0xce, 0x66, 0xc6, 0x59, 0x60, 0xeb, 0xdc, 0x45, 0x6,  0xe2, 0xf3,
-    0xfd, 0x43, 0x3d, 0x5e, 0x72, 0xd,  0x62, 0x70, 0xfd, 0x61, 0x43, 0xe4,
-    0x2f, 0xc5, 0x58, 0x70, 0x18, 0xa2, 0xee, 0xb9, 0xaa, 0x20, 0x3c, 0x4d,
-    0x7f, 0xf5, 0xc3, 0x29, 0x4d, 0x43, 0x20, 0xb1, 0x50, 0x84, 0x38, 0x56,
-    0xb4, 0x94, 0xa2, 0x5,  0xa3, 0x84, 0xae, 0x41, 0x17, 0x53, 0x51, 0xe1,
-    0x2f, 0x4a, 0xa6, 0xa7, 0x8b, 0x5,  0x4b, 0x2f, 0x50, 0xfd, 0xaa, 0xa0,
-    0xe1, 0x59, 0xe6, 0x1b, 0x94, 0x46, 0x17, 0x29, 0x4f, 0xdc, 0x4e, 0x46,
-    0xff, 0xd1, 0xa9, 0x6a, 0x3f, 0xa7, 0x33, 0x13, 0x85, 0x8,  0xd1, 0x40,
-    0xdc, 0x95, 0xe0, 0x53, 0xdc, 0x6c, 0xf4, 0xee, 0xd4, 0x90, 0x76, 0x64,
-    0xc,  0x43, 0x54, 0x44, 0x2d, 0x73, 0xed, 0x63, 0x99, 0xe3, 0x2,  0xad,
-    0x4e, 0x10, 0xc,  0x8f, 0x31, 0x6b, 0x53, 0xeb, 0xc7, 0x6f, 0xfd, 0x3a,
-    0xfe, 0xb2, 0x78, 0x35, 0xc,  0x2b, 0x34, 0xeb, 0x9a, 0x9d, 0xf9, 0x93,
-    0x18, 0xcf, 0xeb, 0x43, 0xb5, 0xaa, 0x89, 0xdd, 0xec, 0x80, 0xd4, 0xbc,
-    0x4a, 0x45, 0xea, 0x56, 0x2,  0xb2, 0xb5, 0xe9, 0xb3, 0x8a, 0x5e, 0x30,
-    0xf7, 0x76, 0xeb, 0xf0, 0x25, 0x4c, 0x5d, 0xe9, 0x76, 0x9,  0x5f, 0x7f,
-    0x54, 0xe5, 0xd0, 0xa0, 0xf,  0xb4, 0xcc, 0x27, 0x1,  0xa4, 0x95, 0x15,
-    0x4,  0xc0, 0xc8, 0x0,  0x16, 0xb6, 0x78, 0xe7, 0x79, 0xd1, 0x1a, 0x5e,
-    0xfc, 0xaa, 0x2a, 0xc4, 0xb3, 0xc3, 0x62, 0x39, 0xde, 0x4c, 0xb7, 0x4b,
-    0x4f, 0x5c, 0xe1, 0x58, 0x7f, 0x4c, 0x7e, 0x81, 0x9a, 0xbc, 0x57, 0xbd,
-    0x1d, 0xae, 0xc7, 0x5a, 0x6f, 0xf8, 0xa7, 0x8c, 0x64, 0xee, 0xb6, 0x88,
-    0x7d, 0xaf, 0x96, 0xfb, 0xf2, 0x60, 0xae, 0xdc,
-};
-const uint8_t kAltGameImages2xF[] = {
-    0xc2, 0xff, 0x83, 0xa7, 0x7c, 0xe3, 0x9f, 0xd0, 0x89, 0xac, 0xe8, 0x95,
-    0x5a, 0xc4, 0xf7, 0xb0, 0x8,  0x8d, 0xb,  0xc,  0x42, 0xf3, 0x6b, 0xb6,
-    0x72, 0xa4, 0xba, 0x25, 0x21, 0x64, 0x7b, 0xac, 0x29, 0xa3, 0xa8, 0xaa,
-    0x9c, 0x8a, 0xfe, 0x4,  0xe6, 0xc8, 0x54, 0xf6, 0x2b, 0xa1, 0x37, 0xe8,
-    0xc1, 0x94, 0xe1, 0xdb, 0x36, 0x75, 0xce, 0xc5, 0x42, 0xa6, 0x31, 0xb,
-    0x5a, 0x1d, 0xfe, 0x74, 0x44, 0xeb, 0x75, 0xc4, 0xd,  0x40, 0x68, 0xe6,
-    0x1,  0x76, 0xfa, 0x61, 0x5e, 0x9d, 0x1d, 0x1b, 0x84, 0xb6, 0xa4, 0x9,
-    0x5,  0xe0, 0x92, 0x93, 0x79, 0xed, 0xa1, 0x37, 0x42, 0xdd, 0xeb, 0xbc,
-    0x80, 0xaa, 0x2e, 0xe6, 0xa8, 0x5c, 0xa3, 0x9a, 0xaf, 0x14, 0x61, 0xaa,
-    0xf4, 0x79, 0x1c, 0x2c, 0xd7, 0x1b, 0xcb, 0x22, 0x11, 0x3d, 0xd9, 0x41,
-    0x9d, 0xb8, 0x56, 0xf3, 0x62, 0xd0, 0x6e, 0xef, 0xbb, 0xcd, 0x9d, 0xdf,
-    0x9e, 0xaa, 0x38, 0xd3, 0x93, 0xaa, 0x92, 0xb2, 0x95, 0x7,  0x98, 0x8f,
-    0xb6, 0x3f, 0x9a, 0xc7, 0x2b, 0x95, 0x4,  0x94, 0xbe, 0xe4, 0x9b, 0x1d,
-    0x4e, 0x62, 0x2b, 0xb9, 0x39, 0x17, 0x6,  0xdb, 0x57, 0x86, 0xdd, 0x22,
-    0x27, 0xa5, 0x82, 0x16, 0x7a, 0xd6, 0xc7, 0xa5, 0x56, 0x46, 0x44, 0xc8,
-    0x68, 0xd8, 0x30, 0xe7, 0xbd, 0xea, 0xb5, 0x74, 0x3,  0x9d, 0x57, 0x1c,
-    0x8e, 0xe2, 0x17, 0x4d, 0xa3, 0x2b, 0xb7, 0xab, 0x21, 0xe0, 0x33, 0xe,
-    0x20, 0x2c, 0xb1, 0x2f, 0x1,  0x8e, 0xaf, 0x36, 0x4,  0x77, 0x42, 0x4,
-    0xb0, 0x39, 0xc0, 0x11, 0x59, 0xd1, 0xba, 0x8d, 0xf0, 0xfd, 0x37, 0xcf,
-    0xec, 0xe9, 0xb9, 0x87, 0xe,  0xda, 0xd4, 0xbf, 0xe1, 0x9e, 0xe9, 0xd1,
-    0x29, 0xb0, 0xcf, 0xb0, 0xdf, 0xbe, 0x14, 0x7,  0xe5, 0xe0, 0x20, 0xe5,
-    0x6f, 0x39, 0x6d, 0x53, 0x35, 0xa8, 0x4d, 0x4a, 0x30, 0x54, 0xfb, 0x96,
-    0x80, 0x4d, 0x44, 0xb6, 0x87, 0x66, 0x72, 0xcd, 0x63, 0x61, 0xf1, 0x2d,
-    0xb1, 0x9c, 0x7,  0x51, 0x48, 0xc1, 0x53, 0x40, 0x0,  0x4f, 0x42, 0x4b,
-    0xbc, 0x3c, 0x7e, 0x3d, 0xc2, 0xaf, 0xe4, 0x36, 0x95, 0x3a, 0x7c, 0xf6,
-    0x14, 0xa0, 0xd4, 0x3d, 0x89, 0xb7, 0xa0, 0x4d, 0x57, 0x41, 0x9e, 0xa4,
-    0x33, 0x6f, 0x28, 0x5a, 0x76, 0x17, 0x0,  0xd2, 0xe0, 0x88, 0xc,  0x43,
-    0x42, 0xc8, 0xb4, 0xdc, 0x24, 0xc3, 0xd7, 0x8,  0x48, 0xe1, 0x76, 0xb8,
-    0x6c, 0xbd, 0x7c, 0x72, 0xb2, 0x9d, 0xf,  0x7,  0x62, 0x3a, 0xf4, 0xd7,
-    0x7b, 0xee, 0x8e, 0xba, 0x1,  0x45, 0x15, 0xfa, 0x55, 0xbd, 0x25, 0xba,
-    0x7a, 0xfe, 0x83, 0x22, 0x9c, 0xca, 0x7b, 0x46, 0xb8, 0xcf, 0xfa, 0x16,
-    0x1c, 0x74, 0x57, 0x75, 0x43, 0x26, 0x10, 0xad, 0x57, 0xff, 0xd4, 0xa7,
-    0xe9, 0xfa, 0xeb, 0x84, 0x9f, 0xdc, 0x34, 0x63, 0x5e, 0x5,  0x8d, 0xc2,
-    0xa6, 0x2e, 0x13, 0x8d, 0x33, 0xcc, 0x25, 0x2f, 0x4,  0xfb, 0x95, 0xcd,
-    0x8d, 0x29, 0xd5, 0x9e, 0xaa, 0x14, 0x7b, 0xa3, 0xda, 0x1b, 0xa3, 0xc4,
-    0x24, 0x75, 0xf1, 0x95, 0xbd, 0xb8, 0x1f, 0x8c, 0xe9, 0xb0, 0x78, 0xee,
-    0x6b, 0x3a, 0x9a, 0x70, 0x1,  0x8,  0xf,  0x5f, 0xde, 0xdf, 0xd5, 0x2c,
-    0x22, 0xbf, 0xc2, 0xbf, 0xcf, 0x7b, 0x7f, 0x58, 0x5c, 0x1e, 0xdf, 0xcd,
-    0xe7, 0x4a, 0x52, 0xf7, 0x3d, 0xba, 0x2f, 0x3f, 0x55, 0x45, 0x7b, 0x9b,
-    0xfc, 0xd0, 0xd4, 0xd3, 0xe0, 0x92, 0xa5, 0x9c, 0x1f, 0xd1, 0xef, 0xbb,
-    0x93, 0xd3, 0x6b, 0x48, 0x59, 0xf1, 0xba, 0xf3, 0xf1, 0x4a, 0x29, 0x83,
-    0xa8, 0x65, 0x8f, 0x46, 0x60, 0xb0, 0x8c, 0x10, 0xaa, 0xd1, 0xf5, 0xa0,
-    0x1,  0xd5, 0x38, 0xeb, 0x14, 0x88, 0x60, 0x95, 0x17, 0xdc, 0x1f, 0xb9,
-    0x55, 0xff, 0x9a, 0x5d, 0x46, 0x67, 0xa2, 0xa0, 0x7b, 0xd9, 0x7b, 0xdb,
-    0x8f, 0xac, 0x43, 0x94, 0xa8, 0xdf, 0xc2, 0xc2, 0xa1, 0xec, 0xf0, 0x8c,
-    0x6e, 0x35, 0x3f, 0xd3, 0x39, 0xcf, 0xee, 0x80, 0x23, 0xa,  0x73, 0x74,
-    0x78, 0x1f, 0x19, 0x5d, 0xb,  0x88, 0xae, 0x3c, 0x67, 0x60, 0x85, 0xdd,
-    0x2,  0x46, 0x51, 0x5c, 0x55, 0xba, 0x15, 0x24, 0xd2, 0x98, 0x70, 0x14,
-    0x19, 0xa,  0x31, 0x3f, 0x38, 0x80, 0x85, 0x48, 0xde, 0xc2, 0xd,  0x67,
-    0xc1, 0x46, 0xd3, 0x93, 0x49, 0x22, 0xa0, 0x4,  0xfe, 0xe6, 0xaa, 0x6f,
-    0xa0, 0x2f, 0x7c, 0x22, 0x5,  0x49, 0xdf, 0xee, 0x2,  0x4d, 0x35, 0x4c,
-    0xd1, 0x5d, 0x6d, 0xe3, 0xe2, 0x5a, 0xc4, 0x5e, 0x43, 0x1e, 0x47, 0x41,
-    0xf9, 0xb7, 0x0,  0x53, 0x3a, 0xc3, 0x5e, 0xa5, 0x81, 0x36, 0x22, 0xe9,
-    0x25, 0x38, 0xfe, 0x3a, 0x7d, 0xf2, 0xee, 0x33, 0x30, 0x72, 0x6e, 0x81,
-    0xa1, 0x7,  0x1b, 0xc4, 0x83, 0x68, 0xde, 0x8e, 0x90, 0xde, 0x43, 0x73,
-    0xda, 0xb2, 0x75, 0x7a, 0xfd, 0x0,  0x21, 0xd2, 0x15, 0x58, 0x45, 0x65,
-    0x10, 0x26, 0x7a, 0x68, 0xfe, 0x9b, 0x31, 0xb5, 0xaa, 0xad, 0x9a, 0x92,
-    0x2e, 0x77, 0x68, 0xc5, 0x90, 0x4,  0xd6, 0x18, 0x6d, 0xf6, 0x99, 0x33,
-    0x99, 0xcd, 0x2,  0xc7, 0x20, 0x4b, 0x1f, 0x18, 0xc0, 0x6d, 0x4f, 0xe3,
-    0x41, 0x79, 0xcd, 0x7f, 0x11, 0xe,  0xdd, 0xee, 0x9a, 0x3f, 0x9,  0xa0,
-    0xc,  0x1f, 0xe1, 0x83, 0x3d, 0xd6, 0x8f, 0xb,  0xb6, 0x12, 0x47, 0x9f,
-    0x7e, 0x4b, 0xaa, 0x23, 0x13, 0xed, 0xee, 0xbb, 0x3d, 0x72, 0xab, 0xfe,
-    0xd2, 0xed, 0x7b, 0xc7, 0xf9, 0xeb, 0xb3, 0x3f, 0x72, 0xd0, 0x15, 0xb8,
-    0x98, 0xb8, 0x60, 0xd9, 0x5f, 0x3,  0x4d, 0x9,  0xfe, 0x28, 0x68, 0xdb,
-    0x2,  0x4d, 0xd7, 0xc5, 0xbd, 0x7a, 0xf6, 0x16, 0x1a, 0xd0, 0xc5, 0x32,
-    0x42, 0x17, 0x7f, 0x3b, 0x67, 0x1a, 0xa5, 0x44, 0x2a, 0xb3, 0x17, 0x81,
-    0x94, 0x75, 0x38, 0x30, 0xa7, 0x31, 0xa2, 0xfa, 0x92, 0x25, 0xcb, 0x1a,
-    0x39, 0x58, 0xdc, 0x3f, 0x5c, 0xb5, 0xa0, 0xbd, 0xdf, 0xa6, 0xe8, 0x8e,
-    0x9f, 0x2e, 0x2d, 0xa2, 0x3e, 0x3e, 0x37, 0xcc, 0x8d, 0x4e, 0x82, 0x44,
-    0xc,  0xac, 0x80, 0xf7, 0xd6, 0x19, 0x71, 0xf6, 0xcb, 0x28, 0x40, 0x68,
-    0x98, 0xee, 0xec, 0x2b, 0x9e, 0x4,  0xcd, 0xa1, 0xbf, 0x4c, 0xa5, 0x1b,
-    0x47, 0xea, 0x43, 0xf5, 0xb0, 0xc4, 0x64, 0xba, 0x54, 0x89, 0x1b, 0x67,
-    0xd9, 0x12, 0x6f, 0x6d, 0x3,  0x42, 0xb4, 0xe4, 0x2d, 0x1f, 0x45, 0x50,
-    0x87, 0x5d, 0x6a, 0xd6, 0xf9, 0xf8, 0xc1, 0xa6, 0xc5, 0x99, 0x8b, 0xc3,
-    0x2d, 0xac, 0x29, 0xee, 0x31, 0x75, 0xcf, 0xd1, 0xb0, 0x4e, 0x67, 0xa2,
-    0x56, 0x42, 0xc5, 0x3b, 0x42, 0x9b, 0x2b, 0xa7, 0xe3, 0x4e, 0x92, 0xa4,
-    0xd3, 0xf8, 0xf9, 0x6c, 0x64, 0x64, 0x9e, 0xd7, 0x74, 0x67, 0xbb, 0xa3,
-    0x4e, 0x24, 0xf,  0x90, 0xbf, 0x92, 0x24, 0xa0, 0xb0, 0x4c, 0x7b, 0xb7,
-    0x9f, 0x8e, 0x76, 0x5e, 0x45, 0x51, 0xe2, 0xdc, 0x69, 0xb0, 0x4d, 0x9e,
-    0xd6, 0xb0, 0x45, 0x48, 0x64, 0x17, 0x1e, 0xad, 0xbb, 0x24, 0xf8, 0x12,
-    0xf5, 0x94, 0x3c, 0xdc, 0xf9, 0xf8, 0x7f, 0x51, 0x3b, 0x80, 0xad, 0x6f,
-    0x1b, 0xe3, 0x98, 0x60, 0x6e, 0xf5, 0xd1, 0x4a, 0x6a, 0xf8, 0x66, 0x26,
-    0xf8, 0xa,  0xb6, 0x3f, 0xd9, 0x91, 0x7c, 0x79, 0xb1, 0x2b, 0xa8, 0x2c,
-    0x77, 0x7d, 0xa2, 0x2e, 0x85, 0x80, 0x9c, 0xcc, 0xb9, 0x67, 0xc7, 0x56,
-    0xaf, 0xcc, 0x49, 0xee, 0x3c, 0x47, 0xf1, 0x6d, 0xb,  0xe4, 0x2c, 0xd3,
-    0xbc, 0xfc, 0x6,  0xa7, 0x44, 0xc5, 0xbe, 0x87, 0x7f, 0xbc, 0x17, 0xb,
-    0x41, 0x9e, 0x6b, 0x78, 0xeb, 0xeb, 0xae, 0x5a, 0x60, 0x8f, 0x6f, 0x7c,
-    0x45, 0x4b, 0xd1, 0x99, 0x67, 0x6b, 0x43, 0x1d, 0xb9, 0x52, 0x95, 0x98,
-    0x17, 0x2a, 0xd6, 0xdf, 0x40, 0x8d, 0x5c, 0x52, 0x13, 0x19, 0x57, 0xbf,
-    0x10, 0x35, 0x9e, 0xda, 0x70, 0xe6, 0x27, 0x4b, 0xc4, 0x36, 0xb7, 0x74,
-    0xe9, 0xf8, 0x85, 0x17, 0x8c, 0x1a, 0x84, 0x85, 0xfb, 0x56, 0xbd, 0x70,
-    0xfc, 0xb5, 0x70, 0xba, 0x79, 0x91, 0x8a, 0x20, 0x54, 0x26, 0x56, 0x8d,
-    0xff, 0xa0, 0xc1, 0x4c, 0x9f, 0x9b, 0x97, 0xc5, 0xf,  0xb6, 0x79, 0x14,
-    0x2e, 0x57, 0x92, 0xdb, 0x89, 0x87, 0x5e, 0x21, 0xb8, 0xa1, 0x60, 0x6f,
-    0xfe, 0xab, 0x49, 0x96, 0x2c, 0xd,  0x64, 0x31, 0xe6, 0x47, 0xd6, 0x5d,
-    0x18, 0x1b, 0xeb, 0xdc, 0x35, 0xcc, 0x61, 0x84, 0x9c, 0xe8, 0xb9, 0x15,
-    0x34, 0x86, 0x6f, 0xfc, 0x15, 0x7d, 0xb9, 0xa3, 0xb4, 0xdf, 0x2,  0x1c,
-    0x25, 0x67, 0xfc, 0x75, 0x5f, 0xb9, 0x1b, 0x9a, 0xc8, 0xf3, 0xdd, 0x8c,
-    0x6f, 0xb8, 0xab, 0x30, 0x57, 0x80, 0xc5, 0x63, 0x5,  0x63, 0xbe, 0x74,
-    0x73, 0xe4, 0xd6, 0xfe, 0xea, 0x53, 0xc2, 0x55, 0xe8, 0xcd, 0xc7, 0xbc,
-    0x72, 0xb4, 0xb,  0xf1, 0xb1, 0xde, 0xdf, 0x17, 0xe4, 0xd,  0xba, 0xfb,
-    0x83, 0x71, 0xdf, 0xe7, 0xdb, 0x26, 0x3b, 0xc3, 0x0,  0x57, 0xcb, 0x17,
-    0x94, 0xb5, 0x8,  0x1b, 0xb5, 0xf3, 0x48, 0xf7, 0x95, 0x8f, 0x78, 0x1d,
-    0xb4, 0xf9, 0x38, 0x6e, 0x2f, 0x59, 0xe8, 0x52, 0x4,  0x8b, 0x80, 0x1b,
-    0xa4, 0xd6, 0x44, 0x43, 0xd6, 0x55, 0xd2, 0x5c, 0x51, 0x67, 0x6d, 0xb7,
-    0x70, 0xb3, 0xad, 0x45, 0xe3, 0x4d, 0x71, 0x57, 0x86, 0x8c, 0xc3, 0x6d,
-    0xf7, 0x8b, 0xd8, 0xc4, 0x3e, 0x78, 0x91, 0x28, 0x4d, 0xf7, 0x55, 0x60,
-    0x3f, 0xcb, 0x97, 0x4f, 0xc9, 0x9f, 0x9,  0x6c, 0x97, 0x9f, 0xc,  0xc,
-    0xdf, 0xb0, 0x33, 0xf2, 0xf,  0x48, 0xcf, 0x52, 0xe8, 0x38, 0x35, 0x84,
-    0x6b, 0x33, 0x48, 0x92, 0xba, 0xb0, 0xbf, 0x55, 0x85, 0xd8, 0xf6, 0x64,
-    0xcb, 0x57, 0xcd, 0x6b, 0x52, 0xf4, 0xa5, 0x31, 0xf3, 0x5,  0x86, 0xa2,
-    0x6b, 0x1f, 0xa2, 0x7,  0xb8, 0x20, 0x3d, 0xce, 0x6a, 0xf,  0xdc, 0xa,
-    0x8a, 0x23, 0xb6, 0xfc, 0x76, 0x76, 0xb1, 0xac, 0x7c, 0xb,  0x23, 0x5b,
-    0x7b, 0x90, 0xda, 0x3b, 0xf4, 0x43, 0x48, 0xa5, 0x2,  0x99, 0xe6, 0x21,
-    0x7f, 0x3b, 0xe1, 0x63, 0xa8, 0xd7, 0x2e, 0x82, 0xc3, 0x40, 0xd1, 0x98,
-    0xee, 0xb,  0x65, 0x67, 0x1d, 0xa,  0x51, 0x57, 0x80, 0x9f, 0xa3, 0xde,
-    0x20, 0xa2, 0x79, 0x2b, 0x7d, 0xf4, 0xa5, 0xf4, 0x83, 0xeb, 0x63, 0x65,
-    0xb7, 0x41, 0xbf, 0x69, 0xdb, 0x9d, 0x13, 0x15, 0xc0, 0xbc, 0x4d, 0x84,
-    0xfe, 0x73, 0x21, 0xd9, 0x1d, 0xa0, 0x33, 0xaf, 0x4,  0x33, 0x9e, 0xf9,
-    0xa8, 0xc1, 0xae, 0xaa, 0xa7, 0xc,  0xf4, 0x17, 0xda, 0x59, 0x6a, 0x31,
-    0x6f, 0x16, 0xf0, 0xa,  0x0,  0x24, 0xc3, 0x6a, 0xa2, 0x50, 0x50, 0xc9,
-    0xdf, 0xb,  0xb6, 0x1f, 0x6f, 0x5e, 0x78, 0x76, 0x29, 0x92, 0x62, 0x62,
-    0x91, 0xbc, 0x49, 0x9a, 0xa1, 0xa7, 0x33, 0x3d, 0xf6, 0xdd, 0x68, 0xa3,
-    0xf7, 0x42, 0x5a, 0x93, 0xda, 0xb0, 0xa6, 0x8,  0x8f, 0x69, 0x2c, 0x85,
-    0xf,  0xf4, 0x96, 0x3,  0xd5, 0xa8, 0xba, 0x28, 0xaf, 0x63, 0xba, 0x55,
-    0xbb, 0x97, 0xa4, 0x5b, 0xa,  0x26, 0xf1, 0x7b, 0x28, 0xb7, 0x1f, 0x27,
-    0x4b, 0xa6, 0xbe, 0xe5, 0x78, 0x57, 0xf3, 0x77, 0x39, 0xba, 0xf,  0x69,
-    0x24, 0x1e, 0x2e, 0x38, 0x9c, 0xba, 0xad, 0xa7, 0x86, 0xa0, 0xfd, 0x2e,
-    0xe5, 0x63, 0xb5, 0xb6, 0x6d, 0x54, 0x55, 0xe0, 0xb0, 0x65, 0xb6, 0x34,
-    0xce, 0xe,  0xf5, 0x2d, 0xc1, 0x26, 0x2e, 0xc8, 0xbc, 0x2b, 0x7c, 0xfe,
-    0xd6, 0xee, 0xd9, 0xc,  0xf6, 0x5d, 0x60, 0xc5, 0x9b, 0xd5, 0xa3, 0xfe,
-    0x83, 0x5f, 0x26, 0x7a, 0xcc, 0xb1, 0x5d, 0xe3, 0xad, 0x34, 0x8,  0x64,
-    0x44, 0x95, 0x3b, 0xa9, 0xb3, 0x43, 0x3f, 0xec, 0x93, 0x39, 0xc1, 0xa8,
-    0x27, 0x49, 0xca, 0xae, 0x70, 0xf,  0x11, 0x54, 0xb2, 0x6b, 0x64, 0x3b,
-    0x9d, 0x7a, 0xf5, 0x2c, 0x9a, 0x43, 0x7d, 0xc6, 0x54, 0x9a, 0xfa, 0x9e,
-    0xad, 0xcd, 0x94, 0x15, 0xfc, 0x89, 0x89, 0xbe, 0xaa, 0x9e, 0x8f, 0xbb,
-    0x6,  0x22, 0x42, 0x5,  0xa0, 0x61, 0xb5, 0x58, 0xd7, 0x58, 0xa2, 0xb8,
-    0xfd, 0x4,  0xf3, 0x64, 0x3f, 0x9b, 0x69, 0xcc, 0xc,  0x7a, 0x34, 0x88,
-    0x13, 0xeb, 0x90, 0x8e, 0x33, 0x27, 0xe,  0x65, 0xcd, 0x81, 0xe0, 0x0,
-    0xbf, 0xa1, 0x94, 0x3e, 0x91, 0xbf, 0x54, 0x3f, 0x2f, 0xc6, 0x30, 0xee,
-    0xc1, 0x39, 0xf7, 0x4a, 0xbe, 0xbd, 0xb3, 0xcb, 0x91, 0x16, 0xad, 0xc4,
-    0xb6, 0x3e, 0xc8, 0x6c, 0xc1, 0xb5, 0x66, 0x1b, 0xa0, 0x97, 0x2a, 0x30,
-    0x6c, 0x20, 0xe5, 0xec, 0x4e, 0xd7, 0xe3, 0xea, 0x3a, 0xd5, 0x41, 0x99,
-    0xd0, 0x95, 0xe3, 0x8b, 0x19, 0xee, 0x92, 0x11, 0x84, 0x13, 0xa7, 0x1e,
-    0x65, 0xb5, 0xc8, 0x23, 0x3d, 0xb3, 0x89, 0x30, 0xda, 0xdd, 0x1f, 0xe9,
-    0x55, 0x3c, 0x22, 0xee, 0x18, 0xa,  0x92, 0x5c, 0x61, 0xc7, 0x39, 0xd,
-    0xea, 0x1b, 0xe4, 0xb,  0x5,  0x6e, 0x7b, 0x8e, 0xd0, 0xd5, 0xa5, 0x6b,
-    0x3,  0xaf, 0x8b, 0xb7, 0x75, 0x24, 0xc7, 0xf9, 0x1d, 0x32, 0xea, 0xa9,
-    0xe5, 0xa5, 0x1a, 0x41, 0x82, 0xdd, 0xc8, 0x86, 0x82, 0x85, 0xcd, 0xe,
-    0x89, 0xa4, 0x4a, 0xe0, 0x6a, 0xf4, 0xe,  0x26, 0x33, 0x33, 0xa1, 0x3a,
-    0xd2, 0xde, 0xff, 0x2f, 0xa6, 0x8a, 0x7a, 0x9e, 0x44, 0xab, 0xed, 0x53,
-    0x30, 0xdf, 0xfd, 0x95, 0xac, 0x6d, 0x82, 0xd,  0x5e, 0x35, 0xc8, 0x3b,
-    0xb6, 0x59, 0x93, 0x1d, 0x6b, 0x8c, 0x27, 0x5e, 0x2,  0xa9, 0xa1, 0x64,
-    0x65, 0xe3, 0xbf, 0x52, 0x87, 0x26, 0x10, 0x6,  0x5a, 0xaf, 0x7c, 0x10,
-    0x44, 0x7e, 0x46, 0xfa, 0xc,  0x85, 0xe5, 0x74, 0x92, 0xf6, 0xd8, 0x8,
-    0x59, 0xe8, 0x46, 0xc3, 0x5b, 0x2c, 0x3,  0xda, 0xb3, 0x17, 0xbf, 0x71,
-    0x3e, 0xbd, 0xe3, 0x41, 0x1f, 0xad, 0xa4, 0x9f, 0x31, 0x8d, 0x38, 0x5f,
-    0x83, 0x92, 0x26, 0x8f, 0xe,  0xe4, 0xcc, 0xdb, 0xf4, 0x83, 0x62, 0x34,
-    0xd7, 0xb9, 0xd0, 0x29, 0xa9, 0x4a, 0xba, 0xf2, 0xe2, 0x18, 0x23, 0x30,
-    0x27, 0x10, 0xf,  0x2e, 0xad, 0x40, 0xab, 0xed, 0xda, 0x76, 0xd6, 0x4e,
-    0x60, 0x80, 0x2a, 0xe3, 0x23, 0x79, 0x27, 0xaa, 0xc8, 0xa4, 0xce, 0x1f,
-    0x4f, 0x88, 0x5b, 0x55, 0x83, 0x47, 0x88, 0x56, 0xd4, 0xe9, 0x79, 0x9b,
-    0x7d, 0x83, 0x83, 0x4d, 0x26, 0xe3, 0x90, 0xdf, 0xbf, 0x6c, 0xa0, 0x4f,
-    0x78, 0x7f, 0x69, 0x86, 0xe7, 0x54, 0xfd, 0x4b, 0x24, 0xe9, 0xb6, 0x46,
-    0xf3, 0xdc, 0xae, 0x5e, 0x2c, 0x21, 0x8e, 0xd5, 0x4d, 0x30, 0x25, 0xfa,
-    0xcd, 0xb,  0x4b, 0x8,  0x4b, 0x7e, 0x15, 0x60, 0x30, 0xba, 0x75, 0xbd,
-    0xfb, 0xe2, 0x49, 0x1,  0xcb, 0xff, 0x3f, 0x23, 0xde, 0xdb, 0xc4, 0xb9,
-    0x26, 0x36, 0xb5, 0xc1, 0xd9, 0xc8, 0x63, 0xe0, 0x48, 0xd9, 0xe0, 0xd2,
-    0x52, 0xf7, 0x15, 0x94, 0xf2, 0x1c, 0xc,  0x32, 0xe0, 0xfe, 0xf0, 0xb5,
-    0x3,  0xa6, 0x50, 0xbd, 0xf3, 0x13, 0x95, 0x92, 0xe9, 0x11, 0xd9, 0x75,
-    0xe5, 0xef, 0x94, 0x20, 0xff, 0xff, 0x79, 0xb1, 0x45, 0x27, 0xec, 0x69,
-    0xf7, 0xe3, 0x2d, 0x9e, 0x36, 0x7a, 0xec, 0xcc, 0xcb, 0x57, 0xce, 0x11,
-    0xcb, 0x60, 0x95, 0x19, 0x49, 0x32, 0x7d, 0xd4, 0x5d, 0x1b, 0x97, 0x3d,
-    0xde, 0xd5, 0xb4, 0x4b, 0x8a, 0x31, 0x52, 0x10, 0xb4, 0xe1, 0x35, 0x3a,
-    0x10, 0xb5, 0x4b, 0xf8, 0x83, 0xff, 0x7e, 0x90, 0xb6, 0x37, 0x61, 0x4a,
-    0xad, 0x80, 0x80, 0x78, 0x67, 0xcf, 0xcb, 0x70, 0x5d, 0xcf, 0x78, 0x46,
-    0x1a, 0xa2, 0xfe, 0x68, 0xe3, 0x0,  0x27, 0xc,  0x3a, 0x1,  0xed, 0x89,
-    0x11, 0x7,  0xc7, 0x77, 0xa4, 0xe8, 0x6e, 0x7b, 0xaa, 0x7c, 0x20, 0x86,
-    0xaf, 0xe2, 0x45, 0x45, 0x9f, 0xb6, 0x65, 0xbe, 0x82, 0x5f, 0xdb, 0xce,
-    0x1a, 0x43, 0x15, 0xeb, 0x90, 0x1a, 0x7e, 0xce, 0x5f, 0x0,  0x45, 0xd7,
-    0x5e, 0x58, 0xa,  0xde, 0xab, 0xf,  0xca, 0x46, 0x8e, 0x4a, 0x18, 0xc4,
-    0xc9, 0x5a, 0xdb, 0x13, 0x2,  0xc8, 0x83, 0xaf, 0x1f, 0xd6, 0xa,  0x29,
-    0xae, 0x9e, 0x5d, 0xbe, 0x8f, 0xd0, 0xb0, 0x9e, 0x68, 0x84, 0xd6, 0x4b,
-    0x8,  0xa2, 0x59, 0x6d, 0x34, 0x9e, 0x0,  0x5b, 0x83, 0xbf, 0x3,  0x70,
-    0x43, 0x3a, 0x15, 0xa6, 0xb0, 0x5e, 0x67, 0xf3, 0xfb, 0x4c, 0xe5, 0x2b,
-    0xc1, 0x4f, 0xd5, 0x69, 0xfb, 0x71, 0x62, 0x27, 0x12, 0x35, 0x5b, 0x6e,
-    0x32, 0xb4, 0xb2, 0x22, 0x3a, 0xb0, 0x4c, 0xbd, 0xf5, 0x63, 0x89, 0x70,
-    0x92, 0xcb, 0x29, 0xca, 0xb7, 0xd9, 0xfe, 0xc5, 0xdb, 0xa3, 0xe3, 0xb3,
-    0x36, 0xbf, 0xa8, 0x49, 0xe1, 0x72, 0x61, 0x44, 0x44, 0x21, 0xdb, 0x71,
-    0x3a, 0xf2, 0x7a, 0x5c, 0x21, 0x2,  0x64, 0x38, 0xe4, 0xb9, 0xee, 0x98,
-    0xd7, 0xa8, 0xde, 0xd0, 0xe1, 0x7e, 0x38, 0x55, 0x79, 0xe1, 0x9a, 0x34,
-    0x82, 0xeb, 0x34, 0xd1, 0x45, 0x48, 0xa8, 0xc,  0xc8, 0xf,  0x6a, 0x40,
-    0x38, 0x36, 0x92, 0xa0, 0x25, 0x4d, 0xe1, 0x4b, 0x43, 0xe5, 0x17, 0x79,
-    0xdb, 0x48, 0xf7, 0x8b, 0x25, 0x4a, 0x61, 0x62, 0x59, 0x71, 0x27, 0xca,
-    0x3b, 0x96, 0xe4, 0x54, 0xd8, 0x33, 0x84, 0x90, 0xf,  0x30, 0x1d, 0x10,
-    0x4b, 0x99, 0x51, 0x1a, 0x6f, 0x39, 0xb,  0x14, 0xa,  0x74, 0xfe, 0x65,
-    0x6a, 0x74, 0xa2, 0x63, 0xc0, 0xbd, 0x97, 0x6e, 0xd6, 0xd3, 0x21, 0x3,
-    0xa9, 0x65, 0x39, 0xcf, 0x87, 0x93, 0x37, 0xdc, 0x60, 0x53, 0xbf, 0x79,
-    0x6d, 0x37, 0x1b, 0x6d, 0x76, 0xc9, 0x5c, 0xc8, 0xd5, 0x51, 0xdb, 0x4a,
-    0xa3, 0x54, 0x0,  0x99, 0x15, 0xab, 0xac, 0x46, 0xae, 0x45, 0xb3, 0xf8,
-    0x7e, 0x98, 0x42, 0xf6, 0x95, 0x9e, 0xb5, 0x19, 0x92, 0x79, 0xf4, 0x25,
-    0x9c, 0xd7, 0xec, 0xd7, 0x7a, 0x2f, 0xef, 0x82, 0x8a, 0xe0, 0x2d, 0xee,
-    0x77, 0xab, 0x81, 0x39, 0x75, 0x44, 0x2b, 0xa4, 0x4b, 0x1c, 0x73, 0x8a,
-    0x23, 0x8e, 0xc0, 0x1f, 0x69, 0xbd, 0x53, 0x88, 0x3e, 0xaa, 0x32, 0x1a,
-    0xa,  0x93, 0xc0, 0x81, 0x8d, 0x37, 0x5e, 0xd1, 0x4,  0x1d, 0xbb, 0x3a,
-    0x56, 0x47, 0xe6, 0x30, 0x7a, 0x6a, 0x6a, 0x9d, 0x4b, 0xb6, 0x4d, 0xce,
-    0x26, 0x69, 0x5b, 0x5,  0x57, 0xdc, 0x33, 0x99, 0x68, 0xca, 0xca, 0xe4,
-    0x42, 0xfe, 0xad, 0xa,  0x1c, 0xf2, 0xe0, 0xa5, 0x43, 0xb,  0xa4, 0xd9,
-    0x9,  0xdc, 0xa1, 0xe,  0x28, 0x77, 0xab, 0xc6, 0x17, 0xc8, 0x47, 0x5e,
-    0x4f, 0x3f, 0x6,  0x78, 0x70, 0x12, 0x69, 0xc9, 0x4a, 0x57, 0x87, 0x49,
-    0xeb, 0x8d, 0x66, 0xb1, 0x13, 0x13, 0x6c, 0x63, 0x96, 0x6c, 0x29, 0x5e,
-    0xce, 0x21, 0x1f, 0xe3, 0x8a, 0xdf, 0xac, 0x5f, 0x9b, 0x34, 0x74, 0x6,
-    0x93, 0x9f, 0x4b, 0xf1, 0x50, 0x17, 0x5,  0x1c, 0xf2, 0xcb, 0x1d, 0xc6,
-    0x85, 0x30, 0xf8, 0xa4, 0x2f, 0xeb, 0xaa, 0x41, 0xb3, 0xa5, 0x42, 0xfb,
-    0x21, 0x4e, 0x4c, 0x4d, 0xc5, 0xda, 0xc8, 0x13, 0xb1, 0x42, 0xba, 0xfe,
-    0x2,  0x39, 0x7d, 0xd,  0xcc, 0x7a, 0x18, 0x6b, 0x79, 0x19, 0x11, 0x2b,
-    0x25, 0xe2, 0x4c, 0xba, 0x83, 0xb3, 0x13, 0xe9, 0x15, 0x7e, 0x3b, 0x7b,
-    0x5b, 0xa3, 0xd,  0x72, 0x70, 0x54, 0xdc, 0x2c, 0xbf, 0xfa, 0x46, 0xc5,
-    0xeb, 0xba, 0xb,  0x2c, 0xa1, 0xd6, 0x5a, 0xdd, 0xc8, 0xc4, 0xd,  0x58,
-    0x8b, 0x94, 0x2f, 0x5f, 0x4e, 0x8c, 0xa0, 0x48, 0x5c, 0x3a, 0x9b, 0xa5,
-    0xbb, 0xa3, 0x88, 0xa8, 0xa2, 0x9a, 0x9,  0xe5, 0x7c, 0x3e, 0x2b, 0x65,
-    0xf8, 0x73, 0x92, 0x9e, 0x6c, 0xe7, 0x14, 0x33, 0xc1, 0xa3, 0xec, 0x90,
-    0xa6, 0xc2, 0xa5, 0xe8, 0xd9, 0xf8, 0x80, 0xa4, 0xe0, 0x28, 0x36, 0x55,
-    0x6b, 0xfd, 0x50, 0xc,  0x4,  0xdb, 0x87, 0xdc, 0xc8, 0x91, 0x76, 0x2c,
-    0xec, 0xc4, 0xd3, 0xe1, 0x8a, 0x94, 0xe5, 0xd5, 0x4f, 0x7b, 0xd0, 0xca,
-    0xa2, 0x3a, 0x33, 0xa1, 0x1f, 0x62, 0x68, 0x9b, 0x82, 0x9a, 0xd7, 0x43,
-    0xcf, 0x62, 0x16, 0x40, 0xe8, 0x4d, 0x69, 0x85, 0x33, 0xad, 0x27, 0x2c,
-    0xe2, 0xbb, 0x91, 0x94, 0xf4, 0x2c, 0xa9, 0x9b, 0x2,  0x2,  0xe1, 0x22,
-    0x79, 0x65, 0x65, 0xac, 0xf6, 0x4e, 0x29, 0x90, 0x97, 0xf5, 0x69, 0x10,
-    0x4a, 0xb1, 0xd6, 0x11, 0xfa, 0xed, 0x33, 0xab, 0x28, 0x76, 0xe8, 0x80,
-    0x7f, 0xfb, 0x39, 0x20, 0xe0, 0x34, 0x4c, 0x3f, 0x15, 0x2,  0xac, 0x88,
-    0x5d, 0x2d, 0x68, 0x88, 0x4e, 0x53, 0xe9, 0xac, 0x1,  0x9f, 0x73, 0x93,
-    0x25, 0x3f, 0x6a, 0x56, 0x52, 0x84, 0x53, 0xf5, 0x4,  0x32, 0xea, 0xc9,
-    0x75, 0xa8, 0x4d, 0x2b, 0xd7, 0x85, 0x51, 0xcd, 0x7d, 0x5e, 0xe6, 0x86,
-    0xb7, 0x2d, 0x8a, 0x4,  0xce, 0x64, 0xea, 0x6,  0x34, 0x29, 0x62, 0xda,
-    0x32, 0xe3, 0xb0, 0x79, 0xd3, 0xf8, 0x8e, 0xc5, 0xf,  0x56, 0x43, 0xec,
-    0xc,  0x16, 0x91, 0x77, 0x3d, 0xf0, 0x77, 0x9d, 0x7,  0xb3, 0xa5, 0xc0,
-    0x3a, 0x14, 0xf5, 0xc5, 0x96, 0x6c, 0x6b, 0xc9, 0xad, 0xc8, 0x66, 0xe8,
-    0x6a, 0xab, 0xaa, 0x40, 0xed, 0x31, 0x8a, 0x2c, 0xf4, 0xa0, 0x41, 0x7b,
-    0x28, 0x6f, 0xad, 0x30, 0x6,  0xc0, 0xff, 0xd7, 0xd5, 0x8b, 0xd0, 0x57,
-    0x64, 0xc1, 0xbb, 0x76, 0x57, 0xef, 0xed, 0x3f, 0x87, 0xe5, 0x99, 0xca,
-    0xd8, 0x41, 0xfd, 0x40, 0xa8, 0x1d, 0xb9, 0x4b, 0xca, 0x29, 0xe2, 0xd1,
-    0xcc, 0x4b, 0x31, 0x1,  0x84, 0xe9, 0x14, 0x76, 0xb9, 0xe1, 0x28, 0x75,
-    0xae, 0x56, 0x50, 0xec, 0x75, 0xd1, 0x98, 0x98, 0xa2, 0x1c, 0xea, 0xd1,
-    0x35, 0xfd, 0x2f, 0x1a, 0xbf, 0x4a, 0x55, 0xa7, 0xb2, 0xc2, 0xef, 0x45,
-    0x8c, 0x41, 0x40, 0x89, 0x46, 0xec, 0xab, 0x13, 0x21, 0xe8, 0x66, 0x80,
-    0x57, 0x61, 0x78, 0x5f, 0x15, 0x40, 0xe2, 0xc0, 0xd0, 0x89, 0xd5, 0x9a,
-    0x66, 0x16, 0x8d, 0xaa, 0x4e, 0xa1, 0x6e, 0xb7, 0xf9, 0x6c, 0xdf, 0xc9,
-    0x86, 0x5e, 0x7d, 0x40, 0x76, 0xfa, 0xa6, 0x16, 0x6c, 0x49, 0x2c, 0xcc,
-    0x64, 0x85, 0x92, 0xe1, 0x16, 0x67, 0xd,  0x10, 0xff, 0x4d, 0x9b, 0xc8,
-    0x3f, 0x9d, 0xae, 0x84, 0x49, 0x6d, 0xb8, 0xe3, 0x8f, 0x5b, 0x3c, 0x21,
-    0xf1, 0x94, 0xf5, 0x9d, 0x4,  0x90, 0x3a, 0x2e, 0xf8, 0xde, 0x32, 0xbb,
-    0x4d, 0xcb, 0xdd, 0xb3, 0x47, 0xe,  0xef, 0x0,  0x39, 0x60, 0x63, 0x3d,
-    0xd9, 0x2f, 0x6e, 0xfd, 0x45, 0x2e, 0xf2, 0x90, 0x37, 0xe2, 0x1b, 0x57,
-    0x20, 0xa4, 0x16, 0x6d, 0x0,  0x5b, 0xe7, 0x93, 0xcf, 0x5b, 0x17, 0x22,
-    0xd5, 0x44, 0x12, 0x93, 0xdc, 0x91, 0x6e, 0xa9, 0x27, 0xa6, 0x95, 0xe3,
-    0xd9, 0xec, 0x95, 0x66, 0xc5, 0x9e, 0x70, 0x7f, 0x89, 0xe5, 0xcb, 0x22,
-    0xb2, 0x50, 0x82, 0xc8, 0x10, 0x9e, 0xb3, 0x61, 0x75, 0xcd, 0x14, 0x3e,
-    0xd2, 0xd1, 0x27, 0xfa, 0x48, 0xc3, 0x38, 0x45, 0x3d, 0xb8, 0xb2, 0x36,
-    0xc9, 0xda, 0x91, 0x8c, 0x35, 0x45, 0x2c, 0x21, 0x85, 0x76, 0xad, 0x67,
-    0x3f, 0xf2, 0x1a, 0x6d, 0x16, 0x58, 0x83, 0xf8, 0x15, 0x66, 0x6b, 0xdf,
-    0xf8, 0x27, 0x98, 0x8,  0x9f, 0x50, 0xc0, 0x3e, 0xee, 0xf,  0x38, 0x53,
-    0x41, 0x33, 0xc6, 0x61, 0x50, 0xc5, 0x49, 0x1b, 0x67, 0x57, 0xac, 0xe1,
-    0x67, 0x7c, 0xe0, 0x6a, 0x80, 0x5e, 0x5d, 0xf5, 0xb3, 0xc1, 0xb,  0x27,
-    0xdf, 0x72, 0xce, 0xbf, 0xaa, 0x3e, 0x9a, 0x31, 0xf9, 0xcd, 0xbf, 0x29,
-    0xb4, 0x3a, 0x7,  0x81, 0x1e, 0x47, 0x1b, 0xd8, 0xf3, 0x82, 0xef, 0x13,
-    0xc8, 0xf0, 0xb6, 0x13, 0x5b, 0x4c, 0xb5, 0x2f, 0x5f, 0xa4, 0xc1, 0x52,
-    0xb8, 0xe,  0x90, 0x43, 0xc5, 0xa7, 0xc2, 0x36, 0x90, 0x4a, 0xdf, 0x5d,
-    0xc8, 0xb7, 0x60, 0x10, 0x38, 0xd6, 0xde, 0x10, 0x7b, 0x5b, 0x76, 0x92,
-    0x82, 0xc7, 0x10, 0xc3, 0xc2, 0xb8, 0xf,  0xc,  0x19, 0xaa, 0xdc, 0x15,
-    0x55, 0x51, 0x55, 0xe4, 0x7d, 0x61, 0x3f, 0xaf, 0xee, 0x40, 0x53, 0x8e,
-    0x7a, 0x63, 0xfe, 0xc9, 0xd6, 0xdb, 0xe3, 0x20, 0xb7, 0xd8, 0x7c, 0x90,
-    0x8d, 0xad, 0x6d, 0x82, 0x1c, 0xba, 0xf3, 0xbc, 0x87, 0x1d, 0x18, 0xdc,
-    0xea, 0x99, 0x70, 0xa4,
-};
-const uint8_t* kAltGameImages2x[] = {
-    kAltGameImages2xA, kAltGameImages2xB, kAltGameImages2xC,
-    kAltGameImages2xD, kAltGameImages2xE, kAltGameImages2xF,
-};
-const size_t kAltGameImages2xLength[] = {
-    base::size(kAltGameImages2xA), base::size(kAltGameImages2xB),
-    base::size(kAltGameImages2xC), base::size(kAltGameImages2xD),
-    base::size(kAltGameImages2xE), base::size(kAltGameImages2xF),
-};
-static_assert(base::size(kAltGameImages2x) == kAltGameImagesCount, "");
-static_assert(base::size(kAltGameImages2xLength) == kAltGameImagesCount, "");
-
-std::string DecryptImage(const std::string& image_ciphertext,
-                         crypto::SymmetricKey* key) {
-  constexpr int kBlockSize = 16;
-  crypto::Encryptor encryptor;
-  // *Never* use this pattern for encrypting anything that matters! There are
-  // many problems with this, but it's just obfuscation so it doesn't matter.
-  if (!encryptor.Init(key, crypto::Encryptor::Mode::CBC,
-                      /*iv=*/key->key().substr(0, kBlockSize))) {
-    DLOG(ERROR) << "Failed to initialize encryptor.";
-    return std::string();
-  }
-
-  std::string image_plaintext;
-  if (!encryptor.Decrypt(image_ciphertext, &image_plaintext)) {
-    DLOG(ERROR) << "Failed to decrypt image.";
-    return std::string();
-  }
-  return image_plaintext;
-}
-
-bool LookupImage(int id, int scale, std::string* image) {
-  if (id < 0 || id >= kAltGameImagesCount)
-    return false;
-
-  if (scale == 1)
-    *image = std::string(reinterpret_cast<const char*>(kAltGameImages1x[id]),
-                         kAltGameImages1xLength[id]);
-  else if (scale == 2)
-    *image = std::string(reinterpret_cast<const char*>(kAltGameImages2x[id]),
-                         kAltGameImages2xLength[id]);
-  else
-    return false;
-  return true;
-}
-
-std::unique_ptr<crypto::SymmetricKey> GetKey() {
-  std::string b64_key = kNetErrorAltGameModeKey.Get();
-  if (b64_key.empty()) {
-    DLOG(ERROR) << "No image encryption key present.";
-    return nullptr;
-  }
-
-  // Note: key is base64url-encoded because the default base64 format includes
-  // the '/' character which interferes with setting the param from the command
-  // line for testing.
-  std::string raw_key;
-  if (!base::Base64UrlDecode(
-          b64_key, base::Base64UrlDecodePolicy::IGNORE_PADDING, &raw_key)) {
-    DLOG(ERROR) << "Failed to base64-decode image encryption key.";
-    return nullptr;
-  }
-
-  std::unique_ptr<crypto::SymmetricKey> key = crypto::SymmetricKey::Import(
-      crypto::SymmetricKey::Algorithm::AES, raw_key);
-  if (!key) {
-    DLOG(ERROR) << "Invalid image encryption key: wrong length?";
-    return nullptr;
-  }
-  return key;
-}
-
-}  // namespace
-
-const base::Feature kNetErrorAltGameMode{"NetErrorAltGameMode",
-                                         base::FEATURE_DISABLED_BY_DEFAULT};
-const base::FeatureParam<std::string> kNetErrorAltGameModeKey{
-    &kNetErrorAltGameMode, "Key", ""};
 
 bool EnableAltGameMode() {
-  return base::FeatureList::IsEnabled(kNetErrorAltGameMode);
+  return false;
 }
 
 std::string GetAltGameImage(int image_id, int scale) {
-  std::string encrypted_image;
-  if (!LookupImage(image_id, scale, &encrypted_image)) {
-    DLOG(ERROR) << "Couldn't find alt game image with ID=" << image_id
-                << " and scale=" << scale << "x.";
-    return std::string();
-  }
-
-  std::unique_ptr<crypto::SymmetricKey> key = GetKey();
-  if (!key) {
-    DLOG(ERROR) << "Failed to load alt game image encryption key.";
-    return std::string();
-  }
-
-  std::string image = DecryptImage(encrypted_image, key.get());
-  if (image.empty()) {
-    DLOG(ERROR) << "Failed to decrypt alt game image " << image_id << " at "
-                << scale << "x scale.";
-    return std::string();
-  }
-
-  if (!base::StartsWith(image, "data:image/png;base64,")) {
-    DLOG(ERROR) << "Decrypted data doesn't look like an image data URL.";
-    return std::string();
-  }
-
-  return image;
+  NOTIMPLEMENTED();
+  return std::string();
 }
 
 int ChooseAltGame() {
-  // Image 0 should be "common".
-  static_assert(1 <= kAltGameImagesCount - 1, "");
-  return base::RandInt(1, kAltGameImagesCount - 1);
+  NOTIMPLEMENTED();
+  return 0;
 }
 
 }  // namespace error_page
diff --git a/components/error_page/common/alt_game_images/README.md b/components/error_page/common/alt_game_images/README.md
new file mode 100644
index 0000000..361bc16
--- /dev/null
+++ b/components/error_page/common/alt_game_images/README.md
@@ -0,0 +1,80 @@
+# How to obfuscate new dino game art before a surprise launch
+
+The tools in this directory make it possible to add art to the dino game but
+keep it hidden until a planned reveal.
+
+The images are built into Chrome in an obfuscated form so that they can't be
+viewed if they're found in the source tree or in the binary. When it's time to
+launch, a secret key can be sent to clients via feature param. If the key is
+present, images are deobfuscated at net error page load time and made available
+to the dino game.
+
+Warning: although this procedure has flavors of cryptography, it should _never_
+be used to protect information that matters!
+
+## Generate a key
+
+Run:
+
+```
+python3 generate_key.py > /tmp/dino_key
+```
+
+Keep the key somewhere safe so that it can remain secret until launch. (An
+internal repo or doc is probably good enough.)
+
+## Generate `alt_game_images.cc`
+
+You'll need to install Pycryptodome, jinja2, and secrets:
+`pip install --user pycryptodome jinja2 secrets`
+
+Run `create_alt_game_images_cc.py` as shown below (filling in your own values as
+needed):
+
+```
+# Paths to directory containing input images.
+IMAGES_DIR=path/to/images
+
+# Names of images in the order in which they should be added to the
+# generated source. They correspond to files named surfing_1x.png,
+# surfing_2x.png, hurdles_1x.png, etc.
+IMAGE_NAMES="common,equestrian,gymnastics,hurdles,surfing,swimming"
+
+# The key you generated in the first step.
+KEY=$(cat /tmp/dino_key)
+
+python3 create_alt_game_images_cc.py \
+  --images_dir=$IMAGES_DIR \
+  --image_names=$IMAGE_NAMES \
+  --key=$KEY
+
+git cl format
+```
+
+# Make your changes to game code
+
+The images are made available to net error page Javascript in
+`LocalizedError::GetPageState()`: see
+https://source.chromium.org/chromium/chromium/src/+/main:components/error_page/common/localized_error.cc;drc=4e22ca0649a83df9026440bf8a4c2c04d1de8633;l=922.
+
+An image data URL passed to the page with
+`result.strings.SetStringPath("someImage", ...)` will be available in Javascript
+as `loadTimeData.someImage`.
+
+# Debug
+
+You can try loading the images by running Chrome with the flag and key set on
+the command line:
+
+```
+out/Debug/chrome --enable-features=NetErrorAltGameMode:Key/$KEY
+```
+
+and then bringing up the net error page somehow (chrome://network-error/-106).
+
+If all is well, there should be no logs that mention `alt_game_images.cc`.
+
+# Launch
+
+The new images can be released to users by enabling the feature
+"NetErrorAltGameMode" and setting feature param "Key" to the key.
diff --git a/components/error_page/common/alt_game_images/alt_game_images.cc.template b/components/error_page/common/alt_game_images/alt_game_images.cc.template
new file mode 100644
index 0000000..4469c39
--- /dev/null
+++ b/components/error_page/common/alt_game_images/alt_game_images.cc.template
@@ -0,0 +1,169 @@
+// Copyright (c) 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file was automatically generated from {{ template_file }}.
+// See {{ readme_file }} for details about how to make changes.
+
+#include "components/error_page/common/alt_game_images.h"
+
+#include <cstring>
+
+#include "base/base64.h"
+#include "base/base64url.h"
+#include "base/rand_util.h"
+#include "base/strings/strcat.h"
+#include "base/strings/string_util.h"
+#include "crypto/encryptor.h"
+#include "crypto/symmetric_key.h"
+
+namespace error_page {
+namespace {
+{% for image in images_1x %}
+  const uint8_t kAltGameImages1x{{ image.name }}[] = {
+    {{ image.literals }}
+  };
+{% endfor %}
+
+const uint8_t* kAltGameImages1x[] = {
+  {% for image in images_1x %}
+    kAltGameImages1x{{ image.name }},
+  {% endfor %}
+};
+constexpr int kAltGameImagesCount = base::size(kAltGameImages1x);
+const size_t kAltGameImages1xLength[] = {
+  {% for image in images_1x %}
+    base::size(kAltGameImages1x{{ image.name }}),
+  {% endfor %}
+};
+static_assert(base::size(kAltGameImages1xLength) == kAltGameImagesCount, "");
+
+{% for image in images_2x %}
+  const uint8_t kAltGameImages2x{{ image.name }}[] = {
+    {{ image.literals }}
+  };
+{% endfor %}
+
+const uint8_t* kAltGameImages2x[] = {
+  {% for image in images_2x %}
+    kAltGameImages2x{{ image.name }},
+  {% endfor %}
+};
+
+const size_t kAltGameImages2xLength[] = {
+  {% for image in images_2x %}
+    base::size(kAltGameImages2x{{ image.name }}),
+  {% endfor %}
+};
+
+static_assert(base::size(kAltGameImages2x) == kAltGameImagesCount, "");
+static_assert(base::size(kAltGameImages2xLength) == kAltGameImagesCount, "");
+
+std::string DecryptImage(const std::string& image_ciphertext,
+                         crypto::SymmetricKey* key) {
+  constexpr int kBlockSize = 16;
+  crypto::Encryptor encryptor;
+  // *Never* use this pattern for encrypting anything that matters! There are
+  // many problems with this, but it's just obfuscation so it doesn't matter.
+  if (!encryptor.Init(key, crypto::Encryptor::Mode::CBC,
+                      /*iv=*/key->key().substr(0, kBlockSize))) {
+    DLOG(ERROR) << "Failed to initialize encryptor.";
+    return std::string();
+  }
+
+  std::string image_plaintext;
+  if (!encryptor.Decrypt(image_ciphertext, &image_plaintext)) {
+    DLOG(ERROR) << "Failed to decrypt image.";
+    return std::string();
+  }
+  return image_plaintext;
+}
+
+bool LookupImage(int id, int scale, std::string* image) {
+  if (id < 0 || id >= kAltGameImagesCount)
+    return false;
+
+  if (scale == 1)
+    *image = std::string(reinterpret_cast<const char*>(kAltGameImages1x[id]),
+                         kAltGameImages1xLength[id]);
+  else if (scale == 2)
+    *image = std::string(reinterpret_cast<const char*>(kAltGameImages2x[id]),
+                         kAltGameImages2xLength[id]);
+  else
+    return false;
+  return true;
+}
+
+std::unique_ptr<crypto::SymmetricKey> GetKey() {
+  std::string b64_key = kNetErrorAltGameModeKey.Get();
+  if (b64_key.empty()) {
+    DLOG(ERROR) << "No image encryption key present.";
+    return nullptr;
+  }
+
+  // Note: key is base64url-encoded because the default base64 format includes
+  // the '/' character which interferes with setting the param from the command
+  // line for testing.
+  std::string raw_key;
+  if (!base::Base64UrlDecode(
+          b64_key, base::Base64UrlDecodePolicy::IGNORE_PADDING, &raw_key)) {
+    DLOG(ERROR) << "Failed to base64-decode image encryption key.";
+    return nullptr;
+  }
+
+  std::unique_ptr<crypto::SymmetricKey> key = crypto::SymmetricKey::Import(
+      crypto::SymmetricKey::Algorithm::AES, raw_key);
+  if (!key) {
+    DLOG(ERROR) << "Invalid image encryption key: wrong length?";
+    return nullptr;
+  }
+  return key;
+}
+
+}  // namespace
+
+const base::Feature kNetErrorAltGameMode{"NetErrorAltGameMode",
+                                         base::FEATURE_DISABLED_BY_DEFAULT};
+const base::FeatureParam<std::string> kNetErrorAltGameModeKey{
+    &kNetErrorAltGameMode, "Key", ""};
+
+bool EnableAltGameMode() {
+  return base::FeatureList::IsEnabled(kNetErrorAltGameMode);
+}
+
+std::string GetAltGameImage(int image_id, int scale) {
+  std::string encrypted_image;
+  if (!LookupImage(image_id, scale, &encrypted_image)) {
+    DLOG(ERROR) << "Couldn't find alt game image with ID=" << image_id
+                << " and scale=" << scale << "x.";
+    return std::string();
+  }
+
+  std::unique_ptr<crypto::SymmetricKey> key = GetKey();
+  if (!key) {
+    DLOG(ERROR) << "Failed to load alt game image encryption key.";
+    return std::string();
+  }
+
+  std::string image = DecryptImage(encrypted_image, key.get());
+  if (image.empty()) {
+    DLOG(ERROR) << "Failed to decrypt alt game image " << image_id << " at "
+                << scale << "x scale.";
+    return std::string();
+  }
+
+  if (!base::StartsWith(image, "data:image/png;base64,")) {
+    DLOG(ERROR) << "Decrypted data doesn't look like an image data URL.";
+    return std::string();
+  }
+
+  return image;
+}
+
+int ChooseAltGame() {
+  // Image 0 should be "common".
+  static_assert(1 <= kAltGameImagesCount - 1, "");
+  return base::RandInt(1, kAltGameImagesCount - 1);
+}
+
+}  // namespace error_page
diff --git a/components/error_page/common/alt_game_images/create_alt_game_images_cc.py b/components/error_page/common/alt_game_images/create_alt_game_images_cc.py
new file mode 100755
index 0000000..c62c17c
--- /dev/null
+++ b/components/error_page/common/alt_game_images/create_alt_game_images_cc.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python/2/3
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from absl import app
+from absl import flags
+from Crypto.Cipher import AES
+from Crypto.Util.Padding import pad
+import base64
+import os
+from jinja2 import Environment, FileSystemLoader, select_autoescape
+
+FLAGS = flags.FLAGS
+flags.DEFINE_string('images_dir', None, 'Directory containing input images.')
+flags.DEFINE_list(
+    'image_names', None,
+    'Comma-separated list of image names in the order in which they should ' +
+    'be included in the generated source.')
+flags.DEFINE_string('key', None,
+                    'Base64url-encoded key used to obfuscate images.')
+flags.mark_flags_as_required(['images_dir', 'image_names', 'key'])
+
+_TEMPLATE_FILE_NAME = 'alt_game_images.cc.template'
+_README_FILE = 'README.md'
+
+
+class Image:
+    def __init__(self, name, literals, size):
+        self.name = name
+        self.literals = literals
+        self.size = size
+
+
+def ObfuscateImage(name, key_bytes, image_bytes):
+    # WARNING: for obfuscation only. A CBC IV should never be taken from the
+    # key material.
+    cipher = AES.new(key_bytes, AES.MODE_CBC, iv=key_bytes[:16])
+    ciphertext_bytes = cipher.encrypt(pad(image_bytes, AES.block_size))
+
+    ciphertext_hex_literals = []
+    for b in ciphertext_bytes:
+        ciphertext_hex_literals.append(hex(b))
+    return Image(name, ','.join(ciphertext_hex_literals),
+                 len(ciphertext_bytes))
+
+
+def ConvertToDataUrl(image_bytes):
+    return b'data:image/png;base64,' + base64.b64encode(image_bytes)
+
+
+def ObfuscateImages(key_bytes, images_dir, image_suffix):
+    if len(FLAGS.image_names) > 26:
+        raise RuntimeError("We aren't prepared to handle more than 26 images.")
+
+    result = []
+    for i, image_name in enumerate(FLAGS.image_names):
+        name = chr(ord('A') + i)
+        image_bytes = None
+        with open(
+                os.path.join(images_dir, image_name) + image_suffix + '.png',
+                'rb') as file:
+            image_bytes = file.read()
+        image_bytes = ConvertToDataUrl(image_bytes)
+        result.append(ObfuscateImage(name, key_bytes, image_bytes))
+
+    return result
+
+
+def CreateAltGameImagesCc(images_1x, images_2x, script_dir):
+    template_dir_path = script_dir
+    env = Environment(loader=FileSystemLoader(template_dir_path),
+                      autoescape=select_autoescape())
+    template = env.get_template(_TEMPLATE_FILE_NAME)
+    rendered = template.render(images_1x=images_1x,
+                               images_2x=images_2x,
+                               template_file='alt_game_images/' +
+                               _TEMPLATE_FILE_NAME,
+                               readme_file=_README_FILE)
+
+    with open(os.path.join(script_dir, '../alt_game_images.cc'),
+              'w') as out_file:
+        out_file.write(rendered)
+
+
+def main(argv):
+    script_dir = os.path.dirname(os.path.abspath(__file__))
+
+    key_bytes = base64.urlsafe_b64decode(FLAGS.key + '==')
+    if len(key_bytes) != 32:
+        raise RuntimeError('Key length must be 32.')
+
+    obfuscated_images_1x = ObfuscateImages(key_bytes, FLAGS.images_dir, '_1x')
+    obfuscated_images_2x = ObfuscateImages(key_bytes, FLAGS.images_dir, '_2x')
+    CreateAltGameImagesCc(obfuscated_images_1x, obfuscated_images_2x,
+                          script_dir)
+
+
+if __name__ == '__main__':
+    app.run(main)
diff --git a/components/error_page/common/alt_game_images/generate_key.py b/components/error_page/common/alt_game_images/generate_key.py
new file mode 100755
index 0000000..6478813b
--- /dev/null
+++ b/components/error_page/common/alt_game_images/generate_key.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python/2/3
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import secrets
+
+
+def main():
+    print(secrets.token_urlsafe(32))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h
index 663060f..5d89e301 100644
--- a/components/infobars/core/infobar_delegate.h
+++ b/components/infobars/core/infobar_delegate.h
@@ -142,7 +142,7 @@
     OFFLINE_PAGE_INFOBAR_DELEGATE_ANDROID = 71,
     SEARCH_GEOLOCATION_DISCLOSURE_INFOBAR_DELEGATE_ANDROID = 72,
     AUTOMATION_INFOBAR_DELEGATE = 73,
-    VR_SERVICES_UPGRADE_ANDROID = 74,
+    // Removed: VR_SERVICES_UPGRADE_ANDROID = 74,
     READER_MODE_INFOBAR_ANDROID = 75,
     VR_FEEDBACK_INFOBAR_ANDROID = 76,
     FRAMEBUST_BLOCK_INFOBAR_ANDROID = 77,
diff --git a/components/javascript_dialogs/tab_modal_dialog_manager.cc b/components/javascript_dialogs/tab_modal_dialog_manager.cc
index 06a7d93..85f420b 100644
--- a/components/javascript_dialogs/tab_modal_dialog_manager.cc
+++ b/components/javascript_dialogs/tab_modal_dialog_manager.cc
@@ -215,7 +215,7 @@
       }
       case content::JAVASCRIPT_DIALOG_TYPE_CONFIRM: {
         *did_suppress_message = true;
-        alerting_web_contents->GetMainFrame()->AddMessageToConsole(
+        render_frame_host->AddMessageToConsole(
             blink::mojom::ConsoleMessageLevel::kWarning,
             base::StringPrintf(kDialogSuppressedConsoleMessageFormat, "confirm",
                                "5140698722467840"));
@@ -223,7 +223,7 @@
       }
       case content::JAVASCRIPT_DIALOG_TYPE_PROMPT: {
         *did_suppress_message = true;
-        alerting_web_contents->GetMainFrame()->AddMessageToConsole(
+        render_frame_host->AddMessageToConsole(
             blink::mojom::ConsoleMessageLevel::kWarning,
             base::StringPrintf(kDialogSuppressedConsoleMessageFormat, "prompt",
                                "5637107137642496"));
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java
index d3084c0..2ffbfc3 100644
--- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java
+++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessagesMetrics.java
@@ -128,6 +128,8 @@
                 return "AutoDarkWebContents";
             case MessageIdentifier.TAILORED_SECURITY_ENABLED:
                 return "TailoredSecurityEnabled";
+            case MessageIdentifier.VR_SERVICES_UPGRADE:
+                return "VrServicesUpgrade";
             default:
                 return "Unknown";
         }
diff --git a/components/messages/android/message_enums.h b/components/messages/android/message_enums.h
index 4f5dc19f..377e7e747 100644
--- a/components/messages/android/message_enums.h
+++ b/components/messages/android/message_enums.h
@@ -96,6 +96,7 @@
   AUTO_DARK_WEB_CONTENTS = 21,
   TEST_MESSAGE = 22,
   TAILORED_SECURITY_ENABLED = 23,
+  VR_SERVICES_UPGRADE = 24,
 
   // Insert new values before this line.
   COUNT
diff --git a/components/optimization_guide/core/hints_fetcher.cc b/components/optimization_guide/core/hints_fetcher.cc
index 0d48247..1f1e9f7 100644
--- a/components/optimization_guide/core/hints_fetcher.cc
+++ b/components/optimization_guide/core/hints_fetcher.cc
@@ -55,6 +55,8 @@
       return "BatchUpdateGoogleSRP";
     case proto::RequestContext::CONTEXT_BATCH_UPDATE_ACTIVE_TABS:
       return "BatchUpdateActiveTabs";
+    case proto::RequestContext::CONTEXT_BOOKMARKS:
+      return "Bookmarks";
   }
   NOTREACHED();
   return std::string();
diff --git a/components/optimization_guide/proto/common_types.proto b/components/optimization_guide/proto/common_types.proto
index 25fc676..2f60b1e6 100644
--- a/components/optimization_guide/proto/common_types.proto
+++ b/components/optimization_guide/proto/common_types.proto
@@ -52,6 +52,9 @@
   CONTEXT_BATCH_UPDATE_ACTIVE_TABS = 5;
   // Requesting a batch of models to update.
   CONTEXT_BATCH_UPDATE_MODELS = 6;
+  // Requesting page load metadata for a user's bookmarks when visiting the
+  // bookmarks surface.
+  CONTEXT_BOOKMARKS = 7;
 }
 
 message FieldTrial {
diff --git a/components/payments/content/service_worker_payment_app_factory.cc b/components/payments/content/service_worker_payment_app_factory.cc
index 68efab99..926ccda 100644
--- a/components/payments/content/service_worker_payment_app_factory.cc
+++ b/components/payments/content/service_worker_payment_app_factory.cc
@@ -21,7 +21,6 @@
 #include "content/public/browser/stored_payment_app.h"
 #include "content/public/browser/supported_delegations.h"
 #include "content/public/browser/web_contents.h"
-#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
 
 namespace payments {
 namespace {
@@ -187,11 +186,8 @@
 
 void ServiceWorkerPaymentAppFactory::Create(base::WeakPtr<Delegate> delegate) {
   auto* rfh = delegate->GetInitiatorRenderFrameHost();
-  // Exit if frame or page is being unloaded or payments are otherwise
-  // disallowed.
-  if (!rfh || !rfh->IsActive() || !delegate->GetWebContents() ||
-      !rfh->IsFeatureEnabled(blink::mojom::PermissionsPolicyFeature::kPayment))
-    return;
+  if (!rfh || !rfh->IsActive() || !delegate->GetWebContents())
+    return;  // The frame or page is being unloaded.
 
   auto creator = std::make_unique<ServiceWorkerPaymentAppCreator>(
       /*owner=*/this, delegate);
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 0c885a0c..f9ea136 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -8006,9 +8006,9 @@
       ],
       'example_value': False,
       'id': 766,
-      'caption': '''Specifies whether to allow insecure websites to make requests to more-private network endpoints''',
+      'caption': '''Specifies whether to allow websites to make requests to more-private network endpoints in an insecure manner''',
       'tags': ['system-security'],
-      'desc': '''Controls whether insecure websites are allowed to make requests to more-private network endpoints.
+      'desc': '''Controls whether websites are allowed to make requests to more-private network endpoints in an insecure manner.
 
           This policy relates to the Private Network Access specification. See https://wicg.github.io/private-network-access/ for more details.
 
@@ -8017,11 +8017,9 @@
           2) Its IP address is private and the other is public.
           In the future, depending on spec evolution, this policy might apply to all cross-origin requests directed at private IPs or localhost.
 
-          A website is deemed secure if it meets the definition of a secure context in https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts. Otherwise, it will be treated as an insecure context.
+          When this policy is either not set or set to false, the default behavior for requests to more-private network endpoints will depend on the user's personal configuration for the <ph name="BLOCK_INSECURE_PRIVATE_NETWORK_REQUESTS_FEATURE_NAME">BlockInsecurePrivateNetworkRequests</ph>, <ph name="PRIVATE_NETWORK_ACCESS_SEND_PREFLIGHTS_FEATURE_NAME">PrivateNetworkAccessSendPreflights</ph>, and <ph name="PRIVATE_NETWORK_ACCESS_RESPECT_PREFLIGHT_RESULTS_FEATURE_NAME">PrivateNetworkAccessRespectPreflightResults</ph> feature flags, which may be set by field trials or on the command line.
 
-          When this policy is either not set or set to false, the default behavior for requests from insecure contexts to more-private network endpoints will depend on the user's personal configuration for the <ph name="BLOCK_INSECURE_PRIVATE_NETWORK_REQUESTS_FEATURE_NAME">BlockInsecurePrivateNetworkRequests</ph> feature, which may be set by a field trial or on the command line.
-
-          When this policy is set to true, insecure websites are allowed to make requests to any network endpoint, subject to other cross-origin checks.''',
+          When this policy is set to true, websites are allowed to make requests to any network endpoint, subject to other cross-origin checks.''',
     },
     {
       'name': 'InsecurePrivateNetworkRequestsAllowedForUrls',
@@ -8047,16 +8045,14 @@
       },
       'example_value': ['http://www.example.com:8080', '[*.]example.edu'],
       'id': 767,
-      'caption': '''Allow the listed sites to make requests to more-private network endpoints from insecure contexts.''',
+      'caption': '''Allow the listed sites to make requests to more-private network endpoints in an insecure manner.''',
       'tags': ['system-security'],
-      'desc': '''List of URL patterns. Private network requests initiated from insecure websites served by matching origins are allowed.
+      'desc': '''List of URL patterns. Requests initiated from websites served by matching origins are not subject to Private Network Access checks.
 
           If unset, this policy behaves as if set to the empty list.
 
           For origins not covered by the patterns specified here, the global default value will be used either from the <ph name="INSECURE_PRIVATE_NETWORK_REQUESTS_ALLOWED_POLICY_NAME">InsecurePrivateNetworkRequestsAllowed</ph> policy, if it is set, or the user's personal configuration otherwise.
 
-          Note that this policy only affects insecure origins, so secure origins (e.g. https://example.com) included in this list will be ignored.
-
           For detailed information on valid URL patterns, please see https://cloud.google.com/docs/chrome-enterprise/policies/url-patterns.''',
     },
     {
diff --git a/components/services/heap_profiling/public/cpp/profiling_client.cc b/components/services/heap_profiling/public/cpp/profiling_client.cc
index 386d812..72d2d20 100644
--- a/components/services/heap_profiling/public/cpp/profiling_client.cc
+++ b/components/services/heap_profiling/public/cpp/profiling_client.cc
@@ -67,10 +67,9 @@
       {base::TaskPriority::BEST_EFFORT, base::MayBlock(),
        base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
       base::BindOnce([]() {
-        bool can_unwind =
-            base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()
-                ->can_unwind_stack_frames();
-        DCHECK(can_unwind);
+        base::trace_event::CFIBacktraceAndroid::GetInitializedInstance()
+            ->can_unwind_stack_frames();
+        // Ignore failures since the default unwind tables are used as backup.
       }),
       base::BindOnce(&ProfilingClient::StartProfilingInternal,
                      base::Unretained(this), std::move(params),
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index e806b830..9b3e3ca 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -1098,7 +1098,8 @@
     tracing::PerfettoTracedProcess::Get()
         ->SetAllowSystemTracingConsumerCallback(
             base::BindRepeating(&ShouldAllowSystemTracingConsumer));
-    tracing::InitTracingPostThreadPoolStartAndFeatureList();
+    tracing::InitTracingPostThreadPoolStartAndFeatureList(
+        /* enable_consumer */ true);
 
     // PowerMonitor is needed in reduced mode. BrowserMainLoop will safely skip
     // initializing it again if it has already been initialized.
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 35e5348..932a428 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -280,7 +280,6 @@
   RFH_INTERECEPT_DOWNLOAD_WHILE_INACTIVE = 253,
   RFH_CREATE_CHILD_FRAME_SANDBOX_FLAGS = 254,
   RFPH_FOCUSED_FENCED_FRAME = 255,
-  WCI_REQUEST_LOCK_MOUSE_FENCED_FRAME = 256,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 8373813..ec1ba57 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -82,6 +82,10 @@
 #include "ui/gl/gl_switches.h"
 #include "ui/latency/latency_info.h"
 
+#if !defined(OS_ANDROID)
+#include "components/metrics/stability_metrics_helper.h"
+#endif
+
 #if defined(OS_WIN)
 #include "base/win/win_util.h"
 #include "sandbox/policy/win/sandbox_win.h"
@@ -781,6 +785,18 @@
       UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessTerminationStatus2",
                                 ConvertToGpuTerminationStatus(info.status),
                                 GpuTerminationStatus::MAX_ENUM);
+#if !defined(OS_ANDROID)
+      if (info.status != base::TERMINATION_STATUS_NORMAL_TERMINATION &&
+          info.status != base::TERMINATION_STATUS_STILL_RUNNING) {
+        // Add a sample to Stability.Counts2's GPU crash bucket.
+        //
+        // On Android Chrome and Android WebLayer, GPU crashes are logged via
+        // ContentStabilityMetricsProvider::OnCrashDumpProcessed() and
+        // StabilityMetricsHelper::IncreaseGpuCrashCount().
+        metrics::StabilityMetricsHelper::RecordStabilityEvent(
+            metrics::StabilityEventType::kGpuCrash);
+      }
+#endif  // !defined(OS_ANDROID)
 
       if (info.status == base::TERMINATION_STATUS_NORMAL_TERMINATION ||
           info.status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 0d372a18..a3da81f 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3617,14 +3617,6 @@
   OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RequestToLockMouse",
                         "render_widget_host", render_widget_host, "privileged",
                         privileged);
-  if (render_widget_host->frame_tree()->type() ==
-      FrameTree::Type::kFencedFrame) {
-    // This is unexpected because Pointer Lock API is blocked in the renderer
-    // process.
-    ReceivedBadMessage(render_widget_host->GetProcess(),
-                       bad_message::WCI_REQUEST_LOCK_MOUSE_FENCED_FRAME);
-    return;
-  }
   for (WebContentsImpl* current = this; current;
        current = current->GetOuterWebContents()) {
     if (current->mouse_lock_widget_) {
diff --git a/content/child/child_process.cc b/content/child/child_process.cc
index 54e33070..039f57a 100644
--- a/content/child/child_process.cc
+++ b/content/child/child_process.cc
@@ -87,7 +87,8 @@
     initialized_thread_pool_ = true;
   }
 
-  tracing::InitTracingPostThreadPoolStartAndFeatureList();
+  tracing::InitTracingPostThreadPoolStartAndFeatureList(
+      /* enable_consumer */ false);
 
 #if defined(OS_ANDROID)
   SetupCpuTimeMetrics();
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index e5f121f5..aeacb8aa 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -619,7 +619,8 @@
 
     StartBrowserThreadPool();
     BrowserTaskExecutor::PostFeatureListSetup();
-    tracing::InitTracingPostThreadPoolStartAndFeatureList();
+    tracing::InitTracingPostThreadPoolStartAndFeatureList(
+        /* enable_consumer */ true);
     InitializeBrowserMemoryInstrumentationClient();
   }
 
diff --git a/content/test/data/gpu/webcodecs/svc.html b/content/test/data/gpu/webcodecs/svc.html
index 0118211..29d2ccb 100644
--- a/content/test/data/gpu/webcodecs/svc.html
+++ b/content/test/data/gpu/webcodecs/svc.html
@@ -54,9 +54,10 @@
           }
 
           frames_encoded++;
-          TEST.assert(metadata.temporalLayerId < arg.layers,
+          TEST.assert(metadata.svc != null);
+          TEST.assert(metadata.svc.temporalLayerId < arg.layers,
                       "too large temporal ID");
-          if (metadata.temporalLayerId == 0) {
+          if (metadata.svc.temporalLayerId == 0) {
             decoder.decode(chunk);
           }
         },
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index 51d73ef8..0f63c67 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -483,7 +483,7 @@
 
 # Pixel_WebGPUImportVideoFrame hangs on Windows FYI bots
 crbug.com/1274796 [ win nvidia-0x2184 ] Pixel_WebGPUImportVideoFrame [ Failure ]
-crbug.com/1274796 [ win intel-0x3e92 ] Pixel_WebGPUImportVideoFrame [ Failure ]
+crbug.com/1274796 [ win intel-0x5912 ] Pixel_WebGPUImportVideoFrame [ Failure ]
 crbug.com/1274796 [ win amd-0x7340 ] Pixel_WebGPUImportVideoFrame [ Failure ]
 
 # Pixel_Video_Media_Stream_Incompatible_Stride flakes on NVIDIA Linux SkiaRenderer GL
diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn
index 43925ec..34fb09a 100644
--- a/crypto/BUILD.gn
+++ b/crypto/BUILD.gn
@@ -203,15 +203,19 @@
   ]
 }
 
-# This is a meta-target that forwards to NSS's SSL library or OpenSSL,
-# according to the state of the crypto flags. A target just wanting to depend
-# on the current SSL library should just depend on this.
+# This target historically abstracted between different cryptography and TLS
+# libraries. Now we always use //third_party/boringssl for cryptography and TLS.
+# On Linux and Chrome OS, we additionally use //build/config/linux/nss for some
+# certificate-related platform integration points. Depend on one or both of the
+# individual targets instead of this one.
+#
+# TODO(https://crbug.com/1275165): Remove this target.
 group("platform") {
   public_deps = [ "//third_party/boringssl" ]
 
   # Link in NSS if it is used for the platform certificate library
   # (use_nss_certs).
   if (use_nss_certs) {
-    public_configs = [ "//build/config/linux/nss:system_nss_no_ssl_config" ]
+    public_configs = [ "//build/config/linux/nss" ]
   }
 }
diff --git a/extensions/common/switches.cc b/extensions/common/switches.cc
index 4b9941c..e65b3918 100644
--- a/extensions/common/switches.cc
+++ b/extensions/common/switches.cc
@@ -32,9 +32,6 @@
 // Enable BLE Advertisiing in apps.
 const char kEnableBLEAdvertising[] = "enable-ble-advertising-in-apps";
 
-const char kDisableDesktopCaptureAudio[] =
-    "disable-audio-support-for-desktop-share";
-
 // Enables extension APIs that are in development.
 const char kEnableExperimentalExtensionApis[] =
     "enable-experimental-extension-apis";
diff --git a/extensions/common/switches.h b/extensions/common/switches.h
index df2708d..962b0b0 100644
--- a/extensions/common/switches.h
+++ b/extensions/common/switches.h
@@ -18,7 +18,6 @@
 extern const char kAllowlistedExtensionID[];
 extern const char kDEPRECATED_AllowlistedExtensionID[];
 extern const char kDisableAppContentVerification[];
-extern const char kDisableDesktopCaptureAudio[];
 extern const char kDisableExtensionsHttpThrottling[];
 extern const char kEmbeddedExtensionOptions[];
 extern const char kEnableExperimentalExtensionApis[];
diff --git a/infra/config/dev/subprojects/chromium/ci.star b/infra/config/dev/subprojects/chromium/ci.star
index 4300345..26d65da 100644
--- a/infra/config/dev/subprojects/chromium/ci.star
+++ b/infra/config/dev/subprojects/chromium/ci.star
@@ -20,7 +20,7 @@
         ),
         acl.entry(
             roles = acl.BUILDBUCKET_OWNER,
-            groups = "google/luci-task-force@google.com",
+            groups = "project-chromium-admins",
         ),
     ],
 )
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index e5e6de1..1c2a071a 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -2015,7 +2015,6 @@
       ref_regexp_exclude: "refs/branch-heads/4430"
       ref_regexp_exclude: "refs/branch-heads/4515"
       ref_regexp_exclude: "refs/branch-heads/4606"
-      ref_regexp_exclude: "refs/branch-heads/4638"
       ref_regexp_exclude: "refs/branch-heads/4664"
       ref_regexp_exclude: "refs/branch-heads/4692"
     }
diff --git a/infra/config/generated/luci/cr-buildbucket-dev.cfg b/infra/config/generated/luci/cr-buildbucket-dev.cfg
index c7a4135..acb7cbc0 100644
--- a/infra/config/generated/luci/cr-buildbucket-dev.cfg
+++ b/infra/config/generated/luci/cr-buildbucket-dev.cfg
@@ -8,7 +8,7 @@
   name: "ci"
   acls {
     role: WRITER
-    group: "google/luci-task-force@google.com"
+    group: "project-chromium-admins"
   }
   acls {
     group: "all"
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 24aa7b8..62a8320ac 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -8,7 +8,7 @@
   name: "ci"
   acls {
     role: WRITER
-    group: "google/luci-task-force@google.com"
+    group: "project-chromium-admins"
   }
   acls {
     group: "all"
@@ -47236,7 +47236,7 @@
   name: "goma"
   acls {
     role: WRITER
-    group: "google/luci-task-force@google.com"
+    group: "project-chromium-admins"
   }
   acls {
     group: "all"
@@ -49774,7 +49774,7 @@
   name: "reclient"
   acls {
     role: WRITER
-    group: "google/luci-task-force@google.com"
+    group: "project-chromium-admins"
   }
   acls {
     group: "all"
@@ -52523,6 +52523,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -52624,7 +52628,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -52824,6 +52828,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -52925,7 +52933,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -53847,6 +53855,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -53941,7 +53953,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -57615,6 +57627,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -57708,7 +57724,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -68783,6 +68799,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -68884,7 +68904,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -70888,6 +70908,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -70989,7 +71013,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -72895,6 +72919,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -72989,7 +73017,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -74092,6 +74120,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -74186,7 +74218,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -75533,7 +75565,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -75630,6 +75662,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -76431,6 +76467,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -76523,7 +76563,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -80622,6 +80662,10 @@
         value: 100
       }
       experiments {
+        key: "luci.recipes.use_python3"
+        value: 1
+      }
+      experiments {
         key: "luci.use_realms"
         value: 100
       }
@@ -80723,7 +80767,7 @@
       }
       experiments {
         key: "luci.recipes.use_python3"
-        value: 1
+        value: 5
       }
       experiments {
         key: "luci.use_realms"
@@ -82036,7 +82080,7 @@
   name: "webrtc"
   acls {
     role: WRITER
-    group: "google/luci-task-force@google.com"
+    group: "project-chromium-admins"
   }
   acls {
     group: "all"
@@ -82506,7 +82550,7 @@
   name: "webrtc.fyi"
   acls {
     role: WRITER
-    group: "google/luci-task-force@google.com"
+    group: "project-chromium-admins"
   }
   acls {
     group: "all"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index a393398..4d0c921 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -811,10 +811,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -1533,10 +1529,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -1949,10 +1941,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -2271,10 +2259,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -2934,10 +2918,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -3480,10 +3460,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -3857,10 +3833,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -4284,10 +4256,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -4684,10 +4652,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -5226,10 +5190,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -5663,10 +5623,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -6136,10 +6092,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -6863,10 +6815,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -7262,10 +7210,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -7635,10 +7579,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -7998,10 +7938,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -8620,10 +8556,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -9052,10 +8984,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -9429,10 +9357,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -9831,10 +9755,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -10153,10 +10073,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -10485,10 +10401,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -10797,10 +10709,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -11110,10 +11018,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -11472,10 +11376,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -11934,10 +11834,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -12286,10 +12182,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -12679,10 +12571,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -13041,10 +12929,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -13417,10 +13301,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -13739,10 +13619,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
@@ -14059,10 +13935,6 @@
         url: "/p/chromium-m94/g/main/console"
       }
       links {
-        text: "m95"
-        url: "/p/chromium-m95/g/main/console"
-      }
-      links {
         text: "m96"
         url: "/p/chromium-m96/g/main/console"
       }
diff --git a/infra/config/generated/luci/realms-dev.cfg b/infra/config/generated/luci/realms-dev.cfg
index c79c32d4..10b523e 100644
--- a/infra/config/generated/luci/realms-dev.cfg
+++ b/infra/config/generated/luci/realms-dev.cfg
@@ -55,7 +55,7 @@
   }
   bindings {
     role: "role/buildbucket.owner"
-    principals: "group:google/luci-task-force@google.com"
+    principals: "group:project-chromium-admins"
   }
   bindings {
     role: "role/buildbucket.reader"
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index 21835b0..ac559d7 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -36,7 +36,6 @@
   }
   bindings {
     role: "role/swarming.poolUser"
-    principals: "group:google/luci-task-force@google.com"
     principals: "group:mdb/chrome-troopers"
   }
   bindings {
@@ -50,7 +49,6 @@
   }
   bindings {
     role: "role/swarming.taskTriggerer"
-    principals: "group:google/luci-task-force@google.com"
     principals: "group:mdb/chrome-troopers"
   }
 }
@@ -65,7 +63,7 @@
   }
   bindings {
     role: "role/buildbucket.owner"
-    principals: "group:google/luci-task-force@google.com"
+    principals: "group:project-chromium-admins"
   }
   bindings {
     role: "role/buildbucket.reader"
@@ -157,7 +155,7 @@
   }
   bindings {
     role: "role/buildbucket.owner"
-    principals: "group:google/luci-task-force@google.com"
+    principals: "group:project-chromium-admins"
   }
   bindings {
     role: "role/buildbucket.reader"
@@ -176,7 +174,6 @@
     principals: "project:chromium-m90"
     principals: "project:chromium-m92"
     principals: "project:chromium-m94"
-    principals: "project:chromium-m95"
     principals: "project:chromium-m96"
     principals: "project:chromium-m97"
     principals: "user:chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -229,7 +226,6 @@
     principals: "project:chromium-m90"
     principals: "project:chromium-m92"
     principals: "project:chromium-m94"
-    principals: "project:chromium-m95"
     principals: "project:chromium-m96"
     principals: "project:chromium-m97"
     principals: "user:infra-try-recipes-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -262,7 +258,7 @@
   }
   bindings {
     role: "role/buildbucket.owner"
-    principals: "group:google/luci-task-force@google.com"
+    principals: "group:project-chromium-admins"
   }
   bindings {
     role: "role/buildbucket.reader"
@@ -323,7 +319,7 @@
   }
   bindings {
     role: "role/buildbucket.owner"
-    principals: "group:google/luci-task-force@google.com"
+    principals: "group:project-chromium-admins"
   }
   bindings {
     role: "role/buildbucket.reader"
@@ -354,7 +350,7 @@
   }
   bindings {
     role: "role/buildbucket.owner"
-    principals: "group:google/luci-task-force@google.com"
+    principals: "group:project-chromium-admins"
   }
   bindings {
     role: "role/buildbucket.reader"
diff --git a/infra/config/milestones.json b/infra/config/milestones.json
index ce1885d..155c609 100644
--- a/infra/config/milestones.json
+++ b/infra/config/milestones.json
@@ -19,11 +19,6 @@
         "project": "chromium-m94",
         "ref": "refs/branch-heads/4606"
     },
-    "95": {
-        "name": "m95",
-        "project": "chromium-m95",
-        "ref": "refs/branch-heads/4638"
-    },
     "96": {
         "name": "m96",
         "project": "chromium-m96",
diff --git a/infra/config/recipes.star b/infra/config/recipes.star
index dfe07d0d..bfa9606c 100644
--- a/infra/config/recipes.star
+++ b/infra/config/recipes.star
@@ -136,13 +136,16 @@
 build_recipe(
     name = "recipe:chromium/orchestrator",
     bootstrappable = True,
+    experiments = {
+        "luci.recipes.use_python3": 1,
+    },
 )
 
 build_recipe(
     name = "recipe:chromium/compilator",
     bootstrappable = True,
     experiments = {
-        "luci.recipes.use_python3": 1,
+        "luci.recipes.use_python3": 5,
     },
 )
 
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index e773e02..b806d01 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -52,7 +52,7 @@
         ),
         acl.entry(
             roles = acl.BUILDBUCKET_OWNER,
-            groups = "google/luci-task-force@google.com",
+            groups = "project-chromium-admins",
         ),
         acl.entry(
             roles = acl.SCHEDULER_TRIGGERER,
diff --git a/infra/config/subprojects/goma/goma.star b/infra/config/subprojects/goma/goma.star
index 57cb7c7..472b152 100644
--- a/infra/config/subprojects/goma/goma.star
+++ b/infra/config/subprojects/goma/goma.star
@@ -17,7 +17,7 @@
         ),
         acl.entry(
             roles = acl.BUILDBUCKET_OWNER,
-            groups = "google/luci-task-force@google.com",
+            groups = "project-chromium-admins",
         ),
     ],
 )
diff --git a/infra/config/subprojects/reclient/reclient.star b/infra/config/subprojects/reclient/reclient.star
index 8a4eb3cc0..60f2d136 100644
--- a/infra/config/subprojects/reclient/reclient.star
+++ b/infra/config/subprojects/reclient/reclient.star
@@ -20,7 +20,7 @@
         ),
         acl.entry(
             roles = acl.BUILDBUCKET_OWNER,
-            groups = "google/luci-task-force@google.com",
+            groups = "project-chromium-admins",
         ),
     ],
 )
diff --git a/infra/config/subprojects/webrtc/webrtc.fyi.star b/infra/config/subprojects/webrtc/webrtc.fyi.star
index 0e4bcef..e4bff93 100644
--- a/infra/config/subprojects/webrtc/webrtc.fyi.star
+++ b/infra/config/subprojects/webrtc/webrtc.fyi.star
@@ -17,7 +17,7 @@
         ),
         acl.entry(
             roles = acl.BUILDBUCKET_OWNER,
-            groups = "google/luci-task-force@google.com",
+            groups = "project-chromium-admins",
         ),
         acl.entry(
             roles = acl.SCHEDULER_OWNER,
diff --git a/infra/config/subprojects/webrtc/webrtc.star b/infra/config/subprojects/webrtc/webrtc.star
index a303eec..b0cadc7 100644
--- a/infra/config/subprojects/webrtc/webrtc.star
+++ b/infra/config/subprojects/webrtc/webrtc.star
@@ -17,7 +17,7 @@
         ),
         acl.entry(
             roles = acl.BUILDBUCKET_OWNER,
-            groups = "google/luci-task-force@google.com",
+            groups = "project-chromium-admins",
         ),
         acl.entry(
             roles = acl.SCHEDULER_OWNER,
diff --git a/infra/config/swarming.star b/infra/config/swarming.star
index b9c070c..6fe229e 100644
--- a/infra/config/swarming.star
+++ b/infra/config/swarming.star
@@ -45,7 +45,6 @@
     pool_realm = "@root",
     groups = [
         "mdb/chrome-troopers",
-        "google/luci-task-force@google.com",
     ],
 )
 
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
index f18fc4c..5a73260 100644
--- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -138,7 +138,7 @@
                 const char* name) {
   for (const auto& field : form) {
     if (field->heuristic_type() == fieldType) {
-      EXPECT_EQ(base::UTF8ToUTF16(name), field->unique_name());
+      EXPECT_EQ(base::UTF8ToUTF16(name), field->name);
       return;
     }
   }
@@ -357,11 +357,11 @@
           ->autofill_manager();
   const auto& forms = autofill_manager->form_structures();
   const auto& form = *(forms.begin()->second);
-  CheckField(form, NAME_FULL, "name_1");
-  CheckField(form, ADDRESS_HOME_LINE1, "address_1");
-  CheckField(form, ADDRESS_HOME_CITY, "city_1");
-  CheckField(form, ADDRESS_HOME_STATE, "state_1");
-  CheckField(form, ADDRESS_HOME_ZIP, "zip_1");
+  CheckField(form, NAME_FULL, "name");
+  CheckField(form, ADDRESS_HOME_LINE1, "address");
+  CheckField(form, ADDRESS_HOME_CITY, "city");
+  CheckField(form, ADDRESS_HOME_STATE, "state");
+  CheckField(form, ADDRESS_HOME_ZIP, "zip");
   ExpectMetric("Autofill.IsEnabled.PageLoad", 1);
   ExpectHappinessMetric(AutofillMetrics::FORMS_LOADED);
 }
diff --git a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm
index 667f710..48ca8d8b1 100644
--- a/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin_sync/signin_sync_view_controller.mm
@@ -407,6 +407,11 @@
   DCHECK(textView == self.learnMoreTextView);
 
   NSMutableString* detailsMessage = [[NSMutableString alloc] init];
+  if (self.enterpriseSignInRestrictions & kEnterpriseForceSignIn) {
+    [self appendRestrictionString:l10n_util::GetNSString(
+                                      IDS_IOS_ENTERPRISE_FORCED_SIGNIN_MESSAGE)
+                         toString:detailsMessage];
+  }
   if (self.enterpriseSignInRestrictions & kEnterpriseRestrictAccounts) {
     [self appendRestrictionString:
               l10n_util::GetNSString(
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_action_row.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_action_row.swift
index 11b854d5..bd84e63 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_action_row.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_action_row.swift
@@ -11,24 +11,22 @@
   @ObservedObject var action: OverflowMenuAction
 
   var body: some View {
-    let enabled = action.enabled && !action.enterpriseDisabled
     Button(
-      action: {
-        if enabled {
-          action.handler()
-        }
-      },
+      action: action.handler,
       label: {
         HStack {
           Text(action.name)
-            .opacity(enabled ? 1 : 0.5)
           Spacer()
           action.image
-            .opacity(enabled ? 1 : 0.5)
+            // Without explicitly removing the image from accessibility,
+            // VoiceOver will occasionally read out icons it thinks it can
+            // recognize.
+            .accessibilityHidden(true)
         }
         .contentShape(Rectangle())
       }
     )
+    .disabled(!action.enabled || action.enterpriseDisabled)
     .accentColor(.cr_textPrimaryColor)
   }
 }
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift
index 7d4d05a2..d0b6638 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_destination_view.swift
@@ -77,6 +77,10 @@
       .padding(interiorPadding)
       .background(iconBackground(configuration: configuration))
       .padding([.leading, .trailing], spacing)
+      // Without explicitly removing the image from accessibility,
+      // VoiceOver will occasionally read out icons it thinks it can
+      // recognize.
+      .accessibilityHidden(true)
   }
 
   /// Text view for the destination.
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_footer_row.swift b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_footer_row.swift
index d529f25..750ca47 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_footer_row.swift
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_footer_row.swift
@@ -41,17 +41,17 @@
           .frame(height: Dimensions.iconLineDividerHeight)
       }
       .padding([.top], Dimensions.iconLineExtraVerticalSpacing)
-      // Add empty tap gesture to the non tapable text, otherwise the link
-      // onTapGesture is triggered when tapping on this text too.
       Text(footer.name)
         .padding([.top], Dimensions.iconLineExtraVerticalSpacing)
         .font(.footnote)
-        .onTapGesture {}
       Text(footer.link)
         .font(.caption2)
         .foregroundColor(.cr_blue)
         .onTapGesture(perform: footer.handler)
     }
-    .contentShape(Rectangle())
+    // Group all children together so VoiceOver doesn't have to read the two
+    // text labels individually.
+    .accessibilityElement(children: .combine)
+    .accessibilityAction(.default, footer.handler)
   }
 }
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 2323fffb..d79ada3 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -75,6 +75,7 @@
     "resources:app_icon_placeholder",
     "resources:encryption_error",
     "resources:enterprise_icon",
+    "resources:legacy_settings_passwords",
     "resources:round_settings_unsafe_state",
     "resources:settings_about_chrome",
     "resources:settings_accounts_add_account",
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
index 2056a37e..848008b 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator.mm
@@ -337,18 +337,22 @@
 #pragma mark - Loads sign out section
 
 - (void)loadSignOutSection {
+  if (!self.syncConsentGiven) {
+    self.signOutAndTurnOffSyncItem = nil;
+    return;
+  }
   // Creates the sign-out item and its section.
   TableViewModel* model = self.consumer.tableViewModel;
-  [model addSectionWithIdentifier:SignOutSectionIdentifier];
+  NSInteger syncDataTypeSectionIndex =
+      [model sectionForSectionIdentifier:SyncDataTypeSectionIdentifier];
+  DCHECK_NE(NSNotFound, syncDataTypeSectionIndex);
+  [model insertSectionWithIdentifier:SignOutSectionIdentifier
+                             atIndex:syncDataTypeSectionIndex + 1];
   TableViewTextItem* item =
       [[TableViewTextItem alloc] initWithType:SignOutItemType];
   item.text = GetNSString(IDS_IOS_OPTIONS_ACCOUNTS_SIGN_OUT_TURN_OFF_SYNC);
   item.textColor = [UIColor colorNamed:kRedColor];
   self.signOutAndTurnOffSyncItem = item;
-
-  if (!self.syncConsentGiven) {
-    return;
-  }
   [model addItem:self.signOutAndTurnOffSyncItem
       toSectionWithIdentifier:SignOutSectionIdentifier];
 
@@ -367,24 +371,21 @@
 }
 
 - (void)updateSignOutSection {
-  BOOL hasModelUpdate = NO;
   TableViewModel* model = self.consumer.tableViewModel;
-  BOOL hasSignOutItem = [model hasItem:self.signOutAndTurnOffSyncItem];
-  if (!hasSignOutItem && self.syncConsentGiven) {
+  BOOL hasSignOutSection =
+      [model hasSectionForSectionIdentifier:SignOutSectionIdentifier];
+  if (!hasSignOutSection && self.syncConsentGiven) {
+    [self loadSignOutSection];
     DCHECK(self.signOutAndTurnOffSyncItem);
-    [model addItem:self.signOutAndTurnOffSyncItem
-        toSectionWithIdentifier:SignOutSectionIdentifier];
-    hasModelUpdate = YES;
-  } else if (hasSignOutItem && !self.syncConsentGiven) {
-    [model removeItemWithType:SignOutItemType
-        fromSectionWithIdentifier:SignOutSectionIdentifier];
-    hasModelUpdate = YES;
-  }
-
-  if (hasModelUpdate) {
     NSUInteger sectionIndex =
         [model sectionForSectionIdentifier:SignOutSectionIdentifier];
-    [self.consumer reloadSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
+    [self.consumer insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
+  } else if (hasSignOutSection && !self.syncConsentGiven) {
+    NSUInteger sectionIndex =
+        [model sectionForSectionIdentifier:SignOutSectionIdentifier];
+    [model removeSectionWithIdentifier:SignOutSectionIdentifier];
+    self.signOutAndTurnOffSyncItem = nil;
+    [self.consumer deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]];
   }
 }
 
diff --git a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm
index 2ec1f00..886490d 100644
--- a/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/google_services/manage_sync_settings_mediator_unittest.mm
@@ -178,7 +178,7 @@
 
   [mediator_ manageSyncSettingsTableViewControllerLoadModel:mediator_.consumer];
 
-  ASSERT_TRUE([mediator_.consumer.tableViewModel
+  EXPECT_FALSE([mediator_.consumer.tableViewModel
       hasSectionForSectionIdentifier:SyncSettingsSectionIdentifier::
                                          SignOutSectionIdentifier]);
 
@@ -189,8 +189,8 @@
   ASSERT_EQ(2UL, advanced_settings_items.count);
 
   TableViewImageItem* encryption_item = advanced_settings_items[0];
-  ASSERT_EQ(encryption_item.type, SyncSettingsItemType::EncryptionItemType);
-  ASSERT_TRUE(encryption_item.enabled);
+  EXPECT_EQ(encryption_item.type, SyncSettingsItemType::EncryptionItemType);
+  EXPECT_TRUE(encryption_item.enabled);
 }
 
 // Tests that encryption is accessible when there is a Sync error due to a
@@ -208,8 +208,8 @@
   ASSERT_EQ(3UL, advanced_settings_items.count);
 
   TableViewImageItem* encryption_item = advanced_settings_items[0];
-  ASSERT_EQ(encryption_item.type, SyncSettingsItemType::EncryptionItemType);
-  ASSERT_TRUE(encryption_item.enabled);
+  EXPECT_EQ(encryption_item.type, SyncSettingsItemType::EncryptionItemType);
+  EXPECT_TRUE(encryption_item.enabled);
 }
 
 // Tests that encryption is accessible when Sync is enabled.
@@ -226,10 +226,10 @@
   ASSERT_EQ(3UL, advanced_settings_items.count);
 
   TableViewImageItem* encryption_item = advanced_settings_items[0];
-  ASSERT_EQ(encryption_item.type, SyncSettingsItemType::EncryptionItemType);
-  ASSERT_TRUE(encryption_item.enabled);
+  EXPECT_EQ(encryption_item.type, SyncSettingsItemType::EncryptionItemType);
+  EXPECT_TRUE(encryption_item.enabled);
 
-  ASSERT_FALSE([mediator_.consumer.tableViewModel
+  EXPECT_FALSE([mediator_.consumer.tableViewModel
       hasSectionForSectionIdentifier:SyncErrorsSectionIdentifier]);
 }
 
@@ -241,11 +241,10 @@
 
   [mediator_ manageSyncSettingsTableViewControllerLoadModel:mediator_.consumer];
 
-  // "Turn off Sync" item is shown.
-  NSArray* sign_out_items = [mediator_.consumer.tableViewModel
-      itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
-                                       SignOutSectionIdentifier];
-  ASSERT_EQ(0UL, sign_out_items.count);
+  // Sign out section not added.
+  EXPECT_FALSE([mediator_.consumer.tableViewModel
+      hasSectionForSectionIdentifier:SyncSettingsSectionIdentifier::
+                                         SignOutSectionIdentifier]);
 }
 
 // Tests that "Turn off Sync" is accessible when Sync is enabled.
@@ -260,7 +259,7 @@
   NSArray* sign_out_items = [mediator_.consumer.tableViewModel
       itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
                                        SignOutSectionIdentifier];
-  ASSERT_EQ(1UL, sign_out_items.count);
+  EXPECT_EQ(1UL, sign_out_items.count);
 }
 
 // Tests that the policy info is shown below the "Turn off Sync" item when the
@@ -279,7 +278,7 @@
   NSArray* sign_out_items = [mediator_.consumer.tableViewModel
       itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
                                        SignOutSectionIdentifier];
-  ASSERT_EQ(1UL, sign_out_items.count);
+  EXPECT_EQ(1UL, sign_out_items.count);
 
   // The footer below "Turn off Sync" is shown.
   ListItem* footer = [mediator_.consumer.tableViewModel
@@ -287,7 +286,7 @@
                                          SignOutSectionIdentifier];
   TableViewLinkHeaderFooterItem* footerTextItem =
       base::mac::ObjCCastStrict<TableViewLinkHeaderFooterItem>(footer);
-  ASSERT_GT([footerTextItem.text length], 0UL);
+  EXPECT_GT([footerTextItem.text length], 0UL);
 }
 
 // Tests that a Sync error that occurs after the user has loaded the Settings
@@ -303,13 +302,13 @@
   // Loads the Sync page again in disabled state.
   [mediator_ onSyncStateChanged];
 
-  ASSERT_TRUE([mediator_.consumer.tableViewModel
+  EXPECT_TRUE([mediator_.consumer.tableViewModel
       hasSectionForSectionIdentifier:SyncSettingsSectionIdentifier::
                                          SyncErrorsSectionIdentifier]);
   NSArray* error_items = [mediator_.consumer.tableViewModel
       itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
                                        SyncErrorsSectionIdentifier];
-  ASSERT_EQ(1UL, error_items.count);
+  EXPECT_EQ(1UL, error_items.count);
 }
 
 // Tests that Sync errors display a single error message when loaded one after
@@ -327,7 +326,7 @@
   // Loads the Sync page again in the needs encryption passphrase error state.
   [mediator_ onSyncStateChanged];
 
-  ASSERT_TRUE([mediator_.consumer.tableViewModel
+  EXPECT_TRUE([mediator_.consumer.tableViewModel
       hasSectionForSectionIdentifier:SyncSettingsSectionIdentifier::
                                          SyncErrorsSectionIdentifier]);
   NSArray* error_items = [mediator_.consumer.tableViewModel
@@ -336,7 +335,7 @@
   ASSERT_EQ(1UL, error_items.count);
   SettingsImageDetailTextItem* error_item =
       base::mac::ObjCCastStrict<SettingsImageDetailTextItem>(error_items[0]);
-  ASSERT_NSEQ(
+  EXPECT_NSEQ(
       error_item.detailText,
       l10n_util::GetNSString(
           IDS_IOS_GOOGLE_SERVICES_SETTINGS_ENTER_PASSPHRASE_TO_START_SYNC));
@@ -353,11 +352,10 @@
 
   [mediator_ manageSyncSettingsTableViewControllerLoadModel:mediator_.consumer];
 
-  // "Turn off Sync" item is hidden.
-  NSArray* hidden_sign_out_items = [mediator_.consumer.tableViewModel
-      itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
-                                       SignOutSectionIdentifier];
-  ASSERT_EQ(0UL, hidden_sign_out_items.count);
+  // Sign out section not added.
+  EXPECT_FALSE([mediator_.consumer.tableViewModel
+      hasSectionForSectionIdentifier:SyncSettingsSectionIdentifier::
+                                         SignOutSectionIdentifier]);
 
   // Set Sync enabled expectations.
   FirstSetupSyncOnWithConsentEnabled();
@@ -371,7 +369,7 @@
   NSArray* shown_sign_out_items = [mediator_.consumer.tableViewModel
       itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
                                        SignOutSectionIdentifier];
-  ASSERT_EQ(1UL, shown_sign_out_items.count);
+  EXPECT_EQ(1UL, shown_sign_out_items.count);
 }
 
 // Tests Signout is shown when first setup is complete and sync engine is off.
@@ -387,7 +385,7 @@
   NSArray* hidden_sign_out_items = [mediator_.consumer.tableViewModel
       itemsInSectionWithIdentifier:SyncSettingsSectionIdentifier::
                                        SignOutSectionIdentifier];
-  ASSERT_EQ(1UL, hidden_sign_out_items.count);
+  EXPECT_EQ(1UL, hidden_sign_out_items.count);
 }
 
 // Tests data types are editable when first setup is complete and sync engine
@@ -407,9 +405,9 @@
     SyncSwitchItem* switch_item =
         base::mac::ObjCCastStrict<SyncSwitchItem>(item);
     if (switch_item.type == AutocompleteWalletItemType) {
-      ASSERT_FALSE(switch_item.enabled);
+      EXPECT_FALSE(switch_item.enabled);
     } else {
-      ASSERT_TRUE(switch_item.enabled);
+      EXPECT_TRUE(switch_item.enabled);
     }
   }
 }
@@ -434,19 +432,19 @@
       itemsInSectionWithIdentifier:SyncDataTypeSectionIdentifier];
   for (TableViewItem* item in items) {
     if (item.type == SyncEverythingItemType) {
-      ASSERT_FALSE([item isKindOfClass:[SyncSwitchItem class]]);
+      EXPECT_FALSE([item isKindOfClass:[SyncSwitchItem class]]);
       continue;
     } else if (item.type == BookmarksDataTypeItemType ||
                item.type == PasswordsDataTypeItemType) {
-      ASSERT_TRUE([item isKindOfClass:[TableViewInfoButtonItem class]]);
+      EXPECT_TRUE([item isKindOfClass:[TableViewInfoButtonItem class]]);
       continue;
     }
     SyncSwitchItem* switch_item =
         base::mac::ObjCCastStrict<SyncSwitchItem>(item);
     if (switch_item.type == AutocompleteWalletItemType) {
-      ASSERT_FALSE(switch_item.enabled);
+      EXPECT_FALSE(switch_item.enabled);
     } else {
-      ASSERT_TRUE(switch_item.enabled);
+      EXPECT_TRUE(switch_item.enabled);
     }
   }
 }
diff --git a/ios/chrome/browser/ui/settings/resources/BUILD.gn b/ios/chrome/browser/ui/settings/resources/BUILD.gn
index 24a63370..fafe555 100644
--- a/ios/chrome/browser/ui/settings/resources/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/resources/BUILD.gn
@@ -114,11 +114,21 @@
   ]
 }
 
+imageset("legacy_settings_passwords") {
+  sources = [
+    "legacy_settings_passwords.imageset/Contents.json",
+    "legacy_settings_passwords.imageset/settings_passwords@2x.png",
+    "legacy_settings_passwords.imageset/settings_passwords@3x.png",
+  ]
+}
+
 imageset("settings_passwords") {
   sources = [
     "settings_passwords.imageset/Contents.json",
     "settings_passwords.imageset/settings_passwords@2x.png",
     "settings_passwords.imageset/settings_passwords@3x.png",
+    "settings_passwords.imageset/settings_passwords_dark@2x.png",
+    "settings_passwords.imageset/settings_passwords_dark@3x.png",
   ]
 }
 
diff --git a/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/Contents.json b/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/Contents.json
new file mode 100644
index 0000000..b235aeb
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/Contents.json
@@ -0,0 +1,18 @@
+{
+    "images": [
+        {
+            "idiom": "universal",
+            "scale": "2x",
+            "filename": "settings_passwords@2x.png"
+        },
+        {
+            "idiom": "universal",
+            "scale": "3x",
+            "filename": "settings_passwords@3x.png"
+        }
+    ],
+    "info": {
+        "version": 1,
+        "author": "xcode"
+    }
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/settings_passwords@2x.png b/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/settings_passwords@2x.png
new file mode 100644
index 0000000..d22104c
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/settings_passwords@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/settings_passwords@3x.png b/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/settings_passwords@3x.png
new file mode 100644
index 0000000..6833196
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/resources/legacy_settings_passwords.imageset/settings_passwords@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json
index b235aeb..60d77c0 100644
--- a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json
+++ b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/Contents.json
@@ -1,18 +1,40 @@
 {
-    "images": [
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "settings_passwords@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "settings_passwords@3x.png",
+      "scale" : "3x"
+    },
+    {
+      "appearances" : [
         {
-            "idiom": "universal",
-            "scale": "2x",
-            "filename": "settings_passwords@2x.png"
-        },
-        {
-            "idiom": "universal",
-            "scale": "3x",
-            "filename": "settings_passwords@3x.png"
+          "appearance" : "luminosity",
+          "value" : "dark"
         }
-    ],
-    "info": {
-        "version": 1,
-        "author": "xcode"
+      ],
+      "idiom" : "universal",
+      "filename" : "settings_passwords_dark@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "appearances" : [
+        {
+          "appearance" : "luminosity",
+          "value" : "dark"
+        }
+      ],
+      "idiom" : "universal",
+      "filename" : "settings_passwords_dark@3x.png",
+      "scale" : "3x"
     }
-}
\ No newline at end of file
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@2x.png b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@2x.png
index d22104c..745707f 100644
--- a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@2x.png
+++ b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@3x.png b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@3x.png
index 6833196..9dd54c2 100644
--- a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@3x.png
+++ b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@2x.png b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@2x.png
new file mode 100644
index 0000000..2d16bd3e
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@2x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@3x.png b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@3x.png
new file mode 100644
index 0000000..3f2824cf
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/resources/settings_passwords.imageset/settings_passwords_dark@3x.png
Binary files differ
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index 529f579..08cbfa36 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -15,6 +15,7 @@
 #include "components/autofill/core/common/autofill_prefs.h"
 #include "components/keyed_service/core/service_access_type.h"
 #include "components/password_manager/core/browser/manage_passwords_referrer.h"
+#include "components/password_manager/core/common/password_manager_features.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #import "components/prefs/ios/pref_observer_bridge.h"
 #include "components/prefs/pref_member.h"
@@ -118,7 +119,9 @@
     @"sync_and_google_services_sync_on";
 NSString* const kSettingsGoogleServicesImageName = @"settings_google_services";
 NSString* const kSettingsSearchEngineImageName = @"settings_search_engine";
-NSString* const kSettingsPasswordsImageName = @"settings_passwords";
+NSString* const kLegacySettingsPasswordsImageName = @"legacy_settings_passwords";
+NSString* const kSettingsPasswordsImageName =
+    @"settings_passwords";
 NSString* const kSettingsAutofillCreditCardImageName =
     @"settings_payment_methods";
 NSString* const kSettingsAutofillProfileImageName = @"settings_addresses";
@@ -779,10 +782,13 @@
                                   : l10n_util::GetNSString(IDS_IOS_SETTING_OFF);
   _passwordsDetailItem =
       [self detailItemWithType:SettingsItemTypePasswords
-                             text:l10n_util::GetNSString(IDS_IOS_PASSWORDS)
-                       detailText:passwordsDetail
-                    iconImageName:kSettingsPasswordsImageName
-          accessibilityIdentifier:kSettingsPasswordsCellId];
+                          text:l10n_util::GetNSString(IDS_IOS_PASSWORDS)
+                    detailText:passwordsDetail
+                 iconImageName:(base::FeatureList::IsEnabled(
+                                                             password_manager::features::kIOSEnablePasswordManagerBrandingUpdate)
+                                    ? kSettingsPasswordsImageName
+                                    : kLegacySettingsPasswordsImageName)
+                 accessibilityIdentifier:kSettingsPasswordsCellId];
 
   return _passwordsDetailItem;
 }
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index b1316e1..42ce94f 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-65ef8e68bebef809d1dc428a52fe2ee81c921b51
\ No newline at end of file
+35ae9a6a21edaa6e789b6c8381ff549419efe3ca
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index 007f46ac..81d3e4d 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-3e65bf0882e346c03fd2e761278568d3ea7f6017
\ No newline at end of file
+3da474eff7c93813ce5ec381ba738b7b672daad8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 656255ab..5c33f14e 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-a7b93f80dd8def1ad5da5608fb7d4aee5dfc568d
\ No newline at end of file
+1ec1b84814ca25b494b6fe6e22429cd4db31eef8
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 60e880b..fd8641e2 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-9d4a276c9d7b00bcf2bf494887ce47f6a6d9061d
\ No newline at end of file
+40032b03cad83612c7c2053d2c3683d479aa5186
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
index 4934a4a..1b9e03c 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-efa910d796cfc9c513faf7dbd21da4cf90c19e58
\ No newline at end of file
+4c20e95f0572ee58cba7758ea16092f8d357e46e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
index b94abf1c..f4d94f8 100644
--- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-bb57108c7146a0faf22e9ca3caa853f32fe7656d
\ No newline at end of file
+f9bad5e4bbc107e57bf4a6c60257eb2296f15b63
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index 7daecc8ee..35f05dc1 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-02c8698543caa9098eb938a1e1690606ef1939c9
\ No newline at end of file
+342a6a1b151276533c8de2286aa90261e0116d21
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 021fd169..2720ea3 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-8faaf98f914c0f46e5969f96251df00c5ba26211
\ No newline at end of file
+b568103da8b5a6232052706009a30819fa22b8e9
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 05877d5..f07fbd7 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-eaa0c251530875e7051a413ef1503a1dd9f851b0
\ No newline at end of file
+298a7afc3c5d6d3be4d0e9d10838218b386bedaa
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index 035f5f2..f22f701a 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-f8d14045b7d643e0ed89b507efb9e5a0de1dda3c
\ No newline at end of file
+97604765973e01c32e6c3450f58d452db84e0d7f
\ No newline at end of file
diff --git a/net/cert/nss_cert_database_unittest.cc b/net/cert/nss_cert_database_unittest.cc
index 74c8c2273..eb191f3 100644
--- a/net/cert/nss_cert_database_unittest.cc
+++ b/net/cert/nss_cert_database_unittest.cc
@@ -543,12 +543,20 @@
   // All the certs in the imported list should now be found in the NSS DB.
   ScopedCERTCertificateList cert_list = ListCerts();
   ASSERT_EQ(3U, cert_list.size());
-  CERTCertificate* found_server_cert = cert_list[1].get();
-  CERTCertificate* found_intermediate_cert = cert_list[2].get();
-  CERTCertificate* found_root_cert = cert_list[0].get();
-  EXPECT_EQ("127.0.0.1", GetSubjectCN(found_server_cert));
-  EXPECT_EQ("Test Intermediate CA", GetSubjectCN(found_intermediate_cert));
-  EXPECT_EQ("Test Root CA", GetSubjectCN(found_root_cert));
+  CERTCertificate* found_server_cert = nullptr;
+  CERTCertificate* found_intermediate_cert = nullptr;
+  CERTCertificate* found_root_cert = nullptr;
+  for (const auto& cert : cert_list) {
+    if (GetSubjectCN(cert.get()) == "127.0.0.1")
+      found_server_cert = cert.get();
+    else if (GetSubjectCN(cert.get()) == "Test Intermediate CA")
+      found_intermediate_cert = cert.get();
+    else if (GetSubjectCN(cert.get()) == "Test Root CA")
+      found_root_cert = cert.get();
+  }
+  ASSERT_TRUE(found_server_cert);
+  ASSERT_TRUE(found_intermediate_cert);
+  ASSERT_TRUE(found_root_cert);
 
   EXPECT_EQ(NSSCertDatabase::TRUST_DEFAULT,
             cert_db_->GetCertTrust(found_server_cert, SERVER_CERT));
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index 57d284e..174aae7 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -1319,7 +1319,8 @@
   EXPECT_EQ(GURL(kExpectCTStaticReportURI), reporter.report_uri());
   EXPECT_EQ(cert1.get(), reporter.served_certificate_chain());
   EXPECT_EQ(cert2.get(), reporter.validated_certificate_chain());
-  EXPECT_EQ(ssl_info.signed_certificate_timestamps.size(),
+  ASSERT_EQ(1u, ssl_info.signed_certificate_timestamps.size());
+  ASSERT_EQ(ssl_info.signed_certificate_timestamps.size(),
             reporter.signed_certificate_timestamps().size());
   EXPECT_EQ(ssl_info.signed_certificate_timestamps[0].status,
             reporter.signed_certificate_timestamps()[0].status);
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index d7d8f0a..81064617 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -668,6 +668,25 @@
   SSLInfo ssl_info_;
 };
 
+#if !defined(OS_IOS)
+// Compute the root cert's SPKI hash on the fly, to avoid hardcoding it within
+// tests.
+bool GetTestRootCertSPKIHash(SHA256HashValue* root_hash) {
+  scoped_refptr<X509Certificate> root_cert =
+      ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
+  if (!root_cert)
+    return false;
+  base::StringPiece root_spki;
+  if (!asn1::ExtractSPKIFromDERCert(
+          x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()),
+          &root_spki)) {
+    return false;
+  }
+  crypto::SHA256HashString(root_spki, root_hash, sizeof(SHA256HashValue));
+  return true;
+}
+#endif
+
 }  // namespace
 
 // Inherit PlatformTest since we require the autorelease pool on Mac OS X.
@@ -10691,22 +10710,6 @@
   TestURLRequestContext context_;
 };
 
-// SHA256 hash of the testserver root_ca_cert DER.
-// openssl x509 -in root_ca_cert.pem -outform der | \
-//   openssl dgst -sha256 -binary | xxd -i
-static const SHA256HashValue kTestRootCertHash = {
-    {0xb2, 0xab, 0xa3, 0xa5, 0xd4, 0x11, 0x56, 0xcb, 0xb9, 0x23, 0x35,
-     0x07, 0x6d, 0x0b, 0x51, 0xbe, 0xd3, 0xee, 0x2e, 0xab, 0xe7, 0xab,
-     0x6b, 0xad, 0xcc, 0x2a, 0xfa, 0x35, 0xfb, 0x8e, 0x31, 0x5e}};
-
-// SHA256 hash of the DER SPKI of the testserver root_ca_cert.
-// openssl x509 -in root_ca_cert.pem -pubkey -noout | \
-//   openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | xxd -i
-static const SHA256HashValue kTestRootCertSPKIHash = {
-    {0x57, 0x2a, 0x4f, 0xdd, 0x55, 0x8b, 0xec, 0xe6, 0xaa, 0x4c, 0x9e,
-     0xe6, 0x20, 0x17, 0xa1, 0x59, 0x89, 0x6f, 0xf2, 0x48, 0x4f, 0xb8,
-     0x51, 0xe9, 0x5a, 0x27, 0x9a, 0xad, 0x92, 0x36, 0x62, 0x32}};
-
 // The test EV policy OID used for generated certs.
 static const char kOCSPTestCertPolicy[] = "1.3.6.1.4.1.11129.2.4.1";
 
@@ -10715,8 +10718,13 @@
   void SetUp() override {
     HTTPSCertNetFetchingTest::SetUp();
 
+    scoped_refptr<X509Certificate> root_cert =
+        ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
+    ASSERT_TRUE(root_cert);
+
     ev_test_policy_ = std::make_unique<ScopedTestEVPolicy>(
-        EVRootCAMetadata::GetInstance(), kTestRootCertHash,
+        EVRootCAMetadata::GetInstance(),
+        X509Certificate::CalculateFingerprint256(root_cert->cert_buffer()),
         kOCSPTestCertPolicy);
   }
 
@@ -11546,8 +11554,10 @@
       EmbeddedTestServer::OCSPConfig::ResponseType::kInvalidResponse);
 
   CertVerifier::Config cert_verifier_config = GetCertVerifierConfig();
+  SHA256HashValue root_cert_spki_hash;
+  ASSERT_TRUE(GetTestRootCertSPKIHash(&root_cert_spki_hash));
   cert_verifier_config.crl_set =
-      CRLSet::ForTesting(false, &kTestRootCertSPKIHash, "", "", {});
+      CRLSet::ForTesting(false, &root_cert_spki_hash, "", "", {});
   context_.cert_verifier()->SetConfig(cert_verifier_config);
 
   CertStatus cert_status;
@@ -11654,8 +11664,10 @@
   ASSERT_TRUE(test_server.Start());
 
   CertVerifier::Config cert_verifier_config = GetCertVerifierConfig();
+  SHA256HashValue root_cert_spki_hash;
+  ASSERT_TRUE(GetTestRootCertSPKIHash(&root_cert_spki_hash));
   cert_verifier_config.crl_set =
-      CRLSet::ForTesting(false, &kTestRootCertSPKIHash,
+      CRLSet::ForTesting(false, &root_cert_spki_hash,
                          test_server.GetCertificate()->serial_number(), "", {});
   context_.cert_verifier()->SetConfig(cert_verifier_config);
 
@@ -11879,17 +11891,8 @@
 
   // Configure for kHSTSSubdomainWithKnownInterception
   CertVerifyResult sts_sub_result = fake_result;
-  // Compute the root cert's hash on the fly, to avoid hardcoding it within
-  // tests.
-  scoped_refptr<X509Certificate> root_cert =
-      ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem");
-  ASSERT_TRUE(root_cert);
-  base::StringPiece root_spki;
-  ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(
-      x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()),
-      &root_spki));
   SHA256HashValue root_hash;
-  crypto::SHA256HashString(root_spki, &root_hash, sizeof(root_hash));
+  ASSERT_TRUE(GetTestRootCertSPKIHash(&root_hash));
   sts_sub_result.public_key_hashes.push_back(HashValue(root_hash));
   sts_sub_result.cert_status |=
       CERT_STATUS_REVOKED | CERT_STATUS_KNOWN_INTERCEPTION_BLOCKED;
diff --git a/pdf/pdf_view_plugin_base.cc b/pdf/pdf_view_plugin_base.cc
index 66511ff9..fc8ed98 100644
--- a/pdf/pdf_view_plugin_base.cc
+++ b/pdf/pdf_view_plugin_base.cc
@@ -970,7 +970,23 @@
     background_parts_.push_back(part);
 }
 
-void PdfViewPluginBase::UpdateScroll(const gfx::Vector2dF& scroll_offset) {
+gfx::PointF PdfViewPluginBase::GetScrollPositionFromOffset(
+    const gfx::Vector2dF& scroll_offset) const {
+  gfx::PointF scroll_origin;
+
+  // TODO(crbug.com/1140374): Right-to-left scrolling currently is not
+  // compatible with the PDF viewer's sticky "scroller" element.
+  if (ui_direction_ == base::i18n::RIGHT_TO_LEFT && IsPrintPreview()) {
+    scroll_origin.set_x(
+        std::max(document_size_.width() * static_cast<float>(zoom_) -
+                     plugin_dip_size_.width(),
+                 0.0f));
+  }
+
+  return scroll_origin + scroll_offset;
+}
+
+void PdfViewPluginBase::UpdateScroll(const gfx::PointF& scroll_position) {
   if (stop_scrolling_)
     return;
 
@@ -981,13 +997,6 @@
                              plugin_dip_size_.height(),
                          0.0f);
 
-  // TODO(crbug.com/1256965): Right-to-left scrolling currently is not
-  // compatible with the PDF viewer's "scroller" element.
-  gfx::PointF scroll_position;
-  if (ui_direction_ == base::i18n::RIGHT_TO_LEFT && IsPrintPreview())
-    scroll_position.set_x(max_x);
-  scroll_position += scroll_offset;
-
   gfx::PointF scaled_scroll_position(
       base::clamp(scroll_position.x(), 0.0f, max_x),
       base::clamp(scroll_position.y(), 0.0f, max_y));
@@ -1282,8 +1291,8 @@
 }
 
 void PdfViewPluginBase::HandleUpdateScrollMessage(const base::Value& message) {
-  UpdateScroll(gfx::Vector2dF(message.FindDoubleKey("x").value(),
-                              message.FindDoubleKey("y").value()));
+  UpdateScroll(GetScrollPositionFromOffset(gfx::Vector2dF(
+      message.FindDoubleKey("x").value(), message.FindDoubleKey("y").value())));
 }
 
 void PdfViewPluginBase::HandleViewportMessage(const base::Value& message) {
@@ -1403,7 +1412,7 @@
   DCHECK(message.FindBoolKey("userInitiated").has_value());
 
   SetZoom(new_zoom);
-  UpdateScroll(scroll_offset);
+  UpdateScroll(GetScrollPositionFromOffset(scroll_offset));
 }
 
 void PdfViewPluginBase::DidStartLoading() {
diff --git a/pdf/pdf_view_plugin_base.h b/pdf/pdf_view_plugin_base.h
index d07466a..8a3627f 100644
--- a/pdf/pdf_view_plugin_base.h
+++ b/pdf/pdf_view_plugin_base.h
@@ -287,9 +287,9 @@
   // aren't painted by the PDF engine).
   void CalculateBackgroundParts();
 
-  // Updates the scroll position. `scroll_offset` is in CSS pixels relative to
-  // the scroll origin (which depends on the UI direction).
-  void UpdateScroll(const gfx::Vector2dF& scroll_offset);
+  // Updates the scroll position, which is in CSS pixels relative to the
+  // top-left corner.
+  void UpdateScroll(const gfx::PointF& scroll_position);
 
   // Computes document width/height in device pixels, based on current zoom and
   // device scale
@@ -424,6 +424,12 @@
   static base::Value::DictStorage DictFromRect(const gfx::Rect& rect);
 
  private:
+  // Converts a scroll offset (which is relative to a UI direction-dependent
+  // scroll origin) to a scroll position (which is always relative to the
+  // top-left corner).
+  gfx::PointF GetScrollPositionFromOffset(
+      const gfx::Vector2dF& scroll_offset) const;
+
   // Message handlers.
   void HandleDisplayAnnotationsMessage(const base::Value& message);
   void HandleGetNamedDestinationMessage(const base::Value& message);
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index 2260b3f1..707f4d17 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -175,6 +175,9 @@
     "//mojo/public/cpp/platform",
     "//remoting/host/mojom",
   ]
+  if (is_win) {
+    deps += [ "//remoting/host/win:acl_util" ]
+  }
 }
 
 # Split up from common to avoid circular dependency.
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc
index 11e37162..5bf16f8 100644
--- a/remoting/host/chromoting_host.cc
+++ b/remoting/host/chromoting_host.cc
@@ -31,6 +31,10 @@
 #include "remoting/protocol/transport_context.h"
 #include "remoting/protocol/webrtc_connection_to_client.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
 using remoting::protocol::ConnectionToClient;
 using remoting::protocol::InputStub;
 
@@ -120,10 +124,14 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!ipc_server_);
 
+#if defined(OS_LINUX) || defined(OS_WIN)
   ipc_server_ = std::make_unique<MojoIpcServer<mojom::ChromotingHostServices>>(
       GetChromotingHostServicesServerName(), this);
   ipc_server_->StartServer();
   HOST_LOG << "ChromotingHostServices IPC server has been started.";
+#else
+  NOTIMPLEMENTED();
+#endif
 }
 
 void ChromotingHost::AddExtension(std::unique_ptr<HostExtension> extension) {
@@ -226,16 +234,34 @@
     observer.OnClientRouteChange(session->client_jid(), channel_name, route);
 }
 
-void ChromotingHost::BindWebAuthnProxy(
-    mojo::PendingReceiver<mojom::WebAuthnProxy> receiver) {
+void ChromotingHost::BindSessionServices(
+    mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   ClientSession* connected_client = GetConnectedClientSession();
   if (!connected_client) {
-    LOG(WARNING) << "No connected client is found. Binding request rejected.";
+    LOG(WARNING) << "Session services bind request rejected: "
+                 << "No connected remote desktop client was found.";
     return;
   }
-  connected_client->BindWebAuthnProxy(std::move(receiver));
+#if defined(OS_WIN)
+  DWORD peer_session_id;
+  if (!ProcessIdToSessionId(ipc_server_->current_peer_pid(),
+                            &peer_session_id)) {
+    PLOG(ERROR) << "Session services bind request rejected: "
+                   "ProcessIdToSessionId failed";
+    return;
+  }
+  if (connected_client->desktop_session_id() != peer_session_id) {
+    LOG(WARNING)
+        << "Session services bind request rejected: "
+        << "Remote desktop client is not connected to the current session.";
+    return;
+  }
+#endif
+  connected_client->BindReceiver(std::move(receiver));
+  VLOG(1) << "Session services bound for receiver ID: "
+          << ipc_server_->current_receiver();
 }
 
 void ChromotingHost::OnIncomingSession(
diff --git a/remoting/host/chromoting_host.h b/remoting/host/chromoting_host.h
index 1fbce22..963f69a 100644
--- a/remoting/host/chromoting_host.h
+++ b/remoting/host/chromoting_host.h
@@ -14,6 +14,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/threading/thread.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/base/backoff_entry.h"
 #include "remoting/host/client_session.h"
 #include "remoting/host/desktop_environment_options.h"
@@ -127,8 +128,9 @@
                             const protocol::TransportRoute& route) override;
 
   // mojom::ChromotingHostServices implementation.
-  void BindWebAuthnProxy(
-      mojo::PendingReceiver<mojom::WebAuthnProxy> receiver) override;
+  void BindSessionServices(
+      mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver)
+      override;
 
   // Callback for SessionManager to accept incoming sessions.
   void OnIncomingSession(
diff --git a/remoting/host/chromoting_host_services_client.cc b/remoting/host/chromoting_host_services_client.cc
index 6f6e687..35a0f5d 100644
--- a/remoting/host/chromoting_host_services_client.cc
+++ b/remoting/host/chromoting_host_services_client.cc
@@ -5,29 +5,70 @@
 #include "remoting/host/chromoting_host_services_client.h"
 
 #include "base/bind.h"
+#include "base/environment.h"
+#include "base/notreached.h"
 #include "base/sequence_checker.h"
+#include "build/build_config.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/system/isolated_connection.h"
 #include "remoting/host/ipc_constants.h"
 #include "remoting/host/mojom/chromoting_host_services.mojom.h"
 
+#if defined(OS_WIN)
+#include <windows.h>
+
+#include "remoting/host/win/acl_util.h"
+#endif
+
 namespace remoting {
 
+namespace {
+
+#if defined(OS_LINUX)
+constexpr char kChromeRemoteDesktopSessionEnvVar[] =
+    "CHROME_REMOTE_DESKTOP_SESSION";
+#endif
+
+bool g_initialized = false;
+
+}  // namespace
+
 ChromotingHostServicesClient::ChromotingHostServicesClient()
-    : server_name_(GetChromotingHostServicesServerName()) {}
+    : environment_(base::Environment::Create()),
+      server_name_(GetChromotingHostServicesServerName()) {
+  DCHECK(g_initialized)
+      << "ChromotingHostServicesClient::Initialize() has not been called.";
+}
 
 ChromotingHostServicesClient::~ChromotingHostServicesClient() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-mojom::ChromotingHostServices* ChromotingHostServicesClient::Get() const {
+// static
+bool ChromotingHostServicesClient::Initialize() {
+  DCHECK(!g_initialized);
+#if defined(OS_WIN)
+  // The ChromotingHostServices server runs under the LocalService account,
+  // which normally isn't allowed to query process info like session ID of a
+  // process running under a different account, so we add an ACL to allow it.
+  g_initialized = AddProcessAccessRightForWellKnownSid(
+      WinLocalServiceSid, PROCESS_QUERY_LIMITED_INFORMATION);
+#else
+  // Other platforms don't need initialization.
+  g_initialized = true;
+#endif
+  return g_initialized;
+}
+
+mojom::ChromotingSessionServices*
+ChromotingHostServicesClient::GetSessionServices() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  if (!const_cast<ChromotingHostServicesClient*>(this)->EnsureConnection()) {
+  if (!const_cast<ChromotingHostServicesClient*>(this)
+           ->EnsureSessionServicesBinding()) {
     return nullptr;
   }
-
-  return remote_.get();
+  return session_services_remote_.get();
 }
 
 bool ChromotingHostServicesClient::EnsureConnection() {
@@ -57,6 +98,27 @@
   return true;
 }
 
+bool ChromotingHostServicesClient::EnsureSessionServicesBinding() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (session_services_remote_.is_bound()) {
+    return true;
+  }
+#if defined(OS_LINUX)
+  if (!environment_->HasVar(kChromeRemoteDesktopSessionEnvVar)) {
+    LOG(WARNING) << "Current desktop environment is not remotable.";
+    return false;
+  }
+#endif
+  if (!EnsureConnection()) {
+    return false;
+  }
+  remote_->BindSessionServices(
+      session_services_remote_.BindNewPipeAndPassReceiver());
+  session_services_remote_.reset_on_disconnect();
+  return true;
+}
+
 void ChromotingHostServicesClient::OnDisconnected() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
diff --git a/remoting/host/chromoting_host_services_client.h b/remoting/host/chromoting_host_services_client.h
index 9c2a922..ca2173f 100644
--- a/remoting/host/chromoting_host_services_client.h
+++ b/remoting/host/chromoting_host_services_client.h
@@ -13,6 +13,10 @@
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 #include "remoting/host/mojom/chromoting_host_services.mojom.h"
 
+namespace base {
+class Environment;
+}  // namespace base
+
 namespace mojo {
 class IsolatedConnection;
 }  // namespace mojo
@@ -31,9 +35,18 @@
       delete;
   ~ChromotingHostServicesClient();
 
-  // Gets the ChromotingHostServices. Always null-check before using it, as
-  // nullptr will be returned if the connection has failed to make.
-  mojom::ChromotingHostServices* Get() const;
+  // Configures the current process to allow it to communicate with the
+  // ChromotingHostServices server. Must be called once before using any
+  // instance of ChromotingHostServicesClient.
+  // Returns a boolean that indicates whether the initialization succeeded.
+  static bool Initialize();
+
+  // Gets the ChromotingSessionServices. Always null-check before using it, as
+  // nullptr will be returned if the connection could not be established.
+  // Note that when the session is not remoted, you will still get a callable
+  // interface, but all outgoing IPCs will be silently dropped, and any pending
+  // receivers/remotes/message pipes sent will be closed.
+  mojom::ChromotingSessionServices* GetSessionServices() const;
 
  private:
   // Attempts to connect to the IPC server if the connection has not been
@@ -41,15 +54,20 @@
   // connection to the chromoting host.
   bool EnsureConnection();
 
+  bool EnsureSessionServicesBinding();
+
   void OnDisconnected();
 
   SEQUENCE_CHECKER(sequence_checker_);
 
+  std::unique_ptr<base::Environment> environment_;
   mojo::NamedPlatformChannel::ServerName server_name_;
   std::unique_ptr<mojo::IsolatedConnection> connection_
       GUARDED_BY_CONTEXT(sequence_checker_);
   mojo::Remote<mojom::ChromotingHostServices> remote_
       GUARDED_BY_CONTEXT(sequence_checker_);
+  mojo::Remote<mojom::ChromotingSessionServices> session_services_remote_
+      GUARDED_BY_CONTEXT(sequence_checker_);
 };
 
 }  // namespace remoting
diff --git a/remoting/host/client_session.cc b/remoting/host/client_session.cc
index 80ad568e..3b93e81 100644
--- a/remoting/host/client_session.cc
+++ b/remoting/host/client_session.cc
@@ -633,6 +633,13 @@
     desktop_and_cursor_composer_->SetMouseCursorPosition(position);
 }
 
+void ClientSession::BindReceiver(
+    mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  session_services_receivers_.Add(this, std::move(receiver));
+}
+
 void ClientSession::BindWebAuthnProxy(
     mojo::PendingReceiver<mojom::WebAuthnProxy> receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/remoting/host/client_session.h b/remoting/host/client_session.h
index 28d2f5f..ca7d17b 100644
--- a/remoting/host/client_session.h
+++ b/remoting/host/client_session.h
@@ -17,6 +17,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "remoting/host/client_session_control.h"
 #include "remoting/host/client_session_details.h"
 #include "remoting/host/desktop_and_cursor_composer_notifier.h"
@@ -25,6 +26,7 @@
 #include "remoting/host/desktop_environment_options.h"
 #include "remoting/host/host_experiment_session_plugin.h"
 #include "remoting/host/host_extension_session_manager.h"
+#include "remoting/host/mojom/chromoting_host_services.mojom.h"
 #include "remoting/host/mojom/webauthn_proxy.mojom.h"
 #include "remoting/host/remote_input_filter.h"
 #include "remoting/proto/action.pb.h"
@@ -70,7 +72,8 @@
                       public ClientSessionControl,
                       public ClientSessionDetails,
                       public DesktopAndCursorComposerNotifier::EventHandler,
-                      public webrtc::MouseCursorMonitor::Callback {
+                      public webrtc::MouseCursorMonitor::Callback,
+                      public mojom::ChromotingSessionServices {
  public:
   // Callback interface for passing events to the ChromotingHost.
   class EventHandler {
@@ -170,7 +173,12 @@
   void OnMouseCursor(webrtc::MouseCursor* mouse_cursor) override;
   void OnMouseCursorPosition(const webrtc::DesktopVector& position) override;
 
-  void BindWebAuthnProxy(mojo::PendingReceiver<mojom::WebAuthnProxy> receiver);
+  // mojom::ChromotingSessionServices implementation.
+  void BindWebAuthnProxy(
+      mojo::PendingReceiver<mojom::WebAuthnProxy> receiver) override;
+
+  void BindReceiver(
+      mojo::PendingReceiver<mojom::ChromotingSessionServices> receiver);
 
   protocol::ConnectionToClient* connection() const { return connection_.get(); }
 
@@ -372,6 +380,9 @@
 
   base::WeakPtr<RemoteWebAuthnMessageHandler> remote_webauthn_message_handler_;
 
+  mojo::ReceiverSet<mojom::ChromotingSessionServices>
+      session_services_receivers_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Used to disable callbacks to |this| once DisconnectSession() has been
diff --git a/remoting/host/mojo_ipc/BUILD.gn b/remoting/host/mojo_ipc/BUILD.gn
index 4d5a905..f5d62b8 100644
--- a/remoting/host/mojo_ipc/BUILD.gn
+++ b/remoting/host/mojo_ipc/BUILD.gn
@@ -9,7 +9,21 @@
     "mojo_ipc_server.h",
     "mojo_ipc_util.cc",
     "mojo_ipc_util.h",
+    "mojo_server_endpoint_connector.h",
   ]
+  if (is_linux) {
+    sources += [
+      "mojo_server_endpoint_connector_linux.cc",
+      "mojo_server_endpoint_connector_linux.h",
+    ]
+  } else if (is_win) {
+    sources += [
+      "mojo_server_endpoint_connector_win.cc",
+      "mojo_server_endpoint_connector_win.h",
+    ]
+  } else {
+    sources += [ "mojo_server_endpoint_connector_unsupported.cc" ]
+  }
   deps = [
     "//base",
     "//mojo/public/cpp/bindings",
@@ -37,7 +51,12 @@
 source_set("unit_tests") {
   testonly = true
 
-  sources = [ "mojo_ipc_server_unittest.cc" ]
+  sources = []
+
+  # Disable MojoIpcServerTest on unsupported platforms (i.e. Mac).
+  if (is_linux || is_win) {
+    sources += [ "mojo_ipc_server_unittest.cc" ]
+  }
   deps = [
     ":mojo_ipc",
     ":test_support",
diff --git a/remoting/host/mojo_ipc/fake_ipc_server.cc b/remoting/host/mojo_ipc/fake_ipc_server.cc
index c6d045e..800e23be 100644
--- a/remoting/host/mojo_ipc/fake_ipc_server.cc
+++ b/remoting/host/mojo_ipc/fake_ipc_server.cc
@@ -34,4 +34,8 @@
   return test_state_->current_receiver;
 }
 
+base::ProcessId FakeIpcServer::current_peer_pid() const {
+  return test_state_->current_peer_pid;
+}
+
 }  // namespace remoting
diff --git a/remoting/host/mojo_ipc/fake_ipc_server.h b/remoting/host/mojo_ipc/fake_ipc_server.h
index 538f83a..47c6fd4 100644
--- a/remoting/host/mojo_ipc/fake_ipc_server.h
+++ b/remoting/host/mojo_ipc/fake_ipc_server.h
@@ -21,6 +21,7 @@
     base::RepeatingClosure disconnect_handler;
     mojo::ReceiverId current_receiver = 0u;
     mojo::ReceiverId last_closed_receiver = 0u;
+    int32_t current_peer_pid = 0;
   };
 
   explicit FakeIpcServer(TestState* test_state);
@@ -33,6 +34,7 @@
   void Close(mojo::ReceiverId id) override;
   void set_disconnect_handler(base::RepeatingClosure handler) override;
   mojo::ReceiverId current_receiver() const override;
+  base::ProcessId current_peer_pid() const override;
 
  private:
   raw_ptr<TestState> test_state_;
diff --git a/remoting/host/mojo_ipc/ipc_server.h b/remoting/host/mojo_ipc/ipc_server.h
index bc860d04..f161cb4 100644
--- a/remoting/host/mojo_ipc/ipc_server.h
+++ b/remoting/host/mojo_ipc/ipc_server.h
@@ -6,6 +6,7 @@
 #define REMOTING_HOST_MOJO_IPC_IPC_SERVER_H_
 
 #include "base/callback.h"
+#include "base/process/process_handle.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 
 namespace remoting {
@@ -35,6 +36,9 @@
   // Call this method to learn which receiver has received the incoming IPC or
   // which receiver is being disconnected.
   virtual mojo::ReceiverId current_receiver() const = 0;
+
+  // Call this method to learn the peer process' PID.
+  virtual base::ProcessId current_peer_pid() const = 0;
 };
 
 }  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_ipc_server.cc b/remoting/host/mojo_ipc/mojo_ipc_server.cc
index bce35da..0c1bd22 100644
--- a/remoting/host/mojo_ipc/mojo_ipc_server.cc
+++ b/remoting/host/mojo_ipc/mojo_ipc_server.cc
@@ -8,11 +8,13 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/location.h"
 #include "base/logging.h"
-#include "base/process/process_handle.h"
+#include "base/notreached.h"
 #include "base/task/thread_pool.h"
+#include "base/time/time.h"
 #include "build/build_config.h"
-#include "mojo/public/cpp/system/isolated_connection.h"
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector.h"
 
 #if defined(OS_WIN)
 #include "base/strings/stringprintf.h"
@@ -21,19 +23,13 @@
 
 namespace remoting {
 
-struct MojoIpcServerBase::PendingConnection {
-  std::unique_ptr<mojo::IsolatedConnection> connection;
-  mojo::ScopedMessagePipeHandle message_pipe;
-};
-
 namespace {
 
-// Sends an invitation and returns the PendingReceiver. Must be called on an
-// IO sequence.
-// Note that this function won't wait for the other end to accept the
-// invitation, even though it makes some blocking API calls.
-std::unique_ptr<MojoIpcServerBase::PendingConnection>
-SendInvitationOnIoSequence(
+// Delay to throttle resending invitations when there is a recurring error.
+// TODO(yuweih): Implement backoff.
+base::TimeDelta kResentInvitationOnErrorDelay = base::Seconds(5);
+
+mojo::PlatformChannelServerEndpoint CreateServerEndpointOnIoSequence(
     const mojo::NamedPlatformChannel::ServerName& server_name) {
   mojo::NamedPlatformChannel::Options options;
   options.server_name = server_name;
@@ -47,29 +43,14 @@
   std::wstring user_sid;
   if (!base::win::GetUserSidString(&user_sid)) {
     LOG(ERROR) << "Failed to get user SID string.";
-    return nullptr;
+    return mojo::PlatformChannelServerEndpoint();
   }
   options.security_descriptor = base::StringPrintf(
       L"O:%lsG:%lsD:(A;;GA;;;AU)", user_sid.c_str(), user_sid.c_str());
 #endif  // defined(OS_WIN)
 
   mojo::NamedPlatformChannel channel(options);
-  auto server_endpoint = channel.TakeServerEndpoint();
-  if (!server_endpoint.is_valid()) {
-    LOG(ERROR) << "Failed to send mojo invitation: Invalid server endpoint.";
-    return nullptr;
-  }
-
-  auto pending_connection =
-      std::make_unique<MojoIpcServerBase::PendingConnection>();
-  pending_connection->connection = std::make_unique<mojo::IsolatedConnection>();
-  pending_connection->message_pipe =
-      pending_connection->connection->Connect(std::move(server_endpoint));
-  if (!pending_connection->message_pipe.is_valid()) {
-    LOG(ERROR) << "Message pipe is invalid.";
-    return nullptr;
-  }
-  return pending_connection;
+  return channel.TakeServerEndpoint();
 }
 
 }  // namespace
@@ -77,8 +58,7 @@
 MojoIpcServerBase::MojoIpcServerBase(
     const mojo::NamedPlatformChannel::ServerName& server_name)
     : server_name_(server_name),
-      pending_message_pipe_watcher_(FROM_HERE,
-                                    mojo::SimpleWatcher::ArmingPolicy::MANUAL) {
+      endpoint_connector_(MojoServerEndpointConnector::Create(this)) {
   io_sequence_ =
       base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()});
 }
@@ -118,11 +98,11 @@
 
 void MojoIpcServerBase::SendInvitation() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!pending_message_pipe_watcher_.IsWatching());
 
   io_sequence_->PostTaskAndReplyWithResult(
-      FROM_HERE, base::BindOnce(&SendInvitationOnIoSequence, server_name_),
-      base::BindOnce(&MojoIpcServerBase::OnInvitationSent,
+      FROM_HERE,
+      base::BindOnce(&CreateServerEndpointOnIoSequence, server_name_),
+      base::BindOnce(&MojoIpcServerBase::OnServerEndpointCreated,
                      weak_factory_.GetWeakPtr()));
 }
 
@@ -133,61 +113,32 @@
   Close(current_receiver());
 }
 
-void MojoIpcServerBase::OnInvitationSent(
-    std::unique_ptr<MojoIpcServerBase::PendingConnection> pending_connection) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(!pending_message_pipe_watcher_.IsWatching());
-  DCHECK(!pending_connection_);
-
-  if (!pending_connection) {
-    LOG(ERROR) << "Connection failed.";
-    return;
-  }
-
-  pending_connection_ = std::move(pending_connection);
-
+void MojoIpcServerBase::OnServerEndpointCreated(
+    mojo::PlatformChannelServerEndpoint endpoint) {
   if (on_invitation_sent_callback_for_testing_) {
     on_invitation_sent_callback_for_testing_.Run();
   }
-
-  pending_message_pipe_watcher_.Watch(
-      pending_connection_->message_pipe.get(), MOJO_HANDLE_SIGNAL_READABLE,
-      MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
-      base::BindRepeating(&MojoIpcServerBase::OnMessagePipeReady,
-                          weak_factory_.GetWeakPtr()));
-  pending_message_pipe_watcher_.ArmOrNotify();
+  if (!endpoint.is_valid()) {
+    OnServerEndpointConnectionFailed();
+    return;
+  }
+  endpoint_connector_->Connect(std::move(endpoint));
 }
 
-void MojoIpcServerBase::OnMessagePipeReady(
-    MojoResult result,
-    const mojo::HandleSignalsState& state) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+void MojoIpcServerBase::OnServerEndpointConnected(
+    std::unique_ptr<mojo::IsolatedConnection> connection,
+    mojo::ScopedMessagePipeHandle message_pipe,
+    base::ProcessId peer_pid) {
+  auto receiver_id = TrackMessagePipe(std::move(message_pipe), peer_pid);
+  active_connections_[receiver_id] = std::move(connection);
 
-  pending_message_pipe_watcher_.Cancel();
-  if (result == MOJO_RESULT_FAILED_PRECONDITION) {
-    LOG(WARNING) << "The message pipe will never become ready.";
-    pending_connection_.reset();
-    SendInvitation();
-    return;
-  }
-  if (result != MOJO_RESULT_OK) {
-    LOG(ERROR) << "Unexpected message pipe result: " << result;
-    pending_connection_.reset();
-    return;
-  }
-  if (state.peer_closed()) {
-    LOG(ERROR) << "Message pipe is closed.";
-    pending_connection_.reset();
-    SendInvitation();
-    return;
-  }
-
-  DCHECK(pending_connection_->message_pipe.is_valid());
-  auto receiver_id =
-      TrackMessagePipe(std::move(pending_connection_->message_pipe));
-  active_connections_[receiver_id] = std::move(pending_connection_->connection);
-  pending_connection_.reset();
   SendInvitation();
 }
 
+void MojoIpcServerBase::OnServerEndpointConnectionFailed() {
+  resent_invitation_on_error_timer_.Start(FROM_HERE,
+                                          kResentInvitationOnErrorDelay, this,
+                                          &MojoIpcServerBase::SendInvitation);
+}
+
 }  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_ipc_server.h b/remoting/host/mojo_ipc/mojo_ipc_server.h
index 12a9dab..a24e94db 100644
--- a/remoting/host/mojo_ipc/mojo_ipc_server.h
+++ b/remoting/host/mojo_ipc/mojo_ipc_server.h
@@ -13,14 +13,18 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/process/process_handle.h"
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
+#include "base/timer/timer.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
+#include "mojo/public/cpp/platform/platform_channel_server_endpoint.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
 #include "remoting/host/mojo_ipc/ipc_server.h"
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector.h"
 
 namespace mojo {
 class IsolatedConnection;
@@ -30,7 +34,8 @@
 
 // Template-less base class to keep implementations in the .cc file. For usage,
 // see MojoIpcServer.
-class MojoIpcServerBase : public IpcServer {
+class MojoIpcServerBase : public IpcServer,
+                          public MojoServerEndpointConnector::Delegate {
  public:
   // Internal use only.
   struct PendingConnection;
@@ -60,7 +65,8 @@
   void OnIpcDisconnected();
 
   virtual mojo::ReceiverId TrackMessagePipe(
-      mojo::ScopedMessagePipeHandle message_pipe) = 0;
+      mojo::ScopedMessagePipeHandle message_pipe,
+      base::ProcessId peer_pid) = 0;
 
   virtual void UntrackMessagePipe(mojo::ReceiverId id) = 0;
 
@@ -71,15 +77,19 @@
   base::RepeatingClosure disconnect_handler_;
 
  private:
+  void OnServerEndpointCreated(mojo::PlatformChannelServerEndpoint endpoint);
+
+  // MojoServerEndpointConnector::Delegate implementation.
+  void OnServerEndpointConnected(
+      std::unique_ptr<mojo::IsolatedConnection> connection,
+      mojo::ScopedMessagePipeHandle message_pipe,
+      base::ProcessId peer_pid) override;
+  void OnServerEndpointConnectionFailed() override;
+
   using ActiveConnectionMap =
       base::flat_map<mojo::ReceiverId,
                      std::unique_ptr<mojo::IsolatedConnection>>;
 
-  void OnInvitationSent(
-      std::unique_ptr<MojoIpcServerBase::PendingConnection> pending_connection);
-  void OnMessagePipeReady(MojoResult result,
-                          const mojo::HandleSignalsState& state);
-
   mojo::NamedPlatformChannel::ServerName server_name_;
 
   bool server_started_ = false;
@@ -87,10 +97,9 @@
   // A task runner to run blocking jobs.
   scoped_refptr<base::SequencedTaskRunner> io_sequence_;
 
-  // The message pipe will be "pending" until a client accepts the invitation.
-  mojo::SimpleWatcher pending_message_pipe_watcher_;
-  std::unique_ptr<PendingConnection> pending_connection_;
+  std::unique_ptr<MojoServerEndpointConnector> endpoint_connector_;
   ActiveConnectionMap active_connections_;
+  base::OneShotTimer resent_invitation_on_error_timer_;
 
   base::RepeatingClosure on_invitation_sent_callback_for_testing_;
 
@@ -151,14 +160,19 @@
     return receiver_set_.current_receiver();
   }
 
+  base::ProcessId current_peer_pid() const override {
+    return receiver_set_.current_context();
+  }
+
  private:
   // MojoIpcServerBase implementation.
-  mojo::ReceiverId TrackMessagePipe(
-      mojo::ScopedMessagePipeHandle message_pipe) override {
+  mojo::ReceiverId TrackMessagePipe(mojo::ScopedMessagePipeHandle message_pipe,
+                                    base::ProcessId peer_pid) override {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-    return receiver_set_.Add(interface_impl_, mojo::PendingReceiver<Interface>(
-                                                  std::move(message_pipe)));
+    return receiver_set_.Add(
+        interface_impl_,
+        mojo::PendingReceiver<Interface>(std::move(message_pipe)), peer_pid);
   }
 
   void UntrackMessagePipe(mojo::ReceiverId id) override {
@@ -170,7 +184,7 @@
   void UntrackAllMessagePipes() override { receiver_set_.Clear(); }
 
   raw_ptr<Interface> interface_impl_;
-  mojo::ReceiverSet<Interface> receiver_set_;
+  mojo::ReceiverSet<Interface, base::ProcessId> receiver_set_;
 };
 
 }  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_ipc_server_unittest.cc b/remoting/host/mojo_ipc/mojo_ipc_server_unittest.cc
index c1df806..fcd793b3 100644
--- a/remoting/host/mojo_ipc/mojo_ipc_server_unittest.cc
+++ b/remoting/host/mojo_ipc/mojo_ipc_server_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/callback.h"
 #include "base/callback_helpers.h"
 #include "base/no_destructor.h"
+#include "base/process/process_handle.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/gmock_callback_support.h"
@@ -82,7 +83,8 @@
 
   mojo::NamedPlatformChannel::ServerName test_server_name_;
 
-  base::test::TaskEnvironment task_environment_;
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::MainThreadType::IO};
 
   // Run loops that wait for MojoIpcServerBase::ObserverForTesting methods to
   // be called.
@@ -129,6 +131,7 @@
 
   std::move(callback).Run(input);
   last_echo_string_receiver_id_ = ipc_server_->current_receiver();
+  ASSERT_EQ(base::GetCurrentProcId(), ipc_server_->current_peer_pid());
 }
 
 void MojoIpcServerTest::OnInvitationSent() {
@@ -235,6 +238,12 @@
   WaitForInvitationSent();
 }
 
+TEST_F(MojoIpcServerTest, RemoteConnectsAndHangs_NewInvitationIsSent) {
+  mojo::IsolatedConnection client_connection;
+  auto handle = client_connection.Connect(ConnectToTestServer());
+  WaitForInvitationSent();
+}
+
 TEST_F(MojoIpcServerTest, ParallelIpcs) {
   base::RunLoop echo_response_run_loop;
   base::MockCallback<EchoStringCallback> echo_mock_callback;
diff --git a/remoting/host/mojo_ipc/mojo_server_endpoint_connector.h b/remoting/host/mojo_ipc/mojo_server_endpoint_connector.h
new file mode 100644
index 0000000..af0c7f1
--- /dev/null
+++ b/remoting/host/mojo_ipc/mojo_server_endpoint_connector.h
@@ -0,0 +1,64 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_H_
+#define REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_H_
+
+#include <memory>
+
+#include "base/memory/raw_ptr.h"
+#include "base/process/process_handle.h"
+#include "mojo/public/cpp/platform/platform_channel_server_endpoint.h"
+#include "mojo/public/cpp/system/isolated_connection.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+
+namespace remoting {
+
+// Interface to allow platform-specific implementations to establish connection
+// between the server endpoint and the client. mojo::IsolatedConnection can
+// take a PlatformChannelServerEndpoint directly, but our implementations allow:
+// 1. Reliably knowing when a new invitation needs to be sent; with the
+//    alternative approach, the best we could do is to wait for an incoming IPC
+//    call, which isn't reliable since a (malicious) client may clog the channel
+//    by connecting and hanging without making any IPCs.
+// 2. Observing the client process' PID without passing it via IPC, which
+//    wouldn't be feasible with the alternative approach, since mojo doesn't
+//    expose the underlying socket/named pipe.
+class MojoServerEndpointConnector {
+ public:
+  class Delegate {
+   public:
+    virtual ~Delegate() = default;
+
+    // Called when the client has connected to the server endpoint.
+    virtual void OnServerEndpointConnected(
+        std::unique_ptr<mojo::IsolatedConnection> connection,
+        mojo::ScopedMessagePipeHandle message_pipe,
+        base::ProcessId peer_pid) = 0;
+
+    // Called when error occurred during the connection process.
+    virtual void OnServerEndpointConnectionFailed() = 0;
+
+   protected:
+    Delegate() = default;
+  };
+
+  // Creates the platform-specific MojoServerEndpointConnector. |delegate| must
+  // outlives the created object.
+  static std::unique_ptr<MojoServerEndpointConnector> Create(
+      raw_ptr<Delegate> delegate);
+
+  virtual ~MojoServerEndpointConnector() = default;
+
+  // Connects to |server_endpoint|; invokes the delegate when it's connected or
+  // failed to connect. Note that only one pending server endpoint is allowed.
+  virtual void Connect(mojo::PlatformChannelServerEndpoint server_endpoint) = 0;
+
+ protected:
+  MojoServerEndpointConnector() = default;
+};
+
+}  // namespace remoting
+
+#endif  // REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_H_
diff --git a/remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.cc b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.cc
new file mode 100644
index 0000000..a14bcc9d
--- /dev/null
+++ b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.cc
@@ -0,0 +1,96 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.h"
+
+#include <sys/socket.h>
+
+#include <memory>
+
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/task/current_thread.h"
+#include "mojo/public/cpp/platform/socket_utils_posix.h"
+
+namespace remoting {
+
+MojoServerEndpointConnectorLinux::MojoServerEndpointConnectorLinux(
+    raw_ptr<Delegate> delegate)
+    : delegate_(delegate) {
+  DCHECK(delegate_);
+}
+
+MojoServerEndpointConnectorLinux::~MojoServerEndpointConnectorLinux() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void MojoServerEndpointConnectorLinux::Connect(
+    mojo::PlatformChannelServerEndpoint server_endpoint) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(server_endpoint.is_valid());
+  DCHECK(!pending_server_endpoint_.is_valid());
+
+  read_watcher_ =
+      std::make_unique<base::MessagePumpForIO::FdWatchController>(FROM_HERE);
+  pending_server_endpoint_ = std::move(server_endpoint);
+  base::CurrentIOThread::Get()->WatchFileDescriptor(
+      pending_server_endpoint_.platform_handle().GetFD().get(), false,
+      base::MessagePumpForIO::WATCH_READ, read_watcher_.get(), this);
+}
+
+void MojoServerEndpointConnectorLinux::OnFileCanReadWithoutBlocking(int fd) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK_EQ(pending_server_endpoint_.platform_handle().GetFD().get(), fd);
+
+  base::ScopedFD socket;
+  bool success = mojo::AcceptSocketConnection(fd, &socket);
+  read_watcher_.reset();
+  pending_server_endpoint_.reset();
+  if (!success) {
+    LOG(ERROR) << "AcceptSocketConnection failed.";
+    delegate_->OnServerEndpointConnectionFailed();
+    return;
+  }
+  if (!socket.is_valid()) {
+    LOG(ERROR) << "Socket is invalid.";
+    delegate_->OnServerEndpointConnectionFailed();
+    return;
+  }
+
+  ucred unix_peer_identity;
+  socklen_t len = sizeof(unix_peer_identity);
+  if (getsockopt(socket.get(), SOL_SOCKET, SO_PEERCRED, &unix_peer_identity,
+                 &len) != 0) {
+    PLOG(ERROR) << "getsockopt failed.";
+    delegate_->OnServerEndpointConnectionFailed();
+    return;
+  }
+
+  // TODO(yuweih): Validate process image path here. Don't check the command
+  // line as it's spoofable; check /proc/id/exe instead.
+
+  mojo::PlatformChannelEndpoint endpoint(
+      mojo::PlatformHandle(std::move(socket)));
+  if (!endpoint.is_valid()) {
+    LOG(ERROR) << "Endpoint is invalid.";
+    delegate_->OnServerEndpointConnectionFailed();
+    return;
+  }
+  auto connection = std::make_unique<mojo::IsolatedConnection>();
+  auto message_pipe = connection->Connect(std::move(endpoint));
+  delegate_->OnServerEndpointConnected(
+      std::move(connection), std::move(message_pipe), unix_peer_identity.pid);
+}
+
+void MojoServerEndpointConnectorLinux::OnFileCanWriteWithoutBlocking(int fd) {
+  NOTREACHED();
+}
+
+// static
+std::unique_ptr<MojoServerEndpointConnector>
+MojoServerEndpointConnector::Create(raw_ptr<Delegate> delegate) {
+  return std::make_unique<MojoServerEndpointConnectorLinux>(delegate);
+}
+
+}  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.h b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.h
new file mode 100644
index 0000000..6511f93
--- /dev/null
+++ b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_linux.h
@@ -0,0 +1,51 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_LINUX_H_
+#define REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_LINUX_H_
+
+#include "base/memory/raw_ptr.h"
+#include "base/message_loop/message_pump_for_io.h"
+#include "base/sequence_checker.h"
+#include "base/thread_annotations.h"
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector.h"
+
+namespace remoting {
+
+// Linux implementation for MojoServerEndpointConnector.
+class MojoServerEndpointConnectorLinux final
+    : public MojoServerEndpointConnector,
+      public base::MessagePumpForIO::FdWatcher {
+ public:
+  explicit MojoServerEndpointConnectorLinux(raw_ptr<Delegate> delegate);
+  MojoServerEndpointConnectorLinux(const MojoServerEndpointConnectorLinux&) =
+      delete;
+  MojoServerEndpointConnectorLinux& operator=(
+      const MojoServerEndpointConnectorLinux&) = delete;
+  ~MojoServerEndpointConnectorLinux() override;
+
+  // MojoServerEndpointConnector implementation.
+  void Connect(mojo::PlatformChannelServerEndpoint server_endpoint) override;
+
+ private:
+  // base::MessagePumpForIO::FdWatcher implementation.
+  void OnFileCanReadWithoutBlocking(int fd) override;
+  void OnFileCanWriteWithoutBlocking(int fd) override;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  raw_ptr<Delegate> delegate_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // These are only valid/non-null when there is a pending connection.
+  // Note that |pending_server_endpoint_| must outlive |read_watcher_|;
+  // otherwise a bad file descriptor error will occur at destruction.
+  mojo::PlatformChannelServerEndpoint pending_server_endpoint_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+  std::unique_ptr<base::MessagePumpForIO::FdWatchController> read_watcher_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+};
+
+}  // namespace remoting
+
+#endif  // REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_LINUX_H_
diff --git a/remoting/host/mojo_ipc/mojo_server_endpoint_connector_unsupported.cc b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_unsupported.cc
new file mode 100644
index 0000000..61340f1
--- /dev/null
+++ b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_unsupported.cc
@@ -0,0 +1,18 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector.h"
+
+namespace remoting {
+
+// static
+// Dummy implementation that returns nullptr for unsupported platforms, i.e.
+// Mac.
+// TODO(yuweih): Implement MojoServerEndpointConnector for Mac.
+std::unique_ptr<MojoServerEndpointConnector>
+MojoServerEndpointConnector::Create(raw_ptr<Delegate> delegate) {
+  return nullptr;
+}
+
+}  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.cc b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.cc
new file mode 100644
index 0000000..18efeec
--- /dev/null
+++ b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.cc
@@ -0,0 +1,136 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.h"
+
+#include <string.h>
+#include <windows.h>
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/check.h"
+#include "base/logging.h"
+#include "base/process/process_handle.h"
+#include "base/sequence_checker.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/task/current_thread.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/win/scoped_handle.h"
+#include "base/win/windows_types.h"
+#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
+#include "mojo/public/cpp/platform/platform_handle.h"
+#include "mojo/public/cpp/system/isolated_connection.h"
+
+namespace remoting {
+
+MojoServerEndpointConnectorWin::MojoServerEndpointConnectorWin(
+    raw_ptr<Delegate> delegate)
+    : delegate_(delegate),
+      client_connected_event_(base::WaitableEvent::ResetPolicy::MANUAL,
+                              base::WaitableEvent::InitialState::NOT_SIGNALED) {
+  DCHECK(delegate_);
+}
+
+MojoServerEndpointConnectorWin::~MojoServerEndpointConnectorWin() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+}
+
+void MojoServerEndpointConnectorWin::Connect(
+    mojo::PlatformChannelServerEndpoint server_endpoint) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(server_endpoint.is_valid());
+  DCHECK(!pending_named_pipe_handle_.IsValid());
+
+  pending_named_pipe_handle_ =
+      server_endpoint.TakePlatformHandle().TakeHandle();
+  // The |lpOverlapped| argument of ConnectNamedPipe() has the annotation of
+  // [in, out, optional], so we reset the content before passing it in, just to
+  // be safe.
+  memset(&connect_overlapped_, 0, sizeof(connect_overlapped_));
+  connect_overlapped_.hEvent = client_connected_event_.handle();
+  BOOL ok =
+      ConnectNamedPipe(pending_named_pipe_handle_.Get(), &connect_overlapped_);
+  if (ok) {
+    PLOG(ERROR) << "Unexpected success while waiting for pipe connection";
+    OnError();
+    return;
+  }
+
+  const DWORD err = GetLastError();
+  switch (err) {
+    case ERROR_PIPE_CONNECTED:
+      // A client has connected before the server calls ConnectNamedPipe().
+      OnReady();
+      return;
+    case ERROR_IO_PENDING:
+      client_connection_watcher_.StartWatching(
+          &client_connected_event_,
+          base::BindOnce(
+              &MojoServerEndpointConnectorWin::OnConnectedEventSignaled,
+              base::Unretained(this)),
+          base::SequencedTaskRunnerHandle::Get());
+      return;
+    default:
+      PLOG(ERROR) << "Unexpected error: " << err;
+      OnError();
+      return;
+  }
+}
+
+void MojoServerEndpointConnectorWin::OnConnectedEventSignaled(
+    base::WaitableEvent* event) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK_EQ(&client_connected_event_, event);
+
+  OnReady();
+}
+
+void MojoServerEndpointConnectorWin::OnReady() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  base::ProcessId peer_pid;
+  if (!GetNamedPipeClientProcessId(pending_named_pipe_handle_.Get(),
+                                   &peer_pid)) {
+    PLOG(ERROR) << "Failed to get peer PID";
+    OnError();
+    return;
+  }
+  // TODO(yuweih): Validate process image path here.
+  mojo::PlatformChannelEndpoint endpoint(
+      mojo::PlatformHandle(std::move(pending_named_pipe_handle_)));
+  if (!endpoint.is_valid()) {
+    LOG(ERROR) << "Endpoint is invalid.";
+    OnError();
+    return;
+  }
+  ResetConnectionObjects();
+  auto connection = std::make_unique<mojo::IsolatedConnection>();
+  auto message_pipe = connection->Connect(std::move(endpoint));
+  delegate_->OnServerEndpointConnected(std::move(connection),
+                                       std::move(message_pipe), peer_pid);
+}
+
+void MojoServerEndpointConnectorWin::OnError() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  ResetConnectionObjects();
+  delegate_->OnServerEndpointConnectionFailed();
+}
+
+// static
+std::unique_ptr<MojoServerEndpointConnector>
+MojoServerEndpointConnector::Create(raw_ptr<Delegate> delegate) {
+  return std::make_unique<MojoServerEndpointConnectorWin>(delegate);
+}
+
+void MojoServerEndpointConnectorWin::ResetConnectionObjects() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  client_connection_watcher_.StopWatching();
+  client_connected_event_.Reset();
+  pending_named_pipe_handle_.Close();
+}
+
+}  // namespace remoting
diff --git a/remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.h b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.h
new file mode 100644
index 0000000..a0b3392
--- /dev/null
+++ b/remoting/host/mojo_ipc/mojo_server_endpoint_connector_win.h
@@ -0,0 +1,63 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_WIN_H_
+#define REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_WIN_H_
+
+#include <windows.h>
+
+#include "base/memory/raw_ptr.h"
+#include "base/sequence_checker.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/synchronization/waitable_event_watcher.h"
+#include "base/thread_annotations.h"
+#include "base/win/scoped_handle.h"
+#include "base/win/windows_types.h"
+#include "remoting/host/mojo_ipc/mojo_server_endpoint_connector.h"
+
+namespace remoting {
+
+// Windows implementation for MojoServerEndpointConnector.
+class MojoServerEndpointConnectorWin final
+    : public MojoServerEndpointConnector {
+ public:
+  explicit MojoServerEndpointConnectorWin(raw_ptr<Delegate> delegate);
+  MojoServerEndpointConnectorWin(const MojoServerEndpointConnectorWin&) =
+      delete;
+  MojoServerEndpointConnectorWin& operator=(
+      const MojoServerEndpointConnectorWin&) = delete;
+  ~MojoServerEndpointConnectorWin() override;
+
+  void Connect(mojo::PlatformChannelServerEndpoint server_endpoint) override;
+
+ private:
+  void OnConnectedEventSignaled(base::WaitableEvent* event);
+
+  void OnReady();
+  void OnError();
+
+  void ResetConnectionObjects();
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  raw_ptr<Delegate> delegate_ GUARDED_BY_CONTEXT(sequence_checker_);
+  base::WaitableEventWatcher client_connection_watcher_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Non-null when there is a pending connection.
+  base::win::ScopedHandle pending_named_pipe_handle_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Signaled by ConnectNamedPipe() once |pending_named_pipe_handle_| is
+  // connected to a client.
+  base::WaitableEvent client_connected_event_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Object to allow ConnectNamedPipe() to run asynchronously.
+  OVERLAPPED connect_overlapped_ GUARDED_BY_CONTEXT(sequence_checker_);
+};
+
+}  // namespace remoting
+
+#endif  // REMOTING_HOST_MOJO_IPC_MOJO_SERVER_ENDPOINT_CONNECTOR_WIN_H_
diff --git a/remoting/host/mojom/chromoting_host_services.mojom b/remoting/host/mojom/chromoting_host_services.mojom
index bfd4ef1..70da0f2 100644
--- a/remoting/host/mojom/chromoting_host_services.mojom
+++ b/remoting/host/mojom/chromoting_host_services.mojom
@@ -16,7 +16,23 @@
 // DO NOT use this interface for communication between two processes in the same
 // mojo network (e.g. between the daemon process and the network process). Use
 // standard (non-isolated) connection in that case.
+// TODO(yuweih): See if we need to make IPCs without a connected client session,
+// e.g. reporting remote state. If that's not the case then we may get rid of
+// this interface and start the connection on ChromotingSessionServices
+// directly.
 interface ChromotingHostServices {
+  // Binds the ChromotingSessionServices interface which allows accessing APIs
+  // that are scoped to the current remote desktop session.
+  // The receiver will be immediately closed if the caller process' desktop
+  // session is not remoted.
+  BindSessionServices(pending_receiver<ChromotingSessionServices> receiver);
+};
+
+// ChromotingHostServices defines APIs that are scoped to an active remote
+// session. The interface is brokered by ChromotingHostServices, so it has the
+// same host-client pair, and the limitation of isolated connections still
+// applies.
+interface ChromotingSessionServices {
   // Binds the WebAuthnProxy interface which allows the WebAuthn native
   // messaging host to send remote WebAuthn requests to the remote client.
   BindWebAuthnProxy(pending_receiver<WebAuthnProxy> receiver);
diff --git a/remoting/host/remote_open_url/BUILD.gn b/remoting/host/remote_open_url/BUILD.gn
index b511463..24124068 100644
--- a/remoting/host/remote_open_url/BUILD.gn
+++ b/remoting/host/remote_open_url/BUILD.gn
@@ -101,10 +101,14 @@
 source_set("unit_tests") {
   testonly = true
 
-  sources = [
-    "remote_open_url_client_unittest.cc",
-    "remote_open_url_message_handler_unittest.cc",
-  ]
+  sources = [ "remote_open_url_message_handler_unittest.cc" ]
+
+  # Temporarily disable RemoteOpenUrlClientTest on unsupported platforms due to
+  # dependency on MojoIpcServer.
+  # TODO(yuweih): Undo once https://crrev.com/c/3271578 is checked in.
+  if (is_linux || is_win) {
+    sources += [ "remote_open_url_client_unittest.cc" ]
+  }
 
   deps = [
     ":common",
diff --git a/remoting/host/remote_open_url/remote_open_url_client_unittest.cc b/remoting/host/remote_open_url/remote_open_url_client_unittest.cc
index b94c13f..24d29e1 100644
--- a/remoting/host/remote_open_url/remote_open_url_client_unittest.cc
+++ b/remoting/host/remote_open_url/remote_open_url_client_unittest.cc
@@ -67,7 +67,8 @@
  private:
   mojo::NamedPlatformChannel::ServerName test_server_name_ =
       test::GenerateRandomServerName();
-  base::test::TaskEnvironment task_environment_;
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::MainThreadType::IO};
 };
 
 RemoteOpenUrlClientTest::RemoteOpenUrlClientTest() {
diff --git a/remoting/host/security_key/BUILD.gn b/remoting/host/security_key/BUILD.gn
index b91f744..174ddedc 100644
--- a/remoting/host/security_key/BUILD.gn
+++ b/remoting/host/security_key/BUILD.gn
@@ -67,6 +67,9 @@
     "//remoting/host:base",
     "//remoting/host:common",
   ]
+  if (is_win) {
+    deps += [ "//remoting/host/win:acl_util" ]
+  }
 }
 
 if (is_win) {
diff --git a/remoting/host/security_key/remote_security_key_main.cc b/remoting/host/security_key/remote_security_key_main.cc
index 3b5bc55..d96d6712 100644
--- a/remoting/host/security_key/remote_security_key_main.cc
+++ b/remoting/host/security_key/remote_security_key_main.cc
@@ -14,6 +14,7 @@
 #include "base/run_loop.h"
 #include "base/task/single_thread_task_executor.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
 #include "mojo/core/embedder/embedder.h"
 #include "mojo/core/embedder/scoped_ipc_support.h"
 #include "remoting/host/host_exit_codes.h"
@@ -22,97 +23,17 @@
 #include "remoting/host/security_key/security_key_message_handler.h"
 
 #if defined(OS_WIN)
-#include <aclapi.h>
 #include <windows.h>
 
-#include "base/win/scoped_handle.h"
-#endif  // defined(OS_WIN)
-
-#if defined(OS_WIN)
-namespace {
-
-bool AddAccessRightForWellKnownSid(WELL_KNOWN_SID_TYPE type, DWORD new_right) {
-  // Open a handle for the current process, read the current DACL, update it,
-  // and write it back.  This will add |new_right| to the current process.
-  base::win::ScopedHandle process_handle(OpenProcess(READ_CONTROL | WRITE_DAC,
-                                                     /*bInheritHandle=*/FALSE,
-                                                     GetCurrentProcessId()));
-  if (!process_handle.IsValid()) {
-    PLOG(ERROR) << "OpenProcess() failed!";
-    return false;
-  }
-
-  // TODO(joedow): Add a custom deleter to handle objects which are freed via
-  // LocalFree().  Tracked by crbug.com/622913
-  PSECURITY_DESCRIPTOR descriptor = nullptr;
-  // |old_dacl| is a pointer into the opaque |descriptor| struct, don't free it.
-  PACL old_dacl = nullptr;
-  PACL new_dacl = nullptr;
-
-  if (GetSecurityInfo(process_handle.Get(),
-                      SE_KERNEL_OBJECT,
-                      DACL_SECURITY_INFORMATION,
-                      /*ppsidOwner=*/nullptr,
-                      /*ppsidGroup=*/nullptr,
-                      &old_dacl,
-                      /*ppSacl=*/nullptr,
-                      &descriptor) != ERROR_SUCCESS) {
-    PLOG(ERROR) << "GetSecurityInfo() failed!";
-    return false;
-  }
-
-  BYTE buffer[SECURITY_MAX_SID_SIZE] = {0};
-  DWORD buffer_size = SECURITY_MAX_SID_SIZE;
-  if (!CreateWellKnownSid(type, /*DomainSid=*/nullptr, buffer, &buffer_size)) {
-    PLOG(ERROR) << "CreateWellKnownSid() failed!";
-    LocalFree(descriptor);
-    return false;
-  }
-
-  SID* sid = reinterpret_cast<SID*>(buffer);
-  EXPLICIT_ACCESS new_access = {0};
-  new_access.grfAccessMode = GRANT_ACCESS;
-  new_access.grfAccessPermissions = new_right;
-  new_access.grfInheritance = NO_INHERITANCE;
-
-  new_access.Trustee.pMultipleTrustee = nullptr;
-  new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
-  new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
-  new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(sid);
-
-  if (SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl) != ERROR_SUCCESS) {
-    PLOG(ERROR) << "SetEntriesInAcl() failed!";
-    LocalFree(descriptor);
-    return false;
-  }
-
-  bool right_added = true;
-  if (SetSecurityInfo(process_handle.Get(),
-                      SE_KERNEL_OBJECT,
-                      DACL_SECURITY_INFORMATION,
-                      /*ppsidOwner=*/nullptr,
-                      /*ppsidGroup=*/nullptr,
-                      new_dacl,
-                      /*ppSacl=*/nullptr) != ERROR_SUCCESS) {
-    PLOG(ERROR) << "SetSecurityInfo() failed!";
-    right_added = false;
-  }
-
-  LocalFree(new_dacl);
-  LocalFree(descriptor);
-
-  return right_added;
-}
-
-}  // namespace
+#include "remoting/host/win/acl_util.h"
 #endif  // defined(OS_WIN)
 
 namespace remoting {
 
 int StartRemoteSecurityKey() {
 #if defined(OS_WIN)
-  if (!AddAccessRightForWellKnownSid(WinLocalServiceSid,
-                                     PROCESS_QUERY_LIMITED_INFORMATION)) {
+  if (!AddProcessAccessRightForWellKnownSid(
+          WinLocalServiceSid, PROCESS_QUERY_LIMITED_INFORMATION)) {
     return kInitializationFailed;
   }
 
diff --git a/remoting/host/webauthn/BUILD.gn b/remoting/host/webauthn/BUILD.gn
index 8643557..7f15a12 100644
--- a/remoting/host/webauthn/BUILD.gn
+++ b/remoting/host/webauthn/BUILD.gn
@@ -39,6 +39,8 @@
     ":webauthn",
     "//base",
     "//mojo/core/embedder:embedder",
+    "//remoting/host:base",
+    "//remoting/host:chromoting_host_services_client",
     "//remoting/host:logging",
     "//remoting/host/native_messaging",
   ]
diff --git a/remoting/host/webauthn/remote_webauthn_main.cc b/remoting/host/webauthn/remote_webauthn_main.cc
index bcf410c..f2dfda9 100644
--- a/remoting/host/webauthn/remote_webauthn_main.cc
+++ b/remoting/host/webauthn/remote_webauthn_main.cc
@@ -14,6 +14,8 @@
 #include "build/build_config.h"
 #include "mojo/core/embedder/embedder.h"
 #include "mojo/core/embedder/scoped_ipc_support.h"
+#include "remoting/host/chromoting_host_services_client.h"
+#include "remoting/host/host_exit_codes.h"
 #include "remoting/host/logging.h"
 #include "remoting/host/native_messaging/native_messaging_pipe.h"
 #include "remoting/host/native_messaging/pipe_messaging_channel.h"
@@ -33,6 +35,10 @@
   base::CommandLine::Init(argc, argv);
   InitHostLogging();
 
+  if (!ChromotingHostServicesClient::Initialize()) {
+    return kInitializationFailed;
+  }
+
   mojo::core::Init();
   mojo::core::ScopedIPCSupport ipc_support(
       task_runner, mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST);
@@ -81,7 +87,7 @@
 
   run_loop.Run();
 
-  return 0;
+  return kSuccessExitCode;
 }
 
 }  // namespace remoting
diff --git a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
index 6f427da..07d13be 100644
--- a/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
+++ b/remoting/host/webauthn/remote_webauthn_native_messaging_host.cc
@@ -110,7 +110,7 @@
     return true;
   }
 
-  auto* api = host_service_api_client_.Get();
+  auto* api = host_service_api_client_.GetSessionServices();
   if (!api) {
     return false;
   }
diff --git a/remoting/host/win/BUILD.gn b/remoting/host/win/BUILD.gn
index a26478d..f81afd1 100644
--- a/remoting/host/win/BUILD.gn
+++ b/remoting/host/win/BUILD.gn
@@ -91,6 +91,14 @@
   deps = [ "//remoting/base" ]
 }
 
+source_set("acl_util") {
+  sources = [
+    "acl_util.cc",
+    "acl_util.h",
+  ]
+  deps = [ "//base" ]
+}
+
 source_set("win") {
   sources = [
     "audio_volume_filter_win.cc",
diff --git a/remoting/host/win/acl_util.cc b/remoting/host/win/acl_util.cc
new file mode 100644
index 0000000..4188adf8
--- /dev/null
+++ b/remoting/host/win/acl_util.cc
@@ -0,0 +1,84 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/host/win/acl_util.h"
+
+#include <aclapi.h>
+#include <windows.h>
+
+#include "base/logging.h"
+#include "base/win/scoped_handle.h"
+#include "base/win/scoped_localalloc.h"
+
+namespace remoting {
+
+bool AddProcessAccessRightForWellKnownSid(WELL_KNOWN_SID_TYPE type,
+                                          DWORD new_right) {
+  // Open a handle for the current process, read the current DACL, update it,
+  // and write it back.  This will add |new_right| to the current process.
+  base::win::ScopedHandle process_handle(OpenProcess(READ_CONTROL | WRITE_DAC,
+                                                     /*bInheritHandle=*/FALSE,
+                                                     GetCurrentProcessId()));
+  if (!process_handle.IsValid()) {
+    PLOG(ERROR) << "OpenProcess() failed!";
+    return false;
+  }
+
+  PSECURITY_DESCRIPTOR descriptor_ptr = nullptr;
+  // |old_dacl_ptr| is a pointer into the opaque |descriptor_ptr| struct, don't
+  // free it.
+  PACL old_dacl_ptr = nullptr;
+  PACL new_dacl_ptr = nullptr;
+
+  if (GetSecurityInfo(process_handle.Get(), SE_KERNEL_OBJECT,
+                      DACL_SECURITY_INFORMATION,
+                      /*ppsidOwner=*/nullptr,
+                      /*ppsidGroup=*/nullptr, &old_dacl_ptr,
+                      /*ppSacl=*/nullptr, &descriptor_ptr) != ERROR_SUCCESS) {
+    PLOG(ERROR) << "GetSecurityInfo() failed!";
+    return false;
+  }
+
+  base::win::ScopedLocalAlloc descriptor =
+      base::win::TakeLocalAlloc(descriptor_ptr);
+  BYTE buffer[SECURITY_MAX_SID_SIZE] = {0};
+  DWORD buffer_size = SECURITY_MAX_SID_SIZE;
+  if (!CreateWellKnownSid(type, /*DomainSid=*/nullptr, buffer, &buffer_size)) {
+    PLOG(ERROR) << "CreateWellKnownSid() failed!";
+    return false;
+  }
+
+  SID* sid = reinterpret_cast<SID*>(buffer);
+  EXPLICIT_ACCESS new_access = {0};
+  new_access.grfAccessMode = GRANT_ACCESS;
+  new_access.grfAccessPermissions = new_right;
+  new_access.grfInheritance = NO_INHERITANCE;
+
+  new_access.Trustee.pMultipleTrustee = nullptr;
+  new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+  new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+  new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(sid);
+
+  if (SetEntriesInAcl(1, &new_access, old_dacl_ptr, &new_dacl_ptr) !=
+      ERROR_SUCCESS) {
+    PLOG(ERROR) << "SetEntriesInAcl() failed!";
+    return false;
+  }
+  base::win::ScopedLocalAllocTyped<ACL> new_dacl =
+      base::win::TakeLocalAlloc(new_dacl_ptr);
+
+  bool right_added = true;
+  if (SetSecurityInfo(process_handle.Get(), SE_KERNEL_OBJECT,
+                      DACL_SECURITY_INFORMATION,
+                      /*psidOwner=*/nullptr,
+                      /*psidGroup=*/nullptr, new_dacl.get(),
+                      /*ppSacl=*/nullptr) != ERROR_SUCCESS) {
+    PLOG(ERROR) << "SetSecurityInfo() failed!";
+    right_added = false;
+  }
+
+  return right_added;
+}
+
+}  // namespace remoting
diff --git a/remoting/host/win/acl_util.h b/remoting/host/win/acl_util.h
new file mode 100644
index 0000000..bb66053
--- /dev/null
+++ b/remoting/host/win/acl_util.h
@@ -0,0 +1,19 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_HOST_WIN_ACL_UTIL_H_
+#define REMOTING_HOST_WIN_ACL_UTIL_H_
+
+#include <windows.h>
+
+namespace remoting {
+
+// Adds new access right to the current process for |type|. Returns a boolean
+// indicating whether the operation was successful.
+bool AddProcessAccessRightForWellKnownSid(WELL_KNOWN_SID_TYPE type,
+                                          DWORD new_right);
+
+}  // namespace remoting
+
+#endif  // REMOTING_HOST_WIN_ACL_UTIL_H_
diff --git a/services/network/websocket.cc b/services/network/websocket.cc
index 4c5d1dc..e8f5346ca 100644
--- a/services/network/websocket.cc
+++ b/services/network/websocket.cc
@@ -12,8 +12,6 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/check.h"
-#include "base/check_op.h"
 #include "base/feature_list.h"
 #include "base/ignore_result.h"
 #include "base/location.h"
@@ -276,7 +274,11 @@
   if (payload.size() > 0) {
     impl_->pending_data_frames_.push(payload);
   }
-  impl_->SendPendingDataFrames(InterruptionReason::kNone);
+  if (impl_->incoming_frame_interceptor_ &&
+      impl_->incoming_frame_interceptor_->IsFrameStarted()) {
+    return;
+  }
+  impl_->SendPendingDataFrames();
 }
 
 void WebSocket::WebSocketEventHandler::OnSendDataFrameDone() {
@@ -514,8 +516,10 @@
 
   // Safe if ReadAndSendFromDataPipe() deletes |this| because this method is
   // only called from mojo.
-  if (!blocked_on_websocket_channel_) {
-    ReadAndSendFromDataPipe(InterruptionReason::kNone);
+  if (!blocked_on_websocket_channel_ &&
+      (!outgoing_frame_interceptor_ ||
+       !outgoing_frame_interceptor_->IsFrameStarted())) {
+    ReadAndSendFromDataPipe();
   }
 }
 
@@ -649,51 +653,47 @@
     OnConnectionError(FROM_HERE);
     return;
   }
-  SendPendingDataFrames(InterruptionReason::kMojoPipe);
+  wait_for_writable_ = false;
+  SendPendingDataFrames();
+  if (pending_data_frames_.empty()) {
+    ignore_result(channel_->ReadFrames());
+  }
 }
 
-void WebSocket::SendPendingDataFrames(InterruptionReason resume_reason) {
+void WebSocket::SendPendingDataFrames() {
   DVLOG(3) << "WebSocket::SendPendingDataFrames @"
            << reinterpret_cast<void*>(this)
            << ", pending_data_frames_.size=" << pending_data_frames_.size()
-           << ", incoming_frames_interrupted_="
-           << static_cast<int>(incoming_frames_interrupted_);
+           << ", wait_for_writable_?" << wait_for_writable_;
 
-  if (incoming_frames_interrupted_ != resume_reason)
+  if (wait_for_writable_) {
     return;
-
-  bool resuming_after_interruption = false;
-  if (incoming_frames_interrupted_ != InterruptionReason::kNone) {
-    incoming_frames_interrupted_ = InterruptionReason::kNone;
-    resuming_after_interruption = true;
   }
   while (!pending_data_frames_.empty()) {
     base::span<const char>& data_frame = pending_data_frames_.front();
     if (incoming_frame_interceptor_ &&
-        resume_reason == InterruptionReason::kNone) {
-      // `Intercept` always intercepts sending data per frame.
+        !incoming_frame_interceptor_->IsFrameStarted()) {
+      // `Intercept` always intercepts sending data per frame. Once intercepted,
+      // the intercepteror needs to be notified when the whole frame is sent by
+      // calling `FinishFrame`.
       auto intercept_result = incoming_frame_interceptor_->Intercept(
           data_frame.size(), base::BindOnce(&WebSocket::SendPendingDataFrames,
-                                            base::Unretained(this),
-                                            InterruptionReason::kInterceptor));
-      if (intercept_result == WebSocketInterceptor::kShouldWait) {
-        DCHECK_EQ(incoming_frames_interrupted_, InterruptionReason::kNone);
-        incoming_frames_interrupted_ = InterruptionReason::kInterceptor;
+                                            base::Unretained(this)));
+      if (intercept_result == WebSocketInterceptor::kShouldWait)
         return;
-      }
     }
     SendDataFrame(&data_frame);
     if (data_frame.size() > 0) {
       // Mojo doesn't have any write buffer so far.
       writable_watcher_.ArmOrNotify();
-      DCHECK_EQ(incoming_frames_interrupted_, InterruptionReason::kNone);
-      incoming_frames_interrupted_ = InterruptionReason::kMojoPipe;
+      wait_for_writable_ = true;
       return;
     }
     pending_data_frames_.pop();
-  }
-  if (resuming_after_interruption) {
-    ignore_result(channel_->ReadFrames());
+    if (incoming_frame_interceptor_ &&
+        incoming_frame_interceptor_->IsFrameStarted()) {
+      incoming_frame_interceptor_->FinishFrame();
+    }
   }
 }
 
@@ -737,39 +737,43 @@
     OnConnectionError(FROM_HERE);
     return;
   }
+  wait_for_readable_ = false;
+
   // Safe if ReadAndSendFromDataPipe() deletes |this| because this method is
   // only called from mojo.
-  ReadAndSendFromDataPipe(InterruptionReason::kMojoPipe);
+  if (!outgoing_frame_interceptor_ ||
+      !outgoing_frame_interceptor_->IsFrameStarted()) {
+    ReadAndSendFromDataPipe();
+  }
 }
 
-void WebSocket::ReadAndSendFromDataPipe(InterruptionReason resume_reason) {
-  if (outgoing_frames_interrupted_ != resume_reason)
+void WebSocket::ReadAndSendFromDataPipe() {
+  if (wait_for_readable_) {
     return;
-
-  if (outgoing_frames_interrupted_ != InterruptionReason::kNone)
-    outgoing_frames_interrupted_ = InterruptionReason::kNone;
-
+  }
   while (!pending_send_data_frames_.empty()) {
     DataFrame& data_frame = pending_send_data_frames_.front();
     DVLOG(2) << " ConsumePendingDataFrame frame=(" << data_frame.type
              << ", (data_length = " << data_frame.data_length << "))";
     if (outgoing_frame_interceptor_ &&
-        resume_reason == InterruptionReason::kNone) {
-      // `Intercept` always intercepts reading data per frame.
+        !outgoing_frame_interceptor_->IsFrameStarted()) {
+      // `Intercept` always intercepts reading data per frame. Once intercepted,
+      // the intercepteror needs to be notified when the whole frame is read by
+      // calling `FinishFrame`.
       auto intercept_result = outgoing_frame_interceptor_->Intercept(
           data_frame.data_length,
           base::BindOnce(&WebSocket::ReadAndSendFromDataPipe,
-                         base::Unretained(this),
-                         InterruptionReason::kInterceptor));
-      if (intercept_result == WebSocketInterceptor::kShouldWait) {
-        DCHECK_EQ(outgoing_frames_interrupted_, InterruptionReason::kNone);
-        outgoing_frames_interrupted_ = InterruptionReason::kInterceptor;
+                         base::Unretained(this)));
+      if (intercept_result == WebSocketInterceptor::kShouldWait)
         return;
-      }
     }
     if (!ReadAndSendFrameFromDataPipe(&data_frame)) {
       return;
     }
+    if (outgoing_frame_interceptor_ &&
+        outgoing_frame_interceptor_->IsFrameStarted()) {
+      outgoing_frame_interceptor_->FinishFrame();
+    }
     pending_send_data_frames_.pop();
   }
   if (pending_start_closing_handshake_) {
@@ -798,8 +802,7 @@
     const MojoResult begin_result = readable_->BeginReadData(
         &buffer, &readable_size, MOJO_READ_DATA_FLAG_NONE);
     if (begin_result == MOJO_RESULT_SHOULD_WAIT) {
-      DCHECK_EQ(outgoing_frames_interrupted_, InterruptionReason::kNone);
-      outgoing_frames_interrupted_ = InterruptionReason::kMojoPipe;
+      wait_for_readable_ = true;
       if (!blocked_on_websocket_channel_) {
         readable_watcher_.ArmOrNotify();
       }
diff --git a/services/network/websocket.h b/services/network/websocket.h
index d6a7a68..c38df7a 100644
--- a/services/network/websocket.h
+++ b/services/network/websocket.h
@@ -170,25 +170,15 @@
 
   void Reset();
 
-  enum class InterruptionReason {
-    // Not interrupted or not resuming after interruptions (but processing a
-    // brand new frame)
-    kNone,
-    // Interrupted by empty Mojo pipe or resuming afterwards
-    kMojoPipe,
-    // Interrupted by the interceptor or resuming afterwards
-    kInterceptor,
-  };
-
   // Datapipe functions to receive.
   void OnWritable(MojoResult result, const mojo::HandleSignalsState& state);
-  void SendPendingDataFrames(InterruptionReason resume_reason);
+  void SendPendingDataFrames();
   void SendDataFrame(base::span<const char>* data_span);
 
   // Datapipe functions to send.
   void OnReadable(MojoResult result, const mojo::HandleSignalsState& state);
 
-  void ReadAndSendFromDataPipe(InterruptionReason resume_reason);
+  void ReadAndSendFromDataPipe();
   // This helper method only called from ReadAndSendFromDataPipe.
   // Note that it may indirectly delete |this|.
   // Returns true if the frame has been sent completely.
@@ -228,18 +218,17 @@
   bool handshake_succeeded_ = false;
   const HasRawHeadersAccess has_raw_headers_access_;
 
-  InterruptionReason incoming_frames_interrupted_ = InterruptionReason::kNone;
-  InterruptionReason outgoing_frames_interrupted_ = InterruptionReason::kNone;
-
   // Datapipe fields to receive.
   mojo::ScopedDataPipeProducerHandle writable_;
   mojo::SimpleWatcher writable_watcher_;
   base::queue<base::span<const char>> pending_data_frames_;
+  bool wait_for_writable_ = false;
 
   // Datapipe fields to send.
   mojo::ScopedDataPipeConsumerHandle readable_;
   mojo::SimpleWatcher readable_watcher_;
   base::queue<DataFrame> pending_send_data_frames_;
+  bool wait_for_readable_ = false;
   bool blocked_on_websocket_channel_ = false;
 
   // True if we should preserve the old behaviour where <=64KB messages were
diff --git a/services/network/websocket_interceptor.cc b/services/network/websocket_interceptor.cc
index a1ca0f0940..3eb2ee4d 100644
--- a/services/network/websocket_interceptor.cc
+++ b/services/network/websocket_interceptor.cc
@@ -36,6 +36,7 @@
     size_t size,
     base::OnceClosure retry_callback) {
   DCHECK(!pending_callback_);
+  DCHECK(!frame_started_);
 
   auto* throttling_interceptor =
       ThrottlingController::GetInterceptor(net_log_source_id_);
@@ -49,11 +50,18 @@
       /*is_upload=*/direction_ == kOutgoing, throttle_callback_);
   if (start_throttle_result == net::ERR_IO_PENDING) {
     pending_callback_ = std::move(retry_callback);
+    frame_started_ = true;
     return kShouldWait;
   }
   return kContinue;
 }
 
+void WebSocketInterceptor::FinishFrame() {
+  DCHECK(frame_started_);
+  DCHECK(pending_callback_.is_null());
+  frame_started_ = false;
+}
+
 void WebSocketInterceptor::ThrottleCallback(int result, int64_t bytes) {
   if (pending_callback_)
     std::move(pending_callback_).Run();
diff --git a/services/network/websocket_interceptor.h b/services/network/websocket_interceptor.h
index 9e468bd..b3fd4c2 100644
--- a/services/network/websocket_interceptor.h
+++ b/services/network/websocket_interceptor.h
@@ -46,7 +46,12 @@
   //   * kShouldWait: frame processing should be paused until `retry_callback`
   //     is invoked.
   //     Calling Intercept again before the callback runs is not allowed.
+  //     Calling Intercept again before calling FinishFrame is also not allowed.
   InterceptResult Intercept(size_t size, base::OnceClosure retry_callback);
+  // This is meant to be called when processing of a single frame is done and it
+  // resets the interceptor state.
+  void FinishFrame();
+  bool IsFrameStarted() { return frame_started_; }
 
  private:
   void ThrottleCallback(int result, int64_t bytes);
@@ -57,6 +62,7 @@
   const std::unique_ptr<ScopedThrottlingToken> throttling_token_;
 
   base::OnceClosure pending_callback_;
+  bool frame_started_ = false;
 };
 
 }  // namespace network
diff --git a/services/network/websocket_interceptor_unittest.cc b/services/network/websocket_interceptor_unittest.cc
index ea38faa9..c9030a7 100644
--- a/services/network/websocket_interceptor_unittest.cc
+++ b/services/network/websocket_interceptor_unittest.cc
@@ -85,6 +85,7 @@
   EXPECT_CALL(mock_callback_, Callback()).Times(1);
   task_environment_.FastForwardUntilNoTasksRemain();
 
+  interceptor_->FinishFrame();
   EXPECT_EQ(WebSocketInterceptor::kShouldWait,
             interceptor_->Intercept(42, MakeCallback()));
 }
@@ -97,7 +98,10 @@
   EXPECT_EQ(WebSocketInterceptor::kShouldWait,
             interceptor_->Intercept(42, MakeCallback()));
 
-  EXPECT_CALL(mock_callback_, Callback()).Times(1);
+  // EXPECT_CALL(mock_callback_, Callback()).Times(1);
+  EXPECT_CALL(mock_callback_, Callback()).Times(1).WillOnce([&] {
+    interceptor_->FinishFrame();
+  });
   ThrottlingController::SetConditions(*kThrottlingProfileId, nullptr);
   interceptor_->Intercept(42, MakeCallback());
 }
@@ -110,7 +114,9 @@
   EXPECT_EQ(WebSocketInterceptor::kShouldWait,
             interceptor_->Intercept(42, MakeCallback()));
 
-  EXPECT_CALL(mock_callback_, Callback()).Times(1);
+  EXPECT_CALL(mock_callback_, Callback()).Times(1).WillOnce([&] {
+    interceptor_->FinishFrame();
+  });
   ThrottlingController::SetConditions(
       *kThrottlingProfileId,
       std::make_unique<NetworkConditions>(/*offline=*/false, /*latency=*/0,
diff --git a/services/shape_detection/BUILD.gn b/services/shape_detection/BUILD.gn
index 6c45116..47c5677 100644
--- a/services/shape_detection/BUILD.gn
+++ b/services/shape_detection/BUILD.gn
@@ -12,16 +12,16 @@
     "text_detection_impl.h",
   ]
 
-  deps = [
-    "//build:branding_buildflags",
-    "//build:chromeos_buildflags",
-    "//mojo/public/cpp/bindings",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-  ]
-
   if (is_mac) {
     sources += [
+      "barcode_detection_impl_mac.h",
+      "barcode_detection_impl_mac.mm",
+      "barcode_detection_impl_mac_vision.h",
+      "barcode_detection_impl_mac_vision.mm",
+      "barcode_detection_impl_mac_vision_api.h",
+      "barcode_detection_impl_mac_vision_api.mm",
+      "barcode_detection_provider_mac.h",
+      "barcode_detection_provider_mac.mm",
       "detection_utils_mac.h",
       "detection_utils_mac.mm",
       "face_detection_impl_mac.h",
@@ -37,6 +37,8 @@
     weak_frameworks = [ "Vision.framework" ]
   } else if (is_win) {
     sources += [
+      "barcode_detection_provider_impl.cc",
+      "barcode_detection_provider_impl.h",
       "detection_utils_win.cc",
       "detection_utils_win.h",
       "face_detection_impl_win.cc",
@@ -46,50 +48,40 @@
       "text_detection_impl_win.cc",
       "text_detection_impl_win.h",
     ]
-  } else if (is_android) {
-    # No C++ sources needed, face and text detection is provided by Java.
+  } else if (is_chromeos_ash && is_chrome_branded) {
+    sources += [
+      "barcode_detection_impl_barhopper.cc",
+      "barcode_detection_impl_barhopper.h",
+      "barcode_detection_provider_barhopper.cc",
+      "barcode_detection_provider_barhopper.h",
+      "face_detection_provider_impl.cc",
+      "face_detection_provider_impl.h",
+      "text_detection_impl.cc",
+    ]
   } else {
     sources += [
+      "barcode_detection_provider_impl.cc",
+      "barcode_detection_provider_impl.h",
       "face_detection_provider_impl.cc",
       "face_detection_provider_impl.h",
       "text_detection_impl.cc",
     ]
   }
 
-  if (is_mac) {
-    # On macOS there is a barcode detection API available from the platform.
-    sources += [
-      "barcode_detection_impl_mac.h",
-      "barcode_detection_impl_mac.mm",
-      "barcode_detection_impl_mac_vision.h",
-      "barcode_detection_impl_mac_vision.mm",
-      "barcode_detection_impl_mac_vision_api.h",
-      "barcode_detection_impl_mac_vision_api.mm",
-      "barcode_detection_provider_mac.h",
-      "barcode_detection_provider_mac.mm",
-    ]
-  } else if (is_android) {
-    # No C++ sources needed, barcode detection is provided by Java.
-  } else if (is_chrome_branded) {
-    # On all other platforms use Google's "Barhopper" library if src-internal is
-    # available.
-    sources += [
-      "barcode_detection_impl_barhopper.cc",
-      "barcode_detection_impl_barhopper.h",
-      "barcode_detection_provider_barhopper.cc",
-      "barcode_detection_provider_barhopper.h",
-    ]
-    deps += [ "//third_party/barhopper" ]
-  } else {
-    # Otherwise, use a stub implementation.
-    sources += [
-      "barcode_detection_provider_impl.cc",
-      "barcode_detection_provider_impl.h",
-    ]
-  }
-
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
 
+  deps = [
+    "//build:branding_buildflags",
+    "//build:chromeos_buildflags",
+    "//mojo/public/cpp/bindings",
+    "//ui/gfx",
+    "//ui/gfx/geometry",
+  ]
+
+  if (is_chromeos_ash && is_chrome_branded) {
+    deps += [ "//third_party/barhopper:barhopper" ]
+  }
+
   public_deps = [
     "//base",
     "//media/capture",
@@ -161,7 +153,7 @@
     ]
   }
 
-  if (!is_mac && !is_android && is_chrome_branded) {
+  if (is_chromeos_ash && is_chrome_branded) {
     sources += [ "barcode_detection_impl_barhopper_unittest.cc" ]
   }
 
diff --git a/services/shape_detection/barcode_detection_impl_barhopper_unittest.cc b/services/shape_detection/barcode_detection_impl_barhopper_unittest.cc
index 644cd68..d934ca7 100644
--- a/services/shape_detection/barcode_detection_impl_barhopper_unittest.cc
+++ b/services/shape_detection/barcode_detection_impl_barhopper_unittest.cc
@@ -15,27 +15,25 @@
 
 namespace shape_detection {
 
-constexpr struct TestParams {
-  base::FilePath::StringPieceType filename;
-  base::StringPiece expected_value;
+struct TestParams {
+  std::string filename;
+  std::string expected_value;
   float x;
   float y;
   float width;
   float height;
-} kTestParams[] = {
-    {FILE_PATH_LITERAL("codabar.png"), "A6.2831853B", 24, 24, 448, 95},
-    {FILE_PATH_LITERAL("code_39.png"), "CHROMIUM", 20, 20, 318, 75},
-    {FILE_PATH_LITERAL("code_93.png"), "CHROMIUM", 20, 20, 216, 75},
-    {FILE_PATH_LITERAL("code_128.png"), "Chromium", 20, 20, 246, 75},
-    {FILE_PATH_LITERAL("data_matrix.png"), "Chromium", 11, 11, 53, 53},
-    {FILE_PATH_LITERAL("ean_8.png"), "62831857", 14, 10, 134, 75},
-    {FILE_PATH_LITERAL("ean_13.png"), "6283185307179", 27, 10, 190, 75},
-    {FILE_PATH_LITERAL("itf.png"), "62831853071795", 10, 10, 135, 39},
-    {FILE_PATH_LITERAL("pdf417.png"), "Chromium", 20, 20, 240, 44},
-    {FILE_PATH_LITERAL("qr_code.png"), "https://chromium.org", 40, 40, 250,
-     250},
-    {FILE_PATH_LITERAL("upc_a.png"), "628318530714", 23, 10, 190, 75},
-    {FILE_PATH_LITERAL("upc_e.png"), "06283186", 23, 10, 102, 75}};
+} kTestParams[] = {{"codabar.png", "A6.2831853B", 24, 24, 448, 95},
+                   {"code_39.png", "CHROMIUM", 20, 20, 318, 75},
+                   {"code_93.png", "CHROMIUM", 20, 20, 216, 75},
+                   {"code_128.png", "Chromium", 20, 20, 246, 75},
+                   {"data_matrix.png", "Chromium", 11, 11, 53, 53},
+                   {"ean_8.png", "62831857", 14, 10, 134, 75},
+                   {"ean_13.png", "6283185307179", 27, 10, 190, 75},
+                   {"itf.png", "62831853071795", 10, 10, 135, 39},
+                   {"pdf417.png", "Chromium", 20, 20, 240, 44},
+                   {"qr_code.png", "https://chromium.org", 40, 40, 250, 250},
+                   {"upc_a.png", "628318530714", 23, 10, 190, 75},
+                   {"upc_e.png", "06283186", 23, 10, 102, 75}};
 
 class BarcodeDetectionImplBarhopperTest
     : public testing::TestWithParam<struct TestParams> {
@@ -60,15 +58,14 @@
     return barcode_service;
   }
 
-  std::unique_ptr<SkBitmap> LoadTestImage(
-      base::FilePath::StringPieceType filename) {
+  std::unique_ptr<SkBitmap> LoadTestImage(std::string filename) {
     // Load image data from test directory.
     base::FilePath image_path;
     EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &image_path));
     image_path = image_path.Append(FILE_PATH_LITERAL("services"))
                      .Append(FILE_PATH_LITERAL("test"))
                      .Append(FILE_PATH_LITERAL("data"))
-                     .Append(filename);
+                     .Append(FILE_PATH_LITERAL(filename));
     EXPECT_TRUE(base::PathExists(image_path));
     std::string image_data;
     EXPECT_TRUE(base::ReadFileToString(image_path, &image_data));
@@ -117,4 +114,4 @@
                          BarcodeDetectionImplBarhopperTest,
                          testing::ValuesIn(kTestParams));
 
-}  // namespace shape_detection
+}  // namespace shape_detection
\ No newline at end of file
diff --git a/services/shape_detection/shape_detection_service.cc b/services/shape_detection/shape_detection_service.cc
index 0e6e101..542c266f 100644
--- a/services/shape_detection/shape_detection_service.cc
+++ b/services/shape_detection/shape_detection_service.cc
@@ -10,6 +10,19 @@
 #include "base/bind.h"
 #include "build/branding_buildflags.h"
 #include "build/chromeos_buildflags.h"
+#if defined(OS_WIN)
+#include "services/shape_detection/barcode_detection_provider_impl.h"
+#include "services/shape_detection/face_detection_provider_win.h"
+#elif defined(OS_MAC)
+#include "services/shape_detection/barcode_detection_provider_mac.h"
+#include "services/shape_detection/face_detection_provider_mac.h"
+#elif BUILDFLAG(GOOGLE_CHROME_BRANDING) && BUILDFLAG(IS_CHROMEOS_ASH)
+#include "services/shape_detection/barcode_detection_provider_barhopper.h"
+#include "services/shape_detection/face_detection_provider_impl.h"
+#else
+#include "services/shape_detection/barcode_detection_provider_impl.h"
+#include "services/shape_detection/face_detection_provider_impl.h"
+#endif
 #include "services/shape_detection/text_detection_impl.h"
 
 #if defined(OS_ANDROID)
@@ -17,26 +30,6 @@
 #include "services/shape_detection/shape_detection_jni_headers/InterfaceRegistrar_jni.h"
 #endif
 
-#if defined(OS_MAC)
-#include "services/shape_detection/barcode_detection_provider_mac.h"
-#elif defined(OS_ANDROID)
-// Barcode detection comes from Java.
-#elif BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#include "services/shape_detection/barcode_detection_provider_barhopper.h"
-#else
-#include "services/shape_detection/barcode_detection_provider_impl.h"
-#endif
-
-#if defined(OS_WIN)
-#include "services/shape_detection/face_detection_provider_win.h"
-#elif defined(OS_MAC)
-#include "services/shape_detection/face_detection_provider_mac.h"
-#elif defined(OS_ANDROID)
-// Face detection comes from Java.
-#else
-#include "services/shape_detection/face_detection_provider_impl.h"
-#endif
-
 namespace shape_detection {
 
 ShapeDetectionService::ShapeDetectionService(
@@ -54,7 +47,7 @@
       receiver.PassPipe().release().value());
 #elif defined(OS_MAC)
   BarcodeDetectionProviderMac::Create(std::move(receiver));
-#elif BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#elif BUILDFLAG(GOOGLE_CHROME_BRANDING) && BUILDFLAG(IS_CHROMEOS_ASH)
   BarcodeDetectionProviderBarhopper::Create(std::move(receiver));
 #else
   BarcodeDetectionProviderImpl::Create(std::move(receiver));
diff --git a/services/tracing/perfetto/test_utils.cc b/services/tracing/perfetto/test_utils.cc
index 2d62455..a221737 100644
--- a/services/tracing/perfetto/test_utils.cc
+++ b/services/tracing/perfetto/test_utils.cc
@@ -443,7 +443,8 @@
   // Also tell PerfettoTracedProcess to use the current task environment.
   test_handle_ = PerfettoTracedProcess::SetupForTesting(
       base::ThreadTaskRunnerHandle::Get());
-  PerfettoTracedProcess::Get()->OnThreadPoolAvailable();
+  PerfettoTracedProcess::Get()->OnThreadPoolAvailable(
+      /* enable_consumer */ true);
 
   // Wait for any posted construction tasks to execute.
   RunUntilIdle();
diff --git a/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc b/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc
index fef347e..e72bcee 100644
--- a/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc
+++ b/services/tracing/public/cpp/perfetto/perfetto_traced_process.cc
@@ -268,7 +268,8 @@
   Get()->ClearDataSourcesForTesting();  // IN-TEST
   // On the first call within the process's lifetime, this will call
   // PerfettoTracedProcess::Get(), ensuring PerfettoTracedProcess is created.
-  InitTracingPostThreadPoolStartAndFeatureList();
+  InitTracingPostThreadPoolStartAndFeatureList(
+      /* enable_consumer */ true);
   // Disassociate the PerfettoTracedProcess from any prior task runner.
   DETACH_FROM_SEQUENCE(PerfettoTracedProcess::Get()->sequence_checker_);
   PerfettoTracedProcess::GetTaskRunner()->GetOrCreateTaskRunner()->PostTask(
@@ -338,7 +339,7 @@
   return true;
 }
 
-void PerfettoTracedProcess::SetupClientLibrary() {
+void PerfettoTracedProcess::SetupClientLibrary(bool enable_consumer) {
   perfetto::TracingInitArgs init_args;
   init_args.platform = platform_.get();
   init_args.custom_backend = tracing_backend_.get();
@@ -346,7 +347,12 @@
 // TODO(eseckler): Not yet supported on Android to avoid binary size regression
 // of the consumer IPC messages. We'll need a way to exclude them.
 #if defined(OS_POSIX) && !defined(OS_ANDROID)
-  if (ShouldSetupSystemTracing()) {
+  // We currently only use the client library system backend for the consumer
+  // side, which is only allowed in the browser process. Furthermore, on
+  // non-Android platforms, sandboxed processes need to delegate the socket
+  // connections to the browser, but this delegation hasn't been hooked up in
+  // the client library yet.
+  if (ShouldSetupSystemTracing() && enable_consumer) {
     init_args.backends |= perfetto::kSystemBackend;
     init_args.tracing_policy = this;
   }
@@ -358,8 +364,8 @@
   perfetto::Tracing::Initialize(init_args);
 }
 
-void PerfettoTracedProcess::OnThreadPoolAvailable() {
-  SetupClientLibrary();
+void PerfettoTracedProcess::OnThreadPoolAvailable(bool enable_consumer) {
+  SetupClientLibrary(enable_consumer);
 
   // Create our task runner now, so that ProducerClient/SystemProducer are
   // notified about future data source registrations and schedule any necessary
diff --git a/services/tracing/public/cpp/perfetto/perfetto_traced_process.h b/services/tracing/public/cpp/perfetto/perfetto_traced_process.h
index 065eedf..04688e44 100644
--- a/services/tracing/public/cpp/perfetto/perfetto_traced_process.h
+++ b/services/tracing/public/cpp/perfetto/perfetto_traced_process.h
@@ -207,7 +207,7 @@
                            bool privacy_filtering_enabled);
 
   // Called on the process's main thread once the thread pool is ready.
-  void OnThreadPoolAvailable();
+  void OnThreadPoolAvailable(bool enable_consumer);
 
   // Set a callback that returns whether a system tracing session is allowed.
   // The callback will be executed on the sequence that set it. Only a single
@@ -288,7 +288,9 @@
 
   // Initialize the Perfetto client library (i.e., perfetto::Tracing) for this
   // process.
-  void SetupClientLibrary();
+  // |enable_consumer| should be true if the system consumer can be enabled.
+  // Currently this is only the case if this is running in the browser process.
+  void SetupClientLibrary(bool enable_consumer);
 
   // perfetto::TracingPolicy implementation:
   void ShouldAllowConsumerSession(
diff --git a/services/tracing/public/cpp/trace_startup.cc b/services/tracing/public/cpp/trace_startup.cc
index 0495282..e0a92ef 100644
--- a/services/tracing/public/cpp/trace_startup.cc
+++ b/services/tracing/public/cpp/trace_startup.cc
@@ -89,14 +89,14 @@
       privacy_filtering_enabled);
 }
 
-void InitTracingPostThreadPoolStartAndFeatureList() {
+void InitTracingPostThreadPoolStartAndFeatureList(bool enable_consumer) {
   if (g_tracing_initialized_after_threadpool_and_featurelist)
     return;
   g_tracing_initialized_after_threadpool_and_featurelist = true;
   DCHECK(base::ThreadPoolInstance::Get());
   DCHECK(base::FeatureList::GetInstance());
 
-  PerfettoTracedProcess::Get()->OnThreadPoolAvailable();
+  PerfettoTracedProcess::Get()->OnThreadPoolAvailable(enable_consumer);
 
   if (ShouldSetupSystemTracing()) {
     // Ensure that data sources are created and registered.
diff --git a/services/tracing/public/cpp/trace_startup.h b/services/tracing/public/cpp/trace_startup.h
index e47d1597..b3f075c 100644
--- a/services/tracing/public/cpp/trace_startup.h
+++ b/services/tracing/public/cpp/trace_startup.h
@@ -45,8 +45,10 @@
 
 // Initialize tracing components that require task runners. Will switch
 // IsTracingInitialized() to return true.
+// |enable_consumer| should be true if the system consumer can be enabled.
+// Currently this is only the case if this is running in the browser process.
 void COMPONENT_EXPORT(TRACING_CPP)
-    InitTracingPostThreadPoolStartAndFeatureList();
+    InitTracingPostThreadPoolStartAndFeatureList(bool enable_consumer);
 
 // If tracing is enabled, grabs the current trace config & mode and tells the
 // child to begin tracing right away via startup tracing command line flags.
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 98445e5..968b217 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -144,7 +144,6 @@
                         "promo_card_max_shown": "3"
                     },
                     "enable_features": [
-                        "ContextualSearchLongpressResolve",
                         "ContextualSearchNewSettings",
                         "ContextualSearchTranslations"
                     ]
@@ -591,7 +590,7 @@
             ]
         }
     ],
-    "AndroidMessagesSavePassword": [
+    "AndroidMessagesSaveUpdatePassword": [
         {
             "platforms": [
                 "android"
@@ -600,7 +599,8 @@
                 {
                     "name": "Enabled",
                     "enable_features": [
-                        "MessagesForAndroidPasswords"
+                        "MessagesForAndroidPasswords",
+                        "MessagesForAndroidUpdatePassword"
                     ]
                 }
             ]
@@ -621,21 +621,6 @@
             ]
         }
     ],
-    "AndroidMessagesUpdatePassword": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "MessagesForAndroidUpdatePassword"
-                    ]
-                }
-            ]
-        }
-    ],
     "AndroidPictureInPictureAPI": [
         {
             "platforms": [
@@ -1162,7 +1147,23 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_2020-02-25",
+                    "name": "Enabled_2021-12-01",
+                    "enable_features": [
+                        "AutofillEnableSupportForMoreStructureInAddresses"
+                    ]
+                }
+            ]
+        }
+    ],
+    "AutofillEnableSupportForMoreStructureInAddressesOnWebView": [
+        {
+            "platforms": [
+                "android_webview",
+                "android_weblayer"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_2021-12-01",
                     "enable_features": [
                         "AutofillEnableSupportForMoreStructureInAddresses"
                     ]
@@ -1183,7 +1184,23 @@
             ],
             "experiments": [
                 {
-                    "name": "EnableSupportForMoreStructureInNames",
+                    "name": "Enabled_2021-12-01",
+                    "enable_features": [
+                        "AutofillEnableSupportForMoreStructureInNames"
+                    ]
+                }
+            ]
+        }
+    ],
+    "AutofillEnableSupportForMoreStructureInNamesOnWebView": [
+        {
+            "platforms": [
+                "android_webview",
+                "android_weblayer"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_2021-12-01",
                     "enable_features": [
                         "AutofillEnableSupportForMoreStructureInNames"
                     ]
@@ -2640,7 +2657,10 @@
             ],
             "experiments": [
                 {
-                    "name": "Launch-candidate_20210915",
+                    "name": "Launch-candidate_20211129",
+                    "enable_features": [
+                        "ContextualSearchLongpressResolve"
+                    ],
                     "disable_features": [
                         "ContextualSearchLiteralSearchTap"
                     ]
@@ -5275,25 +5295,6 @@
             ]
         }
     ],
-    "NavigationPredictor": [
-        {
-            "platforms": [
-                "android",
-                "android_weblayer"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_Logistic_Precision_15_M79_20191029",
-                    "params": {
-                        "random_anchor_sampling_period": "100"
-                    },
-                    "enable_features": [
-                        "NavigationPredictor"
-                    ]
-                }
-            ]
-        }
-    ],
     "NavigationThreadingOptimizations": [
         {
             "platforms": [
@@ -6222,7 +6223,7 @@
             ]
         }
     ],
-    "PreconnectToSearch": [
+    "PreconnectToSearchDesktop": [
         {
             "platforms": [
                 "linux",
@@ -6233,10 +6234,10 @@
             ],
             "experiments": [
                 {
-                    "name": "EnabledWithoutStartupDelay",
+                    "name": "EnabledWithStartupDelayForegroundOnly",
                     "params": {
                         "skip_in_background": "true",
-                        "startup_delay_ms": "0"
+                        "startup_delay_ms": "5000"
                     },
                     "enable_features": [
                         "PreconnectToSearch"
diff --git a/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc b/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc
index bca469b..880fca7 100644
--- a/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc
+++ b/third_party/blink/common/bluetooth/web_bluetooth_device_id.cc
@@ -13,59 +13,56 @@
 
 namespace blink {
 
-namespace {
-
-enum { kDeviceIdLength = 16 /* 128 bits */ };
-
-}  // namespace
-
 WebBluetoothDeviceId::WebBluetoothDeviceId() {}
 
-WebBluetoothDeviceId::WebBluetoothDeviceId(std::string device_id)
-    : device_id_(std::move(device_id)) {
-  CHECK(IsValid());
+WebBluetoothDeviceId::WebBluetoothDeviceId(
+    const std::string& encoded_device_id) {
+  std::string decoded;
+
+  DCHECK(WebBluetoothDeviceId::IsValid(encoded_device_id));
+  DCHECK(base::Base64Decode(encoded_device_id, &decoded));
+
+  std::copy_n(decoded.begin(), device_id_.size(), device_id_.begin());
+  is_initialized_ = true;
 }
 
 WebBluetoothDeviceId::~WebBluetoothDeviceId() {}
 
-const std::string& WebBluetoothDeviceId::str() const {
+WebBluetoothDeviceId::WebBluetoothDeviceId(
+    const WebBluetoothDeviceIdKey& device_id)
+    : device_id_(device_id), is_initialized_(true) {}
+
+std::string WebBluetoothDeviceId::DeviceIdInBase64() const {
+  CHECK(IsValid());
+  return base::Base64Encode(device_id_);
+}
+
+std::string WebBluetoothDeviceId::str() const {
+  return WebBluetoothDeviceId::DeviceIdInBase64();
+}
+
+const WebBluetoothDeviceIdKey& WebBluetoothDeviceId::DeviceId() const {
   CHECK(IsValid());
   return device_id_;
 }
 
 // static
 WebBluetoothDeviceId WebBluetoothDeviceId::Create() {
-  std::string bytes(
-      kDeviceIdLength + 1 /* to avoid bytes being reallocated by WriteInto */,
-      '\0');
+  WebBluetoothDeviceIdKey bytes;
 
-  crypto::RandBytes(base::WriteInto(&bytes /* str */,
-                                    kDeviceIdLength + 1 /* length_with_null */),
-                    kDeviceIdLength);
-
-  base::Base64Encode(bytes, &bytes);
+  crypto::RandBytes(bytes);
 
   return WebBluetoothDeviceId(std::move(bytes));
 }
 
 // static
-bool WebBluetoothDeviceId::IsValid(const std::string& device_id) {
+bool WebBluetoothDeviceId::IsValid(const std::string& encoded_device_id) {
   std::string decoded;
-  if (!base::Base64Decode(device_id, &decoded)) {
+  if (!base::Base64Decode(encoded_device_id, &decoded)) {
     return false;
   }
 
-  if (decoded.size() != kDeviceIdLength) {
-    return false;
-  }
-
-  // When base64-encoding a 128bit string, only the two MSB are used for
-  // the 3rd-to-last character. Because of this, the 3rd-to-last character
-  // can only be one of this four characters.
-  if (!(device_id[device_id.size() - 3] == 'A' ||
-        device_id[device_id.size() - 3] == 'Q' ||
-        device_id[device_id.size() - 3] == 'g' ||
-        device_id[device_id.size() - 3] == 'w')) {
+  if (decoded.size() != sizeof(WebBluetoothDeviceIdKey)) {
     return false;
   }
 
@@ -73,12 +70,12 @@
 }
 
 bool WebBluetoothDeviceId::IsValid() const {
-  return WebBluetoothDeviceId::IsValid(device_id_);
+  return is_initialized_;
 }
 
 bool WebBluetoothDeviceId::operator==(
     const WebBluetoothDeviceId& device_id) const {
-  return str() == device_id.str();
+  return this->DeviceId() == device_id.DeviceId();
 }
 
 bool WebBluetoothDeviceId::operator!=(
@@ -88,7 +85,7 @@
 
 bool WebBluetoothDeviceId::operator<(
     const WebBluetoothDeviceId& device_id) const {
-  return str() < device_id.str();
+  return this->str() < device_id.str();
 }
 
 std::ostream& operator<<(std::ostream& out,
diff --git a/third_party/blink/common/bluetooth/web_bluetooth_device_id_unittest.cc b/third_party/blink/common/bluetooth/web_bluetooth_device_id_unittest.cc
index 77130911..4ff8139 100644
--- a/third_party/blink/common/bluetooth/web_bluetooth_device_id_unittest.cc
+++ b/third_party/blink/common/bluetooth/web_bluetooth_device_id_unittest.cc
@@ -20,6 +20,10 @@
 // A base64 string should have a length of a multiple of 4.
 const char kInvalidLengthDeviceId[] = "123456789012345678901";
 
+const blink::WebBluetoothDeviceIdKey kValidArrDeviceId1 = {
+    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+const blink::WebBluetoothDeviceIdKey kValidArrDeviceId2 = {
+    11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26};
 }  // namespace
 
 TEST(WebBluetoothDeviceIdTest, DefaultConstructor) {
@@ -61,6 +65,15 @@
       [&]() { return WebBluetoothDeviceId(kInvalidLengthDeviceId); }(), "");
 }
 
+TEST(WebBluetoothDeviceIdTest, ArrConstructor) {
+  WebBluetoothDeviceId valid1(kValidArrDeviceId1);
+  WebBluetoothDeviceId valid2(kValidArrDeviceId2);
+
+  EXPECT_TRUE(valid1 == valid1);
+  EXPECT_TRUE(valid2 == valid2);
+  EXPECT_TRUE(valid1 != valid2);
+}
+
 TEST(WebBluetoothDeviceIdTest, IsValid_Valid) {
   EXPECT_TRUE(WebBluetoothDeviceId::IsValid(kValidDeviceId1));
   EXPECT_TRUE(WebBluetoothDeviceId::IsValid(kValidDeviceId2));
diff --git a/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h b/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h
index 98d7dab4..1fc53a3a 100644
--- a/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h
+++ b/third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h
@@ -5,15 +5,17 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_BLUETOOTH_WEB_BLUETOOTH_DEVICE_ID_H_
 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_BLUETOOTH_WEB_BLUETOOTH_DEVICE_ID_H_
 
+#include <array>
 #include <string>
 
 #include "third_party/blink/public/common/common_export.h"
 
 namespace blink {
 
+using WebBluetoothDeviceIdKey = std::array<uint8_t, 16>;
+
 // Used to uniquely identify a Bluetooth Device for an Origin.
-// A WebBluetoothDeviceId is generated by base64-encoding a 128bit
-// string.
+// A WebBluetoothDeviceId represents a 128bit key for bluetooth device id.
 class BLINK_COMMON_EXPORT WebBluetoothDeviceId {
  public:
   // Default constructor that creates an invalid id. We implement it so that
@@ -23,7 +25,10 @@
   WebBluetoothDeviceId();
 
   // CHECKS that |device_id| is valid.
-  explicit WebBluetoothDeviceId(std::string device_id);
+  explicit WebBluetoothDeviceId(const WebBluetoothDeviceIdKey& device_id);
+
+  // CHECKS that |encoded_device_id| is a valid base64-encoded string.
+  explicit WebBluetoothDeviceId(const std::string& encoded_device_id);
 
   // Copyable.
   WebBluetoothDeviceId(const WebBluetoothDeviceId& other) = default;
@@ -35,16 +40,22 @@
 
   ~WebBluetoothDeviceId();
 
-  // Returns the string that represents this WebBluetoothDeviceId.
-  const std::string& str() const;
+  // Returns the base64 encoded string of `device_id_`.
+  std::string DeviceIdInBase64() const;
+
+  // Returns the serialization of the object.
+  std::string str() const;
+
+  // `device_id_` getter.
+  const WebBluetoothDeviceIdKey& DeviceId() const;
 
   // The returned WebBluetoothDeviceId is generated by creating a random 128bit
-  // string and base64-encoding it.
+  // binary key.
   static WebBluetoothDeviceId Create();
 
-  // This method will return true. if |device_id| results in a 128bit
+  // This method will return true. if |encoded_device_id| results in a 128bit
   // base64-encoding string. Otherwise returns false.
-  static bool IsValid(const std::string& device_id);
+  static bool IsValid(const std::string& encoded_device_id);
 
   bool IsValid() const;
 
@@ -53,7 +64,8 @@
   bool operator<(const WebBluetoothDeviceId& device_id) const;
 
  private:
-  std::string device_id_;
+  WebBluetoothDeviceIdKey device_id_;
+  bool is_initialized_ = false;
 };
 
 // This is required by gtest to print a readable output on test failures.
diff --git a/third_party/blink/public/common/bluetooth/web_bluetooth_device_id_mojom_traits.h b/third_party/blink/public/common/bluetooth/web_bluetooth_device_id_mojom_traits.h
index 59e60a0..44e3fec 100644
--- a/third_party/blink/public/common/bluetooth/web_bluetooth_device_id_mojom_traits.h
+++ b/third_party/blink/public/common/bluetooth/web_bluetooth_device_id_mojom_traits.h
@@ -5,8 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_BLUETOOTH_WEB_BLUETOOTH_DEVICE_ID_MOJOM_TRAITS_H_
 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_BLUETOOTH_WEB_BLUETOOTH_DEVICE_ID_MOJOM_TRAITS_H_
 
-#include <string>
-
 #include "third_party/blink/public/common/bluetooth/web_bluetooth_device_id.h"
 #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-shared.h"
 
@@ -15,19 +13,17 @@
 template <>
 struct StructTraits<blink::mojom::WebBluetoothDeviceIdDataView,
                     blink::WebBluetoothDeviceId> {
-  static const std::string& device_id(
+  static const blink::WebBluetoothDeviceIdKey device_id(
       const blink::WebBluetoothDeviceId& device_id) {
-    return device_id.str();
+    return device_id.DeviceId();
   }
 
   static bool Read(blink::mojom::WebBluetoothDeviceIdDataView input,
                    blink::WebBluetoothDeviceId* output) {
-    std::string result;
+    blink::WebBluetoothDeviceIdKey result;
 
     if (!input.ReadDeviceId(&result))
       return false;
-    if (!blink::WebBluetoothDeviceId::IsValid(result))
-      return false;
 
     *output = blink::WebBluetoothDeviceId(std::move(result));
     return true;
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 7efb1c1..c7425f6 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -1265,27 +1265,7 @@
 
   public_deps = [ "//device/bluetooth/public/mojom" ]
 
-  blink_cpp_typemaps = [
-    {
-      types = [
-        {
-          mojom = "blink.mojom.WebBluetoothDeviceId"
-          cpp = "::WTF::String"
-        },
-        {
-          mojom = "bluetooth.mojom.UUID"
-          cpp = "::WTF::String"
-          nullable_is_same_type = true
-        },
-      ]
-      traits_headers = [
-        "//third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h",
-      ]
-      traits_public_deps = [ "//device/bluetooth" ]
-    },
-  ]
-
-  cpp_typemaps = [
+  shared_cpp_typemaps = [
     {
       types = [
         {
@@ -1297,6 +1277,26 @@
     },
   ]
 
+  blink_cpp_typemaps = [
+    {
+      types = [
+        {
+          mojom = "bluetooth.mojom.UUID"
+          cpp = "::WTF::String"
+          nullable_is_same_type = true
+        },
+      ]
+      traits_private_headers = [
+        "//third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h",
+      ]
+      traits_public_deps = [ "//device/bluetooth" ]
+    },
+  ]
+
+  blink_cpp_typemaps += shared_cpp_typemaps
+
+  cpp_typemaps = shared_cpp_typemaps
+
   # The chromium variant must be linked with content and use the same export
   # settings in component build because of the WebBluetoothDeviceId typemap
   # inside content.
diff --git a/third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom b/third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom
index ca007008..c357bb4 100644
--- a/third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom
+++ b/third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom
@@ -156,7 +156,7 @@
 // to a common device. Web content may persist this identifier for future
 // sessions to identify the same device.
 struct WebBluetoothDeviceId {
-  string device_id;
+  array<uint8, 16> device_id;
 };
 
 struct WebBluetoothDevice {
diff --git a/third_party/blink/renderer/bindings/core/v8/module_record_test.cc b/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
index 61a8c2e..9cfc5ee 100644
--- a/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
+++ b/third_party/blink/renderer/bindings/core/v8/module_record_test.cc
@@ -105,13 +105,13 @@
   DummyModulator::Trace(visitor);
 }
 
-class ModuleRecordTest : public ::testing::Test, public ParametrizedModuleTest {
+class ModuleRecordTest : public ::testing::Test, public ModuleTestBase {
  public:
-  void SetUp() override { ParametrizedModuleTest::SetUp(); }
-  void TearDown() override { ParametrizedModuleTest::TearDown(); }
+  void SetUp() override { ModuleTestBase::SetUp(); }
+  void TearDown() override { ModuleTestBase::TearDown(); }
 };
 
-TEST_P(ModuleRecordTest, compileSuccess) {
+TEST_F(ModuleRecordTest, compileSuccess) {
   V8TestingScope scope;
   const KURL js_url("https://example.com/foo.js");
   v8::Local<v8::Module> module = ModuleTestBase::CompileModule(
@@ -119,7 +119,7 @@
   ASSERT_FALSE(module.IsEmpty());
 }
 
-TEST_P(ModuleRecordTest, compileFail) {
+TEST_F(ModuleRecordTest, compileFail) {
   V8TestingScope scope;
   const KURL js_url("https://example.com/foo.js");
   v8::Local<v8::Module> module = ModuleTestBase::CompileModule(
@@ -128,7 +128,7 @@
   EXPECT_TRUE(scope.GetExceptionState().HadException());
 }
 
-TEST_P(ModuleRecordTest, moduleRequests) {
+TEST_F(ModuleRecordTest, moduleRequests) {
   V8TestingScope scope;
   const KURL js_url("https://example.com/foo.js");
   v8::Local<v8::Module> module = ModuleTestBase::CompileModule(
@@ -144,7 +144,7 @@
   EXPECT_EQ(0u, requests[1].import_assertions.size());
 }
 
-TEST_P(ModuleRecordTest, moduleRequestsWithImportAssertions) {
+TEST_F(ModuleRecordTest, moduleRequestsWithImportAssertions) {
   V8TestingScope scope;
   v8::V8::SetFlagsFromString("--harmony-import-assertions");
   const KURL js_url("https://example.com/foo.js");
@@ -170,7 +170,7 @@
   EXPECT_EQ("z", requests[2].GetModuleTypeString());
 }
 
-TEST_P(ModuleRecordTest, instantiateNoDeps) {
+TEST_F(ModuleRecordTest, instantiateNoDeps) {
   V8TestingScope scope;
 
   auto* modulator =
@@ -188,7 +188,7 @@
   EXPECT_EQ(0u, resolver->ResolveCount());
 }
 
-TEST_P(ModuleRecordTest, instantiateWithDeps) {
+TEST_F(ModuleRecordTest, instantiateWithDeps) {
   V8TestingScope scope;
 
   auto* modulator =
@@ -221,7 +221,7 @@
   EXPECT_EQ("b", resolver->Specifiers()[1]);
 }
 
-TEST_P(ModuleRecordTest, EvaluationErrorIsRemembered) {
+TEST_F(ModuleRecordTest, EvaluationErrorIsRemembered) {
   V8TestingScope scope;
   ScriptState* state = scope.GetScriptState();
 
@@ -260,7 +260,7 @@
   EXPECT_EQ("failure", resolver->Specifiers()[0]);
 }
 
-TEST_P(ModuleRecordTest, Evaluate) {
+TEST_F(ModuleRecordTest, Evaluate) {
   V8TestingScope scope;
 
   auto* modulator =
@@ -295,7 +295,7 @@
   EXPECT_EQ(42.0, exported_value->NumberValue(scope.GetContext()).ToChecked());
 }
 
-TEST_P(ModuleRecordTest, EvaluateCaptureError) {
+TEST_F(ModuleRecordTest, EvaluateCaptureError) {
   V8TestingScope scope;
 
   auto* modulator =
@@ -318,12 +318,6 @@
   EXPECT_EQ("bar", ToCoreString(exception.As<v8::String>()));
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(ModuleRecordTestGroup,
-                         ModuleRecordTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 }  // namespace
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index 4aea961..01fde62f 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -871,6 +871,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_bucket_options.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_modules.gni b/third_party/blink/renderer/bindings/idl_in_modules.gni
index a45b802..70e4ca0f 100644
--- a/third_party/blink/renderer/bindings/idl_in_modules.gni
+++ b/third_party/blink/renderer/bindings/idl_in_modules.gni
@@ -827,6 +827,7 @@
           "//third_party/blink/renderer/modules/webcodecs/image_track_list.idl",
           "//third_party/blink/renderer/modules/webcodecs/latency_mode.idl",
           "//third_party/blink/renderer/modules/webcodecs/plane_layout.idl",
+          "//third_party/blink/renderer/modules/webcodecs/svc_output_metadata.idl",
           "//third_party/blink/renderer/modules/webcodecs/video_color_primaries.idl",
           "//third_party/blink/renderer/modules/webcodecs/video_color_space.idl",
           "//third_party/blink/renderer/modules/webcodecs/video_color_space_init.idl",
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index 6bf92321..ede82f0 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -435,9 +435,11 @@
     if (features::IsFencedFramesMPArchBased()) {
       for (HTMLFencedFrameElement* fenced_frame :
            DocumentFencedFrames::From(*document).GetFencedFrames()) {
-        RemoteFrame* frame = To<RemoteFrame>(fenced_frame->ContentFrame());
-        if (RemoteFrameView* view = frame->View())
-          function(*view);
+        if (RemoteFrame* frame =
+                To<RemoteFrame>(fenced_frame->ContentFrame())) {
+          if (RemoteFrameView* view = frame->View())
+            function(*view);
+        }
       }
     }
   }
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
index 392a54af..2c8f75b 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
@@ -65,6 +65,10 @@
   }
 }
 
+NoAllocDirectCallHost* CanvasRenderingContext::AsNoAllocDirectCallHost() {
+  return nullptr;
+}
+
 void CanvasRenderingContext::DidDraw(
     const SkIRect& dirty_rect,
     CanvasPerformanceMonitor::DrawType draw_type) {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
index 7bd5e397e..525f910 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -47,6 +47,7 @@
 class CanvasImageSource;
 class HTMLCanvasElement;
 class ImageBitmap;
+class NoAllocDirectCallHost;
 class
     V8UnionCanvasRenderingContext2DOrGPUCanvasContextOrImageBitmapRenderingContextOrWebGL2RenderingContextOrWebGLRenderingContext;
 class
@@ -96,6 +97,8 @@
     return canvas_rendering_type_ == CanvasRenderingAPI::kWebgpu;
   }
 
+  virtual NoAllocDirectCallHost* AsNoAllocDirectCallHost();
+
   // ActiveScriptWrappable
   // As this class inherits from ActiveScriptWrappable, as long as
   // HasPendingActivity returns true, we can ensure that the Garbage Collector
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 988b225..bd4b5c1 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -94,6 +94,7 @@
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/no_alloc_direct_call_host.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
@@ -101,6 +102,7 @@
 #include "third_party/blink/renderer/platform/graphics/image_data_buffer.h"
 #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image_to_video_frame_copier.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
 #include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h"
@@ -171,6 +173,7 @@
 }
 
 void HTMLCanvasElement::Dispose() {
+  disposing_ = true;
   // We need to record metrics before we dispose of anything
   if (context_)
     UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.HasRendered", bool(ResourceProvider()));
@@ -1583,9 +1586,41 @@
       checked_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max());
   // Subtracting two intptr_t that are known to be positive will never
   // underflow.
-  v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
-      externally_allocated_memory - externally_allocated_memory_);
-  externally_allocated_memory_ = externally_allocated_memory;
+  intptr_t delta_bytes =
+      externally_allocated_memory - externally_allocated_memory_;
+
+  // If the the rendering context supports NoAllocDirectCall, we must use a
+  // deferrable action to update v8's externally allocated memory to avoid
+  // triggering garbage collection while inside a FastAPICall scope.
+  // TODO(junov): We assume that it is impossible to be inside a FastAPICall
+  // from a host interface other than the rendering context.  This assumption
+  // may need to be revisited in the future depending on how the usage of
+  // [NoAllocDirectCall] evolves.
+  if (delta_bytes) {
+    NoAllocDirectCallHost* nadc_host =
+        context_ ? context_->AsNoAllocDirectCallHost() : nullptr;
+    if (nadc_host) {
+      nadc_host->PostDeferrableAction(WTF::Bind(
+          [](intptr_t delta_bytes) {
+            v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+                delta_bytes);
+          },
+          delta_bytes));
+    } else {
+      // Here we check "IsAllocationAllowed", but it is actually garbage
+      // collection that is not allowed, and allocations can trigger GC.
+      // AdjustAmountOfExternalAllocatedMemory is not an allocation but it
+      // can trigger GC, So we use "IsAllocationAllowed" as a proxy for
+      // "is GC allowed". When garbage collection is already in progress,
+      // allocations are not allowed, but calling
+      // AdjustAmountOfExternalAllocatedMemory is safe, hence the
+      // 'diposing_' condition in the DCHECK below.
+      DCHECK(ThreadState::Current()->IsAllocationAllowed() || disposing_);
+      v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+          delta_bytes);
+    }
+    externally_allocated_memory_ = externally_allocated_memory;
+  }
 }
 
 size_t HTMLCanvasElement::GetMemoryUsage() const {
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
index a108a37..d80bea1f 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
@@ -387,6 +387,7 @@
   // Used only for WebGL currently.
   bool context_creation_was_blocked_;
 
+  bool disposing_ = false;
   bool canvas_is_clear_ = true;
 
   bool ignore_reset_;
diff --git a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
index 2b11b88..b6cfb95 100644
--- a/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
+++ b/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc
@@ -539,9 +539,10 @@
   // We dispatch events on the owner element to match the legacy behavior.
   // Other browsers dispatch click events before and after showing the popup.
   if (owner_element_) {
-    // TODO(dtapuska): Why is this event positionless?
     WebMouseEvent event;
     event.SetFrameScale(1);
+    PhysicalRect bounding_box = owner_element_->BoundingBox();
+    event.SetPositionInWidget(bounding_box.X(), bounding_box.Y());
     Element* owner = &OwnerElement();
     if (LocalFrame* frame = owner->GetDocument().GetFrame()) {
       frame->GetEventHandler().HandleTargetedMouseEvent(
diff --git a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc
index de50c90..51c7ca96 100644
--- a/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/custom/layout_worklet_test.cc
@@ -21,10 +21,10 @@
 
 namespace blink {
 
-class LayoutWorkletTest : public PageTestBase, public ParametrizedModuleTest {
+class LayoutWorkletTest : public PageTestBase, public ModuleTestBase {
  public:
   void SetUp() override {
-    ParametrizedModuleTest::SetUp();
+    ModuleTestBase::SetUp();
     PageTestBase::SetUp(IntSize());
     layout_worklet_ =
         MakeGarbageCollected<LayoutWorklet>(*GetDocument().domWindow());
@@ -33,7 +33,7 @@
 
   void TearDown() override {
     PageTestBase::TearDown();
-    ParametrizedModuleTest::TearDown();
+    ModuleTestBase::TearDown();
   }
 
   LayoutWorkletGlobalScopeProxy* GetProxy() {
@@ -78,7 +78,7 @@
   Persistent<LayoutWorklet> layout_worklet_;
 };
 
-TEST_P(LayoutWorkletTest, ParseProperties) {
+TEST_F(LayoutWorkletTest, ParseProperties) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -114,7 +114,7 @@
 // TODO(ikilpatrick): Move all the tests below to wpt tests once we have the
 // layout API actually have effects that we can test in script.
 
-TEST_P(LayoutWorkletTest, RegisterLayout) {
+TEST_F(LayoutWorkletTest, RegisterLayout) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -137,7 +137,7 @@
   EXPECT_FALSE(GetResult(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_EmptyName) {
+TEST_F(LayoutWorkletTest, RegisterLayout_EmptyName) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('', class {
@@ -148,7 +148,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_Duplicate) {
+TEST_F(LayoutWorkletTest, RegisterLayout_Duplicate) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -165,7 +165,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_NoIntrinsicSizes) {
+TEST_F(LayoutWorkletTest, RegisterLayout_NoIntrinsicSizes) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -176,7 +176,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_ThrowingPropertyGetter) {
+TEST_F(LayoutWorkletTest, RegisterLayout_ThrowingPropertyGetter) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -188,7 +188,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_BadPropertyGetter) {
+TEST_F(LayoutWorkletTest, RegisterLayout_BadPropertyGetter) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -200,7 +200,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_NoPrototype) {
+TEST_F(LayoutWorkletTest, RegisterLayout_NoPrototype) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     const foo = function() { };
@@ -212,7 +212,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_BadPrototype) {
+TEST_F(LayoutWorkletTest, RegisterLayout_BadPrototype) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     const foo = function() { };
@@ -224,7 +224,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_BadIntrinsicSizes) {
+TEST_F(LayoutWorkletTest, RegisterLayout_BadIntrinsicSizes) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -236,7 +236,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_NoLayout) {
+TEST_F(LayoutWorkletTest, RegisterLayout_NoLayout) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -248,7 +248,7 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-TEST_P(LayoutWorkletTest, RegisterLayout_BadLayout) {
+TEST_F(LayoutWorkletTest, RegisterLayout_BadLayout) {
   ScriptState::Scope scope(GetScriptState());
   ScriptEvaluationResult result = EvaluateScriptModule(R"JS(
     registerLayout('foo', class {
@@ -261,10 +261,4 @@
   EXPECT_FALSE(GetException(GetScriptState(), result).IsEmpty());
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(LayoutWorkletTestGroup,
-                         LayoutWorkletTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
index c2dd015..f390e15e 100644
--- a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
+++ b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
@@ -32,6 +32,7 @@
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.h"
+#include "third_party/blink/renderer/platform/bindings/no_alloc_direct_call_host.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
@@ -39,6 +40,7 @@
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/image-encoders/image_encoder_utils.h"
 #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -108,6 +110,7 @@
 
 void OffscreenCanvas::Dispose() {
   // We need to drop frame dispatcher, to prevent mojo calls from completing.
+  disposing_ = true;
   frame_dispatcher_ = nullptr;
   DiscardResourceProvider();
 
@@ -558,9 +561,39 @@
   int32_t new_memory_usage =
       memory_usage_checked.ValueOrDefault(std::numeric_limits<int32_t>::max());
 
-  v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
-      new_memory_usage - memory_usage_);
-  memory_usage_ = new_memory_usage;
+  // If the the rendering context supports NoAllocDirectCall, we must use a
+  // deferrable action to update v8's externally allocated memory to avoid
+  // triggering garbage collection while inside a FastAPICall scope.
+  // TODO(junov): We assume that it is impossible to be inside a FastAPICall
+  // from a host interface other than the rendering context.  This assumption
+  // may need to be revisited in the future depending on how the usage of
+  // [NoAllocDirectCall] evolves.
+  intptr_t delta_bytes = new_memory_usage - memory_usage_;
+  if (delta_bytes) {
+    NoAllocDirectCallHost* nadc_host =
+        context_ ? context_->AsNoAllocDirectCallHost() : nullptr;
+    if (nadc_host) {
+      nadc_host->PostDeferrableAction(WTF::Bind(
+          [](intptr_t delta_bytes) {
+            v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+                delta_bytes);
+          },
+          delta_bytes));
+    } else {
+      // Here we check "IsAllocationAllowed", but it is actually garbage
+      // collection that is not allowed, and allocations can trigger GC.
+      // AdjustAmountOfExternalAllocatedMemory is not an allocation but it
+      // can trigger GC, So we use "IsAllocationAllowed" as a proxy for
+      // "is GC allowed". When garbage collection is already in progress,
+      // allocations are not allowed, but calling
+      // AdjustAmountOfExternalAllocatedMemory is safe, hence the
+      // 'diposing_' condition in the DCHECK below.
+      DCHECK(ThreadState::Current()->IsAllocationAllowed() || disposing_);
+      v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
+          delta_bytes);
+    }
+    memory_usage_ = new_memory_usage;
+  }
 }
 
 size_t OffscreenCanvas::GetMemoryUsage() const {
diff --git a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
index 1e58a89..421a46c 100644
--- a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
+++ b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
@@ -244,6 +244,7 @@
   DOMNodeId placeholder_canvas_id_ = kInvalidDOMNodeId;
 
   IntSize size_;
+  bool disposing_ = false;
   bool is_neutered_ = false;
   bool origin_clean_ = true;
   bool disable_reading_from_canvas_ = false;
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.cc b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
index 2c4d45fd..f950753 100644
--- a/third_party/blink/renderer/core/page/pointer_lock_controller.cc
+++ b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
@@ -109,14 +109,6 @@
     return promise;
   }
 
-  if (window->GetFrame()->IsInFencedFrameTree()) {
-    EnqueueEvent(event_type_names::kPointerlockerror, target);
-    exception_state.ThrowSecurityError(
-        "Blocked pointer lock on an element because the element is contained "
-        "in a fence frame tree");
-    return promise;
-  }
-
   bool unadjusted_movement_requested =
       options ? options->unadjustedMovement() : false;
   if (element_) {
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
index 47d0c17..a3ba633bd 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -51,6 +51,7 @@
   const ComputedStyle& style = layout_object.StyleRef();
 
   reasons |= CompositingReasonsFor3DTransform(layout_object);
+  reasons |= CompositingReasonsFor3DSceneLeaf(layout_object);
 
   if (style.BackfaceVisibility() == EBackfaceVisibility::kHidden)
     reasons |= CompositingReason::kBackfaceVisibilityHidden;
@@ -130,16 +131,18 @@
   if (object.GetDocument().Printing())
     return CompositingReason::kNone;
 
+  auto reasons = CompositingReasonsFor3DSceneLeaf(object);
+
   // TODO(wangxianzhu): Don't depend on PaintLayer for CompositeAfterPaint.
   if (!object.HasLayer()) {
     if (object.IsSVGChild())
-      return DirectReasonsForSVGChildPaintProperties(object);
-    return CompositingReason::kNone;
+      reasons |= DirectReasonsForSVGChildPaintProperties(object);
+    return reasons;
   }
 
   const ComputedStyle& style = object.StyleRef();
-  auto reasons = CompositingReasonsForAnimation(object) |
-                 CompositingReasonsForWillChange(style);
+  reasons |= CompositingReasonsForAnimation(object) |
+             CompositingReasonsForWillChange(style);
 
   reasons |= CompositingReasonsFor3DTransform(object);
 
@@ -230,13 +233,18 @@
   if (object.IsText())
     return CompositingReason::kNone;
 
-  // Disable compositing of SVG if there is clip-path or mask to avoid hairline
-  // along the edges. TODO(crbug.com/1171601): Fix the root cause.
+  // Even though SVG doesn't support 3D transforms, it might be the leaf
+  // of a 3D scene that contains it.
+  auto reasons = CompositingReasonsFor3DSceneLeaf(object);
+
+  // Disable compositing of SVG, except in the cases where it is required for
+  // correctness, if there is clip-path or mask to avoid hairline along the
+  // edges. TODO(crbug.com/1171601): Fix the root cause.
   const ComputedStyle& style = object.StyleRef();
   if (style.HasClipPath() || style.HasMask())
-    return CompositingReason::kNone;
+    return reasons;
 
-  auto reasons = CompositingReasonsForAnimation(object);
+  reasons |= CompositingReasonsForAnimation(object);
   reasons |= CompositingReasonsForWillChange(style);
   // Exclude will-change for other properties some of which don't apply to SVG
   // children, e.g. 'top'.
@@ -278,6 +286,34 @@
   return PotentialCompositingReasonsFor3DTransform(layout_object.StyleRef());
 }
 
+CompositingReasons CompositingReasonFinder::CompositingReasonsFor3DSceneLeaf(
+    const LayoutObject& layout_object) {
+  // An effect node (and, eventually, a render pass created due to
+  // cc::RenderSurfaceReason::k3dTransformFlattening) is required for an
+  // element that doesn't preserve 3D but is treated as a 3D object by its
+  // parent.  See
+  // https://bugs.chromium.org/p/chromium/issues/detail?id=1256990#c2 for some
+  // notes on why this is needed.  Briefly, we need to ensure that we don't
+  // output quads with a 3d sorting_context of 0 in the middle of the quads
+  // that need to be 3D sorted; this is needed to contain any such quads in a
+  // separate render pass.
+  //
+  // Note that this is done even on elements that don't create a stacking
+  // context, and this appears to work.
+  //
+  // This could be improved by skipping this if we know that the
+  // descendants won't produce any quads in the render pass's quad list.
+  if (layout_object.IsForElement() && !layout_object.StyleRef().Preserves3D()) {
+    const LayoutObject* parent_object =
+        layout_object.NearestAncestorForElement();
+    if (parent_object && parent_object->StyleRef().Preserves3D()) {
+      return CompositingReason::kTransform3DSceneLeaf;
+    }
+  }
+
+  return CompositingReason::kNone;
+}
+
 CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
     const PaintLayer& layer) {
   CompositingReasons direct_reasons = CompositingReason::kNone;
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
index 5f99805..8123ba1d 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
@@ -60,6 +60,8 @@
       const ComputedStyle&);
   static CompositingReasons CompositingReasonsFor3DTransform(
       const LayoutObject&);
+  static CompositingReasons CompositingReasonsFor3DSceneLeaf(
+      const LayoutObject&);
   static bool RequiresCompositingForRootScroller(const PaintLayer&);
 
   static CompositingReasons CompositingReasonsForScrollDependentPosition(
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
index 6e577b1a..1c38b92 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -356,7 +356,7 @@
 }
 
 TEST_P(CompositingReasonFinderTest,
-       CompositeWithBackfaceVisibilityAncestorAndPreserve3D) {
+       CompositeWithBackfaceVisibilityAncestorAndPreserve3DAncestor) {
   ScopedBackfaceVisibilityInteropForTest bfi_enabled(true);
 
   SetBodyInnerHTML(R"HTML(
@@ -371,6 +371,36 @@
 
   if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
     PaintLayer* target_layer = GetPaintLayerByElementId("target");
+    // This likely doesn't pass anymore, but I'm going to skip updating the
+    // non-CAP codepath.
+    EXPECT_REASONS(CompositingReason::kBackfaceInvisibility3DAncestor,
+                   target_layer->PotentialCompositingReasonsFromNonStyle());
+    EXPECT_EQ(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
+  }
+
+  EXPECT_REASONS(
+      CompositingReason::kBackfaceInvisibility3DAncestor |
+          CompositingReason::kTransform3DSceneLeaf,
+      DirectReasonsForPaintProperties(*GetLayoutObjectByElementId("target")));
+}
+
+TEST_P(CompositingReasonFinderTest,
+       CompositeWithBackfaceVisibilityAncestorAndPreserve3D) {
+  ScopedBackfaceVisibilityInteropForTest bfi_enabled(true);
+
+  SetBodyInnerHTML(R"HTML(
+    <!DOCTYPE html>
+    <style>
+      div { width: 100px; height: 100px; position: relative }
+    </style>
+    <div style="backface-visibility: hidden; transform-style: preserve-3d">
+      <div id=target style="transform-style: preserve-3d"></div>
+    </div>
+  )HTML");
+
+  if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+    // completely untested non-CAP test
+    PaintLayer* target_layer = GetPaintLayerByElementId("target");
     EXPECT_REASONS(CompositingReason::kBackfaceInvisibility3DAncestor,
                    target_layer->PotentialCompositingReasonsFromNonStyle());
     EXPECT_EQ(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
@@ -428,6 +458,8 @@
     PaintLayer* intermediate_layer = GetPaintLayerByElementId("intermediate");
     PaintLayer* target_layer = GetPaintLayerByElementId("target");
 
+    // This likely doesn't pass anymore, but I'm going to skip updating the
+    // non-CAP codepath.
     EXPECT_REASONS(
         CompositingReason::kBackfaceInvisibility3DAncestor,
         intermediate_layer->PotentialCompositingReasonsFromNonStyle());
@@ -438,7 +470,8 @@
     EXPECT_NE(kPaintsIntoOwnBacking, target_layer->GetCompositingState());
   }
 
-  EXPECT_REASONS(CompositingReason::kBackfaceInvisibility3DAncestor,
+  EXPECT_REASONS(CompositingReason::kBackfaceInvisibility3DAncestor |
+                     CompositingReason::kTransform3DSceneLeaf,
                  DirectReasonsForPaintProperties(
                      *GetLayoutObjectByElementId("intermediate")));
   EXPECT_REASONS(
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index fc739e74..c14f0bbd 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1198,8 +1198,14 @@
 
 static bool NeedsEffect(const LayoutObject& object,
                         CompositingReasons direct_compositing_reasons) {
-  if (object.IsText())
+  if (object.IsText()) {
+    DCHECK(
+        !(direct_compositing_reasons & CompositingReasonsForEffectProperty()));
     return false;
+  }
+
+  if (direct_compositing_reasons & CompositingReasonsForEffectProperty())
+    return true;
 
   const ComputedStyle& style = object.StyleRef();
 
@@ -1221,12 +1227,6 @@
 
     if (layer->HasNonIsolatedDescendantWithBlendMode())
       return true;
-
-    // An effect node is required by cc if the layer flattens its subtree but it
-    // is treated as a 3D object by its parent.
-    if (!layer->Preserves3D() && layer->HasSelfPaintingLayerDescendant() &&
-        layer->Parent() && layer->Parent()->Preserves3D())
-      return true;
   }
 
   SkBlendMode blend_mode = object.IsBlendingAllowed()
@@ -1242,9 +1242,6 @@
   if (style.Opacity() != 1.0f)
     return true;
 
-  if (direct_compositing_reasons & CompositingReasonsForEffectProperty())
-    return true;
-
   if (object.StyleRef().HasMask())
     return true;
 
@@ -1267,8 +1264,11 @@
   DCHECK(NeedsEffect(object_, full_context_.direct_compositing_reasons));
 
   if (!object_.HasLayer()) {
-    // An SVG object's effect never interleaves with clips.
-    DCHECK(object_.IsSVG());
+    // This is either SVG or it's the effect node to create flattening at the
+    // leaves of a 3D scene.
+    //
+    // Either way, the effect never interleaves with clips, because
+    // positioning is the only situation where clip order changes.
     return true;
   }
 
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
index 96c9c9d..654fb1a 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -3363,7 +3363,7 @@
   EXPECT_EQ(a_properties->Transform()->RenderingContextId(),
             d_properties->Transform()->RenderingContextId());
   EXPECT_FALSE(d_properties->Transform()->FlattensInheritedTransform());
-  EXPECT_EQ(d_properties->Effect(), nullptr);
+  EXPECT_NE(d_properties->Effect(), nullptr);
 }
 
 TEST_P(PaintPropertyTreeBuilderTest,
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
index 9de2b0c..3e5a622 100644
--- a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
+++ b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -201,17 +201,16 @@
   }
 };
 
-class DynamicModuleResolverTest : public testing::Test,
-                                  public ParametrizedModuleTest {
+class DynamicModuleResolverTest : public testing::Test, public ModuleTestBase {
  public:
-  void SetUp() override { ParametrizedModuleTest::SetUp(); }
+  void SetUp() override { ModuleTestBase::SetUp(); }
 
-  void TearDown() override { ParametrizedModuleTest::TearDown(); }
+  void TearDown() override { ModuleTestBase::TearDown(); }
 };
 
 }  // namespace
 
-TEST_P(DynamicModuleResolverTest, ResolveSuccess) {
+TEST_F(DynamicModuleResolverTest, ResolveSuccess) {
   V8TestingScope scope;
   auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>(
       scope.GetScriptState());
@@ -252,7 +251,7 @@
   EXPECT_EQ("hello", capture->CapturedValue());
 }
 
-TEST_P(DynamicModuleResolverTest, ResolveJSONModuleSuccess) {
+TEST_F(DynamicModuleResolverTest, ResolveJSONModuleSuccess) {
   V8TestingScope scope;
   auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>(
       scope.GetScriptState());
@@ -279,7 +278,7 @@
   // validated during DynamicModuleResolverTestModulator::FetchTree.
 }
 
-TEST_P(DynamicModuleResolverTest, ResolveSpecifierFailure) {
+TEST_F(DynamicModuleResolverTest, ResolveSpecifierFailure) {
   V8TestingScope scope;
   auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>(
       scope.GetScriptState());
@@ -309,7 +308,7 @@
   EXPECT_TRUE(capture->Message().StartsWith("Failed to resolve"));
 }
 
-TEST_P(DynamicModuleResolverTest, ResolveModuleTypeFailure) {
+TEST_F(DynamicModuleResolverTest, ResolveModuleTypeFailure) {
   V8TestingScope scope;
   auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>(
       scope.GetScriptState());
@@ -340,7 +339,7 @@
   EXPECT_EQ("\"notARealType\" is not a valid module type.", capture->Message());
 }
 
-TEST_P(DynamicModuleResolverTest, FetchFailure) {
+TEST_F(DynamicModuleResolverTest, FetchFailure) {
   V8TestingScope scope;
   auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>(
       scope.GetScriptState());
@@ -374,7 +373,7 @@
   EXPECT_TRUE(capture->Message().StartsWith("Failed to fetch"));
 }
 
-TEST_P(DynamicModuleResolverTest, ExceptionThrown) {
+TEST_F(DynamicModuleResolverTest, ExceptionThrown) {
   V8TestingScope scope;
   auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>(
       scope.GetScriptState());
@@ -415,7 +414,7 @@
   EXPECT_EQ("bar", capture->Message());
 }
 
-TEST_P(DynamicModuleResolverTest, ResolveWithNullReferrerScriptSuccess) {
+TEST_F(DynamicModuleResolverTest, ResolveWithNullReferrerScriptSuccess) {
   V8TestingScope scope;
   scope.GetDocument().SetURL(KURL("https://example.com"));
 
@@ -459,7 +458,7 @@
   EXPECT_EQ("hello", capture->CapturedValue());
 }
 
-TEST_P(DynamicModuleResolverTest, ResolveWithReferrerScriptInfoBaseURL) {
+TEST_F(DynamicModuleResolverTest, ResolveWithReferrerScriptInfoBaseURL) {
   V8TestingScope scope;
   scope.GetDocument().SetURL(KURL("https://example.com"));
 
@@ -484,10 +483,4 @@
   EXPECT_TRUE(modulator->fetch_tree_was_called());
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(DynamicModuleResolverTestGroup,
-                         DynamicModuleResolverTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/module_map_test.cc b/third_party/blink/renderer/core/script/module_map_test.cc
index 8d3659a..9f0e021 100644
--- a/third_party/blink/renderer/core/script/module_map_test.cc
+++ b/third_party/blink/renderer/core/script/module_map_test.cc
@@ -183,7 +183,7 @@
   test_requests_.clear();
 }
 
-class ModuleMapTest : public PageTestBase, public ParametrizedModuleTest {
+class ModuleMapTest : public PageTestBase, public ModuleTestBase {
  public:
   void SetUp() override;
   void TearDown() override;
@@ -197,7 +197,7 @@
 };
 
 void ModuleMapTest::SetUp() {
-  ParametrizedModuleTest::SetUp();
+  ModuleTestBase::SetUp();
   PageTestBase::SetUp(IntSize(500, 500));
   NavigateTo(KURL("https://example.com"));
   modulator_ = MakeGarbageCollected<ModuleMapTestModulator>(
@@ -206,11 +206,11 @@
 }
 
 void ModuleMapTest::TearDown() {
-  ParametrizedModuleTest::TearDown();
+  ModuleTestBase::TearDown();
   PageTestBase::TearDown();
 }
 
-TEST_P(ModuleMapTest, sequentialRequests) {
+TEST_F(ModuleMapTest, sequentialRequests) {
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
       platform;
   platform->AdvanceClockSeconds(1.);  // For non-zero DocumentParserTimings
@@ -257,7 +257,7 @@
   EXPECT_TRUE(client2->GetModuleScript());
 }
 
-TEST_P(ModuleMapTest, concurrentRequestsShouldJoin) {
+TEST_F(ModuleMapTest, concurrentRequestsShouldJoin) {
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
       platform;
   platform->AdvanceClockSeconds(1.);  // For non-zero DocumentParserTimings
@@ -297,10 +297,5 @@
   EXPECT_TRUE(client2->WasNotifyFinished());
   EXPECT_TRUE(client2->GetModuleScript());
 }
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(ModuleMapTestGroup,
-                         ModuleMapTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc b/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc
index b383fe3a..43a6db9 100644
--- a/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc
+++ b/third_party/blink/renderer/core/script/module_record_resolver_impl_test.cc
@@ -106,7 +106,7 @@
 }  // namespace
 
 class ModuleRecordResolverImplTest : public testing::Test,
-                                     public ParametrizedModuleTest {
+                                     public ModuleTestBase {
  public:
   void SetUp() override;
   void TearDown() override;
@@ -122,16 +122,16 @@
 };
 
 void ModuleRecordResolverImplTest::SetUp() {
-  ParametrizedModuleTest::SetUp();
+  ModuleTestBase::SetUp();
   platform_->AdvanceClockSeconds(1.);  // For non-zero DocumentParserTimings
   modulator_ = MakeGarbageCollected<ModuleRecordResolverImplTestModulator>();
 }
 
 void ModuleRecordResolverImplTest::TearDown() {
-  ParametrizedModuleTest::TearDown();
+  ModuleTestBase::TearDown();
 }
 
-TEST_P(ModuleRecordResolverImplTest, RegisterResolveSuccess) {
+TEST_F(ModuleRecordResolverImplTest, RegisterResolveSuccess) {
   V8TestingScope scope;
   ModuleRecordResolver* resolver =
       MakeGarbageCollected<ModuleRecordResolverImpl>(
@@ -157,10 +157,4 @@
       << "Unexpectedly fetched URL: " << modulator_->FetchedUrl().GetString();
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(ModuleRecordResolverImplTestGroup,
-                         ModuleRecordResolverImplTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/script/module_script_test.cc b/third_party/blink/renderer/core/script/module_script_test.cc
index adff78e..48ae257 100644
--- a/third_party/blink/renderer/core/script/module_script_test.cc
+++ b/third_party/blink/renderer/core/script/module_script_test.cc
@@ -66,7 +66,7 @@
 
 }  // namespace
 
-class ModuleScriptTest : public ::testing::Test, public ParametrizedModuleTest {
+class ModuleScriptTest : public ::testing::Test, public ModuleTestBase {
  protected:
   static String LargeSourceText(const char* suffix = nullptr) {
     StringBuilder builder;
@@ -129,11 +129,11 @@
     return handler->cached_metadata_discarded_;
   }
 
-  void SetUp() override { ParametrizedModuleTest::SetUp(); }
+  void SetUp() override { ModuleTestBase::SetUp(); }
 
   void TearDown() override {
     feature_list_.Reset();
-    ParametrizedModuleTest::TearDown();
+    ModuleTestBase::TearDown();
   }
 
   base::test::ScopedFeatureList feature_list_;
@@ -142,7 +142,7 @@
 // Test expectations depends on heuristics in V8CodeCache and therefore these
 // tests should be updated if necessary when V8CodeCache is modified. The
 // version without code cache discarding.
-TEST_P(ModuleScriptTest, V8CodeCacheWithoutDiscarding) {
+TEST_F(ModuleScriptTest, V8CodeCacheWithoutDiscarding) {
   feature_list_.InitAndDisableFeature(
       blink::features::kDiscardCodeCacheAfterFirstUse);
   using Checkpoint = testing::StrictMock<testing::MockFunction<void(int)>>;
@@ -260,7 +260,7 @@
 // Test expectations depends on heuristics in V8CodeCache and therefore these
 // tests should be updated if necessary when V8CodeCache is modified. The
 // version with code cache discarding.
-TEST_P(ModuleScriptTest, V8CodeCacheWithDiscarding) {
+TEST_F(ModuleScriptTest, V8CodeCacheWithDiscarding) {
   feature_list_.InitAndEnableFeature(
       blink::features::kDiscardCodeCacheAfterFirstUse);
   using Checkpoint = testing::StrictMock<testing::MockFunction<void(int)>>;
@@ -389,7 +389,7 @@
   EXPECT_FALSE(cache_handler->GetCachedMetadata(kCodeTag));
 }
 
-TEST_P(ModuleScriptTest, ValueWrapperSyntheticModuleScript) {
+TEST_F(ModuleScriptTest, ValueWrapperSyntheticModuleScript) {
   V8TestingScope scope;
   v8::Local<v8::Value> local_value(v8::Number::New(scope.GetIsolate(), 1234));
   Modulator* modulator =
@@ -399,7 +399,7 @@
   ASSERT_FALSE(module_script->V8Module().IsEmpty());
 }
 
-TEST_P(ModuleScriptTest, V8CodeCacheWithHashChecking) {
+TEST_F(ModuleScriptTest, V8CodeCacheWithHashChecking) {
   // The order of steps below is chosen so that only the last step's behavior
   // differs based on this flag. The important tests that verify rejection of
   // cache data on content mismatches occur before that point.
@@ -568,10 +568,4 @@
   }
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(ModuleScriptTestGroup,
-                         ModuleScriptTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/testing/module_test_base.cc b/third_party/blink/renderer/core/testing/module_test_base.cc
index 6697df81..7ee4c01 100644
--- a/third_party/blink/renderer/core/testing/module_test_base.cc
+++ b/third_party/blink/renderer/core/testing/module_test_base.cc
@@ -36,25 +36,8 @@
                                exception_state);
 }
 
-void ParametrizedModuleTestBase::SetUp(bool use_top_level_await) {
-  if (use_top_level_await) {
-    feature_list_.InitAndEnableFeature(features::kTopLevelAwait);
-  } else {
-    feature_list_.InitAndDisableFeature(features::kTopLevelAwait);
-  }
-  SetV8Flags(use_top_level_await);
-}
-
-void ParametrizedModuleTestBase::SetV8Flags(bool use_top_level_await) {
-  if (use_top_level_await) {
-    v8::V8::SetFlagsFromString("--harmony-top-level-await");
-  } else {
-    v8::V8::SetFlagsFromString("--no-harmony-top-level-await");
-  }
-}
-
-void ParametrizedModuleTest::SetUp() {
-  ParametrizedModuleTestBase::SetUp(UseTopLevelAwait());
+void ModuleTestBase::SetUp() {
+  feature_list_.InitAndEnableFeature(features::kTopLevelAwait);
 }
 
 class SaveResultFunction final : public NewScriptFunction::Callable {
@@ -86,14 +69,10 @@
   }
 };
 
-v8::Local<v8::Value> ParametrizedModuleTestBase::GetResult(
-    ScriptState* script_state,
-    ScriptEvaluationResult result) {
+v8::Local<v8::Value> ModuleTestBase::GetResult(ScriptState* script_state,
+                                               ScriptEvaluationResult result) {
   CHECK_EQ(result.GetResultType(),
            ScriptEvaluationResult::ResultType::kSuccess);
-  if (!base::FeatureList::IsEnabled(features::kTopLevelAwait)) {
-    return result.GetSuccessValue();
-  }
 
   ScriptPromise script_promise = result.GetPromise(script_state);
   v8::Local<v8::Promise> promise = script_promise.V8Promise();
@@ -113,15 +92,9 @@
   return resolve_function->GetResult();
 }
 
-v8::Local<v8::Value> ParametrizedModuleTestBase::GetException(
+v8::Local<v8::Value> ModuleTestBase::GetException(
     ScriptState* script_state,
     ScriptEvaluationResult result) {
-  if (!base::FeatureList::IsEnabled(features::kTopLevelAwait)) {
-    CHECK_EQ(result.GetResultType(),
-             ScriptEvaluationResult::ResultType::kException);
-    return result.GetExceptionForModule();
-  }
-
   CHECK_EQ(result.GetResultType(),
            ScriptEvaluationResult::ResultType::kSuccess);
 
diff --git a/third_party/blink/renderer/core/testing/module_test_base.h b/third_party/blink/renderer/core/testing/module_test_base.h
index d67e433..cc1e709f 100644
--- a/third_party/blink/renderer/core/testing/module_test_base.h
+++ b/third_party/blink/renderer/core/testing/module_test_base.h
@@ -17,23 +17,9 @@
 
 class ModuleTestBase {
  public:
-  static v8::Local<v8::Module> CompileModule(
-      ScriptState*,
-      const char*,
-      const KURL&,
-      ExceptionState& state = DummyExceptionStateForTesting().ReturnThis());
-  static v8::Local<v8::Module> CompileModule(
-      ScriptState*,
-      String,
-      const KURL&,
-      ExceptionState& state = DummyExceptionStateForTesting().ReturnThis());
-};
-
-// Helper used to enable or disable top-level await in parametrized tests.
-class ParametrizedModuleTestBase : public ModuleTestBase {
- protected:
-  void SetUp(bool use_top_level_await);
+  void SetUp();
   void TearDown() {}
+
   // Get the results of a ScriptEvaluationResult from a module.
   // If top-level await is enabled, the method will wait for the result
   // Promise to be resolved.
@@ -45,27 +31,21 @@
   v8::Local<v8::Value> GetException(ScriptState* script_state,
                                     ScriptEvaluationResult result);
 
+  static v8::Local<v8::Module> CompileModule(
+      ScriptState*,
+      const char*,
+      const KURL&,
+      ExceptionState& state = DummyExceptionStateForTesting().ReturnThis());
+  static v8::Local<v8::Module> CompileModule(
+      ScriptState*,
+      String,
+      const KURL&,
+      ExceptionState& state = DummyExceptionStateForTesting().ReturnThis());
+
  private:
-  void SetV8Flags(bool use_top_level_await);
   base::test::ScopedFeatureList feature_list_;
 };
 
-class ParametrizedModuleTest : public ParametrizedModuleTestBase,
-                               public testing::WithParamInterface<bool> {
- protected:
-  void SetUp();
-
-  bool UseTopLevelAwait() { return GetParam(); }
-};
-
-// Used in INSTANTIATE_TEST_SUITE_P for returning more readable test names.
-struct ParametrizedModuleTestParamName {
-  std::string operator()(
-      const testing::TestParamInfo<ParametrizedModuleTest::ParamType>& info) {
-    return info.param ? "TopLevelAwait" : "noTopLevelAwait";
-  }
-};
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_MODULE_TEST_BASE_H_
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index 71e226c6e..62c0b75 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -557,15 +557,18 @@
 BluetoothDevice* Bluetooth::GetBluetoothDeviceRepresentingDevice(
     mojom::blink::WebBluetoothDevicePtr device_ptr,
     ExecutionContext* context) {
-  auto it = device_instance_map_.find(device_ptr->id);
+  // TODO(crbug.com/1275634): convert device_instance_map_ to use
+  // WebBluetoothDeviceId as key
+  auto it =
+      device_instance_map_.find(device_ptr->id.DeviceIdInBase64().c_str());
   if (it != device_instance_map_.end()) {
     return it->value;
   }
 
-  String id = device_ptr->id;
   BluetoothDevice* device = MakeGarbageCollected<BluetoothDevice>(
       context, std::move(device_ptr), this);
-  auto result = device_instance_map_.insert(id, device);
+  auto result = device_instance_map_.insert(
+      device->GetDevice()->id.DeviceIdInBase64().c_str(), device);
   DCHECK(result.is_new_entry);
   return device;
 }
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
index f8f51f9..75ca2d1 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h
@@ -81,6 +81,10 @@
 
   Bluetooth* GetBluetooth() { return bluetooth_; }
 
+  const mojom::blink::WebBluetoothDevicePtr& GetDevice() const {
+    return device_;
+  }
+
   // Interface required by Garbage Collection:
   void Trace(Visitor*) const override;
 
@@ -88,7 +92,7 @@
   ScriptPromise watchAdvertisements(ScriptState*,
                                     const WatchAdvertisementsOptions*,
                                     ExceptionState&);
-  String id() { return device_->id; }
+  String id() { return device_->id.DeviceIdInBase64().c_str(); }
   String name() { return device_->name; }
   BluetoothRemoteGATTServer* gatt() { return gatt_; }
   bool watchingAdvertisements() { return client_receiver_.is_bound(); }
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
index 31ceddb6..70ce4e2 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
@@ -98,7 +98,7 @@
                         task_runner_);
 
   service->RemoteServerConnect(
-      device_->id(), std::move(client),
+      device_->GetDevice()->id, std::move(client),
       WTF::Bind(&BluetoothRemoteGATTServer::ConnectCallback,
                 WrapPersistent(this), WrapPersistent(resolver)));
 
@@ -112,7 +112,7 @@
   client_receivers_.Clear();
   mojom::blink::WebBluetoothService* service =
       device_->GetBluetooth()->Service();
-  service->RemoteServerDisconnect(device_->id());
+  service->RemoteServerDisconnect(device_->GetDevice()->id);
 }
 
 // Callback that allows us to resolve the promise with a single service or
@@ -219,7 +219,7 @@
   mojom::blink::WebBluetoothService* service =
       device_->GetBluetooth()->Service();
   service->RemoteServerGetPrimaryServices(
-      device_->id(), quantity, services_uuid,
+      device_->GetDevice()->id, quantity, services_uuid,
       WTF::Bind(&BluetoothRemoteGATTServer::GetPrimaryServicesCallback,
                 WrapPersistent(this), services_uuid, quantity,
                 WrapPersistent(resolver)));
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index c9d339c..9025622 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -144,6 +144,10 @@
   return MakeGarbageCollected<V8RenderingContext>(this);
 }
 
+NoAllocDirectCallHost* CanvasRenderingContext2D::AsNoAllocDirectCallHost() {
+  return this;
+}
+
 CanvasRenderingContext2D::~CanvasRenderingContext2D() = default;
 
 void CanvasRenderingContext2D::ValidateStateStackWithCanvas(
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
index 7207ada9..0130e61 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -97,6 +97,7 @@
     return static_cast<HTMLCanvasElement*>(Host());
   }
   V8RenderingContext* AsV8RenderingContext() final;
+  NoAllocDirectCallHost* AsNoAllocDirectCallHost() final;
 
   bool isContextLost() const override;
 
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
index e3a25a9..bb21278 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -265,6 +265,11 @@
   return image;
 }
 
+NoAllocDirectCallHost*
+OffscreenCanvasRenderingContext2D::AsNoAllocDirectCallHost() {
+  return this;
+}
+
 V8RenderingContext* OffscreenCanvasRenderingContext2D::AsV8RenderingContext() {
   return nullptr;
 }
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
index f9383ed1..2e04d9d 100644
--- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
+++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h
@@ -55,6 +55,7 @@
   ~OffscreenCanvasRenderingContext2D() override;
   bool IsComposited() const override { return false; }
   bool IsAccelerated() const override;
+  NoAllocDirectCallHost* AsNoAllocDirectCallHost() final;
   V8RenderingContext* AsV8RenderingContext() final;
   V8OffscreenRenderingContext* AsV8OffscreenRenderingContext() final;
   void SetIsInHiddenPage(bool) final { NOTREACHED(); }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
index 7e9e2fb..3550605 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope_test.cc
@@ -57,11 +57,10 @@
 
 // The test uses OfflineAudioWorkletThread because the test does not have a
 // strict real-time constraint.
-class AudioWorkletGlobalScopeTest : public PageTestBase,
-                                    public ParametrizedModuleTest {
+class AudioWorkletGlobalScopeTest : public PageTestBase, public ModuleTestBase {
  public:
   void SetUp() override {
-    ParametrizedModuleTest::SetUp();
+    ModuleTestBase::SetUp();
     PageTestBase::SetUp(IntSize());
     NavigateTo(KURL("https://example.com/"));
     reporting_proxy_ = std::make_unique<WorkerReportingProxy>();
@@ -69,7 +68,7 @@
 
   void TearDown() override {
     PageTestBase::TearDown();
-    ParametrizedModuleTest::TearDown();
+    ModuleTestBase::TearDown();
   }
 
   std::unique_ptr<OfflineAudioWorkletThread> CreateAudioWorkletThread() {
@@ -396,7 +395,7 @@
   std::unique_ptr<WorkerReportingProxy> reporting_proxy_;
 };
 
-TEST_P(AudioWorkletGlobalScopeTest, Basic) {
+TEST_F(AudioWorkletGlobalScopeTest, Basic) {
   std::unique_ptr<OfflineAudioWorkletThread> thread
       = CreateAudioWorkletThread();
   RunBasicTest(thread.get());
@@ -404,7 +403,7 @@
   thread->WaitForShutdownForTesting();
 }
 
-TEST_P(AudioWorkletGlobalScopeTest, Parsing) {
+TEST_F(AudioWorkletGlobalScopeTest, Parsing) {
   std::unique_ptr<OfflineAudioWorkletThread> thread
       = CreateAudioWorkletThread();
   RunParsingTest(thread.get());
@@ -412,7 +411,7 @@
   thread->WaitForShutdownForTesting();
 }
 
-TEST_P(AudioWorkletGlobalScopeTest, BufferProcessing) {
+TEST_F(AudioWorkletGlobalScopeTest, BufferProcessing) {
   std::unique_ptr<OfflineAudioWorkletThread> thread
       = CreateAudioWorkletThread();
   RunSimpleProcessTest(thread.get());
@@ -420,7 +419,7 @@
   thread->WaitForShutdownForTesting();
 }
 
-TEST_P(AudioWorkletGlobalScopeTest, ParsingParameterDescriptor) {
+TEST_F(AudioWorkletGlobalScopeTest, ParsingParameterDescriptor) {
   std::unique_ptr<OfflineAudioWorkletThread> thread
       = CreateAudioWorkletThread();
   RunParsingParameterDescriptorTest(thread.get());
@@ -428,10 +427,4 @@
   thread->WaitForShutdownForTesting();
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(AudioWorkletGlobalScopeTestGroup,
-                         AudioWorkletGlobalScopeTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
index 0fe7d80..c0169791 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
+++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_thread_test.cc
@@ -46,14 +46,10 @@
 
 namespace blink {
 
-class AudioWorkletThreadTestBase : public PageTestBase,
-                                   public ParametrizedModuleTestBase {
+class AudioWorkletThreadTest : public PageTestBase, public ModuleTestBase {
  public:
-  explicit AudioWorkletThreadTestBase(bool use_top_level_await)
-      : use_top_level_await_(use_top_level_await) {}
-
   void SetUp() override {
-    ParametrizedModuleTestBase::SetUp(use_top_level_await_);
+    ModuleTestBase::SetUp();
     PageTestBase::SetUp(IntSize());
     NavigateTo(KURL("https://example.com/"));
     reporting_proxy_ = std::make_unique<WorkerReportingProxy>();
@@ -63,7 +59,7 @@
     OfflineAudioWorkletThread::ClearSharedBackingThread();
     RealtimeAudioWorkletThread::ClearSharedBackingThread();
     SemiRealtimeAudioWorkletThread::ClearSharedBackingThread();
-    ParametrizedModuleTestBase::TearDown();
+    ModuleTestBase::TearDown();
   }
 
   std::unique_ptr<WorkerThread> CreateAudioWorkletThread(
@@ -83,7 +79,7 @@
     PostCrossThreadTask(
         *thread->GetWorkerBackingThread().BackingThread().GetTaskRunner(),
         FROM_HERE,
-        CrossThreadBindOnce(&AudioWorkletThreadTestBase::ExecuteScriptInWorklet,
+        CrossThreadBindOnce(&AudioWorkletThreadTest::ExecuteScriptInWorklet,
                             CrossThreadUnretained(this),
                             CrossThreadUnretained(thread),
                             CrossThreadUnretained(&wait_event)));
@@ -139,16 +135,9 @@
   }
 
   std::unique_ptr<WorkerReportingProxy> reporting_proxy_;
-  bool use_top_level_await_;
 };
 
-class AudioWorkletThreadTest : public AudioWorkletThreadTestBase,
-                               public testing::WithParamInterface<bool> {
- public:
-  AudioWorkletThreadTest() : AudioWorkletThreadTestBase(GetParam()) {}
-};
-
-TEST_P(AudioWorkletThreadTest, Basic) {
+TEST_F(AudioWorkletThreadTest, Basic) {
   std::unique_ptr<WorkerThread> audio_worklet_thread =
       CreateAudioWorkletThread(true, true);
   CheckWorkletCanExecuteScript(audio_worklet_thread.get());
@@ -158,7 +147,7 @@
 
 // Creates 2 different AudioWorkletThreads with different RT constraints.
 // Checks if they are running on a different thread.
-TEST_P(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_1) {
+TEST_F(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_1) {
   // Create RealtimeAudioWorkletThread.
   std::unique_ptr<WorkerThread> first_worklet_thread =
       CreateAudioWorkletThread(true, true);
@@ -185,7 +174,7 @@
 
 // Creates 2 AudioWorkletThreads with RT constraint from 2 different
 // originating frames. Checks if they are running on a different thread.
-TEST_P(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_2) {
+TEST_F(AudioWorkletThreadTest, CreateDifferentWorkletThreadsAndTerminate_2) {
   // Create an AudioWorkletThread from a main frame with RT constraint.
   std::unique_ptr<WorkerThread> first_worklet_thread =
       CreateAudioWorkletThread(true, true);
@@ -210,20 +199,13 @@
   second_worklet_thread->WaitForShutdownForTesting();
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadTestGroup,
-                         AudioWorkletThreadTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
-
 class AudioWorkletThreadInteractionTest
-    : public AudioWorkletThreadTestBase,
-      public testing::WithParamInterface<std::tuple<bool, bool, bool>> {
+    : public AudioWorkletThreadTest,
+      public testing::WithParamInterface<std::tuple<bool, bool>> {
  public:
   AudioWorkletThreadInteractionTest()
-      : AudioWorkletThreadTestBase(std::get<0>(GetParam())),
-        has_realtime_constraint_(std::get<1>(GetParam())),
-        is_top_level_frame_(std::get<2>(GetParam())) {}
+      : has_realtime_constraint_(std::get<0>(GetParam())),
+        is_top_level_frame_(std::get<1>(GetParam())) {}
 
  protected:
   const bool has_realtime_constraint_;
@@ -320,12 +302,9 @@
 
 INSTANTIATE_TEST_SUITE_P(AudioWorkletThreadInteractionTestGroup,
                          AudioWorkletThreadInteractionTest,
-                         testing::Combine(testing::Bool(),
-                                          testing::Bool(),
-                                          testing::Bool()));
+                         testing::Combine(testing::Bool(), testing::Bool()));
 
 struct ThreadPriorityTestParam {
-  const bool use_top_level_await;
   const bool has_realtime_constraint;
   const bool is_top_level_frame;
   const bool is_enabled_by_finch;
@@ -334,41 +313,28 @@
 
 constexpr ThreadPriorityTestParam kThreadPriorityTestParams[] = {
     // RT thread enabled by Finch.
-    {true, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
+    {true, true, true, base::ThreadPriority::REALTIME_AUDIO},
 
     // RT thread disabled by Finch.
-    {true, true, true, false, base::ThreadPriority::NORMAL},
+    {true, true, false, base::ThreadPriority::NORMAL},
 
     // Non-main frame, RT thread enabled by Finch.
-    {true, true, false, true, base::ThreadPriority::DISPLAY},
+    {true, false, true, base::ThreadPriority::DISPLAY},
 
     // Non-main frame, RT thread disabled by Finch.
-    {true, true, false, false, base::ThreadPriority::NORMAL},
+    {true, false, false, base::ThreadPriority::NORMAL},
 
     // The OfflineAudioContext always uses a NORMAL priority thread.
-    {true, false, true, true, base::ThreadPriority::NORMAL},
-    {true, false, true, false, base::ThreadPriority::NORMAL},
-    {true, false, false, true, base::ThreadPriority::NORMAL},
-    {true, false, false, false, base::ThreadPriority::NORMAL},
-
-    // Top-level await does not affect the test result.
-    {false, true, true, true, base::ThreadPriority::REALTIME_AUDIO},
-    {false, true, true, false, base::ThreadPriority::NORMAL},
-    {false, true, false, true, base::ThreadPriority::DISPLAY},
-    {false, true, false, false, base::ThreadPriority::NORMAL},
-    {false, false, true, true, base::ThreadPriority::NORMAL},
-    {false, false, true, false, base::ThreadPriority::NORMAL},
-    {false, false, false, true, base::ThreadPriority::NORMAL},
-    {false, false, false, false, base::ThreadPriority::NORMAL},
+    {false, true, true, base::ThreadPriority::NORMAL},
+    {false, true, false, base::ThreadPriority::NORMAL},
+    {false, false, true, base::ThreadPriority::NORMAL},
+    {false, false, false, base::ThreadPriority::NORMAL},
 };
 
 class AudioWorkletThreadPriorityTest
-    : public AudioWorkletThreadTestBase,
+    : public AudioWorkletThreadTest,
       public testing::WithParamInterface<ThreadPriorityTestParam> {
  public:
-  AudioWorkletThreadPriorityTest()
-      : AudioWorkletThreadTestBase(GetParam().use_top_level_await) {}
-
   void InitWithRealtimePrioritySettings(bool is_enabled_by_finch) {
     std::vector<base::Feature> enabled;
     std::vector<base::Feature> disabled;
diff --git a/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_metadata.idl b/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_metadata.idl
index 4ae2695..3b75fe4a 100644
--- a/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_metadata.idl
+++ b/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_metadata.idl
@@ -6,5 +6,6 @@
 
 dictionary EncodedVideoChunkMetadata {
   VideoDecoderConfig decoderConfig;
+  SvcOutputMetadata svc;
   [EnforceRange] unsigned long temporalLayerId;
 };
diff --git a/third_party/blink/renderer/modules/webcodecs/svc_output_metadata.idl b/third_party/blink/renderer/modules/webcodecs/svc_output_metadata.idl
new file mode 100644
index 0000000..f7e5737
--- /dev/null
+++ b/third_party/blink/renderer/modules/webcodecs/svc_output_metadata.idl
@@ -0,0 +1,9 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/web-codecs
+
+dictionary SvcOutputMetadata {
+  [EnforceRange] unsigned long temporalLayerId;
+};
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
index 05f619b7..74612a6 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -43,6 +43,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_avc_encoder_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_metadata.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h"
@@ -865,8 +866,12 @@
   auto* chunk = MakeGarbageCollected<EncodedVideoChunk>(std::move(buffer));
 
   auto* metadata = EncodedVideoChunkMetadata::Create();
-  if (active_config->options.scalability_mode.has_value())
+  if (active_config->options.scalability_mode.has_value()) {
+    auto* svc_metadata = SvcOutputMetadata::Create();
+    svc_metadata->setTemporalLayerId(output.temporal_id);
+    metadata->setSvc(svc_metadata);
     metadata->setTemporalLayerId(output.temporal_id);
+  }
 
   // TODO(https://crbug.com/1241448): All encoders should output color space.
   // For now, fallback to 601 since that is correct most often.
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 9ba2998..03056c2 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -239,6 +239,10 @@
                               WebGLRenderingContextBase::kWhenAvailable);
 }
 
+NoAllocDirectCallHost* WebGLRenderingContextBase::AsNoAllocDirectCallHost() {
+  return this;
+}
+
 WebGLRenderingContextBase* WebGLRenderingContextBase::OldestContext() {
   if (ActiveContexts().IsEmpty())
     return nullptr;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
index 1cbe02a58..45a5c1a 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -145,6 +145,8 @@
 
   ~WebGLRenderingContextBase() override;
 
+  NoAllocDirectCallHost* AsNoAllocDirectCallHost() final;
+
   HTMLCanvasElement* canvas() const {
     if (Host()->IsOffscreenCanvas())
       return nullptr;
diff --git a/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc b/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc
index 2170e8b..315eec7 100644
--- a/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc
+++ b/third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread_test.cc
@@ -43,10 +43,10 @@
 }  // namespace
 
 class AnimationAndPaintWorkletThreadTest : public PageTestBase,
-                                           public ParametrizedModuleTest {
+                                           public ModuleTestBase {
  public:
   void SetUp() override {
-    ParametrizedModuleTest::SetUp();
+    ModuleTestBase::SetUp();
     PageTestBase::SetUp(IntSize());
     NavigateTo(KURL("https://example.com/"));
     reporting_proxy_ = std::make_unique<WorkerReportingProxy>();
@@ -54,7 +54,7 @@
 
   void TearDown() override {
     PageTestBase::TearDown();
-    ParametrizedModuleTest::TearDown();
+    ModuleTestBase::TearDown();
   }
 
   // Attempts to run some simple script for |thread|.
@@ -96,7 +96,7 @@
   }
 };
 
-TEST_P(AnimationAndPaintWorkletThreadTest, Basic) {
+TEST_F(AnimationAndPaintWorkletThreadTest, Basic) {
   std::unique_ptr<AnimationAndPaintWorkletThread> worklet =
       CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(),
                                                         reporting_proxy_.get());
@@ -107,7 +107,7 @@
 
 // Tests that the same WebThread is used for new worklets if the WebThread is
 // still alive.
-TEST_P(AnimationAndPaintWorkletThreadTest, CreateSecondAndTerminateFirst) {
+TEST_F(AnimationAndPaintWorkletThreadTest, CreateSecondAndTerminateFirst) {
   // Create the first worklet and wait until it is initialized.
   std::unique_ptr<AnimationAndPaintWorkletThread> first_worklet =
       CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(),
@@ -145,7 +145,7 @@
 
 // Tests that the WebThread is reused if all existing worklets are terminated
 // before a new worklet is created, as long as the worklets are not destructed.
-TEST_P(AnimationAndPaintWorkletThreadTest, TerminateFirstAndCreateSecond) {
+TEST_F(AnimationAndPaintWorkletThreadTest, TerminateFirstAndCreateSecond) {
   // Create the first worklet, wait until it is initialized, and terminate it.
   std::unique_ptr<AnimationAndPaintWorkletThread> worklet =
       CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(),
@@ -170,7 +170,7 @@
 
 // Tests that v8::Isolate and WebThread are correctly set-up if a worklet is
 // created while another is terminating.
-TEST_P(AnimationAndPaintWorkletThreadTest,
+TEST_F(AnimationAndPaintWorkletThreadTest,
        CreatingSecondDuringTerminationOfFirst) {
   std::unique_ptr<AnimationAndPaintWorkletThread> first_worklet =
       CreateThreadAndProvideAnimationWorkletProxyClient(&GetDocument(),
@@ -203,7 +203,7 @@
 
 // Tests that the backing thread is correctly created, torn down, and recreated
 // as AnimationWorkletThreads are created and destroyed.
-TEST_P(AnimationAndPaintWorkletThreadTest,
+TEST_F(AnimationAndPaintWorkletThreadTest,
        WorkletThreadHolderIsRefCountedProperly) {
   EXPECT_FALSE(
       AnimationAndPaintWorkletThread::GetWorkletThreadHolderForTesting());
@@ -247,9 +247,4 @@
   worklet3->WaitForShutdownForTesting();
 }
 
-// Instantiate tests once with TLA and once without:
-INSTANTIATE_TEST_SUITE_P(AnimationAndPaintWorkletThreadTestGroup,
-                         AnimationAndPaintWorkletThreadTest,
-                         testing::Bool(),
-                         ParametrizedModuleTestParamName());
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index 149c9ba..2de6ea0 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -501,22 +501,6 @@
     CreateCompositorScrollNode(*scroll_node, compositor_node);
   }
 
-  // If the parent transform node flattens transform (as |transform_node|
-  // flattens inherited transform) while it participates in the 3d sorting
-  // context of an ancestor, cc needs a render surface for correct flattening.
-  // TODO(crbug.com/504464): Move the logic into cc compositor thread.
-  auto* current_cc_effect = GetEffectTree().Node(current_.effect_id);
-  if (current_cc_effect && !current_cc_effect->HasRenderSurface() &&
-      current_cc_effect->transform_id == parent_id &&
-      transform_node.FlattensInheritedTransform()) {
-    const auto* parent = transform_node.UnaliasedParent();
-    if (parent && parent->RenderingContextId() &&
-        !parent->FlattensInheritedTransform()) {
-      current_cc_effect->render_surface_reason =
-          cc::RenderSurfaceReason::k3dTransformFlattening;
-    }
-  }
-
   compositor_node.visible_frame_element_id =
       transform_node.GetVisibleFrameElementId();
 
@@ -1178,6 +1162,13 @@
   }
   if (effect.DocumentTransitionSharedElementId().valid())
     return cc::RenderSurfaceReason::kDocumentTransitionParticipant;
+  // If the effect's transform node flattens the transform while it
+  // participates in the 3d sorting context of an ancestor, cc needs a
+  // render surface for correct flattening.
+  // TODO(crbug.com/504464): Move the logic into cc compositor thread.
+  if (effect.FlattensAtLeafOf3DScene())
+    return cc::RenderSurfaceReason::k3dTransformFlattening;
+
   return cc::RenderSurfaceReason::kNone;
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
index 55baccd9..15dbc3b 100644
--- a/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.cc
@@ -134,6 +134,8 @@
     {CompositingReason::kBackfaceInvisibility3DAncestor,
      "BackfaceInvisibility3DAncestor",
      "Ancestor in same 3D rendering context has a hidden backface"},
+    {CompositingReason::kTransform3DSceneLeaf, "Transform3DSceneLeaf",
+     "Leaf of a 3D scene, for flattening its descendants into that scene"},
     {CompositingReason::kDocumentTransitionSharedElement,
      "DocumentTransitionSharedElement",
      "This element is shared during document transition"},
diff --git a/third_party/blink/renderer/platform/graphics/compositing_reasons.h b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
index a7171f7..e31810e 100644
--- a/third_party/blink/renderer/platform/graphics/compositing_reasons.h
+++ b/third_party/blink/renderer/platform/graphics/compositing_reasons.h
@@ -42,8 +42,13 @@
   V(WillChangeOpacity)                                                        \
   V(WillChangeFilter)                                                         \
   V(WillChangeBackdropFilter)                                                 \
+                                                                              \
   /* Reasons that depend on ancestor properties */                            \
   V(BackfaceInvisibility3DAncestor)                                           \
+  /* TODO(crbug.com/1256990): Transform3DSceneLeaf today depends only on the  \
+     element and its properties, but in the future it could be optimized      \
+     to consider descendants and moved to the subtree group below. */         \
+  V(Transform3DSceneLeaf)                                                     \
   /* This flag is needed only when none of the explicit kWillChange* reasons  \
      are set. */                                                              \
   V(WillChangeOther)                                                          \
@@ -140,7 +145,7 @@
         kOverflowScrollingParent | kOutOfFlowClipping | kVideoOverlay |
         kXrOverlay | kRoot | kRootScroller | kComboScrollDependentPosition |
         kAffectedByOuterViewportBoundsDelta | kBackfaceInvisibility3DAncestor |
-        kDocumentTransitionSharedElement,
+        kTransform3DSceneLeaf | kDocumentTransitionSharedElement,
 
     kComboAllDirectReasons = kComboAllDirectStyleDeterminedReasons |
                              kComboAllDirectNonStyleDeterminedReasons,
@@ -179,7 +184,7 @@
     kDirectReasonsForEffectProperty =
         kActiveOpacityAnimation | kWillChangeOpacity | kBackdropFilter |
         kWillChangeBackdropFilter | kActiveBackdropFilterAnimation |
-        kDocumentTransitionSharedElement,
+        kDocumentTransitionSharedElement | kTransform3DSceneLeaf,
     kDirectReasonsForFilterProperty =
         kActiveFilterAnimation | kWillChangeFilter,
     kDirectReasonsForBackdropFilter = kBackdropFilter |
diff --git a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
index 786596d1..527cf9c5 100644
--- a/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
+++ b/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h
@@ -280,6 +280,11 @@
            CompositingReason::kBackdropFilterMask;
   }
 
+  bool FlattensAtLeafOf3DScene() const {
+    return state_.direct_compositing_reasons &
+           CompositingReason::kTransform3DSceneLeaf;
+  }
+
   // TODO(crbug.com/900241): Use HaveActiveXXXAnimation() instead of this
   // function when we can track animations for each property type.
   bool RequiresCompositingForAnimation() const {
diff --git a/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.cc b/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.cc
index 07f47f2..fe99833 100644
--- a/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.cc
+++ b/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.cc
@@ -9,13 +9,6 @@
 namespace mojo {
 
 // static
-bool StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String>::
-    Read(::blink::mojom::WebBluetoothDeviceIdDataView data,
-         WTF::String* output) {
-  return data.ReadDeviceId(output);
-}
-
-// static
 bool StructTraits<bluetooth::mojom::UUIDDataView, WTF::String>::Read(
     bluetooth::mojom::UUIDDataView data,
     WTF::String* output) {
diff --git a/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h b/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h
index b970277..2fb6e43 100644
--- a/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h
+++ b/third_party/blink/renderer/platform/mojo/bluetooth_mojom_traits.h
@@ -5,8 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BLUETOOTH_MOJOM_TRAITS_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BLUETOOTH_MOJOM_TRAITS_H_
 
-#include "device/bluetooth/public/mojom/uuid.mojom-blink-forward.h"
-#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h"
+#include "device/bluetooth/public/mojom/uuid.mojom-shared.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -14,17 +13,6 @@
 
 template <>
 struct PLATFORM_EXPORT
-    StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String> {
-  static const WTF::String& device_id(const WTF::String& input) {
-    return input;
-  }
-
-  static bool Read(::blink::mojom::WebBluetoothDeviceIdDataView,
-                   WTF::String* output);
-};
-
-template <>
-struct PLATFORM_EXPORT
     StructTraits<bluetooth::mojom::UUIDDataView, WTF::String> {
   static const WTF::String& uuid(const WTF::String& input) { return input; }
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 90b87e6..d6c87c86f 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -281,7 +281,14 @@
     },
     {
       name: "BarcodeDetector",
-      status: "stable",
+      status: {
+        // Built-in barcode detection APIs are only available from some
+        // platforms. See //services/shape_detection.
+        "Android": "stable",
+        "ChromeOS": "stable",
+        "Mac": "stable",
+        "default": "test",
+      },
     },
     {
       // https://github.com/chrishtr/battery-savings/blob/master/explainer.md
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
index e64e17ce..334db23 100644
--- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
+++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -60,6 +60,8 @@
     else:
         host = Host()
 
+    if six.PY3 and stderr.isatty():
+        stderr.reconfigure(write_through=True)
     printer = printing.Printer(host, options, stderr)
 
     try:
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index f6d4000e..c346419 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -100,6 +100,8 @@
 crbug.com/1173843 external/wpt/css/css-flexbox/frameset-crash.html [ Skip ]
 crbug.com/1069614 external/wpt/css/css-flexbox/overflow-area-001.html [ Failure ]
 crbug.com/1069614 external/wpt/css/css-flexbox/overflow-area-002.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-flexbox/scrollbars-auto.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-flexbox/scrollbars.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-flexbox/synthesize-vrl-baseline.html [ Failure ]
 crbug.com/1181403 external/wpt/css/css-flexbox/table-as-item-inflexible-in-column-2.html [ Failure ]
 crbug.com/1181403 external/wpt/css/css-flexbox/table-as-item-specified-height.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index c55b82e70..d612dbd 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -987,11 +987,6 @@
 crbug.com/240765 external/wpt/css/css-flexbox/flex-container-max-content-001.html [ Failure ]
 crbug.com/240765 external/wpt/css/css-flexbox/flex-container-min-content-001.html [ Failure ]
 
-# These tests are in conflict with overflow-area-*, update them if our change is web compatible.
-crbug.com/1069614 external/wpt/css/css-flexbox/scrollbars-auto.html [ Failure ]
-crbug.com/1069614 external/wpt/css/css-flexbox/scrollbars.html [ Failure ]
-crbug.com/1069614 css3/flexbox/overflow-and-padding.html [ Failure ]
-
 # These require css-align-3 positional keywords that Blink doesn't yet support for flexbox.
 crbug.com/1011718 external/wpt/css/css-flexbox/flexbox-safe-overflow-position-001.html [ Failure ]
 
@@ -2826,11 +2821,13 @@
 crbug.com/1053965 external/wpt/css/css-values/ex-unit-004.html [ Failure ]
 crbug.com/759914 external/wpt/css/css-values/ch-unit-011.html [ Failure ]
 crbug.com/965366 external/wpt/css/css-values/ch-unit-017.html [ Failure ]
+crbug.com/937101 external/wpt/css/css-values/ic-unit-008.html [ Failure ]
+crbug.com/937101 external/wpt/css/css-values/ic-unit-009.html [ Failure ]
 crbug.com/937101 external/wpt/css/css-values/ic-unit-010.html [ Failure ]
 crbug.com/937101 external/wpt/css/css-values/ic-unit-011.html [ Failure ]
-crbug.com/937101 external/wpt/css/css-values/ic-unit-009.html [ Failure ]
-crbug.com/937101 external/wpt/css/css-values/ic-unit-008.html [ Failure ]
 crbug.com/937101 external/wpt/css/css-values/ic-unit-012.html [ Failure ]
+crbug.com/937101 external/wpt/css/css-values/ic-unit-013.html [ Failure ]
+crbug.com/937101 external/wpt/css/css-values/ic-unit-014.html [ Failure ]
 crbug.com/937104 external/wpt/css/css-values/lh-unit-002.html [ Failure ]
 crbug.com/937104 external/wpt/css/css-values/lh-unit-001.html [ Failure ]
 
@@ -3097,11 +3094,7 @@
 crbug.com/626703 [ Mac11-arm64 ] virtual/css-modules/external/wpt/html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html [ Crash ]
 crbug.com/626703 [ Mac11-arm64 ] virtual/dark-color-scheme/external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-visited-link-initial.html [ Crash ]
 crbug.com/626703 [ Win10.20h2 ] virtual/without-coep-for-shared-worker/external/wpt/html/cross-origin-embedder-policy/credentialless/cache-storage.tentative.https.window.html?service_worker [ Skip Timeout ]
-crbug.com/626703 external/wpt/css/css-values/ic-unit-013.html [ Failure ]
-crbug.com/626703 external/wpt/css/css-values/ic-unit-014.html [ Failure ]
 crbug.com/626703 [ Mac11-arm64 ] external/wpt/navigation-timing/nav2_test_response_end_and_duration_before_during_and_after_load_event.html [ Timeout ]
-crbug.com/626703 virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/ic-unit-013.html [ Failure ]
-crbug.com/626703 virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/ic-unit-014.html [ Failure ]
 crbug.com/1270841 [ Mac ] external/wpt/media-capabilities/encodingInfo.any.worker.html [ Crash ]
 crbug.com/626703 [ Mac11 ] virtual/plz-dedicated-worker/external/wpt/workers/constructors/SharedWorker/setting-port-members.html [ Failure Timeout ]
 crbug.com/626703 [ Mac10.15 ] virtual/without-coep-for-shared-worker/external/wpt/html/cross-origin-embedder-policy/reporting-subresource-corp.https.html [ Skip Timeout ]
@@ -7365,3 +7358,6 @@
 
 # Sheriff 2021-11-30
 crbug.com/1256763 [ Linux ] virtual/gpu-rasterization/images/color-profile-image-shape.html [ Failure Pass ]
+
+# Sheriff 2021-12-01
+crbug.com/1275658 http/tests/misc/script-after-slow-stylesheet-removed.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/compositing/layer-creation/no-compositing-for-preserve-3d.html b/third_party/blink/web_tests/compositing/layer-creation/no-compositing-for-preserve-3d.html
index 0dcaa49..db12ca82 100644
--- a/third_party/blink/web_tests/compositing/layer-creation/no-compositing-for-preserve-3d.html
+++ b/third_party/blink/web_tests/compositing/layer-creation/no-compositing-for-preserve-3d.html
@@ -39,21 +39,19 @@
 </head>
 <body>
 
-  <div class="preserve3d">
+  <div class="preserve3d" id="layer1">
     This layer should not be composited.
-    <div class="box"></div>
-    </div>
+    <div class="box" id="box1"></div>
   </div>
 
-  <div class="preserve3d">
+  <div class="preserve3d" id="layer2">
     This layer should not be composited.
-    <div class="box" style="transform: rotate(10deg)"></div>
-    </div>
+    <div class="box" id="box2" style="transform: rotate(10deg)"></div>
   </div>
 
-  <div class="preserve3d">
+  <div class="preserve3d" id="layer3">
     This layer should be composited.
-    <div class="box" style="transform: rotateY(10deg)"></div>
+    <div class="box" id="box3" style="transform: rotateY(10deg)"></div>
   </div>
 <pre id="layers">Layer tree goes here in DRT</pre>
 
diff --git a/third_party/blink/web_tests/css3/flexbox/overflow-and-padding.html b/third_party/blink/web_tests/css3/flexbox/overflow-and-padding.html
deleted file mode 100644
index d14972d..0000000
--- a/third_party/blink/web_tests/css3/flexbox/overflow-and-padding.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html>
-<title>CSS Flexbox: padding on a flexbox with overflowing content.</title>
-<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#overflow-properties">
-<link rel="help" href="https://drafts.csswg.org/css-flexbox/#item-margins">
-<link rel="help" href="https://codereview.chromium.org/134603002">
-<meta name="assert" content="This test checks that all paddings but padding-right work on a flexbox in the face of overflowing content, matching the Blink/WebKit behavior for 'display:block'." />
-
-<style>
-#scrollable {
-  overflow: scroll;
-  background: pink;
-  height: 300px;
-  width: 300px;
-  box-sizing: border-box;
-  display: flex;
-  padding: 100px;
-}
-
-#item {
-  width: 300px;
-  height: 300px;
-  background: salmon;
-  flex-shrink: 0;
-}
-</style>
-
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../resources/check-layout-th.js"></script>
-
-<body onload="checkLayout('#scrollable')">
-
-<div id=log></div>
-
-<p>Tests that padding bottom on a flexbox works in the face of overflowing content.
-Padding-right does not work. This matches the Blink/WebKit display:block behavior.
-Unfortunately, IE and Gecko both lose the padding bottom and the padding right.</p>
-
-<div id="scrollable" data-expected-scroll-height=500 data-expected-scroll-width=400>
-  <div id="item"></div>
-</div>
-
-</body>
-</html>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html
index 4b10b17..655bff8c2 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html
+++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm.https.html
@@ -27,6 +27,16 @@
     return promise_rejects_dom(t, 'AbortError', result);
   }, "User approval decline should reject the promise.");
 
+  fedcm_test(async (t, mock) => {
+    mock.returnError("ErrorTooManyRequests");
+    const first = await navigator.credentials.get(test_options);
+    const second = await navigator.credentials.get(test_options);
+    assert_equals(first, undefined);
+    return promise_rejects_dom(t, 'AbortError', second);
+  },
+  "When there's a pending request, a second `get` call should be rejected. ",
+  "Only one navigator.credentials.get request may be outstanding at one time.");
+
   promise_test(async t => {
     const result = navigator.credentials.get({
     federated: {
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.js b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.js
index fa292e5..428a2fc 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.js
+++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.js
@@ -5,12 +5,14 @@
 
 import { MockFederatedAuthRequest } from './fedcm-mock.js';
 
-export function fedcm_test(test_func, name, properties) {
+export function fedcm_test(test_func, name, exception, properties) {
   promise_test(async (t) => {
     assert_implements(navigator.credentials, 'missing navigator.credentials');
     const mock = new MockFederatedAuthRequest();
     try {
       await test_func(t, mock);
+    } catch (e) {
+      assert_equals(exception, e.message)
     } finally {
       await mock.reset();
     }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-auto-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-auto-ref.html
index 590b533..ededbbe 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-auto-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-auto-ref.html
@@ -49,72 +49,29 @@
 }
 .column > div, .column-reverse > div {
   display: flex;
+  margin: 3px;
 }
 
 /* Adjust margins to account for collapsing. */
-.ltr.horizontal > .row > .leaf3 {
-  margin-right: 0;
-}
-.ltr.flipped-blocks > .row > .leaf3, .ltr.flipped-lines > .row > .leaf3 {
-  margin-bottom: 0;
-}
-.rtl.horizontal > .row > .leaf3 {
-  margin-left: 0;
-}
-.rtl.flipped-blocks > .row > .leaf3, .rtl.flipped-lines > .row > .leaf3 {
-  margin-top: 0;
-}
-
-.ltr.horizontal > .row-reverse > .leaf3 {
-  margin-left: 0;
-}
-.ltr.flipped-blocks > .row-reverse > .leaf3, .ltr.flipped-lines > .row-reverse > .leaf3 {
-  margin-top: 0;
-}
-.rtl.horizontal > .row-reverse > .leaf3 {
-  margin-right: 0;
-}
-.rtl.flipped-blocks > .row-reverse > .leaf3, .rtl.flipped-lines > .row-reverse > .leaf3 {
-  margin-bottom: 0;
-}
-
 .horizontal > .column > .leaf1, .horizontal > .column > .leaf2 {
   margin: 3px 3px 6px 3px;
 }
-.horizontal > .column > .leaf3 {
-  margin: 3px;
-}
 .flipped-blocks > .column > .leaf1, .flipped-blocks > .column > .leaf2 {
   margin: 3px 3px 3px 6px;
 }
-.flipped-blocks > .column > .leaf3 {
-  margin: 3px;
-}
 .flipped-lines > .column > .leaf1, .flipped-lines > .column > .leaf2 {
   margin: 3px 6px 3px 3px;
 }
-.flipped-lines > .column > .leaf3 {
-  margin: 3px;
-}
 
 .horizontal > .column-reverse > .leaf1, .horizontal > .column-reverse > .leaf2 {
   margin: 6px 3px 3px 3px;
 }
-.horizontal > .column-reverse > .leaf3 {
-  margin: 0 3px 3px 3px;
-}
 .flipped-blocks > .column-reverse > .leaf1, .flipped-blocks > .column-reverse > .leaf2 {
   margin: 3px 6px 3px 3px;
 }
-.flipped-blocks > .column-reverse > .leaf3 {
-  margin: 3px 0 3px 3px;
-}
 .flipped-lines > .column-reverse > .leaf1, .flipped-lines > .column-reverse > .leaf2 {
   margin: 3px 3px 3px 6px;
 }
-.flipped-lines > .column-reverse > .leaf3 {
-  margin: 3px 3px 3px 0;
-}
 
 .flex > div {
   width: 30px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-ref.html
index 911e7ac..0715fef 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/scrollbars-ref.html
@@ -49,72 +49,29 @@
 }
 .column > div, .column-reverse > div {
   display: flex;
+  margin: 3px;
 }
 
 /* Adjust margins to account for collapsing. */
-.ltr.horizontal > .row > .leaf3 {
-  margin-right: 0;
-}
-.ltr.flipped-blocks > .row > .leaf3, .ltr.flipped-lines > .row > .leaf3 {
-  margin-bottom: 0;
-}
-.rtl.horizontal > .row > .leaf3 {
-  margin-left: 0;
-}
-.rtl.flipped-blocks > .row > .leaf3, .rtl.flipped-lines > .row > .leaf3 {
-  margin-top: 0;
-}
-
-.ltr.horizontal > .row-reverse > .leaf3 {
-  margin-left: 0;
-}
-.ltr.flipped-blocks > .row-reverse > .leaf3, .ltr.flipped-lines > .row-reverse > .leaf3 {
-  margin-top: 0;
-}
-.rtl.horizontal > .row-reverse > .leaf3 {
-  margin-right: 0;
-}
-.rtl.flipped-blocks > .row-reverse > .leaf3, .rtl.flipped-lines > .row-reverse > .leaf3 {
-  margin-bottom: 0;
-}
-
 .horizontal > .column > .leaf1, .horizontal > .column > .leaf2 {
   margin: 3px 3px 6px 3px;
 }
-.horizontal > .column > .leaf3 {
-  margin: 3px;
-}
 .flipped-blocks > .column > .leaf1, .flipped-blocks > .column > .leaf2 {
   margin: 3px 3px 3px 6px;
 }
-.flipped-blocks > .column > .leaf3 {
-  margin: 3px;
-}
 .flipped-lines > .column > .leaf1, .flipped-lines > .column > .leaf2 {
   margin: 3px 6px 3px 3px;
 }
-.flipped-lines > .column > .leaf3 {
-  margin: 3px;
-}
 
 .horizontal > .column-reverse > .leaf1, .horizontal > .column-reverse > .leaf2 {
   margin: 6px 3px 3px 3px;
 }
-.horizontal > .column-reverse > .leaf3 {
-  margin: 0 3px 3px 3px;
-}
 .flipped-blocks > .column-reverse > .leaf1, .flipped-blocks > .column-reverse > .leaf2 {
   margin: 3px 6px 3px 3px;
 }
-.flipped-blocks > .column-reverse > .leaf3 {
-  margin: 3px 0 3px 3px;
-}
 .flipped-lines > .column-reverse > .leaf1, .flipped-lines > .column-reverse > .leaf2 {
   margin: 3px 3px 3px 6px;
 }
-.flipped-lines > .column-reverse > .leaf3 {
-  margin: 3px 3px 3px 0;
-}
 
 .flex > div {
   width: 30px;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-001-ref.html
new file mode 100644
index 0000000..62252a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-001-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test Reference (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+
+<style>
+body {
+  margin: 0;
+}
+
+.reference {
+  background: blue;
+  width: 100px;
+  height: 100px;
+  transform-origin: 0 0;
+  transform: translate(50px, 100px) perspective(1000px) rotateX(30deg) translateY(50px) translateZ(100px);
+}
+</style>
+
+<div class="reference"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-001.html
new file mode 100644
index 0000000..411b945e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-001.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="The element is rendered at the correct position.">
+<link rel="match" href="preserve3d-and-flattening-001-ref.html">
+<meta name="fuzzy" content="maxDifference=0-127;totalPixels=0-101">
+
+<style>
+body {
+  margin: 0;
+}
+.scene-wrapper {
+  margin-top: 100px;
+  margin-left: 50px;
+  width: 200px;
+  height: 200px;
+  perspective: 1000px;
+  perspective-origin: 0px 0px;
+}
+.scene-root {
+  transform: rotateX(30deg);
+  transform-origin: 0px 0px;
+  transform-style:preserve-3d;
+  /* This is in place of a transition in the original. */
+  will-change: transform;
+}
+.descendent-of-flattener {
+  height: 50px;
+  will-change: transform;
+}
+.scene-3d-element {
+  background: blue;
+  transform: translateZ(100px);
+  width: 100px;
+  height: 100px;
+  transform-style:preserve-3d
+}
+</style>
+
+<div class="scene-wrapper">
+  <div class="scene-root">
+    <div class="scene-flattener">
+      <div class="descendent-of-flattener"></div>
+    </div>
+    <div class="scene-3d-element"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-002-ref.html
new file mode 100644
index 0000000..5a2b59c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-002-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+
+<style>
+body {
+  margin: 0;
+}
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+}
+.flattener {
+  background: fuchsia;
+}
+.sibling {
+  background: blue;
+  top: 50px;
+  left: 25px;
+}
+.child {
+  background: silver;
+  left: 50px;
+}
+</style>
+
+<div class="sibling"></div>
+<div class="flattener"></div>
+<div class="child"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-002.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-002.html
new file mode 100644
index 0000000..eaadcfee
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-002.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="The element is rendered at the correct position.">
+<link rel="match" href="preserve3d-and-flattening-002-ref.html">
+
+<style>
+body {
+  margin: 0;
+}
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.outer {
+  background: gray;
+}
+.flattener {
+  background: fuchsia;
+}
+.sibling {
+  background: blue;
+  transform: translate3d(25px, 50px, -20px);
+}
+.child {
+  background: silver;
+  transform: translate3d(50px, 0, 10px);
+}
+</style>
+
+<div class="outer">
+  <div class="flattener">
+    <div class="child"></div>
+  </div>
+  <div class="sibling"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html
new file mode 100644
index 0000000..7fb0d70
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-003.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="The element is rendered at the correct position.">
+<link rel="match" href="preserve3d-and-flattening-002-ref.html">
+
+<style>
+body {
+  margin: 0;
+}
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.outer {
+  background: gray;
+}
+.flattener {
+  background: fuchsia;
+  transform: translateX(0);
+}
+.sibling {
+  background: blue;
+  transform: translate3d(25px, 50px, -20px);
+}
+.child {
+  background: silver;
+  transform: translate3d(50px, 0, 10px);
+}
+</style>
+
+<div class="outer">
+  <div class="flattener">
+    <div class="child"></div>
+  </div>
+  <div class="sibling"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-001.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-001.html
new file mode 100644
index 0000000..99c3816
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-001.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="reference/green.html">
+
+<style>
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+  background: red;
+}
+.outer {
+  position: relative;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+</style>
+
+<p>Pass if there is NO red below:</p>
+
+<div class="outer">
+  <div class="sibling"></div>
+  <div class="flattener"><div class="child"></div></div>
+  <div class="sibling" style="background: green"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-002.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-002.html
new file mode 100644
index 0000000..243aab6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-002.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="reference/green.html">
+
+<style>
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+  background: red;
+}
+.outer {
+  position: relative;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.flattener {
+  transform: translateX(0);
+}
+</style>
+
+<p>Pass if there is NO red below:</p>
+
+<div class="outer">
+  <div class="sibling"></div>
+  <div class="flattener"><div class="child"></div></div>
+  <div class="sibling" style="background: green"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-003.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-003.html
new file mode 100644
index 0000000..f87b7691
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-003.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="reference/green.html">
+
+<style>
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+  background: red;
+}
+.outer {
+  position: relative;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.child {
+  background: green;
+}
+</style>
+
+<p>Pass if there is NO red below:</p>
+
+<div class="outer">
+  <div class="sibling"></div>
+  <div class="flattener"><div class="child"></div></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-004.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-004.html
new file mode 100644
index 0000000..2bf1510
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-004.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="reference/green.html">
+
+<style>
+div {
+  position: absolute;
+  height: 100px;
+  width: 100px;
+  top: 0;
+  left: 0;
+  background: red;
+}
+.outer {
+  position: relative;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.flattener {
+  transform: translateX(0);
+}
+.child {
+  background: green;
+}
+</style>
+
+<p>Pass if there is NO red below:</p>
+
+<div class="outer">
+  <div class="sibling"></div>
+  <div class="flattener"><div class="child"></div></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-005.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-005.html
new file mode 100644
index 0000000..36582ec
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-005.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="reference/green.html">
+
+<style>
+div, span {
+  height: 100px;
+  width: 100px;
+  background: red;
+}
+span {
+  display: inline-block;
+  vertical-align: top;
+}
+div:not(:first-child):not(.outer) {
+  /* put everything at the same position without using absolute positioning */
+  margin-top: -100px;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.sibling {
+  transform: translateZ(-10px);
+}
+.child {
+  will-change: transform;
+  position: relative;
+  z-index: -1;
+}
+</style>
+
+<p>Pass if there is NO red below:</p>
+
+<div class="outer">
+  <div class="sibling"></div>
+  <div class="flattener"><span style="background: green"></span><div class="child"></div><div></div></div>
+  <div class="flattener"><div class="child"></div><div></div></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html
new file mode 100644
index 0000000..826ee4f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-006.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="preserve3d-and-flattening-002-ref.html">
+
+<style>
+body {
+  margin: 0;
+}
+div, span {
+  height: 100px;
+  width: 100px;
+  background: red;
+}
+span {
+  display: inline-block;
+  vertical-align: top;
+}
+div:not(:first-child):not(.outer) {
+  /* put everything at the same position without using absolute positioning */
+  margin-top: -100px;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.outer {
+  background: gray;
+}
+.flattener {
+  /* adding position:relative or a transform changes things */
+  background: fuchsia;
+}
+.sibling {
+  background: blue;
+  transform: translate3d(25px, 50px, -20px);
+}
+.child {
+  background: silver;
+  transform: translate3d(50px, 0, 10px);
+}
+</style>
+
+<div class="outer">
+  <div class="flattener">
+    <div class="child"></div>
+  </div>
+  <div class="sibling"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-007.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-007.html
new file mode 100644
index 0000000..8f22825
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-007.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="preserve3d-and-flattening-002-ref.html">
+
+<style>
+body {
+  margin: 0;
+}
+div, span {
+  height: 100px;
+  width: 100px;
+  background: red;
+}
+span {
+  display: inline-block;
+  vertical-align: top;
+}
+div:not(:first-child):not(.outer) {
+  /* put everything at the same position without using absolute positioning */
+  margin-top: -100px;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.outer {
+  background: gray;
+}
+.flattener {
+  /* adding position:relative or a transform changes things */
+  background: fuchsia;
+}
+.sibling {
+  background: blue;
+  transform: translate3d(25px, 50px, -20px);
+}
+.child {
+  background: silver;
+  transform: translate3d(50px, 0, 10px);
+  will-change: transform;
+}
+</style>
+
+<div class="outer">
+  <div class="flattener">
+    <div class="child"></div>
+  </div>
+  <div class="sibling"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-008.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-008.html
new file mode 100644
index 0000000..3370f8c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/preserve3d-and-flattening-z-order-008.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>CSS Test (Transforms): Flattening at the leafward edges of a preserve-3d scene</title>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1255544">
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#3d-transform-rendering">
+<meta name="assert" content="Elements are drawn in the correct z-order.">
+<link rel="match" href="reference/green.html">
+
+<style>
+div, span {
+  height: 100px;
+  width: 100px;
+  background: red;
+}
+span {
+  display: inline-block;
+  vertical-align: bottom;
+}
+.outer, .sibling {
+  transform-style: preserve-3d;
+}
+.sibling {
+  margin-top: -100px;
+  transform: translateZ(-10px);
+}
+
+.flattener:first-child {
+  background: linear-gradient(to bottom, green 0%, green 25%, red 25%, red 100%);
+}
+.flattener:first-child > .child {
+  background: linear-gradient(to bottom, green 0%, green 50%, red 50%, red 100%);
+  margin-top: 50px;
+  height: 50px;
+}
+.flattener:last-child {
+  background: linear-gradient(to bottom, green 0px, green 25px, red 25px, red 75px);
+  margin-top: -75px;
+  height: 75px;
+}
+.flattener:last-child > .child {
+  background: green;
+  margin-top: 50px;
+  height: 25px;
+}
+</style>
+
+<p>Pass if there is NO red below:</p>
+
+<div class="outer">
+  <div class="flattener"><span class="child"></span></div>
+  <div class="sibling"></div>
+  <div class="flattener"><span class="child"></span></div>
+</div>
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
deleted file mode 100644
index 5e18161f..0000000
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-This layer should not be composited.
-This layer should not be composited.
-This layer should be composited.
-{
-  "layers": [
-    {
-      "name": "Scrolling background of LayoutView #document",
-      "bounds": [785, 618],
-      "contentsOpaque": true,
-      "backgroundColor": "#FFFFFF"
-    },
-    {
-      "name": "LayoutNGBlockFlow DIV class='preserve3d'",
-      "bounds": [342, 182],
-      "transform": 2
-    },
-    {
-      "name": "LayoutNGBlockFlow (relative positioned) DIV class='box'",
-      "bounds": [100, 100],
-      "contentsOpaque": true,
-      "backgroundColor": "#C0C0C0",
-      "transform": 4
-    },
-    {
-      "name": "VerticalScrollbar",
-      "position": [785, 0],
-      "bounds": [15, 600]
-    }
-  ],
-  "transforms": [
-    {
-      "id": 1,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [18, 394, 0, 1]
-      ]
-    },
-    {
-      "id": 2,
-      "parent": 1,
-      "renderingContext": 1
-    },
-    {
-      "id": 3,
-      "parent": 2,
-      "transform": [
-        [1, 0, 0, 0],
-        [0, 1, 0, 0],
-        [0, 0, 1, 0],
-        [31, 51, 0, 1]
-      ],
-      "flattenInheritedTransform": false,
-      "renderingContext": 1
-    },
-    {
-      "id": 4,
-      "parent": 3,
-      "transform": [
-        [0.984807753012208, 0, -0.17364817766693, 0],
-        [0, 1, 0, 0],
-        [0.17364817766693, 0, 0.984807753012208, 0],
-        [0, 0, 0, 1]
-      ],
-      "origin": [50, 50],
-      "flattenInheritedTransform": false,
-      "renderingContext": 1
-    }
-  ]
-}
-
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
index 31ab0b9..410e6ba3 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
@@ -15,14 +15,13 @@
     },
     {
       "name": "LayoutNGBlockFlow (positioned) DIV id='target'",
-      "position": [28, 28],
       "bounds": [100, 100],
       "contentsOpaque": true,
       "backgroundColor": "#FF0000",
       "invalidations": [
         [0, 0, 100, 100]
       ],
-      "transform": 1
+      "transform": 4
     }
   ],
   "transforms": [
@@ -47,6 +46,18 @@
       "parent": 2,
       "flattenInheritedTransform": false,
       "renderingContext": 1
+    },
+    {
+      "id": 4,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [28, 28, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
     }
   ]
 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
index ed10803f..433aa2e 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
@@ -10,16 +10,30 @@
       "backgroundColor": "#FFFFFF"
     },
     {
-      "name": "LayoutBlockFlow DIV class='preserve3d'",
-      "bounds": [342, 182],
-      "transform": 2
-    },
-    {
-      "name": "LayoutBlockFlow (relative positioned) DIV class='box'",
+      "name": "LayoutBlockFlow (relative positioned) DIV id='box1' class='box'",
       "bounds": [100, 100],
       "contentsOpaque": true,
       "backgroundColor": "#C0C0C0",
-      "transform": 4
+      "transform": 2
+    },
+    {
+      "name": "LayoutBlockFlow (relative positioned) DIV id='box2' class='box'",
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 5
+    },
+    {
+      "name": "LayoutBlockFlow DIV id='layer3' class='preserve3d'",
+      "bounds": [342, 182],
+      "transform": 7
+    },
+    {
+      "name": "LayoutBlockFlow (relative positioned) DIV id='box3' class='box'",
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 9
     },
     {
       "name": "VerticalScrollbar",
@@ -30,6 +44,51 @@
   "transforms": [
     {
       "id": 1,
+      "renderingContext": 1
+    },
+    {
+      "id": 2,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [49, 61, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
+    },
+    {
+      "id": 3,
+      "renderingContext": 2
+    },
+    {
+      "id": 4,
+      "parent": 3,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [49, 253, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 5,
+      "parent": 4,
+      "transform": [
+        [0.984807753012208, 0.17364817766693, 0, 0],
+        [-0.17364817766693, 0.984807753012208, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "origin": [50, 50],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 6,
       "transform": [
         [1, 0, 0, 0],
         [0, 1, 0, 0],
@@ -38,13 +97,13 @@
       ]
     },
     {
-      "id": 2,
-      "parent": 1,
-      "renderingContext": 1
+      "id": 7,
+      "parent": 6,
+      "renderingContext": 3
     },
     {
-      "id": 3,
-      "parent": 2,
+      "id": 8,
+      "parent": 7,
       "transform": [
         [1, 0, 0, 0],
         [0, 1, 0, 0],
@@ -52,11 +111,11 @@
         [31, 51, 0, 1]
       ],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     },
     {
-      "id": 4,
-      "parent": 3,
+      "id": 9,
+      "parent": 8,
       "transform": [
         [0.984807753012208, 0, -0.17364817766693, 0],
         [0, 1, 0, 0],
@@ -65,7 +124,7 @@
       ],
       "origin": [50, 50],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     }
   ]
 }
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
index 28f5f0f7..b1a2d8d 100644
--- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
@@ -15,14 +15,13 @@
     },
     {
       "name": "LayoutBlockFlow (positioned) DIV id='target'",
-      "position": [28, 28],
       "bounds": [100, 100],
       "contentsOpaque": true,
       "backgroundColor": "#FF0000",
       "invalidations": [
         [0, 0, 100, 100]
       ],
-      "transform": 1
+      "transform": 4
     }
   ],
   "transforms": [
@@ -47,6 +46,18 @@
       "parent": 2,
       "flattenInheritedTransform": false,
       "renderingContext": 1
+    },
+    {
+      "id": 4,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [28, 28, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
     }
   ]
 }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/compositing/3d-cube-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/compositing/3d-cube-expected.png
index 42e46d0..ef2eda3 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/compositing/3d-cube-expected.png
+++ b/third_party/blink/web_tests/flag-specific/highdpi/compositing/3d-cube-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
index 98470b4..7547605 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
@@ -4,29 +4,41 @@
 {
   "layers": [
     {
-      "name": "Scrolling Contents Layer",
+      "name": "Scrolling background of LayoutView #document",
       "bounds": [1178, 916],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
     },
     {
-      "name": "LayoutNGBlockFlow DIV class='preserve3d'",
-      "position": [27, 585],
-      "bounds": [513, 270],
-      "transform": 1
-    },
-    {
-      "name": "LayoutNGBlockFlow (relative positioned) DIV class='box'",
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box1' class='box'",
       "bounds": [150, 150],
       "contentsOpaque": true,
       "backgroundColor": "#C0C0C0",
-      "transform": 3
+      "transform": 2
     },
     {
-      "name": "ContentsLayer for Vertical Scrollbar Layer",
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box2' class='box'",
+      "bounds": [150, 150],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 5
+    },
+    {
+      "name": "LayoutNGBlockFlow DIV id='layer3' class='preserve3d'",
+      "bounds": [513, 270],
+      "transform": 7
+    },
+    {
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box3' class='box'",
+      "bounds": [150, 150],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 9
+    },
+    {
+      "name": "VerticalScrollbar",
       "position": [1178, 0],
-      "bounds": [22, 900],
-      "contentsOpaque": true
+      "bounds": [22, 900]
     }
   ],
   "transforms": [
@@ -41,14 +53,69 @@
         [1, 0, 0, 0],
         [0, 1, 0, 0],
         [0, 0, 1, 0],
-        [74, 659, 0, 1]
+        [74, 89, 0, 1]
       ],
       "flattenInheritedTransform": false,
       "renderingContext": 1
     },
     {
       "id": 3,
-      "parent": 2,
+      "renderingContext": 2
+    },
+    {
+      "id": 4,
+      "parent": 3,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [74, 374, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 5,
+      "parent": 4,
+      "transform": [
+        [0.984807753012208, 0.17364817766693, 0, 0],
+        [-0.17364817766693, 0.984807753012208, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "origin": [75, 75],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 6,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [27, 585, 0, 1]
+      ]
+    },
+    {
+      "id": 7,
+      "parent": 6,
+      "renderingContext": 3
+    },
+    {
+      "id": 8,
+      "parent": 7,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [47, 74, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 3
+    },
+    {
+      "id": 9,
+      "parent": 8,
       "transform": [
         [0.984807753012208, 0, -0.17364817766693, 0],
         [0, 1, 0, 0],
@@ -57,7 +124,7 @@
       ],
       "origin": [75, 75],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     }
   ]
 }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
index b3cf8d09..c726b823 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
@@ -1,7 +1,7 @@
 {
   "layers": [
     {
-      "name": "Scrolling Contents Layer",
+      "name": "Scrolling background of LayoutView #document",
       "bounds": [1200, 900],
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF"
@@ -14,14 +14,14 @@
       "transform": 3
     },
     {
-      "name": "Squashing Layer (first squashed layer: LayoutNGBlockFlow (positioned) DIV id='target')",
-      "position": [30, 30],
+      "name": "LayoutNGBlockFlow (positioned) DIV id='target'",
       "bounds": [150, 150],
+      "contentsOpaque": true,
       "backgroundColor": "#FF0000",
       "invalidations": [
         [0, 0, 150, 150]
       ],
-      "transform": 2
+      "transform": 4
     }
   ],
   "transforms": [
@@ -46,6 +46,18 @@
       "parent": 2,
       "flattenInheritedTransform": false,
       "renderingContext": 1
+    },
+    {
+      "id": 4,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [42, 42, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
     }
   ]
 }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
deleted file mode 100644
index bbbbeb8..0000000
--- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js
index 9f15356..1871a0d 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/websocket/slow-network.js
@@ -14,16 +14,12 @@
         return new Promise((resolve) => {
           const ws = new WebSocket('ws://localhost:8880/echo');
           let startTime;
-          let numMessages = 0;
           ws.onopen = () => {
             startTime = performance.now();
-            ws.send('x'.repeat(1000));
-            ws.send('x'.repeat(1000));
+            ws.send('x'.repeat(2000));
+            ws.send('x'.repeat(2000));
           };
-          ws.onmessage = () => {
-            ++numMessages;
-            if (numMessages == 2) resolve(performance.now() - startTime);
-          }
+          ws.onmessage = () => { resolve(performance.now() - startTime); }
           ws.onerror = () => log += 'onerror ';
           ws.onclose = () => log += 'onclose ';
         });
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt
index c704856..92e6b2e 100644
--- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt
@@ -1,4 +1,9 @@
 [INTERFACES]
+interface BarcodeDetector
+    static method getSupportedFormats
+    attribute @@toStringTag
+    method constructor
+    method detect
 interface Notification : EventTarget
     getter image
 [NAMESPACES]
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 83dcd944..c69b987 100644
--- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -51,11 +51,6 @@
     attribute @@toStringTag
     method constructor
     method updateUI
-interface BarcodeDetector
-    static method getSupportedFormats
-    attribute @@toStringTag
-    method constructor
-    method detect
 interface Blob
     attribute @@toStringTag
     getter size
diff --git a/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt b/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
index 31ab0b9..410e6ba3 100644
--- a/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
+++ b/third_party/blink/web_tests/paint/invalidation/compositing/squashing-inside-preserve-3d-element-expected.txt
@@ -15,14 +15,13 @@
     },
     {
       "name": "LayoutNGBlockFlow (positioned) DIV id='target'",
-      "position": [28, 28],
       "bounds": [100, 100],
       "contentsOpaque": true,
       "backgroundColor": "#FF0000",
       "invalidations": [
         [0, 0, 100, 100]
       ],
-      "transform": 1
+      "transform": 4
     }
   ],
   "transforms": [
@@ -47,6 +46,18 @@
       "parent": 2,
       "flattenInheritedTransform": false,
       "renderingContext": 1
+    },
+    {
+      "id": 4,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [28, 28, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
     }
   ]
 }
diff --git a/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png b/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
index 72a5871..856e7197 100644
--- a/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
+++ b/third_party/blink/web_tests/platform/linux/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/3d-cube-expected.png b/third_party/blink/web_tests/platform/mac/compositing/3d-cube-expected.png
index 384ae88..0379629e 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/3d-cube-expected.png
+++ b/third_party/blink/web_tests/platform/mac/compositing/3d-cube-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt b/third_party/blink/web_tests/platform/mac/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
index 016ef3a..80731a7cf 100644
--- a/third_party/blink/web_tests/platform/mac/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
@@ -10,16 +10,30 @@
       "backgroundColor": "#FFFFFF"
     },
     {
-      "name": "LayoutNGBlockFlow DIV class='preserve3d'",
-      "bounds": [342, 180],
-      "transform": 2
-    },
-    {
-      "name": "LayoutNGBlockFlow (relative positioned) DIV class='box'",
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box1' class='box'",
       "bounds": [100, 100],
       "contentsOpaque": true,
       "backgroundColor": "#C0C0C0",
-      "transform": 4
+      "transform": 2
+    },
+    {
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box2' class='box'",
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 5
+    },
+    {
+      "name": "LayoutNGBlockFlow DIV id='layer3' class='preserve3d'",
+      "bounds": [342, 180],
+      "transform": 7
+    },
+    {
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box3' class='box'",
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 9
     },
     {
       "name": "VerticalScrollbar",
@@ -30,6 +44,51 @@
   "transforms": [
     {
       "id": 1,
+      "renderingContext": 1
+    },
+    {
+      "id": 2,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [49, 59, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
+    },
+    {
+      "id": 3,
+      "renderingContext": 2
+    },
+    {
+      "id": 4,
+      "parent": 3,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [49, 249, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 5,
+      "parent": 4,
+      "transform": [
+        [0.984807753012208, 0.17364817766693, 0, 0],
+        [-0.17364817766693, 0.984807753012208, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "origin": [50, 50],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 6,
       "transform": [
         [1, 0, 0, 0],
         [0, 1, 0, 0],
@@ -38,13 +97,13 @@
       ]
     },
     {
-      "id": 2,
-      "parent": 1,
-      "renderingContext": 1
+      "id": 7,
+      "parent": 6,
+      "renderingContext": 3
     },
     {
-      "id": 3,
-      "parent": 2,
+      "id": 8,
+      "parent": 7,
       "transform": [
         [1, 0, 0, 0],
         [0, 1, 0, 0],
@@ -52,11 +111,11 @@
         [31, 49, 0, 1]
       ],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     },
     {
-      "id": 4,
-      "parent": 3,
+      "id": 9,
+      "parent": 8,
       "transform": [
         [0.984807753012208, 0, -0.17364817766693, 0],
         [0, 1, 0, 0],
@@ -65,7 +124,7 @@
       ],
       "origin": [50, 50],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     }
   ]
 }
diff --git a/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png b/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
index 435549f0..43681bc 100644
--- a/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
+++ b/third_party/blink/web_tests/platform/mac/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt
index d6e213f..6abc29e 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-platform-specific-service-worker-expected.txt
@@ -1,4 +1,9 @@
 [INTERFACES]
+interface BarcodeDetector
+    static method getSupportedFormats
+    attribute @@toStringTag
+    method constructor
+    method detect
 interface Notification : EventTarget
 [NAMESPACES]
 [GLOBAL OBJECT]
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
index 038f2b1..5c8c872 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
@@ -4,6 +4,11 @@
 
 Starting worker: resources/global-interface-listing-worker.js
 [Worker] [INTERFACES]
+[Worker] interface BarcodeDetector
+[Worker]     static method getSupportedFormats
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method detect
 [Worker] interface Notification : EventTarget
 [Worker] [NAMESPACES]
 [Worker] [GLOBAL OBJECT]
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
index 3af5376..fa72a06 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-expected.txt
@@ -3,6 +3,11 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 [INTERFACES]
+interface BarcodeDetector
+    static method getSupportedFormats
+    attribute @@toStringTag
+    method constructor
+    method detect
 interface Bluetooth : EventTarget
     attribute @@toStringTag
     method constructor
diff --git a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
index 034c681..802ec99 100644
--- a/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/virtual/stable/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
@@ -4,6 +4,11 @@
 
 Starting worker: resources/global-interface-listing-worker.js
 [Worker] [INTERFACES]
+[Worker] interface BarcodeDetector
+[Worker]     static method getSupportedFormats
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method detect
 [Worker] interface Notification : EventTarget
 [Worker] [NAMESPACES]
 [Worker] [GLOBAL OBJECT]
diff --git a/third_party/blink/web_tests/platform/win/compositing/3d-cube-expected.png b/third_party/blink/web_tests/platform/win/compositing/3d-cube-expected.png
index ce4ff2a71..5f45f629 100644
--- a/third_party/blink/web_tests/platform/win/compositing/3d-cube-expected.png
+++ b/third_party/blink/web_tests/platform/win/compositing/3d-cube-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt b/third_party/blink/web_tests/platform/win/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
index 5e18161f..6a2fbf1 100644
--- a/third_party/blink/web_tests/platform/win/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
+++ b/third_party/blink/web_tests/platform/win/compositing/layer-creation/no-compositing-for-preserve-3d-expected.txt
@@ -10,16 +10,30 @@
       "backgroundColor": "#FFFFFF"
     },
     {
-      "name": "LayoutNGBlockFlow DIV class='preserve3d'",
-      "bounds": [342, 182],
-      "transform": 2
-    },
-    {
-      "name": "LayoutNGBlockFlow (relative positioned) DIV class='box'",
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box1' class='box'",
       "bounds": [100, 100],
       "contentsOpaque": true,
       "backgroundColor": "#C0C0C0",
-      "transform": 4
+      "transform": 2
+    },
+    {
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box2' class='box'",
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 5
+    },
+    {
+      "name": "LayoutNGBlockFlow DIV id='layer3' class='preserve3d'",
+      "bounds": [342, 182],
+      "transform": 7
+    },
+    {
+      "name": "LayoutNGBlockFlow (relative positioned) DIV id='box3' class='box'",
+      "bounds": [100, 100],
+      "contentsOpaque": true,
+      "backgroundColor": "#C0C0C0",
+      "transform": 9
     },
     {
       "name": "VerticalScrollbar",
@@ -30,6 +44,51 @@
   "transforms": [
     {
       "id": 1,
+      "renderingContext": 1
+    },
+    {
+      "id": 2,
+      "parent": 1,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [49, 61, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 1
+    },
+    {
+      "id": 3,
+      "renderingContext": 2
+    },
+    {
+      "id": 4,
+      "parent": 3,
+      "transform": [
+        [1, 0, 0, 0],
+        [0, 1, 0, 0],
+        [0, 0, 1, 0],
+        [49, 253, 0, 1]
+      ],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 5,
+      "parent": 4,
+      "transform": [
+        [0.984807753012208, 0.17364817766693, 0, 0],
+        [-0.17364817766693, 0.984807753012208, 0, 0],
+        [0, 0, 1, 0],
+        [0, 0, 0, 1]
+      ],
+      "origin": [50, 50],
+      "flattenInheritedTransform": false,
+      "renderingContext": 2
+    },
+    {
+      "id": 6,
       "transform": [
         [1, 0, 0, 0],
         [0, 1, 0, 0],
@@ -38,13 +97,13 @@
       ]
     },
     {
-      "id": 2,
-      "parent": 1,
-      "renderingContext": 1
+      "id": 7,
+      "parent": 6,
+      "renderingContext": 3
     },
     {
-      "id": 3,
-      "parent": 2,
+      "id": 8,
+      "parent": 7,
       "transform": [
         [1, 0, 0, 0],
         [0, 1, 0, 0],
@@ -52,11 +111,11 @@
         [31, 51, 0, 1]
       ],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     },
     {
-      "id": 4,
-      "parent": 3,
+      "id": 9,
+      "parent": 8,
       "transform": [
         [0.984807753012208, 0, -0.17364817766693, 0],
         [0, 1, 0, 0],
@@ -65,7 +124,7 @@
       ],
       "origin": [50, 50],
       "flattenInheritedTransform": false,
-      "renderingContext": 1
+      "renderingContext": 3
     }
   ]
 }
diff --git a/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png b/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
index 4061944..bde18113 100644
--- a/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
+++ b/third_party/blink/web_tests/platform/win/transforms/3d/point-mapping/3d-point-mapping-preserve-3d-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/resources/global-interface-listing.js b/third_party/blink/web_tests/resources/global-interface-listing.js
index 5b4d5aa..16fbc4e 100644
--- a/third_party/blink/web_tests/resources/global-interface-listing.js
+++ b/third_party/blink/web_tests/resources/global-interface-listing.js
@@ -118,6 +118,7 @@
 // platform-specific expectations files to a bare minimum to make updates in the
 // common (platform-neutral) case as simple as possible.
 var platformSpecificInterfaces = new Set([
+  'BarcodeDetector',
   'Bluetooth',
   'BluetoothCharacteristicProperties',
   'BluetoothDevice',
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index 08d172c52..d25a338 100644
--- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -51,11 +51,6 @@
     attribute @@toStringTag
     method constructor
     method updateUI
-interface BarcodeDetector
-    static method getSupportedFormats
-    attribute @@toStringTag
-    method constructor
-    method detect
 interface Blob
     attribute @@toStringTag
     getter size
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 17e6b65..2a352b6 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -79,11 +79,6 @@
 [Worker]     method match
 [Worker]     method matchAll
 [Worker]     setter onprogress
-[Worker] interface BarcodeDetector
-[Worker]     static method getSupportedFormats
-[Worker]     attribute @@toStringTag
-[Worker]     method constructor
-[Worker]     method detect
 [Worker] interface Blob
 [Worker]     attribute @@toStringTag
 [Worker]     getter size
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
index 8680bdd..2769a0e 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -320,11 +320,6 @@
     attribute @@toStringTag
     getter visible
     method constructor
-interface BarcodeDetector
-    static method getSupportedFormats
-    attribute @@toStringTag
-    method constructor
-    method detect
 interface BaseAudioContext : EventTarget
     attribute @@toStringTag
     getter audioWorklet
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
index 8b1e371e..ab9f8573 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -44,11 +44,6 @@
 [Worker]     method match
 [Worker]     method matchAll
 [Worker]     setter onprogress
-[Worker] interface BarcodeDetector
-[Worker]     static method getSupportedFormats
-[Worker]     attribute @@toStringTag
-[Worker]     method constructor
-[Worker]     method detect
 [Worker] interface Blob
 [Worker]     attribute @@toStringTag
 [Worker]     getter size
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index e6837c3..8feba2bf 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -79,11 +79,6 @@
 [Worker]     method match
 [Worker]     method matchAll
 [Worker]     setter onprogress
-[Worker] interface BarcodeDetector
-[Worker]     static method getSupportedFormats
-[Worker]     attribute @@toStringTag
-[Worker]     method constructor
-[Worker]     method detect
 [Worker] interface Blob
 [Worker]     attribute @@toStringTag
 [Worker]     getter size
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index a41f0fa4..3feddb0 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -537,11 +537,6 @@
     attribute @@toStringTag
     getter visible
     method constructor
-interface BarcodeDetector
-    static method getSupportedFormats
-    attribute @@toStringTag
-    method constructor
-    method detect
 interface BaseAudioContext : EventTarget
     attribute @@toStringTag
     getter audioWorklet
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
index 35dc755..bf64d64f 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-dedicated-worker-expected.txt
@@ -4,6 +4,11 @@
 
 Starting worker: resources/global-interface-listing-worker.js
 [Worker] [INTERFACES]
+[Worker] interface BarcodeDetector
+[Worker]     static method getSupportedFormats
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method detect
 [Worker] interface Notification : EventTarget
 [Worker]     getter image
 [Worker] [NAMESPACES]
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt
index 0e40791..c4d6a2e2 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-expected.txt
@@ -3,6 +3,11 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 [INTERFACES]
+interface BarcodeDetector
+    static method getSupportedFormats
+    attribute @@toStringTag
+    method constructor
+    method detect
 interface Bluetooth : EventTarget
     attribute @@toStringTag
     getter onadvertisementreceived
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
index be8425d..639c7c6 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-platform-specific-shared-worker-expected.txt
@@ -4,6 +4,11 @@
 
 Starting worker: resources/global-interface-listing-worker.js
 [Worker] [INTERFACES]
+[Worker] interface BarcodeDetector
+[Worker]     static method getSupportedFormats
+[Worker]     attribute @@toStringTag
+[Worker]     method constructor
+[Worker]     method detect
 [Worker] interface Notification : EventTarget
 [Worker]     getter image
 [Worker] [NAMESPACES]
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
index 5a539be..2e328ac 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -44,11 +44,6 @@
 [Worker]     method match
 [Worker]     method matchAll
 [Worker]     setter onprogress
-[Worker] interface BarcodeDetector
-[Worker]     static method getSupportedFormats
-[Worker]     attribute @@toStringTag
-[Worker]     method constructor
-[Worker]     method detect
 [Worker] interface Blob
 [Worker]     attribute @@toStringTag
 [Worker]     getter size
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/pointer-lock.https.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/pointer-lock.https.html
deleted file mode 100644
index fd0e22d..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/pointer-lock.https.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<title>Test of pointer lock</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src="resources/utils.js"></script>
-
-<body>
-
-<script>
-promise_test(async t => {
-  const pointer_lock_key = KEYS['pointer-lock'];
-
-  attachFencedFrame('resources/pointer-lock-inner.html');
-  const actual_result = await nextValueFromServer(pointer_lock_key);
-
-  assert_equals(
-      actual_result, 'Pointer lock failed',
-      'Pointer lock in a fenced frame must fail.');
-}, 'Pointer lock in a fenced frame must fail');
-</script>
-
-</body>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/pointer-lock-inner.html b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/pointer-lock-inner.html
deleted file mode 100644
index 4adbac992..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/pointer-lock-inner.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src="utils.js"></script>
-<title>Fenced frame content to test pointer lock</title>
-
-<body>
-<script>
-(() => {
-  const canvas = document.createElement('canvas');
-  document.body.appendChild(canvas);
-  const button = document.createElement('button');
-  button.appendChild(document.createTextNode('Click'));
-  button.addEventListener('click', async () => {
-    const pointer_lock_key = KEYS['pointer-lock'];
-    const pointerlockerror_promise = new Promise(resolve => {
-      document.addEventListener('pointerlockerror', resolve);
-    });
-    try {
-      await canvas.requestPointerLock();
-      writeValueToServer(pointer_lock_key, 'Pointer lock succeeded');
-    } catch (e) {
-      await pointerlockerror_promise;
-      writeValueToServer(pointer_lock_key, 'Pointer lock failed');
-    }
-    document.exitPointerLock();
-  });
-  document.body.appendChild(button);
-  new test_driver
-      .Actions()
-      .pointerMove(/*x=*/ 0, /*y=*/ 0, {origin: button})
-      .pointerDown()
-      .pointerUp()
-      .send();
-})();
-</script>
-</body>
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/pointer-lock-inner.html.headers b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/pointer-lock-inner.html.headers
deleted file mode 100644
index 1b63235..0000000
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/pointer-lock-inner.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Supports-Loading-Mode: fenced-frame
diff --git a/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js b/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js
index ac02a6b7..f6a393e 100644
--- a/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js
+++ b/third_party/blink/web_tests/wpt_internal/webcodecs/temporal_svc.https.any.js
@@ -16,8 +16,10 @@
       frames_encoded++;
 
       // Filter out all frames, but base layer.
-      assert_less_than(metadata.temporalLayerId, layers);
-      if (metadata.temporalLayerId == 0)
+      assert_own_property(metadata, "svc");
+      assert_own_property(metadata.svc, "temporalLayerId");
+      assert_less_than(metadata.svc.temporalLayerId, layers);
+      if (metadata.svc.temporalLayerId == 0)
         chunks.push(chunk);
     },
     error(e) {
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
index b17f1ba..1315dc3 100644
--- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
+++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
@@ -2676,7 +2676,6 @@
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,exp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,exp2:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,faceForward:*'>
-<meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,floor:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,fma:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,fract:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,scalar_case_frexp:*'>
@@ -2707,6 +2706,7 @@
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,tan:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,tanh:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,float_built_functions:float_builtin_functions,trunc:*'>
+<meta name=variant content='?q=webgpu:shader,execution,builtin,floor:float_builtin_functions,floor:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,unsigned_clamp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,signed_clamp:*'>
 <meta name=variant content='?q=webgpu:shader,execution,builtin,integer_built_in_functions:integer_builtin_functions,count_1_bits:*'>
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium
index eeecde3..3a6a4cc 100644
--- a/third_party/metrics_proto/README.chromium
+++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@
 Name: Metrics Protos
 Short Name: metrics_proto
 URL: This is the canonical public repository
-Version: 410840368
-Date: 2021/11/18 UTC
+Version: 412995826
+Date: 2021/11/29 UTC
 License: BSD
 Security Critical: Yes
 
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto
index 3ee91722..1a0dff1 100644
--- a/third_party/metrics_proto/system_profile.proto
+++ b/third_party/metrics_proto/system_profile.proto
@@ -619,25 +619,6 @@
     // it only gives the process a few seconds to clean up.)
     optional int32 incomplete_shutdown_count = 17;
 
-    // The number of times the program was able register with breakpad crash
-    // services.
-    optional int32 breakpad_registration_success_count = 18;
-
-    // The number of times the program failed to register with breakpad crash
-    // services.  If crash registration fails then when the program crashes no
-    // crash report will be generated.
-    optional int32 breakpad_registration_failure_count = 19;
-
-    // The number of times the program has run under a debugger.  This should
-    // be an exceptional condition.  Running under a debugger prevents crash
-    // dumps from being generated.
-    optional int32 debugger_present_count = 20;
-
-    // The number of times the program has run without a debugger attached.
-    // This should be most common scenario and should be very close to
-    // |launch_count|.
-    optional int32 debugger_not_present_count = 21;
-
     // Whether the metrics being reported are from a previous run picked up via
     // the left-over memory mapped files.
     optional bool from_previous_run = 29;
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt
index 4300af6..af250ca 100644
--- a/third_party/webgpu-cts/ts_sources.txt
+++ b/third_party/webgpu-cts/ts_sources.txt
@@ -255,6 +255,7 @@
 src/webgpu/shader/execution/builtin/ceil.spec.ts
 src/webgpu/shader/execution/builtin/cos.spec.ts
 src/webgpu/shader/execution/builtin/float_built_functions.spec.ts
+src/webgpu/shader/execution/builtin/floor.spec.ts
 src/webgpu/shader/execution/builtin/integer_built_in_functions.spec.ts
 src/webgpu/shader/execution/builtin/logical_built_in_functions.spec.ts
 src/webgpu/shader/execution/builtin/min.spec.ts
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 2bd906e..478489c 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -8241,7 +8241,6 @@
   <int value="253" label="RFH_INTERECEPT_DOWNLOAD_WHILE_INACTIVE"/>
   <int value="254" label="RFH_CREATE_CHILD_FRAME_SANDBOX_FLAGS"/>
   <int value="255" label="RFPH_FOCUSED_FENCED_FRAME"/>
-  <int value="256" label="WCI_REQUEST_LOCK_MOUSE_FENCED_FRAME"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions">
@@ -57618,6 +57617,7 @@
   <int value="21" label="AutoDarkWebContents"/>
   <int value="22" label="TestMessage"/>
   <int value="23" label="TailoredSecurityEnabled"/>
+  <int value="24" label="VrServicesUpgrade"/>
 </enum>
 
 <enum name="MessageLoopProblems">
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index dc3cbf2c..091d8b08 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -102,6 +102,7 @@
   <variant name=".SyncError"/>
   <variant name=".TailoredSecurityEnabled"/>
   <variant name=".UpdatePassword"/>
+  <variant name=".VrServicesUpgrade"/>
 </variants>
 
 <variants name="ProviderPermissionType">
@@ -4009,7 +4010,7 @@
 </histogram>
 
 <histogram name="Android.WebView.ForceDarkBehavior"
-    enum="WebViewForceDarkBehavior" expires_after="2021-12-03">
+    enum="WebViewForceDarkBehavior" expires_after="2022-06-03">
   <owner>peter@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -4019,7 +4020,7 @@
 </histogram>
 
 <histogram name="Android.WebView.ForceDarkMode" enum="WebViewForceDarkMode"
-    expires_after="2021-12-03">
+    expires_after="2022-06-03">
   <owner>peter@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml
index 9a287ba..3e42972 100644
--- a/tools/metrics/histograms/metadata/commerce/histograms.xml
+++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -150,6 +150,19 @@
   </summary>
 </histogram>
 
+<histogram name="Commerce.PriceDrop.AnnotationsEnabled" enum="Boolean"
+    expires_after="2022-06-01">
+  <owner>ayman@chromium.org</owner>
+  <owner>zhiyuancai@chromium.org</owner>
+  <owner>chrome-shopping@google.com</owner>
+  <summary>
+    Records whether the price drop annotation is enabled. Recorded when user
+    enters the grid tab switcher. The record frequency is controlled by a
+    feature parameter and by default it is recorded at most once every day.
+    Implemented for Android.
+  </summary>
+</histogram>
+
 <histogram name="Commerce.PriceDrop.NotificationChannelBlocked" enum="Boolean"
     expires_after="2022-06-01">
   <owner>zhiyuancai@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/content_creation/histograms.xml b/tools/metrics/histograms/metadata/content_creation/histograms.xml
index 6a6cc4dd..293f0b2 100644
--- a/tools/metrics/histograms/metadata/content_creation/histograms.xml
+++ b/tools/metrics/histograms/metadata/content_creation/histograms.xml
@@ -25,6 +25,21 @@
 
 <histograms>
 
+<histogram name="LightweightReactions.AssetsFetchDuration" units="ms"
+    expires_after="2022-07-31">
+  <obsolete>
+    Removed 12/2021 in favor of
+    LightweightReactions.AssetsFetchDuration.{Outcome}, which is more useful
+    because it includes whether the fetch was a success or not.
+  </obsolete>
+  <owner>gujen@google.com</owner>
+  <owner>chrome-creation@google.com</owner>
+  <summary>
+    Records the amount of time taken to download all assets during dialog
+    initialization.
+  </summary>
+</histogram>
+
 <histogram name="LightweightReactions.AssetsFetchDuration.{Outcome}" units="ms"
     expires_after="2022-07-31">
   <owner>gujen@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index ba9eaf0f..462b006 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -10832,6 +10832,7 @@
   <suffix name="BatchUpdateGoogleSRP"
       label="Batch update of hints for result links off the Google SRP"/>
   <suffix name="BatchUpdateModels" label="Batch update of models"/>
+  <suffix name="Bookmarks" label="Batch update of hints for bookmarks"/>
   <suffix name="PageNavigation" label="Page navigation"/>
   <affected-histogram
       name="OptimizationGuide.HintsFetcher.GetHintsRequest.ActiveRequestCanceled"/>
@@ -17216,6 +17217,7 @@
 
 <histogram_suffixes name="SystemNotificationAgeType" separator=".">
   <suffix name="ClickToCall" label="Click To Call"/>
+  <suffix name="PriceDrop" label="Price Drop Alerts"/>
   <suffix name="SendTabToSelf" label="Send Tab To Self"/>
   <suffix name="SharedClipboard" label="Shared Clipboard"/>
   <affected-histogram name="Mobile.SystemNotification.Action.Click.Age"/>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 4499ffc..15e7a9ba 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -7095,6 +7095,28 @@
 <histogram
     name="Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart.Frames"
     units="vsyncs" expires_after="2021-09-01">
+  <obsolete>
+    Removed 2021-11-29.
+  </obsolete>
+  <owner>sadrul@chromium.org</owner>
+  <owner>behdadb@chromium.org</owner>
+  <summary>Metric is replaced by DroppedFrameAfterScrollStart2.Time.</summary>
+</histogram>
+
+<histogram
+    name="Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart.Time"
+    units="ms" expires_after="2021-09-01">
+  <obsolete>
+    Removed 2021-11-29.
+  </obsolete>
+  <owner>sadrul@chromium.org</owner>
+  <owner>behdadb@chromium.org</owner>
+  <summary>Metric is replaced by DroppedFrameAfterScrollStart2.Time.</summary>
+</histogram>
+
+<histogram
+    name="Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart2.Frames"
+    units="vsyncs" expires_after="2022-11-29">
   <owner>sadrul@chromium.org</owner>
   <owner>behdadb@chromium.org</owner>
   <summary>
@@ -7106,8 +7128,8 @@
 </histogram>
 
 <histogram
-    name="Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart.Time"
-    units="ms" expires_after="2021-09-01">
+    name="Graphics.Smoothness.Diagnostic.DroppedFrameAfterScrollStart2.Time"
+    units="ms" expires_after="2022-11-29">
   <owner>sadrul@chromium.org</owner>
   <owner>behdadb@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 081edb5..8f9859f 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,12 +5,12 @@
             "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "win": {
-            "hash": "effa04c578df0d6ac049ea745e65dd07e27e1571",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/70f73380a55418668aa87df92c6c85253e053af3/trace_processor_shell.exe"
+            "hash": "9405df9253ab4a871ff35fa75ad18727814a2f2e",
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/9296f1edfee55523164a8c3cae7458b21a36dc2d/trace_processor_shell.exe"
         },
         "mac": {
             "hash": "4a926d300d0f033f8228621e17025616e662f664",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/b3264966e5b08c517f603457910595b5aa456c90/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/4a9b683ccbbb7f1d3d16645671e960dae6a8a352/trace_processor_shell"
         },
         "linux_arm64": {
             "hash": "5074025a2898ec41a872e70a5719e417acb0a380",
@@ -18,7 +18,7 @@
         },
         "linux": {
             "hash": "df3fbde5f64bc02eac02cc4b745c21e879d68953",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/9296f1edfee55523164a8c3cae7458b21a36dc2d/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/4a9b683ccbbb7f1d3d16645671e960dae6a8a352/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index 95e43e42..e3fa859f 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -508,6 +508,7 @@
 # Memory dumps don't work at the moment for Google Earth and AutoCAD, see the issue.
 crbug.com/1057035 system_health.memory_desktop/browse:tools:earth:2020 [ Skip ]
 crbug.com/1057035 system_health.memory_desktop/browse:tools:autocad:2021 [ Skip ]
+crbug.com/1057035 system_health.memory_desktop/browse:tools:photoshop:2021 [ Skip ]
 
 # Benchmark: system_health.memory_mobile
 crbug.com/1007355 [ android-go android-webview ] system_health.memory_mobile/load:media:imgur:2018 [ Skip ]
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json
index 483e3cf..ca4662d 100644
--- a/tools/perf/page_sets/data/system_health_desktop.json
+++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -148,6 +148,9 @@
         "browse:tools:maps:2019": {
             "DEFAULT": "system_health_desktop_feb332ef0c.wprgo"
         },
+        "browse:tools:photoshop:2021": {
+            "DEFAULT": "system_health_desktop_c2c16f23ac.wprgo"
+        },
         "browse:tools:sheets:2019": {
             "DEFAULT": "system_health_desktop_d7b02362d8.wprgo"
         },
diff --git a/tools/perf/page_sets/data/system_health_desktop_c2c16f23ac.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_c2c16f23ac.wprgo.sha1
new file mode 100644
index 0000000..ac319633
--- /dev/null
+++ b/tools/perf/page_sets/data/system_health_desktop_c2c16f23ac.wprgo.sha1
@@ -0,0 +1 @@
+c2c16f23ac8862fad72dfe92df829c26fd6deabd
\ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py
index 590435d..819964b 100644
--- a/tools/perf/page_sets/system_health/browsing_stories.py
+++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -709,6 +709,63 @@
   TAGS = [story_tags.JAVASCRIPT_HEAVY, story_tags.YEAR_2019]
 
 
+class PhotoshopDesktopStory2021(_MediaBrowsingStory):
+  """Photoshop desktop story,
+  Measure the time it takes to open a shared Photoshop file.
+  """
+  NAME = 'browse:tools:photoshop:2021'
+  URL = 'https://photoshop.adobe.com/id/urn:aaid:sc:EU:1856a1e7-f397-4616-b399-9cd3b3d8c029'
+  SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
+  TAGS = [story_tags.YEAR_2021, story_tags.WEBASSEMBLY, story_tags.WEBGL]
+
+  # This map translates page-specific event names to event names needed for
+  # the reported_by_page:* metric.
+  EVENTS_REPORTED_BY_PAGE = '''
+    window.__telemetry_reported_page_events = {
+      'Doc.open':
+          'telemetry:reported_by_page:benchmark_begin',
+      'Doc.open complete':
+          'telemetry:reported_by_page:benchmark_end'
+    };
+  '''
+
+  # Patch performance.mark to get notified about page events.
+  PERFORMANCE_MARK_PATCH = '''
+    window.__telemetry_observed_page_events = new Set();
+    (function () {
+      let reported = window.__telemetry_reported_page_events;
+      let observed = window.__telemetry_observed_page_events;
+      let performance_mark = window.performance.mark;
+      window.performance.mark = function (label) {
+        performance_mark.call(window.performance, label);
+        if (reported.hasOwnProperty(label)) {
+          performance_mark.call(
+              window.performance, reported[label]);
+          observed.add(reported[label]);
+        }
+      }
+    })();
+  '''
+
+  # Page event queries.
+  FINISHED_EVENT = '''
+    (window.__telemetry_observed_page_events.has(
+        "telemetry:reported_by_page:benchmark_end"))
+  '''
+
+  def __init__(self, story_set, take_memory_measurement):
+    super(PhotoshopDesktopStory2021, self).__init__(story_set,
+                                                    take_memory_measurement)
+    self.script_to_evaluate_on_commit = js_template.Render(
+        '''{{@events_reported_by_page}}
+        {{@performance_mark}}''',
+        events_reported_by_page=self.EVENTS_REPORTED_BY_PAGE,
+        performance_mark=self.PERFORMANCE_MARK_PATCH)
+
+  def _DidLoadDocument(self, action_runner):
+    action_runner.WaitForJavaScriptCondition(self.FINISHED_EVENT)
+
+
 class AutoCADDesktopStory2021(_MediaBrowsingStory):
   """AutoCAD desktop story,
   TODO: add a description here.
diff --git a/tools/perf/system_health_stories.csv b/tools/perf/system_health_stories.csv
index 562c71e..311e597 100644
--- a/tools/perf/system_health_stories.csv
+++ b/tools/perf/system_health_stories.csv
@@ -58,6 +58,7 @@
 browse:tools:gmail-openconversation:2020,,desktop,2020
 browse:tools:gmail-search:2020,,desktop,2020
 browse:tools:maps:2019,Google maps story:,"desktop,mobile","2019,emerging_market,health_check,javascript_heavy,webgl"
+browse:tools:photoshop:2021,"Photoshop desktop story,",desktop,"2021,wasm,webgl"
 browse:tools:sheets:2019,,desktop,"2019,health_check,javascript_heavy"
 browse_accessibility:media:youtube,Tests interacting with the YouTube home page.,desktop,"2016,accessibility,keyboard_input"
 browse_accessibility:tech:codesearch:2018,Tests scrolling an element within a page.,desktop,"2018,accessibility,scroll"
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc
index a0ab4f5..ae66c0f3 100644
--- a/ui/accessibility/ax_event_generator.cc
+++ b/ui/accessibility/ax_event_generator.cc
@@ -1135,6 +1135,14 @@
       }
     }
 
+    // Don't fire parent changed on ignored events, because these nodes do not
+    // exist for platform accessibility. If the node toggles the ignored state,
+    // that's an IGNORED_CHANGED event and it's treated differently. In some
+    // occasions it may result in a PARENT_CHANGED event on a different node
+    // (see AXEventGenerator::OnIgnoredChanged).
+    if (node->IsIgnored())
+      RemoveEvent(&node_events, Event::PARENT_CHANGED);
+
     // Don't fire subtree created on this node if any of its ancestors also has
     // subtree created.
     parent = node->GetUnignoredParent();
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc
index 039dada..38df4e1 100644
--- a/ui/accessibility/ax_event_generator_unittest.cc
+++ b/ui/accessibility/ax_event_generator_unittest.cc
@@ -3012,4 +3012,356 @@
           HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 3)));
 }
 
+TEST(AXEventGeneratorTest, NoParentChangedOnIgnoredNode) {
+  // This test produces parent-changed events on ignored nodes, and serves as a
+  // way to test they are properly removed in PostprocessEvents.
+  // It was created through pseudo-automatic code generation and is based on the
+  // chrome://history page, where we detected this kind of events happening.
+
+  // BEFORE:
+  // id=47 application child_ids=167,94
+  //   id=167 inlineTextBox
+  //   id=94 grid child_ids=98,99
+  //     id=98 genericContainer IGNORED
+  //     id=99 genericContainer child_ids=100
+  //       id=100 genericContainer IGNORED child_ids=101
+  //         id=101 genericContainer IGNORED INVISIBLE
+
+  // AFTER
+  // id=47 application child_ids=167,168
+  //   id=167 inlineTextBox
+  //   id=168 grid IGNORED INVISIBLE child_ids=169,170
+  //     id=169 genericContainer IGNORED INVISIBLE
+  //     id=170 genericContainer IGNORED INVISIBLE child_ids=100
+  //       id=100 genericContainer IGNORED INVISIBLE child_ids=101
+  //         id=101 genericContainer IGNORED INVISIBLE
+
+  AXTreeUpdate initial_state;
+  initial_state.root_id = 47;
+  {
+    AXNodeData data;
+    data.id = 47;
+    data.role = ax::mojom::Role::kApplication;
+    data.child_ids = {167, 94};
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 167;
+    data.role = ax::mojom::Role::kInlineTextBox;
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 94;
+    data.role = ax::mojom::Role::kGrid;
+    data.child_ids = {98, 99};
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 98;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.AddState(ax::mojom::State::kIgnored);
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 99;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {100};
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 100;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {101};
+    data.AddState(ax::mojom::State::kIgnored);
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 101;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    initial_state.nodes.push_back(data);
+  }
+
+  AXTree tree(initial_state);
+  AXEventGenerator event_generator(&tree);
+  ASSERT_THAT(event_generator, IsEmpty());
+
+  AXTreeUpdate update;
+  {
+    AXNodeData data;
+    data.id = 47;
+    data.role = ax::mojom::Role::kApplication;
+    data.child_ids = {167, 168};
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 167;
+    data.role = ax::mojom::Role::kInlineTextBox;
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 168;
+    data.role = ax::mojom::Role::kGrid;
+    data.child_ids = {169, 170};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 169;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 170;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {100};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 100;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {101};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 101;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+
+  ASSERT_TRUE(tree.Unserialize(update));
+  EXPECT_THAT(
+      event_generator,
+      UnorderedElementsAre(
+          HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 47),
+          HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 100),
+          HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+                         100),
+          HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 168)));
+  // These are the events that shouldn't be happening:
+  // HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 100),
+  // HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 101),
+}
+
+TEST(AXEventGeneratorTest, ParentChangedOnIgnoredNodeFiresOnChildren) {
+  // This is a variation of the previous test, designed to check if, in the
+  // situation of parent-changed events happening on ignored nodes, the events
+  // are correctly fired in their non-ignored children.
+
+  // BEFORE:
+  // id=47 application child_ids=167,94
+  //   id=167 inlineTextBox
+  //   id=94 grid child_ids=98,99
+  //     id=98 genericContainer IGNORED
+  //     id=99 genericContainer child_ids=100
+  //       id=100 genericContainer IGNORED child_ids=101,102
+  //         id=101 genericContainer IGNORED INVISIBLE child_ids=103,104
+  //           id=103 staticText
+  //           id=104 staticText
+  //         id=102 staticText
+
+  // AFTER
+  // id=47 application child_ids=167,168
+  //   id=167 inlineTextBox
+  //   id=168 grid IGNORED INVISIBLE child_ids=169,170
+  //     id=169 genericContainer IGNORED INVISIBLE
+  //     id=170 genericContainer IGNORED INVISIBLE child_ids=100
+  //       id=100 genericContainer IGNORED INVISIBLE child_ids=101,102
+  //         id=101 genericContainer IGNORED INVISIBLE child_ids=103,104
+  //           id=103 staticText
+  //           id=104 staticText
+  //         id=102 staticText
+
+  AXTreeUpdate initial_state;
+  initial_state.root_id = 47;
+  {
+    AXNodeData data;
+    data.id = 47;
+    data.role = ax::mojom::Role::kApplication;
+    data.child_ids = {167, 94};
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 167;
+    data.role = ax::mojom::Role::kInlineTextBox;
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 94;
+    data.role = ax::mojom::Role::kGrid;
+    data.child_ids = {98, 99};
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 98;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.AddState(ax::mojom::State::kIgnored);
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 99;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {100};
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 100;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {101, 102};
+    data.AddState(ax::mojom::State::kIgnored);
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 101;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {103, 104};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 102;
+    data.role = ax::mojom::Role::kStaticText;
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 103;
+    data.role = ax::mojom::Role::kStaticText;
+    initial_state.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 104;
+    data.role = ax::mojom::Role::kStaticText;
+    initial_state.nodes.push_back(data);
+  }
+
+  AXTree tree(initial_state);
+  AXEventGenerator event_generator(&tree);
+  ASSERT_THAT(event_generator, IsEmpty());
+
+  AXTreeUpdate update;
+  {
+    AXNodeData data;
+    data.id = 47;
+    data.role = ax::mojom::Role::kApplication;
+    data.child_ids = {167, 168};
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 167;
+    data.role = ax::mojom::Role::kInlineTextBox;
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 168;
+    data.role = ax::mojom::Role::kGrid;
+    data.child_ids = {169, 170};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 169;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 170;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {100};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 100;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {101, 102};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 101;
+    data.role = ax::mojom::Role::kGenericContainer;
+    data.child_ids = {103, 104};
+    data.AddState(ax::mojom::State::kInvisible);
+    data.AddState(ax::mojom::State::kIgnored);
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 102;
+    data.role = ax::mojom::Role::kStaticText;
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 103;
+    data.role = ax::mojom::Role::kStaticText;
+    update.nodes.push_back(data);
+  }
+  {
+    AXNodeData data;
+    data.id = 104;
+    data.role = ax::mojom::Role::kStaticText;
+    update.nodes.push_back(data);
+  }
+
+  ASSERT_TRUE(tree.Unserialize(update));
+  EXPECT_THAT(
+      event_generator,
+      UnorderedElementsAre(
+          HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 47),
+          HasEventAtNode(AXEventGenerator::Event::STATE_CHANGED, 100),
+          HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+                         100),
+          HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 168),
+          HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 102),
+          HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 103),
+          HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 104)));
+  // These are the events that shouldn't be happening:
+  // HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 100),
+  // HasEventAtNode(AXEventGenerator::Event::PARENT_CHANGED, 101),
+}
+
 }  // namespace ui
diff --git a/ui/base/interaction/element_identifier.h b/ui/base/interaction/element_identifier.h
index 6a27d97..970a911 100644
--- a/ui/base/interaction/element_identifier.h
+++ b/ui/base/interaction/element_identifier.h
@@ -34,7 +34,7 @@
 // "MyClass::kMyIdentifierName":
 //
 //   class MyClass {
-//     DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(MyClass, kMyIdentifierName);
+//     DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kMyIdentifierName);
 //   };
 //
 // Then in the corresponding .cc file, add the following:
@@ -270,7 +270,7 @@
 
 // Use this code in your class declaration in its .h file to declare an
 // identifier that is scoped to your class.
-#define DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(ClassName, IdentifierName)    \
+#define DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(IdentifierName)               \
   static const ui::internal::ElementIdentifierImpl IdentifierName##Provider; \
   static constexpr ui::ElementIdentifier IdentifierName {                    \
     &IdentifierName##Provider                                                \
diff --git a/ui/base/interaction/element_tracker.h b/ui/base/interaction/element_tracker.h
index f367e468..444f10a 100644
--- a/ui/base/interaction/element_tracker.h
+++ b/ui/base/interaction/element_tracker.h
@@ -134,7 +134,7 @@
   // element completes, but in the future we may implement a ref-counting
   // system for systems that use a temporary identifier so that it does not
   // persist longer than it is needed.
-  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(ElementTracker, kTemporaryIdentifier);
+  DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kTemporaryIdentifier);
 
   // Gets the element tracker to be used by clients to subscribe to and receive
   // events.
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane.cc
index 5e7259c5..477c0b93 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane.cc
@@ -6,12 +6,16 @@
 
 #include <drm_fourcc.h>
 #include <drm_mode.h>
+#include <string>
 
 #include "base/logging.h"
+#include "base/notreached.h"
+#include "base/strings/string_util.h"
 #include "base/trace_event/traced_value.h"
 #include "ui/ozone/platform/drm/common/drm_util.h"
 #include "ui/ozone/platform/drm/gpu/drm_device.h"
 #include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
+#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h"
 
 namespace ui {
 
@@ -35,6 +39,13 @@
     supported_format_modifiers->push_back(modifiers[k]);
 }
 
+std::string IdSetToString(const base::flat_set<uint32_t>& ids) {
+  std::vector<std::string> string_ids;
+  for (auto id : ids)
+    string_ids.push_back(std::to_string(id));
+  return "[" + base::JoinString(string_ids, ", ") + "]";
+}
+
 }  // namespace
 HardwareDisplayPlane::Properties::Properties() = default;
 HardwareDisplayPlane::Properties::~Properties() = default;
@@ -43,8 +54,8 @@
 
 HardwareDisplayPlane::~HardwareDisplayPlane() {}
 
-bool HardwareDisplayPlane::CanUseForCrtc(uint32_t crtc_index) const {
-  return crtc_mask_ & (1 << crtc_index);
+bool HardwareDisplayPlane::CanUseForCrtcId(uint32_t crtc_id) const {
+  return possible_crtc_ids_.contains(crtc_id);
 }
 
 void HardwareDisplayPlane::AsValueInto(
@@ -52,6 +63,25 @@
   value->SetInteger("plane_id", id_);
   value->SetInteger("owning_crtc", owning_crtc_);
   value->SetBoolean("in_use", in_use_);
+  {
+    auto scoped_array = value->BeginArrayScoped("possible_crtc_ids");
+    for (auto id : possible_crtc_ids_)
+      value->AppendInteger(id);
+  }
+
+  switch (properties_.type.value) {
+    case DRM_PLANE_TYPE_OVERLAY:
+      value->SetString("type", "DRM_PLANE_TYPE_OVERLAY");
+      break;
+    case DRM_PLANE_TYPE_PRIMARY:
+      value->SetString("type", "DRM_PLANE_TYPE_PRIMARY");
+      break;
+    case DRM_PLANE_TYPE_CURSOR:
+      value->SetString("type", "DRM_PLANE_TYPE_CURSOR");
+      break;
+    default:
+      NOTREACHED();
+  }
 }
 
 bool HardwareDisplayPlane::Initialize(DrmDevice* drm) {
@@ -60,7 +90,9 @@
   ScopedDrmPlanePtr drm_plane(drm->GetPlane(id_));
   DCHECK(drm_plane);
 
-  crtc_mask_ = drm_plane->possible_crtcs;
+  possible_crtc_ids_ =
+      drm->plane_manager()->CrtcMaskToCrtcIds(drm_plane->possible_crtcs);
+
   if (properties_.in_formats.id) {
     ScopedDrmPropertyBlobPtr blob(
         drm->GetPropertyBlob(properties_.in_formats.value));
@@ -85,8 +117,8 @@
         drm->get_fd(), properties_.plane_color_range.id, "YCbCr limited range");
   }
 
-  VLOG(3) << "Initialized plane=" << id_ << " crtc_mask=" << std::hex << "0x"
-          << crtc_mask_ << std::dec
+  VLOG(3) << "Initialized plane=" << id_
+          << " possible_crtc_ids=" << IdSetToString(possible_crtc_ids_)
           << " supported_formats_count=" << supported_formats_.size()
           << " supported_modifiers_count="
           << supported_format_modifiers_.size();
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane.h b/ui/ozone/platform/drm/gpu/hardware_display_plane.h
index 55abfd6..0ed63e7c 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane.h
@@ -12,6 +12,7 @@
 
 #include <vector>
 
+#include "base/containers/flat_set.h"
 #include "base/trace_event/traced_value.h"
 #include "ui/ozone/platform/drm/common/scoped_drm_types.h"
 #include "ui/ozone/platform/drm/gpu/drm_device.h"
@@ -33,7 +34,7 @@
 
   std::vector<uint64_t> ModifiersForFormat(uint32_t format) const;
 
-  bool CanUseForCrtc(uint32_t crtc_index) const;
+  bool CanUseForCrtcId(uint32_t crtc_id) const;
 
   void AsValueInto(base::trace_event::TracedValue* value) const;
 
@@ -77,10 +78,10 @@
   };
 
   const uint32_t id_;
-  uint32_t crtc_mask_ = 0;
 
   Properties properties_ = {};
 
+  base::flat_set<uint32_t> possible_crtc_ids_;
   uint32_t owning_crtc_ = 0;
   uint32_t last_used_format_ = 0;
   bool in_use_ = false;
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index 4b45904..70bd00b 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -6,6 +6,7 @@
 
 #include <drm_fourcc.h>
 #include <algorithm>
+#include <cstdint>
 #include <memory>
 #include <set>
 #include <utility>
@@ -103,11 +104,11 @@
 
 HardwareDisplayPlane* HardwareDisplayPlaneManager::FindNextUnusedPlane(
     size_t* index,
-    uint32_t crtc_index,
+    uint32_t crtc_id,
     const DrmOverlayPlane& overlay) const {
   for (size_t i = *index; i < planes_.size(); ++i) {
     auto* plane = planes_[i].get();
-    if (!plane->in_use() && IsCompatible(plane, overlay, crtc_index)) {
+    if (!plane->in_use() && IsCompatible(plane, overlay, crtc_id)) {
       *index = i + 1;
       return plane;
     }
@@ -133,11 +134,22 @@
   return {};
 }
 
+base::flat_set<uint32_t> HardwareDisplayPlaneManager::CrtcMaskToCrtcIds(
+    uint32_t crtc_mask) const {
+  base::flat_set<uint32_t> crtc_ids;
+  for (uint32_t idx = 0; idx < crtc_state_.size(); idx++) {
+    if (crtc_mask & (1 << idx))
+      crtc_ids.insert(crtc_state_[idx].properties.id);
+  }
+
+  return crtc_ids;
+}
+
 bool HardwareDisplayPlaneManager::IsCompatible(HardwareDisplayPlane* plane,
                                                const DrmOverlayPlane& overlay,
-                                               uint32_t crtc_index) const {
+                                               uint32_t crtc_id) const {
   if (plane->type() == DRM_PLANE_TYPE_CURSOR ||
-      !plane->CanUseForCrtc(crtc_index))
+      !plane->CanUseForCrtcId(crtc_id))
     return false;
 
   const uint32_t format =
@@ -201,16 +213,10 @@
     HardwareDisplayPlaneList* plane_list,
     const DrmOverlayPlaneList& overlay_list,
     uint32_t crtc_id) {
-  auto crtc_index = LookupCrtcIndex(crtc_id);
-  if (!crtc_index) {
-    LOG(ERROR) << "Cannot find crtc " << crtc_id;
-    return false;
-  }
-
   size_t plane_idx = 0;
   for (const auto& plane : overlay_list) {
     HardwareDisplayPlane* hw_plane =
-        FindNextUnusedPlane(&plane_idx, *crtc_index, plane);
+        FindNextUnusedPlane(&plane_idx, crtc_id, plane);
     if (!hw_plane) {
       RestoreCurrentPlaneList(plane_list);
       return false;
@@ -247,13 +253,8 @@
 std::vector<uint64_t> HardwareDisplayPlaneManager::GetFormatModifiers(
     uint32_t crtc_id,
     uint32_t format) const {
-  auto crtc_index = LookupCrtcIndex(crtc_id);
-  if (!crtc_index) {
-    return {};
-  }
-
   for (const auto& plane : planes_) {
-    if (plane->CanUseForCrtc(*crtc_index) &&
+    if (plane->CanUseForCrtcId(crtc_id) &&
         plane->type() == DRM_PLANE_TYPE_PRIMARY) {
       return plane->ModifiersForFormat(format);
     }
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index 0fe0933..b576165 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -8,9 +8,11 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <xf86drmMode.h>
+#include <cstdint>
 #include <memory>
 #include <vector>
 
+#include "base/containers/flat_set.h"
 #include "base/trace_event/traced_value.h"
 #include "ui/display/types/gamma_ramp_rgb_entry.h"
 #include "ui/ozone/platform/drm/common/scoped_drm_types.h"
@@ -169,6 +171,9 @@
   virtual bool ValidatePrimarySize(const DrmOverlayPlane& primary,
                                    const drmModeModeInfo& mode) = 0;
 
+  // Get the set of CRTC IDs from a plane's possible CRTCs bitmap
+  base::flat_set<uint32_t> CrtcMaskToCrtcIds(uint32_t crtc_mask) const;
+
   const std::vector<std::unique_ptr<HardwareDisplayPlane>>& planes() const {
     return planes_;
   }
@@ -232,10 +237,10 @@
   virtual std::unique_ptr<HardwareDisplayPlane> CreatePlane(uint32_t plane_id);
 
   // Finds the plane located at or after |*index| that is not in use and can
-  // be used with |crtc_index|.
+  // be used with |crtc_id|.
   HardwareDisplayPlane* FindNextUnusedPlane(
       size_t* index,
-      uint32_t crtc_index,
+      uint32_t crtc_id,
       const DrmOverlayPlane& overlay) const;
 
   // Convert |crtc/connector_id| into an index, returning empty if the ID
@@ -247,10 +252,10 @@
   CrtcState& CrtcStateForCrtcId(uint32_t crtc_id);
 
   // Returns true if |plane| can support |overlay| and compatible with
-  // |crtc_index|.
+  // |crtc_id|.
   virtual bool IsCompatible(HardwareDisplayPlane* plane,
                             const DrmOverlayPlane& overlay,
-                            uint32_t crtc_index) const;
+                            uint32_t crtc_id) const;
 
   // Resets |plane_list| setting all planes to unused.
   // Frees any temporary data structure in |plane_list| used for pageflipping.
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
index e6db3f1..fe43fbc 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -344,15 +344,12 @@
   ScopedDrmPropertyBlob property_blob(
       drm_->CreatePropertyBlob(ctm_blob_data.get(), sizeof(drm_color_ctm)));
 
-  const auto crtc_index = LookupCrtcIndex(crtc_id);
-  DCHECK(crtc_index.has_value());
-
   for (auto& plane : planes_) {
     HardwareDisplayPlaneAtomic* atomic_plane =
         static_cast<HardwareDisplayPlaneAtomic*>(plane.get());
 
     // This assumes planes can only belong to one crtc.
-    if (!atomic_plane->CanUseForCrtc(*crtc_index))
+    if (!atomic_plane->CanUseForCrtcId(crtc_id))
       continue;
 
     if (!atomic_plane->SetPlaneCtm(property_set.get(), property_blob->id())) {
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
index a4587a7f..3c8592f3 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -206,9 +206,9 @@
 bool HardwareDisplayPlaneManagerLegacy::IsCompatible(
     HardwareDisplayPlane* plane,
     const DrmOverlayPlane& overlay,
-    uint32_t crtc_index) const {
+    uint32_t crtc_id) const {
   if (plane->type() == DRM_PLANE_TYPE_CURSOR ||
-      !plane->CanUseForCrtc(crtc_index))
+      !plane->CanUseForCrtcId(crtc_id))
     return false;
 
   // When using legacy kms we always scanout only one plane (the primary),
diff --git a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
index c6906dc..19d8a117 100644
--- a/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
+++ b/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
@@ -54,7 +54,7 @@
                     const gfx::Rect& src_rect) override;
   bool IsCompatible(HardwareDisplayPlane* plane,
                     const DrmOverlayPlane& overlay,
-                    uint32_t crtc_index) const override;
+                    uint32_t crtc_id) const override;
   bool CommitColorMatrix(const CrtcProperties& crtc_props) override;
   bool CommitGammaCorrection(const CrtcProperties& crtc_props) override;
 };
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.m.d.ts b/ui/webui/resources/cr_elements/cr_input/cr_input.m.d.ts
index 37b3e4a5..dbc13d4 100644
--- a/ui/webui/resources/cr_elements/cr_input/cr_input.m.d.ts
+++ b/ui/webui/resources/cr_elements/cr_input/cr_input.m.d.ts
@@ -9,7 +9,7 @@
   ariaLabel: string|null|undefined;
   autofocus: boolean;
   autoValidate: boolean|null|undefined;
-  disabled: boolean|null|undefined;
+  disabled: boolean;
   errorMessage: string|null|undefined;
   invalid: boolean;
   max: number|null|undefined;
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn
index fad4f5a1..84f4ceb 100644
--- a/weblayer/shell/android/BUILD.gn
+++ b/weblayer/shell/android/BUILD.gn
@@ -65,9 +65,7 @@
   jinja_template(_manifest_target) {
     input = "shell_apk/AndroidManifest.xml"
     output = _weblayer_shell_manifest
-    if (defined(invoker.weblayer_package)) {
-      variables = [ "weblayer_package=" + invoker.weblayer_package ]
-    }
+    variables = [ "weblayer_package=" + invoker.weblayer_package ]
   }
 
   android_apk(target_name + "_apk") {
@@ -98,6 +96,7 @@
 }
 
 weblayer_shell_apk_helper("weblayer_shell_system_webview") {
+  weblayer_package = system_webview_package_name
   apk_name = "WebLayerShellSystemWebView"
 }